From d4ceda7211f3a84b654272db9cf3ba83a8722663 Mon Sep 17 00:00:00 2001 From: zefie Date: Mon, 10 Oct 2022 15:40:09 -0400 Subject: [PATCH] pc_services now uses node Express - reduces chance of error with older webtv clients sending http request - version bump to 0.9.32 --- zefie_wtvp_minisrv/app.js | 585 ++++++++--------- zefie_wtvp_minisrv/config.json | 2 + zefie_wtvp_minisrv/package-lock.json | 912 ++++++++++++++++++++++++++- zefie_wtvp_minisrv/package.json | 3 +- 4 files changed, 1217 insertions(+), 285 deletions(-) diff --git a/zefie_wtvp_minisrv/app.js b/zefie_wtvp_minisrv/app.js index 07442920..a3b7fb16 100644 --- a/zefie_wtvp_minisrv/app.js +++ b/zefie_wtvp_minisrv/app.js @@ -19,6 +19,8 @@ const WTVMime = require("./WTVMime.js"); const { WTVShared, clientShowAlert } = require("./WTVShared.js"); const WTVFlashrom = require("./WTVFlashrom.js"); const vm = require('vm'); +const express = require('express'); +const { url } = require('inspector'); process .on('SIGTERM', shutdown('SIGTERM')) @@ -39,6 +41,7 @@ var ssid_sessions = new Array(); var socket_sessions = new Array(); var ports = []; +var pc_ports = []; // add .reverse() feature to all JavaScript Strings in this application // works for service vault scripts too. @@ -185,12 +188,16 @@ var runScriptInVM = function (script_data, user_contextObj = {}, privileged = fa return contextObj; // updated context object with whatever global varibles the script set } -async function processPath(socket, service_vault_file_path, request_headers = new Array(), service_name, shared_romcache = null) { +function sendToPCClient(headers, data) { + +} + +async function processPath(socket, service_vault_file_path, request_headers = new Array(), service_name, shared_romcache = null, pc_services = false) { var headers, data = null; var request_is_async = false; var service_vault_found = false; var service_path = unescape(service_vault_file_path); - var usingSharedROMCache = false; + var usingSharedROMCache = false; var contextObj = { "privileged": false, "socket": socket, @@ -208,11 +215,14 @@ async function processPath(socket, service_vault_file_path, request_headers = ne // format: [ ourvarname, scriptsvarname ] ["headers", "headers"], // we need to be able to read the script's response headers ["data", "data"], // we need to be able to read the script's response data - ["request_is_async", "request_is_async"], // we need to know if the script is async or not - ["ssid_sessions", "ssid_sessions"], // global ssid_sessions object for privileged service scripts, such as wtv-setup, wtv-head-waiter, etc - ["socket_sessions", "socket_sessions"], // global socket_sessions object for privileged service scripts, such as wtv-1800, etc - [`ssid_sessions[${socket.ssid}]`, "session_data"] // user-specific session data from unprivileged scripts - ]; + ["request_is_async", "request_is_async"] // we need to know if the script is async or not + ] + + if (!pc_services) { + updateFromVM.push(["ssid_sessions", "ssid_sessions"]); // global ssid_sessions object for privileged service scripts, such as wtv-setup, wtv-head-waiter, etc + updateFromVM.push(["socket_sessions", "socket_sessions"]); // global socket_sessions object for privileged service scripts, such as wtv-1800, etc + updateFromVM.push([`ssid_sessions[${socket.ssid}]`, "session_data"]); // user-specific session data from unprivileged scripts + } try { service_vaults.forEach(function (service_vault_dir) { @@ -238,6 +248,7 @@ async function processPath(socket, service_vault_file_path, request_headers = ne } else { service_vault_file_path = wtvshared.makeSafePath(service_vault_dir, service_path); } + // deny access to catchall file name directly var service_path_split = service_path.split("/"); var service_path_request_file = service_path_split[service_path_split.length - 1]; @@ -373,7 +384,7 @@ async function processPath(socket, service_vault_file_path, request_headers = ne var script_data = fs.readFileSync(service_vault_file_path + ".js").toString(); var priv = false; if (minisrv_config.services[service_name]) priv = (minisrv_config.services[service_name].privileged) ? true : false; - else if (socket.minisrv_pc_mode) priv = (minisrv_config.services['pc_services'].privileged) ? true : false; + else if (pc_services) priv = (minisrv_config.services['pc_services'].privileged) ? true : false; var vmResults = runScriptInVM(script_data, contextObj, priv, service_vault_file_path + ".js"); // Here we read back certain data from the ServiceVault Script Context Object @@ -417,7 +428,7 @@ async function processPath(socket, service_vault_file_path, request_headers = ne var script_data = fs.readFileSync(catchall_file).toString(); var priv = false; if (minisrv_config.services[service_name]) priv = (minisrv_config.services[service_name].privileged) ? true : false; - else if (socket.minisrv_pc_mode) priv = (minisrv_config.services['pc_services'].privileged) ? true : false; + else if (pc_services) priv = (minisrv_config.services['pc_services'].privileged) ? true : false; runScriptInVM(script_data, contextObj, priv, catchall_file); @@ -444,7 +455,7 @@ async function processPath(socket, service_vault_file_path, request_headers = ne var errpage = wtvshared.doErrorPage(400); headers = errpage[0]; data = errpage[1]; - if (socket.minisrv_pc_mode) { + if (pc_services) { if (minisrv_config.services.pc_services.show_verbose_errors) data += "

