import { randomBytes } from "node:crypto"; import { existsSync, readFileSync, writeFileSync } from "node:fs"; import type { Permission } from "./permission/permission"; export interface SettingConfig { /** * if true, server will bind on '127.0.0.1' rather than '0.0.0.0' */ localmode: boolean; /** * secure only */ secure: boolean; /** * guest permission */ guest: Permission[]; /** * JWT secret key. if you change its value, all access tokens are invalidated. */ jwt_secretkey: string; /** * the port which running server is binding on. */ port: number; mode: "development" | "production"; /** * if true, do not show 'electron' window and show terminal only. */ cli: boolean; /** forbid to login admin from remote client. but, it do not invalidate access token. * if you want to invalidate access token, change 'jwt_secretkey'. */ forbid_remote_admin_login: boolean; } const default_setting: SettingConfig = { localmode: true, secure: true, guest: [], jwt_secretkey: "itsRandom", port: 8080, mode: "production", cli: false, forbid_remote_admin_login: true, }; let setting: null | SettingConfig = null; // biome-ignore lint/suspicious/noExplicitAny: const setEmptyToDefault = (target: any, default_table: SettingConfig) => { let diff_occur = false; for (const key in default_table) { if (key === undefined || key in target) { continue; } target[key] = default_table[key as keyof SettingConfig]; diff_occur = true; } return diff_occur; }; export const read_setting_from_file = () => { const ret = existsSync("settings.json") ? JSON.parse(readFileSync("settings.json", { encoding: "utf8" })) : {}; const partial_occur = setEmptyToDefault(ret, default_setting); if (partial_occur) { writeFileSync("settings.json", JSON.stringify(ret)); } return ret as SettingConfig; }; export function get_setting(): SettingConfig { if (setting === null) { setting = read_setting_from_file(); const env = process.env.NODE_ENV; if (env !== undefined && env !== "production" && env !== "development") { throw new Error('process unknown value in NODE_ENV: must be either "development" or "production"'); } setting.mode = env ?? setting.mode; } return setting; }