dockge/backend/util-server.ts

92 lines
2.2 KiB
TypeScript

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);
}