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.service.member
|
2024-04-22 10:02:34 +02:00
|
|
|
{
|
|
|
|
|
|
|
|
/**
|
|
|
|
*/
|
|
|
|
var _hooks_change : Array<() => void> = [];
|
|
|
|
|
|
|
|
|
|
|
|
/**
|
|
|
|
*/
|
|
|
|
export function listen_change(
|
|
|
|
procedure : () => void
|
|
|
|
) : void
|
|
|
|
{
|
|
|
|
_hooks_change.push(procedure);
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
/**
|
|
|
|
*/
|
2024-05-27 21:27:36 +02:00
|
|
|
function signal_change(
|
2024-04-22 10:02:34 +02:00
|
|
|
) : void
|
|
|
|
{
|
|
|
|
_hooks_change.forEach(
|
|
|
|
procedure => {
|
|
|
|
procedure();
|
|
|
|
}
|
|
|
|
);
|
|
|
|
}
|
|
|
|
|
|
|
|
|
2024-04-30 14:05:01 +02:00
|
|
|
/**
|
|
|
|
*/
|
2024-06-20 15:13:58 +02:00
|
|
|
function validate_password(
|
2024-04-30 14:05:01 +02:00
|
|
|
password : string
|
|
|
|
) : Array<{incident : string; details : Record<string, any>}>
|
|
|
|
{
|
2024-06-20 15:13:58 +02:00
|
|
|
return _espe.helper.password.validate(
|
|
|
|
_espe.conf.get().settings.password_policy,
|
|
|
|
password
|
|
|
|
);
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
/**
|
|
|
|
*/
|
|
|
|
function generate_password(
|
|
|
|
) : string
|
|
|
|
{
|
|
|
|
return _espe.helper.password.generate(
|
|
|
|
_espe.conf.get().settings.password_policy
|
|
|
|
);
|
2024-04-30 14:05:01 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
|
2024-04-22 10:02:34 +02:00
|
|
|
/**
|
2024-05-20 09:52:09 +02:00
|
|
|
* ermittelt den Anmelde-Name des Mitglieds
|
2024-04-22 10:02:34 +02:00
|
|
|
*/
|
2024-04-30 08:46:52 +02:00
|
|
|
export function name_login(
|
2024-04-29 22:40:52 +02:00
|
|
|
object : _espe.type.member_object
|
|
|
|
) : string
|
|
|
|
{
|
|
|
|
return lib_plankton.string.coin(
|
|
|
|
"{{object}}{{extension}}",
|
|
|
|
{
|
2024-04-30 14:05:01 +02:00
|
|
|
"object": lib_plankton.call.convey(
|
|
|
|
object.name_real_value,
|
|
|
|
[
|
2024-05-27 17:32:42 +02:00
|
|
|
(x : string) => x.toLowerCase(),
|
|
|
|
(x : string) => x.replace(new RegExp(" ", "g"), "."),
|
|
|
|
(x : string) => x.replace(new RegExp("[äÄ]", "g"), "ae"),
|
|
|
|
(x : string) => x.replace(new RegExp("[öÖ]", "g"), "oe"),
|
|
|
|
(x : string) => x.replace(new RegExp("[üÜ]", "g"), "ue"),
|
|
|
|
(x : string) => x.replace(new RegExp("[ß]", "g"), "ss"),
|
2024-06-24 09:55:46 +02:00
|
|
|
(x : string) => x.replace(new RegExp("[^0-9a-z-\.]", "g"), "_"),
|
2024-04-30 14:05:01 +02:00
|
|
|
]
|
|
|
|
),
|
2024-04-29 22:40:52 +02:00
|
|
|
"extension": (
|
2024-04-30 01:32:24 +02:00
|
|
|
(object.name_real_index <= 1)
|
2024-04-29 22:40:52 +02:00
|
|
|
? ""
|
|
|
|
: ("." + object.name_real_index.toFixed(0))
|
|
|
|
),
|
|
|
|
}
|
|
|
|
);
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
/**
|
2024-05-20 09:52:09 +02:00
|
|
|
* ermittelt den Anzeige-Name des Mitglieds
|
2024-04-29 22:40:52 +02:00
|
|
|
*/
|
2024-04-30 08:46:52 +02:00
|
|
|
export function name_display(
|
2024-04-29 22:40:52 +02:00
|
|
|
object : _espe.type.member_object
|
|
|
|
) : string
|
|
|
|
{
|
|
|
|
return object.name_real_value;
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
/**
|
2024-05-20 09:52:09 +02:00
|
|
|
* ermittelt die verschleierte E-Mail-Adresse des Mitglieds
|
2024-04-29 22:40:52 +02:00
|
|
|
*/
|
2024-04-30 08:46:52 +02:00
|
|
|
export function email_address_veiled(
|
2024-04-29 22:40:52 +02:00
|
|
|
object : _espe.type.member_object
|
2024-05-27 18:12:15 +02:00
|
|
|
) : (null | string)
|
2024-04-29 22:40:52 +02:00
|
|
|
{
|
2024-05-27 18:12:15 +02:00
|
|
|
return (
|
|
|
|
(object.membership_number === null)
|
|
|
|
? null
|
|
|
|
: lib_plankton.string.coin(
|
|
|
|
"{{prefix}}{{membership_number}}@{{domain}}",
|
|
|
|
{
|
2024-06-03 12:33:15 +02:00
|
|
|
"prefix": _espe.conf.get().settings.misc.prefix_for_veiled_email_addresses,
|
2024-05-27 18:12:15 +02:00
|
|
|
"membership_number": object.membership_number,
|
2024-06-03 12:33:15 +02:00
|
|
|
"domain": _espe.conf.get().settings.organisation.domain,
|
2024-05-27 18:12:15 +02:00
|
|
|
}
|
|
|
|
)
|
2024-04-29 22:40:52 +02:00
|
|
|
);
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
/**
|
2024-05-20 09:52:09 +02:00
|
|
|
* ermittelt die namentliche E-Mail-Adresse des Mitglieds
|
2024-04-29 22:40:52 +02:00
|
|
|
*/
|
2024-04-30 08:46:52 +02:00
|
|
|
export function email_address_nominal(
|
2024-04-29 22:40:52 +02:00
|
|
|
object : _espe.type.member_object
|
|
|
|
) : string
|
|
|
|
{
|
|
|
|
return lib_plankton.string.coin(
|
|
|
|
"{{user}}@{{domain}}",
|
|
|
|
{
|
|
|
|
"user": name_login(object),
|
2024-06-03 12:33:15 +02:00
|
|
|
"domain": _espe.conf.get().settings.organisation.domain,
|
2024-04-29 22:40:52 +02:00
|
|
|
}
|
|
|
|
);
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
/**
|
2024-05-20 09:52:09 +02:00
|
|
|
* ermittelt die allgemein zu verwendende E-Mail-Adresse des Mitglieds
|
2024-04-29 22:40:52 +02:00
|
|
|
*/
|
2024-04-30 08:46:52 +02:00
|
|
|
export function email_address(
|
2024-04-29 22:40:52 +02:00
|
|
|
object : _espe.type.member_object
|
|
|
|
) : (null | string)
|
|
|
|
{
|
|
|
|
return (
|
|
|
|
object.email_use_nominal_address
|
|
|
|
? email_address_nominal(object)
|
|
|
|
: (
|
|
|
|
object.email_use_veiled_address
|
|
|
|
? email_address_veiled(object)
|
|
|
|
: object.email_address_private
|
|
|
|
)
|
|
|
|
);
|
|
|
|
}
|
|
|
|
|
|
|
|
|
2024-05-20 12:20:59 +02:00
|
|
|
/**
|
|
|
|
* ermittelt das Passwort-Abbild anhand des tatsächlichen Passworts
|
|
|
|
*/
|
|
|
|
function password_image(
|
|
|
|
password : (null | string)
|
2024-05-27 17:32:42 +02:00
|
|
|
) : Promise<(null | string)>
|
2024-05-20 12:20:59 +02:00
|
|
|
{
|
|
|
|
return (
|
|
|
|
(
|
|
|
|
(! (password === null))
|
|
|
|
&&
|
|
|
|
(! (password === ""))
|
|
|
|
)
|
|
|
|
? _espe.helpers.bcrypt_compute(password)
|
2024-05-27 17:32:42 +02:00
|
|
|
: Promise.resolve<(null | string)>(null)
|
2024-05-20 12:20:59 +02:00
|
|
|
);
|
|
|
|
}
|
|
|
|
|
2024-05-27 21:27:36 +02:00
|
|
|
|
|
|
|
/**
|
|
|
|
*/
|
|
|
|
async function send_activation_email(
|
2024-06-20 16:32:59 +02:00
|
|
|
member_object : _espe.type.member_object,
|
|
|
|
options : {
|
|
|
|
password ?: (null | string);
|
|
|
|
} = {}
|
2024-05-27 21:27:36 +02:00
|
|
|
) : Promise<void>
|
|
|
|
{
|
2024-06-20 16:32:59 +02:00
|
|
|
options = Object.assign(
|
|
|
|
{
|
|
|
|
"password": null,
|
|
|
|
},
|
|
|
|
options
|
|
|
|
);
|
2024-05-27 21:27:36 +02:00
|
|
|
if (! member_object.enabled) {
|
|
|
|
// do nothing
|
|
|
|
}
|
|
|
|
else {
|
|
|
|
if (member_object.email_address_private === null) {
|
|
|
|
// do nothing
|
|
|
|
}
|
|
|
|
else {
|
|
|
|
await _espe.helpers.email_send(
|
|
|
|
[
|
|
|
|
member_object.email_address_private,
|
|
|
|
],
|
|
|
|
lib_plankton.string.coin(
|
2024-06-03 12:33:15 +02:00
|
|
|
"{{head}} | {{core}}",
|
|
|
|
{
|
|
|
|
"head": _espe.conf.get().settings.organisation.name,
|
|
|
|
"core": lib_plankton.translate.get("email.activation.subject"),
|
|
|
|
}
|
|
|
|
),
|
|
|
|
lib_plankton.string.coin(
|
|
|
|
lib_plankton.translate.get("email.activation.body"),
|
2024-05-27 21:27:36 +02:00
|
|
|
{
|
|
|
|
"name_display": name_display(member_object),
|
|
|
|
"name_login": name_login(member_object),
|
2024-06-03 12:33:15 +02:00
|
|
|
"url": (_espe.conf.get().settings.connections.login_url ?? "--"),
|
2024-06-20 16:32:59 +02:00
|
|
|
"password_info": (
|
|
|
|
(
|
|
|
|
(options.password === undefined)
|
|
|
|
||
|
|
|
|
(options.password === null)
|
|
|
|
)
|
|
|
|
? ""
|
|
|
|
: lib_plankton.string.coin(
|
2024-06-23 11:47:28 +02:00
|
|
|
lib_plankton.translate.get("email.activation.password_info"),
|
2024-06-20 16:32:59 +02:00
|
|
|
{
|
|
|
|
"password": options.password,
|
|
|
|
}
|
|
|
|
)
|
|
|
|
),
|
2024-05-27 21:27:36 +02:00
|
|
|
}
|
|
|
|
)
|
|
|
|
);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
|
2024-04-29 22:40:52 +02:00
|
|
|
/**
|
2024-05-20 09:52:09 +02:00
|
|
|
* gibt die vollständigen Daten aller Mitglieder aus
|
2024-04-29 22:40:52 +02:00
|
|
|
*/
|
2024-08-18 13:54:58 +02:00
|
|
|
export async function dump(
|
2024-04-29 22:40:52 +02:00
|
|
|
) : Promise<
|
|
|
|
Array<
|
|
|
|
{
|
|
|
|
id : _espe.type.member_id;
|
|
|
|
object : _espe.type.member_object;
|
|
|
|
}
|
|
|
|
>
|
|
|
|
>
|
|
|
|
{
|
|
|
|
return _espe.repository.member.dump();
|
|
|
|
}
|
2024-04-30 01:32:24 +02:00
|
|
|
|
|
|
|
|
|
|
|
/**
|
2024-05-20 09:52:09 +02:00
|
|
|
* gibt eine Auflistung aller Mitgliedr aus
|
2024-04-30 01:32:24 +02:00
|
|
|
*/
|
|
|
|
export async function list(
|
|
|
|
search_term : (null | string)
|
|
|
|
) : Promise<
|
|
|
|
Array<
|
|
|
|
{
|
|
|
|
id : _espe.type.member_id;
|
|
|
|
preview : {
|
|
|
|
membership_number : string;
|
|
|
|
name_real_value : string;
|
|
|
|
name_real_index : int;
|
|
|
|
};
|
|
|
|
}
|
|
|
|
>
|
|
|
|
>
|
|
|
|
{
|
|
|
|
return _espe.repository.member.list(search_term);
|
|
|
|
}
|
|
|
|
|
2024-04-29 22:40:52 +02:00
|
|
|
|
|
|
|
|
|
|
|
/**
|
2024-05-20 09:52:09 +02:00
|
|
|
* gibt die Angaben eines bestimmten Mitglieds aus
|
2024-04-29 22:40:52 +02:00
|
|
|
*/
|
2024-04-30 01:32:24 +02:00
|
|
|
export function get(
|
2024-04-29 22:40:52 +02:00
|
|
|
id : _espe.type.member_id
|
|
|
|
) : Promise<_espe.type.member_object>
|
|
|
|
{
|
|
|
|
return _espe.repository.member.read(id);
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
/**
|
2024-05-20 09:52:09 +02:00
|
|
|
* legt ein Mitglied an
|
2024-04-29 22:40:52 +02:00
|
|
|
*/
|
|
|
|
export async function project(
|
2024-04-29 20:48:20 +02:00
|
|
|
data : {
|
2024-05-27 19:10:01 +02:00
|
|
|
membership_number : (null | string);
|
2024-04-29 20:48:20 +02:00
|
|
|
name_real_value : string;
|
|
|
|
email_address_private : (null | string);
|
|
|
|
}
|
2024-04-29 22:40:52 +02:00
|
|
|
) : Promise<_espe.type.member_id>
|
2024-04-22 10:02:34 +02:00
|
|
|
{
|
2024-04-29 22:40:52 +02:00
|
|
|
const name_real_index : int = await _espe.service.name_index.next(data.name_real_value);
|
|
|
|
const object : _espe.type.member_object = {
|
2024-04-29 20:48:20 +02:00
|
|
|
"membership_number": data.membership_number,
|
|
|
|
"name_real_value": data.name_real_value,
|
|
|
|
"name_real_index": name_real_index,
|
|
|
|
"email_address_private": data.email_address_private,
|
|
|
|
"registered": false,
|
2024-04-30 15:35:17 +02:00
|
|
|
"enabled": true,
|
2024-04-29 20:48:20 +02:00
|
|
|
"email_use_veiled_address": false,
|
|
|
|
"email_use_nominal_address": false,
|
|
|
|
"email_redirect_to_private_address": false,
|
|
|
|
"email_allow_sending": false,
|
|
|
|
"password_image": null,
|
2024-05-20 12:20:59 +02:00
|
|
|
"password_change_last_attempt": null,
|
|
|
|
"password_change_token": null,
|
2024-04-22 10:02:34 +02:00
|
|
|
};
|
2024-04-29 22:40:52 +02:00
|
|
|
const id : _espe.type.member_id = await _espe.repository.member.create(object);
|
2024-05-27 21:27:36 +02:00
|
|
|
signal_change();
|
2024-04-29 20:48:20 +02:00
|
|
|
return id;
|
2024-04-22 10:02:34 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
|
2024-04-29 22:40:52 +02:00
|
|
|
/**
|
2024-05-20 09:52:09 +02:00
|
|
|
* sendet an ein Mitglied eine E-Mail mit Aufforderung zur Registrierung
|
2024-04-29 22:40:52 +02:00
|
|
|
*/
|
|
|
|
export async function summon(
|
|
|
|
member_id : _espe.type.member_id,
|
|
|
|
url_template : string
|
2024-05-27 17:32:42 +02:00
|
|
|
) : Promise<(null | string)>
|
2024-04-22 10:02:34 +02:00
|
|
|
{
|
2024-05-27 21:27:36 +02:00
|
|
|
_espe.helpers.frontend_url_check();
|
2024-04-29 22:40:52 +02:00
|
|
|
const member_object : _espe.type.member_object = await get(member_id);
|
2024-05-27 17:32:42 +02:00
|
|
|
if (member_object.email_address_private === null) {
|
|
|
|
return null;
|
|
|
|
}
|
|
|
|
else {
|
2024-05-27 21:27:36 +02:00
|
|
|
const url : (null | string) = _espe.helpers.frontend_url_get(
|
2024-05-27 17:32:42 +02:00
|
|
|
url_template,
|
2024-04-29 22:40:52 +02:00
|
|
|
{
|
2024-05-27 21:27:36 +02:00
|
|
|
"verification": await _espe.helpers.verification_get(member_id),
|
2024-04-29 22:40:52 +02:00
|
|
|
}
|
2024-05-27 17:32:42 +02:00
|
|
|
);
|
2024-05-27 21:27:36 +02:00
|
|
|
if (url === null) {
|
|
|
|
// do nothing
|
|
|
|
}
|
|
|
|
else {
|
|
|
|
await _espe.helpers.email_send(
|
|
|
|
[
|
|
|
|
member_object.email_address_private,
|
|
|
|
],
|
|
|
|
lib_plankton.string.coin(
|
2024-06-03 12:33:15 +02:00
|
|
|
"{{head}} | {{core}}",
|
|
|
|
{
|
|
|
|
"head": _espe.conf.get().settings.organisation.name,
|
|
|
|
"core": lib_plankton.translate.get("email.summon.subject"),
|
|
|
|
}
|
|
|
|
),
|
|
|
|
lib_plankton.string.coin(
|
|
|
|
lib_plankton.translate.get("email.summon.body"),
|
2024-05-27 21:27:36 +02:00
|
|
|
{
|
|
|
|
"name": name_display(member_object),
|
|
|
|
"url": url,
|
2024-06-03 12:33:15 +02:00
|
|
|
"remark": (
|
|
|
|
(_espe.conf.get().settings.summon_email.remark === null)
|
|
|
|
? ""
|
|
|
|
: (_espe.conf.get().settings.summon_email.remark + "\n\n")
|
|
|
|
),
|
2024-05-27 21:27:36 +02:00
|
|
|
}
|
|
|
|
)
|
|
|
|
);
|
|
|
|
}
|
2024-05-27 17:32:42 +02:00
|
|
|
return url;
|
|
|
|
}
|
2024-04-22 10:02:34 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
|
2024-04-29 22:40:52 +02:00
|
|
|
/**
|
2024-05-20 09:52:09 +02:00
|
|
|
* gibt Daten über ein Mitglied aus, die relevant für die Registrierung sind
|
2024-04-29 22:40:52 +02:00
|
|
|
*/
|
|
|
|
export async function info(
|
|
|
|
member_id : _espe.type.member_id
|
|
|
|
) : Promise<
|
|
|
|
(
|
|
|
|
null
|
|
|
|
|
|
|
|
|
{
|
|
|
|
name_real_value : string;
|
|
|
|
name_real_index : int;
|
|
|
|
name_login : string;
|
2024-05-27 18:12:15 +02:00
|
|
|
email_address_veiled : (null | string);
|
2024-04-29 22:40:52 +02:00
|
|
|
email_address_nominal : string;
|
|
|
|
}
|
|
|
|
)
|
|
|
|
>
|
2024-04-22 10:02:34 +02:00
|
|
|
{
|
2024-04-29 22:40:52 +02:00
|
|
|
const member_object : _espe.type.member_object = await _espe.repository.member.read(member_id);
|
|
|
|
if (! member_object.registered) {
|
|
|
|
return {
|
|
|
|
"name_real_value": member_object.name_real_value,
|
|
|
|
"name_real_index": member_object.name_real_index,
|
|
|
|
"name_login": name_login(member_object),
|
|
|
|
"email_address_veiled": email_address_veiled(member_object),
|
|
|
|
"email_address_nominal": email_address_nominal(member_object),
|
|
|
|
};
|
|
|
|
}
|
|
|
|
else {
|
|
|
|
return null;
|
|
|
|
}
|
2024-04-22 10:02:34 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
|
2024-04-29 22:40:52 +02:00
|
|
|
/**
|
2024-05-20 09:52:09 +02:00
|
|
|
* führt die Registrierung für ein Mitglied durch
|
2024-04-29 22:40:52 +02:00
|
|
|
*/
|
2024-04-22 10:02:34 +02:00
|
|
|
export async function register(
|
2024-04-29 22:40:52 +02:00
|
|
|
member_id : _espe.type.member_id,
|
2024-04-22 10:02:34 +02:00
|
|
|
data : {
|
2024-04-29 22:40:52 +02:00
|
|
|
email_use_veiled_address : boolean;
|
|
|
|
email_use_nominal_address : boolean;
|
|
|
|
email_redirect_to_private_address : boolean;
|
2024-05-27 17:32:42 +02:00
|
|
|
password : (null | string);
|
2024-04-29 22:40:52 +02:00
|
|
|
},
|
|
|
|
options : {
|
2024-05-27 21:27:36 +02:00
|
|
|
notification_target_url_template ?: (null | string);
|
2024-04-29 22:40:52 +02:00
|
|
|
} = {}
|
2024-04-30 14:05:01 +02:00
|
|
|
) : Promise<Array<{incident : string; details : Record<string, any>;}>>
|
2024-04-22 10:02:34 +02:00
|
|
|
{
|
2024-04-29 22:40:52 +02:00
|
|
|
options = Object.assign(
|
|
|
|
{
|
2024-05-27 21:27:36 +02:00
|
|
|
"notification_target_url_template": null,
|
2024-04-29 22:40:52 +02:00
|
|
|
},
|
|
|
|
options
|
|
|
|
);
|
2024-04-30 14:05:01 +02:00
|
|
|
|
2024-04-29 22:40:52 +02:00
|
|
|
const member_object : _espe.type.member_object = await get(member_id);
|
2024-06-20 16:32:59 +02:00
|
|
|
|
2024-04-30 14:05:01 +02:00
|
|
|
let flaws : Array<{incident : string; details : Record<string, any>;}> = [];
|
2024-06-20 16:32:59 +02:00
|
|
|
let password_value : string;
|
|
|
|
let password_generated : boolean;
|
2024-04-29 22:40:52 +02:00
|
|
|
if (member_object.registered) {
|
2024-04-30 14:05:01 +02:00
|
|
|
flaws.push({"incident": "already_registered", "details": {}});
|
2024-06-20 16:32:59 +02:00
|
|
|
password_value = "";
|
|
|
|
password_generated = false;
|
2024-04-22 10:02:34 +02:00
|
|
|
}
|
|
|
|
else {
|
2024-05-27 17:32:42 +02:00
|
|
|
if (
|
|
|
|
(data.password !== null)
|
2024-06-20 16:32:59 +02:00
|
|
|
&&
|
|
|
|
(data.password !== "")
|
2024-05-27 17:32:42 +02:00
|
|
|
) {
|
2024-04-30 14:05:01 +02:00
|
|
|
flaws = flaws.concat(
|
|
|
|
validate_password(data.password)
|
|
|
|
.map(flaw => ({"incident": ("password_" + flaw.incident), "details": flaw.details}))
|
|
|
|
);
|
2024-06-20 16:32:59 +02:00
|
|
|
password_value = data.password;
|
|
|
|
password_generated = false;
|
2024-04-30 14:05:01 +02:00
|
|
|
}
|
|
|
|
else {
|
2024-06-20 16:32:59 +02:00
|
|
|
password_value = generate_password();
|
|
|
|
password_generated = true;
|
2024-04-30 14:05:01 +02:00
|
|
|
}
|
2024-04-29 22:40:52 +02:00
|
|
|
}
|
|
|
|
|
2024-04-30 14:05:01 +02:00
|
|
|
if (flaws.length > 0) {
|
2024-04-29 22:40:52 +02:00
|
|
|
// do nothing
|
|
|
|
}
|
|
|
|
else {
|
2024-05-27 19:16:00 +02:00
|
|
|
member_object.email_use_veiled_address = data.email_use_veiled_address;
|
|
|
|
member_object.email_use_nominal_address = data.email_use_nominal_address;
|
2024-04-30 14:05:01 +02:00
|
|
|
member_object.email_redirect_to_private_address = data.email_redirect_to_private_address;
|
2024-06-20 16:32:59 +02:00
|
|
|
member_object.password_image = await password_image(password_value);
|
2024-04-30 14:05:01 +02:00
|
|
|
member_object.registered = true;
|
|
|
|
await _espe.repository.member.update(member_id, member_object);
|
2024-05-27 21:27:36 +02:00
|
|
|
signal_change();
|
|
|
|
{
|
|
|
|
const url : (null | string) = (
|
2024-05-10 19:41:19 +02:00
|
|
|
(
|
2024-05-27 21:27:36 +02:00
|
|
|
(options.notification_target_url_template === undefined)
|
|
|
|
||
|
|
|
|
(options.notification_target_url_template === null)
|
|
|
|
)
|
|
|
|
? null
|
|
|
|
: _espe.helpers.frontend_url_get(
|
|
|
|
options.notification_target_url_template,
|
|
|
|
{
|
|
|
|
"id": member_id.toFixed(0),
|
|
|
|
}
|
|
|
|
)
|
2024-04-30 14:05:01 +02:00
|
|
|
);
|
2024-06-20 16:32:59 +02:00
|
|
|
/*await*/ _espe.helpers.notify_admins(
|
|
|
|
lib_plankton.string.coin(
|
|
|
|
"{{head}} | {{core}}",
|
|
|
|
{
|
|
|
|
"head": _espe.conf.get().settings.organisation.name,
|
|
|
|
"core": lib_plankton.translate.get("email.registration.subject"),
|
|
|
|
}
|
|
|
|
),
|
|
|
|
lib_plankton.string.coin(
|
|
|
|
lib_plankton.translate.get("email.registration.body"),
|
|
|
|
{
|
|
|
|
"name_display": name_display(member_object),
|
|
|
|
"url": (url ?? "?"),
|
|
|
|
}
|
|
|
|
)
|
|
|
|
);
|
2024-04-30 14:05:01 +02:00
|
|
|
}
|
2024-06-20 16:32:59 +02:00
|
|
|
/*await*/ send_activation_email(member_object, {"password": password_generated ? password_value : null});
|
2024-04-22 10:02:34 +02:00
|
|
|
}
|
2024-04-30 14:05:01 +02:00
|
|
|
|
|
|
|
return Promise.resolve(flaws);
|
2024-04-22 10:02:34 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
|
2024-04-30 01:32:24 +02:00
|
|
|
/**
|
2024-05-20 09:52:09 +02:00
|
|
|
* ändert bestimmte Daten des Mitglied
|
2024-04-30 01:32:24 +02:00
|
|
|
*/
|
2024-04-29 22:40:52 +02:00
|
|
|
export async function modify(
|
2024-04-30 01:32:24 +02:00
|
|
|
member_id : _espe.type.member_id,
|
|
|
|
data : {
|
|
|
|
email_address_private : (null | string);
|
|
|
|
registered : boolean;
|
|
|
|
enabled : boolean;
|
|
|
|
}
|
2024-04-29 22:40:52 +02:00
|
|
|
) : Promise<void>
|
2024-04-22 10:02:34 +02:00
|
|
|
{
|
2024-04-30 01:32:24 +02:00
|
|
|
const member_object_old : _espe.type.member_object = await get(member_id);
|
|
|
|
const member_object_new : _espe.type.member_object = {
|
|
|
|
"membership_number": member_object_old.membership_number,
|
|
|
|
"name_real_value": member_object_old.name_real_value,
|
|
|
|
"name_real_index": member_object_old.name_real_index,
|
|
|
|
"email_address_private": data.email_address_private,
|
|
|
|
"registered": data.registered,
|
|
|
|
"enabled": data.enabled,
|
|
|
|
"email_use_veiled_address": member_object_old.email_use_veiled_address,
|
|
|
|
"email_use_nominal_address": member_object_old.email_use_nominal_address,
|
|
|
|
"email_redirect_to_private_address": member_object_old.email_redirect_to_private_address,
|
|
|
|
"email_allow_sending": member_object_old.email_allow_sending,
|
|
|
|
"password_image": member_object_old.password_image,
|
2024-05-20 12:20:59 +02:00
|
|
|
"password_change_last_attempt": member_object_old.password_change_last_attempt,
|
|
|
|
"password_change_token": member_object_old.password_change_token,
|
2024-04-30 01:32:24 +02:00
|
|
|
};
|
|
|
|
await _espe.repository.member.update(member_id, member_object_new);
|
2024-05-27 21:27:36 +02:00
|
|
|
signal_change();
|
|
|
|
/*await*/ send_activation_email(member_object_new);
|
2024-04-22 10:02:34 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
|
2024-06-23 11:47:28 +02:00
|
|
|
/**
|
|
|
|
*/
|
|
|
|
export async function remove(
|
|
|
|
id : _espe.type.member_id
|
|
|
|
) : Promise<void>
|
|
|
|
{
|
|
|
|
await _espe.repository.member.delete_(id);
|
|
|
|
signal_change();
|
|
|
|
}
|
|
|
|
|
|
|
|
|
2024-05-20 12:20:59 +02:00
|
|
|
/**
|
|
|
|
* bereitet eine Passwort-Rücksetzung für Mitglieder vor
|
|
|
|
*
|
|
|
|
* @todo Zwangs-Pause falls Abklingzeit noch nicht vorbei um vorzugaukeln, dass es geklappt hat?
|
|
|
|
*/
|
|
|
|
export async function password_change_initialize(
|
|
|
|
identifier : string,
|
|
|
|
url_template : string
|
|
|
|
) : Promise<void>
|
|
|
|
{
|
2024-05-27 21:27:36 +02:00
|
|
|
_espe.helpers.frontend_url_check();
|
|
|
|
const now : int = lib_plankton.base.get_current_timestamp(true);
|
|
|
|
const cooldown_time : int = _espe.conf.get().settings.password_change.cooldown_time;
|
|
|
|
const member_ids : Array<_espe.type.member_id> = await (
|
|
|
|
(await _espe.repository.member.dump())
|
|
|
|
.filter(
|
|
|
|
member_entry => (
|
|
|
|
member_entry.object.registered
|
|
|
|
&&
|
|
|
|
member_entry.object.enabled
|
|
|
|
&&
|
|
|
|
(
|
2024-05-20 12:20:59 +02:00
|
|
|
(
|
2024-05-27 21:27:36 +02:00
|
|
|
(! (member_entry.object.email_address_private === null))
|
|
|
|
&&
|
|
|
|
(member_entry.object.email_address_private === identifier)
|
2024-05-20 12:20:59 +02:00
|
|
|
)
|
2024-05-27 21:27:36 +02:00
|
|
|
||
|
|
|
|
(name_login(member_entry.object) === identifier)
|
2024-05-20 12:20:59 +02:00
|
|
|
)
|
|
|
|
)
|
2024-05-27 21:27:36 +02:00
|
|
|
)
|
|
|
|
.map(
|
|
|
|
member_entry => member_entry.id
|
|
|
|
)
|
|
|
|
);
|
|
|
|
for await (const member_id of member_ids) {
|
|
|
|
const member_object_old : _espe.type.member_object = await _espe.repository.member.read(member_id);
|
|
|
|
if (
|
|
|
|
(! (member_object_old.password_change_last_attempt === null))
|
|
|
|
&&
|
|
|
|
((now - member_object_old.password_change_last_attempt) <= cooldown_time)
|
|
|
|
) {
|
|
|
|
lib_plankton.log.notice(
|
|
|
|
"member_password_change_cooldown_not_over",
|
|
|
|
{
|
|
|
|
"member_id": member_id,
|
|
|
|
"last_attempt": member_object_old.password_change_last_attempt,
|
|
|
|
"now": now,
|
|
|
|
}
|
|
|
|
);
|
|
|
|
// do nothing
|
|
|
|
}
|
|
|
|
else {
|
|
|
|
if (member_object_old.email_address_private === null) {
|
2024-05-20 12:20:59 +02:00
|
|
|
lib_plankton.log.notice(
|
2024-05-27 21:27:36 +02:00
|
|
|
"member_password_change_impossible_due_to_missing_private_email_address",
|
2024-05-20 12:20:59 +02:00
|
|
|
{
|
|
|
|
"member_id": member_id,
|
|
|
|
}
|
|
|
|
);
|
|
|
|
// do nothing
|
|
|
|
}
|
|
|
|
else {
|
2024-05-27 21:27:36 +02:00
|
|
|
// keine echte Verifizierung, der Algorithmus ist aber der passende
|
|
|
|
const token : string = await _espe.helpers.verification_get(Math.floor(Math.random() * (1 << 24)));
|
|
|
|
const member_object_new : _espe.type.member_object = {
|
|
|
|
"membership_number": member_object_old.membership_number,
|
|
|
|
"name_real_value": member_object_old.name_real_value,
|
|
|
|
"name_real_index": member_object_old.name_real_index,
|
|
|
|
"email_address_private": member_object_old.email_address_private,
|
|
|
|
"registered": member_object_old.registered,
|
|
|
|
"enabled": member_object_old.enabled,
|
|
|
|
"email_use_veiled_address": member_object_old.email_use_veiled_address,
|
|
|
|
"email_use_nominal_address": member_object_old.email_use_nominal_address,
|
|
|
|
"email_redirect_to_private_address": member_object_old.email_redirect_to_private_address,
|
|
|
|
"email_allow_sending": member_object_old.email_allow_sending,
|
|
|
|
"password_image": member_object_old.password_image,
|
|
|
|
"password_change_last_attempt": now,
|
|
|
|
"password_change_token": token,
|
|
|
|
};
|
|
|
|
await _espe.repository.member.update(member_id, member_object_new);
|
|
|
|
// signal_change();
|
|
|
|
// do NOT wait in order to reduce information for potential attackers
|
|
|
|
const url : (null | string) = _espe.helpers.frontend_url_get(
|
|
|
|
url_template,
|
|
|
|
{
|
|
|
|
"id": member_id.toFixed(0),
|
|
|
|
"token": token,
|
|
|
|
}
|
|
|
|
);
|
|
|
|
if (url === null) {
|
2024-05-20 12:20:59 +02:00
|
|
|
// do nothing
|
|
|
|
}
|
|
|
|
else {
|
2024-05-20 14:06:54 +02:00
|
|
|
/*await*/ _espe.helpers.email_send(
|
2024-05-20 12:20:59 +02:00
|
|
|
[
|
|
|
|
member_object_old.email_address_private,
|
|
|
|
],
|
|
|
|
lib_plankton.string.coin(
|
2024-06-03 12:33:15 +02:00
|
|
|
"{{head}} | {{core}}",
|
|
|
|
{
|
|
|
|
"head": _espe.conf.get().settings.organisation.name,
|
|
|
|
"core": lib_plankton.translate.get("email.password_change.initialization.subject"),
|
|
|
|
}
|
|
|
|
),
|
|
|
|
lib_plankton.string.coin(
|
|
|
|
lib_plankton.translate.get("email.password_change.initialization.body"),
|
2024-05-20 12:20:59 +02:00
|
|
|
{
|
2024-05-20 14:06:54 +02:00
|
|
|
"name": name_display(member_object_old),
|
2024-05-27 21:27:36 +02:00
|
|
|
"url": url,
|
2024-05-20 12:20:59 +02:00
|
|
|
}
|
|
|
|
)
|
|
|
|
);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
/**
|
|
|
|
* führt eine Passwort-Rücksetzung für ein Mitglied durch
|
|
|
|
*
|
|
|
|
* @todo zeitliche Begrenzung?
|
|
|
|
*/
|
|
|
|
export async function password_change_execute(
|
|
|
|
member_id : _espe.type.member_id,
|
|
|
|
token : string,
|
|
|
|
password_new : string
|
2024-05-20 14:06:54 +02:00
|
|
|
) : Promise<Array<{incident : string; details : Record<string, any>;}>>
|
2024-05-20 12:20:59 +02:00
|
|
|
{
|
|
|
|
const member_object_old : _espe.type.member_object = await _espe.repository.member.read(member_id);
|
2024-05-27 17:32:42 +02:00
|
|
|
if (member_object_old.email_address_private === null) {
|
|
|
|
return Promise.reject(new Error("private e-mail address missing"));
|
2024-05-20 12:20:59 +02:00
|
|
|
}
|
|
|
|
else {
|
2024-05-27 17:32:42 +02:00
|
|
|
let flaws : Array<{incident : string; details : Record<string, any>;}> = [];
|
|
|
|
if (
|
|
|
|
(member_object_old.password_change_token === null)
|
|
|
|
||
|
|
|
|
(! (token === member_object_old.password_change_token))
|
|
|
|
) {
|
|
|
|
lib_plankton.log.notice(
|
|
|
|
"member_password_change_token_invalid",
|
|
|
|
{
|
|
|
|
"member_id": member_id,
|
|
|
|
"token_sent": token,
|
|
|
|
}
|
|
|
|
);
|
|
|
|
flaws.push({"incident": "token_invalid", "details": {}});
|
2024-05-20 14:06:54 +02:00
|
|
|
}
|
|
|
|
else {
|
2024-05-27 17:32:42 +02:00
|
|
|
flaws = flaws.concat(
|
|
|
|
validate_password(password_new)
|
|
|
|
.map(flaw => ({"incident": ("password_" + flaw.incident), "details": flaw.details}))
|
2024-05-20 14:06:54 +02:00
|
|
|
);
|
2024-05-27 17:32:42 +02:00
|
|
|
if (flaws.length > 0) {
|
|
|
|
// do nothing
|
|
|
|
}
|
|
|
|
else {
|
|
|
|
const member_object_new : _espe.type.member_object = {
|
|
|
|
"membership_number": member_object_old.membership_number,
|
|
|
|
"name_real_value": member_object_old.name_real_value,
|
|
|
|
"name_real_index": member_object_old.name_real_index,
|
|
|
|
"email_address_private": member_object_old.email_address_private,
|
|
|
|
"registered": member_object_old.registered,
|
|
|
|
"enabled": member_object_old.enabled,
|
|
|
|
"email_use_veiled_address": member_object_old.email_use_veiled_address,
|
|
|
|
"email_use_nominal_address": member_object_old.email_use_nominal_address,
|
|
|
|
"email_redirect_to_private_address": member_object_old.email_redirect_to_private_address,
|
|
|
|
"email_allow_sending": member_object_old.email_allow_sending,
|
|
|
|
"password_image": await password_image(password_new),
|
|
|
|
"password_change_last_attempt": member_object_old.password_change_last_attempt,
|
|
|
|
"password_change_token": null,
|
|
|
|
};
|
|
|
|
await _espe.repository.member.update(member_id, member_object_new);
|
2024-05-27 21:27:36 +02:00
|
|
|
signal_change();
|
2024-05-27 17:32:42 +02:00
|
|
|
await _espe.helpers.email_send(
|
|
|
|
[
|
|
|
|
member_object_old.email_address_private,
|
|
|
|
],
|
|
|
|
lib_plankton.string.coin(
|
2024-06-03 12:33:15 +02:00
|
|
|
"{{head}} | {{core}}",
|
|
|
|
{
|
|
|
|
"head": _espe.conf.get().settings.organisation.name,
|
|
|
|
"core": lib_plankton.translate.get("email.password_change.execution.subject"),
|
|
|
|
}
|
|
|
|
),
|
|
|
|
lib_plankton.string.coin(
|
|
|
|
lib_plankton.translate.get("email.password_change.execution.body"),
|
2024-05-27 17:32:42 +02:00
|
|
|
{
|
|
|
|
"name": name_display(member_object_old),
|
|
|
|
}
|
|
|
|
)
|
|
|
|
);
|
|
|
|
}
|
2024-05-20 14:06:54 +02:00
|
|
|
}
|
2024-05-27 17:32:42 +02:00
|
|
|
return flaws;
|
2024-05-20 12:20:59 +02:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2024-04-30 01:32:24 +02:00
|
|
|
|
2024-04-29 22:40:52 +02:00
|
|
|
/**
|
2024-04-22 17:34:41 +02:00
|
|
|
* @todo check validity (e.g. username characters)
|
2024-04-29 22:40:52 +02:00
|
|
|
*/
|
2024-08-18 13:54:58 +02:00
|
|
|
export async function export_authelia_user_data(
|
2024-05-13 10:08:43 +02:00
|
|
|
options : {
|
|
|
|
custom_data ?: (null | Array<_espe.type.member_object>);
|
|
|
|
} = {}
|
2024-08-18 13:54:58 +02:00
|
|
|
) : Promise<any>
|
2024-04-22 10:02:34 +02:00
|
|
|
{
|
2024-05-13 10:08:43 +02:00
|
|
|
options = Object.assign(
|
|
|
|
{
|
|
|
|
"custom_data": null,
|
|
|
|
},
|
|
|
|
options
|
|
|
|
);
|
|
|
|
|
2024-05-27 17:32:42 +02:00
|
|
|
type type_entry = {
|
|
|
|
disabled : boolean;
|
|
|
|
displayname : string;
|
|
|
|
email : string;
|
|
|
|
groups : Array<string>;
|
|
|
|
password : string;
|
|
|
|
};
|
2024-04-22 10:02:34 +02:00
|
|
|
return lib_plankton.call.convey(
|
2024-05-13 10:08:43 +02:00
|
|
|
(
|
2024-05-27 17:32:42 +02:00
|
|
|
(
|
|
|
|
(options.custom_data !== undefined)
|
|
|
|
&&
|
|
|
|
(options.custom_data !== null)
|
|
|
|
)
|
2024-05-13 10:08:43 +02:00
|
|
|
? (options.custom_data.map((member_object, index) => ({"id": index, "object": member_object})))
|
|
|
|
: await dump()
|
|
|
|
),
|
2024-04-22 10:02:34 +02:00
|
|
|
[
|
2024-05-27 17:32:42 +02:00
|
|
|
(x : Array<any>) => x.map(
|
2024-04-22 10:02:34 +02:00
|
|
|
entry => Object.assign(
|
|
|
|
entry,
|
2024-04-29 22:40:52 +02:00
|
|
|
{"email_address": email_address(entry.object)}
|
2024-04-22 10:02:34 +02:00
|
|
|
)
|
|
|
|
),
|
2024-05-27 17:32:42 +02:00
|
|
|
(x : Array<any>) => x.filter(
|
2024-04-22 10:02:34 +02:00
|
|
|
entry => (
|
2024-04-29 22:40:52 +02:00
|
|
|
entry.object.registered
|
2024-04-22 10:02:34 +02:00
|
|
|
&&
|
|
|
|
(
|
2024-04-29 22:40:52 +02:00
|
|
|
(entry.object.password_image !== null)
|
2024-04-22 10:02:34 +02:00
|
|
|
&&
|
2024-04-29 22:40:52 +02:00
|
|
|
(entry.object.password_image !== "")
|
2024-04-22 10:02:34 +02:00
|
|
|
)
|
|
|
|
&&
|
|
|
|
(entry.email_address !== null)
|
|
|
|
)
|
|
|
|
),
|
2024-05-27 17:32:42 +02:00
|
|
|
(x : Array<any>) => x.map(
|
2024-04-22 10:02:34 +02:00
|
|
|
entry => ([
|
2024-04-29 22:40:52 +02:00
|
|
|
name_login(entry.object),
|
2024-04-22 10:02:34 +02:00
|
|
|
{
|
2024-04-29 22:40:52 +02:00
|
|
|
"disabled": (! entry.object.enabled),
|
|
|
|
"displayname": name_display(entry.object),
|
2024-04-22 10:02:34 +02:00
|
|
|
"email": entry.email_address,
|
|
|
|
"groups": [],
|
2024-04-29 22:40:52 +02:00
|
|
|
"password": entry.object.password_image,
|
2024-04-22 10:02:34 +02:00
|
|
|
}
|
|
|
|
])
|
|
|
|
),
|
|
|
|
Object.fromEntries,
|
2024-05-27 17:32:42 +02:00
|
|
|
(x : Record<string, type_entry>) => ({"users": x}),
|
2024-04-22 10:02:34 +02:00
|
|
|
]
|
|
|
|
);
|
|
|
|
}
|
|
|
|
|
2024-08-18 13:54:58 +02:00
|
|
|
|
|
|
|
/**
|
|
|
|
*/
|
|
|
|
export async function export_authelia_user_file(
|
|
|
|
options : {
|
|
|
|
custom_data ?: (null | Array<_espe.type.member_object>);
|
|
|
|
} = {}
|
|
|
|
) : Promise<string>
|
|
|
|
{
|
|
|
|
options = Object.assign(
|
|
|
|
{
|
|
|
|
"custom_data": null,
|
|
|
|
},
|
|
|
|
options
|
|
|
|
);
|
|
|
|
|
|
|
|
const nm_yaml = require("yaml");
|
|
|
|
return nm_yaml.stringify(await export_authelia_user_data(options));
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
/**
|
|
|
|
*/
|
|
|
|
export async function output_authelia_file(
|
|
|
|
output_parameters : {
|
|
|
|
path : string;
|
|
|
|
}
|
|
|
|
) : Promise<void>
|
|
|
|
{
|
|
|
|
await lib_plankton.file.write(
|
|
|
|
output_parameters.path,
|
|
|
|
await _espe.service.member.export_authelia_user_file()
|
|
|
|
);
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
/**
|
|
|
|
*/
|
|
|
|
export async function output_http(
|
|
|
|
output_parameters : {
|
|
|
|
scheme : ("http" | "https");
|
|
|
|
host : string;
|
|
|
|
path : string;
|
|
|
|
method : ("get" | "post" | "put" | "patch" | "delete" | "head" | "options");
|
|
|
|
query : (null | string);
|
|
|
|
headers : Record<string,string>;
|
|
|
|
}
|
|
|
|
) : Promise<void>
|
|
|
|
{
|
|
|
|
const http_request : lib_plankton.http.type_request = {
|
|
|
|
"scheme": output_parameters.scheme,
|
|
|
|
"host": output_parameters.host,
|
|
|
|
"path": output_parameters.path,
|
|
|
|
"version": "HTTP/1.1",
|
|
|
|
"method": (
|
|
|
|
(
|
|
|
|
{
|
|
|
|
"get": lib_plankton.http.enum_method.get,
|
|
|
|
"post": lib_plankton.http.enum_method.post,
|
|
|
|
"put": lib_plankton.http.enum_method.put,
|
|
|
|
"patch": lib_plankton.http.enum_method.patch,
|
|
|
|
"delete": lib_plankton.http.enum_method.delete,
|
|
|
|
"head": lib_plankton.http.enum_method.head,
|
|
|
|
"options": lib_plankton.http.enum_method.options,
|
|
|
|
}[output_parameters.method]
|
|
|
|
)
|
|
|
|
??
|
|
|
|
lib_plankton.http.enum_method.post
|
|
|
|
),
|
|
|
|
"query": output_parameters.query,
|
|
|
|
"headers": output_parameters.headers,
|
|
|
|
"body": lib_plankton.json.encode(await _espe.service.member.dump()),
|
|
|
|
};
|
|
|
|
const http_response : lib_plankton.http.type_response = await lib_plankton.http.call(
|
|
|
|
http_request
|
|
|
|
);
|
|
|
|
if (! ((http_response.status_code >= 200) && (http_response.status_code < 400))) {
|
|
|
|
lib_plankton.log.warning(
|
|
|
|
"output_http_failed",
|
|
|
|
{
|
|
|
|
"http_request": http_request,
|
|
|
|
"http_response_status_code": http_response.status_code,
|
|
|
|
}
|
|
|
|
);
|
|
|
|
}
|
|
|
|
else {
|
|
|
|
// do nothing
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
/**
|
|
|
|
*/
|
2024-08-22 08:04:45 +02:00
|
|
|
export async function output_arc(
|
2024-08-18 13:54:58 +02:00
|
|
|
output_parameters : {
|
|
|
|
http_scheme : ("http" | "https");
|
|
|
|
http_host : string;
|
2024-08-22 07:46:06 +02:00
|
|
|
http_port : int;
|
2024-08-18 13:54:58 +02:00
|
|
|
hash_salt : string;
|
|
|
|
}
|
|
|
|
) : Promise<void>
|
|
|
|
{
|
|
|
|
const timestamp : float = lib_plankton.base.get_current_timestamp();
|
|
|
|
const auth : string = lib_plankton.sha256.get(
|
|
|
|
timestamp.toFixed(0)
|
|
|
|
+
|
|
|
|
output_parameters.hash_salt
|
|
|
|
);
|
|
|
|
const http_request : lib_plankton.http.type_request = {
|
|
|
|
"scheme": output_parameters.http_scheme,
|
2024-08-22 07:46:06 +02:00
|
|
|
"host": lib_plankton.string.coin(
|
|
|
|
"{{host}}:{{port}}",
|
|
|
|
{
|
|
|
|
"host": output_parameters.http_host,
|
|
|
|
"port": output_parameters.http_port.toFixed(0),
|
|
|
|
}
|
|
|
|
),
|
2024-08-18 13:54:58 +02:00
|
|
|
"path": "/users/set",
|
|
|
|
"version": "HTTP/1.1",
|
|
|
|
"method": lib_plankton.http.enum_method.put,
|
|
|
|
"query": lib_plankton.string.coin(
|
|
|
|
"?timestamp={{timestamp}}&auth={{auth}}",
|
|
|
|
{
|
|
|
|
"timestamp": timestamp.toFixed(0),
|
|
|
|
"auth": auth,
|
|
|
|
}
|
|
|
|
),
|
|
|
|
"headers": {
|
|
|
|
"Content-Type": "application/json",
|
|
|
|
},
|
2024-08-21 15:18:40 +02:00
|
|
|
// @ts-ignore
|
|
|
|
"body": Buffer.from(
|
|
|
|
lib_plankton.json.encode(
|
|
|
|
(await _espe.service.member.export_authelia_user_data())
|
|
|
|
),
|
|
|
|
"utf8"
|
|
|
|
),
|
2024-08-18 13:54:58 +02:00
|
|
|
};
|
|
|
|
const http_response : lib_plankton.http.type_response = await lib_plankton.http.call(
|
|
|
|
http_request
|
|
|
|
);
|
|
|
|
if (http_response.status_code !== 200) {
|
|
|
|
lib_plankton.log.warning(
|
2024-08-22 08:04:45 +02:00
|
|
|
"output_arcback_failed",
|
2024-08-18 13:54:58 +02:00
|
|
|
{
|
|
|
|
"http_response_status_code": http_response.status_code,
|
|
|
|
}
|
|
|
|
);
|
|
|
|
}
|
|
|
|
else {
|
|
|
|
// do nothing
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2024-04-22 10:02:34 +02:00
|
|
|
}
|
|
|
|
|