fix and optimize (except WTVIRC, it needs a lot of work)
This commit is contained in:
@@ -0,0 +1,49 @@
|
|||||||
|
{# Page list template for published pages #}
|
||||||
|
<HTML>
|
||||||
|
<HEAD>
|
||||||
|
<SCRIPT language="JavaScript">
|
||||||
|
var gIsWebTV = false;
|
||||||
|
var AppName = new String;
|
||||||
|
AppName = window.navigator.appName;
|
||||||
|
if (AppName.indexOf("WebTV") >= 0 )
|
||||||
|
gIsWebTV = true;
|
||||||
|
</SCRIPT>
|
||||||
|
<TITLE>{{ subscriber_name }}</TITLE>
|
||||||
|
</HEAD>
|
||||||
|
<body
|
||||||
|
background="/ROMCache/ExternalBackground.gif"
|
||||||
|
bgcolor=#1e4261
|
||||||
|
text=AEBFD1 link=B8BDC7
|
||||||
|
vlink=B8BDC7
|
||||||
|
hspace=0
|
||||||
|
vspace=0
|
||||||
|
>
|
||||||
|
<table cellspacing=0 cellpadding=0 width=100%>
|
||||||
|
<tr>
|
||||||
|
<td width=22 rowspan=100><td><td><td><td><td width=22 rowspan=100>
|
||||||
|
<tr>
|
||||||
|
<td height=12>
|
||||||
|
<tr>
|
||||||
|
<td height=25 valign=top colspan=4>
|
||||||
|
<font size=+1 color=D1D1D1>Pages of {{ subscriber_name }}</font>
|
||||||
|
<tr>
|
||||||
|
<td height=14>
|
||||||
|
<tr><td height=10>
|
||||||
|
{% for page in published_pages %}
|
||||||
|
<tr><td>
|
||||||
|
<td width=5>
|
||||||
|
<td>
|
||||||
|
<table>
|
||||||
|
<tr><td colspan=2><font color=AEBFD1><B>
|
||||||
|
<a href="{{ page.publishname }}/index.html">{{ page.title }}</a>
|
||||||
|
</B></font>
|
||||||
|
<tr>
|
||||||
|
<td width=12>
|
||||||
|
<td><font size=-1>{{ page.description }}</font>
|
||||||
|
</table>
|
||||||
|
<tr><td height=10>
|
||||||
|
<tr><td height=10>
|
||||||
|
{% endfor %}
|
||||||
|
</table>
|
||||||
|
</BODY>
|
||||||
|
</HTML>
|
||||||
@@ -12,7 +12,7 @@ exports.createServer = (opts, handler) => {
|
|||||||
socket.pause();
|
socket.pause();
|
||||||
|
|
||||||
// Determine if this is an HTTP(s) request
|
// Determine if this is an HTTP(s) request
|
||||||
let byte = buffer[0];
|
const byte = buffer[0];
|
||||||
|
|
||||||
let protocol;
|
let protocol;
|
||||||
if (byte === 22) {
|
if (byte === 22) {
|
||||||
@@ -21,7 +21,7 @@ exports.createServer = (opts, handler) => {
|
|||||||
protocol = 'http';
|
protocol = 'http';
|
||||||
}
|
}
|
||||||
|
|
||||||
let proxy = server[protocol];
|
const proxy = server[protocol];
|
||||||
if (proxy) {
|
if (proxy) {
|
||||||
// Push the buffer back onto the front of the data stream
|
// Push the buffer back onto the front of the data stream
|
||||||
socket.unshift(buffer);
|
socket.unshift(buffer);
|
||||||
|
|||||||
@@ -34,7 +34,7 @@ class LZSS {
|
|||||||
}
|
}
|
||||||
|
|
||||||
insertNode(i) {
|
insertNode(i) {
|
||||||
let keyi = this.ring_buffer[i];
|
const keyi = this.ring_buffer[i];
|
||||||
let keyii = this.ring_buffer[i + 1] ^ this.ring_buffer[i + 2];
|
let keyii = this.ring_buffer[i + 1] ^ this.ring_buffer[i + 2];
|
||||||
keyii = ((keyii ^ (keyii >> 4)) & 0x0F) << 8;
|
keyii = ((keyii ^ (keyii >> 4)) & 0x0F) << 8;
|
||||||
|
|
||||||
@@ -129,7 +129,7 @@ class LZSS {
|
|||||||
this.parent[this.rchild[i]] = ii;
|
this.parent[this.rchild[i]] = ii;
|
||||||
}
|
}
|
||||||
this.parent[ii] = this.parent[i];
|
this.parent[ii] = this.parent[i];
|
||||||
let parent_link = this.parent[i];
|
const parent_link = this.parent[i];
|
||||||
if (this.rchild[parent_link] !== i) {
|
if (this.rchild[parent_link] !== i) {
|
||||||
this.lchild[parent_link] = ii;
|
this.lchild[parent_link] = ii;
|
||||||
} else {
|
} else {
|
||||||
|
|||||||
@@ -4,8 +4,8 @@ const prototypes = {
|
|||||||
return this.split("").reverse().join("");
|
return this.split("").reverse().join("");
|
||||||
},
|
},
|
||||||
toHexString: function () {
|
toHexString: function () {
|
||||||
var result = '';
|
let result = '';
|
||||||
for (var i = 0; i < this.length; i++) {
|
for (let i = 0; i < this.length; i++) {
|
||||||
result += this.charCodeAt(i).toString(16);
|
result += this.charCodeAt(i).toString(16);
|
||||||
}
|
}
|
||||||
return result;
|
return result;
|
||||||
@@ -13,7 +13,7 @@ const prototypes = {
|
|||||||
},
|
},
|
||||||
Array: {
|
Array: {
|
||||||
replace: function(sub, newSub) {
|
replace: function(sub, newSub) {
|
||||||
splits = this.split(sub, 2);
|
const splits = this.split(sub, 2);
|
||||||
return Array.concat(splits[0], newSub, splits[1])
|
return Array.concat(splits[0], newSub, splits[1])
|
||||||
},
|
},
|
||||||
moveKey: function (from, to) {
|
moveKey: function (from, to) {
|
||||||
|
|||||||
@@ -28,8 +28,8 @@ class WTVAdmin {
|
|||||||
*/
|
*/
|
||||||
constructor(minisrv_config, wtvclient, service_name) {
|
constructor(minisrv_config, wtvclient, service_name) {
|
||||||
this.minisrv_config = minisrv_config;
|
this.minisrv_config = minisrv_config;
|
||||||
var { WTVShared } = require("./WTVShared.js");
|
const { WTVShared } = require("./WTVShared.js");
|
||||||
var WTVRegister = require("./WTVRegister.js");
|
const WTVRegister = require("./WTVRegister.js");
|
||||||
this.wtvclient = wtvclient;
|
this.wtvclient = wtvclient;
|
||||||
this.wtvshared = new WTVShared(minisrv_config);
|
this.wtvshared = new WTVShared(minisrv_config);
|
||||||
this.wtvr = new WTVRegister(minisrv_config);
|
this.wtvr = new WTVRegister(minisrv_config);
|
||||||
@@ -54,13 +54,14 @@ class WTVAdmin {
|
|||||||
if (ssid == admin_ssid) {
|
if (ssid == admin_ssid) {
|
||||||
return this.REASON_NOSELF;
|
return this.REASON_NOSELF;
|
||||||
} else {
|
} else {
|
||||||
var fake_config = this.wtvshared.getUserConfig();
|
const fake_config = this.wtvshared.getUserConfig();
|
||||||
if (!fake_config.config) fake_config.config = {};
|
if (!fake_config.config) fake_config.config = {};
|
||||||
if (!fake_config.config.ssid_block_list) fake_config.config.ssid_block_list = [];
|
if (!fake_config.config.ssid_block_list) fake_config.config.ssid_block_list = [];
|
||||||
var entry_exists = false;
|
let entry_exists = false;
|
||||||
var self = this;
|
const self = this;
|
||||||
Object.keys(fake_config.config.ssid_block_list).forEach(function (k) {
|
Object.keys(fake_config.config.ssid_block_list).forEach(function (k) {
|
||||||
if (fake_config.config.ssid_block_list[k] == ssid) {
|
if (fake_config.config.ssid_block_list[k] == ssid) {
|
||||||
|
entry_exists = true;
|
||||||
return self.REASON_EXISTS;
|
return self.REASON_EXISTS;
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
@@ -78,8 +79,8 @@ class WTVAdmin {
|
|||||||
* @returns {number} The result of the unban operation
|
* @returns {number} The result of the unban operation
|
||||||
*/
|
*/
|
||||||
unbanSSID(ssid) {
|
unbanSSID(ssid) {
|
||||||
var config_changed = false;
|
let config_changed = false;
|
||||||
var fake_config = this.wtvshared.getUserConfig();
|
const fake_config = this.wtvshared.getUserConfig();
|
||||||
if (!fake_config.config) fake_config.config = {};
|
if (!fake_config.config) fake_config.config = {};
|
||||||
if (!fake_config.config.ssid_block_list) fake_config.config.ssid_block_list = [];
|
if (!fake_config.config.ssid_block_list) fake_config.config.ssid_block_list = [];
|
||||||
if (typeof ssid === 'string') {
|
if (typeof ssid === 'string') {
|
||||||
@@ -100,8 +101,8 @@ class WTVAdmin {
|
|||||||
});
|
});
|
||||||
}
|
}
|
||||||
if (config_changed) {
|
if (config_changed) {
|
||||||
wtvshared.writeToUserConfig(fake_config);
|
this.wtvshared.writeToUserConfig(fake_config);
|
||||||
minisrv_config = reloadConfig();
|
//this.minisrv_config = reloadConfig();
|
||||||
return this.SUCCESS
|
return this.SUCCESS
|
||||||
} else {
|
} else {
|
||||||
return this.REASON_NONEXIST;
|
return this.REASON_NONEXIST;
|
||||||
@@ -114,7 +115,7 @@ class WTVAdmin {
|
|||||||
* @returns {string} The reason for rejecting the connection
|
* @returns {string} The reason for rejecting the connection
|
||||||
*/
|
*/
|
||||||
rejectConnection(reason_is_ssid) {
|
rejectConnection(reason_is_ssid) {
|
||||||
var rejectReason;
|
let rejectReason;
|
||||||
if (this.pcservices) {
|
if (this.pcservices) {
|
||||||
rejectReason = this.clientAddress + " is not in the whitelist for PC Services Admin.";
|
rejectReason = this.clientAddress + " is not in the whitelist for PC Services Admin.";
|
||||||
console.log(" * Request from IP (" + this.clientAddress + ") for PC Services Admin, but that IP is not authorized.");
|
console.log(" * Request from IP (" + this.clientAddress + ") for PC Services Admin, but that IP is not authorized.");
|
||||||
@@ -158,12 +159,12 @@ class WTVAdmin {
|
|||||||
* @returns {Array} An array of arrays, each containing the SSID and its associated account information
|
* @returns {Array} An array of arrays, each containing the SSID and its associated account information
|
||||||
*/
|
*/
|
||||||
listRegisteredSSIDs() {
|
listRegisteredSSIDs() {
|
||||||
var search_dir = this.wtvshared.getAbsolutePath(this.minisrv_config.config.SessionStore + this.path.sep + "accounts");
|
const search_dir = this.wtvshared.getAbsolutePath(this.minisrv_config.config.SessionStore + this.path.sep + "accounts");
|
||||||
var self = this;
|
const self = this;
|
||||||
var out = [];
|
const out = [];
|
||||||
this.fs.readdirSync(search_dir).forEach(file => {
|
this.fs.readdirSync(search_dir).forEach(file => {
|
||||||
if (self.fs.lstatSync(search_dir + self.path.sep + file).isDirectory()) {
|
if (self.fs.lstatSync(search_dir + self.path.sep + file).isDirectory()) {
|
||||||
var user = self.getAccountInfoBySSID(file);
|
const user = self.getAccountInfoBySSID(file);
|
||||||
out.push([file, user]);
|
out.push([file, user]);
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
@@ -176,19 +177,19 @@ class WTVAdmin {
|
|||||||
* @return {boolean} True if authorized, false otherwise
|
* @return {boolean} True if authorized, false otherwise
|
||||||
*/
|
*/
|
||||||
isAuthorized(justchecking = false) {
|
isAuthorized(justchecking = false) {
|
||||||
var allowed_ssid = false;
|
let allowed_ssid = false;
|
||||||
var allowed_ip = false;
|
let allowed_ip = false;
|
||||||
var use_ssid = (this.wtvclient.ssid && !this.pcservices) ? true : false
|
const use_ssid = (this.wtvclient.ssid && !this.pcservices) ? true : false
|
||||||
if (use_ssid) {
|
if (use_ssid) {
|
||||||
if (this.minisrv_config.services[this.service_name].authorized_ssids) {
|
if (this.minisrv_config.services[this.service_name].authorized_ssids) {
|
||||||
var self = this;
|
const self = this;
|
||||||
Object.keys(self.minisrv_config.services[this.service_name].authorized_ssids).forEach(function (k) {
|
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") {
|
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]
|
const ssid = self.minisrv_config.services[self.service_name].authorized_ssids[k]
|
||||||
if (ssid == self.wtvclient.ssid) allowed_ssid = true;
|
if (ssid == self.wtvclient.ssid) allowed_ssid = true;
|
||||||
allowed_ip = true; // no ip block defined
|
allowed_ip = true; // no ip block defined
|
||||||
} else {
|
} else {
|
||||||
var ssid = k;
|
const ssid = k;
|
||||||
if (ssid == self.wtvclient.ssid) {
|
if (ssid == self.wtvclient.ssid) {
|
||||||
allowed_ssid = true;
|
allowed_ssid = true;
|
||||||
Object.keys(self.minisrv_config.services[self.service_name].authorized_ssids[k]).forEach(function (j) {
|
Object.keys(self.minisrv_config.services[self.service_name].authorized_ssids[k]).forEach(function (j) {
|
||||||
@@ -209,7 +210,7 @@ class WTVAdmin {
|
|||||||
}
|
}
|
||||||
|
|
||||||
if (this.minisrv_config.config.pc_admin.ip_whitelist) {
|
if (this.minisrv_config.config.pc_admin.ip_whitelist) {
|
||||||
var self = this;
|
const self = this;
|
||||||
Object.keys(this.minisrv_config.config.pc_admin.ip_whitelist).forEach(function (k) {
|
Object.keys(this.minisrv_config.config.pc_admin.ip_whitelist).forEach(function (k) {
|
||||||
if (allowed_ip) return;
|
if (allowed_ip) return;
|
||||||
allowed_ip = self.wtvshared.isInSubnet(self.clientAddress, self.minisrv_config.config.pc_admin.ip_whitelist[k]);
|
allowed_ip = self.wtvshared.isInSubnet(self.clientAddress, self.minisrv_config.config.pc_admin.ip_whitelist[k]);
|
||||||
@@ -232,9 +233,9 @@ class WTVAdmin {
|
|||||||
* @returns {Object|null} An object containing account information if the username is found, null otherwise
|
* @returns {Object|null} An object containing account information if the username is found, null otherwise
|
||||||
*/
|
*/
|
||||||
getAccountInfo(username, directory = null) {
|
getAccountInfo(username, directory = null) {
|
||||||
var search_dir = this.wtvshared.getAbsolutePath(this.minisrv_config.config.SessionStore + this.path.sep + "accounts");
|
let search_dir = this.wtvshared.getAbsolutePath(this.minisrv_config.config.SessionStore + this.path.sep + "accounts");
|
||||||
var account_data = null;
|
let account_data = null;
|
||||||
var self = this;
|
const self = this;
|
||||||
if (directory) search_dir = directory;
|
if (directory) search_dir = directory;
|
||||||
this.fs.readdirSync(search_dir).forEach(file => {
|
this.fs.readdirSync(search_dir).forEach(file => {
|
||||||
if (self.fs.lstatSync(search_dir + self.path.sep + file).isDirectory() && account_data === null) {
|
if (self.fs.lstatSync(search_dir + self.path.sep + file).isDirectory() && account_data === null) {
|
||||||
@@ -243,8 +244,8 @@ class WTVAdmin {
|
|||||||
if (account_data !== null) return;
|
if (account_data !== null) return;
|
||||||
if (!file.match(/.*\.json/ig)) return;
|
if (!file.match(/.*\.json/ig)) return;
|
||||||
try {
|
try {
|
||||||
var temp_session_data_file = self.fs.readFileSync(search_dir + self.path.sep + file, 'Utf8');
|
const temp_session_data_file = self.fs.readFileSync(search_dir + self.path.sep + file, 'Utf8');
|
||||||
var temp_session_data = JSON.parse(temp_session_data_file);
|
const temp_session_data = JSON.parse(temp_session_data_file);
|
||||||
|
|
||||||
if (temp_session_data.subscriber_username.toLowerCase() == username.toLowerCase()) {
|
if (temp_session_data.subscriber_username.toLowerCase() == username.toLowerCase()) {
|
||||||
account_data = [temp_session_data, (search_dir + self.path.sep + file).replace(this.wtvshared.getAbsolutePath(this.minisrv_config.config.SessionStore + this.path.sep + "accounts"), "").split(this.path.sep)[1]];
|
account_data = [temp_session_data, (search_dir + self.path.sep + file).replace(this.wtvshared.getAbsolutePath(this.minisrv_config.config.SessionStore + this.path.sep + "accounts"), "").split(this.path.sep)[1]];
|
||||||
@@ -255,11 +256,11 @@ class WTVAdmin {
|
|||||||
});
|
});
|
||||||
if (account_data !== null) {
|
if (account_data !== null) {
|
||||||
if (account_data.ssid) return account_data;
|
if (account_data.ssid) return account_data;
|
||||||
var account_info = {};
|
const account_info = {};
|
||||||
account_info.ssid = account_data[1];
|
account_info.ssid = account_data[1];
|
||||||
account_info.username = account_data[0].subscriber_username;
|
account_info.username = account_data[0].subscriber_username;
|
||||||
account_info.user_id = account_data[0].subscriber_userid;
|
account_info.user_id = account_data[0].subscriber_userid;
|
||||||
var userSession = new this.WTVClientSessionData(this.minisrv_config, account_info.ssid);
|
const userSession = new this.WTVClientSessionData(this.minisrv_config, account_info.ssid);
|
||||||
userSession.user_id = 0;
|
userSession.user_id = 0;
|
||||||
account_info.account_users = userSession.listPrimaryAccountUsers();
|
account_info.account_users = userSession.listPrimaryAccountUsers();
|
||||||
return account_info;
|
return account_info;
|
||||||
@@ -273,8 +274,8 @@ class WTVAdmin {
|
|||||||
* @returns {Object|boolean} An object containing account information if the SSID is registered, false otherwise
|
* @returns {Object|boolean} An object containing account information if the SSID is registered, false otherwise
|
||||||
*/
|
*/
|
||||||
getAccountInfoBySSID(ssid) {
|
getAccountInfoBySSID(ssid) {
|
||||||
var account_info = {};
|
const account_info = {};
|
||||||
var userSession = new this.WTVClientSessionData(this.minisrv_config, ssid);
|
const userSession = new this.WTVClientSessionData(this.minisrv_config, ssid);
|
||||||
userSession.user_id = 0;
|
userSession.user_id = 0;
|
||||||
if (userSession.isRegistered(false)) {
|
if (userSession.isRegistered(false)) {
|
||||||
account_info.ssid = ssid;
|
account_info.ssid = ssid;
|
||||||
@@ -301,7 +302,7 @@ class WTVAdmin {
|
|||||||
* @returns {WTVClientSessionData} The session data object for the account
|
* @returns {WTVClientSessionData} The session data object for the account
|
||||||
*/
|
*/
|
||||||
getAccountBySSID(ssid) {
|
getAccountBySSID(ssid) {
|
||||||
var userSession = new this.WTVClientSessionData(this.minisrv_config, ssid);
|
const userSession = new this.WTVClientSessionData(this.minisrv_config, ssid);
|
||||||
userSession.user_id = 0;
|
userSession.user_id = 0;
|
||||||
return userSession;
|
return userSession;
|
||||||
}
|
}
|
||||||
@@ -312,8 +313,8 @@ class WTVAdmin {
|
|||||||
* @returns {boolean} True if the SSID is banned, false otherwise
|
* @returns {boolean} True if the SSID is banned, false otherwise
|
||||||
*/
|
*/
|
||||||
isBanned(ssid) {
|
isBanned(ssid) {
|
||||||
var self = this;
|
const self = this;
|
||||||
var isBanned = false;
|
let isBanned = false;
|
||||||
if (this.minisrv_config.config.ssid_block_list) {
|
if (this.minisrv_config.config.ssid_block_list) {
|
||||||
Object.keys(this.minisrv_config.config.ssid_block_list).forEach(function (k) {
|
Object.keys(this.minisrv_config.config.ssid_block_list).forEach(function (k) {
|
||||||
if (self.minisrv_config.config.ssid_block_list[k] == ssid) {
|
if (self.minisrv_config.config.ssid_block_list[k] == ssid) {
|
||||||
|
|||||||
@@ -60,9 +60,9 @@ class WTVAuthor {
|
|||||||
pagestoreExists() {
|
pagestoreExists() {
|
||||||
if (this.pagestore_dir === null) {
|
if (this.pagestore_dir === null) {
|
||||||
// set pagestore directory local var so we don't call the function every time
|
// set pagestore directory local var so we don't call the function every time
|
||||||
var userstore_dir = this.wtvclient.getUserStoreDirectory();
|
const userstore_dir = this.wtvclient.getUserStoreDirectory();
|
||||||
// PageStore
|
// PageStore
|
||||||
var store_dir = "PageStore" + this.path.sep;
|
const store_dir = "PageStore" + this.path.sep;
|
||||||
this.pagestore_dir = userstore_dir + store_dir;
|
this.pagestore_dir = userstore_dir + store_dir;
|
||||||
}
|
}
|
||||||
return this.fs.existsSync(this.pagestore_dir);
|
return this.fs.existsSync(this.pagestore_dir);
|
||||||
@@ -79,66 +79,68 @@ class WTVAuthor {
|
|||||||
}
|
}
|
||||||
|
|
||||||
createPage(style) {
|
createPage(style) {
|
||||||
this.pagestoreExists()
|
this.pagestoreExists()
|
||||||
var pagestorepath = this.pagestore_dir;
|
let pagenum = 0;
|
||||||
// All this shit is to work around the part where I don't use UUIDs to store pages, which is bad
|
let pagefile = null;
|
||||||
var pages = this.fs.readdirSync(pagestorepath)
|
const pagestorepath = this.pagestore_dir;
|
||||||
if (pages.length == 0) {
|
// All this shit is to work around the part where I don't use UUIDs to store pages, which is bad
|
||||||
pagenum = 0;
|
const pages = this.fs.readdirSync(pagestorepath)
|
||||||
} else {
|
if (pages.length === 0) {
|
||||||
var pagelen = pages.length;
|
pagenum = 0;
|
||||||
if (pagelen < 0) pagelen = 0;
|
} else {
|
||||||
this.debug("createPage","pages",pages)
|
let pagelen = pages.length;
|
||||||
var pagenums = [];
|
if (pagelen < 0) pagelen = 0;
|
||||||
for(let i = 0; i < pagelen; i++) {
|
this.debug("createPage","pages",pages)
|
||||||
var toarr = pages[i].slice(0, pages[i].indexOf('.'));
|
let pagenums = [];
|
||||||
pagenums.push(parseInt(toarr));
|
for(let i = 0; i < pagelen; i++) {
|
||||||
}
|
const toarr = pages[i].slice(0, pages[i].indexOf('.'));
|
||||||
pagenums = pagenums.sort()
|
pagenums.push(parseInt(toarr));
|
||||||
this.debug("createPage", "pagenums", pagenums)
|
|
||||||
var pagenum = parseInt(pagenums[pagelen - 1]);
|
|
||||||
this.debug("createPage", "pagenum", pagenum)
|
|
||||||
this.debug("createPage", "pagelen", pagelen)
|
|
||||||
}
|
}
|
||||||
if (pages.length == 0) {
|
pagenums = pagenums.sort()
|
||||||
pagenum = 0
|
this.debug("createPage", "pagenums", pagenums)
|
||||||
var pagefile = pagenum + this.pageFileExt;
|
const pagenum = parseInt(pagenums[pagelen - 1]);
|
||||||
} else {
|
this.debug("createPage", "pagenum", pagenum)
|
||||||
var pagefile = (pagenum + 1) + this.pageFileExt;
|
this.debug("createPage", "pagelen", pagelen)
|
||||||
}
|
}
|
||||||
var pagefileout = this.pagestore_dir + pagefile;
|
if (pages.length == 0) {
|
||||||
// JSON data structure
|
pagenum = 0
|
||||||
var pagedata = {
|
pagefile = pagenum + this.pageFileExt;
|
||||||
"style": style,
|
} else {
|
||||||
"title": "(Untitled)",
|
pagefile = (pagenum + 1) + this.pageFileExt;
|
||||||
"description": "(no description)",
|
}
|
||||||
"pagebreaks": [],
|
const pagefileout = this.pagestore_dir + pagefile;
|
||||||
"showtitle": true,
|
// JSON data structure
|
||||||
"inlist": true,
|
const pagedata = {
|
||||||
"published": false,
|
"style": style,
|
||||||
"publishdate": null,
|
"title": "(Untitled)",
|
||||||
"publishname": null,
|
"description": "(no description)",
|
||||||
"blocks": []
|
"pagebreaks": [],
|
||||||
}
|
"showtitle": true,
|
||||||
if (this.fs.existsSync(pagefileout)) {
|
"inlist": true,
|
||||||
console.error(" * ERROR: Page already exists (should never happen). Page lost.");
|
"published": false,
|
||||||
return false;
|
"publishdate": null,
|
||||||
}
|
"publishname": null,
|
||||||
|
"blocks": []
|
||||||
|
}
|
||||||
|
if (this.fs.existsSync(pagefileout)) {
|
||||||
|
console.error(" * ERROR: Page already exists (should never happen). Page lost.");
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
// Encode page data into JSON
|
// Encode page data into JSON
|
||||||
var returnval = pages.length
|
let returnval = pages.length
|
||||||
var result = this.fs.writeFileSync(pagefileout, JSON.stringify(pagedata));
|
this.fs.writeFileSync(pagefileout, JSON.stringify(pagedata));
|
||||||
if (returnval != 0) {
|
if (returnval != 0) {
|
||||||
var npages = this.fs.readdirSync(pagestorepath)
|
const npages = this.fs.readdirSync(pagestorepath)
|
||||||
var returnval = npages.length - 1;
|
returnval = npages.length - 1;
|
||||||
}
|
}
|
||||||
return returnval;
|
return returnval;
|
||||||
}
|
}
|
||||||
|
|
||||||
loadPage(pagenum) {
|
loadPage(pagenum) {
|
||||||
this.pagestoreExists()
|
this.pagestoreExists()
|
||||||
var page_file = this.listPages();
|
const page_file = this.listPages();
|
||||||
var page_data_raw = page_file[pagenum];
|
const page_data_raw = page_file[pagenum];
|
||||||
|
|
||||||
if (page_data_raw) {
|
if (page_data_raw) {
|
||||||
return page_data_raw;
|
return page_data_raw;
|
||||||
@@ -149,13 +151,13 @@ class WTVAuthor {
|
|||||||
setStyle(style, title, desc, state, docName) {
|
setStyle(style, title, desc, state, docName) {
|
||||||
// There's probably a better way to do this involving external files for each style, but no
|
// There's probably a better way to do this involving external files for each style, but no
|
||||||
this.debug("setStyle", "this.wtvshared.makeSafeStringPath(style) (before load)", this.wtvshared.makeSafeStringPath(style));
|
this.debug("setStyle", "this.wtvshared.makeSafeStringPath(style) (before load)", this.wtvshared.makeSafeStringPath(style));
|
||||||
var template_data_file = this.wtvshared.getTemplate("wtv-author", "styles/" + this.wtvshared.makeSafeStringPath(style) + ".js", true);
|
const template_data_file = this.wtvshared.getTemplate("wtv-author", "styles/" + this.wtvshared.makeSafeStringPath(style) + ".js", true);
|
||||||
if (template_data_file) {
|
if (template_data_file) {
|
||||||
this.debug("setStyle", "template_data_file", template_data_file);
|
this.debug("setStyle", "template_data_file", template_data_file);
|
||||||
const PBTemplate = require(template_data_file);
|
const PBTemplate = require(template_data_file);
|
||||||
var pbtemplate = new PBTemplate(this, title, desc, state, docName);
|
const pbtemplate = new PBTemplate(this, title, desc, state, docName);
|
||||||
var template_data = pbtemplate.get();
|
const template_data = pbtemplate.get();
|
||||||
var self = this;
|
const self = this;
|
||||||
Object.keys(template_data).forEach((k) => {
|
Object.keys(template_data).forEach((k) => {
|
||||||
self[k] = template_data[k];
|
self[k] = template_data[k];
|
||||||
})
|
})
|
||||||
@@ -291,8 +293,8 @@ class WTVAuthor {
|
|||||||
}
|
}
|
||||||
|
|
||||||
generatePage(state, pagenum, page) {
|
generatePage(state, pagenum, page) {
|
||||||
var pagedata = this.loadPage(pagenum);
|
const pagedata = this.loadPage(pagenum);
|
||||||
var title
|
let title;
|
||||||
// Should probably have a better way to know if the page has no title
|
// Should probably have a better way to know if the page has no title
|
||||||
if (pagedata.title == "(Untitled)" && state == "editing")
|
if (pagedata.title == "(Untitled)" && state == "editing")
|
||||||
title = "<i>Choose this to add a title to your document</i>"
|
title = "<i>Choose this to add a title to your document</i>"
|
||||||
@@ -300,7 +302,7 @@ class WTVAuthor {
|
|||||||
title = pagedata.title
|
title = pagedata.title
|
||||||
// Set the page style with too many paramaters
|
// Set the page style with too many paramaters
|
||||||
this.setStyle(pagedata.style, title, pagedata.description, state, pagenum);
|
this.setStyle(pagedata.style, title, pagedata.description, state, pagenum);
|
||||||
var html = this.header
|
let html = this.header
|
||||||
if (page == 1) {
|
if (page == 1) {
|
||||||
if (pagedata.showtitle == true){
|
if (pagedata.showtitle == true){
|
||||||
html += this.titheader
|
html += this.titheader
|
||||||
@@ -310,12 +312,10 @@ class WTVAuthor {
|
|||||||
// This generates blocks on separate pages in the most neat and optimized way possible (i think, i hate past jar)
|
// This generates blocks on separate pages in the most neat and optimized way possible (i think, i hate past jar)
|
||||||
if (page != 1) {
|
if (page != 1) {
|
||||||
for (let i = pagedata.pagebreaks[page - 2]; i < (pagedata.pagebreaks[page - 1] || pagedata.blocks.length); i++) {
|
for (let i = pagedata.pagebreaks[page - 2]; i < (pagedata.pagebreaks[page - 1] || pagedata.blocks.length); i++) {
|
||||||
var type = pagedata.blocks[i].type
|
|
||||||
html += this.generateBlock(i, pagenum, state)
|
html += this.generateBlock(i, pagenum, state)
|
||||||
}
|
}
|
||||||
} else if (pagedata.pagebreaks.length != 0){
|
} else if (pagedata.pagebreaks.length != 0){
|
||||||
for (let i = 0; i < pagedata.pagebreaks[0]; i++) {
|
for (let i = 0; i < pagedata.pagebreaks[0]; i++) {
|
||||||
var type = pagedata.blocks[i].type
|
|
||||||
html += this.generateBlock(i, pagenum, state)
|
html += this.generateBlock(i, pagenum, state)
|
||||||
if (this.afterblock1 && i == 0) {
|
if (this.afterblock1 && i == 0) {
|
||||||
html += this.afterblock1
|
html += this.afterblock1
|
||||||
@@ -323,7 +323,6 @@ class WTVAuthor {
|
|||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
for (let i = 0; i < pagedata.blocks.length; i++) {
|
for (let i = 0; i < pagedata.blocks.length; i++) {
|
||||||
var type = pagedata.blocks[i].type
|
|
||||||
html += this.generateBlock(i, pagenum, state)
|
html += this.generateBlock(i, pagenum, state)
|
||||||
if (this.afterblock1 && i == 0) {
|
if (this.afterblock1 && i == 0) {
|
||||||
html += this.afterblock1
|
html += this.afterblock1
|
||||||
@@ -334,18 +333,18 @@ class WTVAuthor {
|
|||||||
// Add the footer if we're not in edit mode
|
// Add the footer if we're not in edit mode
|
||||||
html += this.getPaginationFooter(state, pagedata, page, pagenum)
|
html += this.getPaginationFooter(state, pagedata, page, pagenum)
|
||||||
html += this.footerend
|
html += this.footerend
|
||||||
return html;
|
return html;
|
||||||
}
|
}
|
||||||
|
|
||||||
editPage(pagedata, pagenum, callPublish = true) {
|
editPage(pagedata, pagenum, callPublish = true) {
|
||||||
// just stolen from favorites lmao
|
// just stolen from favorites lmao
|
||||||
var pageout = new Object();
|
const pageout = new Object();
|
||||||
var pagepath = this.pagestore_dir;
|
const pagepath = this.pagestore_dir;
|
||||||
Object.assign(pageout, pagedata);
|
Object.assign(pageout, pagedata);
|
||||||
var pagestorepath = this.pagestore_dir;
|
const pagestorepath = this.pagestore_dir;
|
||||||
var pages = this.fs.readdirSync(pagestorepath)
|
const pages = this.fs.readdirSync(pagestorepath)
|
||||||
var page = pages[pagenum]
|
const page = pages[pagenum]
|
||||||
var result = this.fs.writeFileSync(pagepath + page, JSON.stringify(pageout));
|
const result = this.fs.writeFileSync(pagepath + page, JSON.stringify(pageout));
|
||||||
if (pagedata.published == true && callPublish) {
|
if (pagedata.published == true && callPublish) {
|
||||||
this.publishPage(pagenum, pagedata.inlist, false)
|
this.publishPage(pagenum, pagedata.inlist, false)
|
||||||
}
|
}
|
||||||
@@ -353,44 +352,39 @@ class WTVAuthor {
|
|||||||
}
|
}
|
||||||
|
|
||||||
editMetadata(title, description, showtitle, pagenum) {
|
editMetadata(title, description, showtitle, pagenum) {
|
||||||
var pagedata = this.loadPage(pagenum);
|
const pagedata = this.loadPage(pagenum);
|
||||||
if (!pagedata) return false;
|
if (!pagedata) return false;
|
||||||
|
|
||||||
if (showtitle == "true")
|
pagedata.title = title;
|
||||||
var showtitle2 = false
|
pagedata.description = description;
|
||||||
else
|
pagedata.showtitle = !showtitle;
|
||||||
var showtitle2 = true
|
|
||||||
|
|
||||||
pagedata.title = title
|
|
||||||
pagedata.description = description
|
|
||||||
pagedata.showtitle = showtitle2
|
|
||||||
this.editPage(pagedata, pagenum);
|
this.editPage(pagedata, pagenum);
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
listPages() {
|
listPages() {
|
||||||
// i don't remember why, but i'm pretty sure this function sucks
|
// i don't remember why, but i'm pretty sure this function sucks
|
||||||
var pagestore = this.pagestoreExists();
|
const pagestore = this.pagestoreExists();
|
||||||
if (!pagestore) this.createPagestore();
|
if (!pagestore) this.createPagestore();
|
||||||
var userstore_dir = this.wtvclient.getUserStoreDirectory();
|
const userstore_dir = this.wtvclient.getUserStoreDirectory();
|
||||||
|
|
||||||
// PageStore
|
// PageStore
|
||||||
var store_dir = "PageStore" + this.path.sep;
|
const store_dir = "PageStore" + this.path.sep;
|
||||||
this.pagestore_dir = userstore_dir + store_dir;
|
this.pagestore_dir = userstore_dir + store_dir;
|
||||||
var pagestorepath = this.pagestore_dir;
|
const pagestorepath = this.pagestore_dir;
|
||||||
var self = this;
|
const self = this;
|
||||||
self.pageArr = [];
|
self.pageArr = [];
|
||||||
if (self.fs.existsSync(pagestorepath)) {
|
if (self.fs.existsSync(pagestorepath)) {
|
||||||
var files = this.fs.readdirSync(pagestorepath)
|
const files = this.fs.readdirSync(pagestorepath)
|
||||||
this.debug("listPages","files",files)
|
this.debug("listPages","files",files)
|
||||||
files.map(function (v) {
|
files.map(function (v) {
|
||||||
if (v.endsWith(self.pageFileExt)) {
|
if (v.endsWith(self.pageFileExt)) {
|
||||||
// oh yeah it's because any non-JSON file in pagestore will throw an error and break everything
|
// oh yeah it's because any non-JSON file in pagestore will throw an error and break everything
|
||||||
var page_data_raw = null;
|
let page_data_raw = null;
|
||||||
var pagepath = pagestorepath + self.path.sep + v;
|
const pagepath = pagestorepath + self.path.sep + v;
|
||||||
if (self.fs.existsSync(pagepath)) page_data_raw = self.fs.readFileSync(pagepath);
|
if (self.fs.existsSync(pagepath)) page_data_raw = self.fs.readFileSync(pagepath);
|
||||||
if (page_data_raw) {
|
if (page_data_raw) {
|
||||||
var page_data = JSON.parse(page_data_raw);
|
const page_data = JSON.parse(page_data_raw);
|
||||||
self.pageArr.push(page_data);
|
self.pageArr.push(page_data);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -400,12 +394,12 @@ class WTVAuthor {
|
|||||||
}
|
}
|
||||||
|
|
||||||
deleteBlock(pagenum, position) {
|
deleteBlock(pagenum, position) {
|
||||||
var pagedata = this.loadPage(pagenum);
|
const pagedata = this.loadPage(pagenum);
|
||||||
if (!pagedata) return false;
|
if (!pagedata) return false;
|
||||||
|
|
||||||
var block = pagedata.blocks[position]
|
const block = pagedata.blocks[position];
|
||||||
|
|
||||||
var blocks = pagedata.blocks
|
const blocks = pagedata.blocks;
|
||||||
blocks.splice(position, 1);
|
blocks.splice(position, 1);
|
||||||
this.editPage(pagedata, pagenum);
|
this.editPage(pagedata, pagenum);
|
||||||
if (block.type == "break")
|
if (block.type == "break")
|
||||||
@@ -418,7 +412,7 @@ class WTVAuthor {
|
|||||||
return this.minisrv_config.services['wtv-author'].public_domain;
|
return this.minisrv_config.services['wtv-author'].public_domain;
|
||||||
} else {
|
} else {
|
||||||
if (this.minisrv_config.services['wtv-author'].publish_mode == "service") {
|
if (this.minisrv_config.services['wtv-author'].publish_mode == "service") {
|
||||||
var target_service = this.minisrv_config.services[this.minisrv_config.services['wtv-author'].publish_dest];
|
const target_service = this.minisrv_config.services[this.minisrv_config.services['wtv-author'].publish_dest];
|
||||||
if (target_service) {
|
if (target_service) {
|
||||||
return target_service.host + ":" + target_service.port;
|
return target_service.host + ":" + target_service.port;
|
||||||
}
|
}
|
||||||
@@ -437,9 +431,9 @@ class WTVAuthor {
|
|||||||
}
|
}
|
||||||
|
|
||||||
getPublishDir() {
|
getPublishDir() {
|
||||||
var destDir = false;
|
let destDir = false;
|
||||||
if (this.minisrv_config.services['wtv-author'].publish_mode == "service") {
|
if (this.minisrv_config.services['wtv-author'].publish_mode == "service") {
|
||||||
var target_service = this.minisrv_config.services[this.minisrv_config.services['wtv-author'].publish_dest];
|
const target_service = this.minisrv_config.services[this.minisrv_config.services['wtv-author'].publish_dest];
|
||||||
if (target_service) {
|
if (target_service) {
|
||||||
if (!target_service.pc_services) {
|
if (!target_service.pc_services) {
|
||||||
console.error("Invalid service configuration: publish_dest is not a pc service.");
|
console.error("Invalid service configuration: publish_dest is not a pc service.");
|
||||||
@@ -451,7 +445,7 @@ class WTVAuthor {
|
|||||||
if (target_service.service_vaults) {
|
if (target_service.service_vaults) {
|
||||||
destDir = target_service.service_vaults[0] + this.path.sep + target_service.servicevault_dir + this.path.sep;
|
destDir = target_service.service_vaults[0] + this.path.sep + target_service.servicevault_dir + this.path.sep;
|
||||||
} else {
|
} else {
|
||||||
destDir = minisrv_config.config.ServiceVaults[0] + this.path.sep + target_service.servicevault_dir + this.path.sep;
|
destDir = this.minisrv_config.config.ServiceVaults[0] + this.path.sep + target_service.servicevault_dir + this.path.sep;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
} else if (this.minisrv_config.services['wtv-author'].publish_mode == "directory") {
|
} else if (this.minisrv_config.services['wtv-author'].publish_mode == "directory") {
|
||||||
@@ -465,12 +459,12 @@ class WTVAuthor {
|
|||||||
|
|
||||||
|
|
||||||
unpublishPage(pagenum) {
|
unpublishPage(pagenum) {
|
||||||
var pagedata = this.loadPage(pagenum)
|
const pagedata = this.loadPage(pagenum)
|
||||||
var destDir = this.getPublishDir();
|
const destDir = this.getPublishDir();
|
||||||
if (pagedata.published != true) {
|
if (pagedata.published != true) {
|
||||||
return "This page is not published."
|
return "This page is not published."
|
||||||
}
|
}
|
||||||
var publishname = pagedata.publishname;
|
const publishname = pagedata.publishname;
|
||||||
if (this.fs.existsSync(destDir + this.wtvclient.session_store.subscriber_username + '/' + publishname)) {
|
if (this.fs.existsSync(destDir + this.wtvclient.session_store.subscriber_username + '/' + publishname)) {
|
||||||
try {
|
try {
|
||||||
this.fs.rmSync(destDir + this.wtvclient.session_store.subscriber_username + '/' + publishname, { recursive: true })
|
this.fs.rmSync(destDir + this.wtvclient.session_store.subscriber_username + '/' + publishname, { recursive: true })
|
||||||
@@ -491,9 +485,9 @@ class WTVAuthor {
|
|||||||
publishPage(pagenum, listpublicly) {
|
publishPage(pagenum, listpublicly) {
|
||||||
// this was done in a rush and probably also sucks
|
// this was done in a rush and probably also sucks
|
||||||
// remember to increment the "hours wasted here" comment at the top of the file
|
// remember to increment the "hours wasted here" comment at the top of the file
|
||||||
var pagedata = this.loadPage(pagenum)
|
const pagedata = this.loadPage(pagenum)
|
||||||
var destDir = this.getPublishDir();
|
const destDir = this.getPublishDir();
|
||||||
var publishname = null;
|
let publishname, fileout;
|
||||||
|
|
||||||
if (pagedata.published != true) {
|
if (pagedata.published != true) {
|
||||||
publishname = pagedata.title.slice(0, 50).replaceAll(" ", "").replace(/[^A-Za-z0-9]/g, "-");
|
publishname = pagedata.title.slice(0, 50).replaceAll(" ", "").replace(/[^A-Za-z0-9]/g, "-");
|
||||||
@@ -510,11 +504,11 @@ class WTVAuthor {
|
|||||||
this.fs.mkdirSync(destDir + this.wtvclient.session_store.subscriber_username + '/' + publishname + "/clipart/styleMedia/", { recursive: true })
|
this.fs.mkdirSync(destDir + this.wtvclient.session_store.subscriber_username + '/' + publishname + "/clipart/styleMedia/", { recursive: true })
|
||||||
this.fs.mkdirSync(destDir + this.wtvclient.session_store.subscriber_username + '/' + publishname + "/media/", { recursive: true })
|
this.fs.mkdirSync(destDir + this.wtvclient.session_store.subscriber_username + '/' + publishname + "/media/", { recursive: true })
|
||||||
for (let i = 1; i < pagedata.pagebreaks.length + 2; i++) {
|
for (let i = 1; i < pagedata.pagebreaks.length + 2; i++) {
|
||||||
var pagehtml = this.generatePage("publishing", pagenum, i)
|
const pagehtml = this.generatePage("publishing", pagenum, i)
|
||||||
if (i == 1)
|
if (i == 1)
|
||||||
var fileout = "index.html"
|
fileout = "index.html"
|
||||||
else
|
else
|
||||||
var fileout = "page" + i + ".html"
|
fileout = "page" + i + ".html"
|
||||||
this.fs.writeFile(destDir + this.wtvclient.session_store.subscriber_username + '/' + publishname + '/' + fileout, pagehtml, err => {
|
this.fs.writeFile(destDir + this.wtvclient.session_store.subscriber_username + '/' + publishname + '/' + fileout, pagehtml, err => {
|
||||||
if (err) {
|
if (err) {
|
||||||
console.error(err);
|
console.error(err);
|
||||||
@@ -528,7 +522,7 @@ class WTVAuthor {
|
|||||||
if (err) throw err;
|
if (err) throw err;
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
var strftime = require('strftime');
|
const strftime = require('strftime');
|
||||||
pagedata.publishdate = strftime("%a, %b %d, %Y, %I:%M%P", new Date(new Date().toUTCString()))
|
pagedata.publishdate = strftime("%a, %b %d, %Y, %I:%M%P", new Date(new Date().toUTCString()))
|
||||||
pagedata.published = true;
|
pagedata.published = true;
|
||||||
pagedata.inlist = listpublicly;
|
pagedata.inlist = listpublicly;
|
||||||
@@ -540,66 +534,24 @@ class WTVAuthor {
|
|||||||
|
|
||||||
generatePageList() {
|
generatePageList() {
|
||||||
// this one's pretty ok i think, but it should have screenshots of each page
|
// this one's pretty ok i think, but it should have screenshots of each page
|
||||||
const pagelist = this.listPages()
|
const pagelist = this.listPages();
|
||||||
let html = `<HTML>
|
|
||||||
<HEAD>
|
// Filter published pages that should be listed
|
||||||
<SCRIPT language="JavaScript">
|
const publishedPages = pagelist.filter(page => page.published === true && page.inlist === true);
|
||||||
var gIsWebTV = false;
|
|
||||||
var AppName = new String;
|
const templatePath = this.wtvshared.getServiceDep('wtv-author/page_list.njk', true);
|
||||||
AppName = window.navigator.appName;
|
this.nunjucks.configure({ autoescape: false });
|
||||||
if (AppName.indexOf("WebTV") >= 0 )
|
|
||||||
gIsWebTV = true;
|
const html = this.nunjucks.render(templatePath, {
|
||||||
</SCRIPT>
|
subscriber_name: this.wtvclient.session_store.subscriber_name,
|
||||||
<TITLE>${this.wtvclient.session_store.subscriber_name}</TITLE>
|
published_pages: publishedPages
|
||||||
</HEAD>
|
});
|
||||||
<body
|
|
||||||
background="/ROMCache/ExternalBackground.gif"
|
|
||||||
bgcolor=#1e4261
|
|
||||||
text=AEBFD1 link=B8BDC7
|
|
||||||
vlink=B8BDC7
|
|
||||||
hspace=0
|
|
||||||
vspace=0
|
|
||||||
>
|
|
||||||
<table cellspacing=0 cellpadding=0 width=100%>
|
|
||||||
<tr>
|
|
||||||
<td width=22 rowspan=100><td><td><td><td><td width=22 rowspan=100>
|
|
||||||
<tr>
|
|
||||||
<td height=12>
|
|
||||||
<tr>
|
|
||||||
<td height=25 valign=top colspan=4>
|
|
||||||
<font size=+1 color=D1D1D1>Pages of ${this.wtvclient.session_store.subscriber_name}</font>
|
|
||||||
<tr>
|
|
||||||
<td height=14>
|
|
||||||
<tr><td height=10>`;
|
|
||||||
loop:
|
|
||||||
for (let i = 0; i < pagelist.length; i++) {
|
|
||||||
if (pagelist[i].published == true && pagelist[i].inlist == true) {
|
|
||||||
html += `<tr><td>
|
|
||||||
<td width=5>
|
|
||||||
<td>
|
|
||||||
<table>
|
|
||||||
<tr><td colspan=2><font color=AEBFD1><B>
|
|
||||||
<a href=${pagelist[i].publishname}/index.html>${pagelist[i].title}</a>
|
|
||||||
</B></font>
|
|
||||||
<tr>
|
|
||||||
<td width=12>
|
|
||||||
<td><font size=-1>${pagelist[i].description}</font>
|
|
||||||
</table>
|
|
||||||
<tr><td height=10>
|
|
||||||
<tr><td height=10>`
|
|
||||||
} else {
|
|
||||||
continue loop;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
html += `</table>
|
|
||||||
</BODY>
|
|
||||||
</HTML>`
|
|
||||||
|
|
||||||
this.fs.writeFile(this.getPublishDir() + this.wtvclient.session_store.subscriber_username + '/index.html', html, err => {
|
this.fs.writeFile(this.getPublishDir() + this.wtvclient.session_store.subscriber_username + '/index.html', html, err => {
|
||||||
if (err) {
|
if (err) {
|
||||||
console.error(err);
|
console.error(err);
|
||||||
}
|
}
|
||||||
// file written successfully
|
// file written successfully
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -628,7 +580,7 @@ vspace=0
|
|||||||
for (let i = 0; i < pagelist.length; i++) {
|
for (let i = 0; i < pagelist.length; i++) {
|
||||||
this.deletePage(i);
|
this.deletePage(i);
|
||||||
}
|
}
|
||||||
const userstore_dir = otherUser.getUserStoreDirectory();
|
const userstore_dir = this.wtvclient.getUserStoreDirectory();
|
||||||
const store_dir = "PageStore" + this.path.sep;
|
const store_dir = "PageStore" + this.path.sep;
|
||||||
this.pagestore_dir = userstore_dir + store_dir;
|
this.pagestore_dir = userstore_dir + store_dir;
|
||||||
this.wtvclient.switchUserID(0, false, false, false);
|
this.wtvclient.switchUserID(0, false, false, false);
|
||||||
@@ -663,7 +615,7 @@ vspace=0
|
|||||||
pagedata.blocks[oldposition].style = style
|
pagedata.blocks[oldposition].style = style
|
||||||
|
|
||||||
if (oldposition != position)
|
if (oldposition != position)
|
||||||
moveArrayKey(pagedata.blocks,oldposition,position);
|
this.wtvshared.moveObjectKey(pagedata.blocks,oldposition,position);
|
||||||
|
|
||||||
this.editPage(pagedata, pagenum);
|
this.editPage(pagedata, pagenum);
|
||||||
return true;
|
return true;
|
||||||
@@ -710,7 +662,7 @@ vspace=0
|
|||||||
blocks[oldposition].caption = caption
|
blocks[oldposition].caption = caption
|
||||||
|
|
||||||
if (oldposition != position) {
|
if (oldposition != position) {
|
||||||
moveArrayKey(blocks, oldposition,position);
|
this.wtvshared.moveObjectKey(blocks, oldposition,position);
|
||||||
}
|
}
|
||||||
|
|
||||||
this.editPage(pagedata, pagenum);
|
this.editPage(pagedata, pagenum);
|
||||||
@@ -746,7 +698,7 @@ vspace=0
|
|||||||
pagedata.blocks[oldposition].dividerAfter = dividerAfter
|
pagedata.blocks[oldposition].dividerAfter = dividerAfter
|
||||||
|
|
||||||
if (oldposition != position)
|
if (oldposition != position)
|
||||||
moveArrayKey(pagedata.blocks, oldposition,position);
|
this.wtvshared.moveObjectKey(pagedata.blocks, oldposition,position);
|
||||||
|
|
||||||
this.editPage(pagedata, pagenum);
|
this.editPage(pagedata, pagenum);
|
||||||
return true;
|
return true;
|
||||||
@@ -777,7 +729,7 @@ vspace=0
|
|||||||
pagedata.blocks[oldposition].items = items
|
pagedata.blocks[oldposition].items = items
|
||||||
|
|
||||||
if (oldposition != position)
|
if (oldposition != position)
|
||||||
moveArrayKey(pagedata.blocks,oldposition,position);
|
this.wtvshared.moveObjectKey(pagedata.blocks,oldposition,position);
|
||||||
|
|
||||||
this.editPage(pagedata, pagenum);
|
this.editPage(pagedata, pagenum);
|
||||||
return true;
|
return true;
|
||||||
@@ -842,7 +794,7 @@ vspace=0
|
|||||||
pagedata.blocks[oldposition].items = items
|
pagedata.blocks[oldposition].items = items
|
||||||
|
|
||||||
if (oldposition != position)
|
if (oldposition != position)
|
||||||
moveArrayKey(pagedata.blocks,oldposition,position);
|
this.wtvshared.moveObjectKey(pagedata.blocks,oldposition,position);
|
||||||
|
|
||||||
this.editPage(pagedata, pagenum);
|
this.editPage(pagedata, pagenum);
|
||||||
return true;
|
return true;
|
||||||
@@ -868,7 +820,7 @@ vspace=0
|
|||||||
if (!pagedata) return false;
|
if (!pagedata) return false;
|
||||||
|
|
||||||
if (oldposition != position)
|
if (oldposition != position)
|
||||||
moveArrayKey(pagedata.blocks,oldposition,position);
|
this.wtvshared.moveObjectKey(pagedata.blocks,oldposition,position);
|
||||||
|
|
||||||
this.editPage(pagedata, pagenum);
|
this.editPage(pagedata, pagenum);
|
||||||
this.generateBreakList(pagenum);
|
this.generateBreakList(pagenum);
|
||||||
|
|||||||
@@ -1246,18 +1246,18 @@ class WTVBGMusic {
|
|||||||
constructor(minisrv_config, session_data) {
|
constructor(minisrv_config, session_data) {
|
||||||
if (!minisrv_config) throw ("minisrv_config required");
|
if (!minisrv_config) throw ("minisrv_config required");
|
||||||
if (!session_data) throw ("WTVClientSessionData required");
|
if (!session_data) throw ("WTVClientSessionData required");
|
||||||
var WTVShared = require("./WTVShared.js")['WTVShared'];
|
const WTVShared = require("./WTVShared.js")['WTVShared'];
|
||||||
this.minisrv_config = minisrv_config;
|
this.minisrv_config = minisrv_config;
|
||||||
this.session_data = session_data;
|
this.session_data = session_data;
|
||||||
this.wtvshared = new WTVShared(minisrv_config);
|
this.wtvshared = new WTVShared(minisrv_config);
|
||||||
}
|
}
|
||||||
|
|
||||||
getMusicObj(force_default = false) {
|
getMusicObj(force_default = false) {
|
||||||
var music_obj = this.session_data.getSessionData("wtv-bgmusic");
|
let music_obj = this.session_data.getSessionData("wtv-bgmusic");
|
||||||
if (music_obj === null) music_obj = {};
|
if (music_obj === null) music_obj = {};
|
||||||
|
|
||||||
// check if we need to set defaults
|
// check if we need to set defaults
|
||||||
var setDefaults = force_default;
|
let setDefaults = force_default;
|
||||||
if (!music_obj.enableCategories) setDefaults = true;
|
if (!music_obj.enableCategories) setDefaults = true;
|
||||||
else if (music_obj.enableCategories.length == 0) setDefaults = true;
|
else if (music_obj.enableCategories.length == 0) setDefaults = true;
|
||||||
if (!music_obj.enableSongs) setDefaults = true;
|
if (!music_obj.enableSongs) setDefaults = true;
|
||||||
@@ -1317,12 +1317,13 @@ class WTVBGMusic {
|
|||||||
}
|
}
|
||||||
|
|
||||||
getSong(songid) {
|
getSong(songid) {
|
||||||
|
let musiclist;
|
||||||
if (this.session_data.hasCap("client-can-do-rmf")) {
|
if (this.session_data.hasCap("client-can-do-rmf")) {
|
||||||
// use rmf list
|
// use rmf list
|
||||||
var musiclist = this.musiclist_rmf;
|
musiclist = this.musiclist_rmf;
|
||||||
} else {
|
} else {
|
||||||
// use classic list
|
// use classic list
|
||||||
var musiclist = this.musiclist_classic;
|
musiclist = this.musiclist_classic;
|
||||||
}
|
}
|
||||||
if (musiclist[songid]) return musiclist[songid];
|
if (musiclist[songid]) return musiclist[songid];
|
||||||
return null;
|
return null;
|
||||||
@@ -1341,14 +1342,15 @@ class WTVBGMusic {
|
|||||||
|
|
||||||
|
|
||||||
getCategorySongList(category) {
|
getCategorySongList(category) {
|
||||||
|
let musiclist;
|
||||||
if (this.session_data.hasCap("client-can-do-rmf")) {
|
if (this.session_data.hasCap("client-can-do-rmf")) {
|
||||||
// use rmf list
|
// use rmf list
|
||||||
var musiclist = this.musiclist_rmf;
|
musiclist = this.musiclist_rmf;
|
||||||
} else {
|
} else {
|
||||||
// use classic list
|
// use classic list
|
||||||
var musiclist = this.musiclist_classic;
|
musiclist = this.musiclist_classic;
|
||||||
}
|
}
|
||||||
var songList = [];
|
const songList = [];
|
||||||
Object.keys(musiclist).forEach(function (k) {
|
Object.keys(musiclist).forEach(function (k) {
|
||||||
musiclist[k].id = k;
|
musiclist[k].id = k;
|
||||||
if (String(category).length === 1) {
|
if (String(category).length === 1) {
|
||||||
@@ -1363,10 +1365,10 @@ class WTVBGMusic {
|
|||||||
}
|
}
|
||||||
|
|
||||||
getCategoryList() {
|
getCategoryList() {
|
||||||
var enabledCategories = [];
|
const enabledCategories = [];
|
||||||
var self = this;
|
const self = this;
|
||||||
Object.keys(self.categories).forEach(function (k) {
|
Object.keys(self.categories).forEach(function (k) {
|
||||||
var songList = self.getCategorySongList(parseInt(k) + 1);
|
const songList = self.getCategorySongList(parseInt(k) + 1);
|
||||||
if (songList.length > 0) enabledCategories.push({
|
if (songList.length > 0) enabledCategories.push({
|
||||||
"id": parseInt(k) + 1, "name": self.categories[k]
|
"id": parseInt(k) + 1, "name": self.categories[k]
|
||||||
});
|
});
|
||||||
@@ -1380,8 +1382,8 @@ class WTVBGMusic {
|
|||||||
}
|
}
|
||||||
|
|
||||||
isCategoryEnabled(category) {
|
isCategoryEnabled(category) {
|
||||||
var music_obj = this.getMusicObj();
|
const music_obj = this.getMusicObj();
|
||||||
var enabled = false;
|
let enabled = false;
|
||||||
music_obj.enableCategories.forEach(function (v) {
|
music_obj.enableCategories.forEach(function (v) {
|
||||||
if (parseInt(v) == parseInt(category)) {
|
if (parseInt(v) == parseInt(category)) {
|
||||||
enabled = true;
|
enabled = true;
|
||||||
@@ -1391,13 +1393,13 @@ class WTVBGMusic {
|
|||||||
}
|
}
|
||||||
|
|
||||||
isSongEnabled(song, checkCat = false) {
|
isSongEnabled(song, checkCat = false) {
|
||||||
var music_obj = this.getMusicObj();
|
const music_obj = this.getMusicObj();
|
||||||
var enabled = false;
|
let enabled = false;
|
||||||
music_obj.enableSongs.forEach(function (v) {
|
music_obj.enableSongs.forEach(function (v) {
|
||||||
if (parseInt(v) == parseInt(song)) {
|
if (parseInt(v) == parseInt(song)) {
|
||||||
if (checkCat) {
|
if (checkCat) {
|
||||||
songCategory = getSongCategory(song);
|
const songCategory = this.getSongCategory(song);
|
||||||
if (isCategoryEnabled(songCategory)) {
|
if (this.isCategoryEnabled(songCategory)) {
|
||||||
enabled = true;
|
enabled = true;
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
|
|||||||
@@ -20,7 +20,7 @@ class WTVClientCapabilities {
|
|||||||
// (this script does not do that, also note that LC2 MiniBrowser does not support client:relog)
|
// (this script does not do that, also note that LC2 MiniBrowser does not support client:relog)
|
||||||
// None of this is 100% for certain yet (except the bitfield stuff), do not trust as verbatim, more testing needed
|
// None of this is 100% for certain yet (except the bitfield stuff), do not trust as verbatim, more testing needed
|
||||||
|
|
||||||
var capabilities_table = [
|
const capabilities_table = [
|
||||||
["client-can-do-muzac", "Can Do Muzac"],
|
["client-can-do-muzac", "Can Do Muzac"],
|
||||||
["client-can-do-chat", "Can Chat"],
|
["client-can-do-chat", "Can Chat"],
|
||||||
["client-can-do-openISP", "Can do OpenISP"],
|
["client-can-do-openISP", "Can do OpenISP"],
|
||||||
@@ -97,7 +97,7 @@ class WTVClientCapabilities {
|
|||||||
let remainingSize = hex.length;
|
let remainingSize = hex.length;
|
||||||
for (let p = 0; p < hex.length / 8; p++) {
|
for (let p = 0; p < hex.length / 8; p++) {
|
||||||
//In case remaining hex length (or initial) is not multiple of 8
|
//In case remaining hex length (or initial) is not multiple of 8
|
||||||
let blockSize = remainingSize < 8 ? remainingSize : 8;
|
const blockSize = remainingSize < 8 ? remainingSize : 8;
|
||||||
|
|
||||||
binary += parseInt(hex.slice(p * 8, p * 8 + blockSize), 16).toString(2);
|
binary += parseInt(hex.slice(p * 8, p * 8 + blockSize), 16).toString(2);
|
||||||
|
|
||||||
|
|||||||
@@ -158,7 +158,7 @@ class WTVClientSessionData {
|
|||||||
|
|
||||||
findFreeUserSlot() {
|
findFreeUserSlot() {
|
||||||
if (this.user_id != 0) return false; // subscriber only command
|
if (this.user_id != 0) return false; // subscriber only command
|
||||||
let master_directory = this.getUserStoreDirectory(true);
|
const master_directory = this.getUserStoreDirectory(true);
|
||||||
if (this.fs.existsSync(master_directory)) {
|
if (this.fs.existsSync(master_directory)) {
|
||||||
for (let i = 0; i < this.minisrv_config.config.user_accounts.max_users_per_account; i++) {
|
for (let i = 0; i < this.minisrv_config.config.user_accounts.max_users_per_account; i++) {
|
||||||
const test_dir = master_directory + this.path.sep + "user" + i;
|
const test_dir = master_directory + this.path.sep + "user" + i;
|
||||||
@@ -184,7 +184,7 @@ class WTVClientSessionData {
|
|||||||
if (this.user_id != 0) return false; // subscriber only command
|
if (this.user_id != 0) return false; // subscriber only command
|
||||||
|
|
||||||
const master_directory = this.getUserStoreDirectory(true);
|
const master_directory = this.getUserStoreDirectory(true);
|
||||||
let account_data = [];
|
const account_data = [];
|
||||||
const self = this;
|
const self = this;
|
||||||
this.fs.readdirSync(master_directory).forEach(f => {
|
this.fs.readdirSync(master_directory).forEach(f => {
|
||||||
if (self.fs.lstatSync(master_directory + self.path.sep + f).isDirectory()) {
|
if (self.fs.lstatSync(master_directory + self.path.sep + f).isDirectory()) {
|
||||||
@@ -339,7 +339,7 @@ class WTVClientSessionData {
|
|||||||
if (!file_exists || (file_exists && overwrite)) result = this.fs.writeFileSync(store_full_path, data);
|
if (!file_exists || (file_exists && overwrite)) result = this.fs.writeFileSync(store_full_path, data);
|
||||||
if (result !== false && last_modified) {
|
if (result !== false && last_modified) {
|
||||||
const file_timestamp = new Date(last_modified * 1000);
|
const file_timestamp = new Date(last_modified * 1000);
|
||||||
fs.utimesSync(store_full_path, Date.now(), file_timestamp)
|
this.fs.utimesSync(store_full_path, Date.now(), file_timestamp)
|
||||||
}
|
}
|
||||||
} catch (e) {
|
} catch (e) {
|
||||||
console.error(" # User File Store failed", e);
|
console.error(" # User File Store failed", e);
|
||||||
@@ -408,7 +408,7 @@ class WTVClientSessionData {
|
|||||||
this.createScrapbook();
|
this.createScrapbook();
|
||||||
}
|
}
|
||||||
let total_size = 0;
|
let total_size = 0;
|
||||||
let files = this.fs.readdirSync(this.scrapbook_dir);
|
const files = this.fs.readdirSync(this.scrapbook_dir);
|
||||||
files.forEach(file => {
|
files.forEach(file => {
|
||||||
if (!file.endsWith('.meta')) {
|
if (!file.endsWith('.meta')) {
|
||||||
const file_path = this.scrapbook_dir + file;
|
const file_path = this.scrapbook_dir + file;
|
||||||
@@ -498,7 +498,7 @@ class WTVClientSessionData {
|
|||||||
* @returns {Buffer|false} Buffer data, or false if could not open file
|
* @returns {Buffer|false} Buffer data, or false if could not open file
|
||||||
*/
|
*/
|
||||||
getUserStoreFileByURL(url) {
|
getUserStoreFileByURL(url) {
|
||||||
let path_split = url.split('/');
|
const path_split = url.split('/');
|
||||||
path_split.shift();
|
path_split.shift();
|
||||||
path_split.shift();
|
path_split.shift();
|
||||||
const store_dir_path = path_split.join('/').replace('/', this.path.sep);
|
const store_dir_path = path_split.join('/').replace('/', this.path.sep);
|
||||||
@@ -931,21 +931,7 @@ class WTVClientSessionData {
|
|||||||
|
|
||||||
checkSecurity() {
|
checkSecurity() {
|
||||||
const self = this;
|
const self = this;
|
||||||
const rejectReason = null;
|
let rejectReason = null;
|
||||||
const ip2long = function (ip) {
|
|
||||||
let components;
|
|
||||||
|
|
||||||
if (components = ip.match(/^(\d{1,3})\.(\d{1,3})\.(\d{1,3})\.(\d{1,3})$/)) {
|
|
||||||
let iplong = 0;
|
|
||||||
let power = 1;
|
|
||||||
for (let i = 4; i >= 1; i -= 1) {
|
|
||||||
iplong += power * parseInt(components[i]);
|
|
||||||
power *= 256;
|
|
||||||
}
|
|
||||||
return iplong;
|
|
||||||
}
|
|
||||||
else return -1;
|
|
||||||
};
|
|
||||||
|
|
||||||
const rejectSSIDConnection = function (blacklist) {
|
const rejectSSIDConnection = function (blacklist) {
|
||||||
if (blacklist) {
|
if (blacklist) {
|
||||||
@@ -981,7 +967,7 @@ class WTVClientSessionData {
|
|||||||
} else {
|
} else {
|
||||||
rejectSSIDConnection(blacklist);
|
rejectSSIDConnection(blacklist);
|
||||||
}
|
}
|
||||||
if (ssid_access_list_ip_override && self.minisrv_config.config.debug_flags.debug) console.log(" * Request from disallowed SSID", wtvshared.filterSSID(ssid), "was allowed due to IP address whitelist");
|
if (ssid_access_list_ip_override && self.minisrv_config.config.debug_flags.debug) console.log(" * Request from disallowed SSID", this.wtvshared.filterSSID(ssid), "was allowed due to IP address whitelist");
|
||||||
}
|
}
|
||||||
|
|
||||||
// process whitelist first
|
// process whitelist first
|
||||||
|
|||||||
@@ -27,7 +27,7 @@ class WTVFTP {
|
|||||||
|
|
||||||
let user = null;
|
let user = null;
|
||||||
let pass = null;
|
let pass = null;
|
||||||
let host = parsed.hostname;
|
const host = parsed.hostname;
|
||||||
|
|
||||||
if (parsed.auth) {
|
if (parsed.auth) {
|
||||||
const [username, password] = parsed.auth.split(':');
|
const [username, password] = parsed.auth.split(':');
|
||||||
@@ -56,7 +56,7 @@ class WTVFTP {
|
|||||||
|
|
||||||
ftpClient.on('ready', () => {
|
ftpClient.on('ready', () => {
|
||||||
if (filename) {
|
if (filename) {
|
||||||
var totalsize = 0;
|
let totalsize = 0;
|
||||||
ftpClient.cwd(dir, (err) => {
|
ftpClient.cwd(dir, (err) => {
|
||||||
if (err) {
|
if (err) {
|
||||||
this.sendToClient(socket, { 'Status': '500 Failed to change directory', 'Content-Type': 'text/plain' }, 'Failed to change directory');
|
this.sendToClient(socket, { 'Status': '500 Failed to change directory', 'Content-Type': 'text/plain' }, 'Failed to change directory');
|
||||||
@@ -134,7 +134,7 @@ class WTVFTP {
|
|||||||
}
|
}
|
||||||
|
|
||||||
formatDirectoryListing(list) {
|
formatDirectoryListing(list) {
|
||||||
let html = `<html>
|
const html = `<html>
|
||||||
<head>
|
<head>
|
||||||
<title>FTP Directory Listing</title>
|
<title>FTP Directory Listing</title>
|
||||||
<style>
|
<style>
|
||||||
|
|||||||
@@ -169,7 +169,7 @@ class WTVFavorites {
|
|||||||
if (!result) return false;
|
if (!result) return false;
|
||||||
|
|
||||||
} catch (e) {
|
} catch (e) {
|
||||||
console.error(" # FavErr: Favorite Store failed\n", e, "\n", favoritefileout, "\n", favorite, "\n");
|
console.error(" # FavErr: Favorite Store failed\n", e, "\n", favoritefileout, "\n", favoritedata, "\n");
|
||||||
}
|
}
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
@@ -180,7 +180,7 @@ class WTVFavorites {
|
|||||||
self.messageArr = [];
|
self.messageArr = [];
|
||||||
this.fs.readdirSync(folderpath)
|
this.fs.readdirSync(folderpath)
|
||||||
.map(function (v) {
|
.map(function (v) {
|
||||||
const favorite_data_raw = null;
|
let favorite_data_raw;
|
||||||
const favoritepath = folderpath + self.path.sep + v;
|
const favoritepath = folderpath + self.path.sep + v;
|
||||||
if (self.fs.existsSync(favoritepath)) favorite_data_raw = self.fs.readFileSync(favoritepath);
|
if (self.fs.existsSync(favoritepath)) favorite_data_raw = self.fs.readFileSync(favoritepath);
|
||||||
if (favorite_data_raw) {
|
if (favorite_data_raw) {
|
||||||
|
|||||||
@@ -18,17 +18,16 @@ class WTVGuide {
|
|||||||
generatePage(topic, subtopic, page = null) {
|
generatePage(topic, subtopic, page = null) {
|
||||||
// sanitize a bit
|
// sanitize a bit
|
||||||
|
|
||||||
var template = null;
|
let template, template_args;
|
||||||
var template_args = null;
|
let data = false;
|
||||||
var data = false;
|
|
||||||
|
|
||||||
switch (topic.toLowerCase()) {
|
switch (topic.toLowerCase()) {
|
||||||
case "alerts":
|
case "alerts":
|
||||||
// Handle error alert pages using Nunjucks templates
|
// Handle error alert pages using Nunjucks templates
|
||||||
var template = this.wtvshared.getTemplate("wtv-guide", "templates/NunjucksTemplate.js", true);
|
template = this.wtvshared.getTemplate("wtv-guide", "templates/NunjucksTemplate.js", true);
|
||||||
if (this.fs.existsSync(template)) {
|
if (this.fs.existsSync(template)) {
|
||||||
// Map error names to template files
|
// Map error names to template files
|
||||||
var errorTemplateMap = {
|
const errorTemplateMap = {
|
||||||
"forbidden": topic + "/Forbidden.njk",
|
"forbidden": topic + "/Forbidden.njk",
|
||||||
"hostmissing": topic + "/HostMissing.njk",
|
"hostmissing": topic + "/HostMissing.njk",
|
||||||
"internalservererror": topic + "/InternalServerError.njk",
|
"internalservererror": topic + "/InternalServerError.njk",
|
||||||
@@ -36,7 +35,7 @@ class WTVGuide {
|
|||||||
"serviceunavailable": topic + "/ServiceUnavailable.njk"
|
"serviceunavailable": topic + "/ServiceUnavailable.njk"
|
||||||
};
|
};
|
||||||
|
|
||||||
var templateName = errorTemplateMap[subtopic.toLowerCase()];
|
const templateName = errorTemplateMap[subtopic.toLowerCase()];
|
||||||
if (templateName) {
|
if (templateName) {
|
||||||
template_args = {
|
template_args = {
|
||||||
template_name: templateName,
|
template_name: templateName,
|
||||||
@@ -48,27 +47,28 @@ class WTVGuide {
|
|||||||
if (template) break;
|
if (template) break;
|
||||||
|
|
||||||
case "glossary":
|
case "glossary":
|
||||||
var template =this.wtvshared.getTemplate("wtv-guide", "templates/glossary.js", true);
|
template =this.wtvshared.getTemplate("wtv-guide", "templates/glossary.js", true);
|
||||||
var glossary_datafile =this.wtvshared.getTemplate("wtv-guide", "glossary.json", true);
|
const glossary_datafile =this.wtvshared.getTemplate("wtv-guide", "glossary.json", true);
|
||||||
if (!this.fs.existsSync(template)) break;
|
if (!this.fs.existsSync(template)) break;
|
||||||
if (!this.fs.existsSync(glossary_datafile)) break;
|
if (!this.fs.existsSync(glossary_datafile)) break;
|
||||||
|
|
||||||
var glossary = JSON.parse(this.fs.readFileSync(glossary_datafile));
|
const glossary = JSON.parse(this.fs.readFileSync(glossary_datafile));
|
||||||
if (glossary[subtopic.toUpperCase()]) {
|
if (glossary[subtopic.toUpperCase()]) {
|
||||||
if (page) {
|
if (page) {
|
||||||
// glossary word
|
// glossary word
|
||||||
if (glossary[subtopic.toUpperCase()][page.toLowerCase()]) {
|
if (glossary[subtopic.toUpperCase()][page.toLowerCase()]) {
|
||||||
var word = glossary[subtopic.toUpperCase()][page.toLowerCase()].word;
|
const word = glossary[subtopic.toUpperCase()][page.toLowerCase()].word;
|
||||||
var definition = glossary[subtopic.toUpperCase()][page.toLowerCase()].definition;
|
let definition = glossary[subtopic.toUpperCase()][page.toLowerCase()].definition;
|
||||||
// replace <word>the word</word> with a nice convienent link
|
// replace <word>the word</word> with a nice convienent link
|
||||||
var search = "<word";
|
const search = "<word";
|
||||||
|
let start = 0;
|
||||||
while (start = definition.indexOf(search), start >= 0) {
|
while (start = definition.indexOf(search), start >= 0) {
|
||||||
var link_word_for_link = null;
|
let link_word_for_link = null;
|
||||||
var link_word_start_letter = null;
|
let link_word_start_letter = null;
|
||||||
var link_word_override = null;
|
let link_word_override = null;
|
||||||
var original_start, end = 0;
|
let end = 0;
|
||||||
var start = start + search.length;
|
start = start + search.length;
|
||||||
original_start = start;
|
const original_start = start;
|
||||||
// handle <word="whatever">
|
// handle <word="whatever">
|
||||||
if (definition.charAt(start) != ">") {
|
if (definition.charAt(start) != ">") {
|
||||||
start++; // +1 to skip =
|
start++; // +1 to skip =
|
||||||
@@ -87,19 +87,19 @@ class WTVGuide {
|
|||||||
}
|
}
|
||||||
end = definition.indexOf("</word>", start);
|
end = definition.indexOf("</word>", start);
|
||||||
if (end === -1) break; // malformed tag, exit loop
|
if (end === -1) break; // malformed tag, exit loop
|
||||||
var link_word = definition.slice(start, end);
|
const link_word = definition.slice(start, end);
|
||||||
if (!link_word_for_link) link_word_for_link = link_word.replace(/ /g, '').replace(/\'/g,'').replace(/\"/g,'').toLowerCase();
|
if (!link_word_for_link) link_word_for_link = link_word.replace(/ /g, '').replace(/\'/g,'').replace(/\"/g,'').toLowerCase();
|
||||||
if (!link_word_start_letter && link_word_for_link.length > 0) link_word_start_letter = link_word_for_link.charAt(0).toUpperCase();
|
if (!link_word_start_letter && link_word_for_link.length > 0) link_word_start_letter = link_word_for_link.charAt(0).toUpperCase();
|
||||||
if (!link_word_override) link_word_override = link_word;
|
if (!link_word_override) link_word_override = link_word;
|
||||||
|
|
||||||
var link_url = `wtv-guide:/help?topic=Glossary&subtopic=${link_word_start_letter}&page=${link_word_for_link}&word=${encodeURIComponent(link_word_override)}`
|
const link_url = `wtv-guide:/help?topic=Glossary&subtopic=${link_word_start_letter}&page=${link_word_for_link}&word=${encodeURIComponent(link_word_override)}`
|
||||||
var new_definition = definition.slice(0, original_start - search.length) + `<a href="${link_url}">${link_word}</a>` + definition.slice(end + 7);
|
const new_definition = definition.slice(0, original_start - search.length) + `<a href="${link_url}">${link_word}</a>` + definition.slice(end + 7);
|
||||||
definition = new_definition;
|
definition = new_definition;
|
||||||
}
|
}
|
||||||
// replaces <boxname> with the friendly name of the type of unit the user has
|
// replaces <boxname> with the friendly name of the type of unit the user has
|
||||||
while (definition.indexOf("<boxname>") >= 0) {
|
while (definition.indexOf("<boxname>") >= 0) {
|
||||||
var romtype = this.session_data.get("wtv-client-rom-type");
|
const romtype = this.session_data.get("wtv-client-rom-type");
|
||||||
var boxname = "";
|
let boxname = "";
|
||||||
if (romtype == "US-WEBSTAR-disk-0MB-16MB-softmodem-CPU5230" || romtype == "US-DTV-disk-0MB-32MB-softmodem-CPU5230") boxname = "satellite receiver"
|
if (romtype == "US-WEBSTAR-disk-0MB-16MB-softmodem-CPU5230" || romtype == "US-DTV-disk-0MB-32MB-softmodem-CPU5230") boxname = "satellite receiver"
|
||||||
else if (this.session_data.hasCap("client-has-tv-experience")) boxname = "WebTV Plus receiver";
|
else if (this.session_data.hasCap("client-has-tv-experience")) boxname = "WebTV Plus receiver";
|
||||||
else boxname = "WebTV Internet terminal";
|
else boxname = "WebTV Internet terminal";
|
||||||
@@ -107,13 +107,13 @@ class WTVGuide {
|
|||||||
}
|
}
|
||||||
// replaces <boxname_plus> with either "WebTV" or "WebTV Plus" depending on user box type
|
// replaces <boxname_plus> with either "WebTV" or "WebTV Plus" depending on user box type
|
||||||
while (definition.indexOf("<boxname_plus>") >= 0) {
|
while (definition.indexOf("<boxname_plus>") >= 0) {
|
||||||
var boxname = "WebTV";
|
let boxname = "WebTV";
|
||||||
if (this.session_data.hasCap("client-has-tv-experience")) boxname += " Plus";
|
if (this.session_data.hasCap("client-has-tv-experience")) boxname += " Plus";
|
||||||
definition = definition.replace(/\<boxname\_plus\>/g, boxname);
|
definition = definition.replace(/\<boxname\_plus\>/g, boxname);
|
||||||
}
|
}
|
||||||
// replaces <webhome> with either "Home" or "Web Home" depending on user box type
|
// replaces <webhome> with either "Home" or "Web Home" depending on user box type
|
||||||
while (definition.indexOf("<webhome>") >= 0) {
|
while (definition.indexOf("<webhome>") >= 0) {
|
||||||
var homename = "Home";
|
let homename = "Home";
|
||||||
if (this.session_data.hasCap("client-has-tv-experience")) homename = "Web " + homename;
|
if (this.session_data.hasCap("client-has-tv-experience")) homename = "Web " + homename;
|
||||||
definition = definition.replace(/\<webhome\>/g, homename);
|
definition = definition.replace(/\<webhome\>/g, homename);
|
||||||
}
|
}
|
||||||
@@ -125,13 +125,13 @@ class WTVGuide {
|
|||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
// glossary letter word index
|
// glossary letter word index
|
||||||
var template =this.wtvshared.getTemplate("wtv-guide", "templates/glossary_word_index.js", true);
|
template =this.wtvshared.getTemplate("wtv-guide", "templates/glossary_word_index.js", true);
|
||||||
var isPlusBox = false;
|
let isPlusBox = false;
|
||||||
if (this.session_data.hasCap("client-has-tv-experience")) isPlusBox = true;
|
if (this.session_data.hasCap("client-has-tv-experience")) isPlusBox = true;
|
||||||
var worddb = [];
|
const worddb = [];
|
||||||
Object.keys(glossary[subtopic.toUpperCase()]).forEach(function (k) {
|
Object.keys(glossary[subtopic.toUpperCase()]).forEach(function (k) {
|
||||||
if (glossary[subtopic.toUpperCase()][k].plusonly && !isPlusBox) return;
|
if (glossary[subtopic.toUpperCase()][k].plusonly && !isPlusBox) return;
|
||||||
var thisword = glossary[subtopic.toUpperCase()][k];
|
const thisword = glossary[subtopic.toUpperCase()][k];
|
||||||
thisword.link = k;
|
thisword.link = k;
|
||||||
worddb.push(thisword);
|
worddb.push(thisword);
|
||||||
})
|
})
|
||||||
@@ -148,13 +148,13 @@ class WTVGuide {
|
|||||||
case "index":
|
case "index":
|
||||||
switch (subtopic.toLowerCase()) {
|
switch (subtopic.toLowerCase()) {
|
||||||
case "glossary":
|
case "glossary":
|
||||||
var template =this.wtvshared.getTemplate("wtv-guide", "templates/glossary_index.js", true);
|
template = this.wtvshared.getTemplate("wtv-guide", "templates/glossary_index.js", true);
|
||||||
var glossary_datafile =this.wtvshared.getTemplate("wtv-guide", "glossary.json", true);
|
const glossary_datafile =this.wtvshared.getTemplate("wtv-guide", "glossary.json", true);
|
||||||
if (!this.fs.existsSync(template)) break;
|
if (!this.fs.existsSync(template)) break;
|
||||||
if (!this.fs.existsSync(glossary_datafile)) break;
|
if (!this.fs.existsSync(glossary_datafile)) break;
|
||||||
|
|
||||||
var glossary = JSON.parse(this.fs.readFileSync(glossary_datafile));
|
const glossary = JSON.parse(this.fs.readFileSync(glossary_datafile));
|
||||||
var letters = [];
|
const letters = [];
|
||||||
Object.keys(glossary).forEach(function (k) { letters.push(k); });
|
Object.keys(glossary).forEach(function (k) { letters.push(k); });
|
||||||
template_args = {
|
template_args = {
|
||||||
minisrv_config: this.minisrv_config,
|
minisrv_config: this.minisrv_config,
|
||||||
@@ -167,20 +167,20 @@ class WTVGuide {
|
|||||||
default:
|
default:
|
||||||
// fallback to old js file method
|
// fallback to old js file method
|
||||||
try {
|
try {
|
||||||
var prerendered = null;
|
let prerendered;
|
||||||
if (!page) prerendered = this.wtvshared.getTemplate("wtv-guide", "prerendered/" + topic + "/" + subtopic + ".js", true);
|
if (!page) prerendered = this.wtvshared.getTemplate("wtv-guide", "prerendered/" + topic + "/" + subtopic + ".js", true);
|
||||||
else prerendered =this.wtvshared.getTemplate("wtv-guide", "prerendered/" + topic + "/" + subtopic + "/" + page + ".js", true);
|
else prerendered =this.wtvshared.getTemplate("wtv-guide", "prerendered/" + topic + "/" + subtopic + "/" + page + ".js", true);
|
||||||
|
|
||||||
if (!this.fs.existsSync(prerendered)) break;
|
if (!this.fs.existsSync(prerendered)) break;
|
||||||
|
|
||||||
|
|
||||||
var prerendered_jscode = this.fs.readFileSync(prerendered);
|
let prerendered_jscode = this.fs.readFileSync(prerendered);
|
||||||
if (!prerendered_jscode) break;
|
if (!prerendered_jscode) break;
|
||||||
prerendered_jscode = prerendered_jscode.toString('ascii');
|
prerendered_jscode = prerendered_jscode.toString('ascii');
|
||||||
var contextObj = {
|
const contextObj = {
|
||||||
"session_data": this.session_data
|
"session_data": this.session_data
|
||||||
}
|
}
|
||||||
var vmResult = this.runScriptInVM(prerendered_jscode, contextObj);
|
const vmResult = this.runScriptInVM(prerendered_jscode, contextObj);
|
||||||
if (vmResult.data) return vmResult.data;
|
if (vmResult.data) return vmResult.data;
|
||||||
} catch (e) {
|
} catch (e) {
|
||||||
console.log(e);
|
console.log(e);
|
||||||
@@ -190,9 +190,9 @@ class WTVGuide {
|
|||||||
}
|
}
|
||||||
if (template && template_args) {
|
if (template && template_args) {
|
||||||
if (!data) {
|
if (!data) {
|
||||||
var WTVTemplate = require(template); // load template class
|
const WTVTemplate = require(template); // load template class
|
||||||
try {
|
try {
|
||||||
var wtvt = new WTVTemplate(template_args); // initialize template with our args
|
const wtvt = new WTVTemplate(template_args); // initialize template with our args
|
||||||
data = wtvt.getTemplatePage(); // execute template function
|
data = wtvt.getTemplatePage(); // execute template function
|
||||||
} catch (e) {
|
} catch (e) {
|
||||||
console.log(" * wtv-template error:", e)
|
console.log(" * wtv-template error:", e)
|
||||||
|
|||||||
@@ -959,6 +959,7 @@ class WTVIRC {
|
|||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
var srvCommand = parts[1];
|
var srvCommand = parts[1];
|
||||||
|
let whoisNick;
|
||||||
switch (srvCommand) {
|
switch (srvCommand) {
|
||||||
case 'QUIT':
|
case 'QUIT':
|
||||||
var user_name = this.usernames.get(nickname) || nickname;
|
var user_name = this.usernames.get(nickname) || nickname;
|
||||||
@@ -1176,7 +1177,7 @@ class WTVIRC {
|
|||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
var targetUniqueId = parts[2];
|
var targetUniqueId = parts[2];
|
||||||
var whoisNick = this.findUserByUniqueId(targetUniqueId);
|
whoisNick = this.findUserByUniqueId(targetUniqueId);
|
||||||
if (!whoisNick) {
|
if (!whoisNick) {
|
||||||
whoisNick = parts[3].slice(1); // Remove leading ':'
|
whoisNick = parts[3].slice(1); // Remove leading ':'
|
||||||
}
|
}
|
||||||
@@ -3036,9 +3037,9 @@ class WTVIRC {
|
|||||||
if (usermodes && usermodes.includes('B')) {
|
if (usermodes && usermodes.includes('B')) {
|
||||||
output_lines.push(`:${this.servername} 335 ${socket.nickname} ${whoisNick} :is a bot\r\n`);
|
output_lines.push(`:${this.servername} 335 ${socket.nickname} ${whoisNick} :is a bot\r\n`);
|
||||||
}
|
}
|
||||||
var now = this.getDate();
|
const now = this.getDate();
|
||||||
var userTimestamp = whoisSocket.lastspoke || now;
|
const userTimestamp = whoisSocket.lastspoke || now;
|
||||||
var idleTime = now - userTimestamp;
|
const idleTime = now - userTimestamp;
|
||||||
output_lines.push(`:${this.servername} 317 ${socket.nickname} ${whoisNick} ${idleTime} ${this.usersignontimestamps.get(whoisNick) || 0} :seconds idle, signon time\r\n`);
|
output_lines.push(`:${this.servername} 317 ${socket.nickname} ${whoisNick} ${idleTime} ${this.usersignontimestamps.get(whoisNick) || 0} :seconds idle, signon time\r\n`);
|
||||||
if (userChannels.length > 0) {
|
if (userChannels.length > 0) {
|
||||||
output_lines.push(`:${this.servername} 319 ${socket.nickname} ${whoisNick} :${userChannels.join(' ')}\r\n`);
|
output_lines.push(`:${this.servername} 319 ${socket.nickname} ${whoisNick} :${userChannels.join(' ')}\r\n`);
|
||||||
@@ -3090,7 +3091,7 @@ class WTVIRC {
|
|||||||
if (cleanKillReason.startsWith(':')) {
|
if (cleanKillReason.startsWith(':')) {
|
||||||
cleanKillReason = cleanKillReason.slice(1);
|
cleanKillReason = cleanKillReason.slice(1);
|
||||||
}
|
}
|
||||||
var targetSocket = Array.from(this.nicknames.keys()).find(s => this.nicknames.get(s) === target_nick);
|
targetSocket = Array.from(this.nicknames.keys()).find(s => this.nicknames.get(s) === target_nick);
|
||||||
if (!targetSocket) {
|
if (!targetSocket) {
|
||||||
await this.safeWriteToSocket(socket, `:${this.servername} 401 ${socket.nickname} ${target_nick} :No such nick/channel\r\n`);
|
await this.safeWriteToSocket(socket, `:${this.servername} 401 ${socket.nickname} ${target_nick} :No such nick/channel\r\n`);
|
||||||
break;
|
break;
|
||||||
@@ -3155,7 +3156,7 @@ class WTVIRC {
|
|||||||
await this.safeWriteToSocket(socket, `:${this.servername} 461 ${socket.nickname} WALLOPS :Not enough parameters\r\n`);
|
await this.safeWriteToSocket(socket, `:${this.servername} 461 ${socket.nickname} WALLOPS :Not enough parameters\r\n`);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
var wallopsMessage = params.join(' ');
|
let wallopsMessage = params.join(' ');
|
||||||
if (wallopsMessage.startsWith(':')) {
|
if (wallopsMessage.startsWith(':')) {
|
||||||
wallopsMessage = wallopsMessage.slice(1);
|
wallopsMessage = wallopsMessage.slice(1);
|
||||||
}
|
}
|
||||||
@@ -3253,7 +3254,7 @@ class WTVIRC {
|
|||||||
const nickname = this.nicknames.get(socket);
|
const nickname = this.nicknames.get(socket);
|
||||||
if (nickname) {
|
if (nickname) {
|
||||||
if (!socket.signedoff) {
|
if (!socket.signedoff) {
|
||||||
var serverSocket = null;
|
let serverSocket = null;
|
||||||
for (const [srvSocket, users] of this.serverusers.entries()) {
|
for (const [srvSocket, users] of this.serverusers.entries()) {
|
||||||
if (users && typeof users.has === 'function' && users.has(nickname)) {
|
if (users && typeof users.has === 'function' && users.has(nickname)) {
|
||||||
// Don't send QUIT to this server, as it owns the user
|
// Don't send QUIT to this server, as it owns the user
|
||||||
@@ -3451,8 +3452,8 @@ class WTVIRC {
|
|||||||
const sock = Array.from(this.nicknames.keys()).find(s => this.nicknames.get(s) === user);
|
const sock = Array.from(this.nicknames.keys()).find(s => this.nicknames.get(s) === user);
|
||||||
if (sock && sock !== exceptSocket) {
|
if (sock && sock !== exceptSocket) {
|
||||||
if (sock.client_caps && sock.client_caps.includes('extended-join')) {
|
if (sock.client_caps && sock.client_caps.includes('extended-join')) {
|
||||||
var account = this.accounts.get(sourceSocket.nickname) || '*';
|
const account = this.accounts.get(sourceSocket.nickname) || '*';
|
||||||
var userinfo = this.userinfo.get(sourceSocket.nickname) || '';
|
const userinfo = this.userinfo.get(sourceSocket.nickname) || '';
|
||||||
await this.safeWriteToSocket(sock, `:${sourceSocket.nickname}!${sourceSocket.username}@${sourceSocket.host} JOIN ${channel} ${account} :${userinfo}\r\n`);
|
await this.safeWriteToSocket(sock, `:${sourceSocket.nickname}!${sourceSocket.username}@${sourceSocket.host} JOIN ${channel} ${account} :${userinfo}\r\n`);
|
||||||
} else {
|
} else {
|
||||||
await this.safeWriteToSocket(sock,`:${sourceSocket.nickname}!${sourceSocket.username}@${sourceSocket.host} JOIN ${channel}\r\n`);
|
await this.safeWriteToSocket(sock,`:${sourceSocket.nickname}!${sourceSocket.username}@${sourceSocket.host} JOIN ${channel}\r\n`);
|
||||||
@@ -3547,11 +3548,12 @@ class WTVIRC {
|
|||||||
const realhost = socket.realhost;
|
const realhost = socket.realhost;
|
||||||
const realaddress = socket.remoteAddress;
|
const realaddress = socket.remoteAddress;
|
||||||
const nickname = this.nicknames.get(socket);
|
const nickname = this.nicknames.get(socket);
|
||||||
var fullMask = `*!*@${host}`;
|
let fullMask = `*!*@${host}`;
|
||||||
var fullMask2 = `*!*@${realhost}`;
|
let fullMask2 = `*!*@${realhost}`;
|
||||||
var fullMask3 = `*!*@${realaddress}`;
|
let fullMask3 = `*!*@${realaddress}`;
|
||||||
|
let userIdent;
|
||||||
if (nickname) {
|
if (nickname) {
|
||||||
const userIdent = this.usernames.get(nickname) || nickname;
|
userIdent = this.usernames.get(nickname) || nickname;
|
||||||
fullMask = `${nickname}!${userIdent}@${host}`;
|
fullMask = `${nickname}!${userIdent}@${host}`;
|
||||||
fullMask2 = `${nickname}!${userIdent}@${realhost}`;
|
fullMask2 = `${nickname}!${userIdent}@${realhost}`;
|
||||||
fullMask3 = `${nickname}!${userIdent}@${realaddress}`;
|
fullMask3 = `${nickname}!${userIdent}@${realaddress}`;
|
||||||
@@ -3579,7 +3581,7 @@ class WTVIRC {
|
|||||||
const nickRegex = new RegExp('^' + (maskNick || '*').replace(/\*/g, '.*').replace(/\?/g, '.') + '$', 'i');
|
const nickRegex = new RegExp('^' + (maskNick || '*').replace(/\*/g, '.*').replace(/\?/g, '.') + '$', 'i');
|
||||||
const userRegex = new RegExp('^' + (maskUser || '*').replace(/\*/g, '.*').replace(/\?/g, '.') + '$', 'i');
|
const userRegex = new RegExp('^' + (maskUser || '*').replace(/\*/g, '.*').replace(/\?/g, '.') + '$', 'i');
|
||||||
const hostRegex = new RegExp('^' + (maskHost || '*').replace(/\*/g, '.*').replace(/\?/g, '.') + '$', 'i');
|
const hostRegex = new RegExp('^' + (maskHost || '*').replace(/\*/g, '.*').replace(/\?/g, '.') + '$', 'i');
|
||||||
var matches = nickRegex.test(fullNick) && userRegex.test(fullUser) && hostRegex.test(fullHost);
|
let matches = nickRegex.test(fullNick) && userRegex.test(fullUser) && hostRegex.test(fullHost);
|
||||||
if (!matches && fullMask2) {
|
if (!matches && fullMask2) {
|
||||||
// Try matching against the real host if available
|
// Try matching against the real host if available
|
||||||
const [fullNick2, fullRest2] = fullMask2.split('!', 2);
|
const [fullNick2, fullRest2] = fullMask2.split('!', 2);
|
||||||
@@ -3598,7 +3600,7 @@ class WTVIRC {
|
|||||||
filterHostname(socket, hostname) {
|
filterHostname(socket, hostname) {
|
||||||
// Masks the user's hostname or IP for privacy
|
// Masks the user's hostname or IP for privacy
|
||||||
const username = this.nicknames.get(socket);
|
const username = this.nicknames.get(socket);
|
||||||
var modes = null;
|
let modes = null;
|
||||||
if (username) {
|
if (username) {
|
||||||
modes = this.getUserModes(username);
|
modes = this.getUserModes(username);
|
||||||
}
|
}
|
||||||
@@ -3679,7 +3681,7 @@ class WTVIRC {
|
|||||||
|
|
||||||
findUserByUniqueId(uniqueId) {
|
findUserByUniqueId(uniqueId) {
|
||||||
// Find a user by their unique ID
|
// Find a user by their unique ID
|
||||||
var uniqueids = this.uniqueids || new Map();
|
let uniqueids = this.uniqueids || new Map();
|
||||||
if (!uniqueids || uniqueids === true) {
|
if (!uniqueids || uniqueids === true) {
|
||||||
uniqueids = new Map();
|
uniqueids = new Map();
|
||||||
}
|
}
|
||||||
@@ -3715,7 +3717,7 @@ class WTVIRC {
|
|||||||
|
|
||||||
async doMOTD(nickname, socket = null) {
|
async doMOTD(nickname, socket = null) {
|
||||||
// Sends the Message of the Day (MOTD) to the user
|
// Sends the Message of the Day (MOTD) to the user
|
||||||
var output_lines = [];
|
const output_lines = [];
|
||||||
output_lines.push(`:${this.servername} 375 ${nickname} :${this.servername} message of the day\r\n`);
|
output_lines.push(`:${this.servername} 375 ${nickname} :${this.servername} message of the day\r\n`);
|
||||||
if (!this.irc_config.hide_version) {
|
if (!this.irc_config.hide_version) {
|
||||||
output_lines.push(`:${this.servername} 372 ${nickname} :This is zefIRCd v${this.version}, running on minisrv v${this.minisrv_config.version}\r\n`);
|
output_lines.push(`:${this.servername} 372 ${nickname} :This is zefIRCd v${this.version}, running on minisrv v${this.minisrv_config.version}\r\n`);
|
||||||
@@ -3723,7 +3725,7 @@ class WTVIRC {
|
|||||||
if (typeof this.irc_motd === 'string' && this.irc_motd.length > 0) {
|
if (typeof this.irc_motd === 'string' && this.irc_motd.length > 0) {
|
||||||
output_lines.push(`:${this.servername} 372 ${nickname} :${this.irc_motd}\r\n`);
|
output_lines.push(`:${this.servername} 372 ${nickname} :${this.irc_motd}\r\n`);
|
||||||
} else if (Array.isArray(this.irc_motd) && this.irc_motd.length > 0) {
|
} else if (Array.isArray(this.irc_motd) && this.irc_motd.length > 0) {
|
||||||
for (var line of this.irc_motd) {
|
for (let line of this.irc_motd) {
|
||||||
if (line === '') {
|
if (line === '') {
|
||||||
line = '-';
|
line = '-';
|
||||||
}
|
}
|
||||||
@@ -3766,7 +3768,7 @@ class WTVIRC {
|
|||||||
|
|
||||||
isRemoteServerUser(socket, username) {
|
isRemoteServerUser(socket, username) {
|
||||||
// Check if the user is a remote server user
|
// Check if the user is a remote server user
|
||||||
var serverUsers = this.serverusers.get(socket) || new Set();
|
let serverUsers = this.serverusers.get(socket) || new Set();
|
||||||
if (!serverUsers || serverUsers === true) {
|
if (!serverUsers || serverUsers === true) {
|
||||||
serverUsers = new Set();
|
serverUsers = new Set();
|
||||||
}
|
}
|
||||||
@@ -4006,7 +4008,7 @@ class WTVIRC {
|
|||||||
if (!foundSocket) {
|
if (!foundSocket) {
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
var modes = this.usermodes.get(nickname);
|
const modes = this.usermodes.get(nickname);
|
||||||
if (!modes || modes === true) {
|
if (!modes || modes === true) {
|
||||||
this.usermodes.set(nickname, [...this.default_user_modes]);
|
this.usermodes.set(nickname, [...this.default_user_modes]);
|
||||||
}
|
}
|
||||||
@@ -4030,9 +4032,10 @@ class WTVIRC {
|
|||||||
|
|
||||||
async getHostname(socket) {
|
async getHostname(socket) {
|
||||||
// Resolve the hostname for a socket, using reverse DNS lookup
|
// Resolve the hostname for a socket, using reverse DNS lookup
|
||||||
|
let hostname;
|
||||||
if (socket && socket.remoteAddress) {
|
if (socket && socket.remoteAddress) {
|
||||||
try {
|
try {
|
||||||
var hostname = socket.remoteAddress
|
hostname = socket.remoteAddress;
|
||||||
hostname = await new Promise((resolve) => {
|
hostname = await new Promise((resolve) => {
|
||||||
dns.reverse(socket.remoteAddress, (err, hostnames) => {
|
dns.reverse(socket.remoteAddress, (err, hostnames) => {
|
||||||
if (!err && hostnames && hostnames.length > 0) {
|
if (!err && hostnames && hostnames.length > 0) {
|
||||||
@@ -4138,7 +4141,7 @@ class WTVIRC {
|
|||||||
|
|
||||||
getGitRevision() {
|
getGitRevision() {
|
||||||
try {
|
try {
|
||||||
var gitPath = __dirname + path.sep + ".." + path.sep + ".." + path.sep + ".." + path.sep + ".git" + path.sep
|
const gitPath = __dirname + path.sep + ".." + path.sep + ".." + path.sep + ".." + path.sep + ".git" + path.sep
|
||||||
const rev = fs.readFileSync(gitPath + "HEAD").toString().trim();
|
const rev = fs.readFileSync(gitPath + "HEAD").toString().trim();
|
||||||
if (rev.indexOf(':') === -1) {
|
if (rev.indexOf(':') === -1) {
|
||||||
return rev.slice(0, 8);
|
return rev.slice(0, 8);
|
||||||
@@ -4190,12 +4193,13 @@ class WTVIRC {
|
|||||||
|
|
||||||
|
|
||||||
processChannelModeParams(channel, mode, target) {
|
processChannelModeParams(channel, mode, target) {
|
||||||
|
let result = false;
|
||||||
if (!target) {
|
if (!target) {
|
||||||
this.debugLog('warn', `No target specified for mode ${mode} on channel ${channel}`);
|
this.debugLog('warn', `No target specified for mode ${mode} on channel ${channel}`);
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
if (mode === '+o' || mode === '-o') {
|
if (mode === '+o' || mode === '-o') {
|
||||||
var channelOps = this.channelData.get(channel).ops;
|
const channelOps = this.channelData.get(channel).ops;
|
||||||
if (mode === '+o') {
|
if (mode === '+o') {
|
||||||
if (!channelOps.has(target)) {
|
if (!channelOps.has(target)) {
|
||||||
channelOps.add(target);
|
channelOps.add(target);
|
||||||
@@ -4208,7 +4212,7 @@ class WTVIRC {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
} else if (mode === '+h' || mode === '-h') {
|
} else if (mode === '+h' || mode === '-h') {
|
||||||
var channelHalfOps = this.channelData.get(channel).halfops;
|
const channelHalfOps = this.channelData.get(channel).halfops;
|
||||||
if (mode === '+h') {
|
if (mode === '+h') {
|
||||||
if (!channelHalfOps.has(target)) {
|
if (!channelHalfOps.has(target)) {
|
||||||
channelHalfOps.add(target);
|
channelHalfOps.add(target);
|
||||||
@@ -4221,7 +4225,7 @@ class WTVIRC {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
} else if (mode === '+v' || mode === '-v') {
|
} else if (mode === '+v' || mode === '-v') {
|
||||||
var channelVoices = this.channelData.get(channel).voices;
|
const channelVoices = this.channelData.get(channel).voices;
|
||||||
if (mode === '+v') {
|
if (mode === '+v') {
|
||||||
if (!channelVoices.has(target)) {
|
if (!channelVoices.has(target)) {
|
||||||
channelVoices.add(target);
|
channelVoices.add(target);
|
||||||
@@ -4234,7 +4238,7 @@ class WTVIRC {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
} else if (mode === '+b' || mode === '-b') {
|
} else if (mode === '+b' || mode === '-b') {
|
||||||
var channelBans = this.channelData.get(channel).bans;
|
let channelBans = this.channelData.get(channel).bans;
|
||||||
if (mode === '+b') {
|
if (mode === '+b') {
|
||||||
if (!channelBans.includes(target)) {
|
if (!channelBans.includes(target)) {
|
||||||
channelBans.push(target);
|
channelBans.push(target);
|
||||||
@@ -4247,7 +4251,7 @@ class WTVIRC {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
} else if (mode === '+e' || mode === '-e') {
|
} else if (mode === '+e' || mode === '-e') {
|
||||||
var channelExemptions = this.channelData.get(channel).exemptions;
|
let channelExemptions = this.channelData.get(channel).exemptions;
|
||||||
if (mode === '+e') {
|
if (mode === '+e') {
|
||||||
if (!channelExemptions.includes(target)) {
|
if (!channelExemptions.includes(target)) {
|
||||||
channelExemptions.push(target);
|
channelExemptions.push(target);
|
||||||
@@ -4260,7 +4264,7 @@ class WTVIRC {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
} else if (mode === '+I' || mode === '-I') {
|
} else if (mode === '+I' || mode === '-I') {
|
||||||
var channelInvites = this.channelData.get(channel).inviteexemptions;
|
let channelInvites = this.channelData.get(channel).inviteexemptions;
|
||||||
if (mode === '+I') {
|
if (mode === '+I') {
|
||||||
if (!channelInvites.includes(target)) {
|
if (!channelInvites.includes(target)) {
|
||||||
channelInvites.push(target);
|
channelInvites.push(target);
|
||||||
@@ -4274,14 +4278,14 @@ class WTVIRC {
|
|||||||
}
|
}
|
||||||
} else if (mode === '+l' || mode === '-l') {
|
} else if (mode === '+l' || mode === '-l') {
|
||||||
if (mode === '+l') {
|
if (mode === '+l') {
|
||||||
var result = this.setChannelMode(channel, 'l', true);
|
result = this.setChannelMode(channel, 'l', true);
|
||||||
if (result === false && this.channelData.get(channel).limit === parseInt(target)) {
|
if (result === false && this.channelData.get(channel).limit === parseInt(target)) {
|
||||||
return false; // Mode already set with the same limit
|
return false; // Mode already set with the same limit
|
||||||
}
|
}
|
||||||
this.channelData.get(channel).limit = parseInt(target);
|
this.channelData.get(channel).limit = parseInt(target);
|
||||||
return true;
|
return true;
|
||||||
} else {
|
} else {
|
||||||
var result = this.setChannelMode(channel, 'l', false);
|
result = this.setChannelMode(channel, 'l', false);
|
||||||
if (result === false && this.channelData.get(channel).limit === null) {
|
if (result === false && this.channelData.get(channel).limit === null) {
|
||||||
return false; // Mode already unset
|
return false; // Mode already unset
|
||||||
}
|
}
|
||||||
@@ -4290,14 +4294,14 @@ class WTVIRC {
|
|||||||
}
|
}
|
||||||
} else if (mode === '+k' || mode === '-k') {
|
} else if (mode === '+k' || mode === '-k') {
|
||||||
if (mode === '+k') {
|
if (mode === '+k') {
|
||||||
var result = this.setChannelMode(channel, 'k', true);
|
result = this.setChannelMode(channel, 'k', true);
|
||||||
if (result === false && this.channelData.get(channel).key === target) {
|
if (result === false && this.channelData.get(channel).key === target) {
|
||||||
return false; // Mode already set with the same key
|
return false; // Mode already set with the same key
|
||||||
}
|
}
|
||||||
this.channelData.get(channel).key = target;
|
this.channelData.get(channel).key = target;
|
||||||
return true;
|
return true;
|
||||||
} else {
|
} else {
|
||||||
var result = this.setChannelMode(channel, 'k', false);
|
result = this.setChannelMode(channel, 'k', false);
|
||||||
if (result === false && !this.channelData.get(channel).key) {
|
if (result === false && !this.channelData.get(channel).key) {
|
||||||
return false; // Mode already unset
|
return false; // Mode already unset
|
||||||
}
|
}
|
||||||
@@ -4309,13 +4313,13 @@ class WTVIRC {
|
|||||||
|
|
||||||
async processChannelModes(nickname, channel, modes, params, socket) {
|
async processChannelModes(nickname, channel, modes, params, socket) {
|
||||||
// Split modes into array and process each character
|
// Split modes into array and process each character
|
||||||
let modeChars = modes.split('');
|
const modeChars = modes.split('');
|
||||||
let validModes = [];
|
const validModes = [];
|
||||||
let supportedChannelModes = (this.supported_channel_modes.split(',').join('') + this.supported_prefixes[0]).split('');
|
const supportedChannelModes = (this.supported_channel_modes.split(',').join('') + this.supported_prefixes[0]).split('');
|
||||||
var serverModeMsg = '';
|
let serverModeMsg = '';
|
||||||
var target = null;
|
let target = null;
|
||||||
if (socket.isserver) {
|
if (socket.isserver) {
|
||||||
let sourceUniqueId = this.uniqueids.get(nickname);
|
const sourceUniqueId = this.uniqueids.get(nickname);
|
||||||
serverModeMsg = `:${sourceUniqueId} MODE ${channel} `;
|
serverModeMsg = `:${sourceUniqueId} MODE ${channel} `;
|
||||||
} else {
|
} else {
|
||||||
if (!this.checkRegistered(socket)) {
|
if (!this.checkRegistered(socket)) {
|
||||||
@@ -4323,13 +4327,14 @@ class WTVIRC {
|
|||||||
}
|
}
|
||||||
serverModeMsg = `:${socket.uniqueId} MODE ${channel} `;
|
serverModeMsg = `:${socket.uniqueId} MODE ${channel} `;
|
||||||
}
|
}
|
||||||
var username = this.usernames.get(nickname);
|
const username = this.usernames.get(nickname);
|
||||||
var hostname = this.hostnames.get(nickname);
|
const hostname = this.hostnames.get(nickname);
|
||||||
|
|
||||||
let modeMsg = `:${nickname}!${username}@${hostname} MODE ${channel} `;
|
let modeMsg = `:${nickname}!${username}@${hostname} MODE ${channel} `;
|
||||||
let WTVMsg = `${nickname} has set channel mode `;
|
let WTVMsg = `${nickname} has set channel mode `;
|
||||||
let addingFlag = false;
|
let addingFlag = false;
|
||||||
let paramIndex = 0;
|
let paramIndex = 0;
|
||||||
|
const output_lines = [];
|
||||||
if (!socket.isserver) {
|
if (!socket.isserver) {
|
||||||
if (modeChars.includes('o')) {
|
if (modeChars.includes('o')) {
|
||||||
if (!this.isIRCOp(nickname) && !this.isChannelOp(nickname, channel)) {
|
if (!this.isIRCOp(nickname) && !this.isChannelOp(nickname, channel)) {
|
||||||
@@ -4344,8 +4349,7 @@ class WTVIRC {
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
} else if (modes === 'b') {
|
} else if (modes === 'b') {
|
||||||
// Get the list of channel bans
|
// Get the list of channel ban
|
||||||
output_lines = [];
|
|
||||||
if (this.channelData.has(channel).bans) {
|
if (this.channelData.has(channel).bans) {
|
||||||
const bans = this.channelData.has(channel).bans;
|
const bans = this.channelData.has(channel).bans;
|
||||||
for (const ban of bans) {
|
for (const ban of bans) {
|
||||||
@@ -4357,7 +4361,6 @@ class WTVIRC {
|
|||||||
return;
|
return;
|
||||||
} else if (modes === 'e') {
|
} else if (modes === 'e') {
|
||||||
// Get the list of channel exemptions
|
// Get the list of channel exemptions
|
||||||
output_lines = [];
|
|
||||||
if (this.channelData.has(channel).exemptions) {
|
if (this.channelData.has(channel).exemptions) {
|
||||||
const exemptions = this.channelData.has(channel).exemptions;
|
const exemptions = this.channelData.has(channel).exemptions;
|
||||||
for (const exemption of exemptions) {
|
for (const exemption of exemptions) {
|
||||||
@@ -4369,7 +4372,6 @@ class WTVIRC {
|
|||||||
return;
|
return;
|
||||||
} else if (modes === 'I') {
|
} else if (modes === 'I') {
|
||||||
// Get the list of channel invites masks
|
// Get the list of channel invites masks
|
||||||
output_lines = [];
|
|
||||||
if (this.channelData.has(channel).invites) {
|
if (this.channelData.has(channel).invites) {
|
||||||
const invites = this.channelData.has(channel).invites;
|
const invites = this.channelData.has(channel).invites;
|
||||||
for (const invite of invites) {
|
for (const invite of invites) {
|
||||||
@@ -4389,7 +4391,8 @@ class WTVIRC {
|
|||||||
for (let j = 0; j < modeChars.length; j++) {
|
for (let j = 0; j < modeChars.length; j++) {
|
||||||
let param = null;
|
let param = null;
|
||||||
let modeStr = '';
|
let modeStr = '';
|
||||||
let mc = modeChars[j];
|
const mc = modeChars[j];
|
||||||
|
let result = false;
|
||||||
if (mc === '+') {
|
if (mc === '+') {
|
||||||
addingFlag = true;
|
addingFlag = true;
|
||||||
modeMsg += '+';
|
modeMsg += '+';
|
||||||
@@ -4412,7 +4415,7 @@ class WTVIRC {
|
|||||||
modeStr += mc;
|
modeStr += mc;
|
||||||
// Modes that require a parameter
|
// Modes that require a parameter
|
||||||
if ([...this.supported_prefixes[0], 'I', 'b', 'e', 'l', 'k'].includes(mc)) {
|
if ([...this.supported_prefixes[0], 'I', 'b', 'e', 'l', 'k'].includes(mc)) {
|
||||||
var plusminus = (addingFlag) ? "+" : "-";
|
const plusminus = (addingFlag) ? "+" : "-";
|
||||||
param = params[paramIndex];
|
param = params[paramIndex];
|
||||||
if (socket.isserver) {
|
if (socket.isserver) {
|
||||||
target = this.findUserByUniqueId(param);
|
target = this.findUserByUniqueId(param);
|
||||||
@@ -4423,7 +4426,7 @@ class WTVIRC {
|
|||||||
await this.safeWriteToSocket(socket, `:${this.servername} 401 ${nickname} ${param} :No such nick/channel\r\n`);
|
await this.safeWriteToSocket(socket, `:${this.servername} 401 ${nickname} ${param} :No such nick/channel\r\n`);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
var result = this.processChannelModeParams(channel, plusminus + mc, target, socket);
|
result = this.processChannelModeParams(channel, plusminus + mc, target, socket);
|
||||||
paramIndex++;
|
paramIndex++;
|
||||||
if (!result) {
|
if (!result) {
|
||||||
if (params.length > 0) {
|
if (params.length > 0) {
|
||||||
@@ -4431,7 +4434,7 @@ class WTVIRC {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
var result = this.setChannelMode(channel, mc, addingFlag);
|
result = this.setChannelMode(channel, mc, addingFlag);
|
||||||
if (addingFlag) {
|
if (addingFlag) {
|
||||||
if (mc === 'S' && this.kick_insecure_users_on_secure) {
|
if (mc === 'S' && this.kick_insecure_users_on_secure) {
|
||||||
// Kick users who do not have user mode +z
|
// Kick users who do not have user mode +z
|
||||||
@@ -4496,7 +4499,7 @@ class WTVIRC {
|
|||||||
}
|
}
|
||||||
|
|
||||||
async checkRegistered(socket, allowUnregistered = false, silent = false) {
|
async checkRegistered(socket, allowUnregistered = false, silent = false) {
|
||||||
var retval = false
|
let retval = false;
|
||||||
if (socket.isserver) {
|
if (socket.isserver) {
|
||||||
if (!socket.is_srv_authorized && (!socket.registered && !allowUnregistered)) {
|
if (!socket.is_srv_authorized && (!socket.registered && !allowUnregistered)) {
|
||||||
if (socket.writable && !silent) {
|
if (socket.writable && !silent) {
|
||||||
@@ -4594,7 +4597,7 @@ class WTVIRC {
|
|||||||
await new Promise(res => setTimeout(res, 100));
|
await new Promise(res => setTimeout(res, 100));
|
||||||
waited += 100;
|
waited += 100;
|
||||||
}
|
}
|
||||||
var output_lines = []
|
const output_lines = [];
|
||||||
output_lines.push(`:${this.servername} NOTICE AUTH :Welcome to \x02${this.network}\x0F\r\n`);
|
output_lines.push(`:${this.servername} NOTICE AUTH :Welcome to \x02${this.network}\x0F\r\n`);
|
||||||
output_lines.push(`:${this.servername} 001 ${nickname} :Welcome to the IRC server, ${nickname}\r\n`);
|
output_lines.push(`:${this.servername} 001 ${nickname} :Welcome to the IRC server, ${nickname}\r\n`);
|
||||||
output_lines.push(`:${this.servername} 002 ${nickname} :Your host is ${this.servername}, running version zefIRCd v${this.version}\r\n`);
|
output_lines.push(`:${this.servername} 002 ${nickname} :Your host is ${this.servername}, running version zefIRCd v${this.version}\r\n`);
|
||||||
@@ -4625,17 +4628,18 @@ class WTVIRC {
|
|||||||
})
|
})
|
||||||
.join(',');
|
.join(',');
|
||||||
}
|
}
|
||||||
let channelModesParts = this.supported_channel_modes.split(',');
|
const channelModesParts = this.supported_channel_modes.split(',');
|
||||||
|
let sortedModesWithParams;
|
||||||
if (channelModesParts.length > 1) {
|
if (channelModesParts.length > 1) {
|
||||||
let modesToSort = channelModesParts.slice(0, -1).join('').split('');
|
let modesToSort = channelModesParts.slice(0, -1).join('').split('');
|
||||||
modesToSort.push(...this.supported_prefixes[0].split(''));
|
modesToSort.push(...this.supported_prefixes[0].split(''));
|
||||||
modesToSort = Array.from(new Set(modesToSort)); // remove duplicates
|
modesToSort = Array.from(new Set(modesToSort)); // remove duplicates
|
||||||
modesToSort.sort();
|
modesToSort.sort();
|
||||||
var sortedModesWithParams = modesToSort.join('');
|
sortedModesWithParams = modesToSort.join('');
|
||||||
}
|
}
|
||||||
var channelModes = this.supported_channel_modes.split(',').join('') + this.supported_prefixes[0];
|
const channelModes = this.supported_channel_modes.split(',').join('') + this.supported_prefixes[0];
|
||||||
var sortedChannelModes = sortModesAlphaCapsFirst(channelModes).replace(/,/g, '');
|
const sortedChannelModes = sortModesAlphaCapsFirst(channelModes).replace(/,/g, '');
|
||||||
var sortedUserModes = sortModesAlphaCapsFirst(this.supported_user_modes);
|
const sortedUserModes = sortModesAlphaCapsFirst(this.supported_user_modes);
|
||||||
output_lines.push(`:${this.servername} 004 ${nickname} ${this.servername} zefIRCd-${this.version} ${sortedUserModes} ${sortedChannelModes} ${sortedModesWithParams}\r\n`);
|
output_lines.push(`:${this.servername} 004 ${nickname} ${this.servername} zefIRCd-${this.version} ${sortedUserModes} ${sortedChannelModes} ${sortedModesWithParams}\r\n`);
|
||||||
for (const caps of this.caps) {
|
for (const caps of this.caps) {
|
||||||
output_lines.push(`:${this.servername} 005 ${caps}\r\n`);
|
output_lines.push(`:${this.servername} 005 ${caps}\r\n`);
|
||||||
@@ -4669,12 +4673,12 @@ class WTVIRC {
|
|||||||
output_lines.push(`:${this.servername} 265 ${nickname} :Current Local Users: ${this.clients.length} Max: ${this.clientpeak}\r\n`);
|
output_lines.push(`:${this.servername} 265 ${nickname} :Current Local Users: ${this.clients.length} Max: ${this.clientpeak}\r\n`);
|
||||||
const globalUsers = this.countGlobalUsers();
|
const globalUsers = this.countGlobalUsers();
|
||||||
this.globalpeak = Math.max(this.globalpeak, this.countGlobalUsers());
|
this.globalpeak = Math.max(this.globalpeak, this.countGlobalUsers());
|
||||||
var totalSockets = this.clients.length + this.servers.size;
|
const totalSockets = this.clients.length + this.servers.size;
|
||||||
this.socketpeak = Math.max(this.socketpeak, totalSockets);
|
this.socketpeak = Math.max(this.socketpeak, totalSockets);
|
||||||
|
|
||||||
output_lines.push(`:${this.servername} 266 ${nickname} :Current Global Users: ${globalUsers} Max: ${this.globalpeak}\r\n`);
|
output_lines.push(`:${this.servername} 266 ${nickname} :Current Global Users: ${globalUsers} Max: ${this.globalpeak}\r\n`);
|
||||||
output_lines.push(`:${this.servername} 250 ${nickname} :Highest connection count: ${this.socketpeak} (${this.clientpeak} clients) (${this.totalConnections} connections received)\r\n`);
|
output_lines.push(`:${this.servername} 250 ${nickname} :Highest connection count: ${this.socketpeak} (${this.clientpeak} clients) (${this.totalConnections} connections received)\r\n`);
|
||||||
var usermodes = this.usermodes.get(nickname);
|
let usermodes = this.usermodes.get(nickname);
|
||||||
if (!usermodes || usermodes === true) {
|
if (!usermodes || usermodes === true) {
|
||||||
usermodes = [];
|
usermodes = [];
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -221,7 +221,7 @@ class WTVMail {
|
|||||||
switch (header[0].toLowerCase()) {
|
switch (header[0].toLowerCase()) {
|
||||||
case "from":
|
case "from":
|
||||||
if (header[1].indexOf("<") >= 0) {
|
if (header[1].indexOf("<") >= 0) {
|
||||||
let email = header[1].match(/(.+) \<(.+)\>/);
|
const email = header[1].match(/(.+) \<(.+)\>/);
|
||||||
if (email) {
|
if (email) {
|
||||||
from_name = email[1];
|
from_name = email[1];
|
||||||
from_addr = email[2];
|
from_addr = email[2];
|
||||||
@@ -289,8 +289,8 @@ class WTVMail {
|
|||||||
|
|
||||||
// rely on filesystem times for sorting as it is quicker then reading every file
|
// rely on filesystem times for sorting as it is quicker then reading every file
|
||||||
const file_timestamp = new Date(message_data.date * 1000);
|
const file_timestamp = new Date(message_data.date * 1000);
|
||||||
fs.utimesSync(message_file, Date.now(), file_timestamp);
|
this.fs.utimesSync(message_data.message_file, Date.now(), file_timestamp);
|
||||||
if (!result) console.error(" WARNING: Setting timestamp on " + message_file + " failed, mail dates will be inaccurate.");
|
if (!result) console.error(" WARNING: Setting timestamp on " + message_data.message_file + " failed, mail dates will be inaccurate.");
|
||||||
}
|
}
|
||||||
|
|
||||||
checkMessageIdSanity(messageid) {
|
checkMessageIdSanity(messageid) {
|
||||||
@@ -482,8 +482,8 @@ class WTVMail {
|
|||||||
this.fs.readdirSync(this.mailstore_dir).every(mailbox => {
|
this.fs.readdirSync(this.mailstore_dir).every(mailbox => {
|
||||||
if (mailbox_name) return false;
|
if (mailbox_name) return false;
|
||||||
self.fs.readdirSync(self.mailstore_dir + mailbox).every(file => {
|
self.fs.readdirSync(self.mailstore_dir + mailbox).every(file => {
|
||||||
var regexSearch = messageid + self.msgFileExt;
|
const regexSearch = messageid + self.msgFileExt;
|
||||||
var re = new RegExp(regexSearch, "ig");
|
const re = new RegExp(regexSearch, "ig");
|
||||||
if (!file.match(re)) return true;
|
if (!file.match(re)) return true;
|
||||||
mailbox_name = mailbox;
|
mailbox_name = mailbox;
|
||||||
return false;
|
return false;
|
||||||
|
|||||||
@@ -1,32 +1,29 @@
|
|||||||
/**
|
/**
|
||||||
* Simple class for WebTV Mime Types and overrides
|
* Class for WebTV Mime Types and overrides
|
||||||
*/
|
*/
|
||||||
|
|
||||||
|
|
||||||
class WTVMime {
|
class WTVMime {
|
||||||
|
|
||||||
mime = require('mime-types');
|
mime = require('mime-types');
|
||||||
wtvshared = null;
|
wtvshared = null;
|
||||||
minisrv_config = [];
|
minisrv_config = [];
|
||||||
|
|
||||||
|
|
||||||
constructor(minisrv_config) {
|
constructor(minisrv_config) {
|
||||||
const { WTVShared } = require("./WTVShared.js");
|
const { WTVShared } = require("./WTVShared.js");
|
||||||
this.minisrv_config = minisrv_config;
|
this.minisrv_config = minisrv_config;
|
||||||
this.wtvshared = new WTVShared(minisrv_config);
|
this.wtvshared = new WTVShared(minisrv_config);
|
||||||
if (!String.prototype.reverse) {
|
if (!String.prototype.reverse) {
|
||||||
String.prototype.reverse = function () {
|
String.prototype.reverse = function () {
|
||||||
var splitString = this.split("");
|
const splitString = this.split("");
|
||||||
var reverseArray = splitString.reverse();
|
const reverseArray = splitString.reverse();
|
||||||
var joinArray = reverseArray.join("");
|
const joinArray = reverseArray.join("");
|
||||||
return joinArray;
|
return joinArray;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
shouldWeCompress(ssid_session, headers_obj) {
|
shouldWeCompress(ssid_session, headers_obj) {
|
||||||
var compress_data = false;
|
let compress_data = false;
|
||||||
var compression_type = 0; // no compression
|
let compression_type = 0; // no compression
|
||||||
if (ssid_session) {
|
if (ssid_session) {
|
||||||
if (ssid_session.capabilities) {
|
if (ssid_session.capabilities) {
|
||||||
if (ssid_session.capabilities['client-can-receive-compressed-data']) {
|
if (ssid_session.capabilities['client-can-receive-compressed-data']) {
|
||||||
@@ -38,9 +35,9 @@ class WTVMime {
|
|||||||
if (ssid_session) {
|
if (ssid_session) {
|
||||||
// if gzip is enabled...
|
// if gzip is enabled...
|
||||||
if (this.minisrv_config.config.enable_gzip_compression || this.minisrv_config.config.force_compression_type) {
|
if (this.minisrv_config.config.enable_gzip_compression || this.minisrv_config.config.force_compression_type) {
|
||||||
var is_bf0app = ssid_session.get("wtv-client-rom-type") == "bf0app";
|
const is_bf0app = ssid_session.get("wtv-client-rom-type") == "bf0app";
|
||||||
var isOldBuild = this.wtvshared.isOldBuild(ssid_session);
|
const isOldBuild = this.wtvshared.isOldBuild(ssid_session);
|
||||||
var is_softmodem = false;
|
let is_softmodem = false;
|
||||||
if (ssid_session.get("wtv-client-rom-type")) is_softmodem = ssid_session.get("wtv-client-rom-type").match(/softmodem/);
|
if (ssid_session.get("wtv-client-rom-type")) is_softmodem = ssid_session.get("wtv-client-rom-type").match(/softmodem/);
|
||||||
if (!is_bf0app && ((!is_softmodem && !isOldBuild) || (is_softmodem && !isOldBuild))) {
|
if (!is_bf0app && ((!is_softmodem && !isOldBuild) || (is_softmodem && !isOldBuild))) {
|
||||||
// softmodem boxes do not appear to support gzip in the minibrowser
|
// softmodem boxes do not appear to support gzip in the minibrowser
|
||||||
@@ -62,7 +59,7 @@ class WTVMime {
|
|||||||
if (headers_obj["Content-Encoding"]) return 0;
|
if (headers_obj["Content-Encoding"]) return 0;
|
||||||
|
|
||||||
// should we bother to compress?
|
// should we bother to compress?
|
||||||
var content_type = "";
|
let content_type = "";
|
||||||
if (typeof (headers_obj) == 'string') content_type = headers_obj;
|
if (typeof (headers_obj) == 'string') content_type = headers_obj;
|
||||||
else content_type = (typeof (headers_obj["wtv-modern-content-type"]) != 'undefined') ? headers_obj["wtv-modern-content-type"] : headers_obj["Content-type"];
|
else content_type = (typeof (headers_obj["wtv-modern-content-type"]) != 'undefined') ? headers_obj["wtv-modern-content-type"] : headers_obj["Content-type"];
|
||||||
|
|
||||||
@@ -102,9 +99,8 @@ class WTVMime {
|
|||||||
* @returns {Array} (WebTV Content-Type, Modern Content-Type)
|
* @returns {Array} (WebTV Content-Type, Modern Content-Type)
|
||||||
*/
|
*/
|
||||||
getContentType(path) {
|
getContentType(path) {
|
||||||
var file_ext = this.wtvshared.getFileExt(path).toLowerCase();
|
const file_ext = this.wtvshared.getFileExt(path).toLowerCase();
|
||||||
var wtv_mime_type = "";
|
let wtv_mime_type, modern_mime_type = "";
|
||||||
var modern_mime_type = "";
|
|
||||||
// process WebTV overrides, fall back to generic mime lookup
|
// process WebTV overrides, fall back to generic mime lookup
|
||||||
switch (file_ext) {
|
switch (file_ext) {
|
||||||
case "aif":
|
case "aif":
|
||||||
@@ -296,50 +292,48 @@ class WTVMime {
|
|||||||
|
|
||||||
generateMultipartMIME(tuples, options) {
|
generateMultipartMIME(tuples, options) {
|
||||||
// modified for creating usenet compliant headers/content from an attachment
|
// modified for creating usenet compliant headers/content from an attachment
|
||||||
var CRLF = '\n';
|
const CRLF = '\n';
|
||||||
if (tuples.length === 0) {
|
if (tuples.length === 0) {
|
||||||
// according to rfc1341 there should be at least one encapsulation
|
// according to rfc1341 there should be at least one encapsulation
|
||||||
throw new Error('Missing argument. At least one part to generate is required');
|
throw new Error('Missing argument. At least one part to generate is required');
|
||||||
}
|
}
|
||||||
|
|
||||||
options = options || {};
|
options = options || {};
|
||||||
var preamble = options.preamble || "This is a multi-part message in MIME format.";
|
const preamble = options.preamble || "This is a multi-part message in MIME format.";
|
||||||
var epilogue = options.epilogue;
|
const epilogue = options.epilogue;
|
||||||
var boundary = options.boundary || "------------" + this.wtvshared.generateString(24);
|
const boundary = options.boundary || "------------" + this.wtvshared.generateString(24);
|
||||||
|
|
||||||
if (boundary.length < 1 || boundary.length > 70) {
|
if (boundary.length < 1 || boundary.length > 70) {
|
||||||
throw new Error('Boundary should be between 1 and 70 characters long');
|
throw new Error('Boundary should be between 1 and 70 characters long');
|
||||||
}
|
}
|
||||||
|
|
||||||
var boundary_header = 'multipart/mixed; boundary="' + boundary + '"';
|
const boundary_header = 'multipart/mixed; boundary="' + boundary + '"';
|
||||||
|
|
||||||
var delimiter = CRLF + '--' + boundary;
|
const delimiter = CRLF + '--' + boundary;
|
||||||
var closeDelimiter = delimiter + '--';
|
const closeDelimiter = delimiter + '--';
|
||||||
|
|
||||||
var wtvshared = this.wtvshared;
|
const encapsulations = tuples.map(function (tuple, i) {
|
||||||
|
const mimetype = tuple.mime || 'text/plain';
|
||||||
|
const encoding = tuple.encoding || 'utf-8';
|
||||||
|
const use_base64 = tuple.use_base64 || !this.wtvshared.isASCII(tuple.content);
|
||||||
|
const is_base64 = tuple.is_base64 || this.wtvshared.isBase64(tuple.content);
|
||||||
|
const filename = (tuple.filename) ? tuple.filename : (use_base64) ? ('file' + i) : null;
|
||||||
|
|
||||||
var encapsulations = tuples.map(function (tuple, i) {
|
const headers = [
|
||||||
var mimetype = tuple.mime || 'text/plain';
|
|
||||||
var encoding = tuple.encoding || 'utf-8';
|
|
||||||
var use_base64 = tuple.use_base64 || !wtvshared.isASCII(tuple.content);
|
|
||||||
var is_base64 = tuple.is_base64 || wtvshared.isBase64(tuple.content);
|
|
||||||
var filename = (tuple.filename) ? tuple.filename : (use_base64) ? ('file' + i) : null;
|
|
||||||
|
|
||||||
var headers = [
|
|
||||||
`Content-Type: ${mimetype}; ${(use_base64) ? `name="${filename}"` : `charset=${encoding.toUpperCase()}; format=flowed`}`,
|
`Content-Type: ${mimetype}; ${(use_base64) ? `name="${filename}"` : `charset=${encoding.toUpperCase()}; format=flowed`}`,
|
||||||
];
|
];
|
||||||
|
|
||||||
if (filename) headers.push(`Content-Disposition: attachment; filename="${filename}"`);
|
if (filename) headers.push(`Content-Disposition: attachment; filename="${filename}"`);
|
||||||
headers.push(`Content-Transfer-Encoding: ${(use_base64) ? 'base64' : '7bit'}`);
|
headers.push(`Content-Transfer-Encoding: ${(use_base64) ? 'base64' : '7bit'}`);
|
||||||
|
|
||||||
var bodyPart = headers.join(CRLF) + CRLF + CRLF;
|
let bodyPart = headers.join(CRLF) + CRLF + CRLF;
|
||||||
if (use_base64 && !is_base64) bodyPart += wtvshared.lineWrap(Buffer.from(tuple.content).toString('base64'),72) + CRLF;
|
if (use_base64 && !is_base64) bodyPart += this.wtvshared.lineWrap(Buffer.from(tuple.content).toString('base64'),72) + CRLF;
|
||||||
else bodyPart += wtvshared.lineWrap(tuple.content,72);
|
else bodyPart += this.wtvshared.lineWrap(tuple.content,72);
|
||||||
|
|
||||||
return delimiter + CRLF + bodyPart;
|
return delimiter + CRLF + bodyPart;
|
||||||
});
|
});
|
||||||
|
|
||||||
var multipartBody = [
|
const multipartBody = [
|
||||||
preamble ? preamble : undefined,
|
preamble ? preamble : undefined,
|
||||||
encapsulations.join(''),
|
encapsulations.join(''),
|
||||||
closeDelimiter,
|
closeDelimiter,
|
||||||
|
|||||||
@@ -401,7 +401,7 @@ class WTVMinifyingProxy {
|
|||||||
return cssDimension;
|
return cssDimension;
|
||||||
}
|
}
|
||||||
// Remove !important and other CSS-specific suffixes
|
// Remove !important and other CSS-specific suffixes
|
||||||
let cleanDimension = cssDimension.replace(/\s*!important\s*/, '').trim();
|
const cleanDimension = cssDimension.replace(/\s*!important\s*/, '').trim();
|
||||||
|
|
||||||
// For other units or plain numbers, return as-is
|
// For other units or plain numbers, return as-is
|
||||||
return cleanDimension;
|
return cleanDimension;
|
||||||
@@ -487,7 +487,7 @@ class WTVMinifyingProxy {
|
|||||||
// Extract button text to determine appropriate width
|
// Extract button text to determine appropriate width
|
||||||
const valueMatch = attributes.match(/value="([^"]*)"/) || ['', ''];
|
const valueMatch = attributes.match(/value="([^"]*)"/) || ['', ''];
|
||||||
const buttonText = valueMatch[1];
|
const buttonText = valueMatch[1];
|
||||||
let buttonWidth = Math.max(buttonText.length * 8, 80); // Minimum 80px
|
const buttonWidth = Math.max(buttonText.length * 8, 80); // Minimum 80px
|
||||||
attributes = attributes.trim() + ` width="${buttonWidth}"`;
|
attributes = attributes.trim() + ` width="${buttonWidth}"`;
|
||||||
}
|
}
|
||||||
return `<input ${attributes}>`;
|
return `<input ${attributes}>`;
|
||||||
@@ -751,7 +751,7 @@ ${bodyContent}
|
|||||||
const title = titleMatch ? titleMatch[1].trim() : 'WebTV Page';
|
const title = titleMatch ? titleMatch[1].trim() : 'WebTV Page';
|
||||||
|
|
||||||
// Transform the HTML content
|
// Transform the HTML content
|
||||||
let transformed = this.transformHtml(html, url);
|
const transformed = this.transformHtml(html, url);
|
||||||
|
|
||||||
// Extract body content from either the transformed HTML or use all content
|
// Extract body content from either the transformed HTML or use all content
|
||||||
let bodyContent = '';
|
let bodyContent = '';
|
||||||
@@ -837,7 +837,7 @@ ${bodyContent}
|
|||||||
// Check if width exists and ensure it's reasonable for WebTV
|
// Check if width exists and ensure it's reasonable for WebTV
|
||||||
const widthMatch = attributes.match(/width\s*=\s*["']?(\d+)["']?/);
|
const widthMatch = attributes.match(/width\s*=\s*["']?(\d+)["']?/);
|
||||||
if (widthMatch) {
|
if (widthMatch) {
|
||||||
let width = parseInt(widthMatch[1]);
|
const width = parseInt(widthMatch[1]);
|
||||||
// Ensure minimum width of 200px for text inputs on WebTV
|
// Ensure minimum width of 200px for text inputs on WebTV
|
||||||
if (width < 200) {
|
if (width < 200) {
|
||||||
newAttributes = attributes.replace(/width\s*=\s*["']?\d+["']?/, `width="200"`);
|
newAttributes = attributes.replace(/width\s*=\s*["']?\d+["']?/, `width="200"`);
|
||||||
@@ -894,7 +894,7 @@ ${bodyContent}
|
|||||||
// Ensure minimum width for buttons
|
// Ensure minimum width for buttons
|
||||||
const widthMatch = attributes.match(/width\s*=\s*["']?(\d+)["']?/);
|
const widthMatch = attributes.match(/width\s*=\s*["']?(\d+)["']?/);
|
||||||
if (widthMatch) {
|
if (widthMatch) {
|
||||||
let width = parseInt(widthMatch[1]);
|
const width = parseInt(widthMatch[1]);
|
||||||
if (width < 80) {
|
if (width < 80) {
|
||||||
newAttributes = attributes.replace(/width\s*=\s*["']?\d+["']?/, `width="80"`);
|
newAttributes = attributes.replace(/width\s*=\s*["']?\d+["']?/, `width="80"`);
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -238,7 +238,7 @@ class WTVNews {
|
|||||||
}
|
}
|
||||||
|
|
||||||
getHeaderFromMessage(message, header) {
|
getHeaderFromMessage(message, header) {
|
||||||
const response = null;
|
let response;
|
||||||
if (message.article.headers) {
|
if (message.article.headers) {
|
||||||
Object.keys(message.article.headers).forEach((k) => {
|
Object.keys(message.article.headers).forEach((k) => {
|
||||||
if (k.toLowerCase() == header.toLowerCase()) {
|
if (k.toLowerCase() == header.toLowerCase()) {
|
||||||
@@ -255,7 +255,7 @@ class WTVNews {
|
|||||||
this.client.quit().then((response) => {
|
this.client.quit().then((response) => {
|
||||||
if (response.code == 205) resolve(true);
|
if (response.code == 205) resolve(true);
|
||||||
else {
|
else {
|
||||||
console.error(" * WTVNews Error:", "Command: quit", e);
|
console.error(" * WTVNews Error:", "Command: quit", response.code);
|
||||||
reject(`Unexpected response code ${response.code}`);
|
reject(`Unexpected response code ${response.code}`);
|
||||||
}
|
}
|
||||||
}).catch((e) => {
|
}).catch((e) => {
|
||||||
@@ -291,7 +291,7 @@ class WTVNews {
|
|||||||
this.client.post()
|
this.client.post()
|
||||||
.then((response) => {
|
.then((response) => {
|
||||||
if (response.code == 340) {
|
if (response.code == 340) {
|
||||||
var articleData = {};
|
const articleData = {};
|
||||||
articleData.headers = {
|
articleData.headers = {
|
||||||
'Relay-Version': "version zefie_wtvp_minisrv " + this.minisrv_config.version + "; site " + this.minisrv_config.config.domain_name,
|
'Relay-Version': "version zefie_wtvp_minisrv " + this.minisrv_config.version + "; site " + this.minisrv_config.config.domain_name,
|
||||||
'Posting-Version': "version zefie_wtvp_minisrv " + this.minisrv_config.version + "; site " + this.minisrv_config.config.domain_name,
|
'Posting-Version': "version zefie_wtvp_minisrv " + this.minisrv_config.version + "; site " + this.minisrv_config.config.domain_name,
|
||||||
@@ -328,7 +328,7 @@ class WTVNews {
|
|||||||
});
|
});
|
||||||
} else {
|
} else {
|
||||||
this.client.quit();
|
this.client.quit();
|
||||||
console.error('usenet upstream uncaught error', e);
|
console.error('usenet upstream uncaught error');
|
||||||
reject("Could not send post. Server returned unknown error");
|
reject("Could not send post. Server returned unknown error");
|
||||||
};
|
};
|
||||||
}).catch((e) => {
|
}).catch((e) => {
|
||||||
@@ -393,13 +393,13 @@ class WTVNews {
|
|||||||
let message_type = 'text/plain';
|
let message_type = 'text/plain';
|
||||||
body.forEach((element) => {
|
body.forEach((element) => {
|
||||||
let section_type = null;
|
let section_type = null;
|
||||||
let section = element.split("\n");
|
const section = element.split("\n");
|
||||||
attachments[i] = {};
|
attachments[i] = {};
|
||||||
section.forEach((line) => {
|
section.forEach((line) => {
|
||||||
this.debug('section_type', section_type, 'line', line);
|
this.debug('section_type', section_type, 'line', line);
|
||||||
const section_header_match = line.match(/^Content\-/i)
|
const section_header_match = line.match(/^Content\-/i)
|
||||||
if (section_header_match) {
|
if (section_header_match) {
|
||||||
const section_match = line.match(/^Content\-Type\: (.+)\;/i)
|
let section_match = line.match(/^Content\-Type\: (.+)\;/i)
|
||||||
if (section_match) {
|
if (section_match) {
|
||||||
this.debug('section_match', section_match)
|
this.debug('section_match', section_match)
|
||||||
section_type = section_match[1];
|
section_type = section_match[1];
|
||||||
@@ -474,10 +474,10 @@ class WTVNews {
|
|||||||
Object.keys(message_relations[j]).forEach((h) => {
|
Object.keys(message_relations[j]).forEach((h) => {
|
||||||
if (found) return;
|
if (found) return;
|
||||||
if (message_relations[j][h].messageId == ref) {
|
if (message_relations[j][h].messageId == ref) {
|
||||||
var searchref = messages[message_relations[j][h].index].headers.REFERENCES || null;
|
let searchref = messages[message_relations[j][h].index].headers.REFERENCES || null;
|
||||||
var mainref = j; // j is already the main reference messageId
|
let mainref = j; // j is already the main reference messageId
|
||||||
while (searchref !== null) {
|
while (searchref !== null) {
|
||||||
var searchart = messages.find(e => e.messageId == searchref);
|
const searchart = messages.find(e => e.messageId == searchref);
|
||||||
if (searchart) {
|
if (searchart) {
|
||||||
mainref = searchart.messageId;
|
mainref = searchart.messageId;
|
||||||
searchref = searchart.headers.REFERENCES || null;
|
searchref = searchart.headers.REFERENCES || null;
|
||||||
|
|||||||
@@ -17,7 +17,7 @@ class WTVNewsServer {
|
|||||||
this.wtvshared = new WTVShared(this.minisrv_config);
|
this.wtvshared = new WTVShared(this.minisrv_config);
|
||||||
this.featuredGroups = minisrv_config.services['wtv-news'].featuredGroups;
|
this.featuredGroups = minisrv_config.services['wtv-news'].featuredGroups;
|
||||||
const nntp_server = require('nntp-server-zefie');
|
const nntp_server = require('nntp-server-zefie');
|
||||||
var nntp_statuses = require('nntp-server-zefie/lib/status');
|
const nntp_statuses = require('nntp-server-zefie/lib/status');
|
||||||
|
|
||||||
this.username = username || null;
|
this.username = username || null;
|
||||||
this.password = password || null;
|
this.password = password || null;
|
||||||
@@ -34,7 +34,7 @@ class WTVNewsServer {
|
|||||||
|
|
||||||
if (run_server) {
|
if (run_server) {
|
||||||
// nntp-server module overrides
|
// nntp-server module overrides
|
||||||
var self = this;
|
const self = this;
|
||||||
|
|
||||||
nntp_server.prototype = {
|
nntp_server.prototype = {
|
||||||
...nntp_server.prototype,
|
...nntp_server.prototype,
|
||||||
@@ -65,7 +65,7 @@ class WTVNewsServer {
|
|||||||
if (!session.group.name) return nntp_statuses._412_GRP_NOT_SLCTD;
|
if (!session.group.name) return nntp_statuses._412_GRP_NOT_SLCTD;
|
||||||
if (!session.group.current_article) return nntp_statuses._420_ARTICLE_NOT_SLCTD;
|
if (!session.group.current_article) return nntp_statuses._420_ARTICLE_NOT_SLCTD;
|
||||||
if (!self.articleExists(session.group.name, session.group.current_article)) return nntp_statuses._420_ARTICLE_NOT_SLCTD;
|
if (!self.articleExists(session.group.name, session.group.current_article)) return nntp_statuses._420_ARTICLE_NOT_SLCTD;
|
||||||
var res = self.getLastArticle(session.group.name, session.group.current_article);
|
const res = self.getLastArticle(session.group.name, session.group.current_article);
|
||||||
if (!res) return nntp_statuses._422_NO_LAST_ARTICLE;
|
if (!res) return nntp_statuses._422_NO_LAST_ARTICLE;
|
||||||
return res;
|
return res;
|
||||||
},
|
},
|
||||||
@@ -74,14 +74,14 @@ class WTVNewsServer {
|
|||||||
if (!session.group.name) return nntp_statuses._412_GRP_NOT_SLCTD;
|
if (!session.group.name) return nntp_statuses._412_GRP_NOT_SLCTD;
|
||||||
if (!session.group.current_article) return nntp_statuses._420_ARTICLE_NOT_SLCTD;
|
if (!session.group.current_article) return nntp_statuses._420_ARTICLE_NOT_SLCTD;
|
||||||
if (!self.articleExists(session.group.name, session.group.current_article)) return nntp_statuses._420_ARTICLE_NOT_SLCTD;
|
if (!self.articleExists(session.group.name, session.group.current_article)) return nntp_statuses._420_ARTICLE_NOT_SLCTD;
|
||||||
var res = self.getNextArticle(session.group.name, session.group.current_article);
|
const res = self.getNextArticle(session.group.name, session.group.current_article);
|
||||||
if (!res) return nntp_statuses._421_NO_NEXT_ARTICLE;
|
if (!res) return nntp_statuses._421_NO_NEXT_ARTICLE;
|
||||||
return res;
|
return res;
|
||||||
},
|
},
|
||||||
|
|
||||||
_selectGroup: function (session, name) {
|
_selectGroup: function (session, name) {
|
||||||
// selectGroup
|
// selectGroup
|
||||||
var res = self.selectGroup(name);
|
const res = self.selectGroup(name);
|
||||||
if (!res.failed) {
|
if (!res.failed) {
|
||||||
session.group = res;
|
session.group = res;
|
||||||
return true;
|
return true;
|
||||||
@@ -90,7 +90,7 @@ class WTVNewsServer {
|
|||||||
},
|
},
|
||||||
|
|
||||||
_buildHead: function (session, message) {
|
_buildHead: function (session, message) {
|
||||||
var out = "";
|
let out = "";
|
||||||
Object.keys(message.headers).forEach((k) => {
|
Object.keys(message.headers).forEach((k) => {
|
||||||
if (k.length > 0) out += `${k}: ${message.headers[k]}\r\n`;
|
if (k.length > 0) out += `${k}: ${message.headers[k]}\r\n`;
|
||||||
});
|
});
|
||||||
@@ -100,13 +100,13 @@ class WTVNewsServer {
|
|||||||
|
|
||||||
_buildHeaderField: function (session, message, field) {
|
_buildHeaderField: function (session, message, field) {
|
||||||
if (field.indexOf(':') > 0) field = field.replace(/\:/g, '');
|
if (field.indexOf(':') > 0) field = field.replace(/\:/g, '');
|
||||||
var search = self.getHeader(message, field);
|
const search = self.getHeader(message, field);
|
||||||
if (search) return search;
|
if (search) return search;
|
||||||
else return null;
|
else return null;
|
||||||
},
|
},
|
||||||
|
|
||||||
_getOverviewFmt: function (session) {
|
_getOverviewFmt: function (session) {
|
||||||
var headers = [
|
const headers = [
|
||||||
"Subject:",
|
"Subject:",
|
||||||
"From:",
|
"From:",
|
||||||
"Date:",
|
"Date:",
|
||||||
@@ -120,7 +120,7 @@ class WTVNewsServer {
|
|||||||
_getArticle: function (session, message_id) {
|
_getArticle: function (session, message_id) {
|
||||||
// getArticle
|
// getArticle
|
||||||
return new Promise((resolve, reject) => {
|
return new Promise((resolve, reject) => {
|
||||||
var res = self.getArticle(session.group.name, message_id);
|
const res = self.getArticle(session.group.name, message_id);
|
||||||
if (!res.messageId) reject(res);
|
if (!res.messageId) reject(res);
|
||||||
else resolve(res)
|
else resolve(res)
|
||||||
});
|
});
|
||||||
@@ -131,7 +131,7 @@ class WTVNewsServer {
|
|||||||
},
|
},
|
||||||
|
|
||||||
_getRange: function (session, first, last) {
|
_getRange: function (session, first, last) {
|
||||||
var res = self.listGroup(session.group.name, first, last)
|
const res = self.listGroup(session.group.name, first, last)
|
||||||
if (res.failed) return false;
|
if (res.failed) return false;
|
||||||
session.group = res.group_data;
|
session.group = res.group_data;
|
||||||
return res.articles;
|
return res.articles;
|
||||||
@@ -139,7 +139,7 @@ class WTVNewsServer {
|
|||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
var tls_options = {
|
const tls_options = {
|
||||||
ca: this.wtvshared.getServiceDep('wtv-news' + this.path.sep + 'localserver_ca.pem'),
|
ca: this.wtvshared.getServiceDep('wtv-news' + this.path.sep + 'localserver_ca.pem'),
|
||||||
key: this.wtvshared.getServiceDep('wtv-news' + this.path.sep + 'localserver_key.pem'),
|
key: this.wtvshared.getServiceDep('wtv-news' + this.path.sep + 'localserver_key.pem'),
|
||||||
cert: this.wtvshared.getServiceDep('wtv-news' + this.path.sep + 'localserver_cert.pem'),
|
cert: this.wtvshared.getServiceDep('wtv-news' + this.path.sep + 'localserver_cert.pem'),
|
||||||
@@ -150,14 +150,14 @@ class WTVNewsServer {
|
|||||||
}
|
}
|
||||||
|
|
||||||
getMetaFilename(group) {
|
getMetaFilename(group) {
|
||||||
var g = this.getGroupPath(group);
|
const g = this.getGroupPath(group);
|
||||||
if (g) return g + this.path.sep + "meta.json";
|
if (g) return g + this.path.sep + "meta.json";
|
||||||
else return null;
|
else return null;
|
||||||
}
|
}
|
||||||
|
|
||||||
getHeader(message, header) {
|
getHeader(message, header) {
|
||||||
if (message.headers) {
|
if (message.headers) {
|
||||||
var search = Object.keys(message.headers).find(e => (e.toLowerCase() == header.toLowerCase()));
|
const search = Object.keys(message.headers).find(e => (e.toLowerCase() == header.toLowerCase()));
|
||||||
if (search) return message.headers[search];
|
if (search) return message.headers[search];
|
||||||
}
|
}
|
||||||
return null;
|
return null;
|
||||||
@@ -172,7 +172,7 @@ class WTVNewsServer {
|
|||||||
createMetaFile(group, description = null) {
|
createMetaFile(group, description = null) {
|
||||||
const g = this.getMetaFilename(group);
|
const g = this.getMetaFilename(group);
|
||||||
if (this.fs.existsSync(g)) return false;
|
if (this.fs.existsSync(g)) return false;
|
||||||
var metadata = this.selectGroup(group, true, true);
|
const metadata = this.selectGroup(group, true, true);
|
||||||
if (description) metadata.description = description;
|
if (description) metadata.description = description;
|
||||||
this.saveMetadata(group, metadata, true);
|
this.saveMetadata(group, metadata, true);
|
||||||
return (!metadata.failed) ? metadata : false
|
return (!metadata.failed) ? metadata : false
|
||||||
@@ -196,7 +196,7 @@ class WTVNewsServer {
|
|||||||
|
|
||||||
findHeaderCaseInsensitive(headers, header) {
|
findHeaderCaseInsensitive(headers, header) {
|
||||||
// returns the key with the found case
|
// returns the key with the found case
|
||||||
var response = null;
|
let response;
|
||||||
if (headers) {
|
if (headers) {
|
||||||
Object.keys(headers).forEach((k) => {
|
Object.keys(headers).forEach((k) => {
|
||||||
if (k.toLowerCase() == header.toLowerCase()) {
|
if (k.toLowerCase() == header.toLowerCase()) {
|
||||||
@@ -209,13 +209,13 @@ class WTVNewsServer {
|
|||||||
}
|
}
|
||||||
|
|
||||||
postArticle(group, post_data) {
|
postArticle(group, post_data) {
|
||||||
var articleNumber = this.getMetadata(group).max_index + 1;
|
const articleNumber = this.getMetadata(group).max_index + 1;
|
||||||
if (!articleNumber) return false;
|
if (!articleNumber) return false;
|
||||||
try {
|
try {
|
||||||
post_data.articleNumber = articleNumber;
|
post_data.articleNumber = articleNumber;
|
||||||
post_data.messageId = this.getHeader(post_data, "message-id");
|
post_data.messageId = this.getHeader(post_data, "message-id");
|
||||||
if (!post_data.messageId) {
|
if (!post_data.messageId) {
|
||||||
var messageId = "<" + this.wtvshared.generateString(16) + "@" + this.minisrv_config.config.domain_name + ">";
|
const messageId = "<" + this.wtvshared.generateString(16) + "@" + this.minisrv_config.config.domain_name + ">";
|
||||||
post_data.messageId = post_data.headers['Message-ID'] = messageId;
|
post_data.messageId = post_data.headers['Message-ID'] = messageId;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -246,11 +246,11 @@ class WTVNewsServer {
|
|||||||
}
|
}
|
||||||
|
|
||||||
createArticle(group, articleNumber, article) {
|
createArticle(group, articleNumber, article) {
|
||||||
var g = this.getGroupPath(group);
|
const g = this.getGroupPath(group);
|
||||||
var file = g + this.path.sep + articleNumber + ".newz";
|
const file = g + this.path.sep + articleNumber + ".newz";
|
||||||
try {
|
try {
|
||||||
this.fs.writeFileSync(file, JSON.stringify(article));
|
this.fs.writeFileSync(file, JSON.stringify(article));
|
||||||
var metadata = this.getMetadata(group);
|
const metadata = this.getMetadata(group);
|
||||||
metadata.max_index = metadata.max_index + 1;
|
metadata.max_index = metadata.max_index + 1;
|
||||||
metadata.total = metadata.total + 1;
|
metadata.total = metadata.total + 1;
|
||||||
this.saveMetadata(group, metadata)
|
this.saveMetadata(group, metadata)
|
||||||
@@ -276,7 +276,7 @@ class WTVNewsServer {
|
|||||||
}
|
}
|
||||||
|
|
||||||
createGroup(group, description = null) {
|
createGroup(group, description = null) {
|
||||||
var g = this.getGroupPath(group);
|
const g = this.getGroupPath(group);
|
||||||
if (!this.fs.existsSync(g)) {
|
if (!this.fs.existsSync(g)) {
|
||||||
this.fs.mkdirSync(g);
|
this.fs.mkdirSync(g);
|
||||||
return this.createMetaFile(group, description)
|
return this.createMetaFile(group, description)
|
||||||
@@ -288,7 +288,7 @@ class WTVNewsServer {
|
|||||||
const g = this.getArticlePath(group, article);
|
const g = this.getArticlePath(group, article);
|
||||||
if (!this.fs.existsSync(g)) return false;
|
if (!this.fs.existsSync(g)) return false;
|
||||||
try {
|
try {
|
||||||
var data = JSON.parse(this.fs.readFileSync(g));
|
let data = JSON.parse(this.fs.readFileSync(g));
|
||||||
if (data.article) data = data.article;
|
if (data.article) data = data.article;
|
||||||
data.index = data.articleNumber;
|
data.index = data.articleNumber;
|
||||||
if (!data.body) data.body = [''];
|
if (!data.body) data.body = [''];
|
||||||
@@ -302,18 +302,18 @@ class WTVNewsServer {
|
|||||||
|
|
||||||
|
|
||||||
selectGroup(group, force_update = false, initial_update = false) {
|
selectGroup(group, force_update = false, initial_update = false) {
|
||||||
var g = this.getGroupPath(group);
|
const g = this.getGroupPath(group);
|
||||||
var meta = this.getMetadata(group);
|
let meta = this.getMetadata(group);
|
||||||
if (!meta) force_update, initial_update = true;
|
if (!meta) force_update, initial_update = true;
|
||||||
|
let out;
|
||||||
if (initial_update) {
|
if (initial_update) {
|
||||||
var out = {
|
out = {
|
||||||
total: 0,
|
total: 0,
|
||||||
min_index: 0,
|
min_index: 0,
|
||||||
max_index: 0,
|
max_index: 0,
|
||||||
name: group
|
name: group
|
||||||
}
|
}
|
||||||
} else var out = { ...meta }
|
} else out = { ...meta }
|
||||||
|
|
||||||
if (meta.min_index == 0) force_update = true;
|
if (meta.min_index == 0) force_update = true;
|
||||||
if (this.featuredGroups) {
|
if (this.featuredGroups) {
|
||||||
@@ -330,7 +330,7 @@ class WTVNewsServer {
|
|||||||
out.total = 0;
|
out.total = 0;
|
||||||
this.fs.readdirSync(g).forEach(file => {
|
this.fs.readdirSync(g).forEach(file => {
|
||||||
if (file == "meta.json") return;
|
if (file == "meta.json") return;
|
||||||
var articleNumber = parseInt(file.split('.')[0]);
|
const articleNumber = parseInt(file.split('.')[0]);
|
||||||
if (out.min_index == 0) out.min_index = articleNumber;
|
if (out.min_index == 0) out.min_index = articleNumber;
|
||||||
else if (articleNumber < out.min_index) out.min_index = articleNumber;
|
else if (articleNumber < out.min_index) out.min_index = articleNumber;
|
||||||
else if (articleNumber > out.max_index) out.max_index = articleNumber;
|
else if (articleNumber > out.max_index) out.max_index = articleNumber;
|
||||||
@@ -354,7 +354,7 @@ class WTVNewsServer {
|
|||||||
}
|
}
|
||||||
|
|
||||||
getGroups(wildmat = null) {
|
getGroups(wildmat = null) {
|
||||||
var groups = [];
|
const groups = [];
|
||||||
this.fs.readdirSync(this.data_path).forEach(file => {
|
this.fs.readdirSync(this.data_path).forEach(file => {
|
||||||
if (this.fs.lstatSync(this.data_path + this.path.sep + file).isDirectory()) {
|
if (this.fs.lstatSync(this.data_path + this.path.sep + file).isDirectory()) {
|
||||||
if (wildmat) {
|
if (wildmat) {
|
||||||
@@ -366,24 +366,24 @@ class WTVNewsServer {
|
|||||||
}
|
}
|
||||||
|
|
||||||
getLastArticle(group, current) {
|
getLastArticle(group, current) {
|
||||||
var g = this.getGroupPath(group);
|
const g = this.getGroupPath(group);
|
||||||
var res = null;
|
let res;
|
||||||
try {
|
try {
|
||||||
var articleNumbers = [];
|
const articleNumbers = [];
|
||||||
this.fs.readdirSync(g).forEach(file => {
|
this.fs.readdirSync(g).forEach(file => {
|
||||||
if (file == "meta.json") return;
|
if (file == "meta.json") return;
|
||||||
var articleNumber = parseInt(file.split('.')[0]);
|
const articleNumber = parseInt(file.split('.')[0]);
|
||||||
articleNumbers.push(articleNumber);
|
articleNumbers.push(articleNumber);
|
||||||
});
|
});
|
||||||
articleNumbers.sort((a, b) => a - b)
|
articleNumbers.sort((a, b) => a - b)
|
||||||
var index = articleNumbers.findIndex((e) => e == current) - 1;
|
const index = articleNumbers.findIndex((e) => e == current) - 1;
|
||||||
if (index >= 0) res = articleNumbers[index];
|
if (index >= 0) res = articleNumbers[index];
|
||||||
} catch (e) {
|
} catch (e) {
|
||||||
return e;
|
return e;
|
||||||
}
|
}
|
||||||
if (res) {
|
if (res) {
|
||||||
if (res == current) return null;
|
if (res == current) return null;
|
||||||
var message = this.getArticle(group, res);
|
const message = this.getArticle(group, res);
|
||||||
if (message.messageId) {
|
if (message.messageId) {
|
||||||
res = { "articleNumber": res, "message_id": message.messageId };
|
res = { "articleNumber": res, "message_id": message.messageId };
|
||||||
}
|
}
|
||||||
@@ -392,23 +392,23 @@ class WTVNewsServer {
|
|||||||
}
|
}
|
||||||
|
|
||||||
getNextArticle(group, current) {
|
getNextArticle(group, current) {
|
||||||
var g = this.getGroupPath(group);
|
const g = this.getGroupPath(group);
|
||||||
var res = null;
|
let res;
|
||||||
try {
|
try {
|
||||||
var articleNumbers = [];
|
const articleNumbers = [];
|
||||||
this.fs.readdirSync(g).forEach(file => {
|
this.fs.readdirSync(g).forEach(file => {
|
||||||
if (file == "meta.json") return;
|
if (file == "meta.json") return;
|
||||||
var articleNumber = parseInt(file.split('.')[0]);
|
const articleNumber = parseInt(file.split('.')[0]);
|
||||||
articleNumbers.push(articleNumber);
|
articleNumbers.push(articleNumber);
|
||||||
});
|
});
|
||||||
articleNumbers.sort((a, b) => a - b)
|
articleNumbers.sort((a, b) => a - b)
|
||||||
var index = articleNumbers.findIndex((e) => e == current) + 1;
|
const index = articleNumbers.findIndex((e) => e == current) + 1;
|
||||||
if (index < articleNumbers.length) res = articleNumbers[index];
|
if (index < articleNumbers.length) res = articleNumbers[index];
|
||||||
} catch (e) {
|
} catch (e) {
|
||||||
return e;
|
return e;
|
||||||
}
|
}
|
||||||
if (res) {
|
if (res) {
|
||||||
var message = this.getArticle(group, res);
|
const message = this.getArticle(group, res);
|
||||||
if (message.messageId) {
|
if (message.messageId) {
|
||||||
res = { "articleNumber": res, "message_id": message.messageId };
|
res = { "articleNumber": res, "message_id": message.messageId };
|
||||||
}
|
}
|
||||||
@@ -432,28 +432,29 @@ class WTVNewsServer {
|
|||||||
}
|
}
|
||||||
|
|
||||||
listGroup(group, start, end, force_update = false) {
|
listGroup(group, start, end, force_update = false) {
|
||||||
var g = this.getGroupPath(group);
|
const g = this.getGroupPath(group);
|
||||||
var out = {
|
const out = {
|
||||||
total: 0,
|
total: 0,
|
||||||
min_index: 0,
|
min_index: 0,
|
||||||
max_index: 0,
|
max_index: 0,
|
||||||
name: group
|
name: group
|
||||||
}
|
}
|
||||||
var articles = [];
|
let meta;
|
||||||
|
const articles = [];
|
||||||
try {
|
try {
|
||||||
var meta = this.getMetadata(group);
|
meta = this.getMetadata(group);
|
||||||
this.fs.readdirSync(g).forEach(file => {
|
this.fs.readdirSync(g).forEach(file => {
|
||||||
if (file == "meta.json") return;
|
if (file == "meta.json") return;
|
||||||
var articleNumber = parseInt(file.split('.')[0]);
|
const articleNumber = parseInt(file.split('.')[0]);
|
||||||
if (articleNumber < start) return;
|
if (articleNumber < start) return;
|
||||||
if (articleNumber > end) return false;
|
if (articleNumber > end) return false;
|
||||||
if (out.min_index == null) out.min_index = articleNumber;
|
if (out.min_index == null) out.min_index = articleNumber;
|
||||||
else if (articleNumber < out.min_index) out.min_index = articleNumber;
|
else if (articleNumber < out.min_index) out.min_index = articleNumber;
|
||||||
|
|
||||||
if (articleNumber > out.max_index) out.max_index = articleNumber;
|
if (articleNumber > out.max_index) out.max_index = articleNumber;
|
||||||
articles.push(this.getArticle(group, articleNumber));
|
articles.push(this.getArticle(group, articleNumber));
|
||||||
out.total++;
|
out.total++;
|
||||||
});
|
});
|
||||||
if (force_update || this.doesMetaNeedRefreshing(meta)) {
|
if (force_update || this.doesMetaNeedRefreshing(meta)) {
|
||||||
meta = { ...meta, ...out }
|
meta = { ...meta, ...out }
|
||||||
meta.last_scan = Math.floor(Date.now() / 1000);
|
meta.last_scan = Math.floor(Date.now() / 1000);
|
||||||
|
|||||||
@@ -30,8 +30,8 @@ class WTVRegister {
|
|||||||
* @returns {boolean} True if the username is valid, false otherwise
|
* @returns {boolean} True if the username is valid, false otherwise
|
||||||
*/
|
*/
|
||||||
checkUsernameSanity(username) {
|
checkUsernameSanity(username) {
|
||||||
var regex_str = "^([A-Za-z0-9-\_]{" + this.minisrv_config.config.user_accounts.min_username_length + "," + this.minisrv_config.config.user_accounts.max_username_length + "})$";
|
const regex_str = "^([A-Za-z0-9-\_]{" + this.minisrv_config.config.user_accounts.min_username_length + "," + this.minisrv_config.config.user_accounts.max_username_length + "})$";
|
||||||
var regex = new RegExp(regex_str);
|
const regex = new RegExp(regex_str);
|
||||||
return regex.test(username);
|
return regex.test(username);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -41,8 +41,8 @@ class WTVRegister {
|
|||||||
* @returns {boolean} True if the SSID is available for registration, false if it already has an account registered.
|
* @returns {boolean} True if the SSID is available for registration, false if it already has an account registered.
|
||||||
*/
|
*/
|
||||||
checkSSIDAvailable(ssid) {
|
checkSSIDAvailable(ssid) {
|
||||||
var directory = (directory) ? directory : this.session_store_dir + this.path.sep + "accounts";
|
const directory = this.session_store_dir + this.path.sep + "accounts";
|
||||||
var available = true;
|
let available = true;
|
||||||
if (this.fs.existsSync(directory)) {
|
if (this.fs.existsSync(directory)) {
|
||||||
this.fs.readdirSync(directory).forEach(file => {
|
this.fs.readdirSync(directory).forEach(file => {
|
||||||
if (file.toLowerCase() == ssid.toLowerCase()) {
|
if (file.toLowerCase() == ssid.toLowerCase()) {
|
||||||
@@ -61,23 +61,23 @@ class WTVRegister {
|
|||||||
* @returns {boolean} True if the username is available, false if it is already taken
|
* @returns {boolean} True if the username is available, false if it is already taken
|
||||||
*/
|
*/
|
||||||
checkUsernameAvailable(username, directory = null) {
|
checkUsernameAvailable(username, directory = null) {
|
||||||
var self = this;
|
const self = this;
|
||||||
var return_val = false;
|
let return_val = false;
|
||||||
// returns the user's ssid, and user_id and userid in an array if true, false if not
|
// returns the user's ssid, and user_id and userid in an array if true, false if not
|
||||||
|
|
||||||
// check against reserved name list
|
// check against reserved name list
|
||||||
if (this.minisrv_config.config.user_accounts.reserved_names_files) {
|
if (this.minisrv_config.config.user_accounts.reserved_names_files) {
|
||||||
var reserved_names = []
|
const reserved_names = []
|
||||||
this.minisrv_config.config.user_accounts.reserved_names_files.forEach(function (v) {
|
this.minisrv_config.config.user_accounts.reserved_names_files.forEach(function (v) {
|
||||||
var data = self.fs.readFileSync(v);
|
const data = self.fs.readFileSync(v);
|
||||||
var json = JSON.parse(data);
|
const json = JSON.parse(data);
|
||||||
json.forEach(function (v) {
|
json.forEach(function (v) {
|
||||||
reserved_names.push(v);
|
reserved_names.push(v);
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|
||||||
Object.keys(reserved_names).forEach((k) => {
|
Object.keys(reserved_names).forEach((k) => {
|
||||||
var regex = new RegExp("^"+reserved_names[k]+"$", 'i');
|
const regex = new RegExp("^"+reserved_names[k]+"$", 'i');
|
||||||
if (username.match(regex)) return_val = true;
|
if (username.match(regex)) return_val = true;
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
@@ -94,8 +94,8 @@ class WTVRegister {
|
|||||||
}
|
}
|
||||||
if (!file.match(/user.*\.json/ig)) return;
|
if (!file.match(/user.*\.json/ig)) return;
|
||||||
try {
|
try {
|
||||||
var temp_session_data_file = self.fs.readFileSync(directory + self.path.sep + file, 'Utf8');
|
const temp_session_data_file = self.fs.readFileSync(directory + self.path.sep + file, 'Utf8');
|
||||||
var temp_session_data = JSON.parse(temp_session_data_file);
|
const temp_session_data = JSON.parse(temp_session_data_file);
|
||||||
if (temp_session_data.subscriber_username) {
|
if (temp_session_data.subscriber_username) {
|
||||||
if (temp_session_data.subscriber_username.toLowerCase() == username.toLowerCase()) {
|
if (temp_session_data.subscriber_username.toLowerCase() == username.toLowerCase()) {
|
||||||
return_val = true;
|
return_val = true;
|
||||||
@@ -120,7 +120,7 @@ class WTVRegister {
|
|||||||
*/
|
*/
|
||||||
getHTMLTemplate(title, main_content, form_buttons, is_old_build) {
|
getHTMLTemplate(title, main_content, form_buttons, is_old_build) {
|
||||||
try {
|
try {
|
||||||
var template = this.wtvshared.getTemplate("wtv-register", "templates/NunjucksTemplate.js", true);
|
const template = this.wtvshared.getTemplate("wtv-register", "templates/NunjucksTemplate.js", true);
|
||||||
if (this.fs.existsSync(template)) {
|
if (this.fs.existsSync(template)) {
|
||||||
const WTVRegisterTemplate = require(template);
|
const WTVRegisterTemplate = require(template);
|
||||||
|
|
||||||
|
|||||||
@@ -189,7 +189,7 @@ class WTVShared {
|
|||||||
if (isNaN(inbyte)) return '00';
|
if (isNaN(inbyte)) return '00';
|
||||||
|
|
||||||
for (let ii = 0; ii < 8; ii++) {
|
for (let ii = 0; ii < 8; ii++) {
|
||||||
let mix = (crc ^ inbyte) & 1;
|
const mix = (crc ^ inbyte) & 1;
|
||||||
crc >>= 1;
|
crc >>= 1;
|
||||||
if (mix) crc ^= 0x8C;
|
if (mix) crc ^= 0x8C;
|
||||||
inbyte >>= 1;
|
inbyte >>= 1;
|
||||||
@@ -448,7 +448,6 @@ class WTVShared {
|
|||||||
* @return {object} Headers object
|
* @return {object} Headers object
|
||||||
*/
|
*/
|
||||||
headerStringToObj(headers, response = false) {
|
headerStringToObj(headers, response = false) {
|
||||||
let inc_headers = 0;
|
|
||||||
const headers_obj = {};
|
const headers_obj = {};
|
||||||
headers_obj.raw_headers = headers;
|
headers_obj.raw_headers = headers;
|
||||||
const headers_obj_pre = headers.split("\n");
|
const headers_obj_pre = headers.split("\n");
|
||||||
@@ -474,7 +473,7 @@ class WTVShared {
|
|||||||
headers_obj.request_url = decodeURI(request_url).trim("\r");
|
headers_obj.request_url = decodeURI(request_url).trim("\r");
|
||||||
} else if (d.indexOf(":") > 0) {
|
} else if (d.indexOf(":") > 0) {
|
||||||
const d_split = d.split(':');
|
const d_split = d.split(':');
|
||||||
let header_name = d_split[0];
|
const header_name = d_split[0];
|
||||||
if (typeof headers_obj[header_name] === 'string') {
|
if (typeof headers_obj[header_name] === 'string') {
|
||||||
headers_obj[header_name] = [headers_obj[header_name]];
|
headers_obj[header_name] = [headers_obj[header_name]];
|
||||||
headers_obj[header_name].push((d_split.slice(1).join(':')).trim("\r"));
|
headers_obj[header_name].push((d_split.slice(1).join(':')).trim("\r"));
|
||||||
@@ -590,9 +589,7 @@ class WTVShared {
|
|||||||
* @returns {string} The decoded string
|
* @returns {string} The decoded string
|
||||||
*/
|
*/
|
||||||
decodeBufferText(buf) {
|
decodeBufferText(buf) {
|
||||||
var out = "";
|
return this.utf8Decode(this.iconv.decode(Buffer.from(buf),'ISO-8859-1'));;
|
||||||
out = this.utf8Decode(this.iconv.decode(Buffer.from(buf),'ISO-8859-1'));
|
|
||||||
return out;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -636,17 +633,16 @@ class WTVShared {
|
|||||||
* @notice If the file exists but cannot be parsed, it will terminate the process with an error message
|
* @notice If the file exists but cannot be parsed, it will terminate the process with an error message
|
||||||
*/
|
*/
|
||||||
getUserConfig() {
|
getUserConfig() {
|
||||||
|
let minisrv_user_config = {};
|
||||||
|
const user_config_filename = this.getAbsolutePath("user_config.json", this.appdir);
|
||||||
try {
|
try {
|
||||||
var user_config_filename = this.getAbsolutePath("user_config.json", this.appdir);
|
|
||||||
if (this.fs.lstatSync(user_config_filename)) {
|
if (this.fs.lstatSync(user_config_filename)) {
|
||||||
try {
|
try {
|
||||||
var minisrv_user_config = this.parseJSON(this.fs.readFileSync(user_config_filename));
|
minisrv_user_config = this.parseJSON(this.fs.readFileSync(user_config_filename));
|
||||||
} catch (f) {
|
} catch (f) {
|
||||||
console.error("ERROR: Could not read user_config.json", "\n\nReason:\n\n", f);
|
console.error("ERROR: Could not read user_config.json", "\n\nReason:\n\n", f);
|
||||||
this.process.exit(1);
|
this.process.exit(1);
|
||||||
}
|
}
|
||||||
} else {
|
|
||||||
var minisrv_user_config = {}
|
|
||||||
}
|
}
|
||||||
return minisrv_user_config;
|
return minisrv_user_config;
|
||||||
} catch (e) {
|
} catch (e) {
|
||||||
@@ -724,6 +720,7 @@ class WTVShared {
|
|||||||
* @returns {object} The MiniSrv configuration object
|
* @returns {object} The MiniSrv configuration object
|
||||||
*/
|
*/
|
||||||
readMiniSrvConfig(user_config = true, notices = true, reload_notice = false) {
|
readMiniSrvConfig(user_config = true, notices = true, reload_notice = false) {
|
||||||
|
let minisrv_config = {};
|
||||||
const log = (msg) => {
|
const log = (msg) => {
|
||||||
if (notices || reload_notice) console.log(msg);
|
if (notices || reload_notice) console.log(msg);
|
||||||
};
|
};
|
||||||
@@ -738,7 +735,7 @@ class WTVShared {
|
|||||||
|
|
||||||
log(" *** Reading global configuration...");
|
log(" *** Reading global configuration...");
|
||||||
try {
|
try {
|
||||||
var minisrv_config = this.parseJSON(this.fs.readFileSync(this.getAbsolutePath("includes" + this.path.sep + "config.json", this.appdir)));
|
minisrv_config = this.parseJSON(this.fs.readFileSync(this.getAbsolutePath("includes" + this.path.sep + "config.json", this.appdir)));
|
||||||
} catch (e) {
|
} catch (e) {
|
||||||
throw new Error("ERROR: Could not read config.json", e);
|
throw new Error("ERROR: Could not read config.json", e);
|
||||||
}
|
}
|
||||||
@@ -746,7 +743,7 @@ class WTVShared {
|
|||||||
if (user_config) {
|
if (user_config) {
|
||||||
log(" *** Reading user configuration...");
|
log(" *** Reading user configuration...");
|
||||||
try {
|
try {
|
||||||
let minisrv_user_config = this.getUserConfig();
|
const minisrv_user_config = this.getUserConfig();
|
||||||
minisrv_config = this.integrateConfig(minisrv_config, minisrv_user_config);
|
minisrv_config = this.integrateConfig(minisrv_config, minisrv_user_config);
|
||||||
} catch (e) {
|
} catch (e) {
|
||||||
logError("ERROR: Could not integrate user_config.json", e);
|
logError("ERROR: Could not integrate user_config.json", e);
|
||||||
@@ -804,11 +801,11 @@ class WTVShared {
|
|||||||
writeToUserConfig(config) {
|
writeToUserConfig(config) {
|
||||||
if (config) {
|
if (config) {
|
||||||
try {
|
try {
|
||||||
var minisrv_user_config = this.getUserConfig();
|
const minisrv_user_config = this.getUserConfig();
|
||||||
|
|
||||||
// write back
|
// write back
|
||||||
try {
|
try {
|
||||||
var new_user_config = {};
|
const new_user_config = {};
|
||||||
Object.assign(new_user_config, minisrv_user_config, config);
|
Object.assign(new_user_config, minisrv_user_config, config);
|
||||||
if (this.minisrv_config.config.debug_flags.debug) console.log(" * Writing new user configuration...");
|
if (this.minisrv_config.config.debug_flags.debug) console.log(" * Writing new user configuration...");
|
||||||
this.fs.writeFileSync(this.getAbsolutePath("user_config.json", this.appdir), JSON.stringify(new_user_config, null, "\t"));
|
this.fs.writeFileSync(this.getAbsolutePath("user_config.json", this.appdir), JSON.stringify(new_user_config, null, "\t"));
|
||||||
@@ -999,7 +996,7 @@ class WTVShared {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// Allocate a buffer of the correct size
|
// Allocate a buffer of the correct size
|
||||||
let decoded = Buffer.alloc(bufferLength);
|
const decoded = Buffer.alloc(bufferLength);
|
||||||
let bufferIndex = 0;
|
let bufferIndex = 0;
|
||||||
|
|
||||||
for (let i = 0; i < encoded.length; i++) {
|
for (let i = 0; i < encoded.length; i++) {
|
||||||
@@ -1082,11 +1079,11 @@ class WTVShared {
|
|||||||
const filterPasswords = this.minisrv_config.config.filter_passwords_in_logs === true;
|
const filterPasswords = this.minisrv_config.config.filter_passwords_in_logs === true;
|
||||||
try {
|
try {
|
||||||
// Assuming CryptoJS.enc.Utf8 exists and has a stringify method
|
// Assuming CryptoJS.enc.Utf8 exists and has a stringify method
|
||||||
let post_text = CryptoJS.enc.Utf8.stringify(obj.post_data);
|
const post_text = CryptoJS.enc.Utf8.stringify(obj.post_data);
|
||||||
let params = new URLSearchParams(post_text);
|
const params = new URLSearchParams(post_text);
|
||||||
|
|
||||||
if (filterPasswords) {
|
if (filterPasswords) {
|
||||||
for (let [key, value] of params) {
|
for (const [key, value] of params) {
|
||||||
const lowerKey = key.toLowerCase();
|
const lowerKey = key.toLowerCase();
|
||||||
if (/passw(or)?d|^pass$/.test(lowerKey)) {
|
if (/passw(or)?d|^pass$/.test(lowerKey)) {
|
||||||
params.set(key, '*'.repeat(value.length));
|
params.set(key, '*'.repeat(value.length));
|
||||||
@@ -1115,7 +1112,7 @@ class WTVShared {
|
|||||||
// Prevent usage
|
// Prevent usage
|
||||||
return;
|
return;
|
||||||
// Search for the module in the require cache
|
// Search for the module in the require cache
|
||||||
let resolvedPath = require.resolve(moduleName);
|
const resolvedPath = require.resolve(moduleName);
|
||||||
|
|
||||||
// Remove the module from the cache
|
// Remove the module from the cache
|
||||||
if (require.cache[resolvedPath]) {
|
if (require.cache[resolvedPath]) {
|
||||||
@@ -1460,8 +1457,8 @@ class WTVShared {
|
|||||||
* @returns {object} The modified object
|
* @returns {object} The modified object
|
||||||
*/
|
*/
|
||||||
moveObjectKey(currentKey, destKey, obj, case_insensitive = false) {
|
moveObjectKey(currentKey, destKey, obj, case_insensitive = false) {
|
||||||
let keys = Object.keys(obj);
|
const keys = Object.keys(obj);
|
||||||
let values = Object.values(obj);
|
const values = Object.values(obj);
|
||||||
|
|
||||||
const currentIndex = typeof currentKey === 'string' ? this.findObjectKeyIndex(currentKey, obj, case_insensitive) : +currentKey;
|
const currentIndex = typeof currentKey === 'string' ? this.findObjectKeyIndex(currentKey, obj, case_insensitive) : +currentKey;
|
||||||
if (currentIndex === -1) return obj;
|
if (currentIndex === -1) return obj;
|
||||||
|
|||||||
@@ -31,13 +31,13 @@ class WTVShenanigans {
|
|||||||
* @returns {boolean} True if the shenanigan is enabled, false otherwise.
|
* @returns {boolean} True if the shenanigan is enabled, false otherwise.
|
||||||
*/
|
*/
|
||||||
checkShenanigan(value) {
|
checkShenanigan(value) {
|
||||||
var level = this.getShenanigansLevel();
|
const level = this.getShenanigansLevel();
|
||||||
|
|
||||||
// shenanigans are disabled, don't iterate
|
// shenanigans are disabled, don't iterate
|
||||||
if (level === false) return false;
|
if (level === false) return false;
|
||||||
|
|
||||||
var retval = false;
|
let retval = false;
|
||||||
var shenanigans = this.shenanigans;
|
const shenanigans = this.shenanigans;
|
||||||
|
|
||||||
// shenanigans are enabled, so check if the requested shenanigan is within the level enabled
|
// shenanigans are enabled, so check if the requested shenanigan is within the level enabled
|
||||||
Object.keys(shenanigans).forEach((k) => {
|
Object.keys(shenanigans).forEach((k) => {
|
||||||
|
|||||||
@@ -130,7 +130,7 @@ class WTVTellyScriptTokenizer {
|
|||||||
if (regex.test(firstChar)) {
|
if (regex.test(firstChar)) {
|
||||||
sequence += firstChar;
|
sequence += firstChar;
|
||||||
while (this.index <= this.endIndex) {
|
while (this.index <= this.endIndex) {
|
||||||
let nextChar = this.getNextCharacter();
|
const nextChar = this.getNextCharacter();
|
||||||
if (regex.test(nextChar)) {
|
if (regex.test(nextChar)) {
|
||||||
sequence += nextChar;
|
sequence += nextChar;
|
||||||
} else {
|
} else {
|
||||||
@@ -246,13 +246,13 @@ class WTVTellyScriptTokenizer {
|
|||||||
// The main tokenize method processes the raw script and produces an array of token bytes.
|
// The main tokenize method processes the raw script and produces an array of token bytes.
|
||||||
tokenize() {
|
tokenize() {
|
||||||
while (this.index <= this.endIndex) {
|
while (this.index <= this.endIndex) {
|
||||||
let ch = this.getNextCharacter();
|
const ch = this.getNextCharacter();
|
||||||
|
|
||||||
// Handle comments starting with "/*" and ending with "*/".
|
// Handle comments starting with "/*" and ending with "*/".
|
||||||
if (ch === "/" && this.peekCharacter() === "*") {
|
if (ch === "/" && this.peekCharacter() === "*") {
|
||||||
this.getNextCharacter(); // consume '*'
|
this.getNextCharacter(); // consume '*'
|
||||||
while (this.index <= this.endIndex) {
|
while (this.index <= this.endIndex) {
|
||||||
let commentChar = this.getNextCharacter();
|
const commentChar = this.getNextCharacter();
|
||||||
if (commentChar === "*" && this.peekCharacter() === "/") {
|
if (commentChar === "*" && this.peekCharacter() === "/") {
|
||||||
this.getNextCharacter(); // consume '/'
|
this.getNextCharacter(); // consume '/'
|
||||||
break;
|
break;
|
||||||
@@ -270,7 +270,7 @@ class WTVTellyScriptTokenizer {
|
|||||||
this.tokenizeConstant();
|
this.tokenizeConstant();
|
||||||
} else {
|
} else {
|
||||||
// Try to build an identifier/number sequence.
|
// Try to build an identifier/number sequence.
|
||||||
let currentIdx = this.index;
|
const currentIdx = this.index;
|
||||||
let checkSequence = this.buildCheckSequence(ch, "^[a-zA-Z0-9_]$");
|
let checkSequence = this.buildCheckSequence(ch, "^[a-zA-Z0-9_]$");
|
||||||
if (checkSequence !== "") {
|
if (checkSequence !== "") {
|
||||||
if (this.replacements.has(checkSequence)) {
|
if (this.replacements.has(checkSequence)) {
|
||||||
@@ -285,7 +285,7 @@ class WTVTellyScriptTokenizer {
|
|||||||
if (this.replacements.has(checkSequence)) {
|
if (this.replacements.has(checkSequence)) {
|
||||||
this.tokenizedData.push(this.replacements.get(checkSequence));
|
this.tokenizedData.push(this.replacements.get(checkSequence));
|
||||||
} else if (this.replacements.has(ch)) {
|
} else if (this.replacements.has(ch)) {
|
||||||
let replacement = this.replacements.get(ch);
|
const replacement = this.replacements.get(ch);
|
||||||
if (replacement === 0x7F) {
|
if (replacement === 0x7F) {
|
||||||
this.lineNumber++;
|
this.lineNumber++;
|
||||||
}
|
}
|
||||||
@@ -777,14 +777,14 @@ class WTVTellyScriptDetokenizer {
|
|||||||
let ii = 0;
|
let ii = 0;
|
||||||
this.index++; // skip the token identifier (0x43)
|
this.index++; // skip the token identifier (0x43)
|
||||||
while (this.index < this.tokenizedData.length) {
|
while (this.index < this.tokenizedData.length) {
|
||||||
let byteVal = this.tokenizedData[this.index];
|
const byteVal = this.tokenizedData[this.index];
|
||||||
if (byteVal === 0x00) break;
|
if (byteVal === 0x00) break;
|
||||||
let digit = byteVal - 0x30;
|
const digit = byteVal - 0x30;
|
||||||
if (digit >= 0 && digit <= 0x0F) {
|
if (digit >= 0 && digit <= 0x0F) {
|
||||||
constantValue = (constantValue << 4) + digit;
|
constantValue = (constantValue << 4) + digit;
|
||||||
}
|
}
|
||||||
if (ii >= 1 && (ii % 2) === 1 && alphanumericValue !== null) {
|
if (ii >= 1 && (ii % 2) === 1 && alphanumericValue !== null) {
|
||||||
let charValue = constantValue & 0xFF;
|
const charValue = constantValue & 0xFF;
|
||||||
if (charValue >= 0x30 && charValue <= 0x5A) {
|
if (charValue >= 0x30 && charValue <= 0x5A) {
|
||||||
alphanumericValue += String.fromCharCode(charValue);
|
alphanumericValue += String.fromCharCode(charValue);
|
||||||
} else {
|
} else {
|
||||||
@@ -810,13 +810,13 @@ class WTVTellyScriptDetokenizer {
|
|||||||
// Reads a string token until the null terminator and outputs it with proper escape replacements.
|
// Reads a string token until the null terminator and outputs it with proper escape replacements.
|
||||||
detokenizeString() {
|
detokenizeString() {
|
||||||
let count = 0;
|
let count = 0;
|
||||||
let startIndex = ++this.index;
|
const startIndex = ++this.index;
|
||||||
while (this.index <= this.endIndex) {
|
while (this.index <= this.endIndex) {
|
||||||
if (this.tokenizedData[this.index] === 0x00) break;
|
if (this.tokenizedData[this.index] === 0x00) break;
|
||||||
count++;
|
count++;
|
||||||
this.index++;
|
this.index++;
|
||||||
}
|
}
|
||||||
let chars = [];
|
const chars = [];
|
||||||
for (let i = startIndex; i < startIndex + count; i++) {
|
for (let i = startIndex; i < startIndex + count; i++) {
|
||||||
chars.push(String.fromCharCode(this.tokenizedData[i]));
|
chars.push(String.fromCharCode(this.tokenizedData[i]));
|
||||||
}
|
}
|
||||||
@@ -835,7 +835,7 @@ class WTVTellyScriptDetokenizer {
|
|||||||
detokenizeIdentifier() {
|
detokenizeIdentifier() {
|
||||||
this.index++; // skip the identifier token indicator (0x49)
|
this.index++; // skip the identifier token indicator (0x49)
|
||||||
while (this.index < this.tokenizedData.length) {
|
while (this.index < this.tokenizedData.length) {
|
||||||
let byteVal = this.tokenizedData[this.index];
|
const byteVal = this.tokenizedData[this.index];
|
||||||
if (byteVal === 0x00) break;
|
if (byteVal === 0x00) break;
|
||||||
this.rawData += String.fromCharCode(byteVal);
|
this.rawData += String.fromCharCode(byteVal);
|
||||||
this.index++;
|
this.index++;
|
||||||
@@ -861,9 +861,9 @@ class WTVTellyScriptDetokenizer {
|
|||||||
this.rawData = "";
|
this.rawData = "";
|
||||||
this.index = 0;
|
this.index = 0;
|
||||||
while (this.index <= this.endIndex) {
|
while (this.index <= this.endIndex) {
|
||||||
let token = this.tokenizedData[this.index];
|
const token = this.tokenizedData[this.index];
|
||||||
if (this.instructions.hasOwnProperty(token)) {
|
if (this.instructions.hasOwnProperty(token)) {
|
||||||
let instr = this.instructions[token];
|
const instr = this.instructions[token];
|
||||||
if (instr.terminate) break;
|
if (instr.terminate) break;
|
||||||
if (instr.instruction) {
|
if (instr.instruction) {
|
||||||
instr.instruction();
|
instr.instruction();
|
||||||
@@ -1150,7 +1150,7 @@ class WTVTellyScript {
|
|||||||
* @returns {string} The minified TellyScript data.
|
* @returns {string} The minified TellyScript data.
|
||||||
*/
|
*/
|
||||||
minify() {
|
minify() {
|
||||||
let minifier = new WTVTellyScriptMinifier();
|
const minifier = new WTVTellyScriptMinifier();
|
||||||
this.raw_data = minifier.minify(this);
|
this.raw_data = minifier.minify(this);
|
||||||
this.raw_data = this.raw_data.replaceAll("\n\n\n", "\n");
|
this.raw_data = this.raw_data.replaceAll("\n\n\n", "\n");
|
||||||
this.tokenize();
|
this.tokenize();
|
||||||
@@ -1238,7 +1238,7 @@ class WTVTellyScript {
|
|||||||
return TellyScriptState.PACKED;
|
return TellyScriptState.PACKED;
|
||||||
} else {
|
} else {
|
||||||
let hasNull = false, hasEOF = false;
|
let hasNull = false, hasEOF = false;
|
||||||
for (let byte of data) {
|
for (const byte of data) {
|
||||||
if (byte === 0x00) hasNull = true;
|
if (byte === 0x00) hasNull = true;
|
||||||
if (byte === 0xff) hasEOF = true;
|
if (byte === 0xff) hasEOF = true;
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user