mirror of
https://github.com/louislam/dockge.git
synced 2026-05-21 14:02:17 +00:00
wip
This commit is contained in:
@@ -27,7 +27,7 @@ import path from "path";
|
||||
import { TerminalSocketHandler } from "./socket-handlers/terminal-socket-handler";
|
||||
import { Stack } from "./stack";
|
||||
import { Cron } from "croner";
|
||||
import childProcess from "child_process";
|
||||
import gracefulShutdown from "http-graceful-shutdown";
|
||||
|
||||
export class DockgeServer {
|
||||
app : Express;
|
||||
@@ -260,6 +260,16 @@ export class DockgeServer {
|
||||
});
|
||||
|
||||
});
|
||||
|
||||
gracefulShutdown(this.httpServer, {
|
||||
signals: "SIGINT SIGTERM",
|
||||
timeout: 30000, // timeout: 30 secs
|
||||
development: false, // not in dev mode
|
||||
forceExit: true, // triggers process.exit() at the end of shutdown process
|
||||
onShutdown: this.shutdownFunction, // shutdown function (async) - e.g. for cleanup DB, ...
|
||||
finally: this.finalFunction, // finally function (sync) - e.g. for logging
|
||||
});
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -280,12 +290,12 @@ export class DockgeServer {
|
||||
}
|
||||
|
||||
socket.emit("info", {
|
||||
versionProperty,
|
||||
latestVersionProperty,
|
||||
version: versionProperty,
|
||||
latestVersion: latestVersionProperty,
|
||||
isContainer,
|
||||
primaryBaseURL: await Settings.get("primaryBaseURL"),
|
||||
serverTimezone: await this.getTimezone(),
|
||||
serverTimezoneOffset: this.getTimezoneOffset(),
|
||||
//primaryBaseURL: await Settings.get("primaryBaseURL"),
|
||||
//serverTimezone: await this.getTimezone(),
|
||||
//serverTimezoneOffset: this.getTimezoneOffset(),
|
||||
});
|
||||
}
|
||||
|
||||
@@ -472,4 +482,26 @@ export class DockgeServer {
|
||||
get stackDirFullPath() {
|
||||
return path.resolve(this.stacksDir);
|
||||
}
|
||||
|
||||
/**
|
||||
* Shutdown the application
|
||||
* Stops all monitors and closes the database connection.
|
||||
* @param signal The signal that triggered this function to be called.
|
||||
*/
|
||||
async shutdownFunction(signal : string | undefined) {
|
||||
log.info("server", "Shutdown requested");
|
||||
log.info("server", "Called signal: " + signal);
|
||||
|
||||
// TODO: Close all terminals?
|
||||
|
||||
await Database.close();
|
||||
Settings.stopCacheCleaner();
|
||||
}
|
||||
|
||||
/**
|
||||
* Final function called before application exits
|
||||
*/
|
||||
finalFunction() {
|
||||
log.info("server", "Graceful shutdown successful!");
|
||||
}
|
||||
}
|
||||
|
||||
@@ -6,9 +6,10 @@ import { R } from "redbean-node";
|
||||
import { loginRateLimiter, twoFaRateLimiter } from "../rate-limiter";
|
||||
import { generatePasswordHash, needRehashPassword, shake256, SHAKE256_LENGTH, verifyPassword } from "../password-hash";
|
||||
import { User } from "../models/user";
|
||||
import { DockgeSocket } from "../util-server";
|
||||
import { checkLogin, DockgeSocket, doubleCheckPassword } from "../util-server";
|
||||
import { passwordStrength } from "check-password-strength";
|
||||
import jwt from "jsonwebtoken";
|
||||
import { Settings } from "../settings";
|
||||
|
||||
export class MainSocketHandler extends SocketHandler {
|
||||
create(socket : DockgeSocket, server : DockgeServer) {
|
||||
@@ -187,12 +188,63 @@ export class MainSocketHandler extends SocketHandler {
|
||||
}
|
||||
|
||||
});
|
||||
|
||||
socket.on("getSettings", async (callback) => {
|
||||
try {
|
||||
checkLogin(socket);
|
||||
const data = await Settings.getSettings("general");
|
||||
|
||||
callback({
|
||||
ok: true,
|
||||
data: data,
|
||||
});
|
||||
|
||||
} catch (e) {
|
||||
callback({
|
||||
ok: false,
|
||||
msg: e.message,
|
||||
});
|
||||
}
|
||||
});
|
||||
|
||||
socket.on("setSettings", async (data, currentPassword, callback) => {
|
||||
try {
|
||||
checkLogin(socket);
|
||||
|
||||
// If currently is disabled auth, don't need to check
|
||||
// Disabled Auth + Want to Disable Auth => No Check
|
||||
// Disabled Auth + Want to Enable Auth => No Check
|
||||
// Enabled Auth + Want to Disable Auth => Check!!
|
||||
// Enabled Auth + Want to Enable Auth => No Check
|
||||
const currentDisabledAuth = await Settings.get("disableAuth");
|
||||
if (!currentDisabledAuth && data.disableAuth) {
|
||||
await doubleCheckPassword(socket, currentPassword);
|
||||
}
|
||||
|
||||
await Settings.setSettings("general", data);
|
||||
|
||||
callback({
|
||||
ok: true,
|
||||
msg: "Saved"
|
||||
});
|
||||
|
||||
server.sendInfo(socket);
|
||||
|
||||
} catch (e) {
|
||||
callback({
|
||||
ok: false,
|
||||
msg: e.message,
|
||||
});
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
async afterLogin(server: DockgeServer, socket : DockgeSocket, user : User) {
|
||||
socket.userID = user.id;
|
||||
socket.join(user.id.toString());
|
||||
|
||||
server.sendInfo(socket);
|
||||
|
||||
try {
|
||||
server.sendStackList(socket);
|
||||
} catch (e) {
|
||||
|
||||
@@ -198,6 +198,13 @@ export class Stack {
|
||||
let composeList = JSON.parse(res.toString());
|
||||
|
||||
for (let composeStack of composeList) {
|
||||
|
||||
// Skip the dockge stack
|
||||
// TODO: Could be self managed?
|
||||
if (composeStack.Name === "dockge") {
|
||||
continue;
|
||||
}
|
||||
|
||||
let stack = stackList.get(composeStack.Name);
|
||||
|
||||
// This stack probably is not managed by Dockge, but we still want to show it
|
||||
|
||||
@@ -3,6 +3,8 @@ 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";
|
||||
|
||||
export interface DockgeSocket extends Socket {
|
||||
userID: number;
|
||||
@@ -57,3 +59,19 @@ export function callbackError(error : unknown, callback : unknown) {
|
||||
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;
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user