Merge branch 'dev' into feature/FixTv2
This commit is contained in:
@@ -38,6 +38,7 @@ async function processLC2DownloadPage(flashrom_info, headers, numparts = null) {
|
||||
if (!flashrom_info.part_count) flashrom_info.part_count = parseInt(flashrom_info.message.slice(flashrom_info.message.length - 4).replace(/\D/g, ''));
|
||||
if (parseInt(flashrom_info.part_number) >= 0 && flashrom_info.rompath && flashrom_info.next_rompath) {
|
||||
if (!flashrom_info.message && flashrom_info.is_bootrom) {
|
||||
flashrom_info.part_count = 16;
|
||||
flashrom_info.message = "BootRom Part " + (flashrom_info.part_number + 1) + " of " + flashrom_info.part_count;
|
||||
}
|
||||
|
||||
|
||||
@@ -56,18 +56,32 @@ class WTVClientSessionData {
|
||||
this.loginWhitelist.push("wtv-head-waiter:/confirm-transfer");
|
||||
}
|
||||
|
||||
/**
|
||||
* Assigns a new WTVMail instance to the session's mailstore property, using the current minisrv_config and session data.
|
||||
*/
|
||||
assignMailStore() {
|
||||
this.mailstore = new WTVMail(this.minisrv_config, this)
|
||||
}
|
||||
|
||||
/**
|
||||
* Assigns a new WTVFavorites instance to the session's favstore property, using the current minisrv_config and session data.
|
||||
*/
|
||||
assignFavoriteStore() {
|
||||
this.mailstore = this.favstore = new WTVFavorites(this.minisrv_config, this)
|
||||
this.favstore = new WTVFavorites(this.minisrv_config, this)
|
||||
}
|
||||
|
||||
/**
|
||||
* Creates a new WTVSec session. Used for RC4 SECURE ON requests.
|
||||
* @returns {WTVSec} A new WTVSec session instance
|
||||
*/
|
||||
createWTVSecSession() {
|
||||
return new WTVSec(this.minisrv_config)
|
||||
}
|
||||
|
||||
/**
|
||||
* Retrieves the total number of unread messages for the primary account.
|
||||
* @returns {number} Number of unread messages
|
||||
*/
|
||||
getAccountTotalUnreadMessages() {
|
||||
if (!this.isRegistered()) return false; // unregistered
|
||||
if (this.user_id > 0) return false; // not primary user or pre-login
|
||||
@@ -88,6 +102,9 @@ class WTVClientSessionData {
|
||||
return total_unread_messages;
|
||||
}
|
||||
|
||||
/**
|
||||
* Clears all user session data from memory, including session store and data store, and resets mail and favorite stores.
|
||||
*/
|
||||
clearUserSessionMemory() {
|
||||
this.setUserLoggedIn(false);
|
||||
this.data_store = [];
|
||||
@@ -96,6 +113,13 @@ class WTVClientSessionData {
|
||||
this.assignMailStore()
|
||||
}
|
||||
|
||||
/**
|
||||
* Switches the current user ID and optionally updates related data stores.
|
||||
* @param {number} user_id The user ID to switch to
|
||||
* @param {boolean} update_mail Whether to update the mail store
|
||||
* @param {boolean} update_ticket Whether to update the ticket data
|
||||
* @param {boolean} update_favorite Whether to update the favorite store
|
||||
*/
|
||||
switchUserID(user_id, update_mail = true, update_ticket = true, update_favorite = true) {
|
||||
this.user_id = parseInt(user_id);
|
||||
if (user_id !== null) {
|
||||
@@ -143,6 +167,11 @@ class WTVClientSessionData {
|
||||
return true;
|
||||
}
|
||||
|
||||
/**
|
||||
* Checks if a given mail address is in the address book.
|
||||
* @param {string} addr The mail address to check against the address book
|
||||
* @returns {boolean} True if the address is in the address book, false otherwise
|
||||
*/
|
||||
isAddressInAddressBook(addr) {
|
||||
const addresses = this.getSessionData("address_book");
|
||||
if (addresses) {
|
||||
@@ -156,6 +185,11 @@ class WTVClientSessionData {
|
||||
return false;
|
||||
}
|
||||
|
||||
/**
|
||||
* Finds the first available user slot for a new user.
|
||||
* Can only be used by the primary account (user_id 0).
|
||||
* @returns {number|boolean} The first available user slot index, or false if no slots are available
|
||||
*/
|
||||
findFreeUserSlot() {
|
||||
if (this.user_id !== 0) return false; // subscriber only command
|
||||
const master_directory = this.getUserStoreDirectory(true);
|
||||
@@ -170,16 +204,30 @@ class WTVClientSessionData {
|
||||
return false;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the display name of the current user.
|
||||
* @returns {string} The subscriber's display name if user_id is 0, otherwise the current user's display name.
|
||||
*/
|
||||
getDisplayName() {
|
||||
return (this.user_id === 0) ? this.getSessionData("subscriber_name") : this.getSessionData("display_name");
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the number of users for this SSID.
|
||||
* Can only be used by the primary account (user_id 0).
|
||||
* @returns {number} The number of users this SSID has
|
||||
*/
|
||||
getNumberOfUserAccounts() {
|
||||
if (!this.isRegistered()) return false;
|
||||
if (this.user_id !== 0) return false; // subscriber only command
|
||||
return Object.keys(this.listPrimaryAccountUsers()).length;
|
||||
}
|
||||
|
||||
/**
|
||||
* Lists all primary account users for this SSID.
|
||||
*
|
||||
* @returns {Array} An array containing the account data of all users for this SSID
|
||||
*/
|
||||
listPrimaryAccountUsers() {
|
||||
if (this.user_id !== 0) return false; // subscriber only command
|
||||
|
||||
@@ -206,6 +254,10 @@ class WTVClientSessionData {
|
||||
return account_data;
|
||||
}
|
||||
|
||||
/**
|
||||
* Recursively creates directories for the given path.
|
||||
* @param {string} thedir The directory path to create
|
||||
*/
|
||||
mkdirRecursive(thedir) {
|
||||
thedir.split(this.path.sep).reduce(
|
||||
(directories, directory) => {
|
||||
@@ -307,6 +359,13 @@ class WTVClientSessionData {
|
||||
return false;
|
||||
}
|
||||
|
||||
/**
|
||||
* A part of the account transfer process, creates a pending transfer file in both the source and target account
|
||||
* store directories with the relevant SSID and transfer type (source or target) for each account.
|
||||
* This allows the transfer process to be completed or cancelled later, and ensures that only accounts
|
||||
* with a pending transfer can complete the transfer process.
|
||||
* @param {string} ssid
|
||||
*/
|
||||
setPendingTransfer(ssid) {
|
||||
const pending_file = this.getUserStoreDirectory(true) + this.path.sep + "pending_transfer.json";
|
||||
let ssidobj = { "ssid": ssid, "type": "source" };
|
||||
@@ -319,6 +378,10 @@ class WTVClientSessionData {
|
||||
this.fs.writeFileSync(dest_pending_file, JSON.stringify(ssidobj));
|
||||
}
|
||||
|
||||
/**
|
||||
* Cancels a pending account transfer, if it exists.
|
||||
* @returns {string|null} The SSID of the cancelled transfer if a pending transfer was found and cancelled, or null if no pending transfer was found
|
||||
*/
|
||||
cancelPendingTransfer() {
|
||||
const pending_file = this.getUserStoreDirectory(true) + this.path.sep + "pending_transfer.json";
|
||||
if (this.fs.existsSync(pending_file)) {
|
||||
@@ -334,6 +397,10 @@ class WTVClientSessionData {
|
||||
return null;
|
||||
}
|
||||
|
||||
/**
|
||||
* Finalize the transfer, completely moving all user data from the source account to the target account, and removing the pending transfer files.
|
||||
* @returns {boolean} Success of the transfer
|
||||
*/
|
||||
finalizePendingTransfer() {
|
||||
const pending_file = this.getUserStoreDirectory(true) + this.path.sep + "pending_transfer.json";
|
||||
const file = this.fs.readFileSync(pending_file)
|
||||
@@ -353,13 +420,18 @@ class WTVClientSessionData {
|
||||
return true;
|
||||
}
|
||||
|
||||
/**
|
||||
* Check if there is a pending transfer for this account, and optionally check if the pending transfer type matches the specified dtype.
|
||||
* @param {string} dtype {source|target} If specified, only returns the SSID if the pending transfer type matches the specified dtype. If null, returns the pending transfer object with ssid and type.
|
||||
* @returns {string|object|boolean} The SSID of the pending transfer if dtype matches, the pending transfer object if dtype is null, or false if no pending transfer is found
|
||||
*/
|
||||
hasPendingTransfer(dtype = null) {
|
||||
const pending_file = this.getUserStoreDirectory(true) + this.path.sep + "pending_transfer.json";
|
||||
if (this.fs.existsSync(pending_file)) {
|
||||
const ssidobj = JSON.parse(this.fs.readFileSync(pending_file));
|
||||
console.log(ssidobj)
|
||||
if (dtype) {
|
||||
(ssidobj.type === dtype) ? ssidobj.ssid : false;
|
||||
return (ssidobj.type === dtype) ? ssidobj.ssid : false;
|
||||
}
|
||||
else {
|
||||
return ssidobj;
|
||||
@@ -402,6 +474,10 @@ class WTVClientSessionData {
|
||||
return result !== false;
|
||||
}
|
||||
|
||||
/**
|
||||
* Checks if the user has a scrapbook directory.
|
||||
* @returns {boolean} True if the scrapbook directory exists, false otherwise.
|
||||
*/
|
||||
scrapbookExists() {
|
||||
if (this.scrapbook_dir === null) {
|
||||
const userstore_dir = this.getUserStoreDirectory();
|
||||
@@ -411,6 +487,10 @@ class WTVClientSessionData {
|
||||
return this.fs.existsSync(this.scrapbook_dir);
|
||||
}
|
||||
|
||||
/**
|
||||
* Creates a scrapbook directory for the user if it does not already exist.
|
||||
* @returns {boolean} Success of the creation
|
||||
*/
|
||||
createScrapbook() {
|
||||
if (!this.scrapbookExists()) {
|
||||
try {
|
||||
@@ -421,6 +501,10 @@ class WTVClientSessionData {
|
||||
return false
|
||||
}
|
||||
|
||||
/**
|
||||
* A wrapper that returns the scrapbook directory, and creates it if it doesn't exist.
|
||||
* @returns {string} The path to the scrapbook directory
|
||||
*/
|
||||
scrapbookDir() {
|
||||
if (!this.scrapbookExists()) {
|
||||
this.createScrapbook();
|
||||
@@ -428,6 +512,10 @@ class WTVClientSessionData {
|
||||
return this.scrapbook_dir;
|
||||
}
|
||||
|
||||
/**
|
||||
* List the files in the user's scrapbook directory, sorted in ascending order, and excluding any .meta files.
|
||||
* @returns {Array} A filelist of the user's scrapbook files
|
||||
*/
|
||||
listScrapbook() {
|
||||
if (!this.scrapbookExists()) {
|
||||
this.createScrapbook();
|
||||
@@ -442,6 +530,10 @@ class WTVClientSessionData {
|
||||
return filteredFiles;
|
||||
}
|
||||
|
||||
/**
|
||||
* Finds the next available ID slot for a new scrapbook entry.
|
||||
* @returns {number} An available ID slot
|
||||
*/
|
||||
getFreeScrapbookID() {
|
||||
if (!this.scrapbookExists()) {
|
||||
this.createScrapbook();
|
||||
@@ -458,6 +550,10 @@ class WTVClientSessionData {
|
||||
return id;
|
||||
}
|
||||
|
||||
/**
|
||||
* Calculates the total size of the user's scrapbook directory.
|
||||
* @returns {number} The total size in bytes
|
||||
*/
|
||||
getScrapbookUsage() {
|
||||
if (!this.scrapbookExists()) {
|
||||
this.createScrapbook();
|
||||
@@ -475,6 +571,10 @@ class WTVClientSessionData {
|
||||
return total_size;
|
||||
}
|
||||
|
||||
/**
|
||||
* Calculates the percentage of the scrapbook storage space that is in use.
|
||||
* @returns {number} Percentage of the scrapbook storage space that is in use, out of the total allotted.
|
||||
*/
|
||||
getScrapbookUsagePercent() {
|
||||
if (!this.scrapbookExists()) {
|
||||
this.createScrapbook();
|
||||
@@ -486,6 +586,11 @@ class WTVClientSessionData {
|
||||
return Math.round(usage_percent, 2);
|
||||
}
|
||||
|
||||
/**
|
||||
* Get a scrapbook image by its ID.
|
||||
* @param {number} id
|
||||
* @returns {Buffer|null} The image data as a Buffer, or null if the image does not exist
|
||||
*/
|
||||
getScrapbookImage(id) {
|
||||
if (!this.scrapbookExists()) {
|
||||
this.createScrapbook();
|
||||
|
||||
@@ -1130,6 +1130,7 @@ class WTVShared {
|
||||
// DON'T USE THIS
|
||||
// Saved for reference until I come up with a better way
|
||||
// If used, this will exceed the stack limit over time
|
||||
/*
|
||||
unloadModule(moduleName) {
|
||||
// Prevent usage
|
||||
return;
|
||||
@@ -1141,7 +1142,8 @@ class WTVShared {
|
||||
delete require.cache[resolvedPath];
|
||||
}
|
||||
}
|
||||
|
||||
*/
|
||||
|
||||
/**
|
||||
* Returns an absolute path without an trailing path seperator
|
||||
* @param {string} path
|
||||
|
||||
Reference in New Issue
Block a user