- fix: throw proper error if wtv-update:/sync called without arguments
- feature: Support to route all HTTP proxied requests over a SOCKS proxy (eg Tor or VPN)
- feature: Psuedo-HTTPS (WebTV can now visit HTTPS URLs via proxy, but
  we do not use SSL encryption when sending back to the WebTV)
- fix: header issue with login-stage-two.js
- update: wtv-update/sync: allow multiple groups in sync diskmap, fix md5 comparsion
- update: wtv-home:/home: added connection speed
- Renamed processSSID to filterSSID
- Documented and rewrote some functions
This commit is contained in:
zefie
2021-07-20 05:45:43 -04:00
parent 8f91ba2a5c
commit 8bc4d29815
10 changed files with 552 additions and 101 deletions

View File

@@ -10,13 +10,14 @@ This open source server is in alpha status. Use at your own risk.
- Can handle client "relogin" and "reconnect" events
- Suports `.js` service files with synchronous or asynchronous requests
- Supports multiple simultaneous users
- WebTV-compatible HTTP Proxy (via minisrv, or using an external proxy for enhanced features (such as [WebOne](https://github.com/atauenis/webone))
- WebTV-compatible HTTP(S) Proxy (via minisrv, or using an external proxy for enhanced features (such as [WebOne](https://github.com/atauenis/webone))
- wtv-flashrom for LC2 and newer boxes (bf0app unsupported, need test unit)
- Can flash anything on [Ultra Willies](https://wtv.zefie.com/willie.php) with optional `use_zefie_server` flag set on `wtv-flashrom` service.
- wtv-update:/sync for Download-o-Rama style file downloading
### Current issues:
- HTTPS Proxying untested, likely needs SSL spoofing with self-signed solution
- Occasionally, in certain circumstances, a specific SSID may be unable to reconnect to the server until the server is restarted
- Mis-configuring wtv-update:/sync DiskMaps may cause units to delete contents of partitions (need more info)
### Won't fix:
- wtv-encryption stream breaks when two different sessions have the same SSID (eg spoofing, won't fix (production did it too))

View File

@@ -1,14 +1,5 @@
/*
if (socket.ssid != null && !ssid_sessions[socket.ssid].get("wtvsec_login")) {
var wtvsec_login = new WTVSec();
wtvsec_login.IssueChallenge();
wtvsec_login.set_incarnation(request_headers["wtv-incarnation"]);
ssid_sessions[socket.ssid].set("wtvsec_login", wtvsec_login);
} else if (socket.ssid != null) {
var wtvsec_login = ssid_sessions[socket.ssid].get("wtvsec_login");
}
*/
if (socket.ssid != null) {
if (ssid_sessions[socket.ssid].get("wtvsec_login")) ssid_sessions[socket.ssid].delete("wtvsec_login");
var wtvsec_login = new WTVSec();
wtvsec_login.IssueChallenge();
wtvsec_login.set_incarnation(request_headers["wtv-incarnation"]);

View File

@@ -24,11 +24,11 @@ if (socket.ssid !== null) {
if (challenge_response && client_challenge_response) {
//if (challenge_response.toString(CryptoJS.enc.Base64).substring(0,85) == client_challenge_response.substring(0,85)) {
if (challenge_response.toString(CryptoJS.enc.Base64) == client_challenge_response) {
console.log(" * wtv-challenge-response success for " + processSSID(socket.ssid));
console.log(" * wtv-challenge-response success for " + filterSSID(socket.ssid));
wtvsec_login.PrepareTicket();
//socket_sessions[socket.id].secure = true;
} else {
console.log(" * wtv-challenge-response FAILED for " + processSSID(socket.ssid));
console.log(" * wtv-challenge-response FAILED for " + filterSSID(socket.ssid));
if (zdebug) console.log("Response Expected:", challenge_response.toString(CryptoJS.enc.Base64));
if (zdebug) console.log("Response Received:", client_challenge_response)
gourl = "wtv-head-waiter:/login?reissue_challenge=true";
@@ -63,7 +63,7 @@ wtv-country: US
wtv-language-header: en-US,en
wtv-visit: client:closeallpanels
wtv-expire-all: client:closeallpanels
wtv-offline-user-list: `+offline_user_list+`
wtv-offline-user-list: `+ offline_user_list + `
wtv-bypass-proxy: true
wtv-ticket: `+ wtvsec_login.ticket_b64 + `
wtv-messagewatch-checktimeoffset: off
@@ -72,14 +72,15 @@ wtv-connection-timeout: 90
wtv-fader-timeout: 900
wtv-ssl-log-url: wtv-log:/log
wtv-smartcard-inserted-message: Contacting service
user-id: `+userid+`
user-id: `+ userid + `
wtv-transition-override: off
wtv-allow-dsc: true
wtv-messenger-enable: 0
wtv-noback-all: wtv-
wtv-service: reset
`+ getServiceString('all') + `
wtv-boot-url: wtv-1800:/preregister?relogin=true`
wtv-boot-url: wtv-1800:/preregister?relogin=true
`;
//wtv-ssl-certs-download-url: wtv-head-waiter:/ssl-cert.der
//wtv-ssl-certs-checksum: 473926DC1B11F635A6B920953FDCDE6A
headers += `wtv-user-name: `+ nickname + `

View File

@@ -22,8 +22,8 @@ function go() {
}
</script>
<h2>Welcome to `+ z_title + `</h2>
<h3>Encryption Status: `+cryptstatus+`</h3>`
data += `<h4>Working stuff</h4>
<h3>Encryption Status: `+cryptstatus+`</h3>
Connection Speed: &rate;
<form name=access onsubmit="go()">
<ul>
<li><a href="client:relog">client:relog (direct)</a></li>
@@ -43,11 +43,6 @@ data += `width=250 height=10 bgcolor=#444444 text=#ffdd33 cursor=#cc9933 select
</form></li>
</ul>`
try {
if (fs.lstatSync(service_dir + "/home.zefie.html")) {
data += fs.readFileSync(service_dir + "/home.zefie.html", { 'encoding': 'utf8' });
}
} catch (e) {
// silent
}
data += "</body>\n</html>";
if (fs.existsSync(service_vaults[0].path + "/" + service_name + "/home.zefie.html")) {
data += fs.readFileSync(service_vaults[0].path + "/" + service_name + "/home.zefie.html", { 'encoding': 'utf8' });
}

View File

@@ -23,7 +23,7 @@ Content-length: 0`;
logdata_outstring_hex += request_headers.post_data.toString(CryptoJS.enc.Hex);
if (minisrv_config.services[service_name].write_logs_to_disk) {
fs.writeFile(fullpath, logdata_outstring_hex, "Hex", function () {
if (!zquiet) console.log(" * Wrote POST log data from", processSSID(socket.ssid), "for", socket.id);
if (!zquiet) console.log(" * Wrote POST log data from", filterSSID(socket.ssid), "for", socket.id);
sendToClient(socket, headers, data);
});
} else {
@@ -43,7 +43,7 @@ Content-length: 0`;
var logdata_outstring_hex = Buffer.from(logdata_outstring, 'utf8').toString('hex');
if (minisrv_config.services[service_name].write_logs_to_disk) {
fs.writeFile(fullpath, logdata_outstring_hex, "Hex", function () {
if (!zquiet) console.log(" * Wrote GET log data from", processSSID(socket.ssid), "for", socket.id);
if (!zquiet) console.log(" * Wrote GET log data from", filterSSID(socket.ssid), "for", socket.id);
sendToClient(socket, headers, data);
});
} else {

View File

@@ -75,10 +75,10 @@ function processGroup(diskmap_primary_group, diskmap_group_data, diskmap_subgrou
post_data_current_file = post_data[k];
}
if (post_data[k].indexOf(":") > 0) {
var post_data_line = post_data[k].split(":")
var post_data_line = post_data[k].split(": ")
var post_data_line_name = post_data_line[0];
post_data_line.shift();
var post_data_line_data = post_data_line.join(":");
var post_data_line_data = post_data_line.join(": ");
if (!post_data_fileinfo[post_data_filecount]) post_data_fileinfo[post_data_filecount] = new Array();
@@ -90,8 +90,6 @@ function processGroup(diskmap_primary_group, diskmap_group_data, diskmap_subgrou
else {
post_data_fileinfo[post_data_filecount][post_data_line_name] = post_data_line_data;
}
} else {
post_data_filecount++;
post_data_current_file = post_data_current_directory + post_data[k];
@@ -108,8 +106,10 @@ function processGroup(diskmap_primary_group, diskmap_group_data, diskmap_subgrou
post_match_file = service_vaults[g].path + "/" + service_name + "/" + diskmap_group_data.files[k].location;
if (!fs.existsSync(post_match_file)) post_match_file = null;
});
var post_match_file_lstat = fs.lstatSync(post_match_file);
var post_match_result = post_data_fileinfo.find(el => el["file"] === diskmap_group_data.files[k].file) || false;
var post_match_result = post_data_fileinfo.find(el => el.file === diskmap_group_data.files[k].file) || null;
var post_match_file_data = new Buffer.from(fs.readFileSync(post_match_file, {
encoding: null,
flags: 'r'
@@ -121,7 +121,7 @@ function processGroup(diskmap_primary_group, diskmap_group_data, diskmap_subgrou
if (post_match_result) {
// md5s match, so client doesn't need file
if (diskmap_group_data.files[k]['wtv-checksum'] == post_match_result["wtv-checksum"]) return;
if (diskmap_group_data.files[k]['wtv-checksum'].toLowerCase() == post_match_result["wtv-checksum"]) return;
else wtv_download_list.push(diskmap_group_data.files[k]);
} else {
wtv_download_list.push(diskmap_group_data.files[k]);
@@ -150,13 +150,13 @@ if (request_headers.query.diskmap && request_headers.query.group && request_head
}
data = '';
diskmap_data = diskmap_data[request_headers.query.group];
/*if (!diskmap_data.display) {
if (!diskmap_data.display) {
Object.keys(diskmap_data).forEach(function (k) {
if (diskmap_data[k]) data += processGroup(request_headers.query.group,diskmap_data[k],k);
});
} else { */
data = processGroup(request_headers.query.group, diskmap_data);
//}
} else {
data = processGroup(request_headers.query.group, diskmap_data);
}
headers = "200 OK\nContent-Type: wtv/download-list";
} catch (e) {
@@ -172,5 +172,10 @@ if (request_headers.query.diskmap && request_headers.query.group && request_head
data = errpage[1];
console.log("wtv-update:/sync error", "could not find diskmap");
}
} else {
var errpage = doErrorPage(400);
headers = errpage[0];
data = errpage[1];
if (zdebug) console.log("wtv-update:/sync error", "missing query arguments");
}

View File

@@ -3,7 +3,7 @@
const fs = require('fs');
const http = require('http');
const https = require('https');
const strftime = require('strftime');
const strftime = require('strftime'); // used externally by service scripts
const net = require('net');
const CryptoJS = require('crypto-js');
const mime = require('mime-types');
@@ -11,8 +11,14 @@ const { crc16 } = require('easy-crc');
var WTVSec = require('./wtvsec.js');
var ClientSessionData = require('./session_data.js');
// Where we store our session information
var ssid_sessions = new Array();
var socket_sessions = new Array();
var ports = [];
// add .reverse() feature to all JavaScript Strings in this application
// works for service vault scripts too.
String.prototype.reverse = function () {
var splitString = this.split("");
var reverseArray = splitString.reverse();
@@ -20,9 +26,8 @@ String.prototype.reverse = function () {
return joinArray;
}
function getServiceString(service) {
// used externally by service scripts
if (service === "all") {
var out = "";
Object.keys(minisrv_config.services).forEach(function (k) {
@@ -38,12 +43,6 @@ function getServiceString(service) {
}
}
var ssid_sessions = new Array();
var socket_buffer = new Array();
var socket_sessions = new Array();
var script_processing_timeout = 10; // seconds
function getFileExt(path) {
return path.reverse().split(".")[0].reverse();
}
@@ -71,45 +70,45 @@ function doErrorPage(code, data = null) {
return new Array(headers, data);
}
function getConType(path) {
// custom contype for flashrom
if (path.indexOf("wtv-flashrom") && (getFileExt(path).toLowerCase() == "rom" || getFileExt(path).toLowerCase() == "brom")) {
return "binary/x-wtv-flashblock";
} else if (getFileExt(path).toLowerCase() == "rmf") {
return "audio/x-rmf";
}
}
return mime.lookup(path);
}
async function processPath(socket, path, request_headers = new Array(), service_name) {
async function processPath(socket, service_vault_file_path, request_headers = new Array(), service_name) {
var headers, data = null;
var request_is_direct_file = false;
var request_is_async = false;
var service_vault_found = false;
var service_path = path;
var service_path = service_vault_file_path;
try {
service_vaults.forEach(function (service_vault_dir) {
if (service_vault_found) return;
path = service_vault_dir.path + "/" + service_path.replace(/\\/g, "/");
service_vault_file_path = service_vault_dir.path + "/" + service_path.replace(/\\/g, "/");
if (fs.existsSync(path)) {
if (fs.existsSync(service_vault_file_path)) {
// file exists, read it and return it
service_vault_found = true;
request_is_async = true;
if (!zquiet) console.log(" * Found " + path + " in " + service_vault_dir.name +" to handle request (Direct File Mode) [Socket " + socket.id + "]");
var contype = getConType(path);
if (!zquiet) console.log(" * Found " + service_vault_file_path + " in " + service_vault_dir.name +" to handle request (Direct File Mode) [Socket " + socket.id + "]");
var contype = getConType(service_vault_file_path);
headers = "200 OK\n"
headers += "Content-Type: " + contype;
fs.readFile(path, null, function (err, data) {
fs.readFile(service_vault_file_path, null, function (err, data) {
sendToClient(socket, headers, data);
});
} else if (fs.existsSync(path + ".txt")) {
service_vault_found = true;
} else if (fs.existsSync(service_vault_file_path + ".txt")) {
// raw text format, entire payload expected (headers and content)
if (!zquiet) console.log(" * Found " + path + ".txt in " + service_vault_dir.name +" to handle request (Raw TXT Mode) [Socket " + socket.id + "]");
service_vault_found = true;
if (!zquiet) console.log(" * Found " + service_vault_file_path + ".txt in " + service_vault_dir.name +" to handle request (Raw TXT Mode) [Socket " + socket.id + "]");
request_is_async = true;
fs.readFile(path + ".txt", 'Utf-8', function (err, file_raw) {
fs.readFile(service_vault_file_path + ".txt", 'Utf-8', function (err, file_raw) {
if (file_raw.indexOf("\n\n") > 0) {
// split headers and data by newline (unix format)
var file_raw_split = file_raw.split("\n\n");
@@ -129,32 +128,35 @@ async function processPath(socket, path, request_headers = new Array(), service_
}
sendToClient(socket, headers, data);
});
} else if (fs.existsSync(path + ".js")) {
service_vault_found = true;
} else if (fs.existsSync(service_vault_file_path + ".js")) {
// synchronous js scripting, process with vars, must set 'headers' and 'data' appropriately.
// loaded script will have r/w access to any JavaScript vars this function does.
// request headers are in an array named `request_headers`.
// Query arguments in `request_headers.query`
if (!zquiet) console.log(" * Found " + path + ".js in " + service_vault_dir.name + " to handle request (JS Interpreter mode) [Socket " + socket.id + "]");
// Can upgrade to asynchronous by setting `request_is_async` to `true`
// In Asynchronous mode, you are expected to call sendToClient(socket,headers,data) by the end of your script
// `socket` is already defined and should be passed-through.
service_vault_found = true;
if (!zquiet) console.log(" * Found " + service_vault_file_path + ".js in " + service_vault_dir.name + " to handle request (JS Interpreter mode) [Socket " + socket.id + "]");
// expose var service_dir for script path to the root of the wtv-service
var service_dir = service_vault_dir.path.replace(/\\/g, "/") + "/" + service_name;
socket_sessions[socket.id].starttime = Math.floor(new Date().getTime() / 1000);
var jscript_eval = fs.readFileSync(path + ".js").toString();
var jscript_eval = fs.readFileSync(service_vault_file_path + ".js").toString();
eval(jscript_eval);
if (request_is_async && !zquiet) console.log(" * Script requested Asynchronous mode");
}
else if (fs.existsSync(path + ".html")) {
service_vault_found = true;
else if (fs.existsSync(service_vault_file_path + ".html")) {
// Standard HTML with no headers, WTV Style
if (!zquiet) console.log(" * Found " + path + ".html in " + service_vault_dir.name +" to handle request (HTML Mode) [Socket " + socket.id + "]");
service_vault_found = true;
if (!zquiet) console.log(" * Found " + service_vault_file_path + ".html in " + service_vault_dir.name +" to handle request (HTML Mode) [Socket " + socket.id + "]");
request_is_async = true;
headers = "200 OK\n"
headers += "Content-Type: text/html"
fs.readFile(path + ".html", null, function (err, data) {
fs.readFile(service_vault_file_path + ".html", null, function (err, data) {
sendToClient(socket, headers, data);
});
}
// 'headers' and 'data' should both be set with content by this point!
// either `request_is_async`, or `headers` and `data` MUST be defined by this point!
});
} catch (e) {
var errpage = doErrorPage(400);
@@ -183,7 +185,7 @@ async function processPath(socket, path, request_headers = new Array(), service_
}
}
function processSSID(obj) {
function filterSSID(obj) {
if (minisrv_config.config.hide_ssid_in_logs) {
if (typeof (obj) == "string") {
if (obj.substr(0, 8) == "MSTVSIMU") {
@@ -243,14 +245,14 @@ async function processURL(socket, request_headers) {
reqverb = "Psuedo-encrypted " + reqverb;
}
if (ssid != null) {
console.log(" * " + reqverb + " for " + request_headers.request_url + " from WebTV SSID " + (await processSSID(ssid)), 'on', socket.id);
console.log(" * " + reqverb + " for " + request_headers.request_url + " from WebTV SSID " + (await filterSSID(ssid)), 'on', socket.id);
} else {
console.log(" * " + reqverb + " for " + request_headers.request_url, 'on', socket.id);
}
// assume webtv since there is a :/ in the GET
var service_name = shortURL.split(':/')[0];
var urlToPath = service_name + "/" + shortURL.split(':/')[1];
if (zshowheaders) console.log(" * Incoming headers on socket ID", socket.id, (await processSSID(request_headers)));
if (zshowheaders) console.log(" * Incoming headers on socket ID", socket.id, (await filterSSID(request_headers)));
processPath(socket, urlToPath, request_headers, service_name);
} else if (shortURL.indexOf('http://') >= 0 || shortURL.indexOf('https://') >= 0) {
doHTTPProxy(socket, request_headers);
@@ -266,8 +268,8 @@ async function processURL(socket, request_headers) {
}
async function doHTTPProxy(socket, request_headers) {
if (zshowheaders) console.log("HTTP Proxy: Client Request Headers on socket ID", socket.id, (await processSSID(request_headers)));
var request_type = request_headers.request.indexOf('https://') ? 'http' : 'https'
var request_type = (request_headers.request_url.substring(0,5) == 'https') ? 'https' : 'http'
if (zshowheaders) console.log(request_type.toUpperCase() +" Proxy: Client Request Headers on socket ID", socket.id, (await filterSSID(request_headers)));
switch (request_type) {
case "https":
var proxy_agent = https;
@@ -309,10 +311,15 @@ async function doHTTPProxy(socket, request_headers) {
}
if (minisrv_config.services[request_type].use_external_proxy && minisrv_config.services[request_type].external_proxy_port) {
options.host = minisrv_config.services[request_type].external_proxy_host;
options.port = minisrv_config.services[request_type].external_proxy_port;
options.path = request_headers.request.split(' ')[1];
options.headers.Host = request_data.host;
if (minisrv_config.services[request_type].external_proxy_is_socks) {
var ProxyAgent = require('proxy-agent');
options.agent = new ProxyAgent("socks://" + (minisrv_config.services[request_type].external_proxy_host || "127.0.0.1") + ":" + minisrv_config.services[request_type].external_proxy_port);
} else {
options.host = minisrv_config.services[request_type].external_proxy_host;
options.port = minisrv_config.services[request_type].external_proxy_port;
options.path = request_headers.request.split(' ')[1];
options.headers.Host = request_data.host;
}
}
const req = proxy_agent.request(options, function (res) {
var data = [];
@@ -367,7 +374,7 @@ async function doHTTPProxy(socket, request_headers) {
}
}
async function headerStringToObj(headers, response = false) {
function headerStringToObj(headers, response = false) {
var inc_headers = 0;
var headers_obj = new Array();
var headers_obj_pre = headers.split("\n");
@@ -403,7 +410,7 @@ async function sendToClient(socket, headers_obj, data) {
if (typeof (data) === 'undefined') data = '';
if (typeof (headers_obj) === 'string') {
// string to header object
headers_obj = await headerStringToObj(headers_obj, true);
headers_obj = headerStringToObj(headers_obj, true);
}
// add Connection header if missing, default to Keep-Alive
@@ -448,7 +455,7 @@ async function sendToClient(socket, headers_obj, data) {
// header object to string
if (zshowheaders) console.log(" * Outgoing headers on socket ID", socket.id, (await processSSID(headers_obj)));
if (zshowheaders) console.log(" * Outgoing headers on socket ID", socket.id, (await filterSSID(headers_obj)));
Object.keys(headers_obj).forEach(function (k) {
if (k == "http_response") {
headers += headers_obj[k] + "\r\n";
@@ -520,10 +527,11 @@ function moveObjectElement(currentKey, afterKey, obj) {
}
function headersAreStandard(string, verbose = false) {
// the test will see the binary compressed/enrypted data as ASCII, so a generic "isAscii"
// is not suffuicent. This checks for characters expected in unecrypted headers, and returns
// true only if every character in the string matches the regex. Once we know the string is binary
// we can better process it with the raw base64 data in processRequest() below.
// a generic "isAscii" check is not sufficient, as the test will see the binary
// compressed / encrypted data as ASCII. This function checks for characters expected
// in unencrypted headers, and returns true only if every character in the string matches
// the regex. Once we know the string is binary, we can better process it with the
// raw base64 or hex data in processRequest() below.
return /^([A-Za-z0-9\+\/\=\-\.\,\ \"\;\:\?\&\r\n\(\)\%\<\>\_]{8,})$/.test(string);
}
@@ -540,7 +548,7 @@ async function processRequest(socket, data_hex, returnHeadersBeforeSecure = fals
data = data.split("\n\n")[0];
}
if (headersAreStandard(data)) {
headers = await headerStringToObj(data);
headers = headerStringToObj(data);
} else if (!returnHeadersBeforeSecure) {
// if its a POST request, assume its a binary blob and not encrypted (dangerous)
if (!encryptedRequest) {
@@ -676,8 +684,9 @@ wtv-visit: client:relog
Content-type: text/html`;
data = '';
*/
delete socket_sessions[socket.id].wtvsec;
socket_sessions[socket.id].secure = false
socket_sessions[socket.id].close_me = true;
delete socket_sessions[socket.id].wtvsec;
sendToClient(socket, headers, data);
} else {
processURL(socket, headers);
@@ -724,11 +733,10 @@ async function cleanupSocket(socket) {
var fuckyou = ssid_sessions[socket.ssid].sockets;
if (ssid_sessions[socket.ssid].sockets.length === 0 && ssid_sessions[socket.ssid].get("wtvsec_login")) {
// if last socket for SSID disconnected, destroy login session
if (!zquiet) console.log(" * Last socket from WebTV SSID", processSSID(socket.ssid),"disconnected, destroying initial WTVSec instance");
if (!zquiet) console.log(" * Last socket from WebTV SSID", filterSSID(socket.ssid),"disconnected, destroying initial WTVSec instance");
ssid_sessions[socket.ssid].delete("wtvsec_login");
}
}
;
socket.end();
} catch (e) {
console.log(" # Could not clean up socket data for socket ID", socket.id, e);
@@ -738,12 +746,22 @@ async function cleanupSocket(socket) {
async function handleSocket(socket) {
// create unique socket id with client address and port
socket.id = parseInt(crc16('CCITT-FALSE', Buffer.from(String(socket.remoteAddress) + String(socket.remotePort), "utf8")).toString(16), 16);
socket_sessions[socket.id] = [];
socket.setEncoding('hex'); //set data encoding (either 'ascii', 'utf8', or 'base64')
socket.setEncoding('hex'); //set data encoding (Text: 'ascii', 'utf8' ~ Binary: 'hex', 'base64' (do not trust 'binary' encoding))
// NOTE: As it stands we use a 'timeout' to start processing data when we have not recieved any data
// from the client in X time (defined in config, in milliseconds). The problem with this is in the case of
// a modem retrain during a request.
// TODO: Properly know when client is done sending data, by parsing headers.
// Caveat of this is that sometimes the Content-length header does not exist, or will be encrypted.
socket.on('data', function (data_hex) {
socket.setTimeout(minisrv_config.config.socket_timeout);
socket.setTimeout(minisrv_config.config.socket_timeout); // the timeout mentioned above
// Store all received data into a buffer. Kind of misleading as its not a true JS Buffer
// but instead a CryptoJS WordArray
if (socket_sessions[socket.id].buffer) {
socket_sessions[socket.id].buffer.concat(CryptoJS.enc.Hex.parse(data_hex));
} else {
@@ -754,6 +772,7 @@ async function handleSocket(socket) {
socket.on('timeout', async function () {
// start the async chain
if (socket_sessions[socket.id].buffer) {
// process the request if the buffer exists
processRequest(this, socket_sessions[socket.id].buffer.toString(CryptoJS.enc.Hex));
}
});
@@ -763,6 +782,7 @@ async function handleSocket(socket) {
});
socket.on('end', function () {
// Attempt to clean up all of our WTVSec instances
cleanupSocket(socket);
});
}
@@ -794,6 +814,9 @@ function returnAbsolsutePath(path) {
return path;
}
// SERVER START
var z_title = "zefie's wtv minisrv v" + require('./package.json').version;
console.log("**** Welcome to " + z_title + " ****");
console.log(" *** Reading global configuration...");

View File

@@ -32,7 +32,7 @@
"wtv-log": {
"port": 1609,
"connections": 1,
"write_logs_to_disk": false
"write_logs_to_disk": false
},
"wtv-home": {
"port": 1612,
@@ -45,7 +45,7 @@
"wtv-flashrom": {
"port": 1618,
"flags": "0x00000040",
"use_zefie_server": true
"use_zefie_server": true
},
"wtv-music": {
"port": 1656,
@@ -55,10 +55,18 @@
"http": {
"port": 1650,
"connections": 3,
"use_external_proxy": false,
"external_proxy_host": null,
"external_proxy_port": 8080
"use_external_proxy": true,
"external_proxy_is_socks": true,
"external_proxy_host": "127.0.0.1",
"external_proxy_port": 1080
},
"https": {
"port": 1650,
"connections": 3,
"use_external_proxy": true,
"external_proxy_is_socks": true,
"external_proxy_host": "127.0.0.1",
"external_proxy_port": 1080
}
}
}

View File

@@ -1,14 +1,79 @@
{
"name": "zefie_wtvp_minisrv",
"version": "0.7.2",
"version": "0.9.1",
"lockfileVersion": 1,
"requires": true,
"dependencies": {
"@tootallnate/once": {
"version": "1.1.2",
"resolved": "https://registry.npmjs.org/@tootallnate/once/-/once-1.1.2.tgz",
"integrity": "sha512-RbzJvlNzmRq5c3O09UipeuXno4tA1FE6ikOjxZK0tuxVv3412l64l5t1W5pj4+rJq9vpkm/kwiR07aZXnsKPxw=="
},
"agent-base": {
"version": "6.0.2",
"resolved": "https://registry.npmjs.org/agent-base/-/agent-base-6.0.2.tgz",
"integrity": "sha512-RZNwNclF7+MS/8bDg70amg32dyeZGZxiDuQmZxKLAlQjr3jGyLx+4Kkk58UO7D2QdgFIQCovuSuZESne6RG6XQ==",
"requires": {
"debug": "4"
}
},
"ast-types": {
"version": "0.13.4",
"resolved": "https://registry.npmjs.org/ast-types/-/ast-types-0.13.4.tgz",
"integrity": "sha512-x1FCFnFifvYDDzTaLII71vG5uvDwgtmDTEVWAxrgeiR8VjMONcCXJx7E+USjDtHlwFmt9MysbqgF9b9Vjr6w+w==",
"requires": {
"tslib": "^2.0.1"
}
},
"bytes": {
"version": "3.1.0",
"resolved": "https://registry.npmjs.org/bytes/-/bytes-3.1.0.tgz",
"integrity": "sha512-zauLjrfCG+xvoyaqLoV8bLVXXNGC4JqlxFCutSDWA6fJrTo2ZuvLYTqZ7aHBLZSMOopbzwv8f+wZcVzfVTI2Dg=="
},
"core-util-is": {
"version": "1.0.2",
"resolved": "https://registry.npmjs.org/core-util-is/-/core-util-is-1.0.2.tgz",
"integrity": "sha1-tf1UIgqivFq1eqtxQMlAdUUDwac="
},
"crypto-js": {
"version": "4.0.0",
"resolved": "https://registry.npmjs.org/crypto-js/-/crypto-js-4.0.0.tgz",
"integrity": "sha512-bzHZN8Pn+gS7DQA6n+iUmBfl0hO5DJq++QP3U6uTucDtk/0iGpXd/Gg7CGR0p8tJhofJyaKoWBuJI4eAO00BBg=="
},
"data-uri-to-buffer": {
"version": "3.0.1",
"resolved": "https://registry.npmjs.org/data-uri-to-buffer/-/data-uri-to-buffer-3.0.1.tgz",
"integrity": "sha512-WboRycPNsVw3B3TL559F7kuBUM4d8CgMEvk6xEJlOp7OBPjt6G7z8WMWlD2rOFZLk6OYfFIUGsCOWzcQH9K2og=="
},
"debug": {
"version": "4.3.2",
"resolved": "https://registry.npmjs.org/debug/-/debug-4.3.2.tgz",
"integrity": "sha512-mOp8wKcvj7XxC78zLgw/ZA+6TSgkoE2C/ienthhRD298T7UNwAg9diBpLRxC0mOezLl4B0xV7M0cCO6P/O0Xhw==",
"requires": {
"ms": "2.1.2"
}
},
"deep-is": {
"version": "0.1.3",
"resolved": "https://registry.npmjs.org/deep-is/-/deep-is-0.1.3.tgz",
"integrity": "sha1-s2nW+128E+7PUk+RsHD+7cNXzzQ="
},
"degenerator": {
"version": "3.0.1",
"resolved": "https://registry.npmjs.org/degenerator/-/degenerator-3.0.1.tgz",
"integrity": "sha512-LFsIFEeLPlKvAKXu7j3ssIG6RT0TbI7/GhsqrI0DnHASEQjXQ0LUSYcjJteGgRGmZbl1TnMSxpNQIAiJ7Du5TQ==",
"requires": {
"ast-types": "^0.13.2",
"escodegen": "^1.8.1",
"esprima": "^4.0.0",
"vm2": "^3.9.3"
}
},
"depd": {
"version": "1.1.2",
"resolved": "https://registry.npmjs.org/depd/-/depd-1.1.2.tgz",
"integrity": "sha1-m81S4UwJd2PnSbJ0xDRu0uVgtak="
},
"easy-crc": {
"version": "0.0.2",
"resolved": "https://registry.npmjs.org/easy-crc/-/easy-crc-0.0.2.tgz",
@@ -19,6 +84,159 @@
"resolved": "https://registry.npmjs.org/endianness/-/endianness-8.0.2.tgz",
"integrity": "sha512-IU+77+jJ7lpw2qZ3NUuqBZFy3GuioNgXUdsL1L9tooDNTaw0TgOnwNuc+8Ns+haDaTifK97QLzmOANJtI/rGvw=="
},
"escodegen": {
"version": "1.14.3",
"resolved": "https://registry.npmjs.org/escodegen/-/escodegen-1.14.3.tgz",
"integrity": "sha512-qFcX0XJkdg+PB3xjZZG/wKSuT1PnQWx57+TVSjIMmILd2yC/6ByYElPwJnslDsuWuSAp4AwJGumarAAmJch5Kw==",
"requires": {
"esprima": "^4.0.1",
"estraverse": "^4.2.0",
"esutils": "^2.0.2",
"optionator": "^0.8.1",
"source-map": "~0.6.1"
}
},
"esprima": {
"version": "4.0.1",
"resolved": "https://registry.npmjs.org/esprima/-/esprima-4.0.1.tgz",
"integrity": "sha512-eGuFFw7Upda+g4p+QHvnW0RyTX/SVeJBDM/gCtMARO0cLuT2HcEKnTPvhjV6aGeqrCB/sbNop0Kszm0jsaWU4A=="
},
"estraverse": {
"version": "4.3.0",
"resolved": "https://registry.npmjs.org/estraverse/-/estraverse-4.3.0.tgz",
"integrity": "sha512-39nnKffWz8xN1BU/2c79n9nB9HDzo0niYUqx6xyqUnyoAnQyyWpOTdZEeiCch8BBu515t4wp9ZmgVfVhn9EBpw=="
},
"esutils": {
"version": "2.0.3",
"resolved": "https://registry.npmjs.org/esutils/-/esutils-2.0.3.tgz",
"integrity": "sha512-kVscqXk4OCp68SZ0dkgEKVi6/8ij300KBWTJq32P/dYeWTSwK41WyTxalN1eRmA5Z9UU/LX9D7FWSmV9SAYx6g=="
},
"fast-levenshtein": {
"version": "2.0.6",
"resolved": "https://registry.npmjs.org/fast-levenshtein/-/fast-levenshtein-2.0.6.tgz",
"integrity": "sha1-PYpcZog6FqMMqGQ+hR8Zuqd5eRc="
},
"file-uri-to-path": {
"version": "2.0.0",
"resolved": "https://registry.npmjs.org/file-uri-to-path/-/file-uri-to-path-2.0.0.tgz",
"integrity": "sha512-hjPFI8oE/2iQPVe4gbrJ73Pp+Xfub2+WI2LlXDbsaJBwT5wuMh35WNWVYYTpnz895shtwfyutMFLFywpQAFdLg=="
},
"fs-extra": {
"version": "8.1.0",
"resolved": "https://registry.npmjs.org/fs-extra/-/fs-extra-8.1.0.tgz",
"integrity": "sha512-yhlQgA6mnOJUKOsRUFsgJdQCvkKhcz8tlZG5HBQfReYZy46OwLcY+Zia0mtdHsOo9y/hP+CxMN0TU9QxoOtG4g==",
"requires": {
"graceful-fs": "^4.2.0",
"jsonfile": "^4.0.0",
"universalify": "^0.1.0"
}
},
"ftp": {
"version": "0.3.10",
"resolved": "https://registry.npmjs.org/ftp/-/ftp-0.3.10.tgz",
"integrity": "sha1-kZfYYa2BQvPmPVqDv+TFn3MwiF0=",
"requires": {
"readable-stream": "1.1.x",
"xregexp": "2.0.0"
}
},
"get-uri": {
"version": "3.0.2",
"resolved": "https://registry.npmjs.org/get-uri/-/get-uri-3.0.2.tgz",
"integrity": "sha512-+5s0SJbGoyiJTZZ2JTpFPLMPSch72KEqGOTvQsBqg0RBWvwhWUSYZFAtz3TPW0GXJuLBJPts1E241iHg+VRfhg==",
"requires": {
"@tootallnate/once": "1",
"data-uri-to-buffer": "3",
"debug": "4",
"file-uri-to-path": "2",
"fs-extra": "^8.1.0",
"ftp": "^0.3.10"
}
},
"graceful-fs": {
"version": "4.2.6",
"resolved": "https://registry.npmjs.org/graceful-fs/-/graceful-fs-4.2.6.tgz",
"integrity": "sha512-nTnJ528pbqxYanhpDYsi4Rd8MAeaBA67+RZ10CM1m3bTAVFEDcd5AuA4a6W5YkGZ1iNXHzZz8T6TBKLeBuNriQ=="
},
"http-errors": {
"version": "1.7.3",
"resolved": "https://registry.npmjs.org/http-errors/-/http-errors-1.7.3.tgz",
"integrity": "sha512-ZTTX0MWrsQ2ZAhA1cejAwDLycFsd7I7nVtnkT3Ol0aqodaKW+0CTZDQ1uBv5whptCnc8e8HeRRJxRs0kmm/Qfw==",
"requires": {
"depd": "~1.1.2",
"inherits": "2.0.4",
"setprototypeof": "1.1.1",
"statuses": ">= 1.5.0 < 2",
"toidentifier": "1.0.0"
}
},
"http-proxy-agent": {
"version": "4.0.1",
"resolved": "https://registry.npmjs.org/http-proxy-agent/-/http-proxy-agent-4.0.1.tgz",
"integrity": "sha512-k0zdNgqWTGA6aeIRVpvfVob4fL52dTfaehylg0Y4UvSySvOq/Y+BOyPrgpUrA7HylqvU8vIZGsRuXmspskV0Tg==",
"requires": {
"@tootallnate/once": "1",
"agent-base": "6",
"debug": "4"
}
},
"https-proxy-agent": {
"version": "5.0.0",
"resolved": "https://registry.npmjs.org/https-proxy-agent/-/https-proxy-agent-5.0.0.tgz",
"integrity": "sha512-EkYm5BcKUGiduxzSt3Eppko+PiNWNEpa4ySk9vTC6wDsQJW9rHSa+UhGNJoRYp7bz6Ht1eaRIa6QaJqO5rCFbA==",
"requires": {
"agent-base": "6",
"debug": "4"
}
},
"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"
}
},
"inherits": {
"version": "2.0.4",
"resolved": "https://registry.npmjs.org/inherits/-/inherits-2.0.4.tgz",
"integrity": "sha512-k/vGaX4/Yla3WzyMCvTQOXYeIHvqOKtnqBduzTHpzpQZzAskKMhZ2K+EnBiSM9zGSoIFeMpXKxa4dYeZIQqewQ=="
},
"ip": {
"version": "1.1.5",
"resolved": "https://registry.npmjs.org/ip/-/ip-1.1.5.tgz",
"integrity": "sha1-vd7XARQpCCjAoDnnLvJfWq7ENUo="
},
"isarray": {
"version": "0.0.1",
"resolved": "https://registry.npmjs.org/isarray/-/isarray-0.0.1.tgz",
"integrity": "sha1-ihis/Kmo9Bd+Cav8YDiTmwXR7t8="
},
"jsonfile": {
"version": "4.0.0",
"resolved": "https://registry.npmjs.org/jsonfile/-/jsonfile-4.0.0.tgz",
"integrity": "sha1-h3Gq4HmbZAdrdmQPygWPnBDjPss=",
"requires": {
"graceful-fs": "^4.1.6"
}
},
"levn": {
"version": "0.3.0",
"resolved": "https://registry.npmjs.org/levn/-/levn-0.3.0.tgz",
"integrity": "sha1-OwmSTt+fCDwEkP3UwLxEIeBHZO4=",
"requires": {
"prelude-ls": "~1.1.2",
"type-check": "~0.3.2"
}
},
"lru-cache": {
"version": "5.1.1",
"resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-5.1.1.tgz",
"integrity": "sha512-KpNARQA3Iwv+jTA0utUVVbrh+Jlrr1Fv0e56GGzAFOXN7dk/FviaDW8LHmK52DlcH4WP2n6gI8vN1aesBFgo9w==",
"requires": {
"yallist": "^3.0.2"
}
},
"mime-db": {
"version": "1.48.0",
"resolved": "https://registry.npmjs.org/mime-db/-/mime-db-1.48.0.tgz",
@@ -32,10 +250,218 @@
"mime-db": "1.48.0"
}
},
"ms": {
"version": "2.1.2",
"resolved": "https://registry.npmjs.org/ms/-/ms-2.1.2.tgz",
"integrity": "sha512-sGkPx+VjMtmA6MX27oA4FBFELFCZZ4S4XqeGOXCv68tT+jb3vk/RyaKWP0PTKyWtmLSM0b+adUTEvbs1PEaH2w=="
},
"netmask": {
"version": "2.0.2",
"resolved": "https://registry.npmjs.org/netmask/-/netmask-2.0.2.tgz",
"integrity": "sha512-dBpDMdxv9Irdq66304OLfEmQ9tbNRFnFTuZiLo+bD+r332bBmMJ8GBLXklIXXgxd3+v9+KUnZaUR5PJMa75Gsg=="
},
"optionator": {
"version": "0.8.3",
"resolved": "https://registry.npmjs.org/optionator/-/optionator-0.8.3.tgz",
"integrity": "sha512-+IW9pACdk3XWmmTXG8m3upGUJst5XRGzxMRjXzAuJ1XnIFNvfhjjIuYkDvysnPQ7qzqVzLt78BCruntqRhWQbA==",
"requires": {
"deep-is": "~0.1.3",
"fast-levenshtein": "~2.0.6",
"levn": "~0.3.0",
"prelude-ls": "~1.1.2",
"type-check": "~0.3.2",
"word-wrap": "~1.2.3"
}
},
"pac-proxy-agent": {
"version": "5.0.0",
"resolved": "https://registry.npmjs.org/pac-proxy-agent/-/pac-proxy-agent-5.0.0.tgz",
"integrity": "sha512-CcFG3ZtnxO8McDigozwE3AqAw15zDvGH+OjXO4kzf7IkEKkQ4gxQ+3sdF50WmhQ4P/bVusXcqNE2S3XrNURwzQ==",
"requires": {
"@tootallnate/once": "1",
"agent-base": "6",
"debug": "4",
"get-uri": "3",
"http-proxy-agent": "^4.0.1",
"https-proxy-agent": "5",
"pac-resolver": "^5.0.0",
"raw-body": "^2.2.0",
"socks-proxy-agent": "5"
},
"dependencies": {
"socks-proxy-agent": {
"version": "5.0.1",
"resolved": "https://registry.npmjs.org/socks-proxy-agent/-/socks-proxy-agent-5.0.1.tgz",
"integrity": "sha512-vZdmnjb9a2Tz6WEQVIurybSwElwPxMZaIc7PzqbJTrezcKNznv6giT7J7tZDZ1BojVaa1jvO/UiUdhDVB0ACoQ==",
"requires": {
"agent-base": "^6.0.2",
"debug": "4",
"socks": "^2.3.3"
}
}
}
},
"pac-resolver": {
"version": "5.0.0",
"resolved": "https://registry.npmjs.org/pac-resolver/-/pac-resolver-5.0.0.tgz",
"integrity": "sha512-H+/A6KitiHNNW+bxBKREk2MCGSxljfqRX76NjummWEYIat7ldVXRU3dhRIE3iXZ0nvGBk6smv3nntxKkzRL8NA==",
"requires": {
"degenerator": "^3.0.1",
"ip": "^1.1.5",
"netmask": "^2.0.1"
}
},
"prelude-ls": {
"version": "1.1.2",
"resolved": "https://registry.npmjs.org/prelude-ls/-/prelude-ls-1.1.2.tgz",
"integrity": "sha1-IZMqVJ9eUv/ZqCf1cOBL5iqX2lQ="
},
"proxy-agent": {
"version": "5.0.0",
"resolved": "https://registry.npmjs.org/proxy-agent/-/proxy-agent-5.0.0.tgz",
"integrity": "sha512-gkH7BkvLVkSfX9Dk27W6TyNOWWZWRilRfk1XxGNWOYJ2TuedAv1yFpCaU9QSBmBe716XOTNpYNOzhysyw8xn7g==",
"requires": {
"agent-base": "^6.0.0",
"debug": "4",
"http-proxy-agent": "^4.0.0",
"https-proxy-agent": "^5.0.0",
"lru-cache": "^5.1.1",
"pac-proxy-agent": "^5.0.0",
"proxy-from-env": "^1.0.0",
"socks-proxy-agent": "^5.0.0"
},
"dependencies": {
"socks-proxy-agent": {
"version": "5.0.1",
"resolved": "https://registry.npmjs.org/socks-proxy-agent/-/socks-proxy-agent-5.0.1.tgz",
"integrity": "sha512-vZdmnjb9a2Tz6WEQVIurybSwElwPxMZaIc7PzqbJTrezcKNznv6giT7J7tZDZ1BojVaa1jvO/UiUdhDVB0ACoQ==",
"requires": {
"agent-base": "^6.0.2",
"debug": "4",
"socks": "^2.3.3"
}
}
}
},
"proxy-from-env": {
"version": "1.1.0",
"resolved": "https://registry.npmjs.org/proxy-from-env/-/proxy-from-env-1.1.0.tgz",
"integrity": "sha512-D+zkORCbA9f1tdWRK0RaCR3GPv50cMxcrz4X8k5LTSUD1Dkw47mKJEZQNunItRTkWwgtaUSo1RVFRIG9ZXiFYg=="
},
"raw-body": {
"version": "2.4.1",
"resolved": "https://registry.npmjs.org/raw-body/-/raw-body-2.4.1.tgz",
"integrity": "sha512-9WmIKF6mkvA0SLmA2Knm9+qj89e+j1zqgyn8aXGd7+nAduPoqgI9lO57SAZNn/Byzo5P7JhXTyg9PzaJbH73bA==",
"requires": {
"bytes": "3.1.0",
"http-errors": "1.7.3",
"iconv-lite": "0.4.24",
"unpipe": "1.0.0"
}
},
"readable-stream": {
"version": "1.1.14",
"resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-1.1.14.tgz",
"integrity": "sha1-fPTFTvZI44EwhMY23SB54WbAgdk=",
"requires": {
"core-util-is": "~1.0.0",
"inherits": "~2.0.1",
"isarray": "0.0.1",
"string_decoder": "~0.10.x"
}
},
"safer-buffer": {
"version": "2.1.2",
"resolved": "https://registry.npmjs.org/safer-buffer/-/safer-buffer-2.1.2.tgz",
"integrity": "sha512-YZo3K82SD7Riyi0E1EQPojLz7kpepnSQI9IyPbHHg1XXXevb5dJI7tpyN2ADxGcQbHG7vcyRHk0cbwqcQriUtg=="
},
"setprototypeof": {
"version": "1.1.1",
"resolved": "https://registry.npmjs.org/setprototypeof/-/setprototypeof-1.1.1.tgz",
"integrity": "sha512-JvdAWfbXeIGaZ9cILp38HntZSFSo3mWg6xGcJJsd+d4aRMOqauag1C63dJfDw7OaMYwEbHMOxEZ1lqVRYP2OAw=="
},
"smart-buffer": {
"version": "4.1.0",
"resolved": "https://registry.npmjs.org/smart-buffer/-/smart-buffer-4.1.0.tgz",
"integrity": "sha512-iVICrxOzCynf/SNaBQCw34eM9jROU/s5rzIhpOvzhzuYHfJR/DhZfDkXiZSgKXfgv26HT3Yni3AV/DGw0cGnnw=="
},
"socks": {
"version": "2.6.1",
"resolved": "https://registry.npmjs.org/socks/-/socks-2.6.1.tgz",
"integrity": "sha512-kLQ9N5ucj8uIcxrDwjm0Jsqk06xdpBjGNQtpXy4Q8/QY2k+fY7nZH8CARy+hkbG+SGAovmzzuauCpBlb8FrnBA==",
"requires": {
"ip": "^1.1.5",
"smart-buffer": "^4.1.0"
}
},
"source-map": {
"version": "0.6.1",
"resolved": "https://registry.npmjs.org/source-map/-/source-map-0.6.1.tgz",
"integrity": "sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g==",
"optional": true
},
"statuses": {
"version": "1.5.0",
"resolved": "https://registry.npmjs.org/statuses/-/statuses-1.5.0.tgz",
"integrity": "sha1-Fhx9rBd2Wf2YEfQ3cfqZOBR4Yow="
},
"strftime": {
"version": "0.10.0",
"resolved": "https://registry.npmjs.org/strftime/-/strftime-0.10.0.tgz",
"integrity": "sha1-s/D6QZKVICpaKJ9ta+n0kJphcZM="
},
"string_decoder": {
"version": "0.10.31",
"resolved": "https://registry.npmjs.org/string_decoder/-/string_decoder-0.10.31.tgz",
"integrity": "sha1-YuIDvEF2bGwoyfyEMB2rHFMQ+pQ="
},
"toidentifier": {
"version": "1.0.0",
"resolved": "https://registry.npmjs.org/toidentifier/-/toidentifier-1.0.0.tgz",
"integrity": "sha512-yaOH/Pk/VEhBWWTlhI+qXxDFXlejDGcQipMlyxda9nthulaxLZUNcUqFxokp0vcYnvteJln5FNQDRrxj3YcbVw=="
},
"tslib": {
"version": "2.3.0",
"resolved": "https://registry.npmjs.org/tslib/-/tslib-2.3.0.tgz",
"integrity": "sha512-N82ooyxVNm6h1riLCoyS9e3fuJ3AMG2zIZs2Gd1ATcSFjSA23Q0fzjjZeh0jbJvWVDZ0cJT8yaNNaaXHzueNjg=="
},
"type-check": {
"version": "0.3.2",
"resolved": "https://registry.npmjs.org/type-check/-/type-check-0.3.2.tgz",
"integrity": "sha1-WITKtRLPHTVeP7eE8wgEsrUg23I=",
"requires": {
"prelude-ls": "~1.1.2"
}
},
"universalify": {
"version": "0.1.2",
"resolved": "https://registry.npmjs.org/universalify/-/universalify-0.1.2.tgz",
"integrity": "sha512-rBJeI5CXAlmy1pV+617WB9J63U6XcazHHF2f2dbJix4XzpUF0RS3Zbj0FGIOCAva5P/d/GBOYaACQ1w+0azUkg=="
},
"unpipe": {
"version": "1.0.0",
"resolved": "https://registry.npmjs.org/unpipe/-/unpipe-1.0.0.tgz",
"integrity": "sha1-sr9O6FFKrmFltIF4KdIbLvSZBOw="
},
"vm2": {
"version": "3.9.3",
"resolved": "https://registry.npmjs.org/vm2/-/vm2-3.9.3.tgz",
"integrity": "sha512-smLS+18RjXYMl9joyJxMNI9l4w7biW8ilSDaVRvFBDwOH8P0BK1ognFQTpg0wyQ6wIKLTblHJvROW692L/E53Q=="
},
"word-wrap": {
"version": "1.2.3",
"resolved": "https://registry.npmjs.org/word-wrap/-/word-wrap-1.2.3.tgz",
"integrity": "sha512-Hz/mrNwitNRh/HUAtM/VT/5VH+ygD6DV7mYKZAtHOrbs8U7lvPS6xf7EJKMF0uW1KJCl0H701g3ZGus+muE5vQ=="
},
"xregexp": {
"version": "2.0.0",
"resolved": "https://registry.npmjs.org/xregexp/-/xregexp-2.0.0.tgz",
"integrity": "sha1-UqY+VsoLhKfzpfPWGHLxJq16WUM="
},
"yallist": {
"version": "3.1.1",
"resolved": "https://registry.npmjs.org/yallist/-/yallist-3.1.1.tgz",
"integrity": "sha512-a4UGQaWPH59mOXUYnAG2ewncQS4i4F43Tv3JoAM+s2VDAmS9NsK8GpDMLrCHPksFT7h3K6TOoUNn2pb7RoXx4g=="
}
}
}

View File

@@ -1,6 +1,6 @@
{
"name": "zefie_wtvp_minisrv",
"version": "0.9.0",
"version": "0.9.1",
"description": "WebTV Service (WTVP) Emulation Server",
"main": "app.js",
"homepage": "https://github.com/zefie/zefie_wtvp_minisrv",
@@ -26,6 +26,7 @@
"easy-crc": "0.0.2",
"endianness": "^8.0.2",
"mime-types": "^2.1.31",
"proxy-agent": "^5.0.0",
"strftime": "^0.10.0"
}
}