[add] api-aktion "member_urge_for_registration" [mod] E-Mail-Versand

This commit is contained in:
roydfalk 2024-04-23 17:44:31 +02:00
parent 5507cbdcfd
commit e7fbf628d3
6 changed files with 251 additions and 37 deletions

View file

@ -34,6 +34,7 @@ namespace _espe.api
"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,
@ -47,17 +48,28 @@ namespace _espe.api
"password": input.password,
}
);
return Promise.resolve({
"status_code": 200,
"data": null,
});
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,
});
}
},
}
)

View file

@ -0,0 +1,50 @@
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,
});
}
}
);
}
}

View file

@ -27,7 +27,7 @@ namespace _espe.api
_espe.api.register_email(rest_subject);
// verification
{
_espe.api.register_verification_get(rest_subject);
// _espe.api.register_verification_get(rest_subject);
// _espe.api.register_verification_check(rest_subject);
}
// member
@ -38,6 +38,7 @@ namespace _espe.api
_espe.api.register_member_update(rest_subject);
// _espe.api.register_member_delete(rest_subject);
_espe.api.register_member_register(rest_subject);
_espe.api.register_member_urge_for_registration(rest_subject);
}

View file

@ -1,6 +1,16 @@
namespace _espe.conf
{
/**
*/
type type_smtp_credentials = {
host : string;
port : int;
username : string;
password : string;
};
/**
*/
export type type_conf = {
@ -42,27 +52,36 @@ namespace _espe.conf
};
}
);
email_sending : {
mode : (
"regular"
|
"redirect"
|
"console"
|
"drop"
);
smtp_credentials : (
null
email_sending : (
{
kind : "regular";
data : {
smtp_credentials : type_smtp_credentials;
sender : string;
};
}
|
{
host : string;
port : int;
username : string;
password : string;
kind : "redirect";
data : {
smtp_credentials : type_smtp_credentials;
sender : string;
target : string;
};
}
|
{
kind : "console";
data : {
};
}
|
{
kind : "drop";
data : {
};
}
);
};
session_management : {
lifetime : int;
drop_all_at_start : boolean;
@ -70,12 +89,17 @@ namespace _espe.conf
settings : {
target_domain : string;
prefix_for_numberbased_email_addresses : string;
registration_email : {
subject : string;
body : string;
};
};
// TODO: evtl. in Datenbank verlagern
admins : Array<
{
name : string;
password_image : string;
email_address : (null | string);
}
>;
};
@ -122,12 +146,14 @@ namespace _espe.conf
"path": (node_database_data_raw["path"] ?? "data.sqlite"),
}
};
break;
}
case "postgresql": {
return {
"kind": kind,
"data": node_database_data_raw,
};
break;
}
default: {
throw (new Error("unhandled"));
@ -137,10 +163,53 @@ namespace _espe.conf
}) (conf_raw["database"] ?? {})
),
"email_sending": (
((node_email_sending) => ({
"mode": (node_email_sending["mode"] ?? "regular"),
"smtp_credentials": (node_email_sending["smtp_credentials"] ?? null),
})) (conf_raw["email_sending"] ?? {})
((node_email_sending) => {
const kind : string = (node_email_sending["kind"] ?? "regular");
const data_raw = (node_email_sending["data"] ?? {});
switch (kind) {
case "regular": {
return {
"kind": kind,
"data": {
"smtp_credentials": data_raw["smtp_credentials"],
"sender": data_raw["sender"],
}
};
break;
}
case "redirect": {
return {
"kind": kind,
"data": {
"smtp_credentials": data_raw["smtp_credentials"],
"sender": data_raw["sender"],
"target": data_raw["target"],
}
};
break;
}
case "console": {
return {
"kind": kind,
"data": {
}
};
break;
}
case "drop": {
return {
"kind": kind,
"data": {
}
};
break;
}
default: {
throw (new Error("unhandled"));
break;
}
}
}) (conf_raw["email_sending"] ?? {})
),
"session_management": (
((node_session_management) => ({
@ -152,6 +221,10 @@ namespace _espe.conf
((node_settings) => ({
"target_domain": (node_settings["target_domain"] ?? "example.org"),
"prefix_for_numberbased_email_addresses": (node_settings["prefix_for_numberbased_email_addresses"] ?? "member-"),
"registration_email": {
"subject": ((node_settings["registration_email"] ?? {})["subject"] ?? "Registration"),
"body": ((node_settings["registration_email"] ?? {})["body"] ?? "URL: {{url}}"),
},
})) (conf_raw["settings"] ?? {})
),
"admins": (conf_raw["admins"] ?? []),

View file

@ -99,6 +99,61 @@ namespace _espe.helpers
}
/**
* @todo outsource?
*/
async function email_send_real(
smtp_credentials : {
host : string;
port : int;
username : string;
password : string;
},
receivers : Array<string>,
subject : string,
content : string,
options : {
sender ?: (null | string);
} = {}
) : Promise<void>
{
options = Object.assign(
{
"sender": /*null*/"admin@example.org",
},
options
);
lib_plankton.log.info(
"email_send_real",
{
"receivers": receivers,
"subject": subject,
}
);
const nm_nodemailer = require("nodemailer");
const transporter = nm_nodemailer.createTransport(
{
"host": smtp_credentials.host,
"port": smtp_credentials.port,
"secure": false,
"auth": {
"user": smtp_credentials.username,
"pass": smtp_credentials.password,
},
"debug": true,
}
);
const info = await transporter.sendMail(
{
"from": (options.sender ?? ""),
"to": receivers.join(", "),
"subject": subject,
"text": content,
}
)
}
/**
*/
export async function email_send(
@ -107,7 +162,7 @@ namespace _espe.helpers
content : string
) : Promise<void>
{
const mode : string = _espe.conf.get().email_sending.mode;
const mode : string = _espe.conf.get().email_sending.kind;
lib_plankton.log.info(
"email_send",
{
@ -118,20 +173,42 @@ namespace _espe.helpers
);
switch (mode) {
case "regular": {
if (_espe.conf.get().email_sending.smtp_credentials === null) {
return Promise.reject<void>("no smtp credentials specified; add in conf as 'email_sending.smtp_credentials'!");
if (_espe.conf.get().email_sending.data["smtp_credentials"] === null) {
return Promise.reject<void>("no smtp credentials specified; add in conf as 'email_sending.data.smtp_credentials'!");
}
else {
// TODO
return email_send_real(
_espe.conf.get().email_sending.data["smtp_credentials"],
receivers,
subject,
content,
{
"sender": _espe.conf.get().email_sending.data["sender"],
}
);
}
break;
}
case "redirect": {
if (_espe.conf.get().email_sending.smtp_credentials === null) {
return Promise.reject<void>("no smtp credentials specified; add in conf as 'email_sending.smtp_credentials'!");
if (_espe.conf.get().email_sending.data["smtp_credentials"] === null) {
return Promise.reject<void>("no smtp credentials specified; add in conf as 'email_sending.data.smtp_credentials'!");
}
else {
// TODO
return email_send_real(
_espe.conf.get().email_sending.data["smtp_credentials"],
[_espe.conf.get().email_sending.data["target"]],
lib_plankton.string.coin(
"[REDIRECTION] {{receivers}} | {{original_subject}}",
{
"receivers": receivers.join(", "),
"original_subject": subject
}
),
content,
{
"sender": _espe.conf.get().email_sending.data["sender"],
}
);
}
break;
}

View file

@ -41,6 +41,7 @@ ${dir_temp}/espe-unlinked.js: \
${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_urge_for_registration.ts \
${dir_source}/api/actions/member_register.ts \
${dir_source}/api/functions.ts \
${dir_source}/conf.ts \