From 362eb0da3a226132da016072dc1e4c6c779bfb32 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Christian=20Fra=C3=9F?= Date: Mon, 29 Apr 2024 22:40:52 +0200 Subject: [PATCH] [mod] api --- source/api/actions/member_get.ts | 67 --- source/api/actions/member_info.ts | 106 +++++ .../{member_create.ts => member_project.ts} | 38 +- source/api/actions/member_register.ts | 110 +++-- source/api/actions/member_summon.ts | 35 ++ .../actions/member_urge_for_registration.ts | 50 --- source/api/base.ts | 5 +- source/api/functions.ts | 14 +- source/database.ts | 2 +- source/main.ts | 2 + source/repositories/member.ts | 34 +- source/repositories/name_index.ts | 12 +- source/services/member.ts | 389 +++++++++++------- source/{types/member.ts => types.ts} | 8 +- tools/makefile | 12 +- 15 files changed, 505 insertions(+), 379 deletions(-) delete mode 100644 source/api/actions/member_get.ts create mode 100644 source/api/actions/member_info.ts rename source/api/actions/{member_create.ts => member_project.ts} (54%) create mode 100644 source/api/actions/member_summon.ts delete mode 100644 source/api/actions/member_urge_for_registration.ts rename source/{types/member.ts => types.ts} (77%) diff --git a/source/api/actions/member_get.ts b/source/api/actions/member_get.ts deleted file mode 100644 index 33f08d8..0000000 --- a/source/api/actions/member_get.ts +++ /dev/null @@ -1,67 +0,0 @@ -namespace _espe.api -{ - - /** - * @todo types - * @todo restriction - */ - export function register_member_get( - rest_subject : lib_plankton.rest.type_rest - ) : void - { - lib_plankton.rest.register< - int, - ( - null - | - { - name_real : string; - name_login : string; - email_address_numerical_value : string; - email_address_namely_value : string; - } - ) - >( - rest_subject, - lib_plankton.http.enum_method.get, - "/member/get/:id", - { - "description": "gibt Angaben über ein Mitglied aus, die für die Registrierung verwendet werden dürfen", - "query_parameters": [ - { - "name": "key", - "required": true, - "description": "Zugriffs-Schlüssel", - }, - ], - "restriction": restriction_none, - "execution": async ({"path_parameters": path_parameters, "query_parameters": query_parameters, "input": input}) => { - const key : string = query_parameters["key"]; - const member_id : _espe.service.member.type_id = parseInt(path_parameters["id"]); - const member_value : _espe.service.member.type_value = await _espe.service.member.get(member_id); - - if (member_value.registered) { - return Promise.resolve({ - "status_code": 409, - "data": /*"bereits registriert"*/null, - }); - } - else { - return Promise.resolve({ - "status_code": 200, - "data": { - "name_real": member_value.name_real_value, - "name_login": _espe.service.member.derive_login_name(member_value), - // TODO - "email_address_numerical_value": _espe.service.member.derive_email_address_numerical(member_value), - // TODO - "email_address_namely_value": _espe.service.member.derive_email_address_namely(member_value), - }, - }); - } - }, - } - ) - } - -} diff --git a/source/api/actions/member_info.ts b/source/api/actions/member_info.ts new file mode 100644 index 0000000..7c0fad1 --- /dev/null +++ b/source/api/actions/member_info.ts @@ -0,0 +1,106 @@ +namespace _espe.api +{ + + /** + * @todo zeitliche Begrenzung? + */ + export function register_member_info( + rest_subject : lib_plankton.rest.type_rest + ) : void + { + lib_plankton.rest.register< + int, + ( + null + | + { + name_real_value : string; + name_real_index : int; + name_login : string; + email_address_veiled : string; + email_address_nominal : string; + } + ) + >( + rest_subject, + lib_plankton.http.enum_method.get, + "/member/info/:id", + { + "description": "gibt Angaben über ein Mitglied aus, die für die Registrierung verwendet werden dürfen", + "input_schema": () => ({ + "type": "number", + "nullable": false, + }), + "output_schema": () => ({ + "type": "object", + "nullable": false, + "additionalProperties": false, + "properties": { + "name_real_value": { + "type": "string", + "nullable": false, + }, + "name_real_index": { + "type": "number", + "nullable": false, + }, + "name_login": { + "type": "string", + "nullable": false, + }, + "email_address_veiled": { + "type": "string", + "nullable": false, + }, + "email_address_nominal": { + "type": "string", + "nullable": false, + }, + }, + "required": [ + "name_real_value", + "name_real_index", + "name_login", + "email_address_veiled", + "email_address_nominal", + ] + }), + "query_parameters": [ + { + "name": "key", + "required": true, + "description": "Zugriffs-Schlüssel", + }, + ], + "restriction": restriction_verification( + stuff => parseInt(stuff.path_parameters["id"]), + stuff => stuff.query_parameters["key"] + ), + "execution": async ({"path_parameters": path_parameters, "input": input}) => { + const member_id : _espe.type.member_id = parseInt(path_parameters["id"]); + const data : ( + null + | + { + name_real_value : string; + name_real_index : int; + name_login : string; + email_address_veiled : string; + email_address_nominal : string; + } + ) = await _espe.service.member.info(member_id); + + return Promise.resolve({ + "status_code": ( + (data === null) + ? 409 + : 200 + ), + "data": data + }); + }, + } + ) + } + +} diff --git a/source/api/actions/member_create.ts b/source/api/actions/member_project.ts similarity index 54% rename from source/api/actions/member_create.ts rename to source/api/actions/member_project.ts index 9dffde1..d5758b6 100644 --- a/source/api/actions/member_create.ts +++ b/source/api/actions/member_project.ts @@ -3,17 +3,21 @@ namespace _espe.api /** */ - export function register_member_create( + export function register_member_project( rest_subject : lib_plankton.rest.type_rest ) : void { lib_plankton.rest.register< - _espe.service.member.type_value, - _espe.service.member.type_id + { + membership_number : string; + name_real_value : string; + email_address_private : (null | string); + }, + _espe.type.member_id >( rest_subject, lib_plankton.http.enum_method.post, - "/member/create", + "/member/project", { "description": "erstellt ein neues Mitglied und gibt die erzeugte ID aus", "input_schema": () => ({ @@ -29,7 +33,7 @@ namespace _espe.api "type": "string", "nullable": false, }, - "email_address_private_value": { + "email_address_private": { "type": "string", "nullable": true, }, @@ -37,6 +41,7 @@ namespace _espe.api "required": [ "membership_number", "name_real_value", + "email_address_private", ] }), "output_schema": () => ({ @@ -45,22 +50,13 @@ namespace _espe.api }), "restriction": restriction_logged_in, "execution": async ({"input": input}) => { - const member_value : _espe.service.member.type_value = { - "membership_number": input.membership_number, - "name_real_value": input.name_real_value, - "name_real_extension": null, - "email_address_private_value": input.email_address_private_value, - "enabled": false, - "name_display": null, - "name_login": null, - "password_image": null, - "email_address_numberbased_use": false, - "email_address_namebased_use": false, - "email_redirect_to_private": false, - "salutation": null, - "registered": false, - }; - const member_id : _espe.service.member.type_id = await _espe.service.member.add(member_value); + const member_id : _espe.type.member_id = await _espe.service.member.project( + { + "membership_number": input.membership_number, + "name_real_value": input.name_real_value, + "email_address_private": input.email_address_private, + } + ); return Promise.resolve({ "status_code": 201, "data": member_id diff --git a/source/api/actions/member_register.ts b/source/api/actions/member_register.ts index 719be0d..a03b1d8 100644 --- a/source/api/actions/member_register.ts +++ b/source/api/actions/member_register.ts @@ -2,7 +2,7 @@ namespace _espe.api { /** - * @todo types + * @todo zeitliche Begrenzung? */ export function register_member_register( rest_subject : lib_plankton.rest.type_rest @@ -10,12 +10,10 @@ namespace _espe.api { lib_plankton.rest.register< { - name_login : string; - name_display : string; - salutation : string; - email_mode : ("none" | "number" | "number_and_name"); - email_redirect : boolean; - password : string; + email_use_veiled_address : boolean; + email_use_nominal_address : boolean; + email_redirect_to_private_address : boolean; + password : (null | string); }, null >( @@ -24,52 +22,74 @@ namespace _espe.api "/member/register/:id", { "description": "nimmt zusätzliche Angaben eines Mitglieds entgegen", + "input_schema": () => ({ + "type": "object", + "nullable": false, + "additionalProperties": false, + "properties": { + "email_use_veiled_address": { + "type": "boolean", + "nullable": false, + }, + "email_use_nominal_address": { + "type": "boolean", + "nullable": false, + }, + "email_redirect_to_private_address": { + "type": "boolean", + "nullable": false, + }, + "password": { + "type": "string", + "nullable": true, + }, + }, + "required": [ + "email_use_veiled_address", + "email_use_nominal_address", + "email_redirect_to_private_address", + "password", + ] + }), + "output_schema": () => ({ + "nullable": true, + }), "query_parameters": [ { - "name": "verification", + "name": "key", "required": true, - "description": "Prüfwert", + "description": "Zugriffs-Schlüssel", }, ], - "restriction": restriction_verification(stuff => parseInt(stuff.path_parameters["id"])), - "execution": async ({"path_parameters": path_parameters, "query_parameters": query_parameters, "input": input}) => { - const id : _espe.service.member.type_id = parseInt(path_parameters["id"]); - let successful : boolean = false; - try { - await _espe.service.member.register( - id, + "restriction": restriction_verification( + stuff => parseInt(stuff.path_parameters["id"]), + stuff => stuff.query_parameters["key"] + ), + "execution": async ({"path_parameters": path_parameters, "input": input}) => { + const member_id : _espe.type.member_id = parseInt(path_parameters["id"]); + return ( + _espe.service.member.register( + member_id, { - "name_login": input.name_login, - "name_display": input.name_display, - "salutation": input.salutation, - "email_address_numberbased_use": ["number", "number_and_name"].includes(input.email_mode), - "email_address_namebased_use": ["number_and_name"].includes(input.email_mode), - "email_redirect_to_private": input.email_redirect, + "email_use_veiled_address": input.email_use_veiled_address, + "email_use_nominal_address": input.email_use_nominal_address, + "email_redirect_to_private_address": input.email_redirect_to_private_address, "password": input.password, } - ); - successful = true; - } - catch (error) { - successful = false; - } - if (! successful) { - return Promise.resolve({ - "status_code": 409, - "data": "bereits registriert", - }); - } - else { - await _espe.helpers.email_send( - _espe.conf.get().admins.map(admin => admin.email_address).filter(x => (x !== null)), - "Eingegangene Registrierung", - ("Member-ID: " + id.toFixed(0)) - ); - return Promise.resolve({ - "status_code": 200, - "data": null, - }); - } + ) + .then( + () => Promise.resolve({ + "status_code": 200, + "data": null, + }) + ) + .catch( + () => Promise.resolve({ + "status_code": 409, + "data": /*"bereits registriert"*/null, + }) + ) + ); }, } ) diff --git a/source/api/actions/member_summon.ts b/source/api/actions/member_summon.ts new file mode 100644 index 0000000..b2544a8 --- /dev/null +++ b/source/api/actions/member_summon.ts @@ -0,0 +1,35 @@ +namespace _espe.api +{ + + /** + */ + export function register_member_summon( + rest_subject : lib_plankton.rest.type_rest + ) : void + { + lib_plankton.rest.register< + { + url_template : string; + }, + null + >( + rest_subject, + lib_plankton.http.enum_method.post, + "/member/summon/:id", + { + "description": "sendet an ein Mitglied eine E-Mail mit Aufforderung zur Registrierung", + "restriction": restriction_logged_in, + "execution": async ({"path_parameters": path_parameters, "input": input}) => { + const member_id : _espe.type.member_id = parseInt(path_parameters["id"]); + await _espe.service.member.summon(member_id, input.url_template); + + return Promise.resolve({ + "status_code": 200, + "data": null, + }); + } + } + ); + } + +} diff --git a/source/api/actions/member_urge_for_registration.ts b/source/api/actions/member_urge_for_registration.ts deleted file mode 100644 index aa1610a..0000000 --- a/source/api/actions/member_urge_for_registration.ts +++ /dev/null @@ -1,50 +0,0 @@ -namespace _espe.api -{ - - /** - */ - export function register_member_urge_for_registration( - rest_subject : lib_plankton.rest.type_rest - ) : void - { - lib_plankton.rest.register<{id : int; url : string;}, null>( - rest_subject, - lib_plankton.http.enum_method.post, - "/member/urge_for_registration", - { - "description": "sendet an ein Mitglied eine E-Mail mit Aufforderung zur Registrierung", - "restriction": restriction_logged_in, - "execution": async ({"input": input}) => { - const member_id : _espe.service.member.type_id = input.id; - const member_value : _espe.service.member.type_value = await _espe.service.member.get(member_id); - const verification : string = await _espe.helpers.verification_get(member_id); - - await _espe.helpers.email_send( - [ - member_value.email_address_private_value, - ], - _espe.conf.get().settings.registration_email.subject, - lib_plankton.string.coin( - _espe.conf.get().settings.registration_email.body, - { - "name": member_value.name_real_value, - "url": lib_plankton.string.coin( - input.url, - { - "verification": verification, - } - ), - } - ) - ); - - return Promise.resolve({ - "status_code": 200, - "data": null, - }); - } - } - ); - } - -} diff --git a/source/api/base.ts b/source/api/base.ts index ca1ee14..bae66d9 100644 --- a/source/api/base.ts +++ b/source/api/base.ts @@ -34,13 +34,14 @@ namespace _espe.api /** */ export function restriction_verification( - extract_data : ((stuff) => any) + extract_data : ((stuff) => any), + extract_verification : ((stuff) => string) ) : lib_plankton.rest.type_restriction { return ( (stuff) => _espe.helpers.verification_check( extract_data(stuff), - stuff.query_parameters["verification"] + extract_verification(stuff) ) ); } diff --git a/source/api/functions.ts b/source/api/functions.ts index 525c09a..06f44a9 100644 --- a/source/api/functions.ts +++ b/source/api/functions.ts @@ -24,7 +24,7 @@ namespace _espe.api _espe.api.register_session_begin(rest_subject); _espe.api.register_session_end(rest_subject); } - _espe.api.register_email(rest_subject); + // _espe.api.register_email(rest_subject); // verification { // _espe.api.register_verification_get(rest_subject); @@ -32,14 +32,14 @@ namespace _espe.api } // member { - _espe.api.register_member_list(rest_subject); - _espe.api.register_member_read(rest_subject); - _espe.api.register_member_create(rest_subject); + _espe.api.register_member_project(rest_subject); + _espe.api.register_member_summon(rest_subject); + _espe.api.register_member_info(rest_subject); + _espe.api.register_member_register(rest_subject); + // _espe.api.register_member_list(rest_subject); + // _espe.api.register_member_read(rest_subject); // _espe.api.register_member_update(rest_subject); // _espe.api.register_member_delete(rest_subject); - _espe.api.register_member_get(rest_subject); - _espe.api.register_member_register(rest_subject); - _espe.api.register_member_urge_for_registration(rest_subject); } diff --git a/source/database.ts b/source/database.ts index 7135fd7..db1de77 100644 --- a/source/database.ts +++ b/source/database.ts @@ -4,7 +4,7 @@ namespace _espe.database /** */ const _compatible_revisions : Array = [ - "r1", + "r2", ]; diff --git a/source/main.ts b/source/main.ts index 2e6bf24..106c8fd 100644 --- a/source/main.ts +++ b/source/main.ts @@ -159,7 +159,9 @@ async function main( break; } case "api-doc": { + lib_plankton.log.conf_push([]); const rest_subject : lib_plankton.rest.type_rest = _espe.api.make(); + lib_plankton.log.conf_pop(); process.stdout.write( JSON.stringify( lib_plankton.rest.to_oas(rest_subject), diff --git a/source/repositories/member.ts b/source/repositories/member.ts index bdefafb..187479d 100644 --- a/source/repositories/member.ts +++ b/source/repositories/member.ts @@ -7,7 +7,7 @@ namespace _espe.repository.member null | lib_plankton.storage.type_store< - _espe.type.member.id, + _espe.type.member_id, Record, {}, lib_plankton.storage.type_sql_table_autokey_search_term, @@ -20,7 +20,7 @@ namespace _espe.repository.member */ function get_store( ) : lib_plankton.storage.type_store< - _espe.type.member.id, + _espe.type.member_id, Record, {}, lib_plankton.storage.type_sql_table_autokey_search_term, @@ -46,7 +46,7 @@ namespace _espe.repository.member /** */ function encode( - object : _espe.type.member.object + object : _espe.type.member_object ) : Record { return { @@ -69,7 +69,7 @@ namespace _espe.repository.member */ function decode( row : Record - ) : _espe.type.member.object + ) : _espe.type.member_object { return { "membership_number": row["membership_number"], @@ -93,8 +93,8 @@ namespace _espe.repository.member ) : Promise< Array< { - id : _espe.type.member.id; - value : _espe.type.member.object; + id : _espe.type.member_id; + object : _espe.type.member_object; } > > @@ -104,7 +104,7 @@ namespace _espe.repository.member .map( ({"key": key, "preview": preview}) => ({ "id": key, - "value": (preview as _espe.type.member.object), + "object": (preview as _espe.type.member_object), }) ) ); @@ -117,7 +117,7 @@ namespace _espe.repository.member ) : Promise< Array< { - id : _espe.type.member.id; + id : _espe.type.member_id; preview : { membership_number : string, name_real : string; @@ -144,8 +144,8 @@ namespace _espe.repository.member /** */ export async function read( - id : _espe.type.member.id - ) : Promise<_espe.type.member.object> + id : _espe.type.member_id + ) : Promise<_espe.type.member_object> { const row : Record = await get_store().read(id); @@ -156,11 +156,11 @@ namespace _espe.repository.member /** */ export async function create( - value : _espe.type.member.object - ) : Promise<_espe.type.member.id> + value : _espe.type.member_object + ) : Promise<_espe.type.member_id> { const row : Record = encode(value); - const id : _espe.type.member.id = await get_store().create(row); + const id : _espe.type.member_id = await get_store().create(row); return id; } @@ -169,8 +169,8 @@ namespace _espe.repository.member /** */ export async function update( - id : _espe.type.member.id, - value : _espe.type.member.object + id : _espe.type.member_id, + value : _espe.type.member_object ) : Promise { const row : Record = encode(value); @@ -181,8 +181,8 @@ namespace _espe.repository.member /** */ - export async function delete( - id : _espe.type.member.id + export async function delete_( + id : _espe.type.member_id ) : Promise { await get_store().delete(id); diff --git a/source/repositories/name_index.ts b/source/repositories/name_index.ts index 02e851d..9e2b226 100644 --- a/source/repositories/name_index.ts +++ b/source/repositories/name_index.ts @@ -1,4 +1,4 @@ -namespace _espe.repository.member +namespace _espe.repository.name_index { /** @@ -10,7 +10,7 @@ namespace _espe.repository.member Array, Record, lib_plankton.database.type_description_create_table, - lib_plankton.storage.type_sql_table_common_search_term, + lib_plankton.storage.sql_table_common.type_sql_table_common_search_term, Record > ) = null; @@ -23,12 +23,12 @@ namespace _espe.repository.member Array, Record, lib_plankton.database.type_description_create_table, - lib_plankton.storage.type_sql_table_common_search_term, + lib_plankton.storage.sql_table_common.type_sql_table_common_search_term, Record > { if (_chest === null) { - _chest = lib_plankton.storage.sql_table_common_chest( + _chest = lib_plankton.storage.sql_table_common.chest( { "database_implementation": _espe.helpers.database_implementation(), "table_name": "name_indices", @@ -51,7 +51,7 @@ namespace _espe.repository.member { let row : Record; try { - row = await get_chest().read(name); + row = await get_chest().read([name]); return row["index"]; } catch (error) { @@ -67,7 +67,7 @@ namespace _espe.repository.member index : int ) : Promise { - return get_chest().write(name, index); + await get_chest().write([name], {"index": index}); } } diff --git a/source/services/member.ts b/source/services/member.ts index ce79cf7..2f5c9d7 100644 --- a/source/services/member.ts +++ b/source/services/member.ts @@ -31,16 +31,123 @@ namespace _espe.service.member /** */ - export async function draft( + function name_login( + object : _espe.type.member_object + ) : string + { + return lib_plankton.string.coin( + "{{object}}{{extension}}", + { + "object": object.name_real_value.toLowerCase().replace(new RegExp(" ", "g"), "."), + "extension": ( + (object.name_real_index === 0) + ? "" + : ("." + object.name_real_index.toFixed(0)) + ), + } + ); + } + + + /** + */ + function name_display( + object : _espe.type.member_object + ) : string + { + return object.name_real_value; + } + + + /** + */ + function email_address_veiled( + object : _espe.type.member_object + ) : string + { + return lib_plankton.string.coin( + "{{prefix}}{{membership_number}}@{{domain}}", + { + "prefix": _espe.conf.get().settings.prefix_for_numberbased_email_addresses, + "membership_number": object.membership_number, + "domain": _espe.conf.get().settings.target_domain, + } + ); + } + + + /** + */ + function email_address_nominal( + object : _espe.type.member_object + ) : string + { + return lib_plankton.string.coin( + "{{user}}@{{domain}}", + { + "user": name_login(object), + "domain": _espe.conf.get().settings.target_domain, + } + ); + } + + + /** + */ + function email_address( + 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 + ) + ); + } + + + /** + */ + async function dump( + ) : Promise< + Array< + { + id : _espe.type.member_id; + object : _espe.type.member_object; + } + > + > + { + return _espe.repository.member.dump(); + } + + + /** + */ + async function get( + id : _espe.type.member_id + ) : Promise<_espe.type.member_object> + { + return _espe.repository.member.read(id); + } + + + /** + */ + export async function project( data : { membership_number : string; name_real_value : string; email_address_private : (null | string); } - ) : Promise<_espe.type.member.id> + ) : Promise<_espe.type.member_id> { - const name_real_index : int = await _espe.service.name_index.next(object.name_real_value); - const object : _espe.type.member.object = { + const name_real_index : int = await _espe.service.name_index.next(data.name_real_value); + const object : _espe.type.member_object = { "membership_number": data.membership_number, "name_real_value": data.name_real_value, "name_real_index": name_real_index, @@ -53,38 +160,137 @@ namespace _espe.service.member "email_allow_sending": false, "password_image": null, }; - const id : _espe.type.member.id = _espe.repository.member.create(object); + const id : _espe.type.member_id = await _espe.repository.member.create(object); notify_change(); return id; } - /* - export async function dump( - ) : Promise> + /** + */ + export async function summon( + member_id : _espe.type.member_id, + url_template : string + ) : Promise { - return _espe.repository.member.dump(); + const member_object : _espe.type.member_object = await get(member_id); + const verification : string = await _espe.helpers.verification_get(member_id); + + await _espe.helpers.email_send( + [ + member_object.email_address_private, + ], + _espe.conf.get().settings.registration_email.subject, + lib_plankton.string.coin( + _espe.conf.get().settings.registration_email.body, + { + "name": member_object.name_real_value, + "url": lib_plankton.string.coin( + url_template, + { + "verification": verification, + } + ), + } + ) + ); } + /** + */ + export async function info( + member_id : _espe.type.member_id + ) : Promise< + ( + null + | + { + name_real_value : string; + name_real_index : int; + name_login : string; + email_address_veiled : string; + email_address_nominal : string; + } + ) + > + { + 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; + } + } + + + /** + * @todo customize notifiation email (conf values) + */ + export async function register( + member_id : _espe.type.member_id, + data : { + email_use_veiled_address : boolean; + email_use_nominal_address : boolean; + email_redirect_to_private_address : boolean; + password : string; + }, + options : { + notify_admins ?: boolean; + } = {} + ) : Promise + { + options = Object.assign( + { + "notify_admins": false, + }, + options + ); + const member_object : _espe.type.member_object = await get(member_id); + if (member_object.registered) { + return Promise.reject(new Error("already registered")); + } + else { + member_object.email_use_veiled_address = data.email_use_veiled_address + member_object.email_use_nominal_address = data.email_use_nominal_address + member_object.email_redirect_to_private_address = data.email_redirect_to_private_address; + member_object.password_image = await _espe.helpers.bcrypt_compute(data.password); + member_object.registered = true; + await _espe.repository.member.update(member_id, member_object); + } + + notify_change(); + + if (! options.notify_admins) { + // do nothing + } + else { + await _espe.helpers.email_send( + _espe.conf.get().admins.map(admin => admin.email_address).filter(x => (x !== null)), + "Eingegangene Registrierung", + ("Member-ID: " + member_id.toFixed(0)) + ); + } + } + + /* export async function list( - ) : Promise> + ) : Promise> { return _espe.repository.member.list(); } - export async function get( - id : _espe.type.member.id - ) : Promise<_espe.type.member.object> - { - return _espe.repository.member.read(id); - } - - export async function modify( - id : _espe.type.member.id, - object : _espe.type.member.object + id : _espe.type.member_id, + object : _espe.type.member_object ) : Promise { await _espe.repository.member.update(id, object); @@ -93,124 +299,18 @@ namespace _espe.service.member export async function remove( - id : _espe.type.member.id + id : _espe.type.member_id ) : Promise { await _espe.repository.member.delete(id); notify_change(); } + */ - export async function register( - id : _espe.type.member.id, - data : { - name_login : string; - name_display : string; - salutation : string; - email_address_numberbased_use : boolean; - email_address_namebased_use : boolean; - email_redirect_to_private : boolean; - password : string; - } - ) : Promise - { - const member : _espe.type.member.object = await get(id); - - if (member.name_login !== null) { - return Promise.reject(new Error("already registered")); - } - else { - member.name_login = data.name_login; - member.name_display = data.name_display; - member.salutation = data.salutation; - member.email_address_numberbased_use = data.email_address_numberbased_use - member.email_address_namebased_use = data.email_address_namebased_use - member.email_redirect_to_private = data.email_redirect_to_private; - member.password_image = await _espe.helpers.bcrypt_compute(data.password); - member.registered = true; - - await modify(id, member); - } - } - - - export function derive_login_name( - value : _espe.type.member.object - ) : string - { - return lib_plankton.string.coin( - "{{value}}{{extension}}", - { - "value": value.name_real_value.toLowerCase().replace(new RegExp(" ", "g"), "."), - "extension": ( - ( - (value.name_real_extension === null) - || - (value.name_real_extension === "") - ) - ? "" - : ("." + value.name_real_extension) - ), - } - ); - } - - - export function derive_email_address_namely( - value : _espe.type.member.object - ) : string - { - return lib_plankton.string.coin( - "{{value}}{{extension}}@{{domain}}", - { - "value": value.name_real_value.toLowerCase().replace(new RegExp(" ", "g"), "."), - "extension": ( - ( - (value.name_real_extension === null) - || - (value.name_real_extension === "") - ) - ? "" - : ("." + value.name_real_extension) - ), - "domain": _espe.conf.get().settings.target_domain, - } - ); - } - - - export function derive_email_address_numerical( - value : _espe.type.member.object - ) : string - { - return lib_plankton.string.coin( - "{{prefix}}{{membership_number}}@{{domain}}", - { - "prefix": _espe.conf.get().settings.prefix_for_numberbased_email_addresses, - "membership_number": value.membership_number, - "domain": _espe.conf.get().settings.target_domain, - } - ); - } - - - function derive_email_address_to_use( - value : _espe.type.member.object - ) : (null | string) - { - return ( - value.email_address_namebased_use - ? derive_email_address_namely(value) - : ( - value.email_address_numberbased_use - ? derive_email_address_numerical(value) - : value.email_address_private_value - ) - ); - } - - + /** * @todo check validity (e.g. username characters) + */ export async function export_authelia_user_file( ) : Promise { @@ -222,21 +322,17 @@ namespace _espe.service.member x => x.map( entry => Object.assign( entry, - {"email_address": derive_email_address_to_use(entry.value)} + {"email_address": email_address(entry.object)} ) ), x => x.filter( entry => ( - ( - (entry.value.name_login !== null) - && - (entry.value.name_login !== "") - ) + entry.object.registered && ( - (entry.value.password_image !== null) + (entry.object.password_image !== null) && - (entry.value.password_image !== "") + (entry.object.password_image !== "") ) && (entry.email_address !== null) @@ -244,21 +340,13 @@ namespace _espe.service.member ), x => x.map( entry => ([ - entry.value.name_login, + name_login(entry.object), { - "disabled": (! entry.value.enabled), - "displayname": ( - ( - (entry.value.name_display !== null) - && - (entry.value.name_display !== "") - ) - ? entry.value.name_display - : entry.value.name_real_value - ), + "disabled": (! entry.object.enabled), + "displayname": name_display(entry.object), "email": entry.email_address, "groups": [], - "password": entry.value.password_image, + "password": entry.object.password_image, } ]) ), @@ -268,7 +356,6 @@ namespace _espe.service.member ] ); } - */ } diff --git a/source/types/member.ts b/source/types.ts similarity index 77% rename from source/types/member.ts rename to source/types.ts index a29acdd..1daf9a5 100644 --- a/source/types/member.ts +++ b/source/types.ts @@ -1,17 +1,17 @@ -namespace _espe.type.member +namespace _espe.type { /** */ - export type id = int; + export type member_id = int; /** */ - export type object = { + export type member_object = { membership_number : string; name_real_value : string; - name_real_index : string; + name_real_index : int; email_address_private : (null | string); registered : boolean; enabled : boolean; diff --git a/tools/makefile b/tools/makefile index 5c1e3ea..22ac6a4 100644 --- a/tools/makefile +++ b/tools/makefile @@ -28,7 +28,7 @@ ${dir_temp}/espe-unlinked.js: \ ${dir_lib}/plankton/plankton.d.ts \ ${dir_source}/helpers.ts \ ${dir_source}/database.ts \ - ${dir_source}/types/member.ts \ + ${dir_source}/types.ts \ ${dir_source}/repositories/name_index.ts \ ${dir_source}/repositories/member.ts \ ${dir_source}/services/name_index.ts \ @@ -40,13 +40,9 @@ ${dir_temp}/espe-unlinked.js: \ ${dir_source}/api/actions/email.ts \ ${dir_source}/api/actions/verification_get.ts \ ${dir_source}/api/actions/verification_check.ts \ - ${dir_source}/api/actions/member_list.ts \ - ${dir_source}/api/actions/member_read.ts \ - ${dir_source}/api/actions/member_create.ts \ - ${dir_source}/api/actions/member_update.ts \ - ${dir_source}/api/actions/member_delete.ts \ - ${dir_source}/api/actions/member_get.ts \ - ${dir_source}/api/actions/member_urge_for_registration.ts \ + ${dir_source}/api/actions/member_project.ts \ + ${dir_source}/api/actions/member_summon.ts \ + ${dir_source}/api/actions/member_info.ts \ ${dir_source}/api/actions/member_register.ts \ ${dir_source}/api/functions.ts \ ${dir_source}/conf.ts \