/* Espe | Ein schlichtes Werkzeug zur Mitglieder-Verwaltung | Backend Copyright (C) 2024 Christian Fraß This program is free software: you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation, either version 3 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program. If not, see . */ namespace _espe.conf { /** */ export type type_conf = { general : { verbosity : ( "none" | "debug" | "notice" | "info" | "warning" | "error" ); verification_secret : (null | string); }; server : { port : int; path_base : string; }; database : ( { kind : "sqlite"; data : { path : string; }; } | { kind : "postgresql"; data : { host : string; port ?: int; username : string; password : string; schema : string; }; } ); email_sending : ( { kind : "regular"; data : { smtp_credentials : _espe.helpers.type_smtp_credentials; sender : string; }; } | { kind : "redirect"; data : { smtp_credentials : _espe.helpers.type_smtp_credentials; sender : string; target : string; }; } | { kind : "console"; data : { }; } | { kind : "drop"; data : { }; } ); session_management : { in_memory : boolean; drop_all_at_start : boolean; lifetime : int; }; settings : { target_domain : string; frontend_url_base : (null | string); login_url : (null | string); prefix_for_nominal_email_addresses : string; facultative_membership_number : boolean; summon_email : { subject : string; body : string; }; registration_email : { subject : string; body : string; }; activation_email : { subject : string; body : string; }; password_policy : { minimum_length : (null | int); maximum_length : (null | int); must_contain_letter : boolean; must_contain_number : boolean; must_contain_special_character : boolean; }; password_change : { cooldown_time : int; initialization_email : { subject : string; body : string; }; execution_email : { subject : string; body : string; }; }; name_index : { veil : boolean; salt : (null | string); }; }; // TODO: evtl. in Datenbank verlagern admins : Array< { name : string; password_image : string; email_address : (null | string); } >; output : { authelia : (null | string); }; }; /** */ var _data : (null | type_conf) = null; /** */ export function inject( conf_raw : any ) : void { _data = { "general": ( ((node_general) => ({ "verbosity": (node_general["verbosity"] ?? "notice"), "verification_secret": (node_general["verification_secret"] ?? null), })) (conf_raw["general"] ?? {}) ), "server": ( ((node_server) => ({ "port": (node_server["port"] ?? 3593), "path_base": (node_server["path_base"] ?? ""), })) (conf_raw["server"] ?? {}) ), "database": ( ((node_database) => { const kind : string = (node_database["kind"] ?? "sqlite"); const node_database_data_raw = (node_database["data"] ?? {}); switch (kind) { case "sqlite": { return { "kind": kind, "data": { "path": (node_database_data_raw["path"] ?? "data.sqlite"), } }; break; } case "postgresql": { return { "kind": kind, "data": node_database_data_raw, }; break; } default: { throw (new Error("unhandled")); break; } } }) (conf_raw["database"] ?? {}) ), "email_sending": ( ((node_email_sending) => { const kind : string = (node_email_sending["kind"] ?? "regular"); const data_raw = (node_email_sending["data"] ?? {}); switch (kind) { case "regular": { return { "kind": kind, "data": { "smtp_credentials": (data_raw["smtp_credentials"] ?? null), "sender": data_raw["sender"], } }; break; } case "redirect": { return { "kind": kind, "data": { "smtp_credentials": (data_raw["smtp_credentials"] ?? null), "sender": data_raw["sender"], "target": data_raw["target"], } }; break; } case "console": { return { "kind": kind, "data": { } }; break; } case "drop": { return { "kind": kind, "data": { } }; break; } default: { throw (new Error("unhandled")); break; } } }) (conf_raw["email_sending"] ?? {}) ), "session_management": ( ((node_session_management) => ({ "in_memory": (node_session_management["in_memory"] ?? true), "drop_all_at_start": (node_session_management["drop_all_at_start"] ?? true), "lifetime": (node_session_management["lifetime"] ?? 900), })) (conf_raw["session_management"] ?? {}) ), "settings": ( ((node_settings) => ({ "target_domain": (node_settings["target_domain"] ?? "example.org"), "frontend_url_base": (node_settings["frontend_url_base"] ?? null), // TODO: mandatory? "login_url": (node_settings["login_url"] ?? null), "prefix_for_nominal_email_addresses": (node_settings["prefix_for_nominal_email_addresses"] ?? "member-"), "facultative_membership_number": (node_settings["facultative_membership_number"] ?? false), "summon_email": { "subject": ((node_settings["summon_email"] ?? {})["subject"] ?? "Please register"), "body": ((node_settings["summon_email"] ?? {})["body"] ?? "URL: {{url}}"), }, "registration_email": { "subject": ((node_settings["registration_email"] ?? {})["subject"] ?? "Mmeber registered"), "body": ((node_settings["registration_email"] ?? {})["body"] ?? "URL: {{url}}"), }, "activation_email": { "subject": ((node_settings["activation_email"] ?? {})["subject"] ?? "Account activated"), "body": ((node_settings["activation_email"] ?? {})["body"] ?? "URL: {{url}}\n\nLogin name: {{name_login}}\n\n"), }, "password_policy": ( ((node_settings_password_policy) => ({ "minimum_length": ( ("minimum_length" in node_settings_password_policy) ? node_settings_password_policy["minimum_length"] : 8 ), "maximum_length": ( ("maximum_length" in node_settings_password_policy) ? node_settings_password_policy["maximum_length"] : 240 ), "must_contain_letter": (node_settings_password_policy["must_contain_letter"] ?? true), "must_contain_number": (node_settings_password_policy["must_contain_number"] ?? true), "must_contain_special_character": (node_settings_password_policy["must_contain_special_character"] ?? true), })) (node_settings["password_policy"] ?? {}) ), "password_change": ( ((node_settings_password_change) => ({ "cooldown_time": (node_settings_password_change["cooldown_time"] ?? 86400), "initialization_email": { "subject": ((node_settings_password_change["initialization_email"] ?? {})["subject"] ?? "Password change initialized"), "body": ((node_settings_password_change["initialization_email"] ?? {})["body"] ?? "{{url}}"), }, "execution_email": { "subject": ((node_settings_password_change["execution_email"] ?? {})["subject"] ?? "Password changed"), "body": ((node_settings_password_change["execution_email"] ?? {})["body"] ?? ""), }, })) (node_settings["password_change"] ?? {}) ), "name_index": ( ((node_settings_password_policy) => ({ "veil": (node_settings_password_policy["veil"] ?? false), "salt": (node_settings_password_policy["salt"] ?? null), })) (node_settings["name_index"] ?? {}) ), })) (conf_raw["settings"] ?? {}) ), "admins": (conf_raw["admins"] ?? []), "output": ( ((node_session_output) => ({ "authelia": (node_session_output["authelia"] ?? null), })) (conf_raw["output"] ?? {}) ), }; } /** * @todo mandatory fields */ export async function load( path : string ) : Promise { let conf_raw : any; if (! (await lib_plankton.file.exists(path))) { // return Promise.reject(new Error("configuration file not found: " + path + "; using fallback")); conf_raw = {}; } else { try { conf_raw = lib_plankton.json.decode(await lib_plankton.file.read(path)); } catch (error) { conf_raw = null; } } if (conf_raw === null) { return Promise.reject("configuration file could not be read"); } else { inject(conf_raw); // process.stderr.write(JSON.stringify(_data, undefined, "\t")); return Promise.resolve(undefined); } } /** */ export function get( ) : type_conf { if (_data === null) { throw (new Error("conf not loaded yet")); } else { return _data; } } }