[mod] Konfigurations-Verwaltung verbessert
This commit is contained in:
parent
9c56055650
commit
adf0e9675f
5 changed files with 199 additions and 78 deletions
|
@ -27,7 +27,6 @@
|
|||
|
||||
### Anweisungen
|
||||
|
||||
- `conf.json` im build-Verzeichnis anlegen
|
||||
- `tools/run` ausführen
|
||||
|
||||
|
||||
- ins Erzeugnis-Verzeichnis wechseln
|
||||
- `./espe -h` ausführen
|
||||
- für die meisten Anwendungsfälle ist es erforderlich eine Konfigurations-Datei anzulegen
|
||||
|
|
128
source/conf.ts
128
source/conf.ts
|
@ -4,30 +4,7 @@ namespace _espe.conf
|
|||
/**
|
||||
*/
|
||||
export type type_conf = {
|
||||
port : int;
|
||||
database_path : string;
|
||||
email : {
|
||||
mode : (
|
||||
"regular"
|
||||
|
|
||||
"redirect"
|
||||
|
|
||||
"console"
|
||||
|
|
||||
"drop"
|
||||
);
|
||||
smtp_credentials : {
|
||||
host : string;
|
||||
port : int;
|
||||
username : string;
|
||||
password : string;
|
||||
};
|
||||
};
|
||||
session_lifetime : int;
|
||||
session_drop_all_at_start : boolean;
|
||||
email_domain : string;
|
||||
email_numberbased_address_prefix : string;
|
||||
verification_secret : string;
|
||||
general : {
|
||||
verbosity : (
|
||||
"none"
|
||||
|
|
||||
|
@ -41,10 +18,64 @@ namespace _espe.conf
|
|||
|
|
||||
"error"
|
||||
);
|
||||
verification_secret : (null | string);
|
||||
};
|
||||
server : {
|
||||
port : int;
|
||||
};
|
||||
database : (
|
||||
{
|
||||
kind : "sqlite";
|
||||
data : {
|
||||
path : string;
|
||||
};
|
||||
}
|
||||
|
|
||||
{
|
||||
kind : "postgresql";
|
||||
data : {
|
||||
host : string;
|
||||
port ?: int;
|
||||
username : string;
|
||||
password : string;
|
||||
schema : string;
|
||||
};
|
||||
}
|
||||
);
|
||||
email_sending : {
|
||||
mode : (
|
||||
"regular"
|
||||
|
|
||||
"redirect"
|
||||
|
|
||||
"console"
|
||||
|
|
||||
"drop"
|
||||
);
|
||||
smtp_credentials : (
|
||||
null
|
||||
|
|
||||
{
|
||||
host : string;
|
||||
port : int;
|
||||
username : string;
|
||||
password : string;
|
||||
}
|
||||
);
|
||||
};
|
||||
session_management : {
|
||||
lifetime : int;
|
||||
drop_all_at_start : boolean;
|
||||
};
|
||||
settings : {
|
||||
target_domain : string;
|
||||
prefix_for_numberbased_email_addresses : string;
|
||||
};
|
||||
// TODO: evtl. in Datenbank verlagern
|
||||
admins : Array<
|
||||
{
|
||||
name : string;
|
||||
password : string;
|
||||
password_image : string;
|
||||
}
|
||||
>;
|
||||
};
|
||||
|
@ -68,17 +99,44 @@ namespace _espe.conf
|
|||
: {}
|
||||
);
|
||||
_data = {
|
||||
"port": (conf_raw["port"] ?? 7979),
|
||||
"email_domain": (conf_raw["email_domain"] ?? "example.org"),
|
||||
"email_numberbased_address_prefix": (conf_raw["email_numberbased_address_prefix"] ?? "member-"),
|
||||
"email": conf_raw["email"], // TODO: feiner
|
||||
"verification_secret": (conf_raw["verification_secret"] ?? "itsy_bitsy"),
|
||||
"session_lifetime": (conf_raw["session_lifetime"] ?? 900),
|
||||
"session_drop_all_at_start": true,
|
||||
"verbosity": (conf_raw["verbosity"] ?? "notice"),
|
||||
"database_path": (conf_raw["database_path"] ?? "data.sqlite"),
|
||||
"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"] ?? 7979),
|
||||
})) (conf_raw["server"] ?? {})
|
||||
),
|
||||
"database": (
|
||||
((node_database) => ({
|
||||
"kind": (node_database["kind"] ?? "sqlite"),
|
||||
"data": node_database["data"],
|
||||
})) (conf_raw["database"] ?? {})
|
||||
),
|
||||
"email_sending": (
|
||||
((node_email_sending) => ({
|
||||
"mode": (node_email_sending["mode"] ?? "regular"),
|
||||
"smtp_credentials": (node_email_sending["smtp_credentials"] ?? null),
|
||||
})) (conf_raw["email_sending"] ?? {})
|
||||
),
|
||||
"session_management": (
|
||||
((node_session_management) => ({
|
||||
"lifetime": (node_session_management["lifetime"] ?? 900),
|
||||
"drop_all_at_start": (node_session_management["drop_all_at_start"] ?? true),
|
||||
})) (conf_raw["session_management"] ?? {})
|
||||
),
|
||||
"settings": (
|
||||
((node_settings) => ({
|
||||
"target_domain": (node_settings["target_domain"] ?? "example.org"),
|
||||
"prefix_for_numberbased_email_addresses": (node_settings["prefix_for_numberbased_email_addresses"] ?? "member-"),
|
||||
})) (conf_raw["settings"] ?? {})
|
||||
),
|
||||
"admins": (conf_raw["admins"] ?? []),
|
||||
};
|
||||
// process.stderr.write(JSON.stringify(_data, undefined, "\t"));
|
||||
return Promise.resolve<void>(undefined);
|
||||
}
|
||||
|
||||
|
@ -86,7 +144,7 @@ namespace _espe.conf
|
|||
/**
|
||||
*/
|
||||
export function get(
|
||||
) : any
|
||||
) : type_conf
|
||||
{
|
||||
if (_data === null) {
|
||||
throw (new Error("conf not loaded yet"));
|
||||
|
|
|
@ -54,12 +54,20 @@ namespace _espe.helpers
|
|||
export function database_implementation(
|
||||
) : lib_plankton.database.type_database
|
||||
{
|
||||
switch (_espe.conf.get().database.kind) {
|
||||
case "sqlite": {
|
||||
return lib_plankton.database.sqlite_database(
|
||||
{
|
||||
"path": _espe.conf.get().database_path,
|
||||
"path": _espe.conf.get().database.data["path"],
|
||||
"verbose": false,
|
||||
}
|
||||
);
|
||||
break;
|
||||
}
|
||||
default: {
|
||||
throw (new Error("database implementation not available: " + _espe.conf.get().database.kind));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
@ -69,11 +77,17 @@ namespace _espe.helpers
|
|||
data : any
|
||||
) : Promise<string>
|
||||
{
|
||||
const secret : (null | string) = _espe.conf.get().general.verification_secret;
|
||||
if (secret === null) {
|
||||
return Promise.reject<string>(new Error("no verification secret specified; add in conf as 'general.verification_secret'!"));
|
||||
}
|
||||
else {
|
||||
return lib_plankton.sha256.get(
|
||||
lib_plankton.json.encode(data),
|
||||
_espe.conf.get().verification_secret
|
||||
secret
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
|
@ -83,12 +97,18 @@ namespace _espe.helpers
|
|||
verification : string
|
||||
) : Promise<boolean>
|
||||
{
|
||||
const secret : (null | string) = _espe.conf.get().general.verification_secret;
|
||||
if (secret === null) {
|
||||
return Promise.reject<boolean>(new Error("no verification secret specified; add in conf as 'general.verification_secret'!"));
|
||||
}
|
||||
else {
|
||||
const verification_expected : string = lib_plankton.sha256.get(
|
||||
lib_plankton.json.encode(data),
|
||||
_espe.conf.get().verification_secret
|
||||
secret
|
||||
);
|
||||
return (verification === verification_expected);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
|
@ -99,7 +119,7 @@ namespace _espe.helpers
|
|||
content : string
|
||||
) : Promise<void>
|
||||
{
|
||||
const mode : string = _espe.conf.get().email.mode;
|
||||
const mode : string = _espe.conf.get().email_sending.mode;
|
||||
lib_plankton.log.info(
|
||||
"email_send",
|
||||
{
|
||||
|
@ -110,11 +130,21 @@ namespace _espe.helpers
|
|||
);
|
||||
switch (mode) {
|
||||
case "regular": {
|
||||
if (_espe.conf.get().email_sending.smtp_credentials === null) {
|
||||
return Promise.reject<void>("no smtp credentials specified; add in conf as 'email_sending.smtp_credentials'!");
|
||||
}
|
||||
else {
|
||||
// TODO
|
||||
}
|
||||
break;
|
||||
}
|
||||
case "redirect": {
|
||||
if (_espe.conf.get().email_sending.smtp_credentials === null) {
|
||||
return Promise.reject<void>("no smtp credentials specified; add in conf as 'email_sending.smtp_credentials'!");
|
||||
}
|
||||
else {
|
||||
// TODO
|
||||
}
|
||||
break;
|
||||
}
|
||||
case "console": {
|
||||
|
|
|
@ -11,8 +11,46 @@ async function main(
|
|||
"type": lib_plankton.args.enum_type.string,
|
||||
"mode": lib_plankton.args.enum_mode.replace,
|
||||
"default": "serve",
|
||||
"info": "Aktion (serve | doc | password-image | export-authelia | help)",
|
||||
"name": "action",
|
||||
"info": lib_plankton.string.coin(
|
||||
"auszuführende Aktion; Auswahl:\n{{selection}}\n\t\t",
|
||||
{
|
||||
"selection": (
|
||||
[
|
||||
{
|
||||
"name": "serve",
|
||||
"description": "Server starten",
|
||||
},
|
||||
{
|
||||
"name": "api-doc",
|
||||
"description": "API-Dokumentation gemäß OpenAPI Specification auf Standard-Ausgabe schreiben"
|
||||
},
|
||||
{
|
||||
"name": "password-image",
|
||||
"description": "Passwort-Abbild errechnen und auf Standard-Ausgabe schreiben"
|
||||
},
|
||||
{
|
||||
"name": "export-authelia",
|
||||
"description": "Export der Nutzer-Datenbank im Authelia-user-Datei-Format auf Standard-Ausgabe schreiben"
|
||||
},
|
||||
{
|
||||
"name": "help",
|
||||
"description": "Diese Hilfe auf Standard-Ausgabe schreiben"
|
||||
},
|
||||
]
|
||||
.map(
|
||||
entry => lib_plankton.string.coin(
|
||||
"\t\t- {{name}}\n\t\t\t{{description}}\n",
|
||||
{
|
||||
"name": entry.name,
|
||||
"description": entry.description,
|
||||
}
|
||||
)
|
||||
)
|
||||
.join("")
|
||||
),
|
||||
}
|
||||
),
|
||||
}),
|
||||
"arg1": lib_plankton.args.class_argument.positional({
|
||||
"index": 1,
|
||||
|
@ -37,7 +75,7 @@ async function main(
|
|||
"indicators_short": ["c"],
|
||||
"type": lib_plankton.args.enum_type.string,
|
||||
"mode": lib_plankton.args.enum_mode.replace,
|
||||
"default": "conf.json",
|
||||
"default": null,
|
||||
"info": "Pfad zur Konfigurations-Datei",
|
||||
"name": "conf-path",
|
||||
}),
|
||||
|
@ -83,17 +121,13 @@ async function main(
|
|||
"notice": lib_plankton.log.enum_level.notice,
|
||||
"info": lib_plankton.log.enum_level.info,
|
||||
"debug":lib_plankton.log.enum_level.debug,
|
||||
}[_espe.conf.get().verbosity]
|
||||
}[_espe.conf.get().general.verbosity]
|
||||
),
|
||||
]
|
||||
);
|
||||
switch (args["action"]) {
|
||||
default: {
|
||||
process.stderr.write(
|
||||
"invalid action: " + args["action"]
|
||||
+
|
||||
"\n"
|
||||
);
|
||||
process.stderr.write("invalid action: " + args["action"] + "\n");
|
||||
break;
|
||||
}
|
||||
case "password-image": {
|
||||
|
@ -107,7 +141,7 @@ async function main(
|
|||
}
|
||||
break;
|
||||
}
|
||||
case "doc": {
|
||||
case "api-doc": {
|
||||
const rest_subject : lib_plankton.rest.type_rest = _espe.api.make();
|
||||
process.stdout.write(
|
||||
JSON.stringify(
|
||||
|
@ -126,7 +160,7 @@ async function main(
|
|||
lib_plankton.storage.sql_table_common.chest(
|
||||
{
|
||||
"database_implementation": _espe.helpers.database_implementation(),
|
||||
"table_name": "sessions",
|
||||
"table_name": "session_management",
|
||||
"key_names": ["key"],
|
||||
}
|
||||
),
|
||||
|
@ -143,7 +177,7 @@ async function main(
|
|||
]
|
||||
),
|
||||
*/
|
||||
"default_lifetime": _espe.conf.get().session_lifetime,
|
||||
"default_lifetime": _espe.conf.get().session_management.lifetime,
|
||||
}
|
||||
);
|
||||
|
||||
|
@ -158,14 +192,14 @@ async function main(
|
|||
);
|
||||
_espe.service.member.listen_change(
|
||||
async () => {
|
||||
const authelia_export : string = await _espe.service.member.export_authelia_member_file();
|
||||
const authelia_export : string = await _espe.service.member.export_authelia_user_file();
|
||||
process.stdout.write(authelia_export + "\n");
|
||||
}
|
||||
);
|
||||
|
||||
const rest_subject : lib_plankton.rest.type_rest = _espe.api.make();
|
||||
const server : lib_plankton.server.type_subject = lib_plankton.server.make(
|
||||
_espe.conf.get().port,
|
||||
_espe.conf.get().server.port,
|
||||
async (input, metadata) => {
|
||||
const http_request : lib_plankton.http.type_request = lib_plankton.http.decode_request(input);
|
||||
const http_response : lib_plankton.http.type_response = await lib_plankton.rest.call(
|
||||
|
@ -186,7 +220,7 @@ async function main(
|
|||
break;
|
||||
}
|
||||
case "export-authelia": {
|
||||
process.stdout.write(await _espe.service.member.export_authelia_member_file() + "\n");
|
||||
process.stdout.write(await _espe.service.member.export_authelia_user_file() + "\n");
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -271,7 +271,7 @@ namespace _espe.service.member
|
|||
? ""
|
||||
: ("." + value.name_real_extension)
|
||||
),
|
||||
"domain": _espe.conf.get().email_domain,
|
||||
"domain": _espe.conf.get().settings.target_domain,
|
||||
}
|
||||
);
|
||||
}
|
||||
|
@ -286,9 +286,9 @@ namespace _espe.service.member
|
|||
return lib_plankton.string.coin(
|
||||
"{{prefix}}{{membership_number}}@{{domain}}",
|
||||
{
|
||||
"prefix": _espe.conf.get().email_numberbased_address_prefix,
|
||||
"prefix": _espe.conf.get().settings.prefix_for_numberbased_email_addresses,
|
||||
"membership_number": value.membership_number,
|
||||
"domain": _espe.conf.get().email_domain,
|
||||
"domain": _espe.conf.get().settings.target_domain,
|
||||
}
|
||||
);
|
||||
}
|
||||
|
@ -313,9 +313,9 @@ namespace _espe.service.member
|
|||
|
||||
|
||||
/**
|
||||
* @todo check validity (e.g. membername characters)
|
||||
* @todo check validity (e.g. username characters)
|
||||
*/
|
||||
export async function export_authelia_member_file(
|
||||
export async function export_authelia_user_file(
|
||||
) : Promise<string>
|
||||
{
|
||||
const nm_yaml = require("yaml");
|
||||
|
|
Loading…
Add table
Reference in a new issue