diff --git a/conf/example.json b/conf/example.json index 5961c72..5afde0e 100644 --- a/conf/example.json +++ b/conf/example.json @@ -12,15 +12,8 @@ "in_memory": false }, "authentication": { - "kind": "oidc", + "kind": "internal", "data": { - "url_authorization": "https://authelia.linke.sx/api/oidc/authorization", - "url_token": "https://authelia.linke.sx/api/oidc/token", - "url_userinfo": "https://authelia.linke.sx/api/oidc/userinfo", - "client_id": "zeitbild", - "client_secret": "cee00b08a818db87e17e703273818e5194f83280e1ef3eae9214ff14675d9e6d", - "backend_url_base": "https://zeitbild.linke.sx", - "label": "linke.sx" } } } diff --git a/source/api/actions/calendar_add.ts b/source/api/actions/calendar_add.ts index daaa4f3..984b2b7 100644 --- a/source/api/actions/calendar_add.ts +++ b/source/api/actions/calendar_add.ts @@ -4,7 +4,7 @@ namespace _zeitbild.api /** */ - export function register_calendar_list( + export function register_calendar_add( rest_subject : lib_plankton.rest.type_rest ) : void { @@ -52,65 +52,77 @@ namespace _zeitbild.api const session : {key : string; value : lib_plankton.session.type_session;} = await session_from_stuff(stuff); const user_id : _zeitbild.type_user_id = await _zeitbild.service.user.identify(session.value.name); - // TODO move logic to calendar service - const resource_object : _zeitbild.type_resource_object = ( - { - "local": { - "kind": "local", - "data": { - "events": [], - } + if (stuff.input === null) { + return Promise.reject(new Error("impossible")); + } + else { + // TODO move logic to calendar service + let resource_object : _zeitbild.type_resource_object; + switch (stuff.input.resource.kind) { + case "local": { + resource_object = { + "kind": "local", + "data": { + "event_ids": [], + } + }; + break; + } + case "caldav": { + resource_object = { + "kind": "caldav", + "data": { + "url": stuff.input.resource.data.url, + "read_only": stuff.input.resource.data.read_only, + } + }; + break; + } + } + const resource_id : _zeitbild.type_resource_id = await _zeitbild.service.resource.add( + resource_object + ); + const calendar_object : _zeitbild.type_calendar_object = { + "name": stuff.input.name, + "access": { + "default_level": _zeitbild.value_object.access_level.from_string(stuff.input.access.default_level), + "attributed": lib_plankton.map.hashmap.implementation_map( + lib_plankton.map.hashmap.make( + x => x.toFixed(0), + { + "pairs": ( + stuff.input.access.attributed + .map( + (entry) => ({ + "key": entry.user_id, + "value": _zeitbild.value_object.access_level.from_string(entry.level), + }) + ) + .concat( + [ + { + "key": user_id, + "value": _zeitbild.enum_access_level.admin, + } + ] + ) + ), + } + ) + ), }, - "caldav": { - "kind": "caldav", - "data": { - "url": stuff.input.resource.data.url, - "read_only": stuff.input.resource.data.read_only, - } - }, - }[stuff.input.resource.kind] - ); - const resource_id : _zeitbild.type_resource_id = _zeitbild.service.resource.add( - resource_object - ); - const calendar_object : _zeitbild.type_calendar_object = { - "name": stuff.input.name, - "access": { - "default_level": _zeitbild.value_object.access_level.from_string(stuff.input.access.default_level), - "attributed": lib_plankton.map.hashmap.make( - x => x.toFixed(0), - { - "pairs": ( - stuff.input.access.attributed - .map( - (entry) => ({ - "key": entry.user_id, - "value": _zeitbild.value_object.access_level.from_string(entry.level), - }) - ) - .concat( - [ - { - "key": user_id, - "value": _zeitbild.enum_access_level.admin, - } - ] - ) - ), - } + "resource_id": resource_id + }; + return ( + _zeitbild.service.calendar.add(calendar_object) + .then( + (calendar_id : _zeitbild.type_calendar_id) => Promise.resolve({ + "status_code": 200, + "data": calendar_id, + }) ) - }, - "resource_id": resource_id - }; - return ( - _zeitbild.service.calendar.add(calendar_object) - .then( - (calendar_id : _zeitbild.type_calendar_id) => Promise.resolve({ - "status_code": 200, - "data": calendar_id, - }) - ) - ); + ); + } } } ); diff --git a/source/api/actions/calendar_event_add.ts b/source/api/actions/calendar_event_add.ts index 234368d..e7dae14 100644 --- a/source/api/actions/calendar_event_add.ts +++ b/source/api/actions/calendar_event_add.ts @@ -32,10 +32,6 @@ namespace _zeitbild.api "nullable": false, "type": "object", "properties": { - "name": { - "nullable": false, - "type": "string" - }, "name": { "nullable": false, "type": "string" @@ -81,18 +77,23 @@ namespace _zeitbild.api }), "restriction": restriction_logged_in, "execution": async (stuff) => { - return ( - _zeitbild.service.calendar.event_add( - stuff.input.calendar_id, - stuff.input.event - ) - .then( - () => Promise.resolve({ - "status_code": 200, - "data": null, - }) - ) - ); + if (stuff.input === null) { + return Promise.reject(new Error("impossible")); + } + else { + return ( + _zeitbild.service.calendar.event_add( + stuff.input.calendar_id, + stuff.input.event + ) + .then( + () => Promise.resolve({ + "status_code": 200, + "data": null, + }) + ) + ); + } } } ); diff --git a/source/main.ts b/source/main.ts index e7d7819..6842f3f 100644 --- a/source/main.ts +++ b/source/main.ts @@ -23,7 +23,24 @@ type type_data = { } >; }; - resource : _zeitbild.type_resource_object; + resource : ( + { + kind : "local"; + data : { + events : Array< + _zeitbild.type_event_object + > + }; + } + | + { + kind : "caldav"; + data : { + url : string; + read_only : boolean; + }; + } + ); } >; }; @@ -63,7 +80,35 @@ async function data_init( track.user[user_raw.id] = user_id; } for await (const calendar_raw of data.calendars) { - const resource_object : _zeitbild.type_resource_object = calendar_raw.resource; + let resource_object : _zeitbild.type_resource_object; + switch (calendar_raw.resource.kind) { + case "local": { + const event_ids : Array<_zeitbild.type_event_id> = await Promise.all<_zeitbild.type_event_id>( + calendar_raw.resource.data.events + .map( + // TODO do not use repository, but service + (event_raw : _zeitbild.type_event_object) => _zeitbild.repository.local_resource_event.create(event_raw) + ) + ); + resource_object = { + "kind": "local", + "data": { + "event_ids": event_ids, + } + }; + break; + } + case "caldav": { + resource_object = { + "kind": "caldav", + "data": { + "url": calendar_raw.resource.data.url, + "read_only": calendar_raw.resource.data.read_only, + } + }; + break; + } + } const resource_id : _zeitbild.type_resource_id = await _zeitbild.service.resource.add( resource_object ); diff --git a/source/repositories/local_resource_event.ts b/source/repositories/local_resource_event.ts index 1ad8bde..ffe66d0 100644 --- a/source/repositories/local_resource_event.ts +++ b/source/repositories/local_resource_event.ts @@ -47,8 +47,7 @@ namespace _zeitbild.repository.local_resource_event /** */ function encode( - event : _zeitbild.type_event_object, - local_resource_id : int + event : _zeitbild.type_event_object ) : Record { const encode_datetime : ((datetime : _zeitbild.helpers.type_datetime) => string) = ((datetime) => { @@ -82,7 +81,6 @@ namespace _zeitbild.repository.local_resource_event ); }); return { - "local_resource_id": local_resource_id, "name": event.name, "begin": encode_datetime(event.begin), "end": ( @@ -152,8 +150,8 @@ namespace _zeitbild.repository.local_resource_event /** */ - function read( - event_id : _zeitbild.type_local_resource_event_id + export function read( + event_id : _zeitbild.type_event_id ) : Promise<_zeitbild.type_event_object> { return ( @@ -167,9 +165,9 @@ namespace _zeitbild.repository.local_resource_event /** */ - function create( + export function create( event_object : _zeitbild.type_event_object - ) : Promise<_zeitbild.type_local_resource_event_id> + ) : Promise<_zeitbild.type_event_id> { return ( Promise.resolve(encode(event_object)) diff --git a/source/repositories/resource.ts b/source/repositories/resource.ts index 873021e..4c2c1f3 100644 --- a/source/repositories/resource.ts +++ b/source/repositories/resource.ts @@ -277,8 +277,10 @@ namespace _zeitbild.repository.resource } ); for await (const event_id of resource_object.data.event_ids) { - await get_local_resource_event_chest().create( - [local_resource_id, event_id] + await get_local_resource_event_chest().write( + [local_resource_id, event_id], + { + } ) } const resource_id : _zeitbild.type_resource_id = await get_resource_core_store().create( @@ -307,6 +309,7 @@ namespace _zeitbild.repository.resource break; } default: { + // @ts-ignore throw (new Error("invalid resource kind: " + resource_object.kind)); break; } @@ -384,6 +387,7 @@ namespace _zeitbild.repository.resource break; } default: { + // @ts-ignore throw (new Error("invalid resource kind: " + resource_object.kind)); break; } @@ -394,7 +398,7 @@ namespace _zeitbild.repository.resource /** */ - export function local_resource_event_add( + export async function local_resource_event_add( resource_id : _zeitbild.type_resource_id, event_id : _zeitbild.type_event_id ) : Promise @@ -419,7 +423,7 @@ namespace _zeitbild.repository.resource /** */ - export function local_resource_event_delete( + export async function local_resource_event_delete( resource_id : _zeitbild.type_resource_id, event_id : _zeitbild.type_event_id ) : Promise @@ -431,8 +435,7 @@ namespace _zeitbild.repository.resource else { return ( get_local_resource_event_chest().delete( - [dataset_core["sub_id"], event_id], - {} + [dataset_core["sub_id"], event_id] ) .then( () => Promise.resolve(undefined) diff --git a/source/services/calendar.ts b/source/services/calendar.ts index 0eab9cf..480d61c 100644 --- a/source/services/calendar.ts +++ b/source/services/calendar.ts @@ -76,13 +76,16 @@ namespace _zeitbild.service.calendar event_object : _zeitbild.type_event_object ) : Promise { - const calendar_object : _zeitbild.type_calendar_object = _zeitbild.repository.calendar.read( + const calendar_object : _zeitbild.type_calendar_object = await _zeitbild.repository.calendar.read( calendar_id ); - return _zeitbild.repository.resource.event_add( - calendar_object.resource_id, + const event_id : _zeitbild.type_event_id = await _zeitbild.repository.local_resource_event.create( event_object ); + return _zeitbild.repository.resource.local_resource_event_add( + calendar_object.resource_id, + event_id + ); } @@ -102,16 +105,26 @@ namespace _zeitbild.service.calendar const resource_object : _zeitbild.type_resource_object = await _zeitbild.repository.resource.read(calendar_object.resource_id); switch (resource_object.kind) { case "local": { - return Promise.resolve( - resource_object.data.events - .filter( - (event : _zeitbild.type_event_object) => _zeitbild.helpers.pit_is_between( - _zeitbild.helpers.pit_from_datetime(event.begin), - from_pit, - to_pit + return ( + Promise.all( + resource_object.data.event_ids + .map( + (event_id) => _zeitbild.repository.local_resource_event.read(event_id) ) ) - ) + .then( + (events) => Promise.resolve( + events + .filter( + (event : _zeitbild.type_event_object) => _zeitbild.helpers.pit_is_between( + _zeitbild.helpers.pit_from_datetime(event.begin), + from_pit, + to_pit + ) + ) + ) + ) + ); break; } case "caldav": { diff --git a/source/services/resource.ts b/source/services/resource.ts index 3a3c43e..2268ab5 100644 --- a/source/services/resource.ts +++ b/source/services/resource.ts @@ -19,7 +19,7 @@ namespace _zeitbild.service.resource event_object : _zeitbild.type_event_object ) : Promise { - const resource_object : _zeitbild.type_resource_object = _zeitbild.repository.resource.read( + const resource_object : _zeitbild.type_resource_object = await _zeitbild.repository.resource.read( resource_id ); switch (resource_object.kind) { @@ -45,6 +45,7 @@ namespace _zeitbild.service.resource break; } default: { + // @ts-ignore throw (new Error("unhandled resource kind: " + resource_object.kind)); } } @@ -58,7 +59,7 @@ namespace _zeitbild.service.resource event_object : _zeitbild.type_event_object ) : Promise { - const resource_object : _zeitbild.type_resource_object = _zeitbild.repository.resource.read( + const resource_object : _zeitbild.type_resource_object = await _zeitbild.repository.resource.read( resource_id ); switch (resource_object.kind) { @@ -84,6 +85,7 @@ namespace _zeitbild.service.resource break; } default: { + // @ts-ignore throw (new Error("unhandled resource kind: " + resource_object.kind)); } }