diff --git a/misc/sampledata.json b/misc/sampledata.json index a591264..abe7e82 100644 --- a/misc/sampledata.json +++ b/misc/sampledata.json @@ -1,4 +1,26 @@ { + "groups": [ + { + "id": 1, + "name": "auto" + }, + { + "id": 2, + "name": "zug" + }, + { + "id": 3, + "name": "flugzeug" + }, + { + "id": 4, + "name": "fahrrad" + }, + { + "id": 5, + "name": "zu_fuß" + } + ], "admins": [ { "name": "admin", @@ -8,34 +30,33 @@ ], "members": [ { - "membership_number": "123", - "name_real": "Alexandra Ahorn", + "id": 1, + "name": "Alexandra Ahorn", "email_address_private": "alex-rockt@example.org", - "groups": ["auto","zug","flugzeug"] + "groups": [1, 2, 3] }, { - "membership_number": "234", - "name_real": "Berthold Buche", + "id": 2, + "name": "Berthold Buche", "email_address_private": "bert-ohne-ernie@example.org", - "groups": ["fahrrad","zu_fuß","zug"] + "groups": [4, 5, 2] }, { - "membership_number": "345", - "name_real": "Charlotte Castania", + "id": 3, + "name": "Charlotte Castania", "email_adress_private": "charly-the-unicorn@example.org", - "groups": ["fahrrad","auto"] + "groups": [4, 1] } ], "invites": [ { - "membership_number_changeable": false, - "membership_number_value": "456", + "id": 1, "name_changeable": true, "name_value": "Daniel Distel", "email_address_changeable": true, "email_address_value": "duesentrieb@example.org", "groups_changeable": false, - "groups_value": ["flugzeug","zu_fuß"] + "groups_value": [3, 5] } ] } diff --git a/source/api/actions/invite_accept.ts b/source/api/actions/invite_accept.ts index e2c10ad..2663e14 100644 --- a/source/api/actions/invite_accept.ts +++ b/source/api/actions/invite_accept.ts @@ -17,7 +17,7 @@ namespace _espe.api { /** */ - export function register_invite_accept( + export function register_invitation_accept( rest_subject : lib_plankton.rest_http.type_rest ) : void { @@ -25,9 +25,8 @@ namespace _espe.api { key : string; data : { - membership_number : (null | string); - groups : Array; - name : string; + name : (null | string); + groups : (null | Array); email_address : (null | string); password : (null | string); }; @@ -41,7 +40,7 @@ namespace _espe.api >( rest_subject, lib_plankton.http.enum_method.post, - _espe.api.full_path("/invite/accept"), + _espe.api.full_path("/invitation/accept"), { /** * @todo translation @@ -72,7 +71,7 @@ namespace _espe.api { try { - const flaws = await _espe.service.invite.accept( + const flaws = await _espe.service.invitation.accept( input.key, input.data ); diff --git a/source/api/actions/invite_create.ts b/source/api/actions/invite_create.ts index ac59873..e00d6c5 100644 --- a/source/api/actions/invite_create.ts +++ b/source/api/actions/invite_create.ts @@ -18,21 +18,19 @@ namespace _espe.api /** */ - export function register_invite_create( + export function register_invitation_create( rest_subject : lib_plankton.rest_http.type_rest ) : void { lib_plankton.rest_http.register< { data : { - membership_number_changeable : boolean; - membership_number_value : (null | string); name_changeable : boolean; name_value : string; email_address_changeable : boolean; email_address_value : (null | string); groups_changeable : boolean; - groups_value : Array; + groups_value : Array; expiry : (null | int); }; notification_target_url_template ?: (null | string); @@ -49,7 +47,7 @@ namespace _espe.api >( rest_subject, lib_plankton.http.enum_method.post, - _espe.api.full_path("/invite/create"), + _espe.api.full_path("/invitation/create"), { /** * @todo translation @@ -70,16 +68,6 @@ namespace _espe.api "type": "intiger", "description": "Ablaufzeitpunkt" }, - "membership_number_changeable": { - "type": "boolean", - "nullable": false, - "description": "Mitgliedsnummer | änderbar" - }, - "membership_number_value": { - "type": "string", - "nullable": true, - "description": "Mitgliedsnummer | Wert" - }, "name_changeable": { "type": "boolean", "nullable": false, @@ -109,7 +97,7 @@ namespace _espe.api "nullable": false, "type": "array", "items": { - "type": "string", + "type": "integer", "nullable": false, }, "description": "Gruppen | Wert" @@ -168,43 +156,25 @@ namespace _espe.api return Promise.reject(new Error("impossible")); } else { - if ( - (! _espe.conf.get().settings.misc.facultative_membership_number) - && - ( - (input.data.membership_number_value === null) - || - (input.data.membership_number_value === "") - ) - ) { - return Promise.resolve({ - "status_code": 400, - "data": "membership number required" - }); - } - else { - const invite_info : {id : _espe.type.invite_id; key : _espe.type.invite_key;} = await _espe.service.invite.create( - { - "membership_number_changeable": input.data.membership_number_changeable, - "membership_number_value": input.data.membership_number_value, - "name_changeable": input.data.name_changeable, - "name_value": input.data.name_value, - "email_address_changeable": input.data.email_address_changeable, - "email_address_value": input.data.email_address_value, - "groups_changeable": input.data.groups_changeable, - "groups_value": input.data.groups_value, - }, - { - "expiry": input.data.expiry, - "notification_target_url_template": input.notification_target_url_template, - "send_immediatly": input.send_immediatly, - } - ); - return Promise.resolve({ - "status_code": 201, - "data": invite_info - }); - } + const invitation_info : {id : _espe.type.invitation_id; key : _espe.type.invitation_key;} = await _espe.service.invitation.create( + { + "name_changeable": input.data.name_changeable, + "name_value": input.data.name_value, + "email_address_changeable": input.data.email_address_changeable, + "email_address_value": input.data.email_address_value, + "groups_changeable": input.data.groups_changeable, + "groups_value": input.data.groups_value, + }, + { + "expiry": input.data.expiry, + "notification_target_url_template": input.notification_target_url_template, + "send_immediatly": input.send_immediatly, + } + ); + return Promise.resolve({ + "status_code": 201, + "data": invitation_info + }); } } } diff --git a/source/api/actions/invite_examine.ts b/source/api/actions/invite_examine.ts index 163d4a0..5db11fd 100644 --- a/source/api/actions/invite_examine.ts +++ b/source/api/actions/invite_examine.ts @@ -17,7 +17,7 @@ namespace _espe.api { /** */ - export function register_invite_examine( + export function register_invitation_examine( rest_subject : lib_plankton.rest_http.type_rest ) : void { @@ -27,7 +27,7 @@ namespace _espe.api >( rest_subject, lib_plankton.http.enum_method.get, - _espe.api.full_path("/invite/examine"), + _espe.api.full_path("/invitation/examine"), { /** * @todo translation @@ -50,16 +50,6 @@ namespace _espe.api "type": "integer", "description": "Ablaufzeitpunkt" }, - "membership_number_changeable": { - "type": "boolean", - "nullable": false, - "description": "Mitgliedsnummer | änderbar" - }, - "membership_number_value": { - "type": "string", - "nullable": true, - "description": "Mitgliedsnummer | Wert" - }, "name_changeable": { "type": "boolean", "nullable": false, @@ -97,34 +87,30 @@ namespace _espe.api }, "required": [ "expiry", - "membership_number_mode", - "membership_number_value", - "name_mode", + "name_changeable", "name_value", - "email_address_mode", + "email_address_changeable", "email_address_value", - "groups_mode", + "groups_changeable", "groups_value", ] }), "restriction": () => restriction_none, "execution": () => ({"query_parameters": query_parameters, "input": input}) => { - const invite_key : _espe.type.invite_key = query_parameters["key"]; + const invitation_key : _espe.type.invitation_key = query_parameters["key"]; return ( - _espe.service.invite.examine(invite_key) + _espe.service.invitation.examine(invitation_key) .then( - (invite_object) => Promise.resolve({ + (invitation_object) => Promise.resolve({ "status_code": 200, "data": { - "expiry": invite_object.expiry, - "membership_number_changeable": invite_object.membership_number_changeable, - "membership_number_value": invite_object.membership_number_value, - "name_changeable": invite_object.name_changeable, - "name_value": invite_object.name_value, - "email_address_changeable": invite_object.email_address_changeable, - "email_address_value": invite_object.email_address_value, - "groups_changeable": invite_object.groups_changeable, - "groups_value": invite_object.groups_value, + "expiry": invitation_object.expiry, + "name_changeable": invitation_object.name_changeable, + "name_value": invitation_object.name_value, + "email_address_changeable": invitation_object.email_address_changeable, + "email_address_value": invitation_object.email_address_value, + "groups_changeable": invitation_object.groups_changeable, + "groups_value": invitation_object.groups_value, } }) ) diff --git a/source/api/actions/invite_list.ts b/source/api/actions/invite_list.ts index e0bdfdf..929ca30 100644 --- a/source/api/actions/invite_list.ts +++ b/source/api/actions/invite_list.ts @@ -17,7 +17,7 @@ namespace _espe.api { /** */ - export function register_invite_list( + export function register_invitation_list( rest_subject : lib_plankton.rest_http.type_rest ) : void { @@ -25,16 +25,16 @@ namespace _espe.api null, Array< { - id : _espe.type.invite_id; - key : _espe.type.invite_key; + id : _espe.type.invitation_id; + key : _espe.type.invitation_key; expiry : (null | int); - name_value : string; + name_value : (null | string); } > >( rest_subject, lib_plankton.http.enum_method.get, - _espe.api.full_path("/invite/list"), + _espe.api.full_path("/invitation/list"), { /** * @todo translation @@ -73,7 +73,7 @@ namespace _espe.api }), "restriction": () => restriction_logged_in, "execution": () => async ({}) => { - const data = await _espe.service.invite.list(); + const data = await _espe.service.invitation.list(); return Promise.resolve({ "status_code": 200, "data": data diff --git a/source/api/actions/invite_read.ts b/source/api/actions/invite_read.ts index fa3ebe6..8ba4140 100644 --- a/source/api/actions/invite_read.ts +++ b/source/api/actions/invite_read.ts @@ -18,7 +18,7 @@ namespace _espe.api /** */ - export function register_invite_read( + export function register_invitation_read( rest_subject : lib_plankton.rest_http.type_rest ) : void { @@ -30,20 +30,18 @@ namespace _espe.api { key : string; expiry : (null | int); - membership_number_changeable : boolean; - membership_number_value : (null | string); name_changeable : boolean; - name_value : string; + name_value : (null | string); email_address_changeable : boolean; email_address_value : (null | string); groups_changeable : boolean; - groups_value : Array; + groups_value : (null | Array); } ) >( rest_subject, lib_plankton.http.enum_method.get, - _espe.api.full_path("/invite/read"), + _espe.api.full_path("/invitation/read"), { /** * @todo translation @@ -66,16 +64,6 @@ namespace _espe.api "type": "integer", "description": "Ablaufzeitpunkt" }, - "membership_number_changeable": { - "type": "boolean", - "nullable": false, - "description": "Mitgliedsnummer | änderbar" - }, - "membership_number_value": { - "type": "string", - "nullable": true, - "description": "Mitgliedsnummer | Wert" - }, "name_changeable": { "type": "boolean", "nullable": false, @@ -105,7 +93,7 @@ namespace _espe.api "nullable": false, "type": "array", "items": { - "type": "string", + "type": "integer", "nullable": false, }, "description": "Gruppen | Wert" @@ -113,8 +101,6 @@ namespace _espe.api }, "required": [ "expiry", - "membership_number_mode", - "membership_number_value", "name_mode", "name_value", "email_address_mode", @@ -125,23 +111,21 @@ namespace _espe.api }), "restriction": () => restriction_logged_in, "execution": () => ({"query_parameters": query_parameters, "input": input}) => { - const invite_id : _espe.type.invite_id = parseInt(query_parameters["id"]); + const invitation_id : _espe.type.invitation_id = parseInt(query_parameters["id"]); return ( - _espe.service.invite.get_by_id(invite_id) + _espe.service.invitation.get_by_id(invitation_id) .then( - (invite_object) => Promise.resolve({ + (invitation_object) => Promise.resolve({ "status_code": 200, "data": { - "key": invite_object.key, - "expiry": invite_object.expiry, - "membership_number_changeable": invite_object.membership_number_changeable, - "membership_number_value": invite_object.membership_number_value, - "name_changeable": invite_object.name_changeable, - "name_value": invite_object.name_value, - "email_address_changeable": invite_object.email_address_changeable, - "email_address_value": invite_object.email_address_value, - "groups_changeable": invite_object.groups_changeable, - "groups_value": invite_object.groups_value, + "key": invitation_object.key, + "expiry": invitation_object.expiry, + "name_changeable": invitation_object.name_changeable, + "name_value": invitation_object.name_value, + "email_address_changeable": invitation_object.email_address_changeable, + "email_address_value": invitation_object.email_address_value, + "groups_changeable": invitation_object.groups_changeable, + "groups_value": invitation_object.groups_value, } }) ) diff --git a/source/api/actions/member_info.ts b/source/api/actions/member_info.ts deleted file mode 100644 index a5fa539..0000000 --- a/source/api/actions/member_info.ts +++ /dev/null @@ -1,121 +0,0 @@ -/* -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 -. - */ - -namespace _espe.api -{ - - /** - * @todo zeitliche Begrenzung? - */ - export function register_member_info( - rest_subject : lib_plankton.rest_http.type_rest - ) : void - { - lib_plankton.rest_http.register< - int, - ( - null - | - { - name_real_value : string; - name_real_index : int; - name_login : string; - email_address_veiled : (null | string); - email_address_nominal : string; - } - ) - >( - rest_subject, - lib_plankton.http.enum_method.get, - _espe.api.full_path("/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": true, - }, - "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 : (null | 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_list.ts b/source/api/actions/member_list.ts index 420faa5..870806f 100644 --- a/source/api/actions/member_list.ts +++ b/source/api/actions/member_list.ts @@ -28,9 +28,7 @@ namespace _espe.api { id : int; preview : { - membership_number : string; - name_real_value : string; - name_real_index : int; + name : string; }; } > @@ -62,18 +60,10 @@ namespace _espe.api "type": "object", "additionalProperties": false, "properties": { - "membership_number": { + "name": { "type": "string", "nullable": false, }, - "name_real_value": { - "type": "string", - "nullable": false, - }, - "name_real_index": { - "type": "number", - "nullable": false, - }, }, "required": [ "membership_number", diff --git a/source/api/actions/member_modify.ts b/source/api/actions/member_modify.ts index ac63cff..081f163 100644 --- a/source/api/actions/member_modify.ts +++ b/source/api/actions/member_modify.ts @@ -24,9 +24,8 @@ namespace _espe.api { lib_plankton.rest_http.register< { - email_address_private : (null | string); - groups ?: Array; - registered : boolean; + email_address : (null | string); + groups ?: Array; enabled : boolean; }, null @@ -40,7 +39,7 @@ namespace _espe.api "nullable": false, "type": "object", "properties": { - "email_address_private": { + "email_address": { "nullable": true, "type": "string" }, @@ -52,10 +51,6 @@ namespace _espe.api "nullable": false, } }, - "registered": { - "nullable": false, - "type": "boolean" - }, "enabled": { "nullable": false, "type": "boolean" @@ -63,8 +58,7 @@ namespace _espe.api }, "additionalProperties": false, "required": [ - "email_address_private", - "registered", + "email_address", "enabled", ] }), @@ -81,13 +75,12 @@ namespace _espe.api await _espe.service.member.modify( member_id, { - "email_address_private": input.email_address_private, + "email_address": input.email_address, "groups": ( (input.groups === undefined) - ? lib_plankton.pod.make_empty>() - : lib_plankton.pod.make_filled>(input.groups) + ? lib_plankton.pod.make_empty>() + : lib_plankton.pod.make_filled>(input.groups) ), - "registered": input.registered, "enabled": input.enabled, } ); diff --git a/source/api/actions/member_project.ts b/source/api/actions/member_project.ts deleted file mode 100644 index 60431ea..0000000 --- a/source/api/actions/member_project.ts +++ /dev/null @@ -1,153 +0,0 @@ -/* -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 -. - */ - -namespace _espe.api -{ - - /** - */ - export function register_member_project( - rest_subject : lib_plankton.rest_http.type_rest - ) : void - { - lib_plankton.rest_http.register< - { - membership_number : (null | string); - name_real_value : string; - email_address_private : (null | string); - groups ?: Array; - notification_target_url_template ?: (null | string); - }, - ( - string - | - _espe.type.member_id - ) - >( - rest_subject, - lib_plankton.http.enum_method.post, - _espe.api.full_path("/member/project"), - { - "description": () => "erstellt ein neues Mitglied und gibt die erzeugte ID aus", - "input_schema": () => ({ - "type": "object", - "nullable": false, - "additionalProperties": false, - "properties": { - "membership_number": { - "type": "string", - "nullable": false, - "description": "Mitgliedsnummer" - }, - "name_real_value": { - "type": "string", - "nullable": false, - "description": "Klarname" - }, - "email_address_private": { - "type": "string", - "nullable": true, - "description": "private E-Mail-Adresse" - }, - "groups": { - "nullable": false, - "type": "array", - "items": { - "type": "string", - "nullable": false, - } - }, - "notification_target_url_template": { - "type": "string", - "nullable": true, - "description": "Platz-Halter: id" - }, - }, - "required": [ - "membership_number", - "name_real_value", - ] - }), - "output_schema": () => ({ - "type": "number", - "nullable": false, - }), - "restriction": () => restriction_logged_in, - "execution": () => async ({"input": input}) => { - if (input === null) { - return Promise.reject(new Error("impossible")); - } - else { - if ( - (! _espe.conf.get().settings.misc.facultative_membership_number) - && - ( - (input.membership_number === null) - || - (input.membership_number === "") - ) - ) { - return Promise.resolve({ - "status_code": 400, - "data": "membership number required" - }); - } - else { - 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": ( - ("email_address_private" in input) - ? ( - (input.email_address_private !== "") - ? input.email_address_private - : null - ) - : null - ), - "groups": (input.groups ?? []), - } - ); - if (! _espe.conf.get().settings.misc.auto_register) { - // do nothing - } - else { - // TODO: Werte in Konfiguration auslagern - await _espe.service.member.register( - member_id, - { - "email_use_veiled_address": false, - "email_use_nominal_address": false, - "email_redirect_to_private_address": false, - "password": null, - }, - { - "notification_target_url_template": input.notification_target_url_template, - } - ); - } - return Promise.resolve({ - "status_code": 201, - "data": member_id - }); - } - } - } - } - ); - } - -} diff --git a/source/api/actions/member_read.ts b/source/api/actions/member_read.ts index 9df80fe..b988bcb 100644 --- a/source/api/actions/member_read.ts +++ b/source/api/actions/member_read.ts @@ -25,21 +25,11 @@ namespace _espe.api lib_plankton.rest_http.register< null, { - membership_number : (null | string); - name_real_value : string; - name_real_index : int; - email_address_private : (null | string); - groups : Array; - registered : boolean; + name : string; + email_address : (null | string); + groups : Array; enabled : boolean; - email_use_veiled_address : boolean; - email_use_nominal_address : boolean; - email_redirect_to_private_address : boolean; - email_allow_sending : boolean; password_set : boolean; - email_address_veiled : (null | string); - email_address_nominal : string; - name_login : string; } >( rest_subject, @@ -51,19 +41,11 @@ namespace _espe.api "nullable": false, "type": "object", "properties": { - "membership_number": { - "nullable": true, - "type": "string" - }, - "name_real_value": { + "name": { "nullable": false, "type": "string" }, - "name_real_index": { - "nullable": false, - "type": "number" - }, - "email_address_private": { + "email_address": { "nullable": true, "type": "string" }, @@ -72,67 +54,21 @@ namespace _espe.api "type": "array", "items": { "nullable": false, - "type": "string" + "type": "int" } }, - "registered": { - "nullable": false, - "type": "boolean" - }, "enabled": { "nullable": false, "type": "boolean" }, - "email_use_veiled_address": { - "nullable": false, - "type": "boolean" - }, - "email_use_nominal_address": { - "nullable": false, - "type": "boolean" - }, - "email_redirect_to_private_address": { - "nullable": false, - "type": "boolean" - }, - "email_allow_sending": { - "nullable": false, - "type": "boolean" - }, - "password_set": { - "nullable": false, - "type": "boolean" - }, - "email_address_veiled": { - "nullable": true, - "type": "string" - }, - "email_address_nominal": { - "nullable": false, - "type": "string" - }, - "name_login": { - "nullable": false, - "type": "string" - }, }, "additionalProperties": false, "required": [ - "membership_number", - "name_real_value", - "name_real_index", - "email_address_private", + "name", + "email_address", "groups", - "registered", "enabled", - "email_use_veiled_address", - "email_use_nominal_address", - "email_redirect_to_private_address", - "email_allow_sending", "password_set", - "email_address_veiled", - "email_address_nominal", - "name_login", ] }), "restriction": () => restriction_logged_in, @@ -142,21 +78,11 @@ namespace _espe.api return Promise.resolve({ "status_code": 200, "data": { - "membership_number": member_object.membership_number, - "name_real_value": member_object.name_real_value, - "name_real_index": member_object.name_real_index, - "email_address_private": member_object.email_address_private, + "name": member_object.name, + "email_address": member_object.email_address, "groups": member_object.groups, - "registered": member_object.registered, "enabled": member_object.enabled, - "email_use_veiled_address": member_object.email_use_veiled_address, - "email_use_nominal_address": member_object.email_use_nominal_address, - "email_redirect_to_private_address": member_object.email_redirect_to_private_address, - "email_allow_sending": member_object.email_allow_sending, "password_set": (member_object.password_image !== null), - "name_login": _espe.service.member.name_login(member_object), - "email_address_veiled": _espe.service.member.email_address_veiled(member_object), - "email_address_nominal": _espe.service.member.email_address_nominal(member_object), }, }); } diff --git a/source/api/actions/member_register.ts b/source/api/actions/member_register.ts deleted file mode 100644 index a46ecbe..0000000 --- a/source/api/actions/member_register.ts +++ /dev/null @@ -1,159 +0,0 @@ -/* -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 -. - */ - -namespace _espe.api -{ - - /** - * @todo zeitliche Begrenzung? - */ - export function register_member_register( - rest_subject : lib_plankton.rest_http.type_rest - ) : void - { - lib_plankton.rest_http.register< - { - email_use_veiled_address : boolean; - email_use_nominal_address : boolean; - email_redirect_to_private_address : boolean; - password : (null | string); - notification_target_url_template ?: (null | string); - }, - Array< - { - incident : string; - details : Record; - } - > - >( - rest_subject, - lib_plankton.http.enum_method.post, - _espe.api.full_path("/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, - "description": "ob die nummern-basierte E-Mail-Adresse eingerichtet werden soll", - }, - "email_use_nominal_address": { - "type": "boolean", - "nullable": false, - "description": "ob die namens-basierte E-Mail-Adresse eingerichtet werden soll", - }, - "email_redirect_to_private_address": { - "type": "boolean", - "nullable": false, - "description": "ob auf die Partei-Adressen eingehende E-Mails zur privaten Adresse weitergeleitet werden sollen", - }, - "password": { - "type": "string", - "nullable": true, - "description": "Passwort für alle Netz-Dienste", - }, - "notification_target_url_template": { - "type": "string", - "nullable": true, - "description": "Platz-Halter: id" - }, - }, - "required": [ - "email_use_veiled_address", - "email_use_nominal_address", - "email_redirect_to_private_address", - "password", - ] - }), - "output_schema": () => ({ - "nullable": false, - "type": "array", - "items": { - "nullable": false, - "type": "object", - "properties": { - "incident": { - "nullable": false, - "type": "string" - }, - "details": { - "nullable": false, - "type": "object", - "properties": {}, - "additionalProperties": { - "nullable": true - }, - "required": [] - }, - }, - "additionalProperties": false, - "required": [ - "incident", - "details", - ] - } - }), - "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": () => ({"path_parameters": path_parameters, "input": input}) => { - if (input === null) { - return Promise.reject(new Error("impossible")); - } - else { - const member_id : _espe.type.member_id = parseInt(path_parameters["id"]); - return ( - _espe.service.member.register( - member_id, - { - "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, - }, - { - "notification_target_url_template": (input.notification_target_url_template ?? null), - } - ) - .then( - flaws => Promise.resolve({ - "status_code": ( - (flaws.length <= 0) - ? 200 - : 409 - ), - "data": flaws - }) - ) - ); - } - }, - } - ) - } - -} diff --git a/source/api/functions.ts b/source/api/functions.ts index 38b74c0..5e465ee 100644 --- a/source/api/functions.ts +++ b/source/api/functions.ts @@ -45,10 +45,7 @@ namespace _espe.api } // member { - _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_modify(rest_subject); @@ -59,13 +56,13 @@ namespace _espe.api _espe.api.register_member_password_change_execute(rest_subject); } } - // invite + // invitation { - _espe.api.register_invite_list(rest_subject); - _espe.api.register_invite_read(rest_subject); - _espe.api.register_invite_create(rest_subject); - _espe.api.register_invite_examine(rest_subject); - _espe.api.register_invite_accept(rest_subject); + _espe.api.register_invitation_list(rest_subject); + _espe.api.register_invitation_read(rest_subject); + _espe.api.register_invitation_create(rest_subject); + _espe.api.register_invitation_examine(rest_subject); + _espe.api.register_invitation_accept(rest_subject); } return rest_subject; diff --git a/source/repositories/group.ts b/source/repositories/group.ts new file mode 100644 index 0000000..9129ba7 --- /dev/null +++ b/source/repositories/group.ts @@ -0,0 +1,224 @@ +/* +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 +. + */ + +namespace _espe.repository.group +{ + + /** + */ + var _store : ( + null + | + lib_plankton.storage.type_store< + _espe.type.group_id, + Record, + {}, + lib_plankton.storage.type_sql_table_autokey_search_term, + Record + > + ) = null; + + + /** + */ + function get_store( + ) : lib_plankton.storage.type_store< + _espe.type.group_id, + Record, + {}, + lib_plankton.storage.type_sql_table_autokey_search_term, + Record + > + { + if (_store === null) + { + _store = lib_plankton.storage.sql_table_autokey_store( + { + "database_implementation": _espe.helpers.database_implementation(), + "table_name": "groups", + "key_name": "id", + } + ); + } + else + { + // do nothing + } + return _store; + } + + + /** + */ + type type_dispersal = Record; + + + /** + */ + function encode( + object : _espe.type.group_object + ) : type_dispersal + { + return { + "name": object.name, + }; + } + + + /** + */ + function decode( + dispersal : type_dispersal + ) : _espe.type.group_object + { + return { + "name": dispersal.core_row["name"], + }; + } + + + /** + * @todo optimize + */ + export async function list( + search_term : (null | string) + ) : Promise< + Array< + { + id : _espe.type.group_id; + preview : { + name : string; + }; + } + > + > + { + return ( + (await get_store().search(null)) + .filter( + ({"key": key, "preview": preview}) => ( + ( + (search_term === null) + || + (search_term.length <= 1) + ) + ? + true + : + preview["name"].toLowerCase().includes(search_term.toLowerCase()) + ) + ) + .map( + ({"key": key, "preview": preview}) => ({ + "id": key, + "preview": { + "name": preview["name"], + } + }) + ) + ); + } + + + /** + */ + export async function read( + id : _espe.type.group_id + ) : Promise<_espe.type.group_object> + { + const core_row : Record = await get_store().read(id); + + const dispersal : type_dispersal = { + "core_row": core_row, + }; + + return decode(dispersal); + } + + + /** + */ + export async function create( + value : _espe.type.group_object + ) : Promise<_espe.type.group_id> + { + const dispersal : type_dispersal = encode(value); + + // core + const id : _espe.type.group_id = await get_store().create(dispersal.core_row); + + return id; + } + + + /** + * @todo replace groups smartly + */ + export async function update( + id : _espe.type.group_id, + value : _espe.type.group_object + ) : Promise + { + const dispersal : type_dispersal = encode(value); + + // core + await get_store().update(id, dispersal.core_row); + } + + + /** + */ + export async function delete_( + id : _espe.type.group_id + ) : Promise + { + // core + await get_store().delete(id); + } + + + /** + */ + export async function dump( + ) : Promise< + Array< + { + id : _espe.type.group_id; + object : _espe.type.group_object; + } + > + > + { + return ( + Promise.all( + (await get_store().search(null)) + .map(hit => hit.key) + .map( + id => ( + read(id) + .then( + (object) => ({ + "id": id, + "object": object + }) + ) + ) + ) + ) + ); + } + +} + diff --git a/source/repositories/invite.ts b/source/repositories/invitation.ts similarity index 79% rename from source/repositories/invite.ts rename to source/repositories/invitation.ts index 8de1cb0..9042d72 100644 --- a/source/repositories/invite.ts +++ b/source/repositories/invitation.ts @@ -13,7 +13,7 @@ You should have received a copy of the GNU General Public License along with thi . */ -namespace _espe.repository.invite +namespace _espe.repository.invitation { /** @@ -33,7 +33,7 @@ namespace _espe.repository.invite null | lib_plankton.storage.type_store< - _espe.type.invite_id, + _espe.type.invitation_id, Record, {}, lib_plankton.storage.type_sql_table_autokey_search_term, @@ -55,7 +55,7 @@ namespace _espe.repository.invite */ function get_core_store( ) : lib_plankton.storage.type_store< - _espe.type.invite_id, + _espe.type.invitation_id, Record, {}, lib_plankton.storage.type_sql_table_autokey_search_term, @@ -66,7 +66,7 @@ namespace _espe.repository.invite _core_store = lib_plankton.storage.sql_table_autokey_store( { "database_implementation": _espe.helpers.database_implementation(), - "table_name": "invites", + "table_name": "invitations", "key_name": "id", } ); @@ -87,8 +87,8 @@ namespace _espe.repository.invite _group_chest = lib_plankton.storage.sql_table_common.chest( { "database_implementation": _espe.helpers.database_implementation(), - "table_name": "invite_groups", - "key_names": ["invite_id","group_name"], + "table_name": "invitation_groups", + "key_names": ["invitation_id","group_name"], } ); } @@ -112,15 +112,13 @@ namespace _espe.repository.invite /** */ function encode( - object : _espe.type.invite_object + object : _espe.type.invitation_object ) : type_dispersal { return { "core_row": { "key": object.key, "expiry": object.expiry, - "membership_number_changeable": _espe.helpers.dbbool_encode(object.membership_number_changeable), - "membership_number_value": object.membership_number_value, "name_changeable": _espe.helpers.dbbool_encode(object.name_changeable), "name_value": object.name_value, "email_address_changeable": _espe.helpers.dbbool_encode(object.email_address_changeable), @@ -128,7 +126,7 @@ namespace _espe.repository.invite "groups_changeable": _espe.helpers.dbbool_encode(object.groups_changeable), }, "group_rows": ( - object.groups_value + (object.groups_value ?? []) .map( group => ({ "group_name": group, @@ -143,19 +141,17 @@ namespace _espe.repository.invite */ function decode( dispersal : type_dispersal - ) : _espe.type.invite_object + ) : _espe.type.invitation_object { return { "key": dispersal.core_row["key"], "expiry": dispersal.core_row["expiry"], - "membership_number_changeable": _espe.helpers.dbbool_decode(dispersal.core_row["membership_number_changeable"]), - "membership_number_value": dispersal.core_row["membership_number_value"], "name_changeable": _espe.helpers.dbbool_decode(dispersal.core_row["name_changeable"]), "name_value": dispersal.core_row["name_value"], "email_address_changeable": _espe.helpers.dbbool_decode(dispersal.core_row["email_address_changeable"]), "email_address_value": dispersal.core_row["email_address_value"], "groups_changeable": _espe.helpers.dbbool_decode(dispersal.core_row["groups_changeable"]), - "groups_value": lib_plankton.list.sorted( + "groups_value": lib_plankton.list.sorted<_espe.type.group_id>( dispersal.group_rows.map(row => row["group_name"]), { "compare_element": (group1, group2) => (group1 <= group2) @@ -173,7 +169,7 @@ namespace _espe.repository.invite ) : Promise< Array< { - id : _espe.type.invite_id; + id : _espe.type.invitation_id; preview : { name : string; }; @@ -207,14 +203,14 @@ namespace _espe.repository.invite /** */ export async function read( - id : _espe.type.invite_id - ) : Promise<_espe.type.invite_object> + id : _espe.type.invitation_id + ) : Promise<_espe.type.invitation_object> { const core_row : Record = await get_core_store().read(id); const group_hits : Array<{key : Record; preview : Record;}> = await get_group_chest().search( { - "expression": "invite_id = $invite_id", - "arguments": {"invite_id": id} + "expression": "invitation_id = $invitation_id", + "arguments": {"invitation_id": id} } ); @@ -234,13 +230,13 @@ namespace _espe.repository.invite /** */ export async function create( - value : _espe.type.invite_object - ) : Promise<_espe.type.invite_id> + value : _espe.type.invitation_object + ) : Promise<_espe.type.invitation_id> { const dispersal : type_dispersal = encode(value); // core - const id : _espe.type.invite_id = await get_core_store().create(dispersal.core_row); + const id : _espe.type.invitation_id = await get_core_store().create(dispersal.core_row); // groups for await (const group_row of dispersal.group_rows) { @@ -262,14 +258,14 @@ namespace _espe.repository.invite /** */ export async function delete_( - id : _espe.type.invite_id + id : _espe.type.invitation_id ) : Promise { // groups const hits : Array<{key : Array; preview : Record;}> = await get_group_chest().search( { - "expression": "invite_id = $invite_id", - "arguments": {"invite_id": id} + "expression": "invitation_id = $invitation_id", + "arguments": {"invitation_id": id} } ); for (const hit of hits) { @@ -285,16 +281,16 @@ namespace _espe.repository.invite * @todo optimize */ export async function identify( - key : _espe.type.invite_key - ) : Promise<_espe.type.invite_id> + key : _espe.type.invitation_key + ) : Promise<_espe.type.invitation_id> { - const hits : Array<{id : _espe.type.invite_id; preview : any;}> = await list(key); + const hits : Array<{id : _espe.type.invitation_id; preview : any;}> = await list(key); return ( (hits.length !== 1) ? - Promise.reject<_espe.type.invite_id>(new Error("not found")) + Promise.reject<_espe.type.invitation_id>(new Error("not found")) : - Promise.resolve<_espe.type.invite_id>(hits[0].id) + Promise.resolve<_espe.type.invitation_id>(hits[0].id) ); } @@ -305,8 +301,8 @@ namespace _espe.repository.invite ) : Promise< Array< { - id : _espe.type.invite_id; - object : _espe.type.invite_object; + id : _espe.type.invitation_id; + object : _espe.type.invitation_object; } > > diff --git a/source/repositories/member.ts b/source/repositories/member.ts index cf624d4..c4cab2b 100644 --- a/source/repositories/member.ts +++ b/source/repositories/member.ts @@ -88,7 +88,7 @@ namespace _espe.repository.member { "database_implementation": _espe.helpers.database_implementation(), "table_name": "member_groups", - "key_names": ["member_id","group_name"], + "key_names": ["member_id","group_id"], } ); } @@ -117,16 +117,9 @@ namespace _espe.repository.member { return { "core_row": { - "membership_number": object.membership_number, - "name_real_value": object.name_real_value, - "name_real_index": object.name_real_index, - "email_address_private": object.email_address_private, - "registered": _espe.helpers.dbbool_encode(object.registered), + "name": object.name, + "email_address": object.email_address, "enabled": _espe.helpers.dbbool_encode(object.enabled), - "email_use_veiled_address": _espe.helpers.dbbool_encode(object.email_use_veiled_address), - "email_use_nominal_address": _espe.helpers.dbbool_encode(object.email_use_nominal_address), - "email_redirect_to_private_address": _espe.helpers.dbbool_encode(object.email_redirect_to_private_address), - "email_allow_sending": _espe.helpers.dbbool_encode(object.email_allow_sending), "password_image": object.password_image, "password_change_last_attempt": object.password_change_last_attempt, "password_change_token": object.password_change_token, @@ -135,7 +128,7 @@ namespace _espe.repository.member object.groups .map( group => ({ - "group_name": group, + "group_id": group, }) ) ) @@ -150,22 +143,15 @@ namespace _espe.repository.member ) : _espe.type.member_object { return { - "membership_number": dispersal.core_row["membership_number"], - "name_real_value": dispersal.core_row["name_real_value"], - "name_real_index": dispersal.core_row["name_real_index"], - "email_address_private": dispersal.core_row["email_address_private"], - "groups": lib_plankton.list.sorted( - dispersal.group_rows.map(row => row["group_name"]), + "name": dispersal.core_row["name"], + "email_address": dispersal.core_row["email_address"], + "groups": lib_plankton.list.sorted<_espe.type.group_id>( + dispersal.group_rows.map(row => row["group_id"]), { "compare_element": (group1, group2) => (group1 <= group2) } ), - "registered": _espe.helpers.dbbool_decode(dispersal.core_row["registered"]), "enabled": _espe.helpers.dbbool_decode(dispersal.core_row["enabled"]), - "email_use_veiled_address": _espe.helpers.dbbool_decode(dispersal.core_row["email_use_veiled_address"]), - "email_use_nominal_address": _espe.helpers.dbbool_decode(dispersal.core_row["email_use_nominal_address"]), - "email_redirect_to_private_address": _espe.helpers.dbbool_decode(dispersal.core_row["email_redirect_to_private_address"]), - "email_allow_sending": _espe.helpers.dbbool_decode(dispersal.core_row["email_allow_sending"]), "password_image": dispersal.core_row["password_image"], "password_change_last_attempt": dispersal.core_row["password_change_last_attempt"], "password_change_token": dispersal.core_row["password_change_token"], @@ -183,9 +169,7 @@ namespace _espe.repository.member { id : _espe.type.member_id; preview : { - membership_number : string; - name_real_value : string; - name_real_index : int; + name : string; }; } > @@ -200,21 +184,17 @@ namespace _espe.repository.member || (search_term.length <= 1) ) - ? true - : ( - preview["membership_number"].toLowerCase().includes(search_term.toLowerCase()) - || - preview["name_real_value"].toLowerCase().includes(search_term.toLowerCase()) - ) + ? + true + : + preview["name"].toLowerCase().includes(search_term.toLowerCase()) ) ) .map( ({"key": key, "preview": preview}) => ({ "id": key, "preview": { - "membership_number": preview["membership_number"], - "name_real_value": preview["name_real_value"], - "name_real_index": preview["name_real_index"], + "name": preview["name"], } }) ) @@ -240,7 +220,7 @@ namespace _espe.repository.member "core_row": core_row, "group_rows": group_hits.map( hit => ({ - "group_name": hit.preview["group_name"] + "group_id": hit.preview["group_id"] }) ), }; @@ -265,7 +245,7 @@ namespace _espe.repository.member await get_group_chest().write( [ id, - group_row["group_name"], + group_row["group_id"], ], { "_dummy": null, @@ -293,11 +273,10 @@ namespace _espe.repository.member // groups const hits : Array<{key : Array; preview : Record;}> = await get_group_chest().search( { - "expression": "member_id = $member_id", + "expression": "group_id = $group_id", "arguments": {"member_id": id} } ); - lib_plankton.log.info("update_hit", hits); for (const hit of hits) { await get_group_chest().delete(hit.key); } @@ -305,7 +284,7 @@ namespace _espe.repository.member await get_group_chest().write( [ id, - group_row["group_name"], + group_row["group_id"], ], { "_dummy": null, diff --git a/source/repositories/name_index.ts b/source/repositories/name_index.ts deleted file mode 100644 index a3afda9..0000000 --- a/source/repositories/name_index.ts +++ /dev/null @@ -1,108 +0,0 @@ -/* -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 -. - */ - -namespace _espe.repository.name_index -{ - - /** - */ - var _chest : ( - null - | - lib_plankton.storage.type_chest< - Array, - Record, - lib_plankton.database.type_description_create_table, - lib_plankton.storage.sql_table_common.type_sql_table_common_search_term, - Record - > - ) = null; - - - /** - */ - function get_chest( - ) : lib_plankton.storage.type_chest< - Array, - Record, - lib_plankton.database.type_description_create_table, - lib_plankton.storage.sql_table_common.type_sql_table_common_search_term, - Record - > - { - if (_chest === null) { - _chest = lib_plankton.storage.sql_table_common.chest( - { - "database_implementation": _espe.helpers.database_implementation(), - "table_name": "name_indices", - "key_names": ["name_image"], - } - ); - } - else { - // do nothing - } - return _chest; - } - - - /** - */ - async function get_name_image( - name : string - ) : Promise - { - return ( - (! _espe.conf.get().settings.name_index.veil) - ? name - : await lib_plankton.sha256.get( - lib_plankton.json.encode(name), - (_espe.conf.get().settings.name_index.salt ?? undefined) - ) - ); - } - - - /** - */ - export async function read( - name : string - ) : Promise - { - const name_image : string = await get_name_image(name); - let row : Record; - try { - row = await get_chest().read([name_image]); - return row["index"]; - } - catch (error) { - return 0; - } - } - - - /** - */ - export async function write( - name : string, - index : int - ) : Promise - { - const name_image : string = await get_name_image(name); - await get_chest().write([name_image], {"index": index}); - } - -} - diff --git a/source/sample.ts b/source/sample.ts index d435d6b..cb9a93f 100644 --- a/source/sample.ts +++ b/source/sample.ts @@ -19,8 +19,15 @@ namespace _espe.sample /** */ type type_data = { + groups : Array< + { + id : int; + name : string; + } + >; admins : Array< { + id : int; name : string; email_address : (null | string); password : string; @@ -28,22 +35,21 @@ namespace _espe.sample >; members : Array< { - membership_number : string; - name_real : string; - email_address_private : (null | string); - groups : Array; + id : int; + name : string; + email_address : (null | string); + groups : Array; } >; - invites : Array< + invitations : Array< { - membership_number_changeable : boolean; - membership_number_value : string; + id : int; name_changeable : boolean; name_value : string; email_address_changeable : boolean; email_address_value : (null | string); groups_changeable : boolean; - groups_value : Array; + groups_value : Array; } >; }; @@ -55,9 +61,23 @@ namespace _espe.sample data : type_data ) : Promise { + const track_groups : Map = new Map(); + // groups + { + for (const group_raw of data.groups) + { + const group_id : _espe.type.group_id = await _espe.service.group.add( + { + "name": group_raw.name, + } + ); + track_groups.set(group_raw.id, group_id); + } + } // admins { - for (const admin_raw of data.admins) { + for (const admin_raw of data.admins) + { const admin_id : _espe.type.admin_id = await _espe.service.admin.add( admin_raw.name, admin_raw.email_address, @@ -67,13 +87,13 @@ namespace _espe.sample } // members { - for (const member_raw of data.members) { + for (const member_raw of data.members) + { const member_id : _espe.type.member_id = await _espe.service.member.project( { - "membership_number": member_raw.membership_number, - "name_real_value": member_raw.name_real, - "email_address_private": member_raw.email_address_private, - "groups": member_raw.groups + "name": member_raw.name, + "email_address": member_raw.email_address, + "groups": member_raw.groups.map(track_groups.get), }, { "silent": true, @@ -84,19 +104,18 @@ namespace _espe.sample * @todo passwords */ } - // invites + // invitations { - for (const invite_raw of data.invites) { - const result : {id : _espe.type.invite_id; key : _espe.type.invite_key;} = await _espe.service.invite.create( + for (const invitation_raw of data.invitations) + { + const result : {id : _espe.type.invitation_id; key : _espe.type.invitation_key;} = await _espe.service.invitation.create( { - "membership_number_changeable": invite_raw.membership_number_changeable, - "membership_number_value": invite_raw.membership_number_value, - "name_changeable": invite_raw.name_changeable, - "name_value": invite_raw.name_value, - "email_address_changeable": invite_raw.email_address_changeable, - "email_address_value": invite_raw.email_address_value, - "groups_changeable": invite_raw.groups_changeable, - "groups_value": invite_raw.groups_value, + "name_changeable": invitation_raw.name_changeable, + "name_value": invitation_raw.name_value, + "email_address_changeable": invitation_raw.email_address_changeable, + "email_address_value": invitation_raw.email_address_value, + "groups_changeable": invitation_raw.groups_changeable, + "groups_value": invitation_raw.groups_value.map(track_groups.get), } ); } diff --git a/source/services/name_index.ts b/source/services/group.ts similarity index 72% rename from source/services/name_index.ts rename to source/services/group.ts index df4d45e..123b295 100644 --- a/source/services/name_index.ts +++ b/source/services/group.ts @@ -13,19 +13,16 @@ You should have received a copy of the GNU General Public License along with thi . */ -namespace _espe.service.name_index +namespace _espe.service.group { /** */ - export async function next( - name : string - ) : Promise + export function add( + group_object : _espe.type.group_object + ) : Promise<_espe.type.group_id> { - const current : int = await _espe.repository.name_index.read(name); - const result : int = (current + 1); - await _espe.repository.name_index.write(name, result); - return result; + return _espe.repository.group.create(group_object); } } diff --git a/source/services/invite.ts b/source/services/invitation.ts similarity index 63% rename from source/services/invite.ts rename to source/services/invitation.ts index ccc3e06..5a3b56e 100644 --- a/source/services/invite.ts +++ b/source/services/invitation.ts @@ -13,7 +13,7 @@ You should have received a copy of the GNU General Public License along with thi . */ -namespace _espe.service.invite +namespace _espe.service.invitation { /** @@ -22,16 +22,16 @@ namespace _espe.service.invite ) : Promise< Array< { - id : _espe.type.invite_id; - key : _espe.type.invite_key; + id : _espe.type.invitation_id; + key : _espe.type.invitation_key; expiry : (null | int); - name_value : string; + name_value : (null | string); } > > { return ( - _espe.repository.invite.dump() + _espe.repository.invitation.dump() .then( entries => Promise.resolve( entries.map( @@ -52,8 +52,6 @@ namespace _espe.service.invite */ export async function create( { - "membership_number_changeable": membership_number_changeable, - "membership_number_value": membership_number_value, "name_changeable": name_changeable, "name_value": name_value, "email_address_changeable": email_address_changeable, @@ -61,14 +59,12 @@ namespace _espe.service.invite "groups_changeable": groups_changeable, "groups_value": groups_value, } : { - membership_number_changeable : boolean; - membership_number_value : (null | string); name_changeable : boolean; name_value : string; email_address_changeable : boolean; email_address_value : (null | string); groups_changeable : boolean; - groups_value : Array; + groups_value : Array<_espe.type.group_id>; }, { "expiry": expiry = -1, @@ -80,7 +76,7 @@ namespace _espe.service.invite send_immediatly ?: boolean; } = { } - ) : Promise<{id : _espe.type.invite_id; key : _espe.type.invite_key}> + ) : Promise<{id : _espe.type.invitation_id; key : _espe.type.invitation_key}> { /** * @todo outsource to conf @@ -89,7 +85,7 @@ namespace _espe.service.invite /** * @todo proper salt */ - const invite_key : _espe.type.invite_key = lib_plankton.sha256.get( + const invitation_key : _espe.type.invitation_key = lib_plankton.sha256.get( ( name_value + @@ -99,8 +95,8 @@ namespace _espe.service.invite ), "secret" ); - const invite_object : _espe.type.invite_object = { - "key": invite_key, + const invitation_object : _espe.type.invitation_object = { + "key": invitation_key, "expiry": ( ((expiry !== null) && (expiry < 0)) ? @@ -108,8 +104,6 @@ namespace _espe.service.invite : expiry ), - "membership_number_changeable": membership_number_changeable, - "membership_number_value": membership_number_value, "name_changeable": name_changeable, "name_value": name_value, "email_address_changeable": email_address_changeable, @@ -117,7 +111,7 @@ namespace _espe.service.invite "groups_changeable": groups_changeable, "groups_value": groups_value, }; - const invite_id : _espe.type.invite_id = await _espe.repository.invite.create(invite_object); + const invitation_id : _espe.type.invitation_id = await _espe.repository.invitation.create(invitation_object); // send link { if (! send_immediatly) @@ -139,7 +133,7 @@ namespace _espe.service.invite ) { lib_plankton.log._warning( - "espe.service.invite.create.email.condition_unmet", + "espe.service.invitation.create.email.condition_unmet", { "details": { "provided_address": email_address_value, @@ -153,7 +147,7 @@ namespace _espe.service.invite const url : (null | string) = _espe.helpers.frontend_url_get( notification_target_url_template, { - "key": invite_key, + "key": invitation_key, } ); try { @@ -175,7 +169,7 @@ namespace _espe.service.invite catch (error) { lib_plankton.log._error( - "espe.service.invite.create.email.could_not_be_sent", + "espe.service.invitation.create.email.could_not_be_sent", { "details": { "provided_address": email_address_value, @@ -188,8 +182,8 @@ namespace _espe.service.invite } } return { - "id": invite_id, - "key": invite_key, + "id": invitation_id, + "key": invitation_key, }; } @@ -197,23 +191,23 @@ namespace _espe.service.invite /** */ export function get_by_id( - id : _espe.type.invite_id - ) : Promise<_espe.type.invite_object> + id : _espe.type.invitation_id + ) : Promise<_espe.type.invitation_object> { - return _espe.repository.invite.read(id) + return _espe.repository.invitation.read(id) } /** */ function get_by_key( - key : _espe.type.invite_key - ) : Promise<_espe.type.invite_object> + key : _espe.type.invitation_key + ) : Promise<_espe.type.invitation_object> { return ( - _espe.repository.invite.identify(key) + _espe.repository.invitation.identify(key) .then( - (id) => _espe.repository.invite.read(id) + (id) => _espe.repository.invitation.read(id) ) ); } @@ -222,26 +216,26 @@ namespace _espe.service.invite /** */ export async function examine( - key : _espe.type.invite_key - ) : Promise<_espe.type.invite_object> + key : _espe.type.invitation_key + ) : Promise<_espe.type.invitation_object> { - let invite_object : (null | _espe.type.invite_object); + let invitation_object : (null | _espe.type.invitation_object); try { - invite_object = await get_by_key(key); + invitation_object = await get_by_key(key); } catch (error) { - invite_object = null; + invitation_object = null; } - if (invite_object === null) { + if (invitation_object === null) { return Promise.reject(new Error("not found")) } else { const now : int = lib_plankton.base.get_current_timestamp(true); - if ((invite_object.expiry !== null) && (invite_object.expiry < now)) { + if ((invitation_object.expiry !== null) && (invitation_object.expiry < now)) { return Promise.reject(new Error("expired")); } else { - return Promise.resolve(invite_object); + return Promise.resolve(invitation_object); } } } @@ -250,11 +244,10 @@ namespace _espe.service.invite /** */ export async function accept( - key : _espe.type.invite_key, + key : _espe.type.invitation_key, data : { - membership_number : (null | string); - groups : Array; name : (null | string); + groups : (null | Array<_espe.type.group_id>); email_address : (null | string); password : (null | string); } @@ -268,13 +261,13 @@ namespace _espe.service.invite > > { - const invite_id : _espe.type.invite_id = await _espe.repository.invite.identify(key); + const invitation_id : _espe.type.invitation_id = await _espe.repository.invitation.identify(key); /** * might throw, but that's fine, since caught and handled in the API action */ - const invite_object : _espe.type.invite_object = await _espe.repository.invite.read(invite_id); + const invitation_object : _espe.type.invitation_object = await _espe.repository.invitation.read(invitation_id); const now : int = lib_plankton.base.get_current_timestamp(true); - if ((invite_object.expiry !== null) && (invite_object.expiry < now)) + if ((invitation_object.expiry !== null) && (invitation_object.expiry < now)) { return Promise.reject(new Error("expired")); } @@ -306,51 +299,57 @@ namespace _espe.service.invite } else { - const member_id : _espe.type.member_id = await _espe.service.member.add( - { - "membership_number": ( - invite_object.membership_number_changeable - ? - data.membership_number - : - invite_object.membership_number_value - ), - "name_real_value": ( - ( - invite_object.name_changeable - && - (data.name !== null) - ) - ? - data.name - : - invite_object.name_value - ), - "email_address_private": ( - ( - invite_object.email_address_changeable - && - (data.email_address !== null) - ) - ? - data.email_address - : - invite_object.email_address_value - ), - "groups": ( - invite_object.groups_changeable - ? - data.groups - : - invite_object.groups_value - ), - "password": password, - } - ); - - await _espe.repository.invite.delete_(invite_id); - - return []; + if ( + (invitation_object.name_value === null) + && + (data.name === null) + ) + { + throw (new Error("no name provided")); + } + else + { + const member_id : _espe.type.member_id = await _espe.service.member.add( + { + "name": ( + ( + invitation_object.name_changeable + ? + data.name + : + invitation_object.name_value + ) as string + ), + "email_address": ( + ( + invitation_object.email_address_changeable + && + (data.email_address !== null) + ) + ? + data.email_address + : + invitation_object.email_address_value + ), + "groups": ( + ( + invitation_object.groups_changeable + ? + data.groups + : + invitation_object.groups_value + ) + ?? + [] + ), + "password": password, + } + ); + + await _espe.repository.invitation.delete_(invitation_id); + + return []; + } } } } diff --git a/source/services/member.ts b/source/services/member.ts index e8b6e70..448f19c 100644 --- a/source/services/member.ts +++ b/source/services/member.ts @@ -79,7 +79,7 @@ namespace _espe.service.member "{{object}}{{extension}}", { "object": lib_plankton.call.convey( - object.name_real_value, + object.name, [ (x : string) => x.toLowerCase(), (x : string) => x.replace(new RegExp(" ", "g"), "."), @@ -90,11 +90,7 @@ namespace _espe.service.member (x : string) => x.replace(new RegExp("[^0-9a-z-\.]", "g"), "_"), ] ), - "extension": ( - (object.name_real_index <= 1) - ? "" - : ("." + object.name_real_index.toFixed(0)) - ), + "extension": "", } ); } @@ -107,46 +103,7 @@ namespace _espe.service.member object : _espe.type.member_object ) : string { - return object.name_real_value; - } - - - /** - * ermittelt die verschleierte E-Mail-Adresse des Mitglieds - */ - export function email_address_veiled( - object : _espe.type.member_object - ) : (null | string) - { - return ( - (object.membership_number === null) - ? null - : lib_plankton.string.coin( - "{{prefix}}{{membership_number}}@{{domain}}", - { - "prefix": _espe.conf.get().settings.misc.prefix_for_veiled_email_addresses, - "membership_number": object.membership_number, - "domain": _espe.conf.get().settings.organisation.domain, - } - ) - ); - } - - - /** - * ermittelt die namentliche E-Mail-Adresse des Mitglieds - */ - export 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.organisation.domain, - } - ); + return object.name; } @@ -157,15 +114,7 @@ namespace _espe.service.member 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 - ) - ); + return object.email_address; } @@ -207,13 +156,15 @@ namespace _espe.service.member // do nothing } else { - if (member_object.email_address_private === null) { + if (member_object.email_address === null) + { // do nothing } - else { + else + { await _espe.helpers.email_send( [ - member_object.email_address_private, + member_object.email_address, ], lib_plankton.string.coin( "{{head}} | {{core}}", @@ -277,9 +228,7 @@ namespace _espe.service.member { id : _espe.type.member_id; preview : { - membership_number : string; - name_real_value : string; - name_real_index : int; + name : string; }; } > @@ -306,10 +255,9 @@ namespace _espe.service.member */ export async function project( data : { - membership_number : (null | string); - name_real_value : string; - email_address_private : (null | string); - groups : Array; + name : string; + email_address : (null | string); + groups : Array<_espe.type.group_id>; }, { "silent": silent = false, @@ -319,28 +267,22 @@ namespace _espe.service.member } ) : Promise<_espe.type.member_id> { - 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, - "email_address_private": data.email_address_private, - "registered": false, + "name": data.name, + "email_address": data.email_address, + "groups": data.groups, "enabled": true, - "email_use_veiled_address": false, - "email_use_nominal_address": false, - "email_redirect_to_private_address": false, - "email_allow_sending": false, "password_image": null, "password_change_last_attempt": null, "password_change_token": null, - "groups": data.groups, }; const id : _espe.type.member_id = await _espe.repository.member.create(object); - if (silent) { + if (silent) + { // do nothing } - else { + else + { signal_change(); } return id; @@ -352,10 +294,9 @@ namespace _espe.service.member */ export async function add( data : { - membership_number : (null | string); - name_real_value : string; - email_address_private : (null | string); - groups : Array; + name : string; + email_address : (null | string); + groups : Array<_espe.type.group_id>; password : string; }, { @@ -366,22 +307,14 @@ namespace _espe.service.member } ) : Promise<_espe.type.member_id> { - 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, - "email_address_private": data.email_address_private, - "registered": false, + "name": data.name, + "email_address": data.email_address, + "groups": data.groups, "enabled": true, - "email_use_veiled_address": false, - "email_use_nominal_address": false, - "email_redirect_to_private_address": false, - "email_allow_sending": false, "password_image": await password_image(data.password), "password_change_last_attempt": null, "password_change_token": null, - "groups": data.groups, }; const id : _espe.type.member_id = await _espe.repository.member.create(object); if (silent) @@ -406,10 +339,12 @@ namespace _espe.service.member { _espe.helpers.frontend_url_check(); const member_object : _espe.type.member_object = await get(member_id); - if (member_object.email_address_private === null) { + if (member_object.email_address === null) + { return null; } - else { + else + { const url : (null | string) = _espe.helpers.frontend_url_get( url_template, { @@ -422,7 +357,7 @@ namespace _espe.service.member else { await _espe.helpers.email_send( [ - member_object.email_address_private, + member_object.email_address, ], lib_plankton.string.coin( "{{head}} | {{core}}", @@ -450,176 +385,31 @@ namespace _espe.service.member } - /** - * gibt Daten über ein Mitglied aus, die relevant für die Registrierung sind - */ - 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 : (null | 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; - } - } - - - /** - * führt die Registrierung für ein Mitglied durch - */ - 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 : (null | string); - }, - options : { - notification_target_url_template ?: (null | string); - } = {} - ) : Promise;}>> - { - options = Object.assign( - { - "notification_target_url_template": null, - }, - options - ); - - const member_object : _espe.type.member_object = await get(member_id); - - let flaws : Array<{incident : string; details : Record;}> = []; - let password_value : string; - let password_generated : boolean; - if (member_object.registered) { - flaws.push({"incident": "already_registered", "details": {}}); - password_value = ""; - password_generated = false; - } - else { - if ( - (data.password !== null) - && - (data.password !== "") - ) { - flaws = flaws.concat( - validate_password(data.password) - .map(flaw => ({"incident": ("password_" + flaw.incident), "details": flaw.details})) - ); - password_value = data.password; - password_generated = false; - } - else { - password_value = generate_password(); - password_generated = true; - } - } - - if (flaws.length > 0) { - // do nothing - } - 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 password_image(password_value); - member_object.registered = true; - await _espe.repository.member.update(member_id, member_object); - signal_change(); - { - const url : (null | string) = ( - ( - (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), - } - ) - ); - /*await*/ _espe.service.admin.notify_all( - 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 ?? "?"), - } - ) - ); - } - /*await*/ send_activation_email(member_object, {"password": password_generated ? password_value : null}); - } - - return Promise.resolve(flaws); - } - - /** * ändert bestimmte Daten des Mitglied */ export async function modify( member_id : _espe.type.member_id, data : { - email_address_private : (null | string); - registered : boolean; + email_address : (null | string); enabled : boolean; - groups : lib_plankton.pod.type_pod>; + groups : lib_plankton.pod.type_pod>; } ) : Promise { 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, + "name": member_object_old.name, + "email_address": data.email_address, + "groups": ( + lib_plankton.pod.is_filled>(data.groups) + ? lib_plankton.pod.cull>(data.groups) + : member_object_old.groups + ), "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, "password_change_last_attempt": member_object_old.password_change_last_attempt, "password_change_token": member_object_old.password_change_token, - "groups": ( - lib_plankton.pod.is_filled>(data.groups) - ? lib_plankton.pod.cull>(data.groups) - : member_object_old.groups - ), }; await _espe.repository.member.update(member_id, member_object_new); signal_change(); @@ -655,15 +445,13 @@ namespace _espe.service.member (await _espe.repository.member.dump()) .filter( member_entry => ( - member_entry.object.registered - && member_entry.object.enabled && ( ( - (! (member_entry.object.email_address_private === null)) + (! (member_entry.object.email_address === null)) && - (member_entry.object.email_address_private === identifier) + (member_entry.object.email_address === identifier) ) || (name_login(member_entry.object) === identifier) @@ -692,9 +480,9 @@ namespace _espe.service.member // do nothing } else { - if (member_object_old.email_address_private === null) { + if (member_object_old.email_address === null) { lib_plankton.log.notice( - "member_password_change_impossible_due_to_missing_private_email_address", + "member_password_change_impossible_due_to_missing_email_address", { "member_id": member_id, } @@ -705,20 +493,13 @@ namespace _espe.service.member // 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, + "name": member_object_old.name, + "email_address": member_object_old.email_address, "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, + "groups": member_object_old.groups, "password_image": member_object_old.password_image, "password_change_last_attempt": now, "password_change_token": token, - "groups": member_object_old.groups, }; await _espe.repository.member.update(member_id, member_object_new); // signal_change(); @@ -736,7 +517,7 @@ namespace _espe.service.member else { /*await*/ _espe.helpers.email_send( [ - member_object_old.email_address_private, + member_object_old.email_address, ], lib_plankton.string.coin( "{{head}} | {{core}}", @@ -772,10 +553,12 @@ namespace _espe.service.member ) : Promise;}>> { const member_object_old : _espe.type.member_object = await _espe.repository.member.read(member_id); - if (member_object_old.email_address_private === null) { + if (member_object_old.email_address === null) + { return Promise.reject(new Error("private e-mail address missing")); } - else { + else + { let flaws : Array<{incident : string; details : Record;}> = []; if ( (member_object_old.password_change_token === null) @@ -801,26 +584,19 @@ namespace _espe.service.member } 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, + "name": member_object_old.name, + "email_address": member_object_old.email_address, + "groups": member_object_old.groups, "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, - "groups": member_object_old.groups, }; await _espe.repository.member.update(member_id, member_object_new); signal_change(); await _espe.helpers.email_send( [ - member_object_old.email_address_private, + member_object_old.email_address, ], lib_plankton.string.coin( "{{head}} | {{core}}", @@ -903,6 +679,9 @@ namespace _espe.service.member "disabled": (! entry.object.enabled), "displayname": name_display(entry.object), "email": entry.email_address, + /** + * @todo covert to string + */ "groups": entry.object.groups, "password": entry.object.password_image, } diff --git a/source/types.ts b/source/types.ts index 441bddf..0156eb3 100644 --- a/source/types.ts +++ b/source/types.ts @@ -16,6 +16,18 @@ You should have received a copy of the GNU General Public License along with thi namespace _espe.type { + /** + */ + export type group_id = int; + + + /** + */ + export type group_object = { + name : string; + }; + + /** */ export type admin_id = int; @@ -39,17 +51,10 @@ namespace _espe.type /** */ export type member_object = { - membership_number : (null | string); - name_real_value : string; - name_real_index : int; - email_address_private : (null | string); - groups : Array; - registered : boolean; + name : string; + email_address : (null | string); + groups : Array; enabled : boolean; - email_use_veiled_address : boolean; - email_use_nominal_address : boolean; - email_redirect_to_private_address : boolean; - email_allow_sending : boolean; password_image : (null | string); password_change_last_attempt : (null | int); password_change_token : (null | string); @@ -58,27 +63,26 @@ namespace _espe.type /** */ - export type invite_id = int; + export type invitation_id = int; /** */ - export type invite_key = string; + export type invitation_key = string; /** + * @todo use "pod" instead of "changable"/"value" */ - export type invite_object = { - key : invite_key; + export type invitation_object = { + key : invitation_key; expiry : (null | int); - membership_number_changeable : boolean; - membership_number_value : (null | string); name_changeable : boolean; - name_value : string; + name_value : (null | string); email_address_changeable : boolean; email_address_value : (null | string); groups_changeable : boolean; - groups_value : Array; + groups_value : (null | Array<_espe.type.group_id>); }; } diff --git a/tools/makefile b/tools/makefile index fdd7da5..95edf91 100644 --- a/tools/makefile +++ b/tools/makefile @@ -48,23 +48,20 @@ ${dir_temp}/espe-core.js ${dir_temp}/espe-core.d.ts: \ ${dir_source}/helpers/password.ts \ ${dir_source}/database.ts \ ${dir_source}/types.ts \ + ${dir_source}/repositories/group.ts \ ${dir_source}/repositories/admin.ts \ - ${dir_source}/repositories/name_index.ts \ ${dir_source}/repositories/member.ts \ - ${dir_source}/repositories/invite.ts \ + ${dir_source}/repositories/invitation.ts \ + ${dir_source}/services/group.ts \ ${dir_source}/services/admin.ts \ - ${dir_source}/services/name_index.ts \ ${dir_source}/services/member.ts \ - ${dir_source}/services/invite.ts \ + ${dir_source}/services/invitation.ts \ ${dir_source}/api/base.ts \ ${dir_source}/api/actions/meta_ping.ts \ ${dir_source}/api/actions/meta_spec.ts \ ${dir_source}/api/actions/session_begin.ts \ ${dir_source}/api/actions/session_end.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/actions/member_list.ts \ ${dir_source}/api/actions/member_read.ts \ ${dir_source}/api/actions/member_modify.ts \