The interpreter said:
" + e.stack + "
"; } @@ -453,12 +464,12 @@ async function processPath(socket, service_vault_file_path, request_headers = ne if (!request_is_async) { if (!service_vault_found) { console.error(" * Could not find a Service Vault for " + service_name + ":/" + service_path.replace(service_name + path.sep, "").replace(path.sep, '/')); - var errpage = wtvshared.doErrorPage(404, null, socket.minisrv_pc_mode); + var errpage = wtvshared.doErrorPage(404, null, pc_services); headers = errpage[0]; data = errpage[1]; } if (headers == null && !request_is_async) { - var errpage = wtvshared.doErrorPage(400, null, socket.minisrv_pc_mode); + var errpage = wtvshared.doErrorPage(400, null, pc_services); headers = errpage[0]; data = errpage[1]; console.error(" * Scripting or Data error: Headers were not defined. (headers,data) as follows:") @@ -486,50 +497,51 @@ function verifyServicePort(service_name, socket) { return false; } -async function processURL(socket, request_headers) { +async function processURL(socket, request_headers, pc_services = false) { var shortURL, headers, data, service_name = ""; var enable_multi_query = false; - request_headers.query = new Array(); + request_headers.query = {}; if (request_headers.request_url) { + if (pc_services) { + service_name = verifyServicePort(request_headers.service_name, socket); + delete request_headers.service_name; + } if (request_headers.request_url.indexOf('?') >= 0) { shortURL = request_headers.request_url.split('?')[0]; - if (socket.minisrv_pc_mode) - service_name = verifyServicePort("pc_services", socket); - else - service_name = verifyServicePort(shortURL.split(':')[0], socket); + if (!service_name) service_name = verifyServicePort(shortURL.split(':')[0], socket); if (!service_name) { - service_name = verifyServicePort("pc_services", socket); - socket.minisrv_pc_mode = true; - } - - if (!service_name) { - var errpage = wtvshared.doErrorPage(500, null, socket.minisrv_pc_mode); + var errpage = wtvshared.doErrorPage(500, null, pc_services); socket_sessions[socket.id].close_me = true; sendToClient(socket, errpage[0], errpage[1]); return } - if (minisrv_config.services[service_name]) enable_multi_query = minisrv_config.services[service_name].enable_multi_query || false; - var qraw = request_headers.request_url.split('?')[1]; - if (qraw.length > 0) { - qraw = qraw.split("&"); - for (let i = 0; i < qraw.length; i++) { - var qraw_split = qraw[i].split("="); - if (qraw_split.length == 2) { - var k = qraw_split[0]; - if (request_headers.query[k] && enable_multi_query) { - if (typeof request_headers.query[k] === 'string') { - var keyarray = [request_headers.query[k]]; - request_headers.query[k] = keyarray; + if (request_headers.request_url.indexOf('?') >= 0) { + shortURL = request_headers.request_url.split('?')[0]; + if (minisrv_config.services[service_name]) enable_multi_query = minisrv_config.services[service_name].enable_multi_query || false; + var qraw = request_headers.request_url.split('?')[1]; + if (qraw.length > 0) { + qraw = qraw.split("&"); + for (let i = 0; i < qraw.length; i++) { + var qraw_split = qraw[i].split("="); + if (qraw_split.length == 2) { + var k = qraw_split[0]; + if (request_headers.query[k] && enable_multi_query) { + if (typeof request_headers.query[k] === 'string') { + var keyarray = [request_headers.query[k]]; + request_headers.query[k] = keyarray; + } + request_headers.query[k].push(unescape(qraw[i].split("=")[1].replace(/\+/g, "%20"))); + } else { + request_headers.query[k] = unescape(qraw[i].split("=")[1].replace(/\+/g, "%20")); } - request_headers.query[k].push(unescape(qraw[i].split("=")[1].replace(/\+/g, "%20"))); - } else { - request_headers.query[k] = unescape(qraw[i].split("=")[1].replace(/\+/g, "%20")); + } else if (qraw[i].length == 1) { + request_headers.query[qraw[i]] = null; } - } else if (qraw[i].length == 1) { - request_headers.query[qraw[i]] = null; } } + } else { + shortURL = unescape(request_headers.request_url); } } else { shortURL = unescape(request_headers.request_url); @@ -598,49 +610,9 @@ async function processURL(socket, request_headers) { shortURL_split.shift(); var shortURL_service_path = shortURL_split.join(":"); shortURL = shortURL_service_name + ":/" + shortURL_service_path; - } else if (shortURL.indexOf(":") == -1 && request_headers.request.indexOf("HTTP/1") > 0 && request_headers.Host && socket.ssid == null) { - // PC browsers typically send a Host header - if (minisrv_config.services.pc_services) { - if (!minisrv_config.services.pc_services.disabled) { - socket.minisrv_pc_mode = true; - service_name = verifyServicePort("pc_services", socket); - if (!service_name) { - if (minisrv_config.services.pc_services.drop_connection_on_wrong_port) { - // just close the connection, no fancy error - socket.end(); - return; - } - var errpage = wtvshared.doErrorPage(500, null, socket.minisrv_pc_mode); - socket_sessions[socket.id].close_me = true; - sendToClient(socket, errpage[0], errpage[1]); - return; - } - // if a directory, request index - if (shortURL.substring(shortURL.length - 1) == "/") shortURL += "index"; - shortURL = service_name + ":" + shortURL; - } else { - // minimal pc mode to send error - socket.minisrv_pc_mode = true; - var errpage = wtvshared.doErrorPage(401, "PC services are disabled on this server", socket.minisrv_pc_mode); - headers = errpage[0]; - data = errpage[1] - socket_sessions[socket.id].close_me = true; - sendToClient(socket, headers, data); - return; - } - } else { - // minimal pc mode to send error - socket.minisrv_pc_mode = true; - var errpage = wtvshared.doErrorPage(401, "PC services are disabled on this server", socket.minisrv_pc_mode); - headers = errpage[0]; - data = errpage[1] - socket_sessions[socket.id].close_me = true; - sendToClient(socket, headers, data); - return; - } - } + } - if (!socket.minisrv_pc_mode && !socket.ssid) { + if (socket.ssid) { // skip box auth tests for pc mode // check security @@ -704,10 +676,10 @@ minisrv-no-mail-count: true`; } else { console.log(" * " + reqverb + " for " + request_headers.request_url, 'on', socket.id); } - if (!socket.minisrv_pc_mode) { + if (!pc_services) { var service_name = verifyServicePort(shortURL.split(':/')[0], socket); if (!service_name) { - var errpage = wtvshared.doErrorPage(500, null, socket.minisrv_pc_mode); + var errpage = wtvshared.doErrorPage(500, null, pc_services); socket_sessions[socket.id].close_me = true; sendToClient(socket, errpage[0], errpage[1]); return @@ -720,9 +692,14 @@ minisrv-no-mail-count: true`; } if (minisrv_config.config.debug_flags.show_headers) console.log(" * Incoming headers on socket ID", socket.id, (await wtvshared.decodePostData(wtvshared.filterRequestLog(wtvshared.filterSSID(request_headers))))); socket_sessions[socket.id].request_headers = request_headers; - processPath(socket, urlToPath, request_headers, service_name, shared_romcache); - } else if (shortURL.indexOf('http://') >= 0 || shortURL.indexOf('https://') >= 0) { + processPath(socket, urlToPath, request_headers, service_name, shared_romcache, pc_services); + } else if ((shortURL.indexOf('http://') >= 0 || shortURL.indexOf('https://') >= 0) && !pc_services) { doHTTPProxy(socket, request_headers); + } else if (pc_services) { + // if a directory, request index + if (shortURL.substring(shortURL.length - 1) == "/") shortURL += "index"; + var urlToPath = wtvshared.fixPathSlashes(service_name + path.sep + shortURL); + processPath(socket, urlToPath, request_headers, service_name, shared_romcache, pc_services); } else { // error reading headers (no request_url provided) var errpage = wtvshared.doErrorPage(400); @@ -922,7 +899,7 @@ function stripHeaders(headers_obj, whitelist) { function headerStringToObj(headers, response = false) { var inc_headers = 0; - var headers_obj = new Array(); + var headers_obj = {}; var headers_obj_pre = headers.split("\n"); headers_obj_pre.forEach(function (d) { if (/^SECURE ON/.test(d) && !response) { @@ -973,20 +950,22 @@ async function sendToClient(socket, headers_obj, data) { socket.destroy(); return; } - var wtv_connection_close = (headers_obj["wtv-connection-close"]) ? true : false; - if (typeof (headers_obj["wtv-connection-close"]) != 'undefined') delete headers_obj["wtv-connection-close"]; + if (!socket.res) { + var wtv_connection_close = (headers_obj["wtv-connection-close"]) ? true : false; + if (typeof (headers_obj["wtv-connection-close"]) != 'undefined') delete headers_obj["wtv-connection-close"]; - if (!headers_obj['minisrv-no-mail-count']) { - if (ssid_sessions[socket.ssid]) { - if (ssid_sessions[socket.ssid].isRegistered()) { - if (ssid_sessions[socket.ssid].mailstore) { - headers_obj['wtv-mail-count'] = ssid_sessions[socket.ssid].mailstore.countUnreadMessages(0); + if (!headers_obj['minisrv-no-mail-count']) { + if (ssid_sessions[socket.ssid]) { + if (ssid_sessions[socket.ssid].isRegistered()) { + if (ssid_sessions[socket.ssid].mailstore) { + headers_obj['wtv-mail-count'] = ssid_sessions[socket.ssid].mailstore.countUnreadMessages(0); + } } } + } else { + if (headers_obj['wtv-mail-count']) delete headers_obj['wtv-mail-count']; + delete headers_obj['minisrv-no-mail-count']; } - } else { - if (headers_obj['wtv-mail-count']) delete headers_obj['wtv-mail-count']; - delete headers_obj['minisrv-no-mail-count']; } // add Connection header if missing, default to Keep-Alive @@ -1041,6 +1020,10 @@ async function sendToClient(socket, headers_obj, data) { delete headers_obj["minisrv-force-compression"]; } + if (socket.res) { // pc mode with response object available + if (compression_type == 1) compression_type = 2; // just in case + } + // compress if needed if (compression_type > 0 && content_length > 0 && headers_obj['Response'].substring(0, 3) == "200") { var uncompressed_content_length = content_length; @@ -1076,21 +1059,22 @@ async function sendToClient(socket, headers_obj, data) { if (uncompressed_content_length != compressed_content_length) if (minisrv_config.config.debug_flags.debug) console.log(" # Compression stats: Orig Size:", uncompressed_content_length, "~ Comp Size:", compressed_content_length, "~ Ratio:", compression_ratio, "~ Saved:", compression_percentage.toString() + "%"); } - - // encrypt if needed - if (socket_sessions[socket.id].secure == true && !socket_sessions[socket.id].do_not_encrypt) { - headers_obj["wtv-encrypted"] = 'true'; - headers_obj = moveObjectElement('wtv-encrypted', 'Connection', headers_obj); - if (content_length > 0 && socket_sessions[socket.id].wtvsec) { - if (!minisrv_config.config.debug_flags.quiet) console.log(" * Encrypting response to client ...") - var enc_data = socket_sessions[socket.id].wtvsec.Encrypt(1, data); - data = enc_data; + if (!socket.res) { + // encrypt if needed + if (socket_sessions[socket.id].secure == true && !socket_sessions[socket.id].do_not_encrypt) { + headers_obj["wtv-encrypted"] = 'true'; + headers_obj = moveObjectElement('wtv-encrypted', 'Connection', headers_obj); + if (content_length > 0 && socket_sessions[socket.id].wtvsec) { + if (!minisrv_config.config.debug_flags.quiet) console.log(" * Encrypting response to client ...") + var enc_data = socket_sessions[socket.id].wtvsec.Encrypt(1, data); + data = enc_data; + } } - } - if (socket_sessions[socket.id].do_not_encrypt) { - if (headers_obj["wtv-encrypted"]) delete headers_obj["wtv-encrypted"]; - if (headers_obj["secure"]) delete headers_obj["secure"]; + if (socket_sessions[socket.id].do_not_encrypt) { + if (headers_obj["wtv-encrypted"]) delete headers_obj["wtv-encrypted"]; + if (headers_obj["secure"]) delete headers_obj["secure"]; + } } @@ -1109,77 +1093,72 @@ async function sendToClient(socket, headers_obj, data) { } - // Send wtv-ticket if it has been flagged as updated - if (ssid_sessions[socket.ssid]) { - if (ssid_sessions[socket.ssid].data_store.wtvsec_login) { - if (ssid_sessions[socket.ssid].data_store.wtvsec_login.ticket_b64) { - if (ssid_sessions[socket.ssid].data_store.wtvsec_login.update_ticket) { - headers_obj["wtv-ticket"] = ssid_sessions[socket.ssid].data_store.wtvsec_login.ticket_b64; - headers_obj = moveObjectElement("wtv-ticket", "Connection", headers_obj); - ssid_sessions[socket.ssid].data_store.wtvsec_login.update_ticket = false; + if (!socket.res) { + // Send wtv-ticket if it has been flagged as updated + if (ssid_sessions[socket.ssid]) { + if (ssid_sessions[socket.ssid].data_store.wtvsec_login) { + if (ssid_sessions[socket.ssid].data_store.wtvsec_login.ticket_b64) { + if (ssid_sessions[socket.ssid].data_store.wtvsec_login.update_ticket) { + headers_obj["wtv-ticket"] = ssid_sessions[socket.ssid].data_store.wtvsec_login.ticket_b64; + headers_obj = moveObjectElement("wtv-ticket", "Connection", headers_obj); + ssid_sessions[socket.ssid].data_store.wtvsec_login.update_ticket = false; + } } } } } - var end_of_line = "\n"; - if (socket.minisrv_pc_mode) { - end_of_line = "\r\n"; - headers_obj['Response'] = "HTTP/1.0 " + headers_obj['Response']; - } + if (!socket.res) { + var end_of_line = "\n"; - /* // wtv-request-type download wants minimal headers? - if (data.byteLength > 0) { - if (socket_sessions[socket.id].wtv_request_type == "download") { - if (headers_obj['Content-Type'] != "wtv/download-list") { - // minimalize headers - var new_headers = { "Response": headers_obj['Response'].split(" ")[0] + " " } - if (headers_obj['wtv-encrypted']) new_headers['wtv-encrypted'] = headers_obj['wtv-encrypted']; - new_headers["content-type"] = headers_obj['Content-Type']; - new_headers["content-length"] = headers_obj['Content-length']; - - headers_obj = new_headers; - } - } - } - */ - // header object to string - if (minisrv_config.config.debug_flags.show_headers) console.log(" * Outgoing headers on socket ID", socket.id, (await wtvshared.filterSSID(headers_obj))); - Object.keys(headers_obj).forEach(function (k) { - if (k == "Response") { - headers += headers_obj[k] + end_of_line; - } else { - if (k.indexOf('_') >= 0) { - var j = k.split('_')[0]; - headers += j + ": " + headers_obj[k] + end_of_line; + // header object to string + if (minisrv_config.config.debug_flags.show_headers) console.log(" * Outgoing headers on socket ID", socket.id, (await wtvshared.filterSSID(headers_obj))); + Object.keys(headers_obj).forEach(function (k) { + if (k == "Response") { + headers += headers_obj[k] + end_of_line; } else { - headers += k + ": " + headers_obj[k] + end_of_line; + if (k.indexOf('_') >= 0) { + var j = k.split('_')[0]; + headers += j + ": " + headers_obj[k] + end_of_line; + } else { + headers += k + ": " + headers_obj[k] + end_of_line; + } } - } - }); + }); - if (headers_obj["Connection"]) { - if (headers_obj["Connection"].toLowerCase() == "close" && wtv_connection_close) { - socket_sessions[socket.id].destroy_me = true; + if (headers_obj["Connection"]) { + if (headers_obj["Connection"].toLowerCase() == "close" && wtv_connection_close) { + socket_sessions[socket.id].destroy_me = true; + } } } // send to client - var toClient = null; - if (typeof data == 'string') { - toClient = headers + end_of_line + data; - sendToSocket(socket, Buffer.from(toClient)); - } else if (typeof data == 'object') { - if (minisrv_config.config.debug_flags.quiet) var verbosity_mod = (headers_obj["wtv-encrypted"] == 'true') ? " encrypted response" : ""; - if (socket_sessions[socket.id].secure_headers == true) { - // encrypt headers - if (minisrv_config.config.debug_flags.quiet) verbosity_mod += " with encrypted headers"; - var enc_headers = socket_sessions[socket.id].wtvsec.Encrypt(1, headers + end_of_line); - sendToSocket(socket, new Buffer.from(concatArrayBuffer(enc_headers, data))); - } else { - sendToSocket(socket, new Buffer.from(concatArrayBuffer(Buffer.from(headers + end_of_line), data))); + if (socket.res) { + + var resCode = parseInt(headers_obj.Response.substr(0, 3)); + headers_obj['x-powered-by'] = "Express via " + z_title; + socket.res.writeHead(resCode, headers_obj); + socket.res.end(data); + var log_obj = Object.assign({}, socket.res.getHeaders()); + if (minisrv_config.config.debug_flags.show_headers) console.log(" * Outgoing PC headers on " + socket.service_name + " socket ID", socket.id, log_obj); + } else { + var toClient = null; + if (typeof data == 'string') { + toClient = headers + end_of_line + data; + sendToSocket(socket, Buffer.from(toClient)); + } else if (typeof data == 'object') { + if (minisrv_config.config.debug_flags.quiet) var verbosity_mod = (headers_obj["wtv-encrypted"] == 'true') ? " encrypted response" : ""; + if (socket_sessions[socket.id].secure_headers == true) { + // encrypt headers + if (minisrv_config.config.debug_flags.quiet) verbosity_mod += " with encrypted headers"; + var enc_headers = socket_sessions[socket.id].wtvsec.Encrypt(1, headers + end_of_line); + sendToSocket(socket, new Buffer.from(concatArrayBuffer(enc_headers, data))); + } else { + sendToSocket(socket, new Buffer.from(concatArrayBuffer(Buffer.from(headers + end_of_line), data))); + } + if (minisrv_config.config.debug_flags.quiet) console.log(" * Sent" + verbosity_mod + " " + headers_obj.Response + " to client (Content-Type:", headers_obj['Content-Type'], "~", headers_obj['Content-length'], "bytes)"); } - if (minisrv_config.config.debug_flags.quiet) console.log(" * Sent" + verbosity_mod + " " + headers_obj.Response + " to client (Content-Type:", headers_obj['Content-Type'], "~", headers_obj['Content-length'], "bytes)"); } } @@ -1542,132 +1521,125 @@ async function processRequest(socket, data_hex, skipSecure = false, encryptedReq socket_sessions[socket.id].headers = headers; } } else { - if (!socket.ssid) { - // incomplete, dont use https on pc services yet - socket = new tls.TLSSocket(socket); - socket.minisrv_pc_mode = true; - console.log(socket) - console.log("pc https?"); - } else { + // handle streaming POST - if (socket_sessions[socket.id].expecting_post_data && headers) { - socket_sessions[socket.id].headers = headers; - if (socket_sessions[socket.id].post_data.length < (socket_sessions[socket.id].post_data_length * 2)) { - new_header_obj = null; - var enc_data = CryptoJS.enc.Hex.parse(data_hex); - if (socket_sessions[socket.id].secure) { - // decrypt if encrypted - var dec_data = CryptoJS.lib.WordArray.create(socket_sessions[socket.id].wtvsec.Decrypt(0, enc_data)) - } else { - // just pass it over - var dec_data = enc_data; - } + if (socket_sessions[socket.id].expecting_post_data && headers) { + socket_sessions[socket.id].headers = headers; + if (socket_sessions[socket.id].post_data.length < (socket_sessions[socket.id].post_data_length * 2)) { + new_header_obj = null; + var enc_data = CryptoJS.enc.Hex.parse(data_hex); + if (socket_sessions[socket.id].secure) { + // decrypt if encrypted + var dec_data = CryptoJS.lib.WordArray.create(socket_sessions[socket.id].wtvsec.Decrypt(0, enc_data)) + } else { + // just pass it over + var dec_data = enc_data; + } - socket_sessions[socket.id].post_data += dec_data.toString(CryptoJS.enc.Hex); + socket_sessions[socket.id].post_data += dec_data.toString(CryptoJS.enc.Hex); - var post_string = "POST"; - if (socket_sessions[socket.id].secure == true) post_string = "Encrypted " + post_string; + var post_string = "POST"; + if (socket_sessions[socket.id].secure == true) post_string = "Encrypted " + post_string; - if (minisrv_config.config.post_debug) { - // `post_debug` logging of every chunk - console.log(" * ", Math.floor(new Date().getTime() / 1000), "Receiving", post_string, "data on", socket.id, "[", socket_sessions[socket.id].post_data.length / 2, "of", socket_sessions[socket.id].post_data_length, "bytes ]"); - } else { - // calculate and display percentage of data received - var postPercent = wtvshared.getPercentage(socket_sessions[socket.id].post_data.length, (socket_sessions[socket.id].post_data_length * 2)); - if (minisrv_config.config.post_percentages) { - if (minisrv_config.config.post_percentages.includes(postPercent)) { - if (!socket_sessions[socket.id].post_data_percents_shown) socket_sessions[socket.id].post_data_percents_shown = new Array(); - if (!socket_sessions[socket.id].post_data_percents_shown[postPercent]) { - console.log(" * Received", postPercent, "% of", socket_sessions[socket.id].post_data_length, "bytes on", socket.id, "from", wtvshared.filterSSID(socket.ssid)); - socket_sessions[socket.id].post_data_percents_shown[postPercent] = true; - } - if (postPercent == 100) delete socket_sessions[socket.id].post_data_percents_shown; + if (minisrv_config.config.post_debug) { + // `post_debug` logging of every chunk + console.log(" * ", Math.floor(new Date().getTime() / 1000), "Receiving", post_string, "data on", socket.id, "[", socket_sessions[socket.id].post_data.length / 2, "of", socket_sessions[socket.id].post_data_length, "bytes ]"); + } else { + // calculate and display percentage of data received + var postPercent = wtvshared.getPercentage(socket_sessions[socket.id].post_data.length, (socket_sessions[socket.id].post_data_length * 2)); + if (minisrv_config.config.post_percentages) { + if (minisrv_config.config.post_percentages.includes(postPercent)) { + if (!socket_sessions[socket.id].post_data_percents_shown) socket_sessions[socket.id].post_data_percents_shown = new Array(); + if (!socket_sessions[socket.id].post_data_percents_shown[postPercent]) { + console.log(" * Received", postPercent, "% of", socket_sessions[socket.id].post_data_length, "bytes on", socket.id, "from", wtvshared.filterSSID(socket.ssid)); + socket_sessions[socket.id].post_data_percents_shown[postPercent] = true; } + if (postPercent == 100) delete socket_sessions[socket.id].post_data_percents_shown; } } } - if (socket_sessions[socket.id].post_data.length == (socket_sessions[socket.id].post_data_length * 2)) { - // got all expected data - if (socket_sessions[socket.id].expecting_post_data) delete socket_sessions[socket.id].expecting_post_data; - socket.setTimeout(minisrv_config.config.socket_timeout * 1000); - headers.post_data = CryptoJS.enc.Hex.parse(socket_sessions[socket.id].post_data); - if (socket_sessions[socket.id].secure == true) { - if (minisrv_config.config.debug_flags.debug) console.log(" # Encrypted POST Content (SECURE ON)", "on", socket.id, "[", headers.post_data.sigBytes, "bytes ]"); + } + if (socket_sessions[socket.id].post_data.length == (socket_sessions[socket.id].post_data_length * 2)) { + // got all expected data + if (socket_sessions[socket.id].expecting_post_data) delete socket_sessions[socket.id].expecting_post_data; + socket.setTimeout(minisrv_config.config.socket_timeout * 1000); + headers.post_data = CryptoJS.enc.Hex.parse(socket_sessions[socket.id].post_data); + if (socket_sessions[socket.id].secure == true) { + if (minisrv_config.config.debug_flags.debug) console.log(" # Encrypted POST Content (SECURE ON)", "on", socket.id, "[", headers.post_data.sigBytes, "bytes ]"); + } else { + if (minisrv_config.config.debug_flags.debug) console.log(" # Unencrypted POST Content", "on", socket.id); + } + socket_sessions[socket.id].expecting_post_data = false; + delete socket_sessions[socket.id].headers; + delete socket_sessions[socket.id].post_data; + delete socket_sessions[socket.id].post_data_length; + processURL(socket, headers); + return; + } else if (socket_sessions[socket.id].post_data.length > (socket_sessions[socket.id].post_data_length * 2)) { + socket_sessions[socket.id].expecting_post_data = false; + if (socket_sessions[socket.id].expecting_post_data) delete socket_sessions[socket.id].expecting_post_data; + socket.setTimeout(minisrv_config.config.socket_timeout * 1000); + // got too much data ? ... should not ever reach this code + var errpage = wtvshared.doErrorPage(400, "Received too much data in POST request
Got " + (socket_sessions[socket.id].post_data.length / 2) + ", expected " + socket_sessions[socket.id].post_data_length); + headers = errpage[0]; + data = errpage[1]; + sendToClient(socket, headers, data); + return; + } + } else if (!skipSecure) { + if (!encryptedRequest) { + if (socket_sessions[socket.id].secure != true) { + socket_sessions[socket.id].wtvsec = new WTVSec(minisrv_config); + socket_sessions[socket.id].wtvsec.IssueChallenge(); + socket_sessions[socket.id].wtvsec.SecureOn(); + socket_sessions[socket.id].secure = true; + } + var enc_data = CryptoJS.enc.Hex.parse(data_hex); + if (enc_data.sigBytes > 0) { + if (!socket_sessions[socket.id].wtvsec) { + var errpage = wtvshared.doErrorPage(400); + var headers = errpage[0]; + headers += "wtv-visit: client:relog\n"; + data = errpage[1]; + sendToClient(socket, headers, data); + return; + } + var str_test = enc_data.toString(CryptoJS.enc.Latin1); + if (isUnencryptedString(str_test)) { + var dec_data = enc_data; } else { - if (minisrv_config.config.debug_flags.debug) console.log(" # Unencrypted POST Content", "on", socket.id); + var dec_data = CryptoJS.lib.WordArray.create(socket_sessions[socket.id].wtvsec.Decrypt(0, enc_data)); } - socket_sessions[socket.id].expecting_post_data = false; - delete socket_sessions[socket.id].headers; - delete socket_sessions[socket.id].post_data; - delete socket_sessions[socket.id].post_data_length; - processURL(socket, headers); - return; - } else if (socket_sessions[socket.id].post_data.length > (socket_sessions[socket.id].post_data_length * 2)) { - socket_sessions[socket.id].expecting_post_data = false; - if (socket_sessions[socket.id].expecting_post_data) delete socket_sessions[socket.id].expecting_post_data; - socket.setTimeout(minisrv_config.config.socket_timeout * 1000); - // got too much data ? ... should not ever reach this code - var errpage = wtvshared.doErrorPage(400, "Received too much data in POST request
Got " + (socket_sessions[socket.id].post_data.length / 2) + ", expected " + socket_sessions[socket.id].post_data_length); - headers = errpage[0]; - data = errpage[1]; - sendToClient(socket, headers, data); - return; - } - } else if (!skipSecure) { - if (!encryptedRequest) { - if (socket_sessions[socket.id].secure != true) { - socket_sessions[socket.id].wtvsec = new WTVSec(minisrv_config); - socket_sessions[socket.id].wtvsec.IssueChallenge(); - socket_sessions[socket.id].wtvsec.SecureOn(); - socket_sessions[socket.id].secure = true; - } - var enc_data = CryptoJS.enc.Hex.parse(data_hex); - if (enc_data.sigBytes > 0) { - if (!socket_sessions[socket.id].wtvsec) { - var errpage = wtvshared.doErrorPage(400); - var headers = errpage[0]; - headers += "wtv-visit: client:relog\n"; - data = errpage[1]; - sendToClient(socket, headers, data); - return; - } - var str_test = enc_data.toString(CryptoJS.enc.Latin1); - if (isUnencryptedString(str_test)) { - var dec_data = enc_data; - } else { - var dec_data = CryptoJS.lib.WordArray.create(socket_sessions[socket.id].wtvsec.Decrypt(0, enc_data)); - } - if (!socket_sessions[socket.id].secure_buffer) socket_sessions[socket.id].secure_buffer = ""; - socket_sessions[socket.id].secure_buffer += dec_data.toString(CryptoJS.enc.Hex); - var secure_headers = null; - if (headers['request']) { - if (headers['request'] == "GET") { - if (socket_sessions[socket.id].secure_buffer.indexOf("0d0a0d0a") || socket_sessions[socket.id].secure_buffer.indexOf("0a0a")) { - secure_headers = await processRequest(socket, socket_sessions[socket.id].secure_buffer, true, true); - } - } else { - var secure_headers = await processRequest(socket, socket_sessions[socket.id].secure_buffer, true, true); + if (!socket_sessions[socket.id].secure_buffer) socket_sessions[socket.id].secure_buffer = ""; + socket_sessions[socket.id].secure_buffer += dec_data.toString(CryptoJS.enc.Hex); + var secure_headers = null; + if (headers['request']) { + if (headers['request'] == "GET") { + if (socket_sessions[socket.id].secure_buffer.indexOf("0d0a0d0a") || socket_sessions[socket.id].secure_buffer.indexOf("0a0a")) { + secure_headers = await processRequest(socket, socket_sessions[socket.id].secure_buffer, true, true); } } else { var secure_headers = await processRequest(socket, socket_sessions[socket.id].secure_buffer, true, true); } - if (secure_headers) { - delete socket_sessions[socket.id].secure_buffer; - if (!headers) headers = new Array(); - headers.encrypted = true; - Object.keys(secure_headers).forEach(function (k, v) { - headers[k] = secure_headers[k]; - }); - if (headers['request']) { - if (headers['request'].substring(0, 4) == "POST") { - if (!socket_sessions[socket.id].post_data) { - socket_sessions[socket.id].post_data_length = headers['Content-length'] || headers['Content-Length'] || 0; - socket_sessions[socket.id].post_data = ""; - } - processRequest(socket, dec_data.toString(CryptoJS.enc.Hex)); - } else { - processURL(socket, headers); + } else { + var secure_headers = await processRequest(socket, socket_sessions[socket.id].secure_buffer, true, true); + } + if (secure_headers) { + delete socket_sessions[socket.id].secure_buffer; + if (!headers) headers = new Array(); + headers.encrypted = true; + Object.keys(secure_headers).forEach(function (k, v) { + headers[k] = secure_headers[k]; + }); + if (headers['request']) { + if (headers['request'].substring(0, 4) == "POST") { + if (!socket_sessions[socket.id].post_data) { + socket_sessions[socket.id].post_data_length = headers['Content-length'] || headers['Content-Length'] || 0; + socket_sessions[socket.id].post_data = ""; } + processRequest(socket, dec_data.toString(CryptoJS.enc.Hex)); + } else { + processURL(socket, headers); } } } @@ -1784,8 +1756,8 @@ function reloadConfig() { // SERVER START var git_commit = getGitRevision() var z_title = "zefie's wtv minisrv v" + require('./package.json').version; -if (git_commit) console.log("**** Welcome to " + z_title + " (git " + git_commit + ") ****"); -else console.log("**** Welcome to " + z_title + " ****"); +if (git_commit) z_title += " (git " + git_commit + ")"; +console.log("**** Welcome to " + z_title + " ****"); const wtvshared = new WTVShared(); // creates minisrv_config minisrv_config = wtvshared.getMiniSrvConfig(); // snatches minisrv_config @@ -1834,7 +1806,8 @@ Object.keys(minisrv_config.services).forEach(function (k) { minisrv_config.services[k].host = service_ip; } if (minisrv_config.services[k].port && !minisrv_config.services[k].nobind) { - ports.push(minisrv_config.services[k].port); + if (minisrv_config.services[k].pc_services) pc_ports.push(minisrv_config.services[k].port); + else ports.push(minisrv_config.services[k].port); } // minisrv_config service toString minisrv_config.services[k].toString = function (overrides) { @@ -1892,8 +1865,22 @@ process.on('uncaughtException', function (err) { }); +function findServiceByPort(port) { + var service_name = null; + Object.keys(minisrv_config.services).forEach(function (k) { + if (service_name) return; + if (minisrv_config.services[k].port) { + if (port == parseInt(minisrv_config.services[k].port)) + service_name = k; + } + }) + return service_name; +} + + var initstring = ''; ports.sort(); +pc_ports.sort(); // de-duplicate ports in case user configured multiple services on same port const bind_ports = [...new Set(ports)] @@ -1909,6 +1896,40 @@ bind_ports.every(function (v) { } return false; }); + +// PC Services via express +// de-duplicate ports in case user configured multiple services on same port +const pc_bind_ports = [...new Set(pc_ports)] +if (!minisrv_config.config.bind_ip) minisrv_config.config.bind_ip = "0.0.0.0"; +pc_bind_ports.every(function (v) { + try { + var server = express(); + server.listen(v, minisrv_config.config.bind_ip); + initstring += v + ", "; + server.get('*', (req, res) => { + var request_headers = {}; + req.socket.id = parseInt(crc16('CCITT-FALSE', Buffer.from(String(req.socket.remoteAddress) + String(req.socket.remotePort), "utf8")).toString(16), 16); + socket_sessions[req.socket.id] = []; + var service_name = findServiceByPort(v); + request_headers['request'] = "GET " + req.originalUrl + " HTTP/1.1"; + request_headers.request_url = req.originalUrl; + Object.keys(req.headers).forEach(function (k) { + request_headers[k] = req.headers[k]; + }); + request_headers.query = req.query; + if (minisrv_config.config.debug_flags.show_headers) console.log(" * Incoming PC Headers on", service_name, "socket ID", req.socket.id, wtvshared.filterRequestLog(request_headers)); + request_headers.service_name = service_name; + req.socket.minisrv_pc_mode = true; + req.socket.res = res; + req.socket.service_name = service_name; + processURL(req.socket, request_headers, true) + }) + return true; + } catch (e) { + throw ("Could not bind to port", v, "on", minisrv_config.config.bind_ip, e.toString()); + } + return false; +}); initstring = initstring.substring(0, initstring.length - 2); diff --git a/zefie_wtvp_minisrv/config.json b/zefie_wtvp_minisrv/config.json index db18b2ec..5af262e0 100644 --- a/zefie_wtvp_minisrv/config.json +++ b/zefie_wtvp_minisrv/config.json @@ -155,6 +155,8 @@ }, "pc_services": { "port": 1699, + "pc_services": true, + "hide_minisrv_version": true, "disabled": true, "servicevault_dir": "http_pc", "drop_connection_on_wrong_port": false, diff --git a/zefie_wtvp_minisrv/package-lock.json b/zefie_wtvp_minisrv/package-lock.json index ab9bf057..52173263 100644 --- a/zefie_wtvp_minisrv/package-lock.json +++ b/zefie_wtvp_minisrv/package-lock.json @@ -1,18 +1,19 @@ { "name": "zefie_wtvp_minisrv", - "version": "0.9.30", + "version": "0.9.31", "lockfileVersion": 2, "requires": true, "packages": { "": { "name": "zefie_wtvp_minisrv", - "version": "0.9.30", + "version": "0.9.31", "license": "GPL3", "dependencies": { "adm-zip": "^0.5.9", "crypto-js": "^4.1.1", "easy-crc": "0.0.2", "endianness": "^8.0.2", + "express": "^4.18.2", "html-entities": "^2.3.3", "iconv-lite": "^0.6.3", "mime-types": "^2.1.35", @@ -36,6 +37,18 @@ "node": ">= 6" } }, + "node_modules/accepts": { + "version": "1.3.8", + "resolved": "https://registry.npmjs.org/accepts/-/accepts-1.3.8.tgz", + "integrity": "sha512-PYAthTa2m2VKxuvSD3DPC/Gy+U+sOA1LAuT8mkmRuvw+NACSaeXEQ+NHcVF7rONl6qcaxV3Uuemwawk+7+SJLw==", + "dependencies": { + "mime-types": "~2.1.34", + "negotiator": "0.6.3" + }, + "engines": { + "node": ">= 0.6" + } + }, "node_modules/acorn": { "version": "8.8.0", "resolved": "https://registry.npmjs.org/acorn/-/acorn-8.8.0.tgz", @@ -74,6 +87,11 @@ "node": ">= 6.0.0" } }, + "node_modules/array-flatten": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/array-flatten/-/array-flatten-1.1.1.tgz", + "integrity": "sha512-PCVAQswWemu6UdxsDFFX/+gVeYqKAod3D3UVm91jHwynguOwAvYPhx8nNlM++NqRcK6CxxpUafjmhIdKiHibqg==" + }, "node_modules/ast-types": { "version": "0.13.4", "resolved": "https://registry.npmjs.org/ast-types/-/ast-types-0.13.4.tgz", @@ -85,6 +103,53 @@ "node": ">=4" } }, + "node_modules/body-parser": { + "version": "1.20.1", + "resolved": "https://registry.npmjs.org/body-parser/-/body-parser-1.20.1.tgz", + "integrity": "sha512-jWi7abTbYwajOytWCQc37VulmWiRae5RyTpaCyDcS5/lMdtwSz5lOpDE67srw/HYe35f1z3fDQw+3txg7gNtWw==", + "dependencies": { + "bytes": "3.1.2", + "content-type": "~1.0.4", + "debug": "2.6.9", + "depd": "2.0.0", + "destroy": "1.2.0", + "http-errors": "2.0.0", + "iconv-lite": "0.4.24", + "on-finished": "2.4.1", + "qs": "6.11.0", + "raw-body": "2.5.1", + "type-is": "~1.6.18", + "unpipe": "1.0.0" + }, + "engines": { + "node": ">= 0.8", + "npm": "1.2.8000 || >= 1.4.16" + } + }, + "node_modules/body-parser/node_modules/debug": { + "version": "2.6.9", + "resolved": "https://registry.npmjs.org/debug/-/debug-2.6.9.tgz", + "integrity": "sha512-bC7ElrdJaJnPbAP+1EotYvqZsb3ecl5wi6Bfi6BJTUcNowp6cvspg0jXznRTKDjm/E7AdgFBVeAPVMNcKGsHMA==", + "dependencies": { + "ms": "2.0.0" + } + }, + "node_modules/body-parser/node_modules/iconv-lite": { + "version": "0.4.24", + "resolved": "https://registry.npmjs.org/iconv-lite/-/iconv-lite-0.4.24.tgz", + "integrity": "sha512-v3MXnZAcvnywkTUEZomIActle7RXXeedOR31wwl7VlyoXO4Qi9arvSenNQWne1TcRwhCL1HwLI21bEqdpj8/rA==", + "dependencies": { + "safer-buffer": ">= 2.1.2 < 3" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/body-parser/node_modules/ms": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/ms/-/ms-2.0.0.tgz", + "integrity": "sha512-Tpp60P6IUJDTuOq/5Z8cdskzJujfwqfOTkrwIwj7IRISpnkJnT6SyJ4PCPnGMoFjC9ddhal5KVIYtAt97ix05A==" + }, "node_modules/bytes": { "version": "3.1.2", "resolved": "https://registry.npmjs.org/bytes/-/bytes-3.1.2.tgz", @@ -93,6 +158,50 @@ "node": ">= 0.8" } }, + "node_modules/call-bind": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/call-bind/-/call-bind-1.0.2.tgz", + "integrity": "sha512-7O+FbCihrB5WGbFYesctwmTKae6rOiIzmz1icreWJ+0aA7LJfuqhEso2T9ncpcFtzMQtzXf2QGGueWJGTYsqrA==", + "dependencies": { + "function-bind": "^1.1.1", + "get-intrinsic": "^1.0.2" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/content-disposition": { + "version": "0.5.4", + "resolved": "https://registry.npmjs.org/content-disposition/-/content-disposition-0.5.4.tgz", + "integrity": "sha512-FveZTNuGw04cxlAiWbzi6zTAL/lhehaWbTtgluJh4/E95DqMwTmha3KZN1aAWA8cFIhHzMZUvLevkw5Rqk+tSQ==", + "dependencies": { + "safe-buffer": "5.2.1" + }, + "engines": { + "node": ">= 0.6" + } + }, + "node_modules/content-type": { + "version": "1.0.4", + "resolved": "https://registry.npmjs.org/content-type/-/content-type-1.0.4.tgz", + "integrity": "sha512-hIP3EEPs8tB9AT1L+NUqtwOAps4mk2Zob89MWXMHjHWg9milF/j4osnnQLXBCBFBk/tvIG/tUc9mOUJiPBhPXA==", + "engines": { + "node": ">= 0.6" + } + }, + "node_modules/cookie": { + "version": "0.5.0", + "resolved": "https://registry.npmjs.org/cookie/-/cookie-0.5.0.tgz", + "integrity": "sha512-YZ3GUyn/o8gfKJlnlX7g7xq4gyO6OSuhGPKaaGssGB2qgDUS0gPgtTvoyZLTt9Ab6dC4hfc9dV5arkvc/OCmrw==", + "engines": { + "node": ">= 0.6" + } + }, + "node_modules/cookie-signature": { + "version": "1.0.6", + "resolved": "https://registry.npmjs.org/cookie-signature/-/cookie-signature-1.0.6.tgz", + "integrity": "sha512-QADzlaHc8icV8I7vbaJXJwod9HWYp8uCqf1xa4OfNu1T7JVxQIrUgOWtHdNDtPiywmFbiS12VjotIXLrKM3orQ==" + }, "node_modules/core-util-is": { "version": "1.0.3", "resolved": "https://registry.npmjs.org/core-util-is/-/core-util-is-1.0.3.tgz", @@ -162,6 +271,15 @@ "node": ">= 0.8" } }, + "node_modules/destroy": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/destroy/-/destroy-1.2.0.tgz", + "integrity": "sha512-2sJGJTaXIIaR1w4iJSNoN0hnMY7Gpc/n8D4qSCJw8QqFWXf7cuAgnEHxBpweaVcPevC2l3KpjYCx3NypQQgaJg==", + "engines": { + "node": ">= 0.8", + "npm": "1.2.8000 || >= 1.4.16" + } + }, "node_modules/dom-serializer": { "version": "1.4.1", "resolved": "https://registry.npmjs.org/dom-serializer/-/dom-serializer-1.4.1.tgz", @@ -218,6 +336,19 @@ "resolved": "https://registry.npmjs.org/easy-crc/-/easy-crc-0.0.2.tgz", "integrity": "sha512-h6eqIdhJRe0p271/xZJbM/0klCi13mW5IB7ZEzEGH11yV4QXWAkD4yPErz0fXdhFrd6sZ4Q1k5Iky2kMsMNePw==" }, + "node_modules/ee-first": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/ee-first/-/ee-first-1.1.1.tgz", + "integrity": "sha512-WMwm9LhRUo+WUaRN+vRuETqG89IgZphVSNkdFgeb6sS/E4OrDIN7t48CAewSHXc6C8lefD8KKfr5vY61brQlow==" + }, + "node_modules/encodeurl": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/encodeurl/-/encodeurl-1.0.2.tgz", + "integrity": "sha512-TPJXq8JqFaVYm2CWmPvnP2Iyo4ZSM7/QKcSmuMLDObfpH5fi7RUGmd/rTDf+rut/saiDiQEeVTNgAmJEdAOx0w==", + "engines": { + "node": ">= 0.8" + } + }, "node_modules/endianness": { "version": "8.0.2", "resolved": "https://registry.npmjs.org/endianness/-/endianness-8.0.2.tgz", @@ -234,6 +365,11 @@ "url": "https://github.com/fb55/entities?sponsor=1" } }, + "node_modules/escape-html": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/escape-html/-/escape-html-1.0.3.tgz", + "integrity": "sha512-NiSupZ4OeuGwr68lGIeym/ksIZMJodUGOSCZ/FSnTxcrekbvqrgdUxlJOMpijaKZVjAJrWrGs/6Jy8OMuyj9ow==" + }, "node_modules/escape-string-regexp": { "version": "4.0.0", "resolved": "https://registry.npmjs.org/escape-string-regexp/-/escape-string-regexp-4.0.0.tgz", @@ -294,6 +430,68 @@ "node": ">=0.10.0" } }, + "node_modules/etag": { + "version": "1.8.1", + "resolved": "https://registry.npmjs.org/etag/-/etag-1.8.1.tgz", + "integrity": "sha512-aIL5Fx7mawVa300al2BnEE4iNvo1qETxLrPI/o05L7z6go7fCw1J6EQmbK4FmJ2AS7kgVF/KEZWufBfdClMcPg==", + "engines": { + "node": ">= 0.6" + } + }, + "node_modules/express": { + "version": "4.18.2", + "resolved": "https://registry.npmjs.org/express/-/express-4.18.2.tgz", + "integrity": "sha512-5/PsL6iGPdfQ/lKM1UuielYgv3BUoJfz1aUwU9vHZ+J7gyvwdQXFEBIEIaxeGf0GIcreATNyBExtalisDbuMqQ==", + "dependencies": { + "accepts": "~1.3.8", + "array-flatten": "1.1.1", + "body-parser": "1.20.1", + "content-disposition": "0.5.4", + "content-type": "~1.0.4", + "cookie": "0.5.0", + "cookie-signature": "1.0.6", + "debug": "2.6.9", + "depd": "2.0.0", + "encodeurl": "~1.0.2", + "escape-html": "~1.0.3", + "etag": "~1.8.1", + "finalhandler": "1.2.0", + "fresh": "0.5.2", + "http-errors": "2.0.0", + "merge-descriptors": "1.0.1", + "methods": "~1.1.2", + "on-finished": "2.4.1", + "parseurl": "~1.3.3", + "path-to-regexp": "0.1.7", + "proxy-addr": "~2.0.7", + "qs": "6.11.0", + "range-parser": "~1.2.1", + "safe-buffer": "5.2.1", + "send": "0.18.0", + "serve-static": "1.15.0", + "setprototypeof": "1.2.0", + "statuses": "2.0.1", + "type-is": "~1.6.18", + "utils-merge": "1.0.1", + "vary": "~1.1.2" + }, + "engines": { + "node": ">= 0.10.0" + } + }, + "node_modules/express/node_modules/debug": { + "version": "2.6.9", + "resolved": "https://registry.npmjs.org/debug/-/debug-2.6.9.tgz", + "integrity": "sha512-bC7ElrdJaJnPbAP+1EotYvqZsb3ecl5wi6Bfi6BJTUcNowp6cvspg0jXznRTKDjm/E7AdgFBVeAPVMNcKGsHMA==", + "dependencies": { + "ms": "2.0.0" + } + }, + "node_modules/express/node_modules/ms": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/ms/-/ms-2.0.0.tgz", + "integrity": "sha512-Tpp60P6IUJDTuOq/5Z8cdskzJujfwqfOTkrwIwj7IRISpnkJnT6SyJ4PCPnGMoFjC9ddhal5KVIYtAt97ix05A==" + }, "node_modules/fast-levenshtein": { "version": "2.0.6", "resolved": "https://registry.npmjs.org/fast-levenshtein/-/fast-levenshtein-2.0.6.tgz", @@ -307,6 +505,52 @@ "node": ">= 6" } }, + "node_modules/finalhandler": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/finalhandler/-/finalhandler-1.2.0.tgz", + "integrity": "sha512-5uXcUVftlQMFnWC9qu/svkWv3GTd2PfUhK/3PLkYNAe7FbqJMt3515HaxE6eRL74GdsriiwujiawdaB1BpEISg==", + "dependencies": { + "debug": "2.6.9", + "encodeurl": "~1.0.2", + "escape-html": "~1.0.3", + "on-finished": "2.4.1", + "parseurl": "~1.3.3", + "statuses": "2.0.1", + "unpipe": "~1.0.0" + }, + "engines": { + "node": ">= 0.8" + } + }, + "node_modules/finalhandler/node_modules/debug": { + "version": "2.6.9", + "resolved": "https://registry.npmjs.org/debug/-/debug-2.6.9.tgz", + "integrity": "sha512-bC7ElrdJaJnPbAP+1EotYvqZsb3ecl5wi6Bfi6BJTUcNowp6cvspg0jXznRTKDjm/E7AdgFBVeAPVMNcKGsHMA==", + "dependencies": { + "ms": "2.0.0" + } + }, + "node_modules/finalhandler/node_modules/ms": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/ms/-/ms-2.0.0.tgz", + "integrity": "sha512-Tpp60P6IUJDTuOq/5Z8cdskzJujfwqfOTkrwIwj7IRISpnkJnT6SyJ4PCPnGMoFjC9ddhal5KVIYtAt97ix05A==" + }, + "node_modules/forwarded": { + "version": "0.2.0", + "resolved": "https://registry.npmjs.org/forwarded/-/forwarded-0.2.0.tgz", + "integrity": "sha512-buRG0fpBtRHSTCOASe6hD258tEubFoRLb4ZNA6NxMVHNw2gOcwHo9wyablzMzOA5z9xA9L1KNjk/Nt6MT9aYow==", + "engines": { + "node": ">= 0.6" + } + }, + "node_modules/fresh": { + "version": "0.5.2", + "resolved": "https://registry.npmjs.org/fresh/-/fresh-0.5.2.tgz", + "integrity": "sha512-zJ2mQYM18rEFOudeV4GShTGIQ7RbzA7ozbU9I/XBpm7kqgMywgmylMwXHxZJmkVoYkna9d2pVXVXPdYTP9ej8Q==", + "engines": { + "node": ">= 0.6" + } + }, "node_modules/fs-extra": { "version": "8.1.0", "resolved": "https://registry.npmjs.org/fs-extra/-/fs-extra-8.1.0.tgz", @@ -332,6 +576,24 @@ "node": ">=0.8.0" } }, + "node_modules/function-bind": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/function-bind/-/function-bind-1.1.1.tgz", + "integrity": "sha512-yIovAzMX49sF8Yl58fSCWJ5svSLuaibPxXQJFLmBObTuCr0Mf1KiPopGM9NiFjiYBCbfaa2Fh6breQ6ANVTI0A==" + }, + "node_modules/get-intrinsic": { + "version": "1.1.3", + "resolved": "https://registry.npmjs.org/get-intrinsic/-/get-intrinsic-1.1.3.tgz", + "integrity": "sha512-QJVz1Tj7MS099PevUG5jvnt9tSkXN8K14dxQlikJuPt4uD9hHAHjLyLBiLR5zELelBdD9QNRAXZzsJx0WaDL9A==", + "dependencies": { + "function-bind": "^1.1.1", + "has": "^1.0.3", + "has-symbols": "^1.0.3" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, "node_modules/get-uri": { "version": "3.0.2", "resolved": "https://registry.npmjs.org/get-uri/-/get-uri-3.0.2.tgz", @@ -353,6 +615,28 @@ "resolved": "https://registry.npmjs.org/graceful-fs/-/graceful-fs-4.2.10.tgz", "integrity": "sha512-9ByhssR2fPVsNZj478qUUbKfmL0+t5BDVyjShtyZZLiK7ZDAArFFfopyOTj0M05wE2tJPisA4iTnnXl2YoPvOA==" }, + "node_modules/has": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/has/-/has-1.0.3.tgz", + "integrity": "sha512-f2dvO0VU6Oej7RkWJGrehjbzMAjFp5/VKPp5tTpWIV4JHHZK1/BxbFRtf/siA2SWTe09caDmVtYYzWEIbBS4zw==", + "dependencies": { + "function-bind": "^1.1.1" + }, + "engines": { + "node": ">= 0.4.0" + } + }, + "node_modules/has-symbols": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/has-symbols/-/has-symbols-1.0.3.tgz", + "integrity": "sha512-l3LCuF6MgDNwTDKkdYGEihYjt5pRPbEg46rtlmnSPlUbgmB8LOIrKJbYYFBSbnPaJexMKtiPO8hmeRjRz2Td+A==", + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, "node_modules/html-entities": { "version": "2.3.3", "resolved": "https://registry.npmjs.org/html-entities/-/html-entities-2.3.3.tgz", @@ -437,6 +721,14 @@ "resolved": "https://registry.npmjs.org/ip/-/ip-1.1.8.tgz", "integrity": "sha512-PuExPYUiu6qMBQb4l06ecm6T6ujzhmh+MeJcW9wa89PoAz5pvd4zPgN5WJV104mb6S2T1AwNIAaB70JNrLQWhg==" }, + "node_modules/ipaddr.js": { + "version": "1.9.1", + "resolved": "https://registry.npmjs.org/ipaddr.js/-/ipaddr.js-1.9.1.tgz", + "integrity": "sha512-0KI/607xoxSToH7GjN1FfSbLoU0+btTicjsQSWQlh/hZykN8KpmMf7uYwPW3R+akZ6R/w18ZlXSHBYXiYUPO3g==", + "engines": { + "node": ">= 0.10" + } + }, "node_modules/is-plain-object": { "version": "5.0.0", "resolved": "https://registry.npmjs.org/is-plain-object/-/is-plain-object-5.0.0.tgz", @@ -478,6 +770,38 @@ "yallist": "^3.0.2" } }, + "node_modules/media-typer": { + "version": "0.3.0", + "resolved": "https://registry.npmjs.org/media-typer/-/media-typer-0.3.0.tgz", + "integrity": "sha512-dq+qelQ9akHpcOl/gUVRTxVIOkAJ1wR3QAvb4RsVjS8oVoFjDGTc679wJYmUmknUF5HwMLOgb5O+a3KxfWapPQ==", + "engines": { + "node": ">= 0.6" + } + }, + "node_modules/merge-descriptors": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/merge-descriptors/-/merge-descriptors-1.0.1.tgz", + "integrity": "sha512-cCi6g3/Zr1iqQi6ySbseM1Xvooa98N0w31jzUYrXPX2xqObmFGHJ0tQ5u74H3mVh7wLouTseZyYIq39g8cNp1w==" + }, + "node_modules/methods": { + "version": "1.1.2", + "resolved": "https://registry.npmjs.org/methods/-/methods-1.1.2.tgz", + "integrity": "sha512-iclAHeNqNm68zFtnZ0e+1L2yUIdvzNoauKU4WBA3VvH/vPFieF7qfRlwUZU+DA9P9bPXIS90ulxoUoCH23sV2w==", + "engines": { + "node": ">= 0.6" + } + }, + "node_modules/mime": { + "version": "1.6.0", + "resolved": "https://registry.npmjs.org/mime/-/mime-1.6.0.tgz", + "integrity": "sha512-x0Vn8spI+wuJ1O6S7gnbaQg8Pxh4NNHb7KSINmEWKiPE4RKOplvijn+NkmYmmRgP68mc70j2EbeTFRsrswaQeg==", + "bin": { + "mime": "cli.js" + }, + "engines": { + "node": ">=4" + } + }, "node_modules/mime-db": { "version": "1.52.0", "resolved": "https://registry.npmjs.org/mime-db/-/mime-db-1.52.0.tgz", @@ -513,6 +837,14 @@ "node": "^10 || ^12 || ^13.7 || ^14 || >=15.0.1" } }, + "node_modules/negotiator": { + "version": "0.6.3", + "resolved": "https://registry.npmjs.org/negotiator/-/negotiator-0.6.3.tgz", + "integrity": "sha512-+EUsqGPLsM+j/zdChZjsnX51g4XrHFOIXwfnCVPGlQk/k5giakcKsuxCObBRu6DSm9opw/O6slWbJdghQM4bBg==", + "engines": { + "node": ">= 0.6" + } + }, "node_modules/netmask": { "version": "2.0.2", "resolved": "https://registry.npmjs.org/netmask/-/netmask-2.0.2.tgz", @@ -529,6 +861,25 @@ "node": ">=8.9.0" } }, + "node_modules/object-inspect": { + "version": "1.12.2", + "resolved": "https://registry.npmjs.org/object-inspect/-/object-inspect-1.12.2.tgz", + "integrity": "sha512-z+cPxW0QGUp0mcqcsgQyLVRDoXFQbXOwBaqyF7VIgI4TWNQsDHrBpUQslRmIfAoYWdYzs6UlKJtB2XJpTaNSpQ==", + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/on-finished": { + "version": "2.4.1", + "resolved": "https://registry.npmjs.org/on-finished/-/on-finished-2.4.1.tgz", + "integrity": "sha512-oVlzkg3ENAhCk2zdv7IJwd/QUD4z2RxRwpkcGY8psCVcCYZNq4wYnVWALHM+brtuJjePWiYF/ClmuDr8Ch5+kg==", + "dependencies": { + "ee-first": "1.1.1" + }, + "engines": { + "node": ">= 0.8" + } + }, "node_modules/optionator": { "version": "0.8.3", "resolved": "https://registry.npmjs.org/optionator/-/optionator-0.8.3.tgz", @@ -595,6 +946,19 @@ "resolved": "https://registry.npmjs.org/parse-srcset/-/parse-srcset-1.0.2.tgz", "integrity": "sha512-/2qh0lav6CmI15FzA3i/2Bzk2zCgQhGMkvhOhKNcBVQ1ldgpbfiNTVslmooUmWJcADi1f1kIeynbDRVzNlfR6Q==" }, + "node_modules/parseurl": { + "version": "1.3.3", + "resolved": "https://registry.npmjs.org/parseurl/-/parseurl-1.3.3.tgz", + "integrity": "sha512-CiyeOxFT/JZyN5m0z9PfXw4SCBJ6Sygz1Dpl0wqjlhDEGGBP1GnsUVEL0p63hoG1fcj3fHynXi9NYO4nWOL+qQ==", + "engines": { + "node": ">= 0.8" + } + }, + "node_modules/path-to-regexp": { + "version": "0.1.7", + "resolved": "https://registry.npmjs.org/path-to-regexp/-/path-to-regexp-0.1.7.tgz", + "integrity": "sha512-5DFkuoqlv1uYQKxy8omFBeJPQcdoE07Kv2sferDCrAq1ohOU+MSDswDIbnx3YAM60qIOnYa53wBhXW0EbMonrQ==" + }, "node_modules/picocolors": { "version": "1.0.0", "resolved": "https://registry.npmjs.org/picocolors/-/picocolors-1.0.0.tgz", @@ -631,6 +995,18 @@ "node": ">= 0.8.0" } }, + "node_modules/proxy-addr": { + "version": "2.0.7", + "resolved": "https://registry.npmjs.org/proxy-addr/-/proxy-addr-2.0.7.tgz", + "integrity": "sha512-llQsMLSUDUPT44jdrU/O37qlnifitDP+ZwrmmZcoSKyLKvtZxpyV0n2/bD/N4tBAAZ/gJEdZU7KMraoK1+XYAg==", + "dependencies": { + "forwarded": "0.2.0", + "ipaddr.js": "1.9.1" + }, + "engines": { + "node": ">= 0.10" + } + }, "node_modules/proxy-agent": { "version": "5.0.0", "resolved": "https://registry.npmjs.org/proxy-agent/-/proxy-agent-5.0.0.tgz", @@ -667,6 +1043,28 @@ "resolved": "https://registry.npmjs.org/proxy-from-env/-/proxy-from-env-1.1.0.tgz", "integrity": "sha512-D+zkORCbA9f1tdWRK0RaCR3GPv50cMxcrz4X8k5LTSUD1Dkw47mKJEZQNunItRTkWwgtaUSo1RVFRIG9ZXiFYg==" }, + "node_modules/qs": { + "version": "6.11.0", + "resolved": "https://registry.npmjs.org/qs/-/qs-6.11.0.tgz", + "integrity": "sha512-MvjoMCJwEarSbUYk5O+nmoSzSutSsTwF85zcHPQ9OrlFoZOYIjaqBAJIqIXjptyD5vThxGq52Xu/MaJzRkIk4Q==", + "dependencies": { + "side-channel": "^1.0.4" + }, + "engines": { + "node": ">=0.6" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/range-parser": { + "version": "1.2.1", + "resolved": "https://registry.npmjs.org/range-parser/-/range-parser-1.2.1.tgz", + "integrity": "sha512-Hrgsx+orqoygnmhFbKaHE6c296J+HTAQXoxEF6gNupROmmGJRoyzfG3ccAveqCBrwr/2yxQ5BVd/GTl5agOwSg==", + "engines": { + "node": ">= 0.6" + } + }, "node_modules/raw-body": { "version": "2.5.1", "resolved": "https://registry.npmjs.org/raw-body/-/raw-body-2.5.1.tgz", @@ -703,6 +1101,25 @@ "string_decoder": "~0.10.x" } }, + "node_modules/safe-buffer": { + "version": "5.2.1", + "resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.2.1.tgz", + "integrity": "sha512-rp3So07KcdmmKbGvgaNxQSJr7bGVSVk5S9Eq1F+ppbRo70+YeaDxkw5Dd8NPN+GD6bjnYm2VuPuCXmpuYvmCXQ==", + "funding": [ + { + "type": "github", + "url": "https://github.com/sponsors/feross" + }, + { + "type": "patreon", + "url": "https://www.patreon.com/feross" + }, + { + "type": "consulting", + "url": "https://feross.org/support" + } + ] + }, "node_modules/safer-buffer": { "version": "2.1.2", "resolved": "https://registry.npmjs.org/safer-buffer/-/safer-buffer-2.1.2.tgz", @@ -721,11 +1138,79 @@ "postcss": "^8.3.11" } }, + "node_modules/send": { + "version": "0.18.0", + "resolved": "https://registry.npmjs.org/send/-/send-0.18.0.tgz", + "integrity": "sha512-qqWzuOjSFOuqPjFe4NOsMLafToQQwBSOEpS+FwEt3A2V3vKubTquT3vmLTQpFgMXp8AlFWFuP1qKaJZOtPpVXg==", + "dependencies": { + "debug": "2.6.9", + "depd": "2.0.0", + "destroy": "1.2.0", + "encodeurl": "~1.0.2", + "escape-html": "~1.0.3", + "etag": "~1.8.1", + "fresh": "0.5.2", + "http-errors": "2.0.0", + "mime": "1.6.0", + "ms": "2.1.3", + "on-finished": "2.4.1", + "range-parser": "~1.2.1", + "statuses": "2.0.1" + }, + "engines": { + "node": ">= 0.8.0" + } + }, + "node_modules/send/node_modules/debug": { + "version": "2.6.9", + "resolved": "https://registry.npmjs.org/debug/-/debug-2.6.9.tgz", + "integrity": "sha512-bC7ElrdJaJnPbAP+1EotYvqZsb3ecl5wi6Bfi6BJTUcNowp6cvspg0jXznRTKDjm/E7AdgFBVeAPVMNcKGsHMA==", + "dependencies": { + "ms": "2.0.0" + } + }, + "node_modules/send/node_modules/debug/node_modules/ms": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/ms/-/ms-2.0.0.tgz", + "integrity": "sha512-Tpp60P6IUJDTuOq/5Z8cdskzJujfwqfOTkrwIwj7IRISpnkJnT6SyJ4PCPnGMoFjC9ddhal5KVIYtAt97ix05A==" + }, + "node_modules/send/node_modules/ms": { + "version": "2.1.3", + "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.3.tgz", + "integrity": "sha512-6FlzubTLZG3J2a/NVCAleEhjzq5oxgHyaCU9yYXvcLsvoVaHJq/s5xXI6/XXP6tz7R9xAOtHnSO/tXtF3WRTlA==" + }, + "node_modules/serve-static": { + "version": "1.15.0", + "resolved": "https://registry.npmjs.org/serve-static/-/serve-static-1.15.0.tgz", + "integrity": "sha512-XGuRDNjXUijsUL0vl6nSD7cwURuzEgglbOaFuZM9g3kwDXOWVTck0jLzjPzGD+TazWbboZYu52/9/XPdUgne9g==", + "dependencies": { + "encodeurl": "~1.0.2", + "escape-html": "~1.0.3", + "parseurl": "~1.3.3", + "send": "0.18.0" + }, + "engines": { + "node": ">= 0.8.0" + } + }, "node_modules/setprototypeof": { "version": "1.2.0", "resolved": "https://registry.npmjs.org/setprototypeof/-/setprototypeof-1.2.0.tgz", "integrity": "sha512-E5LDX7Wrp85Kil5bhZv46j8jOeboKq5JMmYM3gVGdGH8xFpPWXUMsNrlODCrkoxMEeNi/XZIwuRvY4XNwYMJpw==" }, + "node_modules/side-channel": { + "version": "1.0.4", + "resolved": "https://registry.npmjs.org/side-channel/-/side-channel-1.0.4.tgz", + "integrity": "sha512-q5XPytqFEIKHkGdiMIrY10mvLRvnQh42/+GoBlFW3b2LXLE2xxJpZFdm94we0BaoV3RwJyGqg5wS7epxTv0Zvw==", + "dependencies": { + "call-bind": "^1.0.0", + "get-intrinsic": "^1.0.2", + "object-inspect": "^1.9.0" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, "node_modules/smart-buffer": { "version": "4.2.0", "resolved": "https://registry.npmjs.org/smart-buffer/-/smart-buffer-4.2.0.tgz", @@ -828,6 +1313,18 @@ "node": ">= 0.8.0" } }, + "node_modules/type-is": { + "version": "1.6.18", + "resolved": "https://registry.npmjs.org/type-is/-/type-is-1.6.18.tgz", + "integrity": "sha512-TkRKr9sUTxEH8MdfuCSP7VizJyzRNMjj2J2do2Jr3Kym598JVdEksuzPQCnlFPW4ky9Q+iA+ma9BGm06XQBy8g==", + "dependencies": { + "media-typer": "0.3.0", + "mime-types": "~2.1.24" + }, + "engines": { + "node": ">= 0.6" + } + }, "node_modules/universalify": { "version": "0.1.2", "resolved": "https://registry.npmjs.org/universalify/-/universalify-0.1.2.tgz", @@ -844,6 +1341,14 @@ "node": ">= 0.8" } }, + "node_modules/utils-merge": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/utils-merge/-/utils-merge-1.0.1.tgz", + "integrity": "sha512-pMZTvIkT1d+TFGvDOqodOclx0QWkkgi6Tdoa8gC8ffGAAqz9pzPTZWAybbsHHoED/ztMtkv/VoYTYyShUn81hA==", + "engines": { + "node": ">= 0.4.0" + } + }, "node_modules/uuid": { "version": "8.3.2", "resolved": "https://registry.npmjs.org/uuid/-/uuid-8.3.2.tgz", @@ -852,6 +1357,14 @@ "uuid": "dist/bin/uuid" } }, + "node_modules/vary": { + "version": "1.1.2", + "resolved": "https://registry.npmjs.org/vary/-/vary-1.1.2.tgz", + "integrity": "sha512-BNGbWLfd0eUPabhkXUVm0j8uuvREyTh5ovRa/dyow/BqAbZJyC+5fU+IzQOzmAKzYqYRAISoRhdQr3eIZ/PXqg==", + "engines": { + "node": ">= 0.8" + } + }, "node_modules/vm2": { "version": "3.9.11", "resolved": "https://registry.npmjs.org/vm2/-/vm2-3.9.11.tgz", @@ -895,6 +1408,15 @@ "resolved": "https://registry.npmjs.org/@tootallnate/once/-/once-1.1.2.tgz", "integrity": "sha512-RbzJvlNzmRq5c3O09UipeuXno4tA1FE6ikOjxZK0tuxVv3412l64l5t1W5pj4+rJq9vpkm/kwiR07aZXnsKPxw==" }, + "accepts": { + "version": "1.3.8", + "resolved": "https://registry.npmjs.org/accepts/-/accepts-1.3.8.tgz", + "integrity": "sha512-PYAthTa2m2VKxuvSD3DPC/Gy+U+sOA1LAuT8mkmRuvw+NACSaeXEQ+NHcVF7rONl6qcaxV3Uuemwawk+7+SJLw==", + "requires": { + "mime-types": "~2.1.34", + "negotiator": "0.6.3" + } + }, "acorn": { "version": "8.8.0", "resolved": "https://registry.npmjs.org/acorn/-/acorn-8.8.0.tgz", @@ -918,6 +1440,11 @@ "debug": "4" } }, + "array-flatten": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/array-flatten/-/array-flatten-1.1.1.tgz", + "integrity": "sha512-PCVAQswWemu6UdxsDFFX/+gVeYqKAod3D3UVm91jHwynguOwAvYPhx8nNlM++NqRcK6CxxpUafjmhIdKiHibqg==" + }, "ast-types": { "version": "0.13.4", "resolved": "https://registry.npmjs.org/ast-types/-/ast-types-0.13.4.tgz", @@ -926,11 +1453,85 @@ "tslib": "^2.0.1" } }, + "body-parser": { + "version": "1.20.1", + "resolved": "https://registry.npmjs.org/body-parser/-/body-parser-1.20.1.tgz", + "integrity": "sha512-jWi7abTbYwajOytWCQc37VulmWiRae5RyTpaCyDcS5/lMdtwSz5lOpDE67srw/HYe35f1z3fDQw+3txg7gNtWw==", + "requires": { + "bytes": "3.1.2", + "content-type": "~1.0.4", + "debug": "2.6.9", + "depd": "2.0.0", + "destroy": "1.2.0", + "http-errors": "2.0.0", + "iconv-lite": "0.4.24", + "on-finished": "2.4.1", + "qs": "6.11.0", + "raw-body": "2.5.1", + "type-is": "~1.6.18", + "unpipe": "1.0.0" + }, + "dependencies": { + "debug": { + "version": "2.6.9", + "resolved": "https://registry.npmjs.org/debug/-/debug-2.6.9.tgz", + "integrity": "sha512-bC7ElrdJaJnPbAP+1EotYvqZsb3ecl5wi6Bfi6BJTUcNowp6cvspg0jXznRTKDjm/E7AdgFBVeAPVMNcKGsHMA==", + "requires": { + "ms": "2.0.0" + } + }, + "iconv-lite": { + "version": "0.4.24", + "resolved": "https://registry.npmjs.org/iconv-lite/-/iconv-lite-0.4.24.tgz", + "integrity": "sha512-v3MXnZAcvnywkTUEZomIActle7RXXeedOR31wwl7VlyoXO4Qi9arvSenNQWne1TcRwhCL1HwLI21bEqdpj8/rA==", + "requires": { + "safer-buffer": ">= 2.1.2 < 3" + } + }, + "ms": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/ms/-/ms-2.0.0.tgz", + "integrity": "sha512-Tpp60P6IUJDTuOq/5Z8cdskzJujfwqfOTkrwIwj7IRISpnkJnT6SyJ4PCPnGMoFjC9ddhal5KVIYtAt97ix05A==" + } + } + }, "bytes": { "version": "3.1.2", "resolved": "https://registry.npmjs.org/bytes/-/bytes-3.1.2.tgz", "integrity": "sha512-/Nf7TyzTx6S3yRJObOAV7956r8cr2+Oj8AC5dt8wSP3BQAoeX58NoHyCU8P8zGkNXStjTSi6fzO6F0pBdcYbEg==" }, + "call-bind": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/call-bind/-/call-bind-1.0.2.tgz", + "integrity": "sha512-7O+FbCihrB5WGbFYesctwmTKae6rOiIzmz1icreWJ+0aA7LJfuqhEso2T9ncpcFtzMQtzXf2QGGueWJGTYsqrA==", + "requires": { + "function-bind": "^1.1.1", + "get-intrinsic": "^1.0.2" + } + }, + "content-disposition": { + "version": "0.5.4", + "resolved": "https://registry.npmjs.org/content-disposition/-/content-disposition-0.5.4.tgz", + "integrity": "sha512-FveZTNuGw04cxlAiWbzi6zTAL/lhehaWbTtgluJh4/E95DqMwTmha3KZN1aAWA8cFIhHzMZUvLevkw5Rqk+tSQ==", + "requires": { + "safe-buffer": "5.2.1" + } + }, + "content-type": { + "version": "1.0.4", + "resolved": "https://registry.npmjs.org/content-type/-/content-type-1.0.4.tgz", + "integrity": "sha512-hIP3EEPs8tB9AT1L+NUqtwOAps4mk2Zob89MWXMHjHWg9milF/j4osnnQLXBCBFBk/tvIG/tUc9mOUJiPBhPXA==" + }, + "cookie": { + "version": "0.5.0", + "resolved": "https://registry.npmjs.org/cookie/-/cookie-0.5.0.tgz", + "integrity": "sha512-YZ3GUyn/o8gfKJlnlX7g7xq4gyO6OSuhGPKaaGssGB2qgDUS0gPgtTvoyZLTt9Ab6dC4hfc9dV5arkvc/OCmrw==" + }, + "cookie-signature": { + "version": "1.0.6", + "resolved": "https://registry.npmjs.org/cookie-signature/-/cookie-signature-1.0.6.tgz", + "integrity": "sha512-QADzlaHc8icV8I7vbaJXJwod9HWYp8uCqf1xa4OfNu1T7JVxQIrUgOWtHdNDtPiywmFbiS12VjotIXLrKM3orQ==" + }, "core-util-is": { "version": "1.0.3", "resolved": "https://registry.npmjs.org/core-util-is/-/core-util-is-1.0.3.tgz", @@ -980,6 +1581,11 @@ "resolved": "https://registry.npmjs.org/depd/-/depd-2.0.0.tgz", "integrity": "sha512-g7nH6P6dyDioJogAAGprGpCtVImJhpPk/roCzdb3fIh61/s/nPsfR6onyMwkCAR/OlC3yBC0lESvUoQEAssIrw==" }, + "destroy": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/destroy/-/destroy-1.2.0.tgz", + "integrity": "sha512-2sJGJTaXIIaR1w4iJSNoN0hnMY7Gpc/n8D4qSCJw8QqFWXf7cuAgnEHxBpweaVcPevC2l3KpjYCx3NypQQgaJg==" + }, "dom-serializer": { "version": "1.4.1", "resolved": "https://registry.npmjs.org/dom-serializer/-/dom-serializer-1.4.1.tgz", @@ -1018,6 +1624,16 @@ "resolved": "https://registry.npmjs.org/easy-crc/-/easy-crc-0.0.2.tgz", "integrity": "sha512-h6eqIdhJRe0p271/xZJbM/0klCi13mW5IB7ZEzEGH11yV4QXWAkD4yPErz0fXdhFrd6sZ4Q1k5Iky2kMsMNePw==" }, + "ee-first": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/ee-first/-/ee-first-1.1.1.tgz", + "integrity": "sha512-WMwm9LhRUo+WUaRN+vRuETqG89IgZphVSNkdFgeb6sS/E4OrDIN7t48CAewSHXc6C8lefD8KKfr5vY61brQlow==" + }, + "encodeurl": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/encodeurl/-/encodeurl-1.0.2.tgz", + "integrity": "sha512-TPJXq8JqFaVYm2CWmPvnP2Iyo4ZSM7/QKcSmuMLDObfpH5fi7RUGmd/rTDf+rut/saiDiQEeVTNgAmJEdAOx0w==" + }, "endianness": { "version": "8.0.2", "resolved": "https://registry.npmjs.org/endianness/-/endianness-8.0.2.tgz", @@ -1028,6 +1644,11 @@ "resolved": "https://registry.npmjs.org/entities/-/entities-2.2.0.tgz", "integrity": "sha512-p92if5Nz619I0w+akJrLZH0MX0Pb5DX39XOwQTtXSdQQOaYH03S1uIQp4mhOZtAXrxq4ViO67YTiLBo2638o9A==" }, + "escape-html": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/escape-html/-/escape-html-1.0.3.tgz", + "integrity": "sha512-NiSupZ4OeuGwr68lGIeym/ksIZMJodUGOSCZ/FSnTxcrekbvqrgdUxlJOMpijaKZVjAJrWrGs/6Jy8OMuyj9ow==" + }, "escape-string-regexp": { "version": "4.0.0", "resolved": "https://registry.npmjs.org/escape-string-regexp/-/escape-string-regexp-4.0.0.tgz", @@ -1060,6 +1681,64 @@ "resolved": "https://registry.npmjs.org/esutils/-/esutils-2.0.3.tgz", "integrity": "sha512-kVscqXk4OCp68SZ0dkgEKVi6/8ij300KBWTJq32P/dYeWTSwK41WyTxalN1eRmA5Z9UU/LX9D7FWSmV9SAYx6g==" }, + "etag": { + "version": "1.8.1", + "resolved": "https://registry.npmjs.org/etag/-/etag-1.8.1.tgz", + "integrity": "sha512-aIL5Fx7mawVa300al2BnEE4iNvo1qETxLrPI/o05L7z6go7fCw1J6EQmbK4FmJ2AS7kgVF/KEZWufBfdClMcPg==" + }, + "express": { + "version": "4.18.2", + "resolved": "https://registry.npmjs.org/express/-/express-4.18.2.tgz", + "integrity": "sha512-5/PsL6iGPdfQ/lKM1UuielYgv3BUoJfz1aUwU9vHZ+J7gyvwdQXFEBIEIaxeGf0GIcreATNyBExtalisDbuMqQ==", + "requires": { + "accepts": "~1.3.8", + "array-flatten": "1.1.1", + "body-parser": "1.20.1", + "content-disposition": "0.5.4", + "content-type": "~1.0.4", + "cookie": "0.5.0", + "cookie-signature": "1.0.6", + "debug": "2.6.9", + "depd": "2.0.0", + "encodeurl": "~1.0.2", + "escape-html": "~1.0.3", + "etag": "~1.8.1", + "finalhandler": "1.2.0", + "fresh": "0.5.2", + "http-errors": "2.0.0", + "merge-descriptors": "1.0.1", + "methods": "~1.1.2", + "on-finished": "2.4.1", + "parseurl": "~1.3.3", + "path-to-regexp": "0.1.7", + "proxy-addr": "~2.0.7", + "qs": "6.11.0", + "range-parser": "~1.2.1", + "safe-buffer": "5.2.1", + "send": "0.18.0", + "serve-static": "1.15.0", + "setprototypeof": "1.2.0", + "statuses": "2.0.1", + "type-is": "~1.6.18", + "utils-merge": "1.0.1", + "vary": "~1.1.2" + }, + "dependencies": { + "debug": { + "version": "2.6.9", + "resolved": "https://registry.npmjs.org/debug/-/debug-2.6.9.tgz", + "integrity": "sha512-bC7ElrdJaJnPbAP+1EotYvqZsb3ecl5wi6Bfi6BJTUcNowp6cvspg0jXznRTKDjm/E7AdgFBVeAPVMNcKGsHMA==", + "requires": { + "ms": "2.0.0" + } + }, + "ms": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/ms/-/ms-2.0.0.tgz", + "integrity": "sha512-Tpp60P6IUJDTuOq/5Z8cdskzJujfwqfOTkrwIwj7IRISpnkJnT6SyJ4PCPnGMoFjC9ddhal5KVIYtAt97ix05A==" + } + } + }, "fast-levenshtein": { "version": "2.0.6", "resolved": "https://registry.npmjs.org/fast-levenshtein/-/fast-levenshtein-2.0.6.tgz", @@ -1070,6 +1749,45 @@ "resolved": "https://registry.npmjs.org/file-uri-to-path/-/file-uri-to-path-2.0.0.tgz", "integrity": "sha512-hjPFI8oE/2iQPVe4gbrJ73Pp+Xfub2+WI2LlXDbsaJBwT5wuMh35WNWVYYTpnz895shtwfyutMFLFywpQAFdLg==" }, + "finalhandler": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/finalhandler/-/finalhandler-1.2.0.tgz", + "integrity": "sha512-5uXcUVftlQMFnWC9qu/svkWv3GTd2PfUhK/3PLkYNAe7FbqJMt3515HaxE6eRL74GdsriiwujiawdaB1BpEISg==", + "requires": { + "debug": "2.6.9", + "encodeurl": "~1.0.2", + "escape-html": "~1.0.3", + "on-finished": "2.4.1", + "parseurl": "~1.3.3", + "statuses": "2.0.1", + "unpipe": "~1.0.0" + }, + "dependencies": { + "debug": { + "version": "2.6.9", + "resolved": "https://registry.npmjs.org/debug/-/debug-2.6.9.tgz", + "integrity": "sha512-bC7ElrdJaJnPbAP+1EotYvqZsb3ecl5wi6Bfi6BJTUcNowp6cvspg0jXznRTKDjm/E7AdgFBVeAPVMNcKGsHMA==", + "requires": { + "ms": "2.0.0" + } + }, + "ms": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/ms/-/ms-2.0.0.tgz", + "integrity": "sha512-Tpp60P6IUJDTuOq/5Z8cdskzJujfwqfOTkrwIwj7IRISpnkJnT6SyJ4PCPnGMoFjC9ddhal5KVIYtAt97ix05A==" + } + } + }, + "forwarded": { + "version": "0.2.0", + "resolved": "https://registry.npmjs.org/forwarded/-/forwarded-0.2.0.tgz", + "integrity": "sha512-buRG0fpBtRHSTCOASe6hD258tEubFoRLb4ZNA6NxMVHNw2gOcwHo9wyablzMzOA5z9xA9L1KNjk/Nt6MT9aYow==" + }, + "fresh": { + "version": "0.5.2", + "resolved": "https://registry.npmjs.org/fresh/-/fresh-0.5.2.tgz", + "integrity": "sha512-zJ2mQYM18rEFOudeV4GShTGIQ7RbzA7ozbU9I/XBpm7kqgMywgmylMwXHxZJmkVoYkna9d2pVXVXPdYTP9ej8Q==" + }, "fs-extra": { "version": "8.1.0", "resolved": "https://registry.npmjs.org/fs-extra/-/fs-extra-8.1.0.tgz", @@ -1089,6 +1807,21 @@ "xregexp": "2.0.0" } }, + "function-bind": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/function-bind/-/function-bind-1.1.1.tgz", + "integrity": "sha512-yIovAzMX49sF8Yl58fSCWJ5svSLuaibPxXQJFLmBObTuCr0Mf1KiPopGM9NiFjiYBCbfaa2Fh6breQ6ANVTI0A==" + }, + "get-intrinsic": { + "version": "1.1.3", + "resolved": "https://registry.npmjs.org/get-intrinsic/-/get-intrinsic-1.1.3.tgz", + "integrity": "sha512-QJVz1Tj7MS099PevUG5jvnt9tSkXN8K14dxQlikJuPt4uD9hHAHjLyLBiLR5zELelBdD9QNRAXZzsJx0WaDL9A==", + "requires": { + "function-bind": "^1.1.1", + "has": "^1.0.3", + "has-symbols": "^1.0.3" + } + }, "get-uri": { "version": "3.0.2", "resolved": "https://registry.npmjs.org/get-uri/-/get-uri-3.0.2.tgz", @@ -1107,6 +1840,19 @@ "resolved": "https://registry.npmjs.org/graceful-fs/-/graceful-fs-4.2.10.tgz", "integrity": "sha512-9ByhssR2fPVsNZj478qUUbKfmL0+t5BDVyjShtyZZLiK7ZDAArFFfopyOTj0M05wE2tJPisA4iTnnXl2YoPvOA==" }, + "has": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/has/-/has-1.0.3.tgz", + "integrity": "sha512-f2dvO0VU6Oej7RkWJGrehjbzMAjFp5/VKPp5tTpWIV4JHHZK1/BxbFRtf/siA2SWTe09caDmVtYYzWEIbBS4zw==", + "requires": { + "function-bind": "^1.1.1" + } + }, + "has-symbols": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/has-symbols/-/has-symbols-1.0.3.tgz", + "integrity": "sha512-l3LCuF6MgDNwTDKkdYGEihYjt5pRPbEg46rtlmnSPlUbgmB8LOIrKJbYYFBSbnPaJexMKtiPO8hmeRjRz2Td+A==" + }, "html-entities": { "version": "2.3.3", "resolved": "https://registry.npmjs.org/html-entities/-/html-entities-2.3.3.tgz", @@ -1172,6 +1918,11 @@ "resolved": "https://registry.npmjs.org/ip/-/ip-1.1.8.tgz", "integrity": "sha512-PuExPYUiu6qMBQb4l06ecm6T6ujzhmh+MeJcW9wa89PoAz5pvd4zPgN5WJV104mb6S2T1AwNIAaB70JNrLQWhg==" }, + "ipaddr.js": { + "version": "1.9.1", + "resolved": "https://registry.npmjs.org/ipaddr.js/-/ipaddr.js-1.9.1.tgz", + "integrity": "sha512-0KI/607xoxSToH7GjN1FfSbLoU0+btTicjsQSWQlh/hZykN8KpmMf7uYwPW3R+akZ6R/w18ZlXSHBYXiYUPO3g==" + }, "is-plain-object": { "version": "5.0.0", "resolved": "https://registry.npmjs.org/is-plain-object/-/is-plain-object-5.0.0.tgz", @@ -1207,6 +1958,26 @@ "yallist": "^3.0.2" } }, + "media-typer": { + "version": "0.3.0", + "resolved": "https://registry.npmjs.org/media-typer/-/media-typer-0.3.0.tgz", + "integrity": "sha512-dq+qelQ9akHpcOl/gUVRTxVIOkAJ1wR3QAvb4RsVjS8oVoFjDGTc679wJYmUmknUF5HwMLOgb5O+a3KxfWapPQ==" + }, + "merge-descriptors": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/merge-descriptors/-/merge-descriptors-1.0.1.tgz", + "integrity": "sha512-cCi6g3/Zr1iqQi6ySbseM1Xvooa98N0w31jzUYrXPX2xqObmFGHJ0tQ5u74H3mVh7wLouTseZyYIq39g8cNp1w==" + }, + "methods": { + "version": "1.1.2", + "resolved": "https://registry.npmjs.org/methods/-/methods-1.1.2.tgz", + "integrity": "sha512-iclAHeNqNm68zFtnZ0e+1L2yUIdvzNoauKU4WBA3VvH/vPFieF7qfRlwUZU+DA9P9bPXIS90ulxoUoCH23sV2w==" + }, + "mime": { + "version": "1.6.0", + "resolved": "https://registry.npmjs.org/mime/-/mime-1.6.0.tgz", + "integrity": "sha512-x0Vn8spI+wuJ1O6S7gnbaQg8Pxh4NNHb7KSINmEWKiPE4RKOplvijn+NkmYmmRgP68mc70j2EbeTFRsrswaQeg==" + }, "mime-db": { "version": "1.52.0", "resolved": "https://registry.npmjs.org/mime-db/-/mime-db-1.52.0.tgz", @@ -1230,6 +2001,11 @@ "resolved": "https://registry.npmjs.org/nanoid/-/nanoid-3.3.4.tgz", "integrity": "sha512-MqBkQh/OHTS2egovRtLk45wEyNXwF+cokD+1YPf9u5VfJiRdAiRwB2froX5Co9Rh20xs4siNPm8naNotSD6RBw==" }, + "negotiator": { + "version": "0.6.3", + "resolved": "https://registry.npmjs.org/negotiator/-/negotiator-0.6.3.tgz", + "integrity": "sha512-+EUsqGPLsM+j/zdChZjsnX51g4XrHFOIXwfnCVPGlQk/k5giakcKsuxCObBRu6DSm9opw/O6slWbJdghQM4bBg==" + }, "netmask": { "version": "2.0.2", "resolved": "https://registry.npmjs.org/netmask/-/netmask-2.0.2.tgz", @@ -1240,6 +2016,19 @@ "resolved": "https://registry.npmjs.org/newsie/-/newsie-1.2.1.tgz", "integrity": "sha512-41jhtKmlpSc27oIBkp681fm4aLURPT/AgeBvSRicxNPWDVeHLaq7tSvG/OsEXz7g41thgv9JMV1ZjYSABMiYVA==" }, + "object-inspect": { + "version": "1.12.2", + "resolved": "https://registry.npmjs.org/object-inspect/-/object-inspect-1.12.2.tgz", + "integrity": "sha512-z+cPxW0QGUp0mcqcsgQyLVRDoXFQbXOwBaqyF7VIgI4TWNQsDHrBpUQslRmIfAoYWdYzs6UlKJtB2XJpTaNSpQ==" + }, + "on-finished": { + "version": "2.4.1", + "resolved": "https://registry.npmjs.org/on-finished/-/on-finished-2.4.1.tgz", + "integrity": "sha512-oVlzkg3ENAhCk2zdv7IJwd/QUD4z2RxRwpkcGY8psCVcCYZNq4wYnVWALHM+brtuJjePWiYF/ClmuDr8Ch5+kg==", + "requires": { + "ee-first": "1.1.1" + } + }, "optionator": { "version": "0.8.3", "resolved": "https://registry.npmjs.org/optionator/-/optionator-0.8.3.tgz", @@ -1296,6 +2085,16 @@ "resolved": "https://registry.npmjs.org/parse-srcset/-/parse-srcset-1.0.2.tgz", "integrity": "sha512-/2qh0lav6CmI15FzA3i/2Bzk2zCgQhGMkvhOhKNcBVQ1ldgpbfiNTVslmooUmWJcADi1f1kIeynbDRVzNlfR6Q==" }, + "parseurl": { + "version": "1.3.3", + "resolved": "https://registry.npmjs.org/parseurl/-/parseurl-1.3.3.tgz", + "integrity": "sha512-CiyeOxFT/JZyN5m0z9PfXw4SCBJ6Sygz1Dpl0wqjlhDEGGBP1GnsUVEL0p63hoG1fcj3fHynXi9NYO4nWOL+qQ==" + }, + "path-to-regexp": { + "version": "0.1.7", + "resolved": "https://registry.npmjs.org/path-to-regexp/-/path-to-regexp-0.1.7.tgz", + "integrity": "sha512-5DFkuoqlv1uYQKxy8omFBeJPQcdoE07Kv2sferDCrAq1ohOU+MSDswDIbnx3YAM60qIOnYa53wBhXW0EbMonrQ==" + }, "picocolors": { "version": "1.0.0", "resolved": "https://registry.npmjs.org/picocolors/-/picocolors-1.0.0.tgz", @@ -1316,6 +2115,15 @@ "resolved": "https://registry.npmjs.org/prelude-ls/-/prelude-ls-1.1.2.tgz", "integrity": "sha512-ESF23V4SKG6lVSGZgYNpbsiaAkdab6ZgOxe52p7+Kid3W3u3bxR4Vfd/o21dmN7jSt0IwgZ4v5MUd26FEtXE9w==" }, + "proxy-addr": { + "version": "2.0.7", + "resolved": "https://registry.npmjs.org/proxy-addr/-/proxy-addr-2.0.7.tgz", + "integrity": "sha512-llQsMLSUDUPT44jdrU/O37qlnifitDP+ZwrmmZcoSKyLKvtZxpyV0n2/bD/N4tBAAZ/gJEdZU7KMraoK1+XYAg==", + "requires": { + "forwarded": "0.2.0", + "ipaddr.js": "1.9.1" + } + }, "proxy-agent": { "version": "5.0.0", "resolved": "https://registry.npmjs.org/proxy-agent/-/proxy-agent-5.0.0.tgz", @@ -1348,6 +2156,19 @@ "resolved": "https://registry.npmjs.org/proxy-from-env/-/proxy-from-env-1.1.0.tgz", "integrity": "sha512-D+zkORCbA9f1tdWRK0RaCR3GPv50cMxcrz4X8k5LTSUD1Dkw47mKJEZQNunItRTkWwgtaUSo1RVFRIG9ZXiFYg==" }, + "qs": { + "version": "6.11.0", + "resolved": "https://registry.npmjs.org/qs/-/qs-6.11.0.tgz", + "integrity": "sha512-MvjoMCJwEarSbUYk5O+nmoSzSutSsTwF85zcHPQ9OrlFoZOYIjaqBAJIqIXjptyD5vThxGq52Xu/MaJzRkIk4Q==", + "requires": { + "side-channel": "^1.0.4" + } + }, + "range-parser": { + "version": "1.2.1", + "resolved": "https://registry.npmjs.org/range-parser/-/range-parser-1.2.1.tgz", + "integrity": "sha512-Hrgsx+orqoygnmhFbKaHE6c296J+HTAQXoxEF6gNupROmmGJRoyzfG3ccAveqCBrwr/2yxQ5BVd/GTl5agOwSg==" + }, "raw-body": { "version": "2.5.1", "resolved": "https://registry.npmjs.org/raw-body/-/raw-body-2.5.1.tgz", @@ -1380,6 +2201,11 @@ "string_decoder": "~0.10.x" } }, + "safe-buffer": { + "version": "5.2.1", + "resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.2.1.tgz", + "integrity": "sha512-rp3So07KcdmmKbGvgaNxQSJr7bGVSVk5S9Eq1F+ppbRo70+YeaDxkw5Dd8NPN+GD6bjnYm2VuPuCXmpuYvmCXQ==" + }, "safer-buffer": { "version": "2.1.2", "resolved": "https://registry.npmjs.org/safer-buffer/-/safer-buffer-2.1.2.tgz", @@ -1398,11 +2224,74 @@ "postcss": "^8.3.11" } }, + "send": { + "version": "0.18.0", + "resolved": "https://registry.npmjs.org/send/-/send-0.18.0.tgz", + "integrity": "sha512-qqWzuOjSFOuqPjFe4NOsMLafToQQwBSOEpS+FwEt3A2V3vKubTquT3vmLTQpFgMXp8AlFWFuP1qKaJZOtPpVXg==", + "requires": { + "debug": "2.6.9", + "depd": "2.0.0", + "destroy": "1.2.0", + "encodeurl": "~1.0.2", + "escape-html": "~1.0.3", + "etag": "~1.8.1", + "fresh": "0.5.2", + "http-errors": "2.0.0", + "mime": "1.6.0", + "ms": "2.1.3", + "on-finished": "2.4.1", + "range-parser": "~1.2.1", + "statuses": "2.0.1" + }, + "dependencies": { + "debug": { + "version": "2.6.9", + "resolved": "https://registry.npmjs.org/debug/-/debug-2.6.9.tgz", + "integrity": "sha512-bC7ElrdJaJnPbAP+1EotYvqZsb3ecl5wi6Bfi6BJTUcNowp6cvspg0jXznRTKDjm/E7AdgFBVeAPVMNcKGsHMA==", + "requires": { + "ms": "2.0.0" + }, + "dependencies": { + "ms": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/ms/-/ms-2.0.0.tgz", + "integrity": "sha512-Tpp60P6IUJDTuOq/5Z8cdskzJujfwqfOTkrwIwj7IRISpnkJnT6SyJ4PCPnGMoFjC9ddhal5KVIYtAt97ix05A==" + } + } + }, + "ms": { + "version": "2.1.3", + "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.3.tgz", + "integrity": "sha512-6FlzubTLZG3J2a/NVCAleEhjzq5oxgHyaCU9yYXvcLsvoVaHJq/s5xXI6/XXP6tz7R9xAOtHnSO/tXtF3WRTlA==" + } + } + }, + "serve-static": { + "version": "1.15.0", + "resolved": "https://registry.npmjs.org/serve-static/-/serve-static-1.15.0.tgz", + "integrity": "sha512-XGuRDNjXUijsUL0vl6nSD7cwURuzEgglbOaFuZM9g3kwDXOWVTck0jLzjPzGD+TazWbboZYu52/9/XPdUgne9g==", + "requires": { + "encodeurl": "~1.0.2", + "escape-html": "~1.0.3", + "parseurl": "~1.3.3", + "send": "0.18.0" + } + }, "setprototypeof": { "version": "1.2.0", "resolved": "https://registry.npmjs.org/setprototypeof/-/setprototypeof-1.2.0.tgz", "integrity": "sha512-E5LDX7Wrp85Kil5bhZv46j8jOeboKq5JMmYM3gVGdGH8xFpPWXUMsNrlODCrkoxMEeNi/XZIwuRvY4XNwYMJpw==" }, + "side-channel": { + "version": "1.0.4", + "resolved": "https://registry.npmjs.org/side-channel/-/side-channel-1.0.4.tgz", + "integrity": "sha512-q5XPytqFEIKHkGdiMIrY10mvLRvnQh42/+GoBlFW3b2LXLE2xxJpZFdm94we0BaoV3RwJyGqg5wS7epxTv0Zvw==", + "requires": { + "call-bind": "^1.0.0", + "get-intrinsic": "^1.0.2", + "object-inspect": "^1.9.0" + } + }, "smart-buffer": { "version": "4.2.0", "resolved": "https://registry.npmjs.org/smart-buffer/-/smart-buffer-4.2.0.tgz", @@ -1478,6 +2367,15 @@ "prelude-ls": "~1.1.2" } }, + "type-is": { + "version": "1.6.18", + "resolved": "https://registry.npmjs.org/type-is/-/type-is-1.6.18.tgz", + "integrity": "sha512-TkRKr9sUTxEH8MdfuCSP7VizJyzRNMjj2J2do2Jr3Kym598JVdEksuzPQCnlFPW4ky9Q+iA+ma9BGm06XQBy8g==", + "requires": { + "media-typer": "0.3.0", + "mime-types": "~2.1.24" + } + }, "universalify": { "version": "0.1.2", "resolved": "https://registry.npmjs.org/universalify/-/universalify-0.1.2.tgz", @@ -1488,11 +2386,21 @@ "resolved": "https://registry.npmjs.org/unpipe/-/unpipe-1.0.0.tgz", "integrity": "sha512-pjy2bYhSsufwWlKwPc+l3cN7+wuJlK6uz0YdJEOlQDbl6jo/YlPi4mb8agUkVC8BF7V8NuzeyPNqRksA3hztKQ==" }, + "utils-merge": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/utils-merge/-/utils-merge-1.0.1.tgz", + "integrity": "sha512-pMZTvIkT1d+TFGvDOqodOclx0QWkkgi6Tdoa8gC8ffGAAqz9pzPTZWAybbsHHoED/ztMtkv/VoYTYyShUn81hA==" + }, "uuid": { "version": "8.3.2", "resolved": "https://registry.npmjs.org/uuid/-/uuid-8.3.2.tgz", "integrity": "sha512-+NYs2QeMWy+GWFOEm9xnn6HCDp0l7QBD7ml8zLUmJ+93Q5NF0NocErnwkTkXVFNiX3/fpC6afS8Dhb/gz7R7eg==" }, + "vary": { + "version": "1.1.2", + "resolved": "https://registry.npmjs.org/vary/-/vary-1.1.2.tgz", + "integrity": "sha512-BNGbWLfd0eUPabhkXUVm0j8uuvREyTh5ovRa/dyow/BqAbZJyC+5fU+IzQOzmAKzYqYRAISoRhdQr3eIZ/PXqg==" + }, "vm2": { "version": "3.9.11", "resolved": "https://registry.npmjs.org/vm2/-/vm2-3.9.11.tgz", diff --git a/zefie_wtvp_minisrv/package.json b/zefie_wtvp_minisrv/package.json index 5e5fa6a4..ba7e1635 100644 --- a/zefie_wtvp_minisrv/package.json +++ b/zefie_wtvp_minisrv/package.json @@ -1,6 +1,6 @@ { "name": "zefie_wtvp_minisrv", - "version": "0.9.31", + "version": "0.9.32", "description": "WebTV Service (WTVP) Emulation Server", "main": "app.js", "homepage": "https://github.com/zefie/zefie_wtvp_minisrv", @@ -31,6 +31,7 @@ "crypto-js": "^4.1.1", "easy-crc": "0.0.2", "endianness": "^8.0.2", + "express": "^4.18.2", "html-entities": "^2.3.3", "iconv-lite": "^0.6.3", "mime-types": "^2.1.35",