import { Socket } from "socket.io"; import { Terminal } from "./terminal"; import { randomBytes } from "crypto"; import { log } from "./log"; import { ERROR_TYPE_VALIDATION } from "./util-common"; import { R } from "redbean-node"; import { verifyPassword } from "./password-hash"; import fs from "fs"; export interface JWTDecoded { username : string; h? : string; } export interface DockgeSocket extends Socket { userID: number; consoleTerminal? : Terminal; } // For command line arguments, so they are nullable export interface Arguments { sslKey? : string; sslCert? : string; sslKeyPassphrase? : string; port? : number; hostname? : string; dataDir? : string; stacksDir? : string; } // Some config values are required export interface Config extends Arguments { dataDir : string; stacksDir : string; } export function checkLogin(socket : DockgeSocket) { if (!socket.userID) { throw new Error("You are not logged in."); } } export class ValidationError extends Error { constructor(message : string) { super(message); } } export function callbackError(error : unknown, callback : unknown) { if (typeof(callback) !== "function") { log.error("console", "Callback is not a function"); return; } if (error instanceof Error) { callback({ ok: false, msg: error.message, }); } else if (error instanceof ValidationError) { callback({ ok: false, type: ERROR_TYPE_VALIDATION, msg: error.message, }); } else { log.debug("console", "Unknown error: " + error); } } export async function doubleCheckPassword(socket : DockgeSocket, currentPassword : unknown) { if (typeof currentPassword !== "string") { throw new Error("Wrong data type?"); } let user = await R.findOne("user", " id = ? AND active = 1 ", [ socket.userID, ]); if (!user || !verifyPassword(currentPassword, user.password)) { throw new Error("Incorrect current password"); } return user; } export function fileExists(file : string) { return fs.promises.access(file, fs.constants.F_OK) .then(() => true) .catch(() => false); }