Compare commits
36 commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
9c91365f98 | ||
|
|
193a21277f | ||
|
|
8264936f21 | ||
|
|
8a9d552760 | ||
|
|
47319b9e10 | ||
|
|
4b75e06057 | ||
|
|
a7a90e8ab8 | ||
|
|
e46be87a99 | ||
|
|
58791676e5 | ||
|
|
74f79ae0b7 | ||
|
|
a716cf6852 | ||
|
|
e549d7b088 | ||
|
|
31194c8c41 | ||
|
|
4e9f7f634d | ||
|
|
bbfc07478f | ||
|
|
5afc562b18 | ||
|
|
6309422429 | ||
|
|
2683d49bba | ||
|
|
1df1fa3ac9 | ||
|
|
5ab91664ed | ||
|
|
fc228fb274 | ||
|
|
6ad47e1943 | ||
|
|
00f416a126 | ||
|
|
64652af779 | ||
|
|
9eab32d573 | ||
|
|
2cb46cd485 | ||
|
|
6f1437b55a | ||
|
|
8ddba38bd5 | ||
|
|
c5d52a7df5 | ||
|
|
b86e1b62e2 | ||
|
|
ef879bb81b | ||
|
|
54e27f2ad9 | ||
|
|
b5b5dde9e3 | ||
|
|
5de4728901 | ||
|
|
9d1fd0b55f | ||
|
|
1127130b00 |
|
|
@ -1,20 +0,0 @@
|
||||||
{
|
|
||||||
"version": 1,
|
|
||||||
"log": [
|
|
||||||
{
|
|
||||||
"kind": "stdout",
|
|
||||||
"data": {
|
|
||||||
"threshold": "info"
|
|
||||||
}
|
|
||||||
}
|
|
||||||
],
|
|
||||||
"session_management": {
|
|
||||||
"in_memory": false,
|
|
||||||
"lifetime": 3600
|
|
||||||
},
|
|
||||||
"authentication": {
|
|
||||||
"kind": "internal",
|
|
||||||
"data": {
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
@ -3,19 +3,22 @@
|
||||||
{
|
{
|
||||||
"id": 1,
|
"id": 1,
|
||||||
"name": "alice",
|
"name": "alice",
|
||||||
"email_address": "alice@example.org",
|
"email_address": "alice@example.org",
|
||||||
|
"dav_token": null,
|
||||||
"password": "alice"
|
"password": "alice"
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"id": 2,
|
"id": 2,
|
||||||
"name": "bob",
|
"name": "bob",
|
||||||
"email_address": "bob@example.org",
|
"email_address": "bob@example.org",
|
||||||
|
"dav_token": "bob_dav",
|
||||||
"password": "bob"
|
"password": "bob"
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"id": 3,
|
"id": 3,
|
||||||
"name": "charlie",
|
"name": "charlie",
|
||||||
"email_address": "charlie@example.org",
|
"email_address": "charlie@example.org",
|
||||||
|
"dav_token": null,
|
||||||
"password": "charlie"
|
"password": "charlie"
|
||||||
}
|
}
|
||||||
],
|
],
|
||||||
|
|
|
||||||
58
misc/conf-example.json
Normal file
58
misc/conf-example.json
Normal file
|
|
@ -0,0 +1,58 @@
|
||||||
|
{
|
||||||
|
"version": 1,
|
||||||
|
"log": [
|
||||||
|
{
|
||||||
|
"kind": "stdout",
|
||||||
|
"data": {
|
||||||
|
"threshold": "info",
|
||||||
|
"format": "jsonl_structured"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"session_management": {
|
||||||
|
"in_memory": false,
|
||||||
|
"lifetime": 3600
|
||||||
|
},
|
||||||
|
"authentication": {
|
||||||
|
"kind": "internal",
|
||||||
|
"data": {
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"database": {
|
||||||
|
"kind": "sqlite",
|
||||||
|
"data": {
|
||||||
|
"path": "../zeitbild.sqlite"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"caldav": {
|
||||||
|
"address": "http://localhost:8000/calendars/-/lampukistan",
|
||||||
|
"username": "lampukistan-{{username}}",
|
||||||
|
"password": "{{password}}",
|
||||||
|
"setup_hints": [
|
||||||
|
{
|
||||||
|
"label": "Android",
|
||||||
|
"link": "https://www.android-user.de/caldavcarddav-kalender-und-adressbuecher-ohne-google-synchronisieren/",
|
||||||
|
"remark": null
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"label": "iOS",
|
||||||
|
"link": "https://all-inkl.com/wichtig/anleitungen/programme/e-mail/caldav-kalenderfunktion/ios-mail_460.html",
|
||||||
|
"remark": "eigentlich für Server 'all-inkl.com' — Zugangsdaten müssen entsprechend geändert werden"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"label": "Thunderbird",
|
||||||
|
"link": "https://www.uni-bielefeld.de/einrichtungen/bits/services/kuz/e-mail-und-kalender/anleitung/kalender-konfiguration-unter-thunderbird/",
|
||||||
|
"remark": "eigentlich für Server 'uni-bielefeld.de' — Zugangsdaten müssen entsprechend geändert werden"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"label": "Evolution",
|
||||||
|
"link": "https://help.gnome.org/users/evolution/stable/calendar-caldav.html.de"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"label": "MS Outlook",
|
||||||
|
"link": "https://www.united-domains.de/help/faq-article/wie-synchronisiere-ich-meinen-kalender-caldav-mit-ms-outlook/",
|
||||||
|
"remark": null
|
||||||
|
}
|
||||||
|
]
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
@ -29,10 +29,9 @@ namespace _zeitbild.api
|
||||||
}
|
}
|
||||||
|
|
|
|
||||||
{
|
{
|
||||||
kind : "caldav";
|
kind : "ics_feed";
|
||||||
data : {
|
data : {
|
||||||
url : string;
|
url : string;
|
||||||
read_only : boolean;
|
|
||||||
from_fucked_up_wordpress : boolean;
|
from_fucked_up_wordpress : boolean;
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
@ -75,12 +74,11 @@ namespace _zeitbild.api
|
||||||
};
|
};
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
case "caldav": {
|
case "ics_feed": {
|
||||||
resource_object = {
|
resource_object = {
|
||||||
"kind": "caldav",
|
"kind": "ics_feed",
|
||||||
"data": {
|
"data": {
|
||||||
"url": stuff.input.resource.data.url,
|
"url": stuff.input.resource.data.url,
|
||||||
"read_only": stuff.input.resource.data.read_only,
|
|
||||||
"from_fucked_up_wordpress": stuff.input.resource.data.from_fucked_up_wordpress,
|
"from_fucked_up_wordpress": stuff.input.resource.data.from_fucked_up_wordpress,
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
|
||||||
127
source/api/actions/export_ics.ts
Normal file
127
source/api/actions/export_ics.ts
Normal file
|
|
@ -0,0 +1,127 @@
|
||||||
|
|
||||||
|
namespace _zeitbild.api
|
||||||
|
{
|
||||||
|
|
||||||
|
/**
|
||||||
|
*/
|
||||||
|
export function register_export_ics(
|
||||||
|
rest_subject : lib_plankton.rest_http.type_rest
|
||||||
|
) : void
|
||||||
|
{
|
||||||
|
register<
|
||||||
|
null,
|
||||||
|
(
|
||||||
|
lib_plankton.ical.type_vcalendar
|
||||||
|
|
|
||||||
|
string
|
||||||
|
)
|
||||||
|
>(
|
||||||
|
rest_subject,
|
||||||
|
lib_plankton.http.enum_method.get,
|
||||||
|
"/export/ics",
|
||||||
|
{
|
||||||
|
"description": "trägt Veranstaltungen aus verschiedenen Kalendern zusammen im ics-Format",
|
||||||
|
"query_parameters": () => ([
|
||||||
|
{
|
||||||
|
"name": "from",
|
||||||
|
"required": false,
|
||||||
|
"description": "UNIX timestamp",
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"name": "to",
|
||||||
|
"required": false,
|
||||||
|
"description": "UNIX timestamp",
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"name": "calendar_ids",
|
||||||
|
"required": false,
|
||||||
|
"description": "comma separated",
|
||||||
|
},
|
||||||
|
]),
|
||||||
|
"output_schema": () => ({
|
||||||
|
"nullable": false,
|
||||||
|
"type": "string",
|
||||||
|
}),
|
||||||
|
"response_body_mimetype": "text/calendar",
|
||||||
|
"response_body_encode": (output) => Buffer.from(
|
||||||
|
(typeof(output) === "string")
|
||||||
|
?
|
||||||
|
output
|
||||||
|
:
|
||||||
|
lib_plankton.ical.ics_encode(output)
|
||||||
|
),
|
||||||
|
"restriction": restriction_web_auth,
|
||||||
|
"execution": async (stuff) => {
|
||||||
|
const user : {id : _zeitbild.type_user_id; object : _zeitbild.type_user_object;} = await _zeitbild.api.user_from_web_auth(stuff);
|
||||||
|
|
||||||
|
const from : lib_plankton.pit.type_pit = (
|
||||||
|
("from" in stuff.query_parameters)
|
||||||
|
?
|
||||||
|
parseInt(stuff.query_parameters["from"])
|
||||||
|
:
|
||||||
|
lib_plankton.pit.shift_week(
|
||||||
|
lib_plankton.pit.now(),
|
||||||
|
-2
|
||||||
|
)
|
||||||
|
);
|
||||||
|
const to : lib_plankton.pit.type_pit = (
|
||||||
|
("to" in stuff.query_parameters)
|
||||||
|
?
|
||||||
|
parseInt(stuff.query_parameters["to"])
|
||||||
|
:
|
||||||
|
lib_plankton.pit.shift_week(
|
||||||
|
lib_plankton.pit.now(),
|
||||||
|
+6
|
||||||
|
)
|
||||||
|
);
|
||||||
|
const calendar_ids_wanted : (null | Array<_zeitbild.type_calendar_id>) = (
|
||||||
|
(
|
||||||
|
("calendar_ids" in stuff.query_parameters)
|
||||||
|
&&
|
||||||
|
(stuff.query_parameters["calendar_ids"] !== null)
|
||||||
|
)
|
||||||
|
?
|
||||||
|
lib_plankton.call.convey(
|
||||||
|
stuff.query_parameters["calendar_ids"],
|
||||||
|
[
|
||||||
|
(x : string) => x.split(","),
|
||||||
|
(x : Array<string>) => x.map(parseInt),
|
||||||
|
(x : Array<int>) => x.filter(y => (! isNaN(y)))
|
||||||
|
]
|
||||||
|
)
|
||||||
|
:
|
||||||
|
null
|
||||||
|
);
|
||||||
|
|
||||||
|
return (
|
||||||
|
_zeitbild.service.calendar.gather_events(
|
||||||
|
calendar_ids_wanted,
|
||||||
|
from,
|
||||||
|
to,
|
||||||
|
user.id
|
||||||
|
)
|
||||||
|
.then(
|
||||||
|
(events_extended) => Promise.resolve(
|
||||||
|
{
|
||||||
|
"status_code": 200,
|
||||||
|
"data": _zeitbild.helpers.icalendar_vcalendar_from_own_event_list(
|
||||||
|
events_extended
|
||||||
|
)
|
||||||
|
}
|
||||||
|
)
|
||||||
|
)
|
||||||
|
.catch(
|
||||||
|
(reason) => Promise.resolve(
|
||||||
|
{
|
||||||
|
"status_code": 403,
|
||||||
|
"data": String(reason),
|
||||||
|
}
|
||||||
|
)
|
||||||
|
)
|
||||||
|
);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
@ -74,6 +74,7 @@ namespace _zeitbild.api
|
||||||
{
|
{
|
||||||
"name": data.userinfo.name,
|
"name": data.userinfo.name,
|
||||||
"email_address": data.userinfo.email,
|
"email_address": data.userinfo.email,
|
||||||
|
"dav_token": null,
|
||||||
}
|
}
|
||||||
);
|
);
|
||||||
lib_plankton.log.info(
|
lib_plankton.log.info(
|
||||||
|
|
|
||||||
152
source/api/actions/user_dav_conf.ts
Normal file
152
source/api/actions/user_dav_conf.ts
Normal file
|
|
@ -0,0 +1,152 @@
|
||||||
|
namespace _zeitbild.api
|
||||||
|
{
|
||||||
|
|
||||||
|
/**
|
||||||
|
*/
|
||||||
|
export function register_user_dav_conf(
|
||||||
|
rest_subject : lib_plankton.rest_http.type_rest
|
||||||
|
) : void
|
||||||
|
{
|
||||||
|
register<
|
||||||
|
null,
|
||||||
|
(
|
||||||
|
null
|
||||||
|
|
|
||||||
|
{
|
||||||
|
address : string;
|
||||||
|
username : string;
|
||||||
|
password : (null | string);
|
||||||
|
setup_hints : Array<
|
||||||
|
{
|
||||||
|
label : string;
|
||||||
|
link : string;
|
||||||
|
remark : (null | string);
|
||||||
|
}
|
||||||
|
>;
|
||||||
|
}
|
||||||
|
)
|
||||||
|
>(
|
||||||
|
rest_subject,
|
||||||
|
lib_plankton.http.enum_method.get,
|
||||||
|
"/user_dav_conf",
|
||||||
|
{
|
||||||
|
"description": "gibt die CalDAV-Zugangsdaten eines Nutzers aus",
|
||||||
|
"output_schema": () => ({
|
||||||
|
"nullable": true,
|
||||||
|
"type": "object",
|
||||||
|
"properties": {
|
||||||
|
"address": {
|
||||||
|
"nullable": false,
|
||||||
|
"type": "string"
|
||||||
|
},
|
||||||
|
"username": {
|
||||||
|
"nullable": false,
|
||||||
|
"type": "string"
|
||||||
|
},
|
||||||
|
"password": {
|
||||||
|
"nullable": true,
|
||||||
|
"type": "string"
|
||||||
|
},
|
||||||
|
"setup_hints": {
|
||||||
|
"nullable": false,
|
||||||
|
"type": "array",
|
||||||
|
"items": {
|
||||||
|
"nullable": false,
|
||||||
|
"type": "object",
|
||||||
|
"properties": {
|
||||||
|
"label": {
|
||||||
|
"nullable": false,
|
||||||
|
"type": "string"
|
||||||
|
},
|
||||||
|
"link": {
|
||||||
|
"nullable": false,
|
||||||
|
"type": "string"
|
||||||
|
},
|
||||||
|
"remark": {
|
||||||
|
"nullable": true,
|
||||||
|
"type": "string",
|
||||||
|
"default": null,
|
||||||
|
},
|
||||||
|
},
|
||||||
|
"required": [
|
||||||
|
"label",
|
||||||
|
"link",
|
||||||
|
],
|
||||||
|
"additionalProperties": false
|
||||||
|
},
|
||||||
|
"default": []
|
||||||
|
},
|
||||||
|
},
|
||||||
|
"required": [
|
||||||
|
"address",
|
||||||
|
"username",
|
||||||
|
"password",
|
||||||
|
"setup_hints",
|
||||||
|
],
|
||||||
|
"additionalProperties": false
|
||||||
|
}),
|
||||||
|
"restriction": restriction_logged_in,
|
||||||
|
"execution": async (stuff) => {
|
||||||
|
let result : (
|
||||||
|
null
|
||||||
|
|
|
||||||
|
{
|
||||||
|
address : string;
|
||||||
|
username : string;
|
||||||
|
password : (null | string);
|
||||||
|
setup_hints : Array<
|
||||||
|
{
|
||||||
|
label : string;
|
||||||
|
link : string;
|
||||||
|
remark : (null | string);
|
||||||
|
}
|
||||||
|
>;
|
||||||
|
}
|
||||||
|
) = null;
|
||||||
|
const raw : (null | any) = _zeitbild.conf.get()["caldav"];
|
||||||
|
if (raw === null)
|
||||||
|
{
|
||||||
|
result = null;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
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);
|
||||||
|
const user_object : _zeitbild.type_user_object = await _zeitbild.service.user.get(user_id);
|
||||||
|
const arguments_ : Record<string, string> = Object.fromEntries(
|
||||||
|
[
|
||||||
|
{"key": "username", "value": user_object.name},
|
||||||
|
{"key": "password", "value": user_object.dav_token},
|
||||||
|
]
|
||||||
|
.filter(
|
||||||
|
entry => (entry.value !== null)
|
||||||
|
)
|
||||||
|
.map(
|
||||||
|
entry => ([entry.key, entry.value as string])
|
||||||
|
)
|
||||||
|
);
|
||||||
|
result = {
|
||||||
|
"address": lib_plankton.string.coin(raw["address"], arguments_),
|
||||||
|
"username": lib_plankton.string.coin(raw["username"], arguments_),
|
||||||
|
"password": (
|
||||||
|
(user_object.dav_token === null)
|
||||||
|
?
|
||||||
|
null
|
||||||
|
:
|
||||||
|
lib_plankton.string.coin(raw["password"], arguments_)
|
||||||
|
),
|
||||||
|
"setup_hints": raw["setup_hints"],
|
||||||
|
};
|
||||||
|
}
|
||||||
|
return Promise.resolve(
|
||||||
|
{
|
||||||
|
"status_code": 200,
|
||||||
|
"data": result,
|
||||||
|
}
|
||||||
|
);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
53
source/api/actions/user_dav_token.ts
Normal file
53
source/api/actions/user_dav_token.ts
Normal file
|
|
@ -0,0 +1,53 @@
|
||||||
|
namespace _zeitbild.api
|
||||||
|
{
|
||||||
|
|
||||||
|
/**
|
||||||
|
*/
|
||||||
|
export function register_user_dav_token(
|
||||||
|
rest_subject : lib_plankton.rest_http.type_rest
|
||||||
|
) : void
|
||||||
|
{
|
||||||
|
register<
|
||||||
|
// string,
|
||||||
|
null,
|
||||||
|
null
|
||||||
|
>(
|
||||||
|
rest_subject,
|
||||||
|
lib_plankton.http.enum_method.patch,
|
||||||
|
"/user_dav_token",
|
||||||
|
{
|
||||||
|
"description": "setzt/überschreibt den DAV-Token eines Nutzers",
|
||||||
|
/*
|
||||||
|
"input_schema": () => ({
|
||||||
|
"nullable": false,
|
||||||
|
"type": "string"
|
||||||
|
}),
|
||||||
|
*/
|
||||||
|
"input_schema": () => ({
|
||||||
|
"nullable": true,
|
||||||
|
}),
|
||||||
|
"output_schema": () => ({
|
||||||
|
"nullable": true
|
||||||
|
}),
|
||||||
|
"restriction": restriction_logged_in,
|
||||||
|
"execution": async (stuff) => {
|
||||||
|
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: outsource to user service?
|
||||||
|
const user_object : _zeitbild.type_user_object = await _zeitbild.service.user.get(user_id);
|
||||||
|
// user_object.dav_token = stuff.input;
|
||||||
|
user_object.dav_token = lib_plankton.random.generate_string({"length": 12});
|
||||||
|
await _zeitbild.service.user.change(user_id, user_object);
|
||||||
|
return Promise.resolve(
|
||||||
|
{
|
||||||
|
"status_code": 200,
|
||||||
|
"data": null,
|
||||||
|
}
|
||||||
|
);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
|
@ -31,6 +31,15 @@ namespace _zeitbild.api
|
||||||
_zeitbild.api.register_session_end(rest_subject);
|
_zeitbild.api.register_session_end(rest_subject);
|
||||||
_zeitbild.api.register_session_oidc(rest_subject);
|
_zeitbild.api.register_session_oidc(rest_subject);
|
||||||
}
|
}
|
||||||
|
// user
|
||||||
|
{
|
||||||
|
_zeitbild.api.register_users(rest_subject);
|
||||||
|
// caldav
|
||||||
|
{
|
||||||
|
_zeitbild.api.register_user_dav_conf(rest_subject);
|
||||||
|
_zeitbild.api.register_user_dav_token(rest_subject);
|
||||||
|
}
|
||||||
|
}
|
||||||
// calendar
|
// calendar
|
||||||
{
|
{
|
||||||
_zeitbild.api.register_calendar_list(rest_subject);
|
_zeitbild.api.register_calendar_list(rest_subject);
|
||||||
|
|
@ -46,13 +55,15 @@ namespace _zeitbild.api
|
||||||
_zeitbild.api.register_calendar_event_remove(rest_subject);
|
_zeitbild.api.register_calendar_event_remove(rest_subject);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
// export
|
||||||
|
{
|
||||||
|
_zeitbild.api.register_export_ics(rest_subject);
|
||||||
|
}
|
||||||
// misc
|
// misc
|
||||||
{
|
{
|
||||||
_zeitbild.api.register_users(rest_subject);
|
|
||||||
_zeitbild.api.register_events(rest_subject);
|
_zeitbild.api.register_events(rest_subject);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
return rest_subject;
|
return rest_subject;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -282,7 +282,95 @@ namespace _zeitbild.conf
|
||||||
"data": {
|
"data": {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
},
|
||||||
|
"external_resources": {
|
||||||
|
"nullable": false,
|
||||||
|
"type": "object",
|
||||||
|
"properties": {
|
||||||
|
"lifetime": {
|
||||||
|
"nullable": false,
|
||||||
|
"type": "integer",
|
||||||
|
"default": 14400
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"additionalProperties": false,
|
||||||
|
"required": [
|
||||||
|
],
|
||||||
|
"default": {
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"caldav": {
|
||||||
|
"nullable": true,
|
||||||
|
"type": "object",
|
||||||
|
"properties": {
|
||||||
|
"address": {
|
||||||
|
"nullable": false,
|
||||||
|
"type": "string"
|
||||||
|
},
|
||||||
|
"username": {
|
||||||
|
"nullable": false,
|
||||||
|
"type": "string"
|
||||||
|
},
|
||||||
|
"password": {
|
||||||
|
"nullable": false,
|
||||||
|
"type": "string"
|
||||||
|
},
|
||||||
|
"setup_hints": {
|
||||||
|
"nullable": false,
|
||||||
|
"type": "array",
|
||||||
|
"items": {
|
||||||
|
"nullable": false,
|
||||||
|
"type": "object",
|
||||||
|
"properties": {
|
||||||
|
"label": {
|
||||||
|
"nullable": false,
|
||||||
|
"type": "string"
|
||||||
|
},
|
||||||
|
"link": {
|
||||||
|
"nullable": false,
|
||||||
|
"type": "string"
|
||||||
|
},
|
||||||
|
"remark": {
|
||||||
|
"nullable": true,
|
||||||
|
"type": "string",
|
||||||
|
"default": null
|
||||||
|
},
|
||||||
|
},
|
||||||
|
"required": [
|
||||||
|
"label",
|
||||||
|
"link",
|
||||||
|
],
|
||||||
|
"additionalProperties": false
|
||||||
|
},
|
||||||
|
"default": []
|
||||||
|
},
|
||||||
|
},
|
||||||
|
"required": [
|
||||||
|
"address",
|
||||||
|
"username",
|
||||||
|
"password"
|
||||||
|
],
|
||||||
|
"additionalProperties": false,
|
||||||
|
"default": null
|
||||||
|
},
|
||||||
|
"misc": {
|
||||||
|
"nullable": false,
|
||||||
|
"type": "object",
|
||||||
|
"properties": {
|
||||||
|
/**
|
||||||
|
* @todo make mandatory
|
||||||
|
*/
|
||||||
|
"auth_salt": {
|
||||||
|
"nullable": false,
|
||||||
|
"type": "string",
|
||||||
|
"default": "unsafe_auth_salt"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"required": [
|
||||||
|
],
|
||||||
|
"additionalProperties": false,
|
||||||
|
"default": {}
|
||||||
|
},
|
||||||
},
|
},
|
||||||
"required": [
|
"required": [
|
||||||
"version"
|
"version"
|
||||||
|
|
|
||||||
|
|
@ -7,7 +7,7 @@ namespace _zeitbild.helpers
|
||||||
/**
|
/**
|
||||||
* @todo timezone
|
* @todo timezone
|
||||||
*/
|
*/
|
||||||
function ical_datetime_to_own_datetime(
|
function icalendar_datetime_to_own_datetime(
|
||||||
ical_datetime : lib_plankton.ical.type_datetime
|
ical_datetime : lib_plankton.ical.type_datetime
|
||||||
) : lib_plankton.pit.type_datetime
|
) : lib_plankton.pit.type_datetime
|
||||||
{
|
{
|
||||||
|
|
@ -31,12 +31,12 @@ namespace _zeitbild.helpers
|
||||||
)
|
)
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @todo timezone
|
* @todo timezone
|
||||||
*/
|
*/
|
||||||
export function ical_dt_to_own_datetime(
|
export function icalendar_dt_to_own_datetime(
|
||||||
ical_dt: lib_plankton.ical.type_dt
|
ical_dt: lib_plankton.ical.type_dt
|
||||||
) : lib_plankton.pit.type_datetime
|
) : lib_plankton.pit.type_datetime
|
||||||
{
|
{
|
||||||
|
|
@ -58,6 +58,125 @@ namespace _zeitbild.helpers
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @todo timezone
|
||||||
|
*/
|
||||||
|
export function icalendar_dt_from_own_datetime(
|
||||||
|
datetime : lib_plankton.pit.type_datetime
|
||||||
|
) : lib_plankton.ical.type_dt
|
||||||
|
{
|
||||||
|
return {
|
||||||
|
"tzid": "Europe/Berlin",
|
||||||
|
"value": {
|
||||||
|
"date": {
|
||||||
|
"year": datetime.date.year,
|
||||||
|
"month": datetime.date.month,
|
||||||
|
"day": datetime.date.day,
|
||||||
|
},
|
||||||
|
"time": (
|
||||||
|
(datetime.time === null)
|
||||||
|
?
|
||||||
|
null
|
||||||
|
:
|
||||||
|
{
|
||||||
|
"utc": true,
|
||||||
|
"hour": datetime.time.hour,
|
||||||
|
"minute": datetime.time.minute,
|
||||||
|
"second": datetime.time.second,
|
||||||
|
}
|
||||||
|
)
|
||||||
|
},
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
*/
|
||||||
|
export function icalendar_vevent_from_own_event(
|
||||||
|
event_extended : _zeitbild.type_event_extended,
|
||||||
|
index : int,
|
||||||
|
{
|
||||||
|
"stamp": stamp = "adhoc",
|
||||||
|
}
|
||||||
|
:
|
||||||
|
{
|
||||||
|
stamp ?: string;
|
||||||
|
}
|
||||||
|
=
|
||||||
|
{
|
||||||
|
}
|
||||||
|
) : lib_plankton.ical.type_vevent
|
||||||
|
{
|
||||||
|
return {
|
||||||
|
"uid": lib_plankton.string.coin(
|
||||||
|
"zeitbild_{{stamp}}_{{id}}",
|
||||||
|
{
|
||||||
|
"stamp": stamp,
|
||||||
|
// "id": event_extended.event_id.toFixed(0),
|
||||||
|
"id": index.toFixed(0),
|
||||||
|
}
|
||||||
|
),
|
||||||
|
"dtstamp": icalendar_dt_from_own_datetime(event_extended.event_object.begin).value,
|
||||||
|
"dtstart": icalendar_dt_from_own_datetime(event_extended.event_object.begin),
|
||||||
|
"dtend": (
|
||||||
|
(event_extended.event_object.end === null)
|
||||||
|
?
|
||||||
|
undefined
|
||||||
|
:
|
||||||
|
icalendar_dt_from_own_datetime(event_extended.event_object.end)
|
||||||
|
),
|
||||||
|
"location": (event_extended.event_object.location ?? undefined),
|
||||||
|
"summary": event_extended.event_object.name,
|
||||||
|
"url": (event_extended.event_object.link ?? undefined),
|
||||||
|
"description": (event_extended.event_object.description ?? undefined),
|
||||||
|
/**
|
||||||
|
* @todo transform name
|
||||||
|
*/
|
||||||
|
"categories": [event_extended.calendar_name],
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @todo assign better uids
|
||||||
|
*/
|
||||||
|
export function icalendar_vcalendar_from_own_event_list(
|
||||||
|
events_extended : Array<_zeitbild.type_event_extended>
|
||||||
|
) : lib_plankton.ical.type_vcalendar
|
||||||
|
{
|
||||||
|
const pit_now : lib_plankton.pit.type_pit = lib_plankton.pit.now();
|
||||||
|
const datetime_now : lib_plankton.pit.type_datetime = lib_plankton.pit.to_datetime(pit_now);
|
||||||
|
const stamp : string = lib_plankton.string.coin(
|
||||||
|
"{{year}}{{month}}{{day}}",
|
||||||
|
{
|
||||||
|
"year": datetime_now.date.year.toFixed(0).padStart(4, "0"),
|
||||||
|
"month": datetime_now.date.month.toFixed(0).padStart(2, "0"),
|
||||||
|
"day": datetime_now.date.day.toFixed(0).padStart(2, "0"),
|
||||||
|
}
|
||||||
|
);
|
||||||
|
return {
|
||||||
|
"version": "2.0",
|
||||||
|
"prodid": "",
|
||||||
|
"vevents": (
|
||||||
|
events_extended
|
||||||
|
.map<lib_plankton.ical.type_vevent>(
|
||||||
|
(event_extended, index) => icalendar_vevent_from_own_event(
|
||||||
|
event_extended,
|
||||||
|
index,
|
||||||
|
{
|
||||||
|
"stamp": stamp,
|
||||||
|
}
|
||||||
|
)
|
||||||
|
)
|
||||||
|
),
|
||||||
|
"method": "PUBLISH",
|
||||||
|
"vtimezone": {
|
||||||
|
"tzid": "Europe/Berlin",
|
||||||
|
},
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
*/
|
*/
|
||||||
export async function template_coin(
|
export async function template_coin(
|
||||||
|
|
|
||||||
|
|
@ -8,6 +8,7 @@ type type_data = {
|
||||||
id : int;
|
id : int;
|
||||||
name : string;
|
name : string;
|
||||||
email_address : string;
|
email_address : string;
|
||||||
|
dav_token : (null | string);
|
||||||
password : string;
|
password : string;
|
||||||
}
|
}
|
||||||
>;
|
>;
|
||||||
|
|
@ -36,10 +37,9 @@ type type_data = {
|
||||||
}
|
}
|
||||||
|
|
|
|
||||||
{
|
{
|
||||||
kind : "caldav";
|
kind : "ics_feed";
|
||||||
data : {
|
data : {
|
||||||
url : string;
|
url : string;
|
||||||
read_only : boolean;
|
|
||||||
from_fucked_up_wordpress ?: boolean;
|
from_fucked_up_wordpress ?: boolean;
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
@ -73,6 +73,7 @@ async function data_init(
|
||||||
const user_object : _zeitbild.type_user_object = {
|
const user_object : _zeitbild.type_user_object = {
|
||||||
"name": user_raw.name,
|
"name": user_raw.name,
|
||||||
"email_address": user_raw.email_address,
|
"email_address": user_raw.email_address,
|
||||||
|
"dav_token": user_raw.dav_token,
|
||||||
};
|
};
|
||||||
const user_id : _zeitbild.type_user_id = await _zeitbild.service.user.add(
|
const user_id : _zeitbild.type_user_id = await _zeitbild.service.user.add(
|
||||||
user_object
|
user_object
|
||||||
|
|
@ -108,13 +109,12 @@ async function data_init(
|
||||||
);
|
);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
case "caldav":
|
case "ics_feed":
|
||||||
{
|
{
|
||||||
resource_object = {
|
resource_object = {
|
||||||
"kind": "caldav",
|
"kind": "ics_feed",
|
||||||
"data": {
|
"data": {
|
||||||
"url": calendar_raw.resource.data.url,
|
"url": calendar_raw.resource.data.url,
|
||||||
"read_only": calendar_raw.resource.data.read_only,
|
|
||||||
"from_fucked_up_wordpress": (calendar_raw.resource.data.from_fucked_up_wordpress ?? false),
|
"from_fucked_up_wordpress": (calendar_raw.resource.data.from_fucked_up_wordpress ?? false),
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
@ -384,7 +384,6 @@ async function main(
|
||||||
case "api-doc": {
|
case "api-doc": {
|
||||||
lib_plankton.log.set_main_logger([]);
|
lib_plankton.log.set_main_logger([]);
|
||||||
const rest_subject : lib_plankton.rest_http.type_rest = _zeitbild.api.make();
|
const rest_subject : lib_plankton.rest_http.type_rest = _zeitbild.api.make();
|
||||||
lib_plankton.log.conf_pop();
|
|
||||||
process.stdout.write(
|
process.stdout.write(
|
||||||
JSON.stringify(
|
JSON.stringify(
|
||||||
lib_plankton.rest_http.to_oas(rest_subject),
|
lib_plankton.rest_http.to_oas(rest_subject),
|
||||||
|
|
@ -480,6 +479,7 @@ async function main(
|
||||||
)
|
)
|
||||||
.catch(
|
.catch(
|
||||||
(error) => {
|
(error) => {
|
||||||
|
// console.error(error);
|
||||||
process.stderr.write(String(error) + "\n");
|
process.stderr.write(String(error) + "\n");
|
||||||
}
|
}
|
||||||
)
|
)
|
||||||
|
|
|
||||||
|
|
@ -42,7 +42,7 @@ namespace _zeitbild.repository.resource
|
||||||
|
|
||||||
/**
|
/**
|
||||||
*/
|
*/
|
||||||
var _caldav_resource_store : (
|
var _ics_feed_resource_store : (
|
||||||
null
|
null
|
||||||
|
|
|
|
||||||
lib_plankton.storage.type_store<
|
lib_plankton.storage.type_store<
|
||||||
|
|
@ -126,7 +126,7 @@ namespace _zeitbild.repository.resource
|
||||||
|
|
||||||
/**
|
/**
|
||||||
*/
|
*/
|
||||||
function get_caldav_resource_store(
|
function get_ics_feed_resource_store(
|
||||||
) : lib_plankton.storage.type_store<
|
) : lib_plankton.storage.type_store<
|
||||||
int,
|
int,
|
||||||
Record<string, any>,
|
Record<string, any>,
|
||||||
|
|
@ -135,11 +135,11 @@ namespace _zeitbild.repository.resource
|
||||||
Record<string, any>
|
Record<string, any>
|
||||||
>
|
>
|
||||||
{
|
{
|
||||||
if (_caldav_resource_store === null) {
|
if (_ics_feed_resource_store === null) {
|
||||||
_caldav_resource_store = lib_plankton.storage.sql_table_autokey_store(
|
_ics_feed_resource_store = lib_plankton.storage.sql_table_autokey_store(
|
||||||
{
|
{
|
||||||
"database_implementation": _zeitbild.database.get_implementation(),
|
"database_implementation": _zeitbild.database.get_implementation(),
|
||||||
"table_name": "caldav_resources",
|
"table_name": "ics_feed_resources",
|
||||||
"key_name": "id",
|
"key_name": "id",
|
||||||
}
|
}
|
||||||
);
|
);
|
||||||
|
|
@ -147,7 +147,7 @@ namespace _zeitbild.repository.resource
|
||||||
else {
|
else {
|
||||||
// do nothing
|
// do nothing
|
||||||
}
|
}
|
||||||
return _caldav_resource_store;
|
return _ics_feed_resource_store;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
@ -358,15 +358,14 @@ namespace _zeitbild.repository.resource
|
||||||
}
|
}
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
case "caldav": {
|
case "ics_feed": {
|
||||||
const dataset_extra_caldav : Record<string, any> = await get_caldav_resource_store().read(dataset_core.sub_id);
|
const dataset_extra_ics_feed : Record<string, any> = await get_ics_feed_resource_store().read(dataset_core.sub_id);
|
||||||
return Promise.resolve<_zeitbild.type_resource_object>(
|
return Promise.resolve<_zeitbild.type_resource_object>(
|
||||||
{
|
{
|
||||||
"kind": "caldav",
|
"kind": "ics_feed",
|
||||||
"data": {
|
"data": {
|
||||||
"url": dataset_extra_caldav["url"],
|
"url": dataset_extra_ics_feed["url"],
|
||||||
"read_only": dataset_extra_caldav["read_only"],
|
"from_fucked_up_wordpress": dataset_extra_ics_feed["from_fucked_up_wordpress"],
|
||||||
"from_fucked_up_wordpress": dataset_extra_caldav["from_fucked_up_wordpress"],
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
);
|
);
|
||||||
|
|
@ -405,18 +404,17 @@ namespace _zeitbild.repository.resource
|
||||||
return Promise.resolve<_zeitbild.type_resource_id>(resource_id);
|
return Promise.resolve<_zeitbild.type_resource_id>(resource_id);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
case "caldav": {
|
case "ics_feed": {
|
||||||
const caldav_resource_id : int = await get_caldav_resource_store().create(
|
const ics_feed_resource_id : int = await get_ics_feed_resource_store().create(
|
||||||
{
|
{
|
||||||
"url": resource_object.data.url,
|
"url": resource_object.data.url,
|
||||||
"read_only": resource_object.data.read_only,
|
|
||||||
"from_fucked_up_wordpress": resource_object.data.from_fucked_up_wordpress,
|
"from_fucked_up_wordpress": resource_object.data.from_fucked_up_wordpress,
|
||||||
}
|
}
|
||||||
);
|
);
|
||||||
const resource_id : _zeitbild.type_resource_id = await get_resource_core_store().create(
|
const resource_id : _zeitbild.type_resource_id = await get_resource_core_store().create(
|
||||||
{
|
{
|
||||||
"kind": "caldav",
|
"kind": "ics_feed",
|
||||||
"sub_id": caldav_resource_id,
|
"sub_id": ics_feed_resource_id,
|
||||||
}
|
}
|
||||||
);
|
);
|
||||||
await lib_plankton.cache.clear(_zeitbild.cache_regular);
|
await lib_plankton.cache.clear(_zeitbild.cache_regular);
|
||||||
|
|
@ -491,12 +489,12 @@ namespace _zeitbild.repository.resource
|
||||||
*/
|
*/
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
case "caldav": {
|
case "ics_feed": {
|
||||||
await get_caldav_resource_store().update(
|
await get_ics_feed_resource_store().update(
|
||||||
dataset_core["sub_id"],
|
dataset_core["sub_id"],
|
||||||
{
|
{
|
||||||
"url": resource_object.data.url,
|
"url": resource_object.data.url,
|
||||||
"read_only": resource_object.data.read_only,
|
"from_fucked_up_wordpress": resource_object.data.from_fucked_up_wordpress,
|
||||||
}
|
}
|
||||||
);
|
);
|
||||||
await lib_plankton.cache.clear(_zeitbild.cache_regular);
|
await lib_plankton.cache.clear(_zeitbild.cache_regular);
|
||||||
|
|
|
||||||
|
|
@ -53,6 +53,7 @@ namespace _zeitbild.repository.user
|
||||||
return {
|
return {
|
||||||
"name": user_object.name,
|
"name": user_object.name,
|
||||||
"email_address": user_object.email_address,
|
"email_address": user_object.email_address,
|
||||||
|
"dav_token": user_object.dav_token,
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -66,6 +67,7 @@ namespace _zeitbild.repository.user
|
||||||
return {
|
return {
|
||||||
"name": row["name"],
|
"name": row["name"],
|
||||||
"email_address": row["email_address"],
|
"email_address": row["email_address"],
|
||||||
|
"dav_token": row["dav_token"],
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -119,6 +121,19 @@ namespace _zeitbild.repository.user
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
*/
|
||||||
|
export async function update(
|
||||||
|
user_id : _zeitbild.type_user_id,
|
||||||
|
user_object : _zeitbild.type_user_object
|
||||||
|
) : Promise<void>
|
||||||
|
{
|
||||||
|
const dispersal : Record<string, any> = encode(user_object);
|
||||||
|
await get_store().update(user_id, dispersal);
|
||||||
|
return Promise.resolve<void>(undefined);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
*/
|
*/
|
||||||
export async function identify(
|
export async function identify(
|
||||||
|
|
|
||||||
|
|
@ -327,41 +327,54 @@ namespace _zeitbild.service.calendar
|
||||||
);
|
);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
case "caldav": {
|
case "ics_feed": {
|
||||||
// TODO readonly
|
// TODO readonly
|
||||||
const url : lib_plankton.url.type_url = lib_plankton.url.decode(
|
const vcalendar : lib_plankton.ical.type_vcalendar = await lib_plankton.cache.get<lib_plankton.ical.type_vcalendar>(
|
||||||
resource_object.data.url
|
_zeitbild.cache_external_resources,
|
||||||
);
|
resource_object.data.url,
|
||||||
const http_request : lib_plankton.http.type_request = {
|
_zeitbild.conf.get().external_resources.lifetime,
|
||||||
"version": "HTTP/2",
|
async () => {
|
||||||
"scheme": ((url.scheme === "https") ? "https" : "http"),
|
const url : lib_plankton.url.type_url = lib_plankton.url.decode(
|
||||||
"host": url.host,
|
resource_object.data.url
|
||||||
"path": (url.path ?? "/"),
|
);
|
||||||
"query": url.query,
|
const http_request : lib_plankton.http.type_request = {
|
||||||
"method": lib_plankton.http.enum_method.get,
|
"version": "HTTP/2",
|
||||||
"headers": {},
|
"scheme": ((url.scheme === "https") ? "https" : "http"),
|
||||||
"body": null,
|
"host": url.host,
|
||||||
};
|
"path": (url.path ?? "/"),
|
||||||
// TODO: cache?
|
"query": url.query,
|
||||||
const http_response : lib_plankton.http.type_response = await lib_plankton.http.call(
|
"method": lib_plankton.http.enum_method.get,
|
||||||
http_request,
|
"headers": {},
|
||||||
{
|
"body": null,
|
||||||
|
};
|
||||||
|
const http_response : lib_plankton.http.type_response = await lib_plankton.http.call(
|
||||||
|
http_request,
|
||||||
|
{
|
||||||
|
}
|
||||||
|
);
|
||||||
|
const ics_raw : string = (
|
||||||
|
(http_response.body === null)
|
||||||
|
?
|
||||||
|
""
|
||||||
|
:
|
||||||
|
http_response.body.toString()
|
||||||
|
);
|
||||||
|
const vcalendar_list : Array<lib_plankton.ical.type_vcalendar> = lib_plankton.ical.ics_decode_multi(
|
||||||
|
ics_raw,
|
||||||
|
{
|
||||||
|
"ignore_unhandled_instruction_keys": resource_object.data.from_fucked_up_wordpress,
|
||||||
|
"from_fucked_up_wordpress": resource_object.data.from_fucked_up_wordpress,
|
||||||
|
}
|
||||||
|
);
|
||||||
|
const vcalendar : lib_plankton.ical.type_vcalendar = {
|
||||||
|
// required
|
||||||
|
"version": vcalendar_list[0].version,
|
||||||
|
"prodid": vcalendar_list[0].prodid,
|
||||||
|
"vevents": vcalendar_list.map(x => x.vevents).reduce((x, y) => x.concat(y), []),
|
||||||
|
};
|
||||||
|
return Promise.resolve<lib_plankton.ical.type_vcalendar>(vcalendar);
|
||||||
}
|
}
|
||||||
);
|
);
|
||||||
const ics_raw : string = http_response.body.toString();
|
|
||||||
const vcalendar_list : Array<lib_plankton.ical.type_vcalendar> = lib_plankton.ical.ics_decode_multi(
|
|
||||||
ics_raw,
|
|
||||||
{
|
|
||||||
"ignore_unhandled_instruction_keys": resource_object.data.from_fucked_up_wordpress,
|
|
||||||
"from_fucked_up_wordpress": resource_object.data.from_fucked_up_wordpress,
|
|
||||||
}
|
|
||||||
);
|
|
||||||
const vcalendar : lib_plankton.ical.type_vcalendar = {
|
|
||||||
// required
|
|
||||||
"version": vcalendar_list[0].version,
|
|
||||||
"prodid": vcalendar_list[0].prodid,
|
|
||||||
"vevents": vcalendar_list.map(x => x.vevents).reduce((x, y) => x.concat(y), []),
|
|
||||||
};
|
|
||||||
return Promise.resolve(
|
return Promise.resolve(
|
||||||
vcalendar.vevents
|
vcalendar.vevents
|
||||||
.map(
|
.map(
|
||||||
|
|
@ -376,11 +389,11 @@ namespace _zeitbild.service.calendar
|
||||||
:
|
:
|
||||||
"???"
|
"???"
|
||||||
),
|
),
|
||||||
"begin": _zeitbild.helpers.ical_dt_to_own_datetime(vevent.dtstart),
|
"begin": _zeitbild.helpers.icalendar_dt_to_own_datetime(vevent.dtstart),
|
||||||
"end": (
|
"end": (
|
||||||
(vevent.dtend !== undefined)
|
(vevent.dtend !== undefined)
|
||||||
?
|
?
|
||||||
_zeitbild.helpers.ical_dt_to_own_datetime(vevent.dtend)
|
_zeitbild.helpers.icalendar_dt_to_own_datetime(vevent.dtend)
|
||||||
:
|
:
|
||||||
null
|
null
|
||||||
),
|
),
|
||||||
|
|
@ -441,19 +454,6 @@ namespace _zeitbild.service.calendar
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
/**
|
|
||||||
*/
|
|
||||||
type type_gather_events_result = Array<
|
|
||||||
{
|
|
||||||
calendar_id : _zeitbild.type_calendar_id;
|
|
||||||
calendar_name : string;
|
|
||||||
access_level : _zeitbild.enum_access_level;
|
|
||||||
event_id : (null | _zeitbild.type_local_resource_event_id);
|
|
||||||
event_object : _zeitbild.type_event_object;
|
|
||||||
}
|
|
||||||
>;
|
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
*/
|
*/
|
||||||
export async function gather_events(
|
export async function gather_events(
|
||||||
|
|
@ -461,7 +461,7 @@ namespace _zeitbild.service.calendar
|
||||||
from_pit : lib_plankton.pit.type_pit,
|
from_pit : lib_plankton.pit.type_pit,
|
||||||
to_pit : lib_plankton.pit.type_pit,
|
to_pit : lib_plankton.pit.type_pit,
|
||||||
user_id : (null | _zeitbild.type_user_id)
|
user_id : (null | _zeitbild.type_user_id)
|
||||||
) : Promise<type_gather_events_result>
|
) : Promise<Array<_zeitbild.type_event_extended>>
|
||||||
{
|
{
|
||||||
const calendar_ids_allowed : Array<_zeitbild.type_calendar_id> = (
|
const calendar_ids_allowed : Array<_zeitbild.type_calendar_id> = (
|
||||||
(await overview(user_id))
|
(await overview(user_id))
|
||||||
|
|
@ -483,8 +483,8 @@ namespace _zeitbild.service.calendar
|
||||||
)
|
)
|
||||||
);
|
);
|
||||||
calendar_ids.sort();
|
calendar_ids.sort();
|
||||||
return lib_plankton.cache.get_complex<any, type_gather_events_result>(
|
return lib_plankton.cache.get_complex<any, Array<_zeitbild.type_event_extended>>(
|
||||||
_zeitbild.cache,
|
_zeitbild.cache_regular,
|
||||||
"gather_events",
|
"gather_events",
|
||||||
{
|
{
|
||||||
"user_id": user_id,
|
"user_id": user_id,
|
||||||
|
|
@ -492,6 +492,10 @@ namespace _zeitbild.service.calendar
|
||||||
"to_pit": to_pit,
|
"to_pit": to_pit,
|
||||||
"calendar_ids": calendar_ids,
|
"calendar_ids": calendar_ids,
|
||||||
},
|
},
|
||||||
|
/**
|
||||||
|
* @todo expire?
|
||||||
|
*/
|
||||||
|
null,
|
||||||
() => (
|
() => (
|
||||||
Promise.all(
|
Promise.all(
|
||||||
calendar_ids
|
calendar_ids
|
||||||
|
|
|
||||||
|
|
@ -31,7 +31,7 @@ namespace _zeitbild.service.resource
|
||||||
return Promise.resolve<_zeitbild.type_event_object>(event_object);
|
return Promise.resolve<_zeitbild.type_event_object>(event_object);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
case "caldav": {
|
case "ics_feed": {
|
||||||
// TODO
|
// TODO
|
||||||
return Promise.reject(new Error("not implemented"));
|
return Promise.reject(new Error("not implemented"));
|
||||||
break;
|
break;
|
||||||
|
|
@ -63,14 +63,8 @@ namespace _zeitbild.service.resource
|
||||||
return Promise.resolve<_zeitbild.type_local_resource_event_id>(local_resource_event_id);
|
return Promise.resolve<_zeitbild.type_local_resource_event_id>(local_resource_event_id);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
case "caldav": {
|
case "ics_feed": {
|
||||||
if (resource_object.data.read_only) {
|
return Promise.reject(new Error("unavailable"));
|
||||||
return Promise.reject(new Error("can not add event to read only caldav resource"));
|
|
||||||
}
|
|
||||||
else {
|
|
||||||
// TODO
|
|
||||||
return Promise.reject(new Error("not implemented"));
|
|
||||||
}
|
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
default: {
|
default: {
|
||||||
|
|
@ -102,14 +96,8 @@ namespace _zeitbild.service.resource
|
||||||
return Promise.resolve<void>(undefined);
|
return Promise.resolve<void>(undefined);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
case "caldav": {
|
case "ics_feed": {
|
||||||
if (resource_object.data.read_only) {
|
return Promise.reject(new Error("unavailable"));
|
||||||
return Promise.reject(new Error("can not change event of read only caldav resource"));
|
|
||||||
}
|
|
||||||
else {
|
|
||||||
// TODO
|
|
||||||
return Promise.reject(new Error("not implemented"));
|
|
||||||
}
|
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
default: {
|
default: {
|
||||||
|
|
@ -139,14 +127,8 @@ namespace _zeitbild.service.resource
|
||||||
return Promise.resolve<void>(undefined);
|
return Promise.resolve<void>(undefined);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
case "caldav": {
|
case "ics_feed": {
|
||||||
if (resource_object.data.read_only) {
|
return Promise.reject(new Error("unavailable"));
|
||||||
return Promise.reject(new Error("can not delete event from read only caldav resource"));
|
|
||||||
}
|
|
||||||
else {
|
|
||||||
// TODO
|
|
||||||
return Promise.reject(new Error("not implemented"));
|
|
||||||
}
|
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
default: {
|
default: {
|
||||||
|
|
|
||||||
|
|
@ -28,6 +28,16 @@ namespace _zeitbild.service.user
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
*/
|
||||||
|
export function get(
|
||||||
|
user_id : _zeitbild.type_user_id
|
||||||
|
) : Promise<_zeitbild.type_user_object>
|
||||||
|
{
|
||||||
|
return _zeitbild.repository.user.read(user_id);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
*/
|
*/
|
||||||
export function add(
|
export function add(
|
||||||
|
|
@ -37,4 +47,15 @@ namespace _zeitbild.service.user
|
||||||
return _zeitbild.repository.user.create(user_object);
|
return _zeitbild.repository.user.create(user_object);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
*/
|
||||||
|
export function change(
|
||||||
|
user_id : _zeitbild.type_user_id,
|
||||||
|
user_object : _zeitbild.type_user_object
|
||||||
|
) : Promise<void>
|
||||||
|
{
|
||||||
|
return _zeitbild.repository.user.update(user_id, user_object);
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -28,6 +28,11 @@ namespace _zeitbild
|
||||||
|
|
|
|
||||||
string
|
string
|
||||||
);
|
);
|
||||||
|
dav_token : (
|
||||||
|
null
|
||||||
|
|
|
||||||
|
string
|
||||||
|
);
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
|
|
@ -82,10 +87,9 @@ namespace _zeitbild
|
||||||
}
|
}
|
||||||
|
|
|
|
||||||
{
|
{
|
||||||
kind : "caldav";
|
kind : "ics_feed";
|
||||||
data : {
|
data : {
|
||||||
url : string;
|
url : string;
|
||||||
read_only : boolean;
|
|
||||||
from_fucked_up_wordpress : boolean;
|
from_fucked_up_wordpress : boolean;
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
@ -111,5 +115,16 @@ namespace _zeitbild
|
||||||
};
|
};
|
||||||
resource_id : type_resource_id;
|
resource_id : type_resource_id;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
*/
|
||||||
|
export type type_event_extended = {
|
||||||
|
calendar_id : type_calendar_id;
|
||||||
|
calendar_name : string;
|
||||||
|
access_level : enum_access_level;
|
||||||
|
event_id : (null | type_local_resource_event_id);
|
||||||
|
event_object : type_event_object;
|
||||||
|
};
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -65,6 +65,8 @@ ${dir_temp}/zeitbild-unlinked.js: \
|
||||||
${dir_source}/api/actions/session_oidc.ts \
|
${dir_source}/api/actions/session_oidc.ts \
|
||||||
${dir_source}/api/actions/session_end.ts \
|
${dir_source}/api/actions/session_end.ts \
|
||||||
${dir_source}/api/actions/users.ts \
|
${dir_source}/api/actions/users.ts \
|
||||||
|
${dir_source}/api/actions/user_dav_conf.ts \
|
||||||
|
${dir_source}/api/actions/user_dav_token.ts \
|
||||||
${dir_source}/api/actions/calendar_list.ts \
|
${dir_source}/api/actions/calendar_list.ts \
|
||||||
${dir_source}/api/actions/calendar_get.ts \
|
${dir_source}/api/actions/calendar_get.ts \
|
||||||
${dir_source}/api/actions/calendar_add.ts \
|
${dir_source}/api/actions/calendar_add.ts \
|
||||||
|
|
@ -75,6 +77,7 @@ ${dir_temp}/zeitbild-unlinked.js: \
|
||||||
${dir_source}/api/actions/calendar_event_change.ts \
|
${dir_source}/api/actions/calendar_event_change.ts \
|
||||||
${dir_source}/api/actions/calendar_event_remove.ts \
|
${dir_source}/api/actions/calendar_event_remove.ts \
|
||||||
${dir_source}/api/actions/events.ts \
|
${dir_source}/api/actions/events.ts \
|
||||||
|
${dir_source}/api/actions/export_ics.ts \
|
||||||
${dir_source}/api/functions.ts \
|
${dir_source}/api/functions.ts \
|
||||||
${dir_source}/main.ts
|
${dir_source}/main.ts
|
||||||
@ ${cmd_log} "compile …"
|
@ ${cmd_log} "compile …"
|
||||||
|
|
|
||||||
Loading…
Reference in a new issue