Merge pull request 'Gruppen' (#1) from task-70 into main
Reviewed-on: #1
This commit is contained in:
commit
4096014bad
7 changed files with 254 additions and 68 deletions
|
@ -25,6 +25,7 @@ namespace _espe.api
|
|||
register<
|
||||
{
|
||||
email_address_private : (null | string);
|
||||
groups ?: Array<string>;
|
||||
registered : boolean;
|
||||
enabled : boolean;
|
||||
},
|
||||
|
@ -43,6 +44,14 @@ namespace _espe.api
|
|||
"nullable": true,
|
||||
"type": "string"
|
||||
},
|
||||
"groups": {
|
||||
"nullable": false,
|
||||
"type": "array",
|
||||
"items": {
|
||||
"type": "string",
|
||||
"nullable": false,
|
||||
}
|
||||
},
|
||||
"registered": {
|
||||
"nullable": false,
|
||||
"type": "boolean"
|
||||
|
@ -73,6 +82,11 @@ namespace _espe.api
|
|||
member_id,
|
||||
{
|
||||
"email_address_private": input.email_address_private,
|
||||
"groups": (
|
||||
(input.groups === undefined)
|
||||
? lib_plankton.pod.make_empty<Array<string>>()
|
||||
: lib_plankton.pod.make_filled<Array<string>>(input.groups)
|
||||
),
|
||||
"registered": input.registered,
|
||||
"enabled": input.enabled,
|
||||
}
|
||||
|
|
|
@ -27,6 +27,7 @@ namespace _espe.api
|
|||
membership_number : (null | string);
|
||||
name_real_value : string;
|
||||
email_address_private : (null | string);
|
||||
groups ?: Array<string>;
|
||||
notification_target_url_template ?: (null | string);
|
||||
},
|
||||
(
|
||||
|
@ -60,6 +61,14 @@ namespace _espe.api
|
|||
"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,
|
||||
|
@ -109,6 +118,7 @@ namespace _espe.api
|
|||
)
|
||||
: null
|
||||
),
|
||||
"groups": (input.groups ?? []),
|
||||
}
|
||||
);
|
||||
if (! _espe.conf.get().settings.misc.auto_register) {
|
||||
|
|
|
@ -29,6 +29,7 @@ namespace _espe.api
|
|||
name_real_value : string;
|
||||
name_real_index : int;
|
||||
email_address_private : (null | string);
|
||||
groups : Array<string>;
|
||||
registered : boolean;
|
||||
enabled : boolean;
|
||||
email_use_veiled_address : boolean;
|
||||
|
@ -66,6 +67,14 @@ namespace _espe.api
|
|||
"nullable": true,
|
||||
"type": "string"
|
||||
},
|
||||
"groups": {
|
||||
"nullable": false,
|
||||
"type": "array",
|
||||
"items": {
|
||||
"nullable": false,
|
||||
"type": "string"
|
||||
}
|
||||
},
|
||||
"registered": {
|
||||
"nullable": false,
|
||||
"type": "boolean"
|
||||
|
@ -113,6 +122,7 @@ namespace _espe.api
|
|||
"name_real_value",
|
||||
"name_real_index",
|
||||
"email_address_private",
|
||||
"groups",
|
||||
"registered",
|
||||
"enabled",
|
||||
"email_use_veiled_address",
|
||||
|
@ -136,6 +146,7 @@ namespace _espe.api
|
|||
"name_real_value": member_object.name_real_value,
|
||||
"name_real_index": member_object.name_real_index,
|
||||
"email_address_private": member_object.email_address_private,
|
||||
"groups": member_object.groups,
|
||||
"registered": member_object.registered,
|
||||
"enabled": member_object.enabled,
|
||||
"email_use_veiled_address": member_object.email_use_veiled_address,
|
||||
|
|
|
@ -19,7 +19,7 @@ namespace _espe.database
|
|||
/**
|
||||
*/
|
||||
const _compatible_revisions : Array<string> = [
|
||||
"r4",
|
||||
"r5",
|
||||
];
|
||||
|
||||
|
||||
|
|
|
@ -15,10 +15,21 @@ You should have received a copy of the GNU General Public License along with thi
|
|||
|
||||
namespace _espe.repository.member
|
||||
{
|
||||
|
||||
/**
|
||||
*/
|
||||
type type_group_chest = lib_plankton.storage.type_chest<
|
||||
Array<any>,
|
||||
Record<string, any>,
|
||||
lib_plankton.database.type_description_create_table,
|
||||
lib_plankton.storage.sql_table_common.type_sql_table_common_search_term,
|
||||
Record<string, any>
|
||||
>;
|
||||
|
||||
|
||||
/**
|
||||
*/
|
||||
var _store : (
|
||||
var _core_store : (
|
||||
null
|
||||
|
|
||||
lib_plankton.storage.type_store<
|
||||
|
@ -33,7 +44,16 @@ namespace _espe.repository.member
|
|||
|
||||
/**
|
||||
*/
|
||||
function get_store(
|
||||
var _group_chest : (
|
||||
null
|
||||
|
|
||||
type_group_chest
|
||||
) = null;
|
||||
|
||||
|
||||
/**
|
||||
*/
|
||||
function get_core_store(
|
||||
) : lib_plankton.storage.type_store<
|
||||
_espe.type.member_id,
|
||||
Record<string, any>,
|
||||
|
@ -42,8 +62,8 @@ namespace _espe.repository.member
|
|||
Record<string, any>
|
||||
>
|
||||
{
|
||||
if (_store === null) {
|
||||
_store = lib_plankton.storage.sql_table_autokey_store(
|
||||
if (_core_store === null) {
|
||||
_core_store = lib_plankton.storage.sql_table_autokey_store(
|
||||
{
|
||||
"database_implementation": _espe.helpers.database_implementation(),
|
||||
"table_name": "members",
|
||||
|
@ -54,30 +74,71 @@ namespace _espe.repository.member
|
|||
else {
|
||||
// do nothing
|
||||
}
|
||||
return _store;
|
||||
return _core_store;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
*/
|
||||
function get_group_chest(
|
||||
) : type_group_chest
|
||||
{
|
||||
if (_group_chest === null) {
|
||||
_group_chest = lib_plankton.storage.sql_table_common.chest(
|
||||
{
|
||||
"database_implementation": _espe.helpers.database_implementation(),
|
||||
"table_name": "member_groups",
|
||||
"key_names": ["member_id","group_name"],
|
||||
}
|
||||
);
|
||||
}
|
||||
else {
|
||||
// do nothing
|
||||
}
|
||||
return _group_chest;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
*/
|
||||
type type_dispersal = {
|
||||
core_row : Record<string, any>;
|
||||
group_rows : Array<
|
||||
Record<string, any>
|
||||
>;
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
*/
|
||||
function encode(
|
||||
object : _espe.type.member_object
|
||||
) : Record<string, any>
|
||||
) : type_dispersal
|
||||
{
|
||||
return {
|
||||
"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": (object.registered ? 1 : 0),
|
||||
"enabled": (object.enabled ? 1 : 0),
|
||||
"email_use_veiled_address": (object.email_use_veiled_address ? 1 : 0),
|
||||
"email_use_nominal_address": (object.email_use_nominal_address ? 1 : 0),
|
||||
"email_redirect_to_private_address": (object.email_redirect_to_private_address ? 1 : 0),
|
||||
"email_allow_sending": (object.email_allow_sending ? 1 : 0),
|
||||
"password_image": object.password_image,
|
||||
"password_change_last_attempt": object.password_change_last_attempt,
|
||||
"password_change_token": object.password_change_token,
|
||||
"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": (object.registered ? 1 : 0),
|
||||
"enabled": (object.enabled ? 1 : 0),
|
||||
"email_use_veiled_address": (object.email_use_veiled_address ? 1 : 0),
|
||||
"email_use_nominal_address": (object.email_use_nominal_address ? 1 : 0),
|
||||
"email_redirect_to_private_address": (object.email_redirect_to_private_address ? 1 : 0),
|
||||
"email_allow_sending": (object.email_allow_sending ? 1 : 0),
|
||||
"password_image": object.password_image,
|
||||
"password_change_last_attempt": object.password_change_last_attempt,
|
||||
"password_change_token": object.password_change_token,
|
||||
},
|
||||
"group_rows": (
|
||||
object.groups
|
||||
.map(
|
||||
group => ({
|
||||
"group_name": group,
|
||||
})
|
||||
)
|
||||
)
|
||||
};
|
||||
}
|
||||
|
||||
|
@ -85,51 +146,31 @@ namespace _espe.repository.member
|
|||
/**
|
||||
*/
|
||||
function decode(
|
||||
row : Record<string, any>
|
||||
dispersal : type_dispersal
|
||||
) : _espe.type.member_object
|
||||
{
|
||||
return {
|
||||
"membership_number": row["membership_number"],
|
||||
"name_real_value": row["name_real_value"],
|
||||
"name_real_index": row["name_real_index"],
|
||||
"email_address_private": row["email_address_private"],
|
||||
"registered": (row["registered"] > 0),
|
||||
"enabled": (row["enabled"] > 0),
|
||||
"email_use_veiled_address": (row["email_use_veiled_address"] > 0),
|
||||
"email_use_nominal_address": (row["email_use_nominal_address"] > 0),
|
||||
"email_redirect_to_private_address": (row["email_redirect_to_private_address"] > 0),
|
||||
"email_allow_sending": (row["email_allow_sending"] > 0),
|
||||
"password_image": row["password_image"],
|
||||
"password_change_last_attempt": row["password_change_last_attempt"],
|
||||
"password_change_token": row["password_change_token"],
|
||||
"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<string>(
|
||||
dispersal.group_rows.map(row => row["group_name"]),
|
||||
(group1, group2) => ((group1 <= group2) ? 0 : 1)
|
||||
),
|
||||
"registered": (dispersal.core_row["registered"] > 0),
|
||||
"enabled": (dispersal.core_row["enabled"] > 0),
|
||||
"email_use_veiled_address": (dispersal.core_row["email_use_veiled_address"] > 0),
|
||||
"email_use_nominal_address": (dispersal.core_row["email_use_nominal_address"] > 0),
|
||||
"email_redirect_to_private_address": (dispersal.core_row["email_redirect_to_private_address"] > 0),
|
||||
"email_allow_sending": (dispersal.core_row["email_allow_sending"] > 0),
|
||||
"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"],
|
||||
};
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
*/
|
||||
export async function dump(
|
||||
) : Promise<
|
||||
Array<
|
||||
{
|
||||
id : _espe.type.member_id;
|
||||
object : _espe.type.member_object;
|
||||
}
|
||||
>
|
||||
>
|
||||
{
|
||||
return (
|
||||
(await get_store().search(null))
|
||||
.map(
|
||||
({"key": key, "preview": preview}) => ({
|
||||
"id": key,
|
||||
"object": (preview as _espe.type.member_object),
|
||||
})
|
||||
)
|
||||
);
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* @todo optimize
|
||||
*/
|
||||
|
@ -149,7 +190,7 @@ namespace _espe.repository.member
|
|||
>
|
||||
{
|
||||
return (
|
||||
(await get_store().search(null))
|
||||
(await get_core_store().search(null))
|
||||
.filter(
|
||||
({"key": key, "preview": preview}) => (
|
||||
(
|
||||
|
@ -185,9 +226,24 @@ namespace _espe.repository.member
|
|||
id : _espe.type.member_id
|
||||
) : Promise<_espe.type.member_object>
|
||||
{
|
||||
const row : Record<string, any> = await get_store().read(id);
|
||||
const core_row : Record<string, any> = await get_core_store().read(id);
|
||||
const group_hits : Array<{key : Record<string, any>; preview : Record<string, any>;}> = await get_group_chest().search(
|
||||
{
|
||||
"expression": "member_id = $member_id",
|
||||
"arguments": {"member_id": id}
|
||||
}
|
||||
);
|
||||
|
||||
return decode(row);
|
||||
const dispersal : type_dispersal = {
|
||||
"core_row": core_row,
|
||||
"group_rows": group_hits.map(
|
||||
hit => ({
|
||||
"group_name": hit.preview["group_name"]
|
||||
})
|
||||
),
|
||||
};
|
||||
|
||||
return decode(dispersal);
|
||||
}
|
||||
|
||||
|
||||
|
@ -197,23 +253,63 @@ namespace _espe.repository.member
|
|||
value : _espe.type.member_object
|
||||
) : Promise<_espe.type.member_id>
|
||||
{
|
||||
const row : Record<string, any> = encode(value);
|
||||
const id : _espe.type.member_id = await get_store().create(row);
|
||||
const dispersal : type_dispersal = encode(value);
|
||||
|
||||
// core
|
||||
const id : _espe.type.member_id = await get_core_store().create(dispersal.core_row);
|
||||
|
||||
// groups
|
||||
for await (const group_row of dispersal.group_rows) {
|
||||
await get_group_chest().write(
|
||||
[
|
||||
id,
|
||||
group_row["group_name"],
|
||||
],
|
||||
{
|
||||
"_dummy": null,
|
||||
}
|
||||
);
|
||||
}
|
||||
|
||||
return id;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* @todo replace groups smartly
|
||||
*/
|
||||
export async function update(
|
||||
id : _espe.type.member_id,
|
||||
value : _espe.type.member_object
|
||||
) : Promise<void>
|
||||
{
|
||||
const row : Record<string, any> = encode(value);
|
||||
const dispersal : type_dispersal = encode(value);
|
||||
|
||||
await get_store().update(id, row);
|
||||
// core
|
||||
await get_core_store().update(id, dispersal.core_row);
|
||||
|
||||
// groups
|
||||
const hits : Array<{key : Array<any>; preview : Record<string, any>;}> = await get_group_chest().search(
|
||||
{
|
||||
"expression": "member_id = $member_id",
|
||||
"arguments": {"member_id": id}
|
||||
}
|
||||
);
|
||||
lib_plankton.log.info("update_hit", hits);
|
||||
for (const hit of hits) {
|
||||
await get_group_chest().delete(hit.key);
|
||||
}
|
||||
for await (const group_row of dispersal.group_rows) {
|
||||
await get_group_chest().write(
|
||||
[
|
||||
id,
|
||||
group_row["group_name"],
|
||||
],
|
||||
{
|
||||
"_dummy": null,
|
||||
}
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
@ -223,7 +319,51 @@ namespace _espe.repository.member
|
|||
id : _espe.type.member_id
|
||||
) : Promise<void>
|
||||
{
|
||||
await get_store().delete(id);
|
||||
// groups
|
||||
const hits : Array<{key : Array<any>; preview : Record<string, any>;}> = await get_group_chest().search(
|
||||
{
|
||||
"expression": "member_id = $member_id",
|
||||
"arguments": {"member_id": id}
|
||||
}
|
||||
);
|
||||
for (const hit of hits) {
|
||||
await get_group_chest().delete(hit.key);
|
||||
}
|
||||
|
||||
// core
|
||||
await get_core_store().delete(id);
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
*/
|
||||
export async function dump(
|
||||
) : Promise<
|
||||
Array<
|
||||
{
|
||||
id : _espe.type.member_id;
|
||||
object : _espe.type.member_object;
|
||||
}
|
||||
>
|
||||
>
|
||||
{
|
||||
return (
|
||||
Promise.all(
|
||||
(await get_core_store().search(null))
|
||||
.map(hit => hit.key)
|
||||
.map(
|
||||
id => (
|
||||
read(id)
|
||||
.then(
|
||||
(object) => ({
|
||||
"id": id,
|
||||
"object": object
|
||||
})
|
||||
)
|
||||
)
|
||||
)
|
||||
)
|
||||
);
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
@ -309,6 +309,7 @@ namespace _espe.service.member
|
|||
membership_number : (null | string);
|
||||
name_real_value : string;
|
||||
email_address_private : (null | string);
|
||||
groups : Array<string>;
|
||||
}
|
||||
) : Promise<_espe.type.member_id>
|
||||
{
|
||||
|
@ -327,6 +328,7 @@ namespace _espe.service.member
|
|||
"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);
|
||||
signal_change();
|
||||
|
@ -534,6 +536,7 @@ namespace _espe.service.member
|
|||
email_address_private : (null | string);
|
||||
registered : boolean;
|
||||
enabled : boolean;
|
||||
groups : lib_plankton.pod.type_pod<Array<string>>;
|
||||
}
|
||||
) : Promise<void>
|
||||
{
|
||||
|
@ -552,6 +555,11 @@ namespace _espe.service.member
|
|||
"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<Array<string>>(data.groups)
|
||||
? lib_plankton.pod.cull<Array<string>>(data.groups)
|
||||
: member_object_old.groups
|
||||
),
|
||||
};
|
||||
await _espe.repository.member.update(member_id, member_object_new);
|
||||
signal_change();
|
||||
|
@ -650,6 +658,7 @@ namespace _espe.service.member
|
|||
"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();
|
||||
|
@ -745,6 +754,7 @@ namespace _espe.service.member
|
|||
"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();
|
||||
|
@ -833,7 +843,7 @@ namespace _espe.service.member
|
|||
"disabled": (! entry.object.enabled),
|
||||
"displayname": name_display(entry.object),
|
||||
"email": entry.email_address,
|
||||
"groups": [],
|
||||
"groups": entry.object.groups,
|
||||
"password": entry.object.password_image,
|
||||
}
|
||||
])
|
||||
|
@ -987,7 +997,7 @@ namespace _espe.service.member
|
|||
);
|
||||
if (http_response.status_code !== 200) {
|
||||
lib_plankton.log.warning(
|
||||
"output_arcback_failed",
|
||||
"output_arc_failed",
|
||||
{
|
||||
"http_response_status_code": http_response.status_code,
|
||||
}
|
||||
|
|
|
@ -28,6 +28,7 @@ namespace _espe.type
|
|||
name_real_value : string;
|
||||
name_real_index : int;
|
||||
email_address_private : (null | string);
|
||||
groups : Array<string>;
|
||||
registered : boolean;
|
||||
enabled : boolean;
|
||||
email_use_veiled_address : boolean;
|
||||
|
|
Loading…
Add table
Reference in a new issue