remove PB pages when removing/unregistering user
This commit is contained in:
1
zefie_wtvp_minisrv/.gitignore
vendored
1
zefie_wtvp_minisrv/.gitignore
vendored
@@ -5,6 +5,7 @@
|
|||||||
|
|
||||||
# ServiceLogPost Posted Logs
|
# ServiceLogPost Posted Logs
|
||||||
ServiceLogPost/*_*
|
ServiceLogPost/*_*
|
||||||
|
client_sim_tests
|
||||||
|
|
||||||
# Large files not pertaining to the service code
|
# Large files not pertaining to the service code
|
||||||
UserServiceVault/*-*
|
UserServiceVault/*-*
|
||||||
|
|||||||
@@ -1238,8 +1238,8 @@ function handleProxy(socket, request_type, request_headers, res, data) {
|
|||||||
console.warn(` * HTML transformation failed: ${err.message}`);
|
console.warn(` * HTML transformation failed: ${err.message}`);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (request_type != "http" && request_type != "https") {
|
if (request_type !== "http" && request_type !== "https") {
|
||||||
// replace http and https links on non http/https protocol (for proto:// for example)
|
// replace http and https links on non http/https protocol (for proto:// for example)
|
||||||
const data_t = Buffer.concat(data).toString().replaceAll("http://", request_type + "://").replaceAll("https://", request_type + "://");
|
const data_t = Buffer.concat(data).toString().replaceAll("http://", request_type + "://").replaceAll("https://", request_type + "://");
|
||||||
data = [Buffer.from(data_t)]
|
data = [Buffer.from(data_t)]
|
||||||
|
|||||||
@@ -1164,7 +1164,7 @@ class WebTVClientSimulator {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// Handle user-id header - indicates successful authentication
|
// Handle user-id header - indicates successful authentication
|
||||||
if (headers['user-id']) {
|
if (headers['user-id'] || (headers['wtv-visit'] && headers['wtv-visit'].startsWith('wtv-register:/splash'))) {
|
||||||
this.debugLog(`*** Authentication successful! user-id detected: ${headers['user-id']} ***`);
|
this.debugLog(`*** Authentication successful! user-id detected: ${headers['user-id']} ***`);
|
||||||
this.userIdDetected = true;
|
this.userIdDetected = true;
|
||||||
|
|
||||||
@@ -1566,7 +1566,7 @@ class WebTVClientSimulator {
|
|||||||
let fileContent = fileResult.body;
|
let fileContent = fileResult.body;
|
||||||
const contentType = fileResult.headers ? fileResult.headers['content-type'] : '';
|
const contentType = fileResult.headers ? fileResult.headers['content-type'] : '';
|
||||||
const normalizedContentType = contentType.split(';')[0].trim().toLowerCase();
|
const normalizedContentType = contentType.split(';')[0].trim().toLowerCase();
|
||||||
var isgzip = false;
|
let isgzip = false;
|
||||||
|
|
||||||
if (normalizedContentType === 'application/gzip' && !this.keepgz) {
|
if (normalizedContentType === 'application/gzip' && !this.keepgz) {
|
||||||
this.debugLog(`Decompressing gzip file for ${fileUrl}...`);
|
this.debugLog(`Decompressing gzip file for ${fileUrl}...`);
|
||||||
@@ -1581,8 +1581,8 @@ class WebTVClientSimulator {
|
|||||||
fileContent = fileResult.body;
|
fileContent = fileResult.body;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
var filePath = this.getServicePath(fileUrl, fileResult.headers || {});
|
let filePath = this.getServicePath(fileUrl, fileResult.headers || {});
|
||||||
if (isgzip) filePath = filePath.slice(0, -3);
|
if (isgzip) filePath = filePath.slice(0, -3);
|
||||||
zip.addFile(filePath, fileContent);
|
zip.addFile(filePath, fileContent);
|
||||||
downloadedFiles.add(fileUrl);
|
downloadedFiles.add(fileUrl);
|
||||||
@@ -1800,9 +1800,9 @@ class WebTVClientSimulator {
|
|||||||
// Images and media
|
// Images and media
|
||||||
/<img[^>]+src\s*=\s*["']([^"']+)["'][^>]*>/gi,
|
/<img[^>]+src\s*=\s*["']([^"']+)["'][^>]*>/gi,
|
||||||
/<image[^>]+src\s*=\s*["']([^"']+)["'][^>]*>/gi,
|
/<image[^>]+src\s*=\s*["']([^"']+)["'][^>]*>/gi,
|
||||||
/<video[^>]+src\s*=\s*["']([^"']+)["'][^>]*>/gi,
|
/<body[^>]+bgsound\s*=\s*["']([^"']+)["'][^>]*>/gi,
|
||||||
/<audio[^>]+src\s*=\s*["']([^"']+)["'][^>]*>/gi,
|
/<bgsound[^>]+src\s*=\s*["']([^"']+)["'][^>]*>/gi,
|
||||||
/<source[^>]+src\s*=\s*["']([^"']+)["'][^>]*>/gi,
|
/<embed[^>]+src\s*=\s*["']([^"']+)["'][^>]*>/gi,
|
||||||
|
|
||||||
// Scripts and stylesheets
|
// Scripts and stylesheets
|
||||||
/<script[^>]+src\s*=\s*["']([^"']+)["'][^>]*>/gi,
|
/<script[^>]+src\s*=\s*["']([^"']+)["'][^>]*>/gi,
|
||||||
@@ -2366,12 +2366,12 @@ class WebTVClientSimulator {
|
|||||||
this.debugLog('Parsing VLN-stage-two HTML for form and hidden fields...');
|
this.debugLog('Parsing VLN-stage-two HTML for form and hidden fields...');
|
||||||
|
|
||||||
// Find the form action URL
|
// Find the form action URL
|
||||||
var formMatch = htmlString.match(/<form[^>]+action=["']([^"']+)["'][^>]*>/i);
|
let formMatch = htmlString.match(/<form[^>]+action=["']([^"']+)["'][^>]*>/i);
|
||||||
if (!formMatch) {
|
if (!formMatch) {
|
||||||
// Match <form ... action=... ...>
|
// Match <form ... action=... ...>
|
||||||
// Handles quoted and unquoted action values
|
// Handles quoted and unquoted action values
|
||||||
// Improved regex: match action attribute, quoted or unquoted, non-greedy
|
// Improved regex: match action attribute, quoted or unquoted, non-greedy
|
||||||
var formMatch = htmlString.match(/<form[^>]*\saction\s*=\s*(?:"([^"]*?)"|'([^']*?)'|([^\s"'<>]+))/i);
|
formMatch = htmlString.match(/<form[^>]*\saction\s*=\s*(?:"([^"]*?)"|'([^']*?)'|([^\s"'<>]+))/i);
|
||||||
if (!formMatch) {
|
if (!formMatch) {
|
||||||
console.error('No form with action found in VLN-stage-two HTML');
|
console.error('No form with action found in VLN-stage-two HTML');
|
||||||
this.cleanup();
|
this.cleanup();
|
||||||
|
|||||||
@@ -10,7 +10,7 @@ var photo;
|
|||||||
var thumbnail;
|
var thumbnail;
|
||||||
|
|
||||||
if (pagedata.blocks[oldBlockNum].photo) {
|
if (pagedata.blocks[oldBlockNum].photo) {
|
||||||
photo = wtvshared.atob(pagedata.blocks[oldBlockNum].photo)
|
photo = wtvshared.btoa(pagedata.blocks[oldBlockNum].photo)
|
||||||
thumbnail = photo.replace('clipart/', 'clipart/icons/');
|
thumbnail = photo.replace('clipart/', 'clipart/icons/');
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -2,7 +2,7 @@ const minisrv_service_file = true;
|
|||||||
session_data.loadSessionData();
|
session_data.loadSessionData();
|
||||||
|
|
||||||
if (session_data.user_id != 0) {
|
if (session_data.user_id != 0) {
|
||||||
const errpage = doErrorPage(400, "You are not authorized to edit the primary account.");
|
const errpage = wtvshared.doErrorPage(400, "You are not authorized to edit the primary account.");
|
||||||
headers = errpage[0];
|
headers = errpage[0];
|
||||||
data = errpage[1];
|
data = errpage[1];
|
||||||
} else {
|
} else {
|
||||||
|
|||||||
@@ -729,19 +729,22 @@ html += `">next page</a>
|
|||||||
var pagestorepath = this.pagestore_dir;
|
var pagestorepath = this.pagestore_dir;
|
||||||
var self = this;
|
var self = this;
|
||||||
self.pageArr = [];
|
self.pageArr = [];
|
||||||
var files = this.fs.readdirSync(pagestorepath)
|
if (self.fs.existsSync(pagestorepath)) {
|
||||||
this.debug("listPages","files",files)
|
var files = this.fs.readdirSync(pagestorepath)
|
||||||
|
this.debug("listPages","files",files)
|
||||||
files.map(function (v) {
|
files.map(function (v) {
|
||||||
// oh yeah it's because any non-JSON file in pagestore will throw an error and break everything
|
if (v.endsWith(self.pageFileExt)) {
|
||||||
var page_data_raw = null;
|
// oh yeah it's because any non-JSON file in pagestore will throw an error and break everything
|
||||||
var pagepath = pagestorepath + self.path.sep + v;
|
var page_data_raw = null;
|
||||||
if (self.fs.existsSync(pagepath)) page_data_raw = self.fs.readFileSync(pagepath);
|
var pagepath = pagestorepath + self.path.sep + v;
|
||||||
if (page_data_raw) {
|
if (self.fs.existsSync(pagepath)) page_data_raw = self.fs.readFileSync(pagepath);
|
||||||
var page_data = JSON.parse(page_data_raw);
|
if (page_data_raw) {
|
||||||
self.pageArr.push(page_data);
|
var page_data = JSON.parse(page_data_raw);
|
||||||
}
|
self.pageArr.push(page_data);
|
||||||
|
}
|
||||||
|
}
|
||||||
})
|
})
|
||||||
|
}
|
||||||
return self.pageArr;
|
return self.pageArr;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -819,9 +822,14 @@ html += `">next page</a>
|
|||||||
var publishname = pagedata.publishname;
|
var 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.rmdirSync(destDir + this.wtvclient.session_store.subscriber_username + '/' + publishname, { recursive: true })
|
this.fs.rmSync(destDir + this.wtvclient.session_store.subscriber_username + '/' + publishname, { recursive: true })
|
||||||
pagedata.published = false;
|
pagedata.published = false;
|
||||||
this.editPage(pagedata, pagenum, false);
|
this.editPage(pagedata, pagenum, false);
|
||||||
|
const pages = this.listPages()
|
||||||
|
const publishedPagesCount = pages.filter(page => page.published).length;
|
||||||
|
if (publishedPagesCount === 0) {
|
||||||
|
this.fs.rmSync(destDir + this.wtvclient.session_store.subscriber_username, { recursive: true });
|
||||||
|
}
|
||||||
this.generatePageList()
|
this.generatePageList()
|
||||||
return true;
|
return true;
|
||||||
} catch { }
|
} catch { }
|
||||||
@@ -881,8 +889,8 @@ html += `">next page</a>
|
|||||||
|
|
||||||
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
|
||||||
var pagelist = this.listPages()
|
const pagelist = this.listPages()
|
||||||
var html = `<HTML>
|
let html = `<HTML>
|
||||||
<HEAD>
|
<HEAD>
|
||||||
<SCRIPT language="JavaScript">
|
<SCRIPT language="JavaScript">
|
||||||
var gIsWebTV = false;
|
var gIsWebTV = false;
|
||||||
@@ -946,19 +954,35 @@ vspace=0
|
|||||||
|
|
||||||
deletePage(pagenum) {
|
deletePage(pagenum) {
|
||||||
// i hate fs operations
|
// i hate fs operations
|
||||||
var pagestore = this.pagestoreExists()
|
const pagestore = this.pagestoreExists()
|
||||||
var userstore_dir = this.wtvclient.getUserStoreDirectory();
|
const userstore_dir = this.wtvclient.getUserStoreDirectory();
|
||||||
this.debug("deletePage","userstore_dir",userstore_dir)
|
this.debug("deletePage","userstore_dir",userstore_dir)
|
||||||
|
|
||||||
// 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 page_file = this.fs.readdirSync(pagestorepath)
|
const page_file = this.fs.readdirSync(pagestorepath)
|
||||||
var page_file_out = page_file[pagenum]
|
const page_file_out = page_file[pagenum]
|
||||||
|
|
||||||
this.unpublishPage(pagenum);
|
this.unpublishPage(pagenum);
|
||||||
this.fs.unlinkSync(this.pagestore_dir + page_file_out, { recursive: true });
|
if (typeof page_file_out === 'undefined') {
|
||||||
|
this.fs.unlinkSync(this.pagestore_dir + page_file_out, { recursive: true });
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
deleteUser(user_id) {;
|
||||||
|
this.wtvclient.switchUserID(user_id, false, false, false);
|
||||||
|
const pagelist = this.listPages();
|
||||||
|
for (let i = 0; i < pagelist.length; i++) {
|
||||||
|
this.deletePage(i);
|
||||||
|
}
|
||||||
|
const userstore_dir = otherUser.getUserStoreDirectory();
|
||||||
|
const store_dir = "PageStore" + this.path.sep;
|
||||||
|
this.pagestore_dir = userstore_dir + store_dir;
|
||||||
|
this.wtvclient.switchUserID(0, false, false, false);
|
||||||
|
}
|
||||||
|
|
||||||
// these totally couldn't have been made into one function nah that's impossible
|
// these totally couldn't have been made into one function nah that's impossible
|
||||||
createTextBlock(pagenum, title, caption, size, style, position) {
|
createTextBlock(pagenum, title, caption, size, style, position) {
|
||||||
var pagedata = this.loadPage(pagenum);
|
var pagedata = this.loadPage(pagenum);
|
||||||
|
|||||||
@@ -241,6 +241,9 @@ class WTVClientSessionData {
|
|||||||
if (parseInt(this.user_id) !== 0) return false; // not primary account
|
if (parseInt(this.user_id) !== 0) return false; // not primary account
|
||||||
if (user_id === 0) return false; // cannot delete primary account in this fashion
|
if (user_id === 0) return false; // cannot delete primary account in this fashion
|
||||||
|
|
||||||
|
const wtvauthor = new WTVAuthor(this.minisrv_config, this)
|
||||||
|
wtvauthor.deleteUser(user_id);
|
||||||
|
|
||||||
const userstore = this.getUserStoreDirectory(false, user_id);
|
const userstore = this.getUserStoreDirectory(false, user_id);
|
||||||
if (this.fs.existsSync(userstore)) {
|
if (this.fs.existsSync(userstore)) {
|
||||||
this.fs.rmSync(userstore, { recursive: true });
|
this.fs.rmSync(userstore, { recursive: true });
|
||||||
@@ -270,7 +273,7 @@ class WTVClientSessionData {
|
|||||||
const dest_pending_file = new_userstore + this.path.sep + "pending_transfer.json";
|
const dest_pending_file = new_userstore + this.path.sep + "pending_transfer.json";
|
||||||
if (this.fs.existsSync(dest_pending_file)) this.fs.unlinkSync(dest_pending_file);
|
if (this.fs.existsSync(dest_pending_file)) this.fs.unlinkSync(dest_pending_file);
|
||||||
this.fs.unlinkSync(pending_file);
|
this.fs.unlinkSync(pending_file);
|
||||||
if (this.fs.existsSync(new_userstore)) this.fs.rmdirSync(new_userstore);
|
if (this.fs.existsSync(new_userstore)) this.fs.rmSync(new_userstore, { recursive: true });
|
||||||
return ssidobj.ssid
|
return ssidobj.ssid
|
||||||
}
|
}
|
||||||
return null;
|
return null;
|
||||||
@@ -790,6 +793,11 @@ class WTVClientSessionData {
|
|||||||
|
|
||||||
unregisterBox() {
|
unregisterBox() {
|
||||||
const user_store_base = this.wtvshared.makeSafePath(this.wtvshared.getAbsolutePath(this.getAccountStoreDirectory()), this.path.sep + this.ssid);
|
const user_store_base = this.wtvshared.makeSafePath(this.wtvshared.getAbsolutePath(this.getAccountStoreDirectory()), this.path.sep + this.ssid);
|
||||||
|
const accountUsers = this.listPrimaryAccountUsers();
|
||||||
|
Object.keys(accountUsers).forEach(userKey => {
|
||||||
|
const user_id = accountUsers[userKey].user_id;
|
||||||
|
this.pagestore.deleteUser(user_id);
|
||||||
|
});
|
||||||
try {
|
try {
|
||||||
if (this.fs.existsSync(user_store_base + ".json")) {
|
if (this.fs.existsSync(user_store_base + ".json")) {
|
||||||
this.fs.unlinkSync(user_store_base + ".json");
|
this.fs.unlinkSync(user_store_base + ".json");
|
||||||
|
|||||||
@@ -137,6 +137,7 @@ class WTVDownloadList {
|
|||||||
const destination = path.replace("file://", "");
|
const destination = path.replace("file://", "");
|
||||||
this.putUserStoreDest(path, destination);
|
this.putUserStoreDest(path, destination);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Adds a GET command to the download list
|
* Adds a GET command to the download list
|
||||||
* @param {string} file Non-absolute path of client destination file (relative to group base)
|
* @param {string} file Non-absolute path of client destination file (relative to group base)
|
||||||
|
|||||||
@@ -17,12 +17,12 @@ class WTVMinifyingProxy {
|
|||||||
];
|
];
|
||||||
|
|
||||||
this.allowedAttributes = [
|
this.allowedAttributes = [
|
||||||
'leftcolor', 'rightcolor', 'maxlevel', 'leftoffset', 'rightoffset',
|
'leftcolor', 'rightcolor', 'maxlevel', 'leftoffset', 'rightoffset', 'background',
|
||||||
'host', 'port', 'channel', 'borderimage', 'font', 'nohighlight', 'autoactivate',
|
'host', 'port', 'channel', 'borderimage', 'font', 'nohighlight', 'autoactivate',
|
||||||
'text', 'cursor',
|
'text', 'cursor', 'loop', 'autostart', 'href', 'src', 'alt', 'title', 'width',
|
||||||
'href', 'src', 'alt', 'title', 'width', 'height', 'border', 'align', 'valign',
|
'height', 'border', 'align', 'valign', 'bgcolor', 'color', 'size',
|
||||||
'bgcolor', 'color', 'size', 'face', 'target', 'name', 'value', 'type', 'action',
|
'face', 'target', 'name', 'value', 'type', 'action',
|
||||||
'method', 'cols', 'rows', 'cellpadding', 'cellspacing', 'nowrap',
|
'method', 'cols', 'rows', 'cellpadding', 'cellspacing', 'nowrap',
|
||||||
// JellyScript event handlers
|
// JellyScript event handlers
|
||||||
'onclick', 'onload', 'onunload', 'onsubmit', 'onreset', 'onfocus', 'onblur',
|
'onclick', 'onload', 'onunload', 'onsubmit', 'onreset', 'onfocus', 'onblur',
|
||||||
'onchange', 'onmouseover', 'onmouseout', 'onmousedown', 'onmouseup'
|
'onchange', 'onmouseover', 'onmouseout', 'onmousedown', 'onmouseup'
|
||||||
@@ -495,14 +495,8 @@ class WTVMinifyingProxy {
|
|||||||
|
|
||||||
// Remove other unsupported content
|
// Remove other unsupported content
|
||||||
return html
|
return html
|
||||||
// Remove noscript content (show it since we support basic JS)
|
|
||||||
.replace(/<noscript\b[^>]*>/gi, '')
|
|
||||||
.replace(/<\/noscript>/gi, '')
|
|
||||||
// Remove object/embed tags
|
// Remove object/embed tags
|
||||||
.replace(/<object\b[^>]*>.*?<\/object>/gis, '')
|
.replace(/<object\b[^>]*>.*?<\/object>/gis, '')
|
||||||
.replace(/<embed\b[^>]*\/?>/gi, '')
|
|
||||||
// Remove iframes
|
|
||||||
.replace(/<iframe\b[^>]*>.*?<\/iframe>/gis, '')
|
|
||||||
// Remove link tags (CSS, etc.)
|
// Remove link tags (CSS, etc.)
|
||||||
.replace(/<link\b[^>]*\/?>/gi, '')
|
.replace(/<link\b[^>]*\/?>/gi, '')
|
||||||
// Remove meta tags except content-type and charset
|
// Remove meta tags except content-type and charset
|
||||||
|
|||||||
Reference in New Issue
Block a user