145 lines
4.1 KiB
TypeScript
145 lines
4.1 KiB
TypeScript
import dotenv from "dotenv";
|
|
import { promises as fs } from "fs";
|
|
import { readFileSync } from "fs";
|
|
import path from "path";
|
|
import { fileURLToPath } from "url";
|
|
import { AutoSSLSetup } from "./utils/auto-ssl-setup.js";
|
|
import { AuthManager } from "./utils/auth-manager.js";
|
|
import { DataCrypto } from "./utils/data-crypto.js";
|
|
import { SystemCrypto } from "./utils/system-crypto.js";
|
|
import { systemLogger, versionLogger } from "./utils/logger.js";
|
|
|
|
(async () => {
|
|
try {
|
|
dotenv.config({ quiet: true });
|
|
|
|
const dataDir = process.env.DATA_DIR || "./db/data";
|
|
const envPath = path.join(dataDir, ".env");
|
|
try {
|
|
await fs.access(envPath);
|
|
const persistentConfig = dotenv.config({ path: envPath, quiet: true });
|
|
if (persistentConfig.parsed) {
|
|
Object.assign(process.env, persistentConfig.parsed);
|
|
}
|
|
} catch (error) {}
|
|
|
|
let version = "unknown";
|
|
|
|
const versionSources = [
|
|
() => process.env.VERSION,
|
|
() => {
|
|
try {
|
|
const packageJsonPath = path.join(process.cwd(), "package.json");
|
|
const packageJson = JSON.parse(
|
|
readFileSync(packageJsonPath, "utf-8"),
|
|
);
|
|
return packageJson.version;
|
|
} catch {
|
|
return null;
|
|
}
|
|
},
|
|
() => {
|
|
try {
|
|
const __filename = fileURLToPath(import.meta.url);
|
|
const packageJsonPath = path.join(
|
|
path.dirname(__filename),
|
|
"../../../package.json",
|
|
);
|
|
const packageJson = JSON.parse(
|
|
readFileSync(packageJsonPath, "utf-8"),
|
|
);
|
|
return packageJson.version;
|
|
} catch {
|
|
return null;
|
|
}
|
|
},
|
|
() => {
|
|
try {
|
|
const packageJsonPath = path.join("/app", "package.json");
|
|
const packageJson = JSON.parse(
|
|
readFileSync(packageJsonPath, "utf-8"),
|
|
);
|
|
return packageJson.version;
|
|
} catch {
|
|
return null;
|
|
}
|
|
},
|
|
];
|
|
|
|
for (const getVersion of versionSources) {
|
|
try {
|
|
const foundVersion = getVersion();
|
|
if (foundVersion && foundVersion !== "unknown") {
|
|
version = foundVersion;
|
|
break;
|
|
}
|
|
} catch {
|
|
continue;
|
|
}
|
|
}
|
|
versionLogger.info(`Termix Backend starting - Version: ${version}`, {
|
|
operation: "startup",
|
|
version: version,
|
|
});
|
|
|
|
const systemCrypto = SystemCrypto.getInstance();
|
|
await systemCrypto.initializeJWTSecret();
|
|
await systemCrypto.initializeDatabaseKey();
|
|
await systemCrypto.initializeInternalAuthToken();
|
|
|
|
await AutoSSLSetup.initialize();
|
|
|
|
const dbModule = await import("./database/db/index.js");
|
|
await dbModule.initializeDatabase();
|
|
|
|
const authManager = AuthManager.getInstance();
|
|
await authManager.initialize();
|
|
DataCrypto.initialize();
|
|
|
|
await import("./database/database.js");
|
|
|
|
await import("./ssh/terminal.js");
|
|
await import("./ssh/tunnel.js");
|
|
await import("./ssh/file-manager.js");
|
|
await import("./ssh/server-stats.js");
|
|
await import("./ssh/docker.js");
|
|
await import("./ssh/docker-console.js");
|
|
await import("./dashboard.js");
|
|
|
|
process.on("SIGINT", () => {
|
|
systemLogger.info(
|
|
"Received SIGINT signal, initiating graceful shutdown...",
|
|
{ operation: "shutdown" },
|
|
);
|
|
process.exit(0);
|
|
});
|
|
|
|
process.on("SIGTERM", () => {
|
|
systemLogger.info(
|
|
"Received SIGTERM signal, initiating graceful shutdown...",
|
|
{ operation: "shutdown" },
|
|
);
|
|
process.exit(0);
|
|
});
|
|
|
|
process.on("uncaughtException", (error) => {
|
|
systemLogger.error("Uncaught exception occurred", error, {
|
|
operation: "error_handling",
|
|
});
|
|
process.exit(1);
|
|
});
|
|
|
|
process.on("unhandledRejection", (reason) => {
|
|
systemLogger.error("Unhandled promise rejection", reason, {
|
|
operation: "error_handling",
|
|
});
|
|
process.exit(1);
|
|
});
|
|
} catch (error) {
|
|
systemLogger.error("Failed to initialize backend services", error, {
|
|
operation: "startup_failed",
|
|
});
|
|
process.exit(1);
|
|
}
|
|
})();
|