2024-05-20 21:56:48 +02:00
|
|
|
/*
|
|
|
|
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
|
|
|
|
<https://www.gnu.org/licenses/>.
|
|
|
|
*/
|
|
|
|
|
2024-04-22 10:22:18 +02:00
|
|
|
namespace _espe.conf
|
2024-04-22 10:02:34 +02:00
|
|
|
{
|
|
|
|
|
|
|
|
/**
|
|
|
|
*/
|
|
|
|
export type type_conf = {
|
2024-04-22 17:34:41 +02:00
|
|
|
general : {
|
|
|
|
verbosity : (
|
|
|
|
"none"
|
|
|
|
|
|
|
|
|
"debug"
|
|
|
|
|
|
|
|
|
"notice"
|
|
|
|
|
|
|
|
|
"info"
|
|
|
|
|
|
|
|
|
"warning"
|
|
|
|
|
|
|
|
|
"error"
|
|
|
|
);
|
|
|
|
verification_secret : (null | string);
|
|
|
|
};
|
|
|
|
server : {
|
|
|
|
port : int;
|
2024-04-30 19:04:07 +02:00
|
|
|
path_base : string;
|
2024-04-22 17:34:41 +02:00
|
|
|
};
|
|
|
|
database : (
|
|
|
|
{
|
|
|
|
kind : "sqlite";
|
|
|
|
data : {
|
|
|
|
path : string;
|
|
|
|
};
|
|
|
|
}
|
|
|
|
|
|
|
|
|
{
|
|
|
|
kind : "postgresql";
|
|
|
|
data : {
|
|
|
|
host : string;
|
|
|
|
port ?: int;
|
|
|
|
username : string;
|
|
|
|
password : string;
|
|
|
|
schema : string;
|
|
|
|
};
|
|
|
|
}
|
|
|
|
);
|
2024-04-23 17:44:31 +02:00
|
|
|
email_sending : (
|
|
|
|
{
|
|
|
|
kind : "regular";
|
|
|
|
data : {
|
2024-05-27 17:32:42 +02:00
|
|
|
smtp_credentials : _espe.helpers.type_smtp_credentials;
|
2024-04-23 17:44:31 +02:00
|
|
|
sender : string;
|
|
|
|
};
|
|
|
|
}
|
|
|
|
|
|
|
|
|
{
|
|
|
|
kind : "redirect";
|
|
|
|
data : {
|
2024-05-27 17:32:42 +02:00
|
|
|
smtp_credentials : _espe.helpers.type_smtp_credentials;
|
2024-04-23 17:44:31 +02:00
|
|
|
sender : string;
|
|
|
|
target : string;
|
|
|
|
};
|
|
|
|
}
|
|
|
|
|
|
|
|
|
{
|
|
|
|
kind : "console";
|
|
|
|
data : {
|
|
|
|
};
|
|
|
|
}
|
|
|
|
|
|
|
|
|
{
|
|
|
|
kind : "drop";
|
|
|
|
data : {
|
|
|
|
};
|
|
|
|
}
|
|
|
|
);
|
2024-04-22 17:34:41 +02:00
|
|
|
session_management : {
|
2024-04-26 11:02:52 +02:00
|
|
|
in_memory : boolean;
|
2024-04-22 17:34:41 +02:00
|
|
|
drop_all_at_start : boolean;
|
2024-04-26 11:02:52 +02:00
|
|
|
lifetime : int;
|
2024-04-22 17:34:41 +02:00
|
|
|
};
|
|
|
|
settings : {
|
|
|
|
target_domain : string;
|
2024-05-20 12:20:59 +02:00
|
|
|
frontend_url_base : (null | string);
|
2024-05-27 21:27:36 +02:00
|
|
|
login_url : (null | string);
|
2024-05-20 21:56:48 +02:00
|
|
|
prefix_for_nominal_email_addresses : string;
|
2024-05-27 19:10:01 +02:00
|
|
|
facultative_membership_number : boolean;
|
2024-05-27 21:27:36 +02:00
|
|
|
summon_email : {
|
|
|
|
subject : string;
|
|
|
|
body : string;
|
|
|
|
};
|
2024-04-23 17:44:31 +02:00
|
|
|
registration_email : {
|
|
|
|
subject : string;
|
|
|
|
body : string;
|
|
|
|
};
|
2024-05-27 21:27:36 +02:00
|
|
|
activation_email : {
|
|
|
|
subject : string;
|
|
|
|
body : string;
|
|
|
|
};
|
2024-04-30 14:54:24 +02:00
|
|
|
password_policy : {
|
|
|
|
minimum_length : (null | int);
|
|
|
|
maximum_length : (null | int);
|
|
|
|
must_contain_letter : boolean;
|
|
|
|
must_contain_number : boolean;
|
|
|
|
must_contain_special_character : boolean;
|
|
|
|
};
|
2024-05-20 12:20:59 +02:00
|
|
|
password_change : {
|
|
|
|
cooldown_time : int;
|
|
|
|
initialization_email : {
|
|
|
|
subject : string;
|
|
|
|
body : string;
|
|
|
|
};
|
|
|
|
execution_email : {
|
|
|
|
subject : string;
|
|
|
|
body : string;
|
|
|
|
};
|
|
|
|
};
|
2024-04-30 19:04:07 +02:00
|
|
|
name_index : {
|
|
|
|
veil : boolean;
|
|
|
|
salt : (null | string);
|
|
|
|
};
|
2024-04-22 17:34:41 +02:00
|
|
|
};
|
|
|
|
// TODO: evtl. in Datenbank verlagern
|
2024-04-22 10:02:34 +02:00
|
|
|
admins : Array<
|
|
|
|
{
|
|
|
|
name : string;
|
2024-04-22 17:34:41 +02:00
|
|
|
password_image : string;
|
2024-04-23 17:44:31 +02:00
|
|
|
email_address : (null | string);
|
2024-04-22 10:02:34 +02:00
|
|
|
}
|
|
|
|
>;
|
2024-05-27 22:01:56 +02:00
|
|
|
output : {
|
|
|
|
authelia : (null | string);
|
|
|
|
};
|
2024-04-22 10:02:34 +02:00
|
|
|
};
|
|
|
|
|
|
|
|
|
|
|
|
/**
|
|
|
|
*/
|
|
|
|
var _data : (null | type_conf) = null;
|
|
|
|
|
|
|
|
|
2024-05-10 19:40:02 +02:00
|
|
|
/**
|
|
|
|
*/
|
|
|
|
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) => ({
|
2024-06-03 11:03:41 +02:00
|
|
|
"port": (node_server["port"] ?? 3593),
|
2024-05-10 19:40:02 +02:00
|
|
|
"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"),
|
2024-05-20 12:20:59 +02:00
|
|
|
"frontend_url_base": (node_settings["frontend_url_base"] ?? null), // TODO: mandatory?
|
2024-05-27 21:27:36 +02:00
|
|
|
"login_url": (node_settings["login_url"] ?? null),
|
2024-05-20 21:56:48 +02:00
|
|
|
"prefix_for_nominal_email_addresses": (node_settings["prefix_for_nominal_email_addresses"] ?? "member-"),
|
2024-05-27 19:10:01 +02:00
|
|
|
"facultative_membership_number": (node_settings["facultative_membership_number"] ?? false),
|
2024-05-27 21:27:36 +02:00
|
|
|
"summon_email": {
|
|
|
|
"subject": ((node_settings["summon_email"] ?? {})["subject"] ?? "Please register"),
|
|
|
|
"body": ((node_settings["summon_email"] ?? {})["body"] ?? "URL: {{url}}"),
|
|
|
|
},
|
2024-05-10 19:40:02 +02:00
|
|
|
"registration_email": {
|
2024-05-27 21:27:36 +02:00
|
|
|
"subject": ((node_settings["registration_email"] ?? {})["subject"] ?? "Mmeber registered"),
|
2024-05-10 19:40:02 +02:00
|
|
|
"body": ((node_settings["registration_email"] ?? {})["body"] ?? "URL: {{url}}"),
|
|
|
|
},
|
2024-05-27 21:27:36 +02:00
|
|
|
"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"),
|
|
|
|
},
|
2024-05-10 19:40:02 +02:00
|
|
|
"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"] ?? {})
|
|
|
|
),
|
2024-05-20 12:20:59 +02:00
|
|
|
"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"] ?? {})
|
|
|
|
),
|
2024-05-10 19:40:02 +02:00
|
|
|
"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"] ?? []),
|
2024-05-27 22:01:56 +02:00
|
|
|
"output": (
|
|
|
|
((node_session_output) => ({
|
|
|
|
"authelia": (node_session_output["authelia"] ?? null),
|
|
|
|
})) (conf_raw["output"] ?? {})
|
|
|
|
),
|
2024-05-10 19:40:02 +02:00
|
|
|
};
|
|
|
|
}
|
|
|
|
|
|
|
|
|
2024-04-22 10:02:34 +02:00
|
|
|
/**
|
|
|
|
* @todo mandatory fields
|
|
|
|
*/
|
|
|
|
export async function load(
|
2024-04-26 11:02:52 +02:00
|
|
|
path : string
|
2024-04-22 10:02:34 +02:00
|
|
|
) : Promise<void>
|
|
|
|
{
|
2024-04-26 11:02:52 +02:00
|
|
|
let conf_raw : any;
|
|
|
|
if (! (await lib_plankton.file.exists(path))) {
|
|
|
|
// return Promise.reject<void>(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<void>("configuration file could not be read");
|
|
|
|
}
|
|
|
|
else {
|
2024-05-10 19:40:02 +02:00
|
|
|
inject(conf_raw);
|
2024-04-26 11:02:52 +02:00
|
|
|
// process.stderr.write(JSON.stringify(_data, undefined, "\t"));
|
|
|
|
return Promise.resolve<void>(undefined);
|
|
|
|
}
|
2024-04-22 10:02:34 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
/**
|
|
|
|
*/
|
|
|
|
export function get(
|
2024-04-22 17:34:41 +02:00
|
|
|
) : type_conf
|
2024-04-22 10:02:34 +02:00
|
|
|
{
|
|
|
|
if (_data === null) {
|
|
|
|
throw (new Error("conf not loaded yet"));
|
|
|
|
}
|
|
|
|
else {
|
|
|
|
return _data;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
}
|