"use strict"; var gTokens = {}; var form = require('form'); var http = require('http'); var gDatabase = new Database("auth"); function readSession(session) { var result = session ? gDatabase.get("session:" + session) : null; if (result) { result = JSON.parse(result); let kRefreshInterval = 1 * 60 * 60 * 1000; let now = Date.now(); if (!result.lastAccess || result.lastAccess < now - kRefreshInterval) { result.lastAccess = now; writeSession(session, result); } } return result; } function writeSession(session, value) { gDatabase.set("session:" + session, JSON.stringify(value)); } function removeSession(session, value) { gDatabase.remove("session:" + session); } function newSession() { var alphabet = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789"; var result = ""; for (var i = 0; i < 32; i++) { result += alphabet.charAt(Math.floor(Math.random() * alphabet.length)); } return result; } function verifyPassword(password, hash) { return bCrypt.hashpw(password, hash) == hash; } function hashPassword(password) { var salt = bCrypt.gensalt(12); return bCrypt.hashpw(password, salt); } function noAdministrator() { return !gGlobalSettings || !gGlobalSettings.permissions || !Object.keys(gGlobalSettings.permissions).some(function(name) { return gGlobalSettings.permissions[name].indexOf("administration") != -1; }); } function makeAdministrator(name) { if (!gGlobalSettings.permissions) { gGlobalSettings.permissions = {}; } if (!gGlobalSettings.permissions[name]) { gGlobalSettings.permissions[name] = []; } if (gGlobalSettings.permissions[name].indexOf("administration") == -1) { gGlobalSettings.permissions[name].push("administration"); } setGlobalSettings(gGlobalSettings); } function authHandler(request, response) { var session = getCookies(request.headers).session; if (request.uri == "/login") { var sessionIsNew = false; var loginError; var formData = form.decodeForm(request.query); if (request.method == "POST" || formData.submit) { session = newSession(); sessionIsNew = true; formData = form.decodeForm(utf8Decode(request.body), formData); if (formData.submit == "Login") { var account = gDatabase.get("user:" + formData.name); account = account ? JSON.parse(account) : account; if (formData.register == "1") { if (!account && formData.password == formData.confirm) { writeSession(session, {name: formData.name}); account = {password: hashPassword(formData.password)}; gDatabase.set("user:" + formData.name, JSON.stringify(account)); if (noAdministrator()) { makeAdministrator(formData.name); } } else { loginError = "Error registering account."; } } else { if (account && account.password && verifyPassword(formData.password, account.password)) { writeSession(session, {name: formData.name}); if (noAdministrator()) { makeAdministrator(formData.name); } } else { loginError = "Invalid username or password."; } } } else { // Proceed as Guest writeSession(session, {name: "guest"}); } } var cookie = "session=" + session + "; path=/; Max-Age=604800; Secure; SameSite=Strict"; var entry = readSession(session); if (entry && formData.return) { response.writeHead(303, {"Location": formData.return, "Set-Cookie": cookie}); response.end(); } else { File.readFile("core/auth.html").then(function(data) { var html = utf8Decode(data); var contents = ""; if (entry) { if (sessionIsNew) { contents += '