81 lines
2.2 KiB
TypeScript
81 lines
2.2 KiB
TypeScript
import { randomBytes } from "node:crypto";
|
|
import { existsSync, readFileSync, writeFileSync } from "node:fs";
|
|
import type { Permission } from "./permission/permission.ts";
|
|
|
|
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: <explanation>
|
|
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;
|
|
}
|