Compare commits

...

2 commits

10 changed files with 951 additions and 674 deletions

View file

@ -133,7 +133,7 @@ esbuild.build({
esbuildCopyPlugin.copy({
resolveFrom: __dirname,
assets: {
from: ["./utilities/**/*"],
from: ["./utils/**/*"],
to: ["./dist"],
}
}),

View file

@ -5,7 +5,7 @@
"scripts": {
"build": "node esbuild.config.js",
"dev": "npm run build && npm run start",
"lint": "eslint --no-error-on-unmatched-pattern src/**/*.js src/*.js tests/**/*.test.js tests/**/*.js",
"lint": "eslint --no-error-on-unmatched-pattern src/**/*.js src/*.js tests/**/*.test.js tests/**/*.js utils/**/*.js",
"lint:fix": "npm run lint -- --fix",
"start": "node dist/svr.js",
"test": "jest"

View file

@ -1,52 +0,0 @@
//SVR.JS LOG HIGHLIGHTER
var readline = require("readline");
var process = require("process");
var args = process.argv;
for (var i = (process.argv[0].indexOf("node") > -1 || process.argv[0].indexOf("bun") > -1 ? 2 : 1); i < args.length; i++) {
if (args[i] == "-h" || args[i] == "--help" || args[i] == "-?" || args[i] == "/h" || args[i] == "/?") {
console.log("SVR.JS log highlighter usage:");
console.log("<some process> | node loghighlight.js [-h] [--help] [-?] [/h] [/?]");
console.log("-h -? /h /? --help -- Displays help");
process.exit(0);
} else {
console.log("Unrecognized argument: " + args[i]);
console.log("SVR.JS log highlighter usage:");
console.log("<some process> | node loghighlight.js [-h] [--help] [-?] [/h] [/?]");
console.log("-h -? /h /? --help -- Displays help");
process.exit(1);
}
}
var rl = readline.createInterface({
input: process.stdin,
output: process.stdout,
terminal: false,
prompt: ''
});
rl.prompt();
rl.on('line', (line) => {
viewLog([line]);
});
function viewLog(log) {
if(log[log.length-1] == "") log.pop();
if(log[0] == "") log.shift();
for(var i=0;i<log.length;i++) {
if(log[i].indexOf("SERVER REQUEST MESSAGE") != -1) {
log[i] = log[i].replace("SERVER REQUEST MESSAGE","\x1b[34m\x1b[1mSERVER REQUEST MESSAGE\x1b[22m") + "\x1b[37m\x1b[0m";
} else if(log[i].indexOf("SERVER RESPONSE MESSAGE") != -1) {
log[i] = log[i].replace("SERVER RESPONSE MESSAGE","\x1b[32m\x1b[1mSERVER RESPONSE MESSAGE\x1b[22m") + "\x1b[37m\x1b[0m";
} else if(log[i].indexOf("SERVER RESPONSE ERROR MESSAGE") != -1) {
log[i] = log[i].replace("SERVER RESPONSE ERROR MESSAGE","\x1b[31m\x1b[1mSERVER RESPONSE ERROR MESSAGE\x1b[22m") + "\x1b[37m\x1b[0m";
} else if(log[i].indexOf("SERVER ERROR MESSAGE") != -1) {
log[i] = log[i].replace("SERVER ERROR MESSAGE","\x1b[41m\x1b[1mSERVER ERROR MESSAGE\x1b[22m") + "\x1b[40m\x1b[0m";
} else if(log[i].indexOf("SERVER WARNING MESSAGE") != -1) {
log[i] = log[i].replace("SERVER WARNING MESSAGE","\x1b[43m\x1b[1mSERVER WARNING MESSAGE\x1b[22m") + "\x1b[40m\x1b[0m";
} else if(log[i].indexOf("SERVER MESSAGE") != -1) {
log[i] = log[i].replace("SERVER MESSAGE","\x1b[1mSERVER MESSAGE\x1b[22m");
}
console.log(log[i]);
}
}

File diff suppressed because one or more lines are too long

View file

@ -1 +0,0 @@
require("./svr.js");

View file

@ -1,442 +0,0 @@
//SVR.JS USER TOOL
var readline = require("readline");
var process = require("process");
var fs = require("fs");
try {
var crypto = require('crypto');
} catch (ex) {
var crypto = {};
crypto.__disabled__ = null;
crypto.createHash = function (type) {
if (type != "SHA256") throw new Error("Hash type not supported!");
return {
msg: "",
update: function (a) {
this.msg = a;
return this;
},
digest: function (ty) {
var chrsz = 8;
var hexcase = 0;
function safe_add(x, y) {
var lsw = (x & 0xFFFF) + (y & 0xFFFF);
var msw = (x >> 16) + (y >> 16) + (lsw >> 16);
return (msw << 16) | (lsw & 0xFFFF);
}
function S(X, n) {
return (X >>> n) | (X << (32 - n));
}
function R(X, n) {
return (X >>> n);
}
function Ch(x, y, z) {
return ((x & y) ^ ((~x) & z));
}
function Maj(x, y, z) {
return ((x & y) ^ (x & z) ^ (y & z));
}
function Sigma0256(x) {
return (S(x, 2) ^ S(x, 13) ^ S(x, 22));
}
function Sigma1256(x) {
return (S(x, 6) ^ S(x, 11) ^ S(x, 25));
}
function Gamma0256(x) {
return (S(x, 7) ^ S(x, 18) ^ R(x, 3));
}
function Gamma1256(x) {
return (S(x, 17) ^ S(x, 19) ^ R(x, 10));
}
function core_sha256(m, l) {
var K = new Array(0x428A2F98, 0x71374491, 0xB5C0FBCF, 0xE9B5DBA5, 0x3956C25B, 0x59F111F1, 0x923F82A4, 0xAB1C5ED5, 0xD807AA98, 0x12835B01, 0x243185BE, 0x550C7DC3, 0x72BE5D74, 0x80DEB1FE, 0x9BDC06A7, 0xC19BF174, 0xE49B69C1, 0xEFBE4786, 0xFC19DC6, 0x240CA1CC, 0x2DE92C6F, 0x4A7484AA, 0x5CB0A9DC, 0x76F988DA, 0x983E5152, 0xA831C66D, 0xB00327C8, 0xBF597FC7, 0xC6E00BF3, 0xD5A79147, 0x6CA6351, 0x14292967, 0x27B70A85, 0x2E1B2138, 0x4D2C6DFC, 0x53380D13, 0x650A7354, 0x766A0ABB, 0x81C2C92E, 0x92722C85, 0xA2BFE8A1, 0xA81A664B, 0xC24B8B70, 0xC76C51A3, 0xD192E819, 0xD6990624, 0xF40E3585, 0x106AA070, 0x19A4C116, 0x1E376C08, 0x2748774C, 0x34B0BCB5, 0x391C0CB3, 0x4ED8AA4A, 0x5B9CCA4F, 0x682E6FF3, 0x748F82EE, 0x78A5636F, 0x84C87814, 0x8CC70208, 0x90BEFFFA, 0xA4506CEB, 0xBEF9A3F7, 0xC67178F2);
var HASH = new Array(0x6A09E667, 0xBB67AE85, 0x3C6EF372, 0xA54FF53A, 0x510E527F, 0x9B05688C, 0x1F83D9AB, 0x5BE0CD19);
var W = new Array(64);
var a, b, c, d, e, f, g, h, i, j;
var T1, T2;
m[l >> 5] |= 0x80 << (24 - l % 32);
m[((l + 64 >> 9) << 4) + 15] = l;
for (var i = 0; i < m.length; i += 16) {
a = HASH[0];
b = HASH[1];
c = HASH[2];
d = HASH[3];
e = HASH[4];
f = HASH[5];
g = HASH[6];
h = HASH[7];
for (var j = 0; j < 64; j++) {
if (j < 16) W[j] = m[j + i];
else W[j] = safe_add(safe_add(safe_add(Gamma1256(W[j - 2]), W[j - 7]), Gamma0256(W[j - 15])), W[j - 16]);
T1 = safe_add(safe_add(safe_add(safe_add(h, Sigma1256(e)), Ch(e, f, g)), K[j]), W[j]);
T2 = safe_add(Sigma0256(a), Maj(a, b, c));
h = g;
g = f;
f = e;
e = safe_add(d, T1);
d = c;
c = b;
b = a;
a = safe_add(T1, T2);
}
HASH[0] = safe_add(a, HASH[0]);
HASH[1] = safe_add(b, HASH[1]);
HASH[2] = safe_add(c, HASH[2]);
HASH[3] = safe_add(d, HASH[3]);
HASH[4] = safe_add(e, HASH[4]);
HASH[5] = safe_add(f, HASH[5]);
HASH[6] = safe_add(g, HASH[6]);
HASH[7] = safe_add(h, HASH[7]);
}
return HASH;
}
function str2binb(str) {
var bin = Array();
var mask = (1 << chrsz) - 1;
for (var i = 0; i < str.length * chrsz; i += chrsz) {
bin[i >> 5] |= (str.charCodeAt(i / chrsz) & mask) << (24 - i % 32);
}
return bin;
}
function Utf8Encode(string) {
string = string.replace(/\r\n/g, '\n');
var utftext = '';
for (var n = 0; n < string.length; n++) {
var c = string.charCodeAt(n);
if (c < 128) {
utftext += String.fromCharCode(c);
} else if ((c > 127) && (c < 2048)) {
utftext += String.fromCharCode((c >> 6) | 192);
utftext += String.fromCharCode((c & 63) | 128);
} else {
utftext += String.fromCharCode((c >> 12) | 224);
utftext += String.fromCharCode(((c >> 6) & 63) | 128);
utftext += String.fromCharCode((c & 63) | 128);
}
}
return utftext;
}
function binb2hex(binarray) {
var hex_tab = hexcase ? '0123456789ABCDEF' : '0123456789abcdef';
var str = '';
for (var i = 0; i < binarray.length * 4; i++) {
str += hex_tab.charAt((binarray[i >> 2] >> ((3 - i % 4) * 8 + 4)) & 0xF) +
hex_tab.charAt((binarray[i >> 2] >> ((3 - i % 4) * 8)) & 0xF);
}
return str;
}
s = Utf8Encode(this.msg);
var str = binb2hex(core_sha256(str2binb(s), s.length * chrsz));
if (ty == "hex") return str;
var hx = [];
for (var i = 0; i < str.length; i += 2) {
hx.push(parseInt(str[i] + str[i + 1], 16));
}
return new Buffer(hx);
}
};
}
}
if (!crypto.randomInt) {
crypto.randomInt = function (min, max) {
return Math.round(Math.random() * (max - min)) + min;
}
}
var configJSON = {};
if (fs.existsSync("config.json")) {
var configJSONf = "";
try {
configJSONf = fs.readFileSync("config.json"); //Read JSON File
} catch (ex) {
throw new Error("Cannot read JSON file.");
}
try {
configJSON = JSON.parse(configJSONf); //Parse JSON
} catch (ex) {
throw new Error("JSON Parse error.");
}
}
var users = [];
if (configJSON.users != undefined) users = configJSON.users;
function saveConfig() {
var configJSONobj = {};
if (fs.existsSync("./config.json")) configJSONobj = JSON.parse(fs.readFileSync("./config.json").toString());
configJSONobj.users = users;
var configString = JSON.stringify(configJSONobj, null, 2);
fs.writeFileSync("config.json", configString);
}
var args = process.argv;
var user = "";
var action = "change";
var forcechange = false;
if (process.argv.length <= (process.argv[0].indexOf("node") > -1 || process.argv[0].indexOf("bun") > -1 ? 2 : 1)) args.push("-h");
for (var i = (process.argv[0].indexOf("node") > -1 || process.argv[0].indexOf("bun") > -1 ? 2 : 1); i < args.length; i++) {
if (args[i] == "-h" || args[i] == "--help" || args[i] == "-?" || args[i] == "/h" || args[i] == "/?") {
console.log("SVR.JS user tool usage:");
console.log("node svrpasswd.js [-h] [--help] [-?] [/h] [/?] [-x] [-a|--add|-d|--delete] <username>");
console.log("-h -? /h /? --help -- Displays help");
console.log("-a --add -- Add an user");
console.log("-d --delete -- Deletes an user");
console.log("-x -- Changes hash algorithm");
process.exit(0);
} else if (args[i] == "-a" || args[i] == "--add") {
if (action != "change") {
console.log("Multiple actions specified.");
console.log("node svrpasswd.js [-h] [--help] [-?] [/h] [/?] [-x] [-a|--add|-d|--delete] <username>");
console.log("-h -? /h /? --help -- Displays help");
console.log("-a --add -- Add an user");
console.log("-d --delete -- Deletes an user");
console.log("-x -- Changes hash algorithm");
process.exit(1);
}
action = "add";
} else if (args[i] == "-d" || args[i] == "--delete") {
if (action != "change") {
console.log("Multiple actions specified.");
console.log("node svrpasswd.js [-h] [--help] [-?] [/h] [/?] [-x] [-a|--add|-d|--delete] <username>");
console.log("-h -? /h /? --help -- Displays help");
console.log("-a --add -- Add an user");
console.log("-d --delete -- Deletes an user");
console.log("-x -- Changes hash algorithm");
process.exit(1);
}
action = "delete";
} else if (args[i] == "-x") {
if (forcechange) {
console.log("Multiple -x options specified.");
console.log("node svrpasswd.js [-h] [--help] [-?] [/h] [/?] [-x] [-a|--add|-d|--delete] <username>");
console.log("-h -? /h /? --help -- Displays help");
console.log("-a --add -- Add an user");
console.log("-d --delete -- Deletes an user");
console.log("-x -- Changes hash algorithm");
process.exit(1);
}
forcechange = true;
} else {
if (user != "") {
console.log("Multiple users specified.");
console.log("node svrpasswd.js [-h] [--help] [-?] [/h] [/?] [-x] [-a|--add|-d|--delete] <username>");
console.log("-h -? /h /? --help -- Displays help");
console.log("-a --add -- Add an user");
console.log("-d --delete -- Deletes an user");
console.log("-x -- Changes hash algorithm");
process.exit(1);
}
user = args[i];
}
}
if (user == "") {
console.log("No user specified.");
console.log("node svrpasswd.js [-h] [--help] [-?] [/h] [/?] [-x] [-a|--add|-d|--delete] <username>");
console.log("-h -? /h /? --help -- Displays help");
console.log("-a --add -- Add an user");
console.log("-d --delete -- Deletes an user");
console.log("-x -- Changes hash algorithm");
process.exit(1);
}
function getUserIndex(username) {
var ind = -1
for (var i = 0; i < users.length; i++) {
if (users[i].name == username) {
ind = i;
break;
}
}
return ind;
}
function sha256(msg) {
var hash = crypto.createHash("SHA256");
hash.update(msg);
return hash.digest('hex');
}
function generateSalt() {
var token = "";
var strlist = "0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ";
for (var i = 0; i < 63; i++) {
token += strlist[crypto.randomInt(0, strlist.length)];
}
return token;
}
function password(callback) {
var rl = readline.createInterface({
input: process.stdin,
output: process.stdout,
prompt: 'Password: '
});
rl.prompt();
process.stdout.writeold = process.stdout.write;
process.stdout.write = function (s) {
process.stdout.writeold(s.replace(/[^\r\n]/g, ""));
};
rl.once('line', function (line) {
process.stdout.write = process.stdout.writeold;
var rl = readline.createInterface({
input: process.stdin,
output: process.stdout,
prompt: 'Confirm password: ',
});
rl.prompt();
process.stdout.writeold = process.stdout.write;
process.stdout.write = function (s) {
process.stdout.writeold(s.replace(/[^\r\n]/g, ""));
};
rl.on('line', function (line2) {
process.stdout.write = process.stdout.writeold;
rl.close();
if (line != line2) callback(false);
else callback(line);
});
});
}
function promptAlgorithms(callback, bypass, pbkdf2, scrypt) {
if (bypass) {
if (scrypt) {
callback("scrypt");
} else if(pbkdf2) {
callback("pbkdf2");
} else {
callback("sha256");
}
return;
}
var algorithms = {
sha256: "Salted SHA256 (1 iteration) - fastest and uses least memory, but less secure",
pbkdf2: "PBKDF2 (PBKDF2-HMAC-SHA512, 36250 iterations) - more secure and uses less memory, but slower",
scrypt: "scrypt (N=2^14, r=8, p=1) - faster and more secure, but uses more memory"
}
if (!crypto.pbkdf2 || (process.isBun && !(process.versions.bun && !process.versions.bun.match(/^(?:0\.|1\.0\.|1\.1\.[0-9](?![0-9])|1\.1\.1[0-2](?![0-9]))/)))) delete algorithms.pbkdf2;
var algorithmNames = Object.keys(algorithms);
if (algorithmNames.length < 2) callback(algorithmNames[0]);
console.log("Select password hashing algorithm. Available algorithms:");
for (var i = 0; i < algorithmNames.length; i++) {
console.log(algorithmNames[i] + " - " + algorithms[algorithmNames[i]]);
}
var rl = readline.createInterface({
input: process.stdin,
output: process.stdout,
prompt: 'Algorithm: '
});
rl.prompt();
rl.on('line', function (line) {
rl.close();
line = line.trim();
if (!algorithms[line]) callback(false);
else callback(line);
});
}
var userindex = getUserIndex(user);
if (action == "add" && userindex != -1) {
console.log("User alerady exists.");
process.exit(1);
} else if (action != "add" && userindex == -1) {
console.log("User doesn't exist.");
process.exit(1);
}
if (action == "delete") {
users.splice(userindex, 1);
saveConfig();
console.log("User deleted successfully");
} else if (action == "add") {
promptAlgorithms(function (algorithm) {
if (!algorithm) {
console.log("Invalid algorithm!");
process.exit(1);
} else {
password(function (password) {
if (!password) {
console.log("Passwords don't match!");
process.exit(1);
} else {
var salt = generateSalt();
var hash = "";
if (algorithm == "scrypt") {
hash = crypto.scryptSync(password, salt, 64).toString("hex");
} else if (algorithm == "pbkdf2") {
hash = crypto.pbkdf2Sync(password, salt, 36250, 64, "sha512").toString("hex");
} else {
hash = sha256(password + salt);
}
users.push({
name: user,
pass: hash,
salt: salt,
pbkdf2: (algorithm == "pbkdf2" ? true : undefined),
scrypt: (algorithm == "scrypt" ? true : undefined),
__svrpasswd_l2: true
});
saveConfig();
console.log("User added successfully");
}
});
}
});
} else {
promptAlgorithms(function (algorithm) {
if (!algorithm) {
console.log("Invalid algorithm!");
process.exit(1);
} else {
password(function (password) {
if (!password) {
console.log("Passwords don't match!");
process.exit(1);
} else {
var salt = generateSalt();
var hash = "";
if (algorithm == "scrypt") {
hash = crypto.scryptSync(password, salt, 64).toString("hex");
} else if (algorithm == "pbkdf2") {
hash = crypto.pbkdf2Sync(password, salt, 36250, 64, "sha512").toString("hex");
} else {
hash = sha256(password + salt);
}
users[userindex] = {
name: user,
pass: hash,
salt: salt,
pbkdf2: (algorithm == "pbkdf2" ? true : undefined),
scrypt: (algorithm == "scrypt" ? true : undefined),
__svrpasswd_l2: true
};
saveConfig();
console.log("Password changed successfully");
}
});
}
}, (users[userindex].__svrpasswd_l2 && !forcechange), users[userindex].pbkdf2, users[userindex].scrypt);
}

91
utils/loghighlight.js Normal file
View file

@ -0,0 +1,91 @@
//SVR.JS LOG HIGHLIGHTER
const readline = require("readline");
const args = process.argv;
for (
let i =
process.argv[0].indexOf("node") > -1 || process.argv[0].indexOf("bun") > -1
? 2
: 1;
i < args.length;
i++
) {
if (
args[i] == "-h" ||
args[i] == "--help" ||
args[i] == "-?" ||
args[i] == "/h" ||
args[i] == "/?"
) {
console.log("SVR.JS log highlighter usage:");
console.log(
"<some process> | node loghighlight.js [-h] [--help] [-?] [/h] [/?]",
);
console.log("-h -? /h /? --help -- Displays help");
process.exit(0);
} else {
console.log("Unrecognized argument: " + args[i]);
console.log("SVR.JS log highlighter usage:");
console.log(
"<some process> | node loghighlight.js [-h] [--help] [-?] [/h] [/?]",
);
console.log("-h -? /h /? --help -- Displays help");
process.exit(1);
}
}
const rl = readline.createInterface({
input: process.stdin,
output: process.stdout,
terminal: false,
prompt: "",
});
rl.prompt();
rl.on("line", (line) => {
viewLog([line]);
});
function viewLog(log) {
if (log[log.length - 1] == "") log.pop();
if (log[0] == "") log.shift();
for (var i = 0; i < log.length; i++) {
if (log[i].indexOf("SERVER REQUEST MESSAGE") != -1) {
log[i] =
log[i].replace(
"SERVER REQUEST MESSAGE",
"\x1b[34m\x1b[1mSERVER REQUEST MESSAGE\x1b[22m",
) + "\x1b[37m\x1b[0m";
} else if (log[i].indexOf("SERVER RESPONSE MESSAGE") != -1) {
log[i] =
log[i].replace(
"SERVER RESPONSE MESSAGE",
"\x1b[32m\x1b[1mSERVER RESPONSE MESSAGE\x1b[22m",
) + "\x1b[37m\x1b[0m";
} else if (log[i].indexOf("SERVER RESPONSE ERROR MESSAGE") != -1) {
log[i] =
log[i].replace(
"SERVER RESPONSE ERROR MESSAGE",
"\x1b[31m\x1b[1mSERVER RESPONSE ERROR MESSAGE\x1b[22m",
) + "\x1b[37m\x1b[0m";
} else if (log[i].indexOf("SERVER ERROR MESSAGE") != -1) {
log[i] =
log[i].replace(
"SERVER ERROR MESSAGE",
"\x1b[41m\x1b[1mSERVER ERROR MESSAGE\x1b[22m",
) + "\x1b[40m\x1b[0m";
} else if (log[i].indexOf("SERVER WARNING MESSAGE") != -1) {
log[i] =
log[i].replace(
"SERVER WARNING MESSAGE",
"\x1b[43m\x1b[1mSERVER WARNING MESSAGE\x1b[22m",
) + "\x1b[40m\x1b[0m";
} else if (log[i].indexOf("SERVER MESSAGE") != -1) {
log[i] = log[i].replace(
"SERVER MESSAGE",
"\x1b[1mSERVER MESSAGE\x1b[22m",
);
}
console.log(log[i]);
}
}

273
utils/logviewer.js Normal file
View file

@ -0,0 +1,273 @@
//SVR.JS LOG VIEWER
const fs = require("fs");
const readline = require("readline");
const args = process.argv;
for (
let i =
process.argv[0].indexOf("node") > -1 || process.argv[0].indexOf("bun") > -1
? 2
: 1;
i < args.length;
i++
) {
if (
args[i] == "-h" ||
args[i] == "--help" ||
args[i] == "-?" ||
args[i] == "/h" ||
args[i] == "/?"
) {
console.log("SVR.JS log viewer usage:");
console.log("node logviewer.js [-h] [--help] [-?] [/h] [/?]");
console.log("-h -? /h /? --help -- Displays help");
process.exit(0);
} else {
console.log("Unrecognized argument: " + args[i]);
console.log("SVR.JS log viewer usage:");
console.log("node logviewer.js [-h] [--help] [-?] [/h] [/?]");
console.log("-h -? /h /? --help -- Displays help");
process.exit(1);
}
}
const logo = [
"",
"",
"",
" \x1b[38;5;002m&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&",
" &&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&",
" &&&\x1b[38;5;243m(((((((((((((((((((((((((((((((((((((((((((((((((((\x1b[38;5;002m&&&",
" \x1b[38;5;002m&&\x1b[38;5;243m((((((\x1b[38;5;241m###########\x1b[38;5;243m(((((((((((((((((((((((\x1b[38;5;011m***\x1b[38;5;243m(\x1b[38;5;011m***\x1b[38;5;243m(\x1b[38;5;011m***\x1b[38;5;243m((\x1b[38;5;002m&&",
" \x1b[38;5;002m&&&\x1b[38;5;243m(((((((((((((((((((((((((((((((((((((((((((((((((((\x1b[38;5;002m&&&",
" \x1b[38;5;002m&&&\x1b[38;5;243m(((((((((((((((((((((((((((((((((((((((((((((((((((\x1b[38;5;002m&&&",
" \x1b[38;5;002m&&\x1b[38;5;243m((((((\x1b[38;5;241m###########\x1b[38;5;243m(((((((((((((((((((((((\x1b[38;5;011m***\x1b[38;5;243m(\x1b[38;5;015m \x1b[38;5;243m(\x1b[38;5;011m***\x1b[38;5;243m((\x1b[38;5;002m&&",
" \x1b[38;5;002m&&&\x1b[38;5;243m(((((((((((((((((((((((((((((((((((((((((((((((((((\x1b[38;5;002m&&&",
" \x1b[38;5;002m&&&\x1b[38;5;243m(((((((((((((((((((((((((((((((((((((((((((((((((((\x1b[38;5;002m&&&",
" \x1b[38;5;002m&&\x1b[38;5;243m((((((\x1b[38;5;241m###########\x1b[38;5;243m(((((((((((((((((((((((\x1b[38;5;015m \x1b[38;5;243m(\x1b[38;5;015m \x1b[38;5;243m(\x1b[38;5;015m \x1b[38;5;243m((\x1b[38;5;002m&&",
" \x1b[38;5;002m&&&\x1b[38;5;243m(((((((((((((((((((((((((((((((((((((((((((((((((((\x1b[38;5;002m&&&",
" \x1b[38;5;002m&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&",
" \x1b[38;5;002m&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&",
" \x1b[38;5;002m&&&&&&&&\x1b[38;5;010m#########################################\x1b[38;5;002m&&&&&&&&",
" \x1b[38;5;002m&&&&&\x1b[38;5;010m###############################################\x1b[38;5;002m&&&&&",
" \x1b[38;5;002m&&&\x1b[38;5;010m###################################################\x1b[38;5;002m&&&",
" \x1b[38;5;002m&&\x1b[38;5;010m####\x1b[38;5;016m@@@@@@\x1b[38;5;010m#\x1b[38;5;016m@@@\x1b[38;5;010m###\x1b[38;5;016m@@@\x1b[38;5;010m#\x1b[38;5;016m@@@@@@@\x1b[38;5;010m###########\x1b[38;5;016m@@\x1b[38;5;010m##\x1b[38;5;016m@@@@@@\x1b[38;5;010m####\x1b[38;5;002m&&",
" \x1b[38;5;002m&&\x1b[38;5;010m###\x1b[38;5;016m@@\x1b[38;5;010m#######\x1b[38;5;016m@@\x1b[38;5;010m###\x1b[38;5;016m@@\x1b[38;5;010m##\x1b[38;5;016m@@\x1b[38;5;010m####\x1b[38;5;016m@@\x1b[38;5;010m##########\x1b[38;5;016m@@\x1b[38;5;010m#\x1b[38;5;016m@@\x1b[38;5;010m#########\x1b[38;5;002m&&",
" \x1b[38;5;002m&&\x1b[38;5;010m######\x1b[38;5;040m#\x1b[38;5;016m@@@@\x1b[38;5;010m##\x1b[38;5;016m@@\x1b[38;5;010m#\x1b[38;5;016m@@\x1b[38;5;010m###\x1b[38;5;016m@@@@@@@\x1b[38;5;010m#######\x1b[38;5;016m@@\x1b[38;5;010m##\x1b[38;5;016m@@\x1b[38;5;010m####\x1b[38;5;040m#\x1b[38;5;016m@@@@\x1b[38;5;010m###\x1b[38;5;002m&&",
" \x1b[38;5;002m&&\x1b[38;5;010m###\x1b[38;5;016m@@\x1b[38;5;034m%\x1b[38;5;010m###\x1b[38;5;016m@@\x1b[38;5;010m###\x1b[38;5;016m@@@\x1b[38;5;010m####\x1b[38;5;016m@@\x1b[38;5;010m####\x1b[38;5;016m@@\x1b[38;5;010m##\x1b[38;5;016m@@\x1b[38;5;010m###\x1b[38;5;016m@@@@\x1b[38;5;010m##\x1b[38;5;016m@@\x1b[38;5;034m%\x1b[38;5;010m###\x1b[38;5;016m@@\x1b[38;5;010m###\x1b[38;5;002m&&",
" \x1b[38;5;002m&&\x1b[38;5;010m#####################################################\x1b[38;5;002m&&",
" \x1b[38;5;002m&&&\x1b[38;5;010m###################################################\x1b[38;5;002m&&&",
" \x1b[38;5;002m&&&&&\x1b[38;5;010m###############################################\x1b[38;5;002m&&&&&",
" \x1b[38;5;002m&&&&&&&&\x1b[38;5;010m#########################################\x1b[38;5;002m&&&&&&&&",
" \x1b[38;5;002m&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&",
" &&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&",
" &&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&",
" \x1b[38;5;246m///////",
" ///////",
" \x1b[38;5;208m((((/))))",
" \x1b[38;5;208m(((((/)))))",
" \x1b[38;5;246m/\x1b[38;5;247m*\x1b[38;5;246m///\x1b[38;5;247m*\x1b[38;5;246m///\x1b[38;5;247m*\x1b[38;5;246m///\x1b[38;5;247m*\x1b[38;5;246m///\x1b[38;5;247m*\x1b[38;5;246m/\x1b[38;5;247m/\x1b[38;5;208m(((((/)))))\x1b[38;5;246m//\x1b[38;5;247m*\x1b[38;5;246m///\x1b[38;5;247m*\x1b[38;5;246m///\x1b[38;5;247m*\x1b[38;5;246m///\x1b[38;5;247m*\x1b[38;5;246m///\x1b[38;5;247m*\x1b[38;5;246m/",
" //\x1b[38;5;247m*\x1b[38;5;246m///////\x1b[38;5;247m*\x1b[38;5;246m///////\x1b[38;5;247m*\x1b[38;5;246m/\x1b[38;5;247m/\x1b[38;5;208m(((((/)))))\x1b[38;5;246m//\x1b[38;5;247m*\x1b[38;5;246m///////\x1b[38;5;247m*\x1b[38;5;246m///////\x1b[38;5;247m*\x1b[38;5;246m//",
" *\x1b[38;5;246m/\x1b[38;5;247m*\x1b[38;5;246m/\x1b[38;5;247m*\x1b[38;5;246m/\x1b[38;5;247m*\x1b[38;5;246m/\x1b[38;5;247m*\x1b[38;5;246m/\x1b[38;5;247m*\x1b[38;5;246m/\x1b[38;5;247m*\x1b[38;5;246m/\x1b[38;5;247m*\x1b[38;5;246m/\x1b[38;5;247m*\x1b[38;5;246m/\x1b[38;5;247m*\x1b[38;5;246m/\x1b[38;5;247m*\x1b[38;5;208m(((((/)))))\x1b[38;5;247m*\x1b[38;5;246m/\x1b[38;5;247m*\x1b[38;5;246m/\x1b[38;5;247m*\x1b[38;5;246m/\x1b[38;5;247m*\x1b[38;5;246m/\x1b[38;5;247m*\x1b[38;5;246m/\x1b[38;5;247m*\x1b[38;5;246m/\x1b[38;5;247m*\x1b[38;5;246m/\x1b[38;5;247m*\x1b[38;5;246m/\x1b[38;5;247m*\x1b[38;5;246m/\x1b[38;5;247m*\x1b[38;5;246m/\x1b[38;5;247m*",
" \x1b[38;5;208m((((/))))",
"",
"",
"",
"\x1b[0m",
];
for (let i = 0; i < logo.length; i++) {
console.log(logo[i]);
}
console.log("Welcome to SVR.JS log viewer");
if (!fs.existsSync(__dirname + "/log")) {
console.log("No log directory, exiting...");
process.exit(1);
}
function prompt(options) {
const rl = readline.createInterface({
input: process.stdin,
output: process.stdout,
prompt: "logviewer> ",
});
console.log("Options:");
for (let i = 0; i < options.length; i++) {
console.log("[" + i + "] - " + options[i].name);
}
rl.prompt();
rl.on("line", (line) => {
const op = line.trim();
if (op == "") {
rl.prompt();
return;
}
rl.close();
if (options[op]) {
options[op].callback();
} else {
console.log("Invalid option.");
prompt(options);
}
});
}
function viewLog(log) {
if (log[log.length - 1] == "") log.pop();
if (log[0] == "") log.shift();
for (let i = 0; i < log.length; i++) {
if (log[i].indexOf("SERVER REQUEST MESSAGE") != -1) {
log[i] =
log[i].replace(
"SERVER REQUEST MESSAGE",
"\x1b[34m\x1b[1mSERVER REQUEST MESSAGE\x1b[22m",
) + "\x1b[37m\x1b[0m";
} else if (log[i].indexOf("SERVER RESPONSE MESSAGE") != -1) {
log[i] =
log[i].replace(
"SERVER RESPONSE MESSAGE",
"\x1b[32m\x1b[1mSERVER RESPONSE MESSAGE\x1b[22m",
) + "\x1b[37m\x1b[0m";
} else if (log[i].indexOf("SERVER RESPONSE ERROR MESSAGE") != -1) {
log[i] =
log[i].replace(
"SERVER RESPONSE ERROR MESSAGE",
"\x1b[31m\x1b[1mSERVER RESPONSE ERROR MESSAGE\x1b[22m",
) + "\x1b[37m\x1b[0m";
} else if (log[i].indexOf("SERVER ERROR MESSAGE") != -1) {
log[i] =
log[i].replace(
"SERVER ERROR MESSAGE",
"\x1b[41m\x1b[1mSERVER ERROR MESSAGE\x1b[22m",
) + "\x1b[40m\x1b[0m";
} else if (log[i].indexOf("SERVER WARNING MESSAGE") != -1) {
log[i] =
log[i].replace(
"SERVER WARNING MESSAGE",
"\x1b[43m\x1b[1mSERVER WARNING MESSAGE\x1b[22m",
) + "\x1b[40m\x1b[0m";
} else if (log[i].indexOf("SERVER MESSAGE") != -1) {
log[i] = log[i].replace(
"SERVER MESSAGE",
"\x1b[1mSERVER MESSAGE\x1b[22m",
);
}
console.log(log[i]);
}
}
function viewMasterLogs() {
const logList = fs.readdirSync(__dirname + "/log");
let masterLogs = [];
for (var i = 0; i < logList.length; i++) {
if (logList[i].match(/^master-[0-9]+\.log$/)) {
masterLogs.push(logList[i]);
}
}
if (masterLogs.length == 0) {
console.log("No master log.");
return;
}
const latestLogFileName = masterLogs.sort().reverse()[0];
viewLog(
fs
.readFileSync(__dirname + "/log/" + latestLogFileName)
.toString()
.split("\n"),
);
prompt(mainOptions);
}
function viewWorkerLogs() {
const logList = fs.readdirSync("log");
let masterLogs = [];
for (var i = 0; i < logList.length; i++) {
if (logList[i].match(/^worker-[0-9]+\.log$/)) {
masterLogs.push(logList[i]);
}
}
if (masterLogs.length == 0) {
console.log("No worker logs.");
return;
}
const latestLogFileNames = masterLogs.sort().reverse().slice(0, 5).reverse();
let log = [];
for (let i = 0; i < latestLogFileNames.length; i++) {
let rlog = fs
.readFileSync("log/" + latestLogFileNames[i])
.toString()
.split("\n");
if (rlog[rlog.length - 1] == "") rlog.pop();
if (rlog[0] == "") rlog.shift();
for (let j = 0; j < rlog.length; j++) {
log.push(rlog[j]);
}
}
log = log.sort();
viewLog(log);
prompt(mainOptions);
}
function viewFilteredWorkerLogs(filter) {
const logList = fs.readdirSync("log");
let masterLogs = [];
for (var i = 0; i < logList.length; i++) {
if (logList[i].match(/^worker-[0-9]+\.log$/)) {
masterLogs.push(logList[i]);
}
}
if (masterLogs.length == 0) {
console.log("No worker logs.");
return;
}
const latestLogFileNames = masterLogs.sort().reverse().slice(0, 20).reverse();
let log = [];
for (let i = 0; i < latestLogFileNames.length; i++) {
let rlog = fs
.readFileSync("log/" + latestLogFileNames[i])
.toString()
.split("\n");
if (rlog[rlog.length - 1] == "") rlog.pop();
if (rlog[0] == "") rlog.shift();
for (let j = 0; j < rlog.length; j++) {
if (rlog[j].indexOf(filter) != -1) log.push(rlog[j]);
}
}
log = log.sort();
viewLog(log);
prompt(mainOptions);
}
function viewFilteredWorkerLogsPrompt() {
var rl2 = readline.createInterface({
input: process.stdin,
output: process.stdout,
prompt: "filter> ",
});
console.log("Input filter:");
rl2.prompt();
rl2.on("line", (line) => {
rl2.close();
viewFilteredWorkerLogs(line);
});
}
var mainOptions = [
{ name: "View latest master log", callback: viewMasterLogs },
{ name: "View 5 latest worker logs", callback: viewWorkerLogs },
{
name: "View filtered worker logs (latest 20 logs)",
callback: viewFilteredWorkerLogsPrompt,
},
{
name: "Exit log viewer",
callback: () => {
console.log("Bye!");
process.exit(0);
},
},
];
prompt(mainOptions);

1
utils/svr_new.js Normal file
View file

@ -0,0 +1 @@
require("./svr.js");

584
utils/svrpasswd.js Normal file
View file

@ -0,0 +1,584 @@
//SVR.JS USER TOOL
const readline = require("readline");
const fs = require("fs");
let crypto = {};
try {
crypto = require("crypto");
} catch (ex) {
crypto = {};
crypto.__disabled__ = null;
crypto.createHash = (type) => {
if (type != "SHA256") throw new Error("Hash type not supported!");
return {
msg: "",
update: (a) => {
this.msg = a;
return this;
},
digest: (ty) => {
const chrsz = 8;
const hexcase = 0;
const safeAdd = (x, y) => {
const lsw = (x & 0xffff) + (y & 0xffff);
const msw = (x >> 16) + (y >> 16) + (lsw >> 16);
return (msw << 16) | (lsw & 0xffff);
};
const S = (X, n) => {
return (X >>> n) | (X << (32 - n));
};
const R = (X, n) => {
return X >>> n;
};
const Ch = (x, y, z) => {
return (x & y) ^ (~x & z);
};
const Maj = (x, y, z) => {
return (x & y) ^ (x & z) ^ (y & z);
};
const Sigma0256 = (x) => {
return S(x, 2) ^ S(x, 13) ^ S(x, 22);
};
const Sigma1256 = (x) => {
return S(x, 6) ^ S(x, 11) ^ S(x, 25);
};
const Gamma0256 = (x) => {
return S(x, 7) ^ S(x, 18) ^ R(x, 3);
};
const Gamma1256 = (x) => {
return S(x, 17) ^ S(x, 19) ^ R(x, 10);
};
function coreSha256(m, l) {
const K = new Array(
0x428a2f98,
0x71374491,
0xb5c0fbcf,
0xe9b5dba5,
0x3956c25b,
0x59f111f1,
0x923f82a4,
0xab1c5ed5,
0xd807aa98,
0x12835b01,
0x243185be,
0x550c7dc3,
0x72be5d74,
0x80deb1fe,
0x9bdc06a7,
0xc19bf174,
0xe49b69c1,
0xefbe4786,
0xfc19dc6,
0x240ca1cc,
0x2de92c6f,
0x4a7484aa,
0x5cb0a9dc,
0x76f988da,
0x983e5152,
0xa831c66d,
0xb00327c8,
0xbf597fc7,
0xc6e00bf3,
0xd5a79147,
0x6ca6351,
0x14292967,
0x27b70a85,
0x2e1b2138,
0x4d2c6dfc,
0x53380d13,
0x650a7354,
0x766a0abb,
0x81c2c92e,
0x92722c85,
0xa2bfe8a1,
0xa81a664b,
0xc24b8b70,
0xc76c51a3,
0xd192e819,
0xd6990624,
0xf40e3585,
0x106aa070,
0x19a4c116,
0x1e376c08,
0x2748774c,
0x34b0bcb5,
0x391c0cb3,
0x4ed8aa4a,
0x5b9cca4f,
0x682e6ff3,
0x748f82ee,
0x78a5636f,
0x84c87814,
0x8cc70208,
0x90befffa,
0xa4506ceb,
0xbef9a3f7,
0xc67178f2,
);
let HASH = new Array(
0x6a09e667,
0xbb67ae85,
0x3c6ef372,
0xa54ff53a,
0x510e527f,
0x9b05688c,
0x1f83d9ab,
0x5be0cd19,
);
let W = new Array(64);
let a, b, c, d, e, f, g, h;
let T1, T2;
m[l >> 5] |= 0x80 << (24 - (l % 32));
m[(((l + 64) >> 9) << 4) + 15] = l;
for (let i = 0; i < m.length; i += 16) {
a = HASH[0];
b = HASH[1];
c = HASH[2];
d = HASH[3];
e = HASH[4];
f = HASH[5];
g = HASH[6];
h = HASH[7];
for (let j = 0; j < 64; j++) {
if (j < 16) W[j] = m[j + i];
else
W[j] = safeAdd(
safeAdd(
safeAdd(Gamma1256(W[j - 2]), W[j - 7]),
Gamma0256(W[j - 15]),
),
W[j - 16],
);
T1 = safeAdd(
safeAdd(safeAdd(safeAdd(h, Sigma1256(e)), Ch(e, f, g)), K[j]),
W[j],
);
T2 = safeAdd(Sigma0256(a), Maj(a, b, c));
h = g;
g = f;
f = e;
e = safeAdd(d, T1);
d = c;
c = b;
b = a;
a = safeAdd(T1, T2);
}
HASH[0] = safeAdd(a, HASH[0]);
HASH[1] = safeAdd(b, HASH[1]);
HASH[2] = safeAdd(c, HASH[2]);
HASH[3] = safeAdd(d, HASH[3]);
HASH[4] = safeAdd(e, HASH[4]);
HASH[5] = safeAdd(f, HASH[5]);
HASH[6] = safeAdd(g, HASH[6]);
HASH[7] = safeAdd(h, HASH[7]);
}
return HASH;
}
const str2binb = (str) => {
let bin = Array();
const mask = (1 << chrsz) - 1;
for (let i = 0; i < str.length * chrsz; i += chrsz) {
bin[i >> 5] |=
(str.charCodeAt(i / chrsz) & mask) << (24 - (i % 32));
}
return bin;
};
const Utf8Encode = (string) => {
string = string.replace(/\r\n/g, "\n");
let utftext = "";
for (let n = 0; n < string.length; n++) {
let c = string.charCodeAt(n);
if (c < 128) {
utftext += String.fromCharCode(c);
} else if (c > 127 && c < 2048) {
utftext += String.fromCharCode((c >> 6) | 192);
utftext += String.fromCharCode((c & 63) | 128);
} else {
utftext += String.fromCharCode((c >> 12) | 224);
utftext += String.fromCharCode(((c >> 6) & 63) | 128);
utftext += String.fromCharCode((c & 63) | 128);
}
}
return utftext;
};
const binb2hex = (binarray) => {
const hexTab = hexcase ? "0123456789ABCDEF" : "0123456789abcdef";
let str = "";
for (let i = 0; i < binarray.length * 4; i++) {
str +=
hexTab.charAt(
(binarray[i >> 2] >> ((3 - (i % 4)) * 8 + 4)) & 0xf,
) +
hexTab.charAt((binarray[i >> 2] >> ((3 - (i % 4)) * 8)) & 0xf);
}
return str;
};
let s = Utf8Encode(this.msg);
let str = binb2hex(coreSha256(str2binb(s), s.length * chrsz));
if (ty == "hex") return str;
let hx = [];
for (var i = 0; i < str.length; i += 2) {
hx.push(parseInt(str[i] + str[i + 1], 16));
}
return Buffer.from(hx);
},
};
};
}
if (!crypto.randomInt) {
crypto.randomInt = (min, max) => {
return Math.round(Math.random() * (max - min)) + min;
};
}
let configJSON = {};
if (fs.existsSync("config.json")) {
let configJSONf = "";
try {
configJSONf = fs.readFileSync("config.json"); //Read JSON File
} catch (ex) {
throw new Error("Cannot read JSON file.");
}
try {
configJSON = JSON.parse(configJSONf); //Parse JSON
} catch (ex) {
throw new Error("JSON Parse error.");
}
}
let users = [];
if (configJSON.users != undefined) users = configJSON.users;
function saveConfig() {
let configJSONobj = {};
if (fs.existsSync("./config.json"))
configJSONobj = JSON.parse(fs.readFileSync("./config.json").toString());
configJSONobj.users = users;
const configString = JSON.stringify(configJSONobj, null, 2);
fs.writeFileSync("config.json", configString);
}
const args = process.argv;
let user = "";
let action = "change";
let forcechange = false;
if (
process.argv.length <=
(process.argv[0].indexOf("node") > -1 || process.argv[0].indexOf("bun") > -1
? 2
: 1)
)
args.push("-h");
for (
let i =
process.argv[0].indexOf("node") > -1 || process.argv[0].indexOf("bun") > -1
? 2
: 1;
i < args.length;
i++
) {
if (
args[i] == "-h" ||
args[i] == "--help" ||
args[i] == "-?" ||
args[i] == "/h" ||
args[i] == "/?"
) {
console.log("SVR.JS user tool usage:");
console.log(
"node svrpasswd.js [-h] [--help] [-?] [/h] [/?] [-x] [-a|--add|-d|--delete] <username>",
);
console.log("-h -? /h /? --help -- Displays help");
console.log("-a --add -- Add an user");
console.log("-d --delete -- Deletes an user");
console.log("-x -- Changes hash algorithm");
process.exit(0);
} else if (args[i] == "-a" || args[i] == "--add") {
if (action != "change") {
console.log("Multiple actions specified.");
console.log(
"node svrpasswd.js [-h] [--help] [-?] [/h] [/?] [-x] [-a|--add|-d|--delete] <username>",
);
console.log("-h -? /h /? --help -- Displays help");
console.log("-a --add -- Add an user");
console.log("-d --delete -- Deletes an user");
console.log("-x -- Changes hash algorithm");
process.exit(1);
}
action = "add";
} else if (args[i] == "-d" || args[i] == "--delete") {
if (action != "change") {
console.log("Multiple actions specified.");
console.log(
"node svrpasswd.js [-h] [--help] [-?] [/h] [/?] [-x] [-a|--add|-d|--delete] <username>",
);
console.log("-h -? /h /? --help -- Displays help");
console.log("-a --add -- Add an user");
console.log("-d --delete -- Deletes an user");
console.log("-x -- Changes hash algorithm");
process.exit(1);
}
action = "delete";
} else if (args[i] == "-x") {
if (forcechange) {
console.log("Multiple -x options specified.");
console.log(
"node svrpasswd.js [-h] [--help] [-?] [/h] [/?] [-x] [-a|--add|-d|--delete] <username>",
);
console.log("-h -? /h /? --help -- Displays help");
console.log("-a --add -- Add an user");
console.log("-d --delete -- Deletes an user");
console.log("-x -- Changes hash algorithm");
process.exit(1);
}
forcechange = true;
} else {
if (user != "") {
console.log("Multiple users specified.");
console.log(
"node svrpasswd.js [-h] [--help] [-?] [/h] [/?] [-x] [-a|--add|-d|--delete] <username>",
);
console.log("-h -? /h /? --help -- Displays help");
console.log("-a --add -- Add an user");
console.log("-d --delete -- Deletes an user");
console.log("-x -- Changes hash algorithm");
process.exit(1);
}
user = args[i];
}
}
if (user == "") {
console.log("No user specified.");
console.log(
"node svrpasswd.js [-h] [--help] [-?] [/h] [/?] [-x] [-a|--add|-d|--delete] <username>",
);
console.log("-h -? /h /? --help -- Displays help");
console.log("-a --add -- Add an user");
console.log("-d --delete -- Deletes an user");
console.log("-x -- Changes hash algorithm");
process.exit(1);
}
function getUserIndex(username) {
let ind = -1;
for (let i = 0; i < users.length; i++) {
if (users[i].name == username) {
ind = i;
break;
}
}
return ind;
}
function sha256(msg) {
let hash = crypto.createHash("SHA256");
hash.update(msg);
return hash.digest("hex");
}
function generateSalt() {
let token = "";
const strlist =
"0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ";
for (let i = 0; i < 63; i++) {
token += strlist[crypto.randomInt(0, strlist.length)];
}
return token;
}
function password(callback) {
const rl = readline.createInterface({
input: process.stdin,
output: process.stdout,
prompt: "Password: ",
});
rl.prompt();
process.stdout.writeold = process.stdout.write;
process.stdout.write = (s) => {
process.stdout.writeold(s.replace(/[^\r\n]/g, ""));
};
rl.once("line", (line) => {
process.stdout.write = process.stdout.writeold;
var rl = readline.createInterface({
input: process.stdin,
output: process.stdout,
prompt: "Confirm password: ",
});
rl.prompt();
process.stdout.writeold = process.stdout.write;
process.stdout.write = (s) => {
process.stdout.writeold(s.replace(/[^\r\n]/g, ""));
};
rl.on("line", (line2) => {
process.stdout.write = process.stdout.writeold;
rl.close();
if (line != line2) callback(false);
else callback(line);
});
});
}
function promptAlgorithms(callback, bypass, pbkdf2, scrypt) {
if (bypass) {
if (scrypt) {
callback("scrypt");
} else if (pbkdf2) {
callback("pbkdf2");
} else {
callback("sha256");
}
return;
}
let algorithms = {
sha256:
"Salted SHA256 (1 iteration) - fastest and uses least memory, but less secure",
pbkdf2:
"PBKDF2 (PBKDF2-HMAC-SHA512, 36250 iterations) - more secure and uses less memory, but slower",
scrypt:
"scrypt (N=2^14, r=8, p=1) - faster and more secure, but uses more memory",
};
if (
!crypto.pbkdf2 ||
(process.isBun &&
!(
process.versions.bun &&
!process.versions.bun.match(
/^(?:0\.|1\.0\.|1\.1\.[0-9](?![0-9])|1\.1\.1[0-2](?![0-9]))/,
)
))
)
delete algorithms.pbkdf2;
const algorithmNames = Object.keys(algorithms);
if (algorithmNames.length < 2) callback(algorithmNames[0]);
console.log("Select password hashing algorithm. Available algorithms:");
for (var i = 0; i < algorithmNames.length; i++) {
console.log(algorithmNames[i] + " - " + algorithms[algorithmNames[i]]);
}
const rl = readline.createInterface({
input: process.stdin,
output: process.stdout,
prompt: "Algorithm: ",
});
rl.prompt();
rl.on("line", (line) => {
rl.close();
line = line.trim();
if (!algorithms[line]) callback(false);
else callback(line);
});
}
const userindex = getUserIndex(user);
if (action == "add" && userindex != -1) {
console.log("User alerady exists.");
process.exit(1);
} else if (action != "add" && userindex == -1) {
console.log("User doesn't exist.");
process.exit(1);
}
if (action == "delete") {
users.splice(userindex, 1);
saveConfig();
console.log("User deleted successfully");
} else if (action == "add") {
promptAlgorithms((algorithm) => {
if (!algorithm) {
console.log("Invalid algorithm!");
process.exit(1);
} else {
password((password) => {
if (!password) {
console.log("Passwords don't match!");
process.exit(1);
} else {
const salt = generateSalt();
let hash = "";
if (algorithm == "scrypt") {
hash = crypto.scryptSync(password, salt, 64).toString("hex");
} else if (algorithm == "pbkdf2") {
hash = crypto
.pbkdf2Sync(password, salt, 36250, 64, "sha512")
.toString("hex");
} else {
hash = sha256(password + salt);
}
users.push({
name: user,
pass: hash,
salt: salt,
pbkdf2: algorithm == "pbkdf2" ? true : undefined,
scrypt: algorithm == "scrypt" ? true : undefined,
__svrpasswd_l2: true,
});
saveConfig();
console.log("User added successfully");
}
});
}
});
} else {
promptAlgorithms(
(algorithm) => {
if (!algorithm) {
console.log("Invalid algorithm!");
process.exit(1);
} else {
password((password) => {
if (!password) {
console.log("Passwords don't match!");
process.exit(1);
} else {
var salt = generateSalt();
var hash = "";
if (algorithm == "scrypt") {
hash = crypto.scryptSync(password, salt, 64).toString("hex");
} else if (algorithm == "pbkdf2") {
hash = crypto
.pbkdf2Sync(password, salt, 36250, 64, "sha512")
.toString("hex");
} else {
hash = sha256(password + salt);
}
users[userindex] = {
name: user,
pass: hash,
salt: salt,
pbkdf2: algorithm == "pbkdf2" ? true : undefined,
scrypt: algorithm == "scrypt" ? true : undefined,
__svrpasswd_l2: true,
};
saveConfig();
console.log("Password changed successfully");
}
});
}
},
users[userindex].__svrpasswd_l2 && !forcechange,
users[userindex].pbkdf2,
users[userindex].scrypt,
);
}