[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
|
### Anweisungen
|
||||||
|
|
||||||
- `conf.json` im build-Verzeichnis anlegen
|
- ins Erzeugnis-Verzeichnis wechseln
|
||||||
- `tools/run` ausführen
|
- `./espe -h` ausführen
|
||||||
|
- für die meisten Anwendungsfälle ist es erforderlich eine Konfigurations-Datei anzulegen
|
||||||
|
|
||||||
|
|
134
source/conf.ts
134
source/conf.ts
|
@ -4,9 +4,45 @@ namespace _espe.conf
|
||||||
/**
|
/**
|
||||||
*/
|
*/
|
||||||
export type type_conf = {
|
export type type_conf = {
|
||||||
port : int;
|
general : {
|
||||||
database_path : string;
|
verbosity : (
|
||||||
email : {
|
"none"
|
||||||
|
|
|
||||||
|
"debug"
|
||||||
|
|
|
||||||
|
"notice"
|
||||||
|
|
|
||||||
|
"info"
|
||||||
|
|
|
||||||
|
"warning"
|
||||||
|
|
|
||||||
|
"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 : (
|
mode : (
|
||||||
"regular"
|
"regular"
|
||||||
|
|
|
|
||||||
|
@ -16,35 +52,30 @@ namespace _espe.conf
|
||||||
|
|
|
|
||||||
"drop"
|
"drop"
|
||||||
);
|
);
|
||||||
smtp_credentials : {
|
smtp_credentials : (
|
||||||
host : string;
|
null
|
||||||
port : int;
|
|
|
||||||
username : string;
|
{
|
||||||
password : string;
|
host : string;
|
||||||
};
|
port : int;
|
||||||
|
username : string;
|
||||||
|
password : string;
|
||||||
|
}
|
||||||
|
);
|
||||||
};
|
};
|
||||||
session_lifetime : int;
|
session_management : {
|
||||||
session_drop_all_at_start : boolean;
|
lifetime : int;
|
||||||
email_domain : string;
|
drop_all_at_start : boolean;
|
||||||
email_numberbased_address_prefix : string;
|
};
|
||||||
verification_secret : string;
|
settings : {
|
||||||
verbosity : (
|
target_domain : string;
|
||||||
"none"
|
prefix_for_numberbased_email_addresses : string;
|
||||||
|
|
};
|
||||||
"debug"
|
// TODO: evtl. in Datenbank verlagern
|
||||||
|
|
|
||||||
"notice"
|
|
||||||
|
|
|
||||||
"info"
|
|
||||||
|
|
|
||||||
"warning"
|
|
||||||
|
|
|
||||||
"error"
|
|
||||||
);
|
|
||||||
admins : Array<
|
admins : Array<
|
||||||
{
|
{
|
||||||
name : string;
|
name : string;
|
||||||
password : string;
|
password_image : string;
|
||||||
}
|
}
|
||||||
>;
|
>;
|
||||||
};
|
};
|
||||||
|
@ -68,17 +99,44 @@ namespace _espe.conf
|
||||||
: {}
|
: {}
|
||||||
);
|
);
|
||||||
_data = {
|
_data = {
|
||||||
"port": (conf_raw["port"] ?? 7979),
|
"general": (
|
||||||
"email_domain": (conf_raw["email_domain"] ?? "example.org"),
|
((node_general) => ({
|
||||||
"email_numberbased_address_prefix": (conf_raw["email_numberbased_address_prefix"] ?? "member-"),
|
"verbosity": (node_general["verbosity"] ?? "notice"),
|
||||||
"email": conf_raw["email"], // TODO: feiner
|
"verification_secret": (node_general["verification_secret"] ?? null),
|
||||||
"verification_secret": (conf_raw["verification_secret"] ?? "itsy_bitsy"),
|
})) (conf_raw["general"] ?? {})
|
||||||
"session_lifetime": (conf_raw["session_lifetime"] ?? 900),
|
),
|
||||||
"session_drop_all_at_start": true,
|
"server": (
|
||||||
"verbosity": (conf_raw["verbosity"] ?? "notice"),
|
((node_server) => ({
|
||||||
"database_path": (conf_raw["database_path"] ?? "data.sqlite"),
|
"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"] ?? []),
|
"admins": (conf_raw["admins"] ?? []),
|
||||||
};
|
};
|
||||||
|
// process.stderr.write(JSON.stringify(_data, undefined, "\t"));
|
||||||
return Promise.resolve<void>(undefined);
|
return Promise.resolve<void>(undefined);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -86,7 +144,7 @@ namespace _espe.conf
|
||||||
/**
|
/**
|
||||||
*/
|
*/
|
||||||
export function get(
|
export function get(
|
||||||
) : any
|
) : type_conf
|
||||||
{
|
{
|
||||||
if (_data === null) {
|
if (_data === null) {
|
||||||
throw (new Error("conf not loaded yet"));
|
throw (new Error("conf not loaded yet"));
|
||||||
|
|
|
@ -54,12 +54,20 @@ namespace _espe.helpers
|
||||||
export function database_implementation(
|
export function database_implementation(
|
||||||
) : lib_plankton.database.type_database
|
) : lib_plankton.database.type_database
|
||||||
{
|
{
|
||||||
return lib_plankton.database.sqlite_database(
|
switch (_espe.conf.get().database.kind) {
|
||||||
{
|
case "sqlite": {
|
||||||
"path": _espe.conf.get().database_path,
|
return lib_plankton.database.sqlite_database(
|
||||||
"verbose": false,
|
{
|
||||||
|
"path": _espe.conf.get().database.data["path"],
|
||||||
|
"verbose": false,
|
||||||
|
}
|
||||||
|
);
|
||||||
|
break;
|
||||||
}
|
}
|
||||||
);
|
default: {
|
||||||
|
throw (new Error("database implementation not available: " + _espe.conf.get().database.kind));
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@ -69,10 +77,16 @@ namespace _espe.helpers
|
||||||
data : any
|
data : any
|
||||||
) : Promise<string>
|
) : Promise<string>
|
||||||
{
|
{
|
||||||
return lib_plankton.sha256.get(
|
const secret : (null | string) = _espe.conf.get().general.verification_secret;
|
||||||
lib_plankton.json.encode(data),
|
if (secret === null) {
|
||||||
_espe.conf.get().verification_secret
|
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),
|
||||||
|
secret
|
||||||
|
);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@ -83,11 +97,17 @@ namespace _espe.helpers
|
||||||
verification : string
|
verification : string
|
||||||
) : Promise<boolean>
|
) : Promise<boolean>
|
||||||
{
|
{
|
||||||
const verification_expected : string = lib_plankton.sha256.get(
|
const secret : (null | string) = _espe.conf.get().general.verification_secret;
|
||||||
lib_plankton.json.encode(data),
|
if (secret === null) {
|
||||||
_espe.conf.get().verification_secret
|
return Promise.reject<boolean>(new Error("no verification secret specified; add in conf as 'general.verification_secret'!"));
|
||||||
);
|
}
|
||||||
return (verification === verification_expected);
|
else {
|
||||||
|
const verification_expected : string = lib_plankton.sha256.get(
|
||||||
|
lib_plankton.json.encode(data),
|
||||||
|
secret
|
||||||
|
);
|
||||||
|
return (verification === verification_expected);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@ -99,7 +119,7 @@ namespace _espe.helpers
|
||||||
content : string
|
content : string
|
||||||
) : Promise<void>
|
) : Promise<void>
|
||||||
{
|
{
|
||||||
const mode : string = _espe.conf.get().email.mode;
|
const mode : string = _espe.conf.get().email_sending.mode;
|
||||||
lib_plankton.log.info(
|
lib_plankton.log.info(
|
||||||
"email_send",
|
"email_send",
|
||||||
{
|
{
|
||||||
|
@ -110,11 +130,21 @@ namespace _espe.helpers
|
||||||
);
|
);
|
||||||
switch (mode) {
|
switch (mode) {
|
||||||
case "regular": {
|
case "regular": {
|
||||||
// TODO
|
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;
|
break;
|
||||||
}
|
}
|
||||||
case "redirect": {
|
case "redirect": {
|
||||||
// TODO
|
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;
|
break;
|
||||||
}
|
}
|
||||||
case "console": {
|
case "console": {
|
||||||
|
|
|
@ -11,8 +11,46 @@ async function main(
|
||||||
"type": lib_plankton.args.enum_type.string,
|
"type": lib_plankton.args.enum_type.string,
|
||||||
"mode": lib_plankton.args.enum_mode.replace,
|
"mode": lib_plankton.args.enum_mode.replace,
|
||||||
"default": "serve",
|
"default": "serve",
|
||||||
"info": "Aktion (serve | doc | password-image | export-authelia | help)",
|
|
||||||
"name": "action",
|
"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({
|
"arg1": lib_plankton.args.class_argument.positional({
|
||||||
"index": 1,
|
"index": 1,
|
||||||
|
@ -37,7 +75,7 @@ async function main(
|
||||||
"indicators_short": ["c"],
|
"indicators_short": ["c"],
|
||||||
"type": lib_plankton.args.enum_type.string,
|
"type": lib_plankton.args.enum_type.string,
|
||||||
"mode": lib_plankton.args.enum_mode.replace,
|
"mode": lib_plankton.args.enum_mode.replace,
|
||||||
"default": "conf.json",
|
"default": null,
|
||||||
"info": "Pfad zur Konfigurations-Datei",
|
"info": "Pfad zur Konfigurations-Datei",
|
||||||
"name": "conf-path",
|
"name": "conf-path",
|
||||||
}),
|
}),
|
||||||
|
@ -83,17 +121,13 @@ async function main(
|
||||||
"notice": lib_plankton.log.enum_level.notice,
|
"notice": lib_plankton.log.enum_level.notice,
|
||||||
"info": lib_plankton.log.enum_level.info,
|
"info": lib_plankton.log.enum_level.info,
|
||||||
"debug":lib_plankton.log.enum_level.debug,
|
"debug":lib_plankton.log.enum_level.debug,
|
||||||
}[_espe.conf.get().verbosity]
|
}[_espe.conf.get().general.verbosity]
|
||||||
),
|
),
|
||||||
]
|
]
|
||||||
);
|
);
|
||||||
switch (args["action"]) {
|
switch (args["action"]) {
|
||||||
default: {
|
default: {
|
||||||
process.stderr.write(
|
process.stderr.write("invalid action: " + args["action"] + "\n");
|
||||||
"invalid action: " + args["action"]
|
|
||||||
+
|
|
||||||
"\n"
|
|
||||||
);
|
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
case "password-image": {
|
case "password-image": {
|
||||||
|
@ -107,7 +141,7 @@ async function main(
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
case "doc": {
|
case "api-doc": {
|
||||||
const rest_subject : lib_plankton.rest.type_rest = _espe.api.make();
|
const rest_subject : lib_plankton.rest.type_rest = _espe.api.make();
|
||||||
process.stdout.write(
|
process.stdout.write(
|
||||||
JSON.stringify(
|
JSON.stringify(
|
||||||
|
@ -126,7 +160,7 @@ async function main(
|
||||||
lib_plankton.storage.sql_table_common.chest(
|
lib_plankton.storage.sql_table_common.chest(
|
||||||
{
|
{
|
||||||
"database_implementation": _espe.helpers.database_implementation(),
|
"database_implementation": _espe.helpers.database_implementation(),
|
||||||
"table_name": "sessions",
|
"table_name": "session_management",
|
||||||
"key_names": ["key"],
|
"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(
|
_espe.service.member.listen_change(
|
||||||
async () => {
|
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");
|
process.stdout.write(authelia_export + "\n");
|
||||||
}
|
}
|
||||||
);
|
);
|
||||||
|
|
||||||
const rest_subject : lib_plankton.rest.type_rest = _espe.api.make();
|
const rest_subject : lib_plankton.rest.type_rest = _espe.api.make();
|
||||||
const server : lib_plankton.server.type_subject = lib_plankton.server.make(
|
const server : lib_plankton.server.type_subject = lib_plankton.server.make(
|
||||||
_espe.conf.get().port,
|
_espe.conf.get().server.port,
|
||||||
async (input, metadata) => {
|
async (input, metadata) => {
|
||||||
const http_request : lib_plankton.http.type_request = lib_plankton.http.decode_request(input);
|
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(
|
const http_response : lib_plankton.http.type_response = await lib_plankton.rest.call(
|
||||||
|
@ -186,7 +220,7 @@ async function main(
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
case "export-authelia": {
|
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;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -271,7 +271,7 @@ namespace _espe.service.member
|
||||||
? ""
|
? ""
|
||||||
: ("." + value.name_real_extension)
|
: ("." + 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(
|
return lib_plankton.string.coin(
|
||||||
"{{prefix}}{{membership_number}}@{{domain}}",
|
"{{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,
|
"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>
|
) : Promise<string>
|
||||||
{
|
{
|
||||||
const nm_yaml = require("yaml");
|
const nm_yaml = require("yaml");
|
||||||
|
|
Loading…
Add table
Reference in a new issue