2025-03-31 20:24:43 +00: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/>.
|
|
|
|
*/
|
|
|
|
|
|
|
|
namespace _espe.service.invite
|
|
|
|
{
|
|
|
|
|
2025-04-12 10:20:58 +00:00
|
|
|
/**
|
|
|
|
*/
|
|
|
|
export function list(
|
|
|
|
) : Promise<
|
|
|
|
Array<
|
|
|
|
{
|
|
|
|
id : _espe.type.invite_id;
|
|
|
|
key : _espe.type.invite_key;
|
|
|
|
expiry : (null | int);
|
|
|
|
name_value : string;
|
|
|
|
}
|
|
|
|
>
|
|
|
|
>
|
|
|
|
{
|
|
|
|
return (
|
|
|
|
_espe.repository.invite.dump()
|
|
|
|
.then(
|
|
|
|
entries => Promise.resolve(
|
|
|
|
entries.map(
|
|
|
|
entry => ({
|
|
|
|
"id": entry.id,
|
|
|
|
"key": entry.object.key,
|
|
|
|
"expiry": entry.object.expiry,
|
|
|
|
"name_value": entry.object.name_value
|
|
|
|
})
|
|
|
|
)
|
|
|
|
)
|
|
|
|
)
|
|
|
|
);
|
|
|
|
}
|
|
|
|
|
|
|
|
|
2025-03-31 20:24:43 +00:00
|
|
|
/**
|
|
|
|
*/
|
2025-04-01 04:20:59 +00:00
|
|
|
export async function create(
|
|
|
|
{
|
2025-04-12 10:20:58 +00:00
|
|
|
"membership_number_changeable": membership_number_changeable,
|
2025-04-01 04:20:59 +00:00
|
|
|
"membership_number_value": membership_number_value,
|
2025-04-12 10:20:58 +00:00
|
|
|
"name_changeable": name_changeable,
|
2025-04-01 04:20:59 +00:00
|
|
|
"name_value": name_value,
|
2025-04-12 10:20:58 +00:00
|
|
|
"email_address_changeable": email_address_changeable,
|
2025-04-01 04:20:59 +00:00
|
|
|
"email_address_value": email_address_value,
|
2025-04-12 10:20:58 +00:00
|
|
|
"groups_changeable": groups_changeable,
|
2025-04-01 04:20:59 +00:00
|
|
|
"groups_value": groups_value,
|
|
|
|
} : {
|
2025-04-12 10:20:58 +00:00
|
|
|
membership_number_changeable : boolean;
|
2025-04-01 04:20:59 +00:00
|
|
|
membership_number_value : (null | string);
|
2025-04-12 10:20:58 +00:00
|
|
|
name_changeable : boolean;
|
2025-04-01 04:20:59 +00:00
|
|
|
name_value : string;
|
2025-04-12 10:20:58 +00:00
|
|
|
email_address_changeable : boolean;
|
2025-04-01 04:20:59 +00:00
|
|
|
email_address_value : (null | string);
|
2025-04-12 10:20:58 +00:00
|
|
|
groups_changeable : boolean;
|
2025-04-01 04:20:59 +00:00
|
|
|
groups_value : Array<string>;
|
|
|
|
},
|
|
|
|
{
|
|
|
|
"expiry": expiry = -1,
|
|
|
|
} : {
|
|
|
|
expiry ?: (null | int);
|
|
|
|
} = {
|
|
|
|
}
|
2025-03-31 20:24:43 +00:00
|
|
|
) : Promise<{id : _espe.type.invite_id; key : _espe.type.invite_key}>
|
|
|
|
{
|
2025-04-01 04:20:59 +00:00
|
|
|
/**
|
|
|
|
* @todo outsource to conf
|
|
|
|
*/
|
|
|
|
const default_lifetime : int = (60 * 60 * 24 * 7 * 2);
|
|
|
|
/**
|
|
|
|
* @todo proper salt
|
|
|
|
*/
|
|
|
|
const invite_key : _espe.type.invite_key = lib_plankton.sha256.get(
|
|
|
|
(
|
|
|
|
name_value
|
|
|
|
+
|
|
|
|
"/"
|
|
|
|
+
|
2025-04-02 21:01:11 +00:00
|
|
|
lib_plankton.base.get_current_timestamp(true).toFixed(0)
|
2025-04-01 04:20:59 +00:00
|
|
|
),
|
|
|
|
"secret"
|
|
|
|
);
|
|
|
|
const invite_object : _espe.type.invite_object = {
|
|
|
|
"key": invite_key,
|
|
|
|
"expiry": (
|
|
|
|
((expiry !== null) && (expiry < 0))
|
|
|
|
?
|
2025-04-02 21:01:11 +00:00
|
|
|
(lib_plankton.base.get_current_timestamp(true) + default_lifetime)
|
2025-04-01 04:20:59 +00:00
|
|
|
:
|
|
|
|
expiry
|
|
|
|
),
|
2025-04-12 10:20:58 +00:00
|
|
|
"membership_number_changeable": membership_number_changeable,
|
2025-04-01 04:20:59 +00:00
|
|
|
"membership_number_value": membership_number_value,
|
2025-04-12 10:20:58 +00:00
|
|
|
"name_changeable": name_changeable,
|
2025-04-01 04:20:59 +00:00
|
|
|
"name_value": name_value,
|
2025-04-12 10:20:58 +00:00
|
|
|
"email_address_changeable": email_address_changeable,
|
2025-04-01 04:20:59 +00:00
|
|
|
"email_address_value": email_address_value,
|
2025-04-12 10:20:58 +00:00
|
|
|
"groups_changeable": groups_changeable,
|
2025-04-01 04:20:59 +00:00
|
|
|
"groups_value": groups_value,
|
|
|
|
};
|
|
|
|
const invite_id : _espe.type.invite_id = await _espe.repository.invite.create(invite_object);
|
|
|
|
return {
|
|
|
|
"id": invite_id,
|
|
|
|
"key": invite_key,
|
|
|
|
};
|
2025-03-31 20:24:43 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
/**
|
2025-04-02 21:01:11 +00:00
|
|
|
*/
|
|
|
|
function get(
|
|
|
|
key : _espe.type.invite_key
|
|
|
|
) : Promise<_espe.type.invite_object>
|
|
|
|
{
|
|
|
|
return (
|
|
|
|
_espe.repository.invite.identify(key)
|
|
|
|
.then(
|
|
|
|
(id) => _espe.repository.invite.read(id)
|
|
|
|
)
|
|
|
|
);
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
/**
|
2025-03-31 20:24:43 +00:00
|
|
|
*/
|
2025-04-01 04:20:59 +00:00
|
|
|
export async function examine(
|
2025-03-31 20:24:43 +00:00
|
|
|
key : _espe.type.invite_key
|
2025-04-01 04:20:59 +00:00
|
|
|
) : Promise<_espe.type.invite_object>
|
2025-03-31 20:24:43 +00:00
|
|
|
{
|
2025-04-02 21:01:11 +00:00
|
|
|
let invite_object : (null | _espe.type.invite_object);
|
|
|
|
try {
|
2025-04-03 12:18:01 +00:00
|
|
|
invite_object = await get(key);
|
2025-04-02 21:01:11 +00:00
|
|
|
}
|
|
|
|
catch (error) {
|
|
|
|
invite_object = null;
|
|
|
|
}
|
|
|
|
if (invite_object === null) {
|
|
|
|
return Promise.reject(new Error("not found"))
|
|
|
|
}
|
|
|
|
else {
|
|
|
|
const now : int = lib_plankton.base.get_current_timestamp(true);
|
2025-04-03 12:18:01 +00:00
|
|
|
if ((invite_object.expiry !== null) && (invite_object.expiry < now)) {
|
2025-04-02 21:01:11 +00:00
|
|
|
return Promise.reject(new Error("expired"));
|
|
|
|
}
|
|
|
|
else {
|
|
|
|
return Promise.resolve(invite_object);
|
|
|
|
}
|
|
|
|
}
|
2025-03-31 20:24:43 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
/**
|
2025-04-01 04:20:59 +00:00
|
|
|
* @todo heed expiry
|
|
|
|
* @todo password?
|
2025-03-31 20:24:43 +00:00
|
|
|
*/
|
2025-04-01 04:20:59 +00:00
|
|
|
export async function accept(
|
2025-03-31 20:24:43 +00:00
|
|
|
key : _espe.type.invite_key,
|
|
|
|
membership_number_value : (null | string),
|
|
|
|
name_value : (null | string),
|
2025-04-01 04:20:59 +00:00
|
|
|
email_address_value : (null | string),
|
|
|
|
groups_value : Array<string>
|
2025-03-31 20:24:43 +00:00
|
|
|
) : Promise<void>
|
|
|
|
{
|
2025-04-01 04:20:59 +00:00
|
|
|
const invite_id : _espe.type.invite_id = await _espe.repository.invite.identify(key);
|
|
|
|
const invite_object : _espe.type.invite_object = await _espe.repository.invite.read(invite_id);
|
2025-04-03 12:18:01 +00:00
|
|
|
const now : int = lib_plankton.base.get_current_timestamp(true);
|
|
|
|
if ((invite_object.expiry !== null) && (invite_object.expiry < now)) {
|
|
|
|
return Promise.reject(new Error("expired"));
|
|
|
|
}
|
|
|
|
else {
|
|
|
|
const member_id : _espe.type.member_id = await _espe.service.member.project(
|
|
|
|
{
|
|
|
|
"membership_number": (
|
2025-04-12 10:20:58 +00:00
|
|
|
invite_object.membership_number_changeable
|
2025-04-03 12:18:01 +00:00
|
|
|
?
|
|
|
|
membership_number_value
|
|
|
|
:
|
|
|
|
invite_object.membership_number_value
|
|
|
|
),
|
|
|
|
"name_real_value": (
|
|
|
|
(
|
2025-04-12 10:20:58 +00:00
|
|
|
invite_object.name_changeable
|
2025-04-03 12:18:01 +00:00
|
|
|
&&
|
|
|
|
(name_value !== null)
|
|
|
|
)
|
|
|
|
?
|
|
|
|
name_value
|
|
|
|
:
|
|
|
|
invite_object.name_value
|
|
|
|
),
|
|
|
|
"email_address_private": (
|
|
|
|
(
|
2025-04-12 10:20:58 +00:00
|
|
|
invite_object.email_address_changeable
|
2025-04-03 12:18:01 +00:00
|
|
|
&&
|
|
|
|
(email_address_value !== null)
|
|
|
|
)
|
|
|
|
?
|
|
|
|
email_address_value
|
|
|
|
:
|
|
|
|
invite_object.email_address_value
|
|
|
|
),
|
|
|
|
"groups": (
|
2025-04-12 10:20:58 +00:00
|
|
|
invite_object.groups_changeable
|
2025-04-03 12:18:01 +00:00
|
|
|
?
|
|
|
|
groups_value
|
|
|
|
:
|
|
|
|
invite_object.groups_value
|
|
|
|
),
|
|
|
|
}
|
|
|
|
);
|
|
|
|
await _espe.repository.invite.delete_(invite_id);
|
|
|
|
}
|
2025-03-31 20:24:43 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
}
|