diff --git a/zefie_wtvp_minisrv/ServiceVault/wtv-admin/admin.js b/zefie_wtvp_minisrv/ServiceVault/wtv-admin/admin.js new file mode 100644 index 00000000..fad5cf02 --- /dev/null +++ b/zefie_wtvp_minisrv/ServiceVault/wtv-admin/admin.js @@ -0,0 +1,94 @@ +var minisrv_service_file = true; + +var WTVAdmin = require("./WTVAdmin.js"); +var wtva = new WTVAdmin(minisrv_config, ssid_sessions[socket.ssid], service_name); +var auth = wtva.isAuthorized(); +if (auth === true) { + var password = null; + if (request_headers.Authorization) { + var authheader = request_headers.Authorization.split(' '); + if (authheader[0] == "Basic") { + password = Buffer.from(authheader[1], 'base64').toString(); + if (password) password = password.split(':')[1]; + } + } + if (wtva.checkPassword(password)) { + headers = "200 OK\r\nContent-Type: text/html"; + data = ` + + +${minisrv_config.config.service_name} Admin Tricks + + + + + +
+
+

${minisrv_config.config.service_name} Admin Tricks

+
+ + + + + + + + + + + + + + + + + +
+
Standard Tricks + +Account Lookup +
+
Ban an SSID + +Delete an Account +
+
Unban an SSID + +Delete User from Account +
+
Whitelist an SSID + +Remove Pass from User +
+
Grant Admin to SSID + +Revoke Admin from SSID +
+
+ + +
+
+ + +
+
+ + + + +
+ + +`; + } else { + var errpage = wtvshared.doErrorPage(401, "Please enter the administration password, you can leave the username blank."); + headers = errpage[0]; + data = errpage[1]; + } +} else { + var errpage = wtvshared.doErrorPage(403, auth); + headers = errpage[0]; + data = errpage[1]; +} \ No newline at end of file diff --git a/zefie_wtvp_minisrv/ServiceVault/wtv-admin/ban.js b/zefie_wtvp_minisrv/ServiceVault/wtv-admin/ban.js new file mode 100644 index 00000000..21836a21 --- /dev/null +++ b/zefie_wtvp_minisrv/ServiceVault/wtv-admin/ban.js @@ -0,0 +1,94 @@ +var minisrv_service_file = true; + +var WTVAdmin = require("./WTVAdmin.js"); +var wtva = new WTVAdmin(minisrv_config, ssid_sessions[socket.ssid], service_name); +var auth = wtva.isAuthorized(); +if (auth === true) { + var password = null; + if (request_headers.Authorization) { + var authheader = request_headers.Authorization.split(' '); + if (authheader[0] == "Basic") { + password = Buffer.from(authheader[1], 'base64').toString(); + if (password) password = password.split(':')[1]; + } + } + if (wtva.checkPassword(password)) { + if (request_headers.query.ssid) { + var ssid = request_headers.query.ssid.toLowerCase(); + if (ssid == socket.ssid) { + var nobanself = true; + } else { + var fake_config = wtvshared.getUserConfig(); + if (!fake_config.config) fake_config.config = {}; + if (!fake_config.config.ssid_block_list) fake_config.config.ssid_block_list = []; + var entry_exists = false; + Object.keys(fake_config.config.ssid_block_list).forEach(function (k) { + if (fake_config.config.ssid_block_list[k] == ssid) { + entry_exists = true; + } + }); + if (!entry_exists) { + fake_config.config.ssid_block_list.push(ssid); + wtvshared.writeToUserConfig(fake_config); + reloadConfig(); + } + } + } + headers = `200 OK +Content-Type: text/html +wtv-expire-all: wtv-admin:/ban`; + if (ssid) { + headers += "\nwtv-noback-all: wtv-admin:/ban"; + } + data = ` + + +${minisrv_config.config.service_name} Admin Tricks + + + + +
+
+

${minisrv_config.config.service_name} Admin Tricks

+
+ + + +
+

Ban an SSID

+
+ + +


` + if (request_headers.query.ssid) { + if (nobanself) { + data += "Cannot ban yourself." + } else { + if (entry_exists) { + data += "SSID " + request_headers.query.ssid + " is already in the ban list.

"; + } else { + data += "SSID " + request_headers.query.ssid + " added to the ban list.

"; + } + } + } + data += ` +
+
+
+

+Go Back +

+ + +`; + } else { + var errpage = wtvshared.doErrorPage(401, "Please enter the administration password, you can leave the username blank."); + headers = errpage[0]; + data = errpage[1]; + } +} else { + var errpage = wtvshared.doErrorPage(403, auth); + headers = errpage[0]; + data = errpage[1]; +} \ No newline at end of file diff --git a/zefie_wtvp_minisrv/ServiceVault/wtv-admin/deleteaccount.js b/zefie_wtvp_minisrv/ServiceVault/wtv-admin/deleteaccount.js new file mode 100644 index 00000000..8c102af6 --- /dev/null +++ b/zefie_wtvp_minisrv/ServiceVault/wtv-admin/deleteaccount.js @@ -0,0 +1,112 @@ +var minisrv_service_file = true; + +var WTVAdmin = require("./WTVAdmin.js"); +var wtva = new WTVAdmin(minisrv_config, ssid_sessions[socket.ssid], service_name); +var auth = wtva.isAuthorized(); +if (auth === true) { + var password = null; + if (request_headers.Authorization) { + var authheader = request_headers.Authorization.split(' '); + if (authheader[0] == "Basic") { + password = Buffer.from(authheader[1], 'base64').toString(); + if (password) password = password.split(':')[1]; + } + } + if (wtva.checkPassword(password)) { + if (request_headers.query.ssid) { + var ssid_match = false; + var ssid = request_headers.query.ssid.toLowerCase(); + var user_info = wtva.getAccountInfoBySSID(ssid); + if (request_headers.query.confirm_delete) { + user_info = null; + if (ssid == socket.ssid) { + ssid_match = true; + } else { + // delete + var userAccount = wtva.getAccountBySSID(ssid); + userAccount.unregisterBox(); + } + } + } + headers = `200 OK +Content-Type: text/html +wtv-expire-all: wtv-admin:/deleteaccount +wtv-noback-all: wtv-admin:/deleteaccount`; + data = ` + + +${minisrv_config.config.service_name} Admin Tricks + + + + +
+
+

${minisrv_config.config.service_name} Admin Tricks

+
+ + + +
+

Delete an Account

+
+   +


` + if (ssid) { + if (user_info) { + data += ` +User Information: + + +`; + if (user_info.account_users) { + data += ``; + if (Object.keys(user_info.account_users).length > 1) { + data += `` + } + } + data += ` + + + +` + data += `
Username:${user_info.username} (User ID: ${user_info.user_id})
SSID:${user_info.ssid}
Primary User:${user_info.account_users['subscriber'].subscriber_username}
Additional Users:`; + Object.keys(user_info.account_users).forEach(function (k) { + if (k == "subscriber") return; + data += user_info.account_users[k].subscriber_username + "
"; + }) + data += `
+
+ + + +
+
`; + } else if (request_headers.query.confirm_delete && ssid_match) { + data += `Cannot delete yourself in this manner.
Try ${minisrv_config.config.service_name} Tricks Unregister.


`; + } else if (request_headers.query.confirm_delete) { + data += "Account for SSID \"" + ssid + "\" has been deleted.

"; + } else { + data += "Could not find an account for SSID \"" + ssid + "\"

"; + } + } + data += ` +
+
+
+

+Go Back +

+ + +`; + } else { + var errpage = wtvshared.doErrorPage(401, "Please enter the administration password, you can leave the username blank."); + headers = errpage[0]; + data = errpage[1]; + } +} else { + var errpage = wtvshared.doErrorPage(403, auth); + headers = errpage[0]; + data = errpage[1]; +} \ No newline at end of file diff --git a/zefie_wtvp_minisrv/ServiceVault/wtv-admin/deleteuser.js b/zefie_wtvp_minisrv/ServiceVault/wtv-admin/deleteuser.js new file mode 100644 index 00000000..78f16fb6 --- /dev/null +++ b/zefie_wtvp_minisrv/ServiceVault/wtv-admin/deleteuser.js @@ -0,0 +1,118 @@ +var minisrv_service_file = true; + +var WTVAdmin = require("./WTVAdmin.js"); +var wtva = new WTVAdmin(minisrv_config, ssid_sessions[socket.ssid], service_name); +var auth = wtva.isAuthorized(); +if (auth === true) { + var password = null; + if (request_headers.Authorization) { + var authheader = request_headers.Authorization.split(' '); + if (authheader[0] == "Basic") { + password = Buffer.from(authheader[1], 'base64').toString(); + if (password) password = password.split(':')[1]; + } + } + if (wtva.checkPassword(password)) { + if (request_headers.query.username) { + var show_cannot_modify_self = false; + var show_cannot_remove_primary = false; + var show_box_was_unregistered = false; + var user_info = wtva.getAccountInfo(request_headers.query.username.toLowerCase()); // username search + if (user_info) { + if (user_info.ssid == socket.ssid) { + show_cannot_modify_self = true; + } + if (request_headers.query.confirm_delete) { + if (!show_cannot_modify_self) { + // delete + var userAccount = wtva.getAccountBySSID(user_info.ssid); + userAccount.switchUserID(0, false, false); + var userCount = Object.keys(user_info.account_users).length; + if (user_info.user_id === 0) { + show_cannot_remove_primary = true; + } else { + var result = userAccount.removeUser(user_info.user_id); + } + } + } + } + } + headers = `200 OK +Content-Type: text/html +wtv-expire-all: wtv-admin:/deleteuser +wtv-noback-all: wtv-admin:/deleteuser`; + data = ` + + +${minisrv_config.config.service_name} Admin Tricks + + + + +
+
+

${minisrv_config.config.service_name} Admin Tricks

+
+ + + +
+

Delete a user from an account

+
+   +


` + if (request_headers.query.username) { + if (user_info && !request_headers.query.confirm_delete) { + data += ` +User Information: + + +`; + if (user_info.account_users) { + data += ``; + } + data += ` + + + +` + data += `
Username:${user_info.username} (User ID: ${user_info.user_id})
SSID:${user_info.ssid}
Primary User:${user_info.account_users['subscriber'].subscriber_username}
+
+ + + +
+
`; + } else if (request_headers.query.confirm_delete && show_cannot_modify_self) { + data += `Cannot modify your account in this manner.
Try wtv-setup.


`; + } else if (request_headers.query.confirm_delete && show_cannot_remove_primary) { + data += `Cannot delete a primary user in this manner.
Try deleting the account.

`; + } else if (request_headers.query.confirm_delete && show_box_was_unregistered) { + data += `Account for "${user_info.username}" was deleted, and SSID ${user_info.ssid} unregistered, as it was the only user.

`; + } else if (request_headers.query.confirm_delete) { + if (result) data += `User "${user_info.username}" has been deleted from account belonging to SSID ${user_info.ssid}.

`; + else data += `Could not delete "${user_info.username}" from SSID ${user_info.ssid}.

`; + } else { + data += "Could not find an account for user \"" + request_headers.query.username + "\"

"; + } + } + data += ` +
+
+
+

+Go Back +

+ + +`; + } else { + var errpage = wtvshared.doErrorPage(401, "Please enter the administration password, you can leave the username blank."); + headers = errpage[0]; + data = errpage[1]; + } +} else { + var errpage = wtvshared.doErrorPage(403, auth); + headers = errpage[0]; + data = errpage[1]; +} \ No newline at end of file diff --git a/zefie_wtvp_minisrv/ServiceVault/wtv-admin/findaccount.js b/zefie_wtvp_minisrv/ServiceVault/wtv-admin/findaccount.js new file mode 100644 index 00000000..d2518f59 --- /dev/null +++ b/zefie_wtvp_minisrv/ServiceVault/wtv-admin/findaccount.js @@ -0,0 +1,97 @@ +var minisrv_service_file = true; + +var WTVAdmin = require("./WTVAdmin.js"); +var wtva = new WTVAdmin(minisrv_config, ssid_sessions[socket.ssid], service_name); +var auth = wtva.isAuthorized(); +if (auth === true) { + var password = null; + if (request_headers.Authorization) { + var authheader = request_headers.Authorization.split(' '); + if (authheader[0] == "Basic") { + password = Buffer.from(authheader[1], 'base64').toString(); + if (password) password = password.split(':')[1]; + } + } + if (wtva.checkPassword(password)) { + if (request_headers.query.username) { + var user_info = wtva.getAccountInfo(request_headers.query.username.toLowerCase()); // username search + if (!user_info) user_info = wtva.getAccountInfoBySSID(request_headers.query.username.toLowerCase()); // ssid search + } + headers = `200 OK +Content-Type: text/html +wtv-expire-all: wtv-admin:/findaccount +wtv-noback-all: wtv-admin:/findaccount`; + data = ` + + +${minisrv_config.config.service_name} Admin Tricks + + + + +
+
+

${minisrv_config.config.service_name} Admin Tricks

+
+ + + +
+

Account Lookup

+
+   +


` + if (request_headers.query.username) { + if (user_info) { + data += ` +User Information: + + +`; + if (user_info.account_users) { + data += ``; + if (Object.keys(user_info.account_users).length > 1) { + data += `` + } + } + data += ` + + + +` + data += `
Username:${user_info.username} (User ID: ${user_info.user_id})
SSID:${user_info.ssid}
Primary User:${user_info.account_users['subscriber'].subscriber_username}
Additional Users:`; + Object.keys(user_info.account_users).forEach(function (k) { + if (k == "subscriber") return; + data += user_info.account_users[k].subscriber_username + "
"; + }) + data += `
+Ban SSID +           +Unban SSID +           +Delete Account +
`; + } else { + data += "Could not find user \"" + request_headers.query.username + "\"

"; + } + } + data += ` +
+
+
+

+Go Back +

+ + +`; + } else { + var errpage = wtvshared.doErrorPage(401, "Please enter the administration password, you can leave the username blank."); + headers = errpage[0]; + data = errpage[1]; + } +} else { + var errpage = wtvshared.doErrorPage(403, auth); + headers = errpage[0]; + data = errpage[1]; +} \ No newline at end of file diff --git a/zefie_wtvp_minisrv/ServiceVault/wtv-admin/images/nuke.gif b/zefie_wtvp_minisrv/ServiceVault/wtv-admin/images/nuke.gif new file mode 100644 index 00000000..f1928032 Binary files /dev/null and b/zefie_wtvp_minisrv/ServiceVault/wtv-admin/images/nuke.gif differ diff --git a/zefie_wtvp_minisrv/ServiceVault/wtv-admin/images/nuke_inverted.gif b/zefie_wtvp_minisrv/ServiceVault/wtv-admin/images/nuke_inverted.gif new file mode 100644 index 00000000..a52ecdf2 Binary files /dev/null and b/zefie_wtvp_minisrv/ServiceVault/wtv-admin/images/nuke_inverted.gif differ diff --git a/zefie_wtvp_minisrv/ServiceVault/wtv-admin/unban.js b/zefie_wtvp_minisrv/ServiceVault/wtv-admin/unban.js new file mode 100644 index 00000000..d2e06283 --- /dev/null +++ b/zefie_wtvp_minisrv/ServiceVault/wtv-admin/unban.js @@ -0,0 +1,104 @@ +var minisrv_service_file = true; + +var WTVAdmin = require("./WTVAdmin.js"); +var wtva = new WTVAdmin(minisrv_config, ssid_sessions[socket.ssid], service_name); +var auth = wtva.isAuthorized(); +var ssids_removed = []; +if (auth === true) { + var password = null; + if (request_headers.Authorization) { + var authheader = request_headers.Authorization.split(' '); + if (authheader[0] == "Basic") { + password = Buffer.from(authheader[1], 'base64').toString(); + if (password) password = password.split(':')[1]; + } + } + if (wtva.checkPassword(password)) { + if (request_headers.query.unban_ssid) { + var config_changed = false; + var fake_config = wtvshared.getUserConfig(); + if (!fake_config.config) fake_config.config = {}; + if (!fake_config.config.ssid_block_list) fake_config.config.ssid_block_list = []; + if (typeof request_headers.query.unban_ssid === 'string') { + Object.keys(fake_config.config.ssid_block_list).forEach(function (k) { + if (fake_config.config.ssid_block_list[k] == request_headers.query.unban_ssid) { + fake_config.config.ssid_block_list.splice(k, 1); + ssids_removed.push(request_headers.query.unban_ssid) + config_changed = true; + } + }); + } else { + Object.keys(fake_config.config.ssid_block_list).forEach(function (k) { + Object.keys(request_headers.query.unban_ssid).forEach(function (j) { + if (fake_config.config.ssid_block_list[k] == request_headers.query.unban_ssid[j]) { + fake_config.config.ssid_block_list.splice(k,1); + ssids_removed.push(request_headers.query.unban_ssid[j]) + config_changed = true; + } + }); + }); + } + if (config_changed) { + wtvshared.writeToUserConfig(fake_config); + minisrv_config = reloadConfig(); + } + } + headers = `200 OK +Content-Type: text/html +wtv-expire-all: wtv-admin:/unban`; + if (request_headers.query.unban_ssid) { + headers += "\nwtv-noback-all: wtv-admin:/unban"; + } + data = ` + + +${minisrv_config.config.service_name} Admin Tricks + + + + +
+
+

${minisrv_config.config.service_name} Admin Tricks

+
+ + + +
+

Unban an SSID

`; + if (minisrv_config.config.ssid_block_list.length > 0) { + data += '
'; + data += '
'; + } else { + data += "No SSIDs are in the ban list.

"; + } + if (ssids_removed.length > 0) { + if (config_changed) { + data += "SSID(s) " + ssids_removed + " removed from the ban list.

"; + } + } + data += ` +
+
+
+

+Go Back +

+ + +`; + } else { + var errpage = wtvshared.doErrorPage(401, "Please enter the administration password, you can leave the username blank."); + headers = errpage[0]; + data = errpage[1]; + } +} else { + var errpage = wtvshared.doErrorPage(403, auth); + headers = errpage[0]; + data = errpage[1]; +} \ No newline at end of file diff --git a/zefie_wtvp_minisrv/WTVAdmin.js b/zefie_wtvp_minisrv/WTVAdmin.js new file mode 100644 index 00000000..78aff4ca --- /dev/null +++ b/zefie_wtvp_minisrv/WTVAdmin.js @@ -0,0 +1,153 @@ +class WTVAdmin { + + fs = require('fs'); + path = require('path'); + minisrv_config = []; + wtvr = null; + wtvshared = null; + wtvclient = null; + WTVClientSessionData = require('./WTVClientSessionData.js'); + service_name = "wtv-admin"; + + constructor(minisrv_config, wtvclient, service_name) { + this.minisrv_config = minisrv_config; + var { WTVShared } = require('./WTVShared.js'); + var WTVRegister = require('./WTVRegister.js'); + this.wtvclient = wtvclient; + this.wtvshared = new WTVShared(minisrv_config); + this.wtvr = new WTVRegister(minisrv_config); + this.clientAddress = wtvclient.getClientAddress(); + this.service_name = service_name; + } + + + ip2long(ip) { + var components; + + if (components = ip.match(/^(\d{1,3})\.(\d{1,3})\.(\d{1,3})\.(\d{1,3})$/)) { + var iplong = 0; + var power = 1; + for (var i = 4; i >= 1; i -= 1) { + iplong += power * parseInt(components[i]); + power *= 256; + } + return iplong; + } + else return -1; + } + + isInSubnet(ip, subnet) { + var mask, base_ip, long_ip = this.ip2long(ip); + if ((mask = subnet.match(/^(.*?)\/(\d{1,2})$/)) && ((base_ip = this.ip2long(mask[1])) >= 0)) { + var freedom = Math.pow(2, 32 - parseInt(mask[2])); + return (long_ip > base_ip) && (long_ip < base_ip + freedom - 1); + } + else return false; + } + + rejectConnection(reason_is_ssid) { + var rejectReason; + if (reason_is_ssid) { + rejectReason = this.wtvclient.ssid + " is not in the whitelist."; + console.log(" * Request from SSID", this.wtvshared.filterSSID(this.wtvclient.ssid), "(" + this.clientAddress + ") for wtv-admin, but that SSID is not in the admin whitelist."); + } else { + rejectReason = this.clientAddress + " is not in the whitelist for SSID " + this.wtvclient.ssid + "."; + console.log(" * Request from SSID", this.wtvshared.filterSSID(this.wtvclient.ssid), "(" + this.clientAddress + ") for wtv-admin, but that IP is not authorized for that SSID."); + } + return rejectReason; + } + + checkPassword(password) { + if (this.minisrv_config.services[this.service_name].password) { + return (password == this.minisrv_config.services[this.service_name].password); + } else { + // no password set + return true; + } + } + + isAuthorized() { + var allowed_ssid = false; + var allowed_ip = false; + if (this.minisrv_config.services[this.service_name].authorized_ssids) { + var self = this; + Object.keys(self.minisrv_config.services[this.service_name].authorized_ssids).forEach(function (k) { + if (typeof self.minisrv_config.services[self.service_name].authorized_ssids[k] == "string") { + var ssid = self.minisrv_config.services[self.service_name].authorized_ssids[k] + if (ssid == self.wtvclient.ssid) allowed_ssid = true; + allowed_ip = true; // no ip block defined + } else { + var ssid = k; + if (ssid == self.wtvclient.ssid) { + allowed_ssid = true; + Object.keys(self.minisrv_config.services[self.service_name].authorized_ssids[k]).forEach(function (j) { + if (self.isInSubnet(self.clientAddress, self.minisrv_config.services[self.service_name].authorized_ssids[k][j])) { + allowed_ip = true; + } + }); + } + } + }); + } + return (allowed_ssid && allowed_ip) ? true : this.rejectConnection(!allowed_ssid); + } + + getAccountInfo(username, directory = null) { + var search_dir = this.minisrv_config.config.SessionStore; + var account_data = null; + var self = this; + if (directory) search_dir = directory; + this.fs.readdirSync(search_dir).forEach(file => { + if (self.fs.lstatSync(search_dir + self.path.sep + file).isDirectory() && account_data === null) { + account_data = self.getAccountInfo(username, search_dir + self.path.sep + file); + } + if (account_data !== null) return; + if (!file.match(/.*\.json/ig)) return; + try { + var temp_session_data_file = self.fs.readFileSync(search_dir + self.path.sep + file, 'Utf8'); + var temp_session_data = JSON.parse(temp_session_data_file); + + if (temp_session_data.subscriber_username.toLowerCase() == username.toLowerCase()) { + account_data = [temp_session_data, (search_dir + self.path.sep + file).replace(this.minisrv_config.config.SessionStore + this.path.sep, "").split(this.path.sep)[0]]; + } + } catch (e) { + console.error(" # Error parsing Session Data JSON", search_dir + self.path.sep + file, e); + } + }); + if (account_data !== null) { + if (account_data.ssid) return account_data; + var account_info = {}; + account_info.ssid = account_data[1]; + account_info.username = account_data[0].subscriber_username; + account_info.user_id = account_data[0].subscriber_userid; + var userSession = new this.WTVClientSessionData(this.minisrv_config, account_info.ssid); + userSession.user_id = 0; + account_info.account_users = userSession.listPrimaryAccountUsers(); + return account_info; + } + return null; + } + + getAccountInfoBySSID(ssid) { + var account_info = {}; + var userSession = new this.WTVClientSessionData(this.minisrv_config, ssid); + userSession.user_id = 0; + if (userSession.isRegistered(false)) { + account_info.ssid = ssid; + account_info.account_users = userSession.listPrimaryAccountUsers(); + account_info.username = account_info.account_users['subscriber'].subscriber_username; + account_info.user_id = 0; + return account_info; + } + else return false; + } + + + getAccountBySSID(ssid) { + var userSession = new this.WTVClientSessionData(this.minisrv_config, ssid); + userSession.user_id = 0; + return userSession; + } +} + +module.exports = WTVAdmin; diff --git a/zefie_wtvp_minisrv/WTVRegister.js b/zefie_wtvp_minisrv/WTVRegister.js index 58bd4fba..838b8dd0 100644 --- a/zefie_wtvp_minisrv/WTVRegister.js +++ b/zefie_wtvp_minisrv/WTVRegister.js @@ -3,7 +3,6 @@ class WTVRegister { fs = require('fs'); path = require('path'); minisrv_config = []; - service_owner = "a minisrv user"; session_store_dir = null; diff --git a/zefie_wtvp_minisrv/WTVShared.js b/zefie_wtvp_minisrv/WTVShared.js index b6099c85..b87c2818 100644 --- a/zefie_wtvp_minisrv/WTVShared.js +++ b/zefie_wtvp_minisrv/WTVShared.js @@ -48,7 +48,6 @@ class WTVShared { return query } - htmlEntitize(string, process_newline = false) { string = this.html_entities.encode(string).replace(/'/g, "'"); @@ -144,6 +143,27 @@ class WTVShared { return (this.isMiniBrowser(ssid_session) || parseInt(ssid_session.get("wtv-system-version")) < 3500) ? true : false; } + getUserConfig() { + try { + if (this.fs.lstatSync(__dirname + "/user_config.json")) { + try { + var minisrv_user_config = JSON.parse(this.fs.readFileSync(__dirname + this.path.sep + "user_config.json")); + } catch (e) { + console.error("ERROR: Could not read user_config.json", e); + var throw_me = true; + } + } else { + var minisrv_user_config = {} + } + return minisrv_user_config; + } catch (e) { + if (minisrv_config.config.debug_flags) { + if (minisrv_config.config.debug_flags.debug) console.error(" * Notice: Could not find user configuration (user_config.json). Using default configuration."); + } + } + } + + readMiniSrvConfig(user_config = true, notices = true) { if (notices) console.log(" *** Reading global configuration..."); try { @@ -169,21 +189,12 @@ class WTVShared { if (user_config) { try { - if (this.fs.lstatSync(__dirname + "/user_config.json")) { - if (notices) console.log(" *** Reading user configuration..."); - try { - var minisrv_user_config = JSON.parse(this.fs.readFileSync(__dirname + this.path.sep + "user_config.json")); - } catch (e) { - console.error("ERROR: Could not read user_config.json", e); - var throw_me = true; - } - // file exists and we read and parsed it, but the variable is undefined - // Likely a syntax parser error that did not trip the exception check above - try { - minisrv_config = integrateConfig(minisrv_config, minisrv_user_config) - } catch (e) { - console.error("ERROR: Could not read user_config.json", e); - } + if (notices) console.log(" *** Reading user configuration..."); + var minisrv_user_config = this.getUserConfig() + try { + minisrv_config = integrateConfig(minisrv_config, minisrv_user_config) + } catch (e) { + console.error("ERROR: Could not read user_config.json", e); } } catch (e) { if (minisrv_config.config.debug_flags) { @@ -192,7 +203,76 @@ class WTVShared { } } - return minisrv_config; + // defaults + minisrv_config.config.debug_flags = []; + minisrv_config.config.debug_flags.debug = false; + minisrv_config.config.debug_flags.quiet = true; // will squash minisrv_config.config.debug_flags.debug even if its true + minisrv_config.config.debug_flags.show_headers = false; + + if (minisrv_config.config.verbosity) { + switch (minisrv_config.config.verbosity) { + case 0: + minisrv_config.config.debug_flags.debug = false; + minisrv_config.config.debug_flags.quiet = true; + minisrv_config.config.debug_flags.show_headers = false; + if (notices) console.log(" * Console Verbosity level 0 (quietest)") + break; + case 1: + minisrv_config.config.debug_flags.debug = false; + minisrv_config.config.debug_flags.quiet = true; + minisrv_config.config.debug_flags.show_headers = true; + if (notices) console.log(" * Console Verbosity level 1 (headers shown)") + break; + case 2: + minisrv_config.config.debug_flags.debug = true; + minisrv_config.config.debug_flags.quiet = true; + minisrv_config.config.debug_flags.show_headers = false; + if (notices) console.log(" * Console Verbosity level 2 (verbose without headers)") + break; + case 3: + minisrv_config.config.debug_flags.debug = true; + minisrv_config.config.debug_flags.quiet = true; + minisrv_config.config.debug_flags.show_headers = true; + if (notices) console.log(" * Console Verbosity level 3 (verbose with headers)") + break; + default: + minisrv_config.config.debug_flags.debug = true; + minisrv_config.config.debug_flags.quiet = false; + minisrv_config.config.debug_flags.show_headers = true; + if (notices) console.log(" * Console Verbosity level 4 (debug verbosity)") + break; + } + } + + if (notices) console.log(" *** Configuration successfully read."); + this.minisrv_config = minisrv_config; + return this.minisrv_config; + } + + writeToUserConfig(config) { + if (config) { + try { + var minisrv_user_config = this.getUserConfig(); + + // write back + try { + var new_user_config = {}; + Object.assign(new_user_config, minisrv_user_config, config); + if (this.minisrv_config.config.debug_flags.debug) console.log(" * Writing new user configuration..."); + this.fs.writeFileSync(__dirname + this.path.sep + "user_config.json", JSON.stringify(new_user_config, null, "\t")); + } + catch (e) { + if (this.minisrv_config.config.debug_flags) { + if (this.minisrv_config.config.debug_flags.debug) console.error(" * WARNING: Could not update user config. Data may have been lost.", e); + } + } + + } catch (e) { + if (this.minisrv_config.config.debug_flags) { + if (this.minisrv_config.config.debug_flags.debug) console.error(" * Notice: Could not find user configuration (user_config.json). Using default configuration."); + } + } + } } getMiniSrvConfig() { diff --git a/zefie_wtvp_minisrv/app.js b/zefie_wtvp_minisrv/app.js index 9060af09..31c1def2 100644 --- a/zefie_wtvp_minisrv/app.js +++ b/zefie_wtvp_minisrv/app.js @@ -165,6 +165,7 @@ async function processPath(socket, service_vault_file_path, request_headers = ne request_is_async: request_is_async, minisrv_version_string: z_title, parseBool: parseBool, + reloadConfig: reloadConfig, cwd: __dirname // current working directory, updated below in function } @@ -1728,6 +1729,12 @@ function getGitRevision() { return null; } } +var minisrv_config = null; + +function reloadConfig() { + minisrv_config = wtvshared.readMiniSrvConfig(true, false); // snatches minisrv_config + return minisrv_config; +} // SERVER START var git_commit = getGitRevision() @@ -1736,7 +1743,7 @@ if (git_commit) console.log("**** Welcome to " + z_title + " (git " + git_commit else console.log("**** Welcome to " + z_title + " ****"); const wtvshared = new WTVShared(); // creates minisrv_config -var minisrv_config = wtvshared.getMiniSrvConfig(); // snatches minisrv_config +minisrv_config = wtvshared.getMiniSrvConfig(); // snatches minisrv_config const wtvmime = new WTVMime(minisrv_config); if (git_commit) { @@ -1832,46 +1839,6 @@ process.on('uncaughtException', function (err) { console.error((err && err.stack) ? err.stack : err); }); -// defaults -minisrv_config.config.debug_flags = []; -minisrv_config.config.debug_flags.debug = false; -minisrv_config.config.debug_flags.quiet = true; // will squash minisrv_config.config.debug_flags.debug even if its true -minisrv_config.config.debug_flags.show_headers = false; - -if (minisrv_config.config.verbosity) { - switch (minisrv_config.config.verbosity) { - case 0: - minisrv_config.config.debug_flags.debug = false; - minisrv_config.config.debug_flags.quiet = true; - minisrv_config.config.debug_flags.show_headers = false; - console.log(" * Console Verbosity level 0 (quietest)") - break; - case 1: - minisrv_config.config.debug_flags.debug = false; - minisrv_config.config.debug_flags.quiet = true; - minisrv_config.config.debug_flags.show_headers = true; - console.log(" * Console Verbosity level 1 (headers shown)") - break; - case 2: - minisrv_config.config.debug_flags.debug = true; - minisrv_config.config.debug_flags.quiet = true; - minisrv_config.config.debug_flags.show_headers = false; - console.log(" * Console Verbosity level 2 (verbose without headers)") - break; - case 3: - minisrv_config.config.debug_flags.debug = true; - minisrv_config.config.debug_flags.quiet = true; - minisrv_config.config.debug_flags.show_headers = true; - console.log(" * Console Verbosity level 3 (verbose with headers)") - break; - default: - minisrv_config.config.debug_flags.debug = true; - minisrv_config.config.debug_flags.quiet = false; - minisrv_config.config.debug_flags.show_headers = true; - console.log(" * Console Verbosity level 4 (debug verbosity)") - break; - } -} var initstring = ''; ports.sort(); diff --git a/zefie_wtvp_minisrv/config.json b/zefie_wtvp_minisrv/config.json index b29efdad..40308694 100644 --- a/zefie_wtvp_minisrv/config.json +++ b/zefie_wtvp_minisrv/config.json @@ -111,6 +111,10 @@ "port": 1608, "connections": 3 }, + "wtv-admin": { + "port": 1698, + "password": "viRak-7" + }, "http": { "port": 1650, "connections": 3, diff --git a/zefie_wtvp_minisrv/package.json b/zefie_wtvp_minisrv/package.json index c1e248ad..5e5fa6a4 100644 --- a/zefie_wtvp_minisrv/package.json +++ b/zefie_wtvp_minisrv/package.json @@ -1,6 +1,6 @@ { "name": "zefie_wtvp_minisrv", - "version": "0.9.30", + "version": "0.9.31", "description": "WebTV Service (WTVP) Emulation Server", "main": "app.js", "homepage": "https://github.com/zefie/zefie_wtvp_minisrv", diff --git a/zefie_wtvp_minisrv/user_config.example.json b/zefie_wtvp_minisrv/user_config.example.json index 8e2cccf0..9216bac5 100644 --- a/zefie_wtvp_minisrv/user_config.example.json +++ b/zefie_wtvp_minisrv/user_config.example.json @@ -35,6 +35,15 @@ "8100000000000000" ] }, + "wtv-admin": { + "authorized_ssids": { + "8100000000000000": [ + "192.168.1.0/24", + "127.0.0.1" + ] + }, + "password": "my-secure-password" + }, "wtv-log": { "write_logs_to_disk": true },