From 11d2ab8c865c2616cb66267eb7b23fa8d3b47e88 Mon Sep 17 00:00:00 2001 From: zefie Date: Mon, 4 May 2026 20:07:18 -0400 Subject: [PATCH] some documentation --- zefie_wtvp_minisrv/app.js | 4 +- .../ServiceVault/wtv-flashrom/get-lc2-page.js | 1 + .../includes/classes/WTVClientSessionData.js | 109 +++++++++++++++++- .../includes/classes/WTVShared.js | 4 +- 4 files changed, 114 insertions(+), 4 deletions(-) diff --git a/zefie_wtvp_minisrv/app.js b/zefie_wtvp_minisrv/app.js index 1cf6d2d8..7cc92cca 100644 --- a/zefie_wtvp_minisrv/app.js +++ b/zefie_wtvp_minisrv/app.js @@ -2704,9 +2704,11 @@ if (protocolHandledPorts.size > 0) console.log(` * Started ${protocolHandledPort const listening_ip_string = (minisrv_config.config.bind_ip !== "0.0.0.0") ? "IP: " + minisrv_config.config.bind_ip : "all interfaces"; console.log(" * Listening on", listening_ip_string, "~", "Service IP:", service_ip); +// Security warning for default user data encryption key if (minisrv_config.config.keys.user_data_key === "PNa$WN7gz}!T=t6X7^=|Ii##CEB~p\\EP") { console.log(" * WARNING: You are using the default user data encryption key. This is not secure, and you should change it in the configuration file before registering any users."); console.log(" * To generate a random key in bash or PowerShell, you can run: node ./tools/configurator.js config.keys.user_data_key $(openssl rand -base64 32)"); - console.log(" * After changing the key in the user_config, you can run tools/update_user_data_key.js to update existing accounts with the new key."); + console.log(" * After changing the key in the user_config, please restart the server."); + console.log(" * If you had existing users prior to changing the key, you can run tools/update_user_data_key.js to update existing accounts with the new key."); console.log(" * Making a backup of your user accounts before doing this is highly recommended, in case something goes wrong during the update process."); } \ No newline at end of file diff --git a/zefie_wtvp_minisrv/includes/ServiceVault/wtv-flashrom/get-lc2-page.js b/zefie_wtvp_minisrv/includes/ServiceVault/wtv-flashrom/get-lc2-page.js index 616e3c56..22b70bbb 100644 --- a/zefie_wtvp_minisrv/includes/ServiceVault/wtv-flashrom/get-lc2-page.js +++ b/zefie_wtvp_minisrv/includes/ServiceVault/wtv-flashrom/get-lc2-page.js @@ -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; } diff --git a/zefie_wtvp_minisrv/includes/classes/WTVClientSessionData.js b/zefie_wtvp_minisrv/includes/classes/WTVClientSessionData.js index c451608d..57d33de9 100644 --- a/zefie_wtvp_minisrv/includes/classes/WTVClientSessionData.js +++ b/zefie_wtvp_minisrv/includes/classes/WTVClientSessionData.js @@ -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(); diff --git a/zefie_wtvp_minisrv/includes/classes/WTVShared.js b/zefie_wtvp_minisrv/includes/classes/WTVShared.js index f48cc99d..61abedd8 100644 --- a/zefie_wtvp_minisrv/includes/classes/WTVShared.js +++ b/zefie_wtvp_minisrv/includes/classes/WTVShared.js @@ -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