Compare commits
10 commits
9eab32d573
...
bbfc07478f
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
bbfc07478f | ||
|
|
5afc562b18 | ||
|
|
6309422429 | ||
|
|
2683d49bba | ||
|
|
1df1fa3ac9 | ||
|
|
5ab91664ed | ||
|
|
fc228fb274 | ||
|
|
6ad47e1943 | ||
|
|
00f416a126 | ||
|
|
64652af779 |
|
|
@ -17,5 +17,11 @@
|
|||
"kind": "internal",
|
||||
"data": {
|
||||
}
|
||||
},
|
||||
"database": {
|
||||
"kind": "sqlite",
|
||||
"data": {
|
||||
"path": "../zeitbild.sqlite"
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -4,18 +4,21 @@
|
|||
"id": 1,
|
||||
"name": "alice",
|
||||
"email_address": "alice@example.org",
|
||||
"dav_token": null,
|
||||
"password": "alice"
|
||||
},
|
||||
{
|
||||
"id": 2,
|
||||
"name": "bob",
|
||||
"email_address": "bob@example.org",
|
||||
"dav_token": "a5f10bc2d4ded8c5a07c5cb1c4e8b74363abce59d626574f0a83e67d499d9d5f",
|
||||
"password": "bob"
|
||||
},
|
||||
{
|
||||
"id": 3,
|
||||
"name": "charlie",
|
||||
"email_address": "charlie@example.org",
|
||||
"dav_token": null,
|
||||
"password": "charlie"
|
||||
}
|
||||
],
|
||||
|
|
@ -44,12 +47,12 @@
|
|||
"name": "Aufstand: Mieten",
|
||||
"begin": {
|
||||
"timezone_shift": 2,
|
||||
"date": {"year": 2024, "month": 11, "day": 14},
|
||||
"date": {"year": 2025, "month": 9, "day": 14},
|
||||
"time": {"hour": 12, "minute": 0, "second": 0}
|
||||
},
|
||||
"end": {
|
||||
"timezone_shift": 2,
|
||||
"date": {"year": 2024, "month": 11, "day": 14},
|
||||
"date": {"year": 2025, "month": 9, "day": 14},
|
||||
"time": {"hour": 15, "minute": 0, "second": 0}
|
||||
},
|
||||
"location": "Porada Ninfu, Haupt-Markt",
|
||||
|
|
@ -59,12 +62,12 @@
|
|||
"name": "Aufstand: Waffen",
|
||||
"begin": {
|
||||
"timezone_shift": 2,
|
||||
"date": {"year": 2024, "month": 11, "day": 21},
|
||||
"date": {"year": 2025, "month": 9, "day": 21},
|
||||
"time": {"hour": 12, "minute": 0, "second": 0}
|
||||
},
|
||||
"end": {
|
||||
"timezone_shift": 2,
|
||||
"date": {"year": 2024, "month": 11, "day": 21},
|
||||
"date": {"year": 2025, "month": 9, "day": 21},
|
||||
"time": {"hour": 15, "minute": 0, "second": 0}
|
||||
},
|
||||
"location": "Tandreell, Stoiber-Platz",
|
||||
|
|
@ -74,12 +77,12 @@
|
|||
"name": "Aufstand: Essen",
|
||||
"begin": {
|
||||
"timezone_shift": 2,
|
||||
"date": {"year": 2024, "month": 12, "day": 28},
|
||||
"date": {"year": 2025, "month": 10, "day": 28},
|
||||
"time": {"hour": 12, "minute": 0, "second": 0}
|
||||
},
|
||||
"end": {
|
||||
"timezone_shift": 2,
|
||||
"date": {"year": 2024, "month": 12, "day": 28},
|
||||
"date": {"year": 2025, "month": 10, "day": 28},
|
||||
"time": {"hour": 15, "minute": 0, "second": 0}
|
||||
},
|
||||
"location": "Kawanda, Nord-Bahnhof",
|
||||
|
|
@ -113,12 +116,12 @@
|
|||
"name": "Feier: Bier",
|
||||
"begin": {
|
||||
"timezone_shift": 2,
|
||||
"date": {"year": 2024, "month": 11, "day": 18},
|
||||
"date": {"year": 2025, "month": 9, "day": 18},
|
||||
"time": {"hour": 18, "minute": 0, "second": 0}
|
||||
},
|
||||
"end": {
|
||||
"timezone_shift": 2,
|
||||
"date": {"year": 2024, "month": 11, "day": 18},
|
||||
"date": {"year": 2025, "month": 9, "day": 18},
|
||||
"time": {"hour": 23, "minute": 0, "second": 0}
|
||||
},
|
||||
"location": "Rudschadinedschad, Schlamm-Park",
|
||||
|
|
@ -128,12 +131,12 @@
|
|||
"name": "Feier: Schnapps",
|
||||
"begin": {
|
||||
"timezone_shift": 2,
|
||||
"date": {"year": 2024, "month": 12, "day": 1},
|
||||
"date": {"year": 2025, "month": 10, "day": 1},
|
||||
"time": {"hour": 18, "minute": 0, "second": 0}
|
||||
},
|
||||
"end": {
|
||||
"timezone_shift": 2,
|
||||
"date": {"year": 2024, "month": 12, "day": 1},
|
||||
"date": {"year": 2025, "month": 10, "day": 1},
|
||||
"time": {"hour": 23, "minute": 0, "second": 0}
|
||||
},
|
||||
"location": "Kawanda, Ratten-Platz",
|
||||
|
|
@ -163,12 +166,12 @@
|
|||
"name": "Aufräumen: Flaschen",
|
||||
"begin": {
|
||||
"timezone_shift": 2,
|
||||
"date": {"year": 2024, "month": 11, "day": 24},
|
||||
"date": {"year": 2025, "month": 9, "day": 24},
|
||||
"time": {"hour": 15, "minute": 0, "second": 0}
|
||||
},
|
||||
"end": {
|
||||
"timezone_shift": 2,
|
||||
"date": {"year": 2024, "month": 11, "day": 24},
|
||||
"date": {"year": 2025, "month": 9, "day": 24},
|
||||
"time": {"hour": 17, "minute": 0, "second": 0}
|
||||
},
|
||||
"location": "Kawanda, Penner-Allee",
|
||||
|
|
@ -202,12 +205,12 @@
|
|||
"name": "Infostand",
|
||||
"begin": {
|
||||
"timezone_shift": 2,
|
||||
"date": {"year": 2024, "month": 11, "day": 16},
|
||||
"date": {"year": 2025, "month": 9, "day": 16},
|
||||
"time": {"hour": 10, "minute": 0, "second": 0}
|
||||
},
|
||||
"end": {
|
||||
"timezone_shift": 2,
|
||||
"date": {"year": 2024, "month": 11, "day": 16},
|
||||
"date": {"year": 2025, "month": 9, "day": 16},
|
||||
"time": {"hour": 14, "minute": 0, "second": 0}
|
||||
},
|
||||
"location": "Rudschadinedschad, Schabracken-Markt",
|
||||
|
|
|
|||
511
lib/plankton/plankton.d.ts
vendored
511
lib/plankton/plankton.d.ts
vendored
|
|
@ -650,6 +650,9 @@ declare namespace lib_plankton.call {
|
|||
value: (null | type_value);
|
||||
error: (null | any);
|
||||
}>;
|
||||
/**
|
||||
*/
|
||||
export function sleep(seconds: float): Promise<void>;
|
||||
export {};
|
||||
}
|
||||
declare namespace lib_plankton.email {
|
||||
|
|
@ -1550,6 +1553,12 @@ declare namespace lib_plankton.conf {
|
|||
} | {
|
||||
not: type_schema;
|
||||
});
|
||||
/**
|
||||
*/
|
||||
type type_sheet<type_content> = {
|
||||
version: (null | string);
|
||||
content: type_content;
|
||||
};
|
||||
/**
|
||||
*/
|
||||
type type_report = {
|
||||
|
|
@ -1562,15 +1571,24 @@ declare namespace lib_plankton.conf {
|
|||
reports: Array<type_report>;
|
||||
result: lib_plankton.pod.type_pod<type_result>;
|
||||
};
|
||||
/**
|
||||
*/
|
||||
type type_migration<type_from, type_to> = (null | {
|
||||
target: string;
|
||||
function: ((content: type_from) => type_to);
|
||||
});
|
||||
}
|
||||
declare namespace lib_plankton.conf {
|
||||
/**
|
||||
* @todo versioning
|
||||
*/
|
||||
function refine<type_result>(schema: type_schema, value_raw: any): type_result;
|
||||
function refine<type_result>(schema: type_schema, content: any): type_result;
|
||||
/**
|
||||
* @deprecated
|
||||
*/
|
||||
function load<type_result>(schema: type_schema, path: (null | string)): Promise<type_result>;
|
||||
/**
|
||||
*/
|
||||
function load(schema: type_schema, path: (null | string)): Promise<void>;
|
||||
function load_versioned(path: string, get_schema: ((version: string) => type_schema), migrations: Record<string, type_migration<any, any>>): Promise<type_sheet<any>>;
|
||||
}
|
||||
declare var plain_text_to_html: (text: string) => string;
|
||||
/**
|
||||
|
|
@ -2495,95 +2513,47 @@ declare namespace lib_plankton.storage.sql_table_common {
|
|||
declare namespace lib_plankton.cache {
|
||||
/**
|
||||
*/
|
||||
type type_cache<type_value> = {
|
||||
init: (() => Promise<void>);
|
||||
clear: (() => Promise<void>);
|
||||
query: ((key: string, retrieve: (() => Promise<type_value>)) => Promise<{
|
||||
retrieved: boolean;
|
||||
value: type_value;
|
||||
}>);
|
||||
type type_result<type_value> = {
|
||||
retrieved: boolean;
|
||||
value: type_value;
|
||||
};
|
||||
/**
|
||||
*/
|
||||
type type_entry<type_value> = {
|
||||
value: type_value;
|
||||
expiry: (null | float);
|
||||
};
|
||||
/**
|
||||
*/
|
||||
type type_subject<type_value> = lib_plankton.storage.type_chest<string, type_entry<type_value>, void, any, any>;
|
||||
}
|
||||
declare namespace lib_plankton.cache {
|
||||
/**
|
||||
*/
|
||||
function get<type_value>(cache: type_cache<type_value>, key: string, retrieve: (() => Promise<type_value>)): Promise<type_value>;
|
||||
/**
|
||||
*/
|
||||
function get_complex<type_input, type_value>(cache: type_cache<type_value>, group: string, input: type_input, retrieve: ((input: type_input) => Promise<type_value>), options?: {
|
||||
encode_input?: ((input: type_input) => string);
|
||||
}): Promise<type_value>;
|
||||
}
|
||||
declare namespace lib_plankton.cache.never {
|
||||
/**
|
||||
* @author fenris
|
||||
*/
|
||||
type type_subject<type_value> = {};
|
||||
/**
|
||||
* @author fenris
|
||||
*/
|
||||
function make<type_value>(): type_subject<type_value>;
|
||||
/**
|
||||
*/
|
||||
function implementation<type_value>(subject: type_subject<type_value>): type_cache<type_value>;
|
||||
}
|
||||
declare namespace lib_plankton.cache.always {
|
||||
/**
|
||||
* @author fenris
|
||||
*/
|
||||
type type_subject<type_value> = {
|
||||
value: lib_plankton.pod.type_pod<type_value>;
|
||||
};
|
||||
/**
|
||||
* @author fenris
|
||||
*/
|
||||
function make<type_value>(value: lib_plankton.pod.type_pod<type_value>): type_subject<type_value>;
|
||||
/**
|
||||
* @author fenris
|
||||
*/
|
||||
function clear<type_value>(subject: type_subject<type_value>): Promise<void>;
|
||||
/**
|
||||
* @author fenris
|
||||
*/
|
||||
function query<type_value>(subject: type_subject<type_value>, key: string, retrieve: (() => Promise<type_value>)): Promise<{
|
||||
retrieved: boolean;
|
||||
value: type_value;
|
||||
}>;
|
||||
/**
|
||||
*/
|
||||
function implementation<type_value>(subject: type_subject<type_value>): type_cache<type_value>;
|
||||
}
|
||||
declare namespace lib_plankton.cache.chest {
|
||||
/**
|
||||
* @author fenris
|
||||
*/
|
||||
type type_subject<type_value> = {
|
||||
chest: lib_plankton.storage.type_chest<string, type_value, void, any, any>;
|
||||
};
|
||||
/**
|
||||
* @author fenris
|
||||
*/
|
||||
function make<type_value>(options?: {
|
||||
chest?: lib_plankton.storage.type_chest<string, type_value, void, any, any>;
|
||||
function make<type_value>({ "chest": chest, }?: {
|
||||
chest?: lib_plankton.storage.type_chest<string, type_entry<type_value>, void, any, any>;
|
||||
}): type_subject<type_value>;
|
||||
/**
|
||||
* @author fenris
|
||||
*/
|
||||
function init<type_value>(subject: type_subject<type_value>): Promise<void>;
|
||||
/**
|
||||
* @author fenris
|
||||
*/
|
||||
function clear<type_value>(subject: type_subject<type_value>): Promise<void>;
|
||||
/**
|
||||
* @author fenris
|
||||
*/
|
||||
function query<type_value>(subject: type_subject<type_value>, key: string, retrieve: (() => Promise<type_value>)): Promise<{
|
||||
retrieved: boolean;
|
||||
value: type_value;
|
||||
}>;
|
||||
function invalidate<type_value>(subject: type_subject<type_value>, key: string): Promise<void>;
|
||||
/**
|
||||
*/
|
||||
function implementation<type_value>(subject: type_subject<type_value>): type_cache<type_value>;
|
||||
function query<type_value>(subject: type_subject<type_value>, key: string, lifetime: (null | float), retrieve: (() => Promise<type_value>)): Promise<type_result<type_value>>;
|
||||
/**
|
||||
* syntactic sugar: if the information, whether the value was retrieved, is irrelevant
|
||||
*/
|
||||
function get<type_value>(subject: type_subject<type_value>, key: string, lifetime: (null | float), retrieve: (() => Promise<type_value>)): Promise<type_value>;
|
||||
/**
|
||||
*/
|
||||
function get_complex<type_input, type_value>(cache: type_subject<type_value>, group: string, input: type_input, lifetime: (null | float), retrieve: ((input: type_input) => Promise<type_value>), { "encode_input": encode_input, }?: {
|
||||
encode_input?: ((input: type_input) => string);
|
||||
}): Promise<type_value>;
|
||||
}
|
||||
declare namespace lib_plankton.shape {
|
||||
/**
|
||||
|
|
@ -3237,18 +3207,45 @@ declare namespace lib_plankton.pit {
|
|||
/**
|
||||
*/
|
||||
function is_before(pit: type_pit, reference: type_pit): boolean;
|
||||
/**
|
||||
*/
|
||||
function is_after(pit: type_pit, reference: type_pit): boolean;
|
||||
/**
|
||||
*/
|
||||
function is_equal_or_after(pit: type_pit, reference: type_pit): boolean;
|
||||
/**
|
||||
*/
|
||||
function is_between(pit: type_pit, reference_left: type_pit, reference_right: type_pit): boolean;
|
||||
/**
|
||||
*/
|
||||
function shift_hour(pit: type_pit, increment: int): type_pit;
|
||||
/**
|
||||
*/
|
||||
function shift_day(pit: type_pit, increment: int): type_pit;
|
||||
/**
|
||||
*/
|
||||
function shift_week(pit: type_pit, increment: int): type_pit;
|
||||
/**
|
||||
*/
|
||||
function shift_year(pit: type_pit, increment: int): type_pit;
|
||||
/**
|
||||
*/
|
||||
function trunc_minute(pit: type_pit): type_pit;
|
||||
/**
|
||||
*/
|
||||
function trunc_hour(pit: type_pit): type_pit;
|
||||
/**
|
||||
*/
|
||||
function trunc_day(pit: type_pit): type_pit;
|
||||
/**
|
||||
*/
|
||||
function trunc_week(pit: type_pit): type_pit;
|
||||
/**
|
||||
*/
|
||||
function trunc_month(pit: type_pit): type_pit;
|
||||
/**
|
||||
*/
|
||||
function trunc_year(pit: type_pit): type_pit;
|
||||
/**
|
||||
*/
|
||||
function now(): type_pit;
|
||||
|
|
@ -3668,352 +3665,6 @@ declare namespace lib_plankton.http {
|
|||
implementation?: ("fetch" | "http_module");
|
||||
}): Promise<type_response>;
|
||||
}
|
||||
declare namespace lib_plankton.xml {
|
||||
/**
|
||||
*/
|
||||
type type_node_data = ({
|
||||
kind: "root";
|
||||
data: {
|
||||
version: string;
|
||||
encoding: string;
|
||||
content: type_node_data;
|
||||
};
|
||||
} | {
|
||||
kind: "comment";
|
||||
data: string;
|
||||
} | {
|
||||
kind: "text";
|
||||
data: string;
|
||||
} | {
|
||||
kind: "complex";
|
||||
data: {
|
||||
tag: string;
|
||||
attributes: Record<string, string>;
|
||||
children: Array<type_node_data>;
|
||||
};
|
||||
});
|
||||
/**
|
||||
*/
|
||||
type type_node_logic = {
|
||||
compile: ((depths: int) => string);
|
||||
};
|
||||
/**
|
||||
*/
|
||||
function get_node_logic(node_data: type_node_data): type_node_logic;
|
||||
/**
|
||||
*/
|
||||
function parse(xml_string: string): Promise<type_node_data>;
|
||||
}
|
||||
declare namespace lib_plankton.webdav {
|
||||
/**
|
||||
* @todo try to base on lib_plankton.http.enum_method
|
||||
*/
|
||||
enum enum_method {
|
||||
options = "options",
|
||||
head = "head",
|
||||
get = "get",
|
||||
delete = "delete",
|
||||
post = "post",
|
||||
put = "put",
|
||||
patch = "patch",
|
||||
propfind = "propfind",
|
||||
proppatch = "proppatch",
|
||||
mkcol = "mkcol",
|
||||
copy = "copy",
|
||||
move = "move",
|
||||
lock = "lock",
|
||||
unlock = "unlock"
|
||||
}
|
||||
/**
|
||||
* @todo try to base on lib_plankton.http.enum_status_code
|
||||
*/
|
||||
enum enum_status_code {
|
||||
continue_ = 100,
|
||||
switching_protocols = 101,
|
||||
early_hints = 103,
|
||||
ok = 200,
|
||||
created = 201,
|
||||
accepted = 202,
|
||||
non_authoritative_information = 203,
|
||||
no_content = 204,
|
||||
reset_content = 205,
|
||||
partial_coentent = 206,
|
||||
multistatus = 207,
|
||||
multiple_choices = 300,
|
||||
moved_permanently = 301,
|
||||
found = 302,
|
||||
see_other = 303,
|
||||
not_modified = 304,
|
||||
temporary_redirect = 307,
|
||||
permanent_redirect = 308,
|
||||
bad_request = 400,
|
||||
unauthorized = 401,
|
||||
payment_required = 402,
|
||||
forbidden = 403,
|
||||
not_found = 404,
|
||||
method_not_allowed = 405,
|
||||
not_acceptable = 406,
|
||||
proxy_authentication_required = 407,
|
||||
request_timeout = 408,
|
||||
conflict = 409,
|
||||
gone = 410,
|
||||
length_required = 411,
|
||||
precondition_failed = 412,
|
||||
payload_too_large = 413,
|
||||
uri_too_long = 414,
|
||||
unsupported_media_type = 415,
|
||||
range_not_satisfiable = 416,
|
||||
expectation_failed = 417,
|
||||
i_m_a_teapot = 418,
|
||||
unprocessable_entity = 422,
|
||||
too_early = 425,
|
||||
upgrade_required = 426,
|
||||
precondition_required = 428,
|
||||
too_many_requests = 429,
|
||||
request_header_fields_too_large = 431,
|
||||
unavailable_for_legal_reasons = 451,
|
||||
internal_server_error = 500,
|
||||
not_implemented = 501,
|
||||
bad_gateway = 502,
|
||||
service_unavailable = 503,
|
||||
gateway_timeout = 504,
|
||||
http_version_not_supported = 505,
|
||||
variant_also_negotiates = 506,
|
||||
insufficient_storage = 507,
|
||||
loop_detected = 508,
|
||||
not_extended = 510,
|
||||
network_authentication = 511
|
||||
}
|
||||
/**
|
||||
* @see http://www.webdav.org/specs/rfc2518.html#ELEMENT_href
|
||||
*/
|
||||
type type_data_href = string;
|
||||
/**
|
||||
* @see http://www.webdav.org/specs/rfc2518.html#ELEMENT_status
|
||||
*/
|
||||
type type_data_status = string;
|
||||
/**
|
||||
*/
|
||||
type type_data_prop_value = ({
|
||||
kind: "none";
|
||||
data: null;
|
||||
} | {
|
||||
kind: "primitive";
|
||||
data: string;
|
||||
} | {
|
||||
kind: "href";
|
||||
data: string;
|
||||
} | {
|
||||
kind: "resourcetype";
|
||||
data: {
|
||||
kind: string;
|
||||
type: string;
|
||||
};
|
||||
} | {
|
||||
kind: "privileges";
|
||||
data: Array<string>;
|
||||
} | {
|
||||
kind: "component_set";
|
||||
data: {
|
||||
name: string;
|
||||
items: Array<string>;
|
||||
};
|
||||
});
|
||||
/**
|
||||
* @see http://www.webdav.org/specs/rfc2518.html#ELEMENT_prop
|
||||
*/
|
||||
type type_data_prop = {
|
||||
name: string;
|
||||
value: type_data_prop_value;
|
||||
};
|
||||
/**
|
||||
* @see http://www.webdav.org/specs/rfc2518.html#ELEMENT_propstat
|
||||
*/
|
||||
type type_data_propstat = {
|
||||
prop: Array<type_data_prop>;
|
||||
status: string;
|
||||
description: (null | string);
|
||||
};
|
||||
/**
|
||||
* @see http://www.webdav.org/specs/rfc2518.html#ELEMENT_response
|
||||
*/
|
||||
type type_data_response = {
|
||||
href: type_data_href;
|
||||
body: ({
|
||||
hrefs: Array<type_data_href>;
|
||||
status: string;
|
||||
} | {
|
||||
propstats: Array<type_data_propstat>;
|
||||
});
|
||||
description: (null | string);
|
||||
};
|
||||
/**
|
||||
* @see http://www.webdav.org/specs/rfc2518.html#ELEMENT_multistatus
|
||||
*/
|
||||
type type_data_multistatus = {
|
||||
responses: Array<type_data_response>;
|
||||
description: (null | string);
|
||||
};
|
||||
/**
|
||||
*/
|
||||
type type_request = lib_plankton.http_base.type_request<enum_method>;
|
||||
/**
|
||||
*/
|
||||
type type_response = lib_plankton.http_base.type_response<enum_status_code>;
|
||||
}
|
||||
declare namespace lib_plankton.webdav {
|
||||
/**
|
||||
*/
|
||||
function is_special_method(method: enum_method): boolean;
|
||||
/**
|
||||
* @author roydfalk <roydfalk@folksprak.org>
|
||||
*/
|
||||
function encode_method(method: enum_method): string;
|
||||
/**
|
||||
* @author roydfalk <roydfalk@folksprak.org>
|
||||
*/
|
||||
function decode_method(method_raw: string): enum_method;
|
||||
/**
|
||||
* @todo check
|
||||
*/
|
||||
function has_body(method: enum_method): boolean;
|
||||
/**
|
||||
*/
|
||||
function decode_request(request_raw: string): type_request;
|
||||
/**
|
||||
*/
|
||||
function encode_response(response: type_response): string;
|
||||
/**
|
||||
*/
|
||||
function decode_response(response_raw: string): type_response;
|
||||
/**
|
||||
*/
|
||||
function encode_request(request: type_request): string;
|
||||
/**
|
||||
* @todo description
|
||||
*/
|
||||
function data_multistatus_encode_xml(data_multistatus: type_data_multistatus): lib_plankton.xml.type_node_data;
|
||||
/**
|
||||
*/
|
||||
function data_multistatus_encode(data_multistatus: type_data_multistatus): string;
|
||||
}
|
||||
declare namespace lib_plankton.caldav {
|
||||
/**
|
||||
* @todo try to base on lib_plankton.webdav.enum_method
|
||||
*/
|
||||
enum enum_method {
|
||||
options = "options",
|
||||
head = "head",
|
||||
get = "get",
|
||||
delete = "delete",
|
||||
post = "post",
|
||||
put = "put",
|
||||
patch = "patch",
|
||||
propfind = "propfind",
|
||||
proppatch = "proppatch",
|
||||
mkcol = "mkcol",
|
||||
copy = "copy",
|
||||
move = "move",
|
||||
lock = "lock",
|
||||
unlock = "unlock",
|
||||
report = "report",
|
||||
mkcalendar = "mkcalendar",
|
||||
acl = "acl"
|
||||
}
|
||||
/**
|
||||
* @todo try to base on lib_plankton.webdav.enum_status_code
|
||||
*/
|
||||
enum enum_status_code {
|
||||
continue_ = 100,
|
||||
switching_protocols = 101,
|
||||
early_hints = 103,
|
||||
ok = 200,
|
||||
created = 201,
|
||||
accepted = 202,
|
||||
non_authoritative_information = 203,
|
||||
no_content = 204,
|
||||
reset_content = 205,
|
||||
partial_coentent = 206,
|
||||
multistatus = 207,
|
||||
multiple_choices = 300,
|
||||
moved_permanently = 301,
|
||||
found = 302,
|
||||
see_other = 303,
|
||||
not_modified = 304,
|
||||
temporary_redirect = 307,
|
||||
permanent_redirect = 308,
|
||||
bad_request = 400,
|
||||
unauthorized = 401,
|
||||
payment_required = 402,
|
||||
forbidden = 403,
|
||||
not_found = 404,
|
||||
method_not_allowed = 405,
|
||||
not_acceptable = 406,
|
||||
proxy_authentication_required = 407,
|
||||
request_timeout = 408,
|
||||
conflict = 409,
|
||||
gone = 410,
|
||||
length_required = 411,
|
||||
precondition_failed = 412,
|
||||
payload_too_large = 413,
|
||||
uri_too_long = 414,
|
||||
unsupported_media_type = 415,
|
||||
range_not_satisfiable = 416,
|
||||
expectation_failed = 417,
|
||||
i_m_a_teapot = 418,
|
||||
unprocessable_entity = 422,
|
||||
too_early = 425,
|
||||
upgrade_required = 426,
|
||||
precondition_required = 428,
|
||||
too_many_requests = 429,
|
||||
request_header_fields_too_large = 431,
|
||||
unavailable_for_legal_reasons = 451,
|
||||
internal_server_error = 500,
|
||||
not_implemented = 501,
|
||||
bad_gateway = 502,
|
||||
service_unavailable = 503,
|
||||
gateway_timeout = 504,
|
||||
http_version_not_supported = 505,
|
||||
variant_also_negotiates = 506,
|
||||
insufficient_storage = 507,
|
||||
loop_detected = 508,
|
||||
not_extended = 510,
|
||||
network_authentication = 511
|
||||
}
|
||||
/**
|
||||
*/
|
||||
type type_request = lib_plankton.http_base.type_request<enum_method>;
|
||||
/**
|
||||
*/
|
||||
type type_response = lib_plankton.http_base.type_response<enum_status_code>;
|
||||
}
|
||||
declare namespace lib_plankton.caldav {
|
||||
/**
|
||||
*/
|
||||
function is_special_method(method: enum_method): boolean;
|
||||
/**
|
||||
*/
|
||||
function encode_method(method: enum_method): string;
|
||||
/**
|
||||
*/
|
||||
function decode_method(method_raw: string): enum_method;
|
||||
/**
|
||||
* @todo check
|
||||
*/
|
||||
function has_body(method: enum_method): boolean;
|
||||
/**
|
||||
*/
|
||||
function encode_request(request: type_request): string;
|
||||
/**
|
||||
*/
|
||||
function decode_request(request_raw: string): type_request;
|
||||
/**
|
||||
*/
|
||||
function encode_response(response: type_response): string;
|
||||
/**
|
||||
*/
|
||||
function decode_response(response_raw: string): type_response;
|
||||
}
|
||||
declare namespace lib_plankton.markdown {
|
||||
/**
|
||||
* @author fenris
|
||||
|
|
@ -4027,6 +3678,10 @@ declare namespace lib_plankton.markdown {
|
|||
* @author fenris
|
||||
*/
|
||||
function sectionhead(level: int, content: string): string;
|
||||
/**
|
||||
* @author fenris
|
||||
*/
|
||||
function list(level: int, elements: Array<string>): string;
|
||||
}
|
||||
declare namespace lib_plankton.api {
|
||||
/**
|
||||
|
|
@ -4334,7 +3989,7 @@ declare namespace lib_plankton.rest_base {
|
|||
servers?: Array<string>;
|
||||
}): any;
|
||||
}
|
||||
declare namespace lib_plankton.rest_caldav {
|
||||
declare namespace lib_plankton.rest_http {
|
||||
/**
|
||||
*/
|
||||
type type_oas_schema = lib_plankton.rest_base.type_oas_schema;
|
||||
|
|
@ -4354,7 +4009,7 @@ declare namespace lib_plankton.rest_caldav {
|
|||
*/
|
||||
type type_rest = lib_plankton.rest_base.type_rest;
|
||||
}
|
||||
declare namespace lib_plankton.rest_caldav {
|
||||
declare namespace lib_plankton.rest_http {
|
||||
/**
|
||||
*/
|
||||
function make(options?: {
|
||||
|
|
@ -4378,25 +4033,25 @@ declare namespace lib_plankton.rest_caldav {
|
|||
};
|
||||
});
|
||||
actions?: Array<{
|
||||
http_method: lib_plankton.caldav.enum_method;
|
||||
http_method: lib_plankton.http.enum_method;
|
||||
path: string;
|
||||
options: lib_plankton.rest_base.type_action_options<any, any>;
|
||||
}>;
|
||||
}): type_rest;
|
||||
/**
|
||||
*/
|
||||
function register<type_input, type_output>(rest: type_rest, http_method: lib_plankton.caldav.enum_method, path: string, options: lib_plankton.rest_base.type_action_options<type_input, type_output>): void;
|
||||
function register<type_input, type_output>(rest: type_rest, http_method: lib_plankton.http.enum_method, path: string, options: lib_plankton.rest_base.type_action_options<type_input, type_output>): void;
|
||||
/**
|
||||
* @todo check request body mimetype?
|
||||
* @todo check query paramater validity
|
||||
* @todo improve status code mapping
|
||||
*/
|
||||
function call(rest: type_rest, http_request: lib_plankton.caldav.type_request, { "checklevel_restriction": option_checklevel_restriction, "checklevel_input": option_checklevel_input, "checklevel_output": option_checklevel_output, "set_content_length": option_set_content_length, }?: {
|
||||
function call(rest: type_rest, http_request: lib_plankton.http.type_request, { "checklevel_restriction": option_checklevel_restriction, "checklevel_input": option_checklevel_input, "checklevel_output": option_checklevel_output, "set_content_length": option_set_content_length, }?: {
|
||||
checklevel_restriction?: lib_plankton.api.enum_checklevel;
|
||||
checklevel_input?: lib_plankton.api.enum_checklevel;
|
||||
checklevel_output?: lib_plankton.api.enum_checklevel;
|
||||
set_content_length?: boolean;
|
||||
}): Promise<lib_plankton.caldav.type_response>;
|
||||
}): Promise<lib_plankton.http.type_response>;
|
||||
/**
|
||||
* @see https://swagger.io/specification/#openrest-object
|
||||
*/
|
||||
|
|
|
|||
File diff suppressed because it is too large
Load diff
|
|
@ -1,236 +0,0 @@
|
|||
|
||||
namespace _zeitbild.api
|
||||
{
|
||||
|
||||
/**
|
||||
*/
|
||||
export function register_caldav_get(
|
||||
rest_subject : lib_plankton.rest_caldav.type_rest
|
||||
) : void
|
||||
{
|
||||
register<
|
||||
null,
|
||||
/*
|
||||
(
|
||||
null
|
||||
|
|
||||
string
|
||||
|
|
||||
lib_plankton.ical.type_vcalendar
|
||||
)
|
||||
*/
|
||||
(
|
||||
null
|
||||
|
|
||||
lib_plankton.xml.type_node_data
|
||||
)
|
||||
>(
|
||||
rest_subject,
|
||||
lib_plankton.caldav.enum_method.report,
|
||||
"/caldav/project/:id",
|
||||
{
|
||||
"description": "trägt Veranstaltungen aus verschiedenen Kalendern zusammen im ical-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",
|
||||
},
|
||||
{
|
||||
"name": "auth",
|
||||
"required": true,
|
||||
"description": "",
|
||||
},
|
||||
]),
|
||||
"output_schema": () => ({
|
||||
"nullable": false,
|
||||
"type": "string",
|
||||
}),
|
||||
/*
|
||||
"response_body_mimetype": "text/calendar",
|
||||
"response_body_encode": (output) => (
|
||||
(output === null)
|
||||
?
|
||||
null
|
||||
:
|
||||
Buffer.from(
|
||||
(typeof(output) === "string")
|
||||
?
|
||||
output
|
||||
:
|
||||
lib_plankton.ical.ics_encode(output)
|
||||
)
|
||||
),
|
||||
*/
|
||||
"response_body_mimetype": "text/xml",
|
||||
"response_body_encode": output => Promise.resolve<Buffer>(
|
||||
Buffer.from(
|
||||
lib_plankton.xml.get_node_logic(output).compile(0)
|
||||
)
|
||||
),
|
||||
"restriction": restriction_none,
|
||||
/**
|
||||
* @todo use stuff.path_parameters["id"]
|
||||
*/
|
||||
"execution": async (stuff) => {
|
||||
const user_id : (null | type_user_id) = await _zeitbild.api.web_auth(
|
||||
stuff.headers["Authorization"]
|
||||
??
|
||||
stuff.headers["authorization"]
|
||||
??
|
||||
null
|
||||
);
|
||||
if (user_id === null) {
|
||||
return Promise.resolve(
|
||||
{
|
||||
"status_code": 401,
|
||||
"data": null,
|
||||
"extra_headers": {
|
||||
"WWW-Authenticate": "Basic realm=Restricted",
|
||||
}
|
||||
}
|
||||
);
|
||||
}
|
||||
else {
|
||||
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(
|
||||
(data) => Promise.resolve(
|
||||
{
|
||||
"status_code": 200,
|
||||
/*
|
||||
"data": _zeitbild.helpers.ical_vcalendar_from_own_event_list(
|
||||
data.map(entry => entry.event_object)
|
||||
)
|
||||
*/
|
||||
"data": lib_plankton.webdav.data_multistatus_encode_xml(
|
||||
{
|
||||
"responses": (
|
||||
/**
|
||||
* @todo find proper solution for null values
|
||||
*/
|
||||
data
|
||||
.filter(
|
||||
entry => (entry.event_id !== null)
|
||||
)
|
||||
.map(
|
||||
entry => ({
|
||||
"href": lib_plankton.string.coin(
|
||||
"/caldav/project/{{calendar_id}}/{{event_id}}",
|
||||
{
|
||||
"calendar_id": stuff.path_parameters["id"],
|
||||
"event_id": (entry.event_id ?? 0).toFixed(0),
|
||||
}
|
||||
),
|
||||
"body": {
|
||||
"propstats": [
|
||||
{
|
||||
"prop": [
|
||||
{
|
||||
"name": "C:calendar-data",
|
||||
"value": {
|
||||
"kind": "primitive",
|
||||
"data": lib_plankton.ical.ics_encode(
|
||||
/*
|
||||
{
|
||||
"version": "2.0",
|
||||
"prodid": "zeitbild",
|
||||
"vevents": [],
|
||||
"method": "publish",
|
||||
}
|
||||
*/
|
||||
_zeitbild.helpers.ical_vcalendar_from_own_event_list(
|
||||
data
|
||||
.map(
|
||||
entry => entry.event_object
|
||||
)
|
||||
)
|
||||
)
|
||||
}
|
||||
},
|
||||
],
|
||||
"status": "HTTP/1.1 200 OK",
|
||||
"description": null,
|
||||
}
|
||||
]
|
||||
},
|
||||
"description": null
|
||||
})
|
||||
)
|
||||
),
|
||||
"description": null
|
||||
}
|
||||
)
|
||||
}
|
||||
)
|
||||
)
|
||||
.catch(
|
||||
(reason) => Promise.resolve(
|
||||
{
|
||||
"status_code": 403,
|
||||
"data": /*String(reason)*/null,
|
||||
}
|
||||
)
|
||||
)
|
||||
);
|
||||
}
|
||||
}
|
||||
}
|
||||
);
|
||||
}
|
||||
|
||||
}
|
||||
|
|
@ -1,109 +0,0 @@
|
|||
|
||||
namespace _zeitbild.api
|
||||
{
|
||||
|
||||
/**
|
||||
*/
|
||||
export function register_caldav_probe(
|
||||
rest_subject : lib_plankton.rest_caldav.type_rest
|
||||
) : void
|
||||
{
|
||||
register<
|
||||
(
|
||||
null
|
||||
|
|
||||
lib_plankton.xml.type_node_data
|
||||
),
|
||||
lib_plankton.xml.type_node_data
|
||||
>(
|
||||
rest_subject,
|
||||
lib_plankton.caldav.enum_method.propfind,
|
||||
"/caldav",
|
||||
{
|
||||
"request_body_mimetype": () => "text/xml",
|
||||
"request_body_decode": () => async (body, header_content_type) => (
|
||||
(
|
||||
(header_content_type !== null)
|
||||
&&
|
||||
(
|
||||
(header_content_type.startsWith("text/xml"))
|
||||
||
|
||||
(header_content_type.startsWith("application/xml"))
|
||||
)
|
||||
)
|
||||
?
|
||||
lib_plankton.xml.parse(body.toString())
|
||||
:
|
||||
Promise.resolve<any>(null)
|
||||
),
|
||||
"output_schema": () => ({
|
||||
"nullable": false,
|
||||
"type": "string",
|
||||
}),
|
||||
"response_body_mimetype": "text/xml",
|
||||
"response_body_encode": output => Promise.resolve<Buffer>(
|
||||
Buffer.from(
|
||||
lib_plankton.xml.get_node_logic(output).compile(0)
|
||||
)
|
||||
),
|
||||
// "restriction": restriction_basic_auth,
|
||||
"restriction": restriction_none,
|
||||
"execution": async (stuff) => {
|
||||
const user_id : (null | type_user_id) = await _zeitbild.api.web_auth(
|
||||
stuff.headers["Authorization"]
|
||||
??
|
||||
stuff.headers["authorization"]
|
||||
??
|
||||
null
|
||||
);
|
||||
if (user_id === null) {
|
||||
return Promise.resolve(
|
||||
{
|
||||
"status_code": 401,
|
||||
"data": {
|
||||
"kind": "text",
|
||||
"data": ""
|
||||
},
|
||||
"extra_headers": {
|
||||
"WWW-Authenticate": "Basic realm=Restricted",
|
||||
}
|
||||
}
|
||||
);
|
||||
}
|
||||
else {
|
||||
const output : (null | lib_plankton.xml.type_node_data) = _zeitbild.service.caldav.probe(
|
||||
stuff.input
|
||||
);
|
||||
if (output !== null) {
|
||||
return Promise.resolve(
|
||||
{
|
||||
"status_code": 207,
|
||||
"data": output
|
||||
}
|
||||
);
|
||||
}
|
||||
else {
|
||||
return Promise.resolve(
|
||||
{
|
||||
"status_code": 501,
|
||||
"data": {
|
||||
"kind": "root",
|
||||
"data": {
|
||||
"version": "1.0",
|
||||
"encoding": "utf-8",
|
||||
"content": {
|
||||
"kind": "text",
|
||||
"data": ""
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
);
|
||||
}
|
||||
|
||||
}
|
||||
|
|
@ -1,115 +0,0 @@
|
|||
|
||||
namespace _zeitbild.api
|
||||
{
|
||||
|
||||
/**
|
||||
*/
|
||||
export function register_caldav_probe_via_well_known(
|
||||
rest_subject : lib_plankton.rest_caldav.type_rest
|
||||
) : void
|
||||
{
|
||||
register<
|
||||
(
|
||||
null
|
||||
|
|
||||
lib_plankton.xml.type_node_data
|
||||
),
|
||||
lib_plankton.xml.type_node_data
|
||||
>(
|
||||
rest_subject,
|
||||
lib_plankton.caldav.enum_method.propfind,
|
||||
"/.well-known/caldav",
|
||||
{
|
||||
"request_body_mimetype": () => "text/xml",
|
||||
"request_body_decode": () => async (body, header_content_type) => (
|
||||
(
|
||||
(header_content_type !== null)
|
||||
&&
|
||||
(
|
||||
(header_content_type.startsWith("text/xml"))
|
||||
||
|
||||
(header_content_type.startsWith("application/xml"))
|
||||
)
|
||||
)
|
||||
?
|
||||
lib_plankton.xml.parse(body.toString())
|
||||
:
|
||||
Promise.resolve<any>(null)
|
||||
),
|
||||
"output_schema": () => ({
|
||||
"nullable": false,
|
||||
"type": "string",
|
||||
}),
|
||||
"response_body_mimetype": "text/xml",
|
||||
"response_body_encode": output => Promise.resolve<Buffer>(
|
||||
Buffer.from(
|
||||
lib_plankton.xml.get_node_logic(output).compile(0)
|
||||
)
|
||||
),
|
||||
// "restriction": restriction_basic_auth,
|
||||
"restriction": restriction_none,
|
||||
"execution": async (stuff) => {
|
||||
const user_id : (null | type_user_id) = await _zeitbild.api.web_auth(
|
||||
stuff.headers["Authorization"]
|
||||
??
|
||||
stuff.headers["authorization"]
|
||||
??
|
||||
null
|
||||
);
|
||||
if (user_id === null) {
|
||||
return Promise.resolve(
|
||||
{
|
||||
"status_code": 401,
|
||||
"data": {
|
||||
"kind": "text",
|
||||
"data": ""
|
||||
},
|
||||
"extra_headers": {
|
||||
"WWW-Authenticate": "Basic realm=Restricted",
|
||||
}
|
||||
}
|
||||
);
|
||||
}
|
||||
else {
|
||||
const output : (null | lib_plankton.xml.type_node_data) = _zeitbild.service.caldav.probe(
|
||||
stuff.input,
|
||||
{
|
||||
"force_props": [
|
||||
"D:displayname",
|
||||
"D:resourcetype",
|
||||
]
|
||||
}
|
||||
);
|
||||
if (output !== null) {
|
||||
return Promise.resolve(
|
||||
{
|
||||
"status_code": 207,
|
||||
"data": output
|
||||
}
|
||||
);
|
||||
}
|
||||
else {
|
||||
return Promise.resolve(
|
||||
{
|
||||
"status_code": 501,
|
||||
"data": {
|
||||
"kind": "root",
|
||||
"data": {
|
||||
"version": "1.0",
|
||||
"encoding": "utf-8",
|
||||
"content": {
|
||||
"kind": "text",
|
||||
"data": ""
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
);
|
||||
}
|
||||
|
||||
}
|
||||
|
|
@ -1,107 +0,0 @@
|
|||
|
||||
namespace _zeitbild.api
|
||||
{
|
||||
|
||||
/**
|
||||
*/
|
||||
export function register_caldav_projects(
|
||||
rest_subject : lib_plankton.rest_caldav.type_rest
|
||||
) : void
|
||||
{
|
||||
register<
|
||||
lib_plankton.xml.type_node_data,
|
||||
(
|
||||
null
|
||||
|
|
||||
lib_plankton.xml.type_node_data
|
||||
)
|
||||
>(
|
||||
rest_subject,
|
||||
lib_plankton.caldav.enum_method.propfind,
|
||||
"/caldav/project",
|
||||
{
|
||||
"output_schema": () => ({
|
||||
"nullable": false,
|
||||
"type": "string",
|
||||
}),
|
||||
"request_body_mimetype": () => "text/xml",
|
||||
"request_body_decode": () => async (body, header_content_type) => (
|
||||
(
|
||||
(header_content_type !== null)
|
||||
&&
|
||||
(
|
||||
(header_content_type.startsWith("text/xml"))
|
||||
||
|
||||
(header_content_type.startsWith("application/xml"))
|
||||
)
|
||||
)
|
||||
?
|
||||
lib_plankton.xml.parse(body.toString())
|
||||
:
|
||||
Promise.resolve<any>(null)
|
||||
),
|
||||
"response_body_mimetype": "text/xml",
|
||||
"response_body_encode": output => Promise.resolve<Buffer>(
|
||||
Buffer.from(
|
||||
lib_plankton.xml.get_node_logic(output).compile(0)
|
||||
)
|
||||
),
|
||||
// "restriction": restriction_basic_auth,
|
||||
"restriction": restriction_none,
|
||||
/**
|
||||
* @todo heed stuff.input
|
||||
*/
|
||||
"execution": async (stuff) => {
|
||||
const user_id : (null | type_user_id) = await _zeitbild.api.web_auth(
|
||||
stuff.headers["Authorization"]
|
||||
??
|
||||
stuff.headers["authorization"]
|
||||
??
|
||||
null
|
||||
);
|
||||
if (user_id === null) {
|
||||
return Promise.resolve(
|
||||
{
|
||||
"status_code": 401,
|
||||
"data": {
|
||||
"kind": "text",
|
||||
"data": ""
|
||||
},
|
||||
"extra_headers": {
|
||||
"WWW-Authenticate": "Basic realm=Restricted",
|
||||
}
|
||||
}
|
||||
);
|
||||
}
|
||||
else {
|
||||
if (stuff.input === null) {
|
||||
return Promise.resolve(
|
||||
{
|
||||
"status_code": 400,
|
||||
"data": null,
|
||||
}
|
||||
);
|
||||
}
|
||||
else {
|
||||
return (
|
||||
_zeitbild.service.caldav.projects(
|
||||
stuff.input,
|
||||
user_id
|
||||
)
|
||||
.then(
|
||||
(output) => Promise.resolve(
|
||||
{
|
||||
"status_code": 207,
|
||||
"data": output,
|
||||
}
|
||||
)
|
||||
)
|
||||
);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
);
|
||||
}
|
||||
|
||||
}
|
||||
|
|
@ -1,32 +0,0 @@
|
|||
|
||||
namespace _zeitbild.api
|
||||
{
|
||||
|
||||
/**
|
||||
*/
|
||||
export function register_caldav_put(
|
||||
rest_subject : lib_plankton.rest_caldav.type_rest
|
||||
) : void
|
||||
{
|
||||
register<
|
||||
null,
|
||||
null
|
||||
>(
|
||||
rest_subject,
|
||||
lib_plankton.caldav.enum_method.put,
|
||||
"/caldav",
|
||||
{
|
||||
"restriction": restriction_none,
|
||||
"execution": async (stuff) => {
|
||||
return Promise.resolve(
|
||||
{
|
||||
"status_code": 200,
|
||||
"data": null
|
||||
}
|
||||
);
|
||||
}
|
||||
}
|
||||
);
|
||||
}
|
||||
|
||||
}
|
||||
|
|
@ -1,46 +0,0 @@
|
|||
|
||||
namespace _zeitbild.api
|
||||
{
|
||||
|
||||
/**
|
||||
*/
|
||||
export function register_caldav_sniff(
|
||||
rest_subject : lib_plankton.rest_caldav.type_rest
|
||||
) : void
|
||||
{
|
||||
register<
|
||||
any,
|
||||
null
|
||||
>(
|
||||
rest_subject,
|
||||
lib_plankton.caldav.enum_method.options,
|
||||
"/caldav",
|
||||
{
|
||||
"restriction": restriction_none,
|
||||
"execution": async (stuff) => {
|
||||
const permitted : boolean = await restriction_basic_auth(stuff);
|
||||
if (! permitted) {
|
||||
return Promise.resolve(
|
||||
{
|
||||
"status_code": 401,
|
||||
"data": null,
|
||||
"extra_headers": {
|
||||
"WWW-Authenticate": "Basic realm=Restricted",
|
||||
}
|
||||
}
|
||||
);
|
||||
}
|
||||
else {
|
||||
return Promise.resolve(
|
||||
{
|
||||
"status_code": 200,
|
||||
"data": null
|
||||
}
|
||||
);
|
||||
}
|
||||
}
|
||||
}
|
||||
);
|
||||
}
|
||||
|
||||
}
|
||||
|
|
@ -5,7 +5,7 @@ namespace _zeitbild.api
|
|||
/**
|
||||
*/
|
||||
export function register_calendar_add(
|
||||
rest_subject : lib_plankton.rest_caldav.type_rest
|
||||
rest_subject : lib_plankton.rest_http.type_rest
|
||||
) : void
|
||||
{
|
||||
register<
|
||||
|
|
@ -29,10 +29,9 @@ namespace _zeitbild.api
|
|||
}
|
||||
|
|
||||
{
|
||||
kind : "caldav";
|
||||
kind : "ics_feed";
|
||||
data : {
|
||||
url : string;
|
||||
read_only : boolean;
|
||||
from_fucked_up_wordpress : boolean;
|
||||
};
|
||||
}
|
||||
|
|
@ -64,7 +63,8 @@ namespace _zeitbild.api
|
|||
else {
|
||||
// TODO move logic to calendar service
|
||||
let resource_object : _zeitbild.type_resource_object;
|
||||
switch (stuff.input.resource.kind) {
|
||||
switch (stuff.input.resource.kind)
|
||||
{
|
||||
case "local": {
|
||||
resource_object = {
|
||||
"kind": "local",
|
||||
|
|
@ -74,12 +74,11 @@ namespace _zeitbild.api
|
|||
};
|
||||
break;
|
||||
}
|
||||
case "caldav": {
|
||||
case "ics_feed": {
|
||||
resource_object = {
|
||||
"kind": "caldav",
|
||||
"kind": "ics_feed",
|
||||
"data": {
|
||||
"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,
|
||||
}
|
||||
};
|
||||
|
|
|
|||
|
|
@ -5,7 +5,7 @@ namespace _zeitbild.api
|
|||
/**
|
||||
*/
|
||||
export function register_calendar_change(
|
||||
rest_subject : lib_plankton.rest_caldav.type_rest
|
||||
rest_subject : lib_plankton.rest_http.type_rest
|
||||
) : void
|
||||
{
|
||||
register<
|
||||
|
|
|
|||
|
|
@ -5,7 +5,7 @@ namespace _zeitbild.api
|
|||
/**
|
||||
*/
|
||||
export function register_calendar_event_add(
|
||||
rest_subject : lib_plankton.rest_caldav.type_rest
|
||||
rest_subject : lib_plankton.rest_http.type_rest
|
||||
) : void
|
||||
{
|
||||
register<
|
||||
|
|
|
|||
|
|
@ -5,7 +5,7 @@ namespace _zeitbild.api
|
|||
/**
|
||||
*/
|
||||
export function register_calendar_event_change(
|
||||
rest_subject : lib_plankton.rest_caldav.type_rest
|
||||
rest_subject : lib_plankton.rest_http.type_rest
|
||||
) : void
|
||||
{
|
||||
register<
|
||||
|
|
|
|||
|
|
@ -5,7 +5,7 @@ namespace _zeitbild.api
|
|||
/**
|
||||
*/
|
||||
export function register_calendar_event_get(
|
||||
rest_subject : lib_plankton.rest_caldav.type_rest
|
||||
rest_subject : lib_plankton.rest_http.type_rest
|
||||
) : void
|
||||
{
|
||||
register<
|
||||
|
|
|
|||
|
|
@ -5,7 +5,7 @@ namespace _zeitbild.api
|
|||
/**
|
||||
*/
|
||||
export function register_calendar_event_remove(
|
||||
rest_subject : lib_plankton.rest_caldav.type_rest
|
||||
rest_subject : lib_plankton.rest_http.type_rest
|
||||
) : void
|
||||
{
|
||||
register<
|
||||
|
|
|
|||
|
|
@ -5,7 +5,7 @@ namespace _zeitbild.api
|
|||
/**
|
||||
*/
|
||||
export function register_calendar_get(
|
||||
rest_subject : lib_plankton.rest_caldav.type_rest
|
||||
rest_subject : lib_plankton.rest_http.type_rest
|
||||
) : void
|
||||
{
|
||||
register<
|
||||
|
|
|
|||
|
|
@ -5,7 +5,7 @@ namespace _zeitbild.api
|
|||
/**
|
||||
*/
|
||||
export function register_calendar_list(
|
||||
rest_subject : lib_plankton.rest_caldav.type_rest
|
||||
rest_subject : lib_plankton.rest_http.type_rest
|
||||
) : void
|
||||
{
|
||||
register<
|
||||
|
|
|
|||
|
|
@ -5,7 +5,7 @@ namespace _zeitbild.api
|
|||
/**
|
||||
*/
|
||||
export function register_calendar_remove(
|
||||
rest_subject : lib_plankton.rest_caldav.type_rest
|
||||
rest_subject : lib_plankton.rest_http.type_rest
|
||||
) : void
|
||||
{
|
||||
register<
|
||||
|
|
|
|||
|
|
@ -5,7 +5,7 @@ namespace _zeitbild.api
|
|||
/**
|
||||
*/
|
||||
export function register_events(
|
||||
rest_subject : lib_plankton.rest_caldav.type_rest
|
||||
rest_subject : lib_plankton.rest_http.type_rest
|
||||
) : void
|
||||
{
|
||||
register<
|
||||
|
|
|
|||
|
|
@ -4,8 +4,8 @@ namespace _zeitbild.api
|
|||
|
||||
/**
|
||||
*/
|
||||
export function register_export_ical(
|
||||
rest_subject : lib_plankton.rest_caldav.type_rest
|
||||
export function register_export_ics(
|
||||
rest_subject : lib_plankton.rest_http.type_rest
|
||||
) : void
|
||||
{
|
||||
register<
|
||||
|
|
@ -18,9 +18,9 @@ namespace _zeitbild.api
|
|||
>(
|
||||
rest_subject,
|
||||
lib_plankton.http.enum_method.get,
|
||||
"/export/ical",
|
||||
"/export/ics",
|
||||
{
|
||||
"description": "trägt Veranstaltungen aus verschiedenen Kalendern zusammen im ical-Format",
|
||||
"description": "trägt Veranstaltungen aus verschiedenen Kalendern zusammen im ics-Format",
|
||||
"query_parameters": () => ([
|
||||
{
|
||||
"name": "from",
|
||||
|
|
@ -37,11 +37,6 @@ namespace _zeitbild.api
|
|||
"required": false,
|
||||
"description": "comma separated",
|
||||
},
|
||||
{
|
||||
"name": "auth",
|
||||
"required": true,
|
||||
"description": "",
|
||||
},
|
||||
]),
|
||||
"output_schema": () => ({
|
||||
"nullable": false,
|
||||
|
|
@ -55,18 +50,9 @@ namespace _zeitbild.api
|
|||
:
|
||||
lib_plankton.ical.ics_encode(output)
|
||||
),
|
||||
"restriction": restriction_none,
|
||||
"restriction": restriction_web_auth,
|
||||
"execution": async (stuff) => {
|
||||
const user_id : (null | _zeitbild.type_user_id) = await (
|
||||
session_from_stuff(stuff)
|
||||
.then(
|
||||
(session : {key : string; value : lib_plankton.session.type_session;}) => (
|
||||
_zeitbild.service.user.identify(session.value.name)
|
||||
.catch(x => Promise.resolve(null))
|
||||
)
|
||||
)
|
||||
.catch(x => Promise.resolve(null))
|
||||
);
|
||||
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)
|
||||
|
|
@ -107,57 +93,32 @@ namespace _zeitbild.api
|
|||
null
|
||||
);
|
||||
|
||||
const auth_hash_shall : string = lib_plankton.sha256.get(
|
||||
(stuff.query_parameters["calendar_ids"] ?? ""),
|
||||
_zeitbild.conf.get()["misc"]["auth_salt"]
|
||||
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),
|
||||
}
|
||||
)
|
||||
)
|
||||
);
|
||||
const auth_hash_is : string = stuff.query_parameters["auth"];
|
||||
/**
|
||||
* @todo remove
|
||||
*/
|
||||
lib_plankton.log.info(
|
||||
"auth_hashes",
|
||||
{
|
||||
"shall": auth_hash_shall,
|
||||
"is": auth_hash_is,
|
||||
}
|
||||
);
|
||||
if (! (auth_hash_is === auth_hash_shall)) {
|
||||
return Promise.resolve(
|
||||
{
|
||||
"status_code": 403,
|
||||
"data": "not authorized",
|
||||
}
|
||||
);
|
||||
}
|
||||
else {
|
||||
return (
|
||||
_zeitbild.service.calendar.gather_events(
|
||||
calendar_ids_wanted,
|
||||
from,
|
||||
to,
|
||||
user_id
|
||||
)
|
||||
.then(
|
||||
(data) => Promise.resolve(
|
||||
{
|
||||
"status_code": 200,
|
||||
"data": _zeitbild.helpers.ical_vcalendar_from_own_event_list(
|
||||
data.map(entry => entry.event_object)
|
||||
)
|
||||
}
|
||||
)
|
||||
)
|
||||
.catch(
|
||||
(reason) => Promise.resolve(
|
||||
{
|
||||
"status_code": 403,
|
||||
"data": String(reason),
|
||||
}
|
||||
)
|
||||
)
|
||||
);
|
||||
}
|
||||
}
|
||||
}
|
||||
);
|
||||
|
|
@ -5,10 +5,10 @@ namespace _zeitbild.api
|
|||
/**
|
||||
*/
|
||||
export function register_meta_ping(
|
||||
rest_subject : lib_plankton.rest_caldav.type_rest
|
||||
rest_subject : lib_plankton.rest_http.type_rest
|
||||
) : void
|
||||
{
|
||||
lib_plankton.rest_caldav.register<
|
||||
lib_plankton.rest_http.register<
|
||||
null,
|
||||
string
|
||||
>
|
||||
|
|
|
|||
|
|
@ -5,10 +5,10 @@ namespace _zeitbild.api
|
|||
/**
|
||||
*/
|
||||
export function register_meta_spec(
|
||||
rest_subject : lib_plankton.rest_caldav.type_rest
|
||||
rest_subject : lib_plankton.rest_http.type_rest
|
||||
) : void
|
||||
{
|
||||
lib_plankton.rest_caldav.register<
|
||||
lib_plankton.rest_http.register<
|
||||
null,
|
||||
any
|
||||
>
|
||||
|
|
@ -27,7 +27,7 @@ namespace _zeitbild.api
|
|||
"execution": () => () => {
|
||||
return Promise.resolve({
|
||||
"status_code": 200,
|
||||
"data": lib_plankton.rest_caldav.to_oas(rest_subject),
|
||||
"data": lib_plankton.rest_http.to_oas(rest_subject),
|
||||
});
|
||||
},
|
||||
}
|
||||
|
|
|
|||
|
|
@ -5,10 +5,10 @@ namespace _zeitbild.api
|
|||
/**
|
||||
*/
|
||||
export function register_session_begin(
|
||||
rest_subject : lib_plankton.rest_caldav.type_rest
|
||||
rest_subject : lib_plankton.rest_http.type_rest
|
||||
) : void
|
||||
{
|
||||
lib_plankton.rest_caldav.register<
|
||||
lib_plankton.rest_http.register<
|
||||
{
|
||||
name : string;
|
||||
password : string;
|
||||
|
|
|
|||
|
|
@ -5,7 +5,7 @@ namespace _zeitbild.api
|
|||
/**
|
||||
*/
|
||||
export function register_session_end(
|
||||
rest_subject : lib_plankton.rest_caldav.type_rest
|
||||
rest_subject : lib_plankton.rest_http.type_rest
|
||||
) : void
|
||||
{
|
||||
register<null, null>(
|
||||
|
|
|
|||
|
|
@ -5,7 +5,7 @@ namespace _zeitbild.api
|
|||
/**
|
||||
*/
|
||||
export function register_session_oidc(
|
||||
rest_subject : lib_plankton.rest_caldav.type_rest
|
||||
rest_subject : lib_plankton.rest_http.type_rest
|
||||
) : void
|
||||
{
|
||||
register<
|
||||
|
|
@ -74,6 +74,7 @@ namespace _zeitbild.api
|
|||
{
|
||||
"name": data.userinfo.name,
|
||||
"email_address": data.userinfo.email,
|
||||
"dav_token": null,
|
||||
}
|
||||
);
|
||||
lib_plankton.log.info(
|
||||
|
|
|
|||
|
|
@ -5,10 +5,10 @@ namespace _zeitbild.api
|
|||
/**
|
||||
*/
|
||||
export function register_session_prepare(
|
||||
rest_subject : lib_plankton.rest_caldav.type_rest
|
||||
rest_subject : lib_plankton.rest_http.type_rest
|
||||
) : void
|
||||
{
|
||||
lib_plankton.rest_caldav.register<
|
||||
lib_plankton.rest_http.register<
|
||||
any,
|
||||
{
|
||||
kind : string;
|
||||
|
|
|
|||
|
|
@ -5,7 +5,7 @@ namespace _zeitbild.api
|
|||
/**
|
||||
*/
|
||||
export function register_users(
|
||||
rest_subject : lib_plankton.rest_caldav.type_rest
|
||||
rest_subject : lib_plankton.rest_http.type_rest
|
||||
) : void
|
||||
{
|
||||
register<
|
||||
|
|
|
|||
|
|
@ -6,10 +6,10 @@ namespace _zeitbild.api
|
|||
* @todo zu plankton auslagern?
|
||||
*/
|
||||
type type_stuff = {
|
||||
version: (null | string);
|
||||
headers: Record<string, string>;
|
||||
path_parameters: Record<string, string>;
|
||||
query_parameters: Record<string, string>;
|
||||
version : (null | string);
|
||||
headers : Record<string, string>;
|
||||
path_parameters : Record<string, string>;
|
||||
query_parameters : Record<string, string>;
|
||||
};
|
||||
|
||||
|
||||
|
|
@ -26,31 +26,47 @@ namespace _zeitbild.api
|
|||
|
||||
|
||||
/**
|
||||
* @todo outsource?
|
||||
*/
|
||||
export async function web_auth(
|
||||
authorization_string : (null | string)
|
||||
) : Promise<(null | _zeitbild.type_user_id)>
|
||||
{
|
||||
if (authorization_string === null) {
|
||||
return Promise.resolve<(null | _zeitbild.type_user_id)>(null);
|
||||
export async function user_from_web_auth(
|
||||
stuff : {headers : Record<string, string>;}
|
||||
) : Promise<
|
||||
{
|
||||
id : _zeitbild.type_user_id;
|
||||
object : _zeitbild.type_user_object;
|
||||
}
|
||||
else {
|
||||
>
|
||||
{
|
||||
const authorization_string : string = (
|
||||
stuff.headers["Authorization"]
|
||||
??
|
||||
stuff.headers["authorization"]
|
||||
??
|
||||
null
|
||||
);
|
||||
if (authorization_string === null)
|
||||
{
|
||||
return Promise.reject(new Error("authorization header missing"));
|
||||
}
|
||||
else
|
||||
{
|
||||
const parts : Array<string> = authorization_string.split(" ");
|
||||
const strategy : string = parts[0];
|
||||
const data_raw : string = parts.slice(1).join(" ");
|
||||
switch (strategy) {
|
||||
default: {
|
||||
switch (strategy)
|
||||
{
|
||||
default:
|
||||
{
|
||||
lib_plankton.log.notice(
|
||||
"zeitbild.web_auth.unhandled_strategy",
|
||||
"zeitbild.user_from_web_auth.unhandled_strategy",
|
||||
{
|
||||
"strategy": strategy,
|
||||
}
|
||||
);
|
||||
return Promise.resolve<(null | _zeitbild.type_user_id)>(null);
|
||||
return Promise.reject(new Error("unhandled authorization strategy: " + strategy));
|
||||
break;
|
||||
}
|
||||
case "Basic": {
|
||||
case "Basic":
|
||||
{
|
||||
const data_raw_decoded : string = lib_plankton.base64.decode(data_raw);
|
||||
const parts_ : Array<string> = data_raw_decoded.split(":");
|
||||
const username : string = parts_[0];
|
||||
|
|
@ -58,35 +74,47 @@ namespace _zeitbild.api
|
|||
const {"value": user_id, "error": error} = await lib_plankton.call.try_catch_wrap_async<_zeitbild.type_user_id>(
|
||||
() => _zeitbild.service.user.identify(username)
|
||||
);
|
||||
if (error !== null) {
|
||||
if ((error !== null) || (user_id === null))
|
||||
{
|
||||
lib_plankton.log.notice(
|
||||
"zeitbild.web_auth.unknown_user",
|
||||
"zeitbild.user_from_web_auth.unknown_user",
|
||||
{
|
||||
"username": username,
|
||||
}
|
||||
);
|
||||
return Promise.resolve<(null | _zeitbild.type_user_id)>(null);
|
||||
return Promise.reject();
|
||||
}
|
||||
else {
|
||||
const password_shall : string = lib_plankton.sha256.get(
|
||||
username,
|
||||
_zeitbild.conf.get()["misc"]["auth_salt"]
|
||||
);
|
||||
if (! (password_is === password_shall)) {
|
||||
/**
|
||||
* @todo remove
|
||||
*/
|
||||
else
|
||||
{
|
||||
const user_object : _zeitbild.type_user_object = await _zeitbild.service.user.get(user_id);
|
||||
if (user_object.dav_token === null)
|
||||
{
|
||||
lib_plankton.log.notice(
|
||||
"zeitbild.web_auth.wrong_pasword",
|
||||
"zeitbild.user_from_web_auth.dav_token_unset",
|
||||
{
|
||||
"shall": password_shall,
|
||||
"is": password_is,
|
||||
"user_id": user_id,
|
||||
}
|
||||
);
|
||||
return Promise.resolve<(null | _zeitbild.type_user_id)>(null);
|
||||
return Promise.reject(new Error("DAV token unset"));
|
||||
}
|
||||
else {
|
||||
return Promise.resolve<(null | _zeitbild.type_user_id)>(user_id);
|
||||
else
|
||||
{
|
||||
const password_shall : string = user_object.dav_token;
|
||||
if (! (password_is === password_shall))
|
||||
{
|
||||
lib_plankton.log.notice(
|
||||
"zeitbild.user_from_web_auth.wrong_password",
|
||||
{
|
||||
"user_id": user_id,
|
||||
"password_is": password_is,
|
||||
}
|
||||
);
|
||||
return Promise.reject(new Error("wrong password"));
|
||||
}
|
||||
else
|
||||
{
|
||||
return Promise.resolve({"id": user_id, "object": user_object});
|
||||
}
|
||||
}
|
||||
}
|
||||
break;
|
||||
|
|
@ -98,7 +126,25 @@ namespace _zeitbild.api
|
|||
|
||||
/**
|
||||
*/
|
||||
export const restriction_logged_in : lib_plankton.rest_caldav.type_restriction<any> = (
|
||||
export const restriction_none : lib_plankton.rest_http.type_restriction<any> = (
|
||||
(stuff) => Promise.resolve<boolean>(true)
|
||||
);
|
||||
|
||||
|
||||
/**
|
||||
*/
|
||||
export const restriction_web_auth : lib_plankton.rest_http.type_restriction<any> = (
|
||||
stuff => (
|
||||
user_from_web_auth(stuff)
|
||||
.then(() => Promise.resolve<boolean>(true))
|
||||
.catch(() => Promise.resolve<boolean>(false))
|
||||
)
|
||||
);
|
||||
|
||||
|
||||
/**
|
||||
*/
|
||||
export const restriction_logged_in : lib_plankton.rest_http.type_restriction<any> = (
|
||||
(stuff) => (
|
||||
session_from_stuff(stuff)
|
||||
.then(() => Promise.resolve<boolean>(true))
|
||||
|
|
@ -107,43 +153,16 @@ namespace _zeitbild.api
|
|||
);
|
||||
|
||||
|
||||
/**
|
||||
*/
|
||||
export const restriction_basic_auth : lib_plankton.rest_caldav.type_restriction<any> = (
|
||||
(stuff) => (
|
||||
web_auth(
|
||||
stuff.headers["Authorization"]
|
||||
??
|
||||
stuff.headers["authorization"]
|
||||
??
|
||||
null
|
||||
)
|
||||
.then<boolean>(
|
||||
(user_id) => Promise.resolve<boolean>(
|
||||
(user_id !== null)
|
||||
)
|
||||
)
|
||||
)
|
||||
);
|
||||
|
||||
|
||||
/**
|
||||
*/
|
||||
export const restriction_none : lib_plankton.rest_caldav.type_restriction<any> = (
|
||||
(stuff) => Promise.resolve<boolean>(true)
|
||||
);
|
||||
|
||||
|
||||
/**
|
||||
*/
|
||||
export function register<type_input, type_output>(
|
||||
rest_subject : lib_plankton.rest_caldav.type_rest,
|
||||
http_method : lib_plankton.caldav.enum_method,
|
||||
rest_subject : lib_plankton.rest_http.type_rest,
|
||||
http_method : lib_plankton.http.enum_method,
|
||||
path : string,
|
||||
options : {
|
||||
active ?: ((version : (null | string)) => boolean);
|
||||
restriction ?: (null | lib_plankton.rest_caldav.type_restriction<type_input>);
|
||||
execution ?: lib_plankton.rest_caldav.type_execution<type_input, type_output>;
|
||||
restriction ?: (null | lib_plankton.rest_http.type_restriction<type_input>);
|
||||
execution ?: lib_plankton.rest_http.type_execution<type_input, type_output>;
|
||||
title ?: (null | string);
|
||||
description ?: (null | string);
|
||||
query_parameters ?: ((version : (null | string)) => Array<
|
||||
|
|
@ -153,8 +172,8 @@ namespace _zeitbild.api
|
|||
required : boolean;
|
||||
}
|
||||
>);
|
||||
input_schema ?: ((version: (null | string)) => lib_plankton.rest_caldav.type_oas_schema);
|
||||
output_schema ?: ((version: (null | string)) => lib_plankton.rest_caldav.type_oas_schema);
|
||||
input_schema ?: ((version: (null | string)) => lib_plankton.rest_http.type_oas_schema);
|
||||
output_schema ?: ((version: (null | string)) => lib_plankton.rest_http.type_oas_schema);
|
||||
request_body_mimetype ?: (
|
||||
(version : (null | string))
|
||||
=>
|
||||
|
|
@ -181,7 +200,7 @@ namespace _zeitbild.api
|
|||
},
|
||||
options
|
||||
);
|
||||
lib_plankton.rest_caldav.register<type_input, type_output>(
|
||||
lib_plankton.rest_http.register<type_input, type_output>(
|
||||
rest_subject,
|
||||
http_method,
|
||||
(_zeitbild.conf.get().server.path_base + path),
|
||||
|
|
@ -195,7 +214,7 @@ namespace _zeitbild.api
|
|||
?
|
||||
undefined
|
||||
:
|
||||
(version) => (options.restriction as lib_plankton.rest_caldav.type_restriction<type_input>)
|
||||
(version) => (options.restriction as lib_plankton.rest_http.type_restriction<type_input>)
|
||||
),
|
||||
/**
|
||||
* @todo heed version
|
||||
|
|
@ -205,7 +224,7 @@ namespace _zeitbild.api
|
|||
?
|
||||
undefined
|
||||
:
|
||||
(version) => (options.execution as lib_plankton.rest_caldav.type_execution<type_input, type_output>)
|
||||
(version) => (options.execution as lib_plankton.rest_http.type_execution<type_input, type_output>)
|
||||
),
|
||||
/**
|
||||
* @todo heed version
|
||||
|
|
|
|||
|
|
@ -5,9 +5,9 @@ namespace _zeitbild.api
|
|||
/**
|
||||
*/
|
||||
export function make(
|
||||
) : lib_plankton.rest_caldav.type_rest
|
||||
) : lib_plankton.rest_http.type_rest
|
||||
{
|
||||
const rest_subject : lib_plankton.rest_caldav.type_rest = lib_plankton.rest_caldav.make(
|
||||
const rest_subject : lib_plankton.rest_http.type_rest = lib_plankton.rest_http.make(
|
||||
{
|
||||
"title": "zeitbild",
|
||||
"versioning_method": "header",
|
||||
|
|
@ -48,16 +48,7 @@ namespace _zeitbild.api
|
|||
}
|
||||
// export
|
||||
{
|
||||
_zeitbild.api.register_export_ical(rest_subject);
|
||||
}
|
||||
// caldav
|
||||
{
|
||||
_zeitbild.api.register_caldav_sniff(rest_subject);
|
||||
_zeitbild.api.register_caldav_put(rest_subject);
|
||||
_zeitbild.api.register_caldav_probe(rest_subject);
|
||||
_zeitbild.api.register_caldav_probe_via_well_known(rest_subject);
|
||||
_zeitbild.api.register_caldav_projects(rest_subject);
|
||||
_zeitbild.api.register_caldav_get(rest_subject);
|
||||
_zeitbild.api.register_export_ics(rest_subject);
|
||||
}
|
||||
// misc
|
||||
{
|
||||
|
|
@ -65,7 +56,6 @@ namespace _zeitbild.api
|
|||
_zeitbild.api.register_events(rest_subject);
|
||||
}
|
||||
|
||||
|
||||
return rest_subject;
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -8,7 +8,7 @@ namespace _zeitbild.api
|
|||
options : {
|
||||
nullable ?: boolean;
|
||||
} = {}
|
||||
) : lib_plankton.rest_caldav.type_oas_schema
|
||||
) : lib_plankton.rest_http.type_oas_schema
|
||||
{
|
||||
options = Object.assign(
|
||||
{
|
||||
|
|
@ -49,7 +49,7 @@ namespace _zeitbild.api
|
|||
options : {
|
||||
nullable ?: boolean;
|
||||
} = {}
|
||||
) : lib_plankton.rest_caldav.type_oas_schema
|
||||
) : lib_plankton.rest_http.type_oas_schema
|
||||
{
|
||||
options = Object.assign(
|
||||
{
|
||||
|
|
@ -90,7 +90,7 @@ namespace _zeitbild.api
|
|||
options : {
|
||||
nullable ?: boolean;
|
||||
} = {}
|
||||
) : lib_plankton.rest_caldav.type_oas_schema
|
||||
) : lib_plankton.rest_http.type_oas_schema
|
||||
{
|
||||
options = Object.assign(
|
||||
{
|
||||
|
|
|
|||
|
|
@ -3,6 +3,16 @@ namespace _zeitbild
|
|||
|
||||
/**
|
||||
*/
|
||||
export var cache : lib_plankton.cache.type_cache<any>;
|
||||
export var cache_regular : lib_plankton.cache.type_subject<any>;
|
||||
|
||||
|
||||
/**
|
||||
*/
|
||||
export var cache_external_resources : lib_plankton.cache.type_subject<any>;
|
||||
|
||||
|
||||
/**
|
||||
*/
|
||||
export var cache_templates : lib_plankton.cache.type_subject<string>;
|
||||
|
||||
}
|
||||
|
|
|
|||
|
|
@ -283,6 +283,22 @@ namespace _zeitbild.conf
|
|||
}
|
||||
}
|
||||
},
|
||||
"external_resources": {
|
||||
"nullable": false,
|
||||
"type": "object",
|
||||
"properties": {
|
||||
"lifetime": {
|
||||
"nullable": false,
|
||||
"type": "integer",
|
||||
"default": 14400
|
||||
}
|
||||
},
|
||||
"additionalProperties": false,
|
||||
"required": [
|
||||
],
|
||||
"default": {
|
||||
}
|
||||
},
|
||||
"misc": {
|
||||
"nullable": false,
|
||||
"type": "object",
|
||||
|
|
@ -300,7 +316,7 @@ namespace _zeitbild.conf
|
|||
],
|
||||
"additionalProperties": false,
|
||||
"default": {}
|
||||
}
|
||||
},
|
||||
},
|
||||
"required": [
|
||||
"version"
|
||||
|
|
|
|||
|
|
@ -7,7 +7,7 @@ namespace _zeitbild.helpers
|
|||
/**
|
||||
* @todo timezone
|
||||
*/
|
||||
function ical_datetime_to_own_datetime(
|
||||
function icalendar_datetime_to_own_datetime(
|
||||
ical_datetime : lib_plankton.ical.type_datetime
|
||||
) : lib_plankton.pit.type_datetime
|
||||
{
|
||||
|
|
@ -36,7 +36,7 @@ namespace _zeitbild.helpers
|
|||
/**
|
||||
* @todo timezone
|
||||
*/
|
||||
export function ical_dt_to_own_datetime(
|
||||
export function icalendar_dt_to_own_datetime(
|
||||
ical_dt: lib_plankton.ical.type_dt
|
||||
) : lib_plankton.pit.type_datetime
|
||||
{
|
||||
|
|
@ -61,7 +61,7 @@ namespace _zeitbild.helpers
|
|||
/**
|
||||
* @todo timezone
|
||||
*/
|
||||
export function ical_dt_from_own_datetime(
|
||||
export function icalendar_dt_from_own_datetime(
|
||||
datetime : lib_plankton.pit.type_datetime
|
||||
) : lib_plankton.ical.type_dt
|
||||
{
|
||||
|
|
@ -92,26 +92,47 @@ namespace _zeitbild.helpers
|
|||
|
||||
/**
|
||||
*/
|
||||
export function ical_vevent_from_own_event(
|
||||
event_object : _zeitbild.type_event_object,
|
||||
uid : string
|
||||
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": uid,
|
||||
"dtstamp": ical_dt_from_own_datetime(event_object.begin).value,
|
||||
"dtstart": ical_dt_from_own_datetime(event_object.begin),
|
||||
"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_object.end === null)
|
||||
(event_extended.event_object.end === null)
|
||||
?
|
||||
undefined
|
||||
:
|
||||
ical_dt_from_own_datetime(event_object.end)
|
||||
icalendar_dt_from_own_datetime(event_extended.event_object.end)
|
||||
),
|
||||
"location": (event_object.location ?? undefined),
|
||||
"summary": event_object.name,
|
||||
"url": (event_object.link ?? undefined),
|
||||
"description": (event_object.description ?? undefined),
|
||||
"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],
|
||||
};
|
||||
}
|
||||
|
||||
|
|
@ -119,8 +140,8 @@ namespace _zeitbild.helpers
|
|||
/**
|
||||
* @todo assign better uids
|
||||
*/
|
||||
export function ical_vcalendar_from_own_event_list(
|
||||
events : Array<_zeitbild.type_event_object>
|
||||
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();
|
||||
|
|
@ -137,18 +158,15 @@ namespace _zeitbild.helpers
|
|||
"version": "2.0",
|
||||
"prodid": "",
|
||||
"vevents": (
|
||||
events
|
||||
events_extended
|
||||
.map<lib_plankton.ical.type_vevent>(
|
||||
(entry, index) => ical_vevent_from_own_event(
|
||||
entry,
|
||||
lib_plankton.string.coin(
|
||||
"zeitbild_{{stamp}}_{{index}}",
|
||||
{
|
||||
"stamp": stamp,
|
||||
"index": index.toFixed(0)
|
||||
}
|
||||
)
|
||||
),
|
||||
(event_extended, index) => icalendar_vevent_from_own_event(
|
||||
event_extended,
|
||||
index,
|
||||
{
|
||||
"stamp": stamp,
|
||||
}
|
||||
)
|
||||
)
|
||||
),
|
||||
"method": "PUBLISH",
|
||||
|
|
@ -161,37 +179,29 @@ namespace _zeitbild.helpers
|
|||
|
||||
/**
|
||||
*/
|
||||
var _template_cache : Record<string, string> = {};
|
||||
|
||||
|
||||
/**
|
||||
* @todo caching
|
||||
*/
|
||||
export async function template_coin(
|
||||
name : string,
|
||||
data : Record<string, string>
|
||||
) : Promise<string>
|
||||
{
|
||||
let content : string;
|
||||
if (! (name in _template_cache)) {
|
||||
content = (
|
||||
(
|
||||
await lib_plankton.file.read(
|
||||
lib_plankton.string.coin(
|
||||
"templates/{{name}}.html.tpl",
|
||||
{
|
||||
"name": name,
|
||||
}
|
||||
)
|
||||
const content : string = await lib_plankton.cache.get<string>(
|
||||
_zeitbild.cache_templates,
|
||||
name,
|
||||
null,
|
||||
() => (
|
||||
lib_plankton.file.read(
|
||||
lib_plankton.string.coin(
|
||||
"templates/{{name}}.html.tpl",
|
||||
{
|
||||
"name": name,
|
||||
}
|
||||
)
|
||||
)
|
||||
.toString()
|
||||
);
|
||||
_template_cache[name] = content;
|
||||
}
|
||||
else {
|
||||
content = _template_cache[name];
|
||||
}
|
||||
.then(
|
||||
x => Promise.resolve<string>(x.toString())
|
||||
)
|
||||
)
|
||||
);
|
||||
return Promise.resolve<string>(
|
||||
lib_plankton.string.coin(
|
||||
content,
|
||||
|
|
|
|||
|
|
@ -8,6 +8,7 @@ type type_data = {
|
|||
id : int;
|
||||
name : string;
|
||||
email_address : string;
|
||||
dav_token : (null | string);
|
||||
password : string;
|
||||
}
|
||||
>;
|
||||
|
|
@ -36,10 +37,9 @@ type type_data = {
|
|||
}
|
||||
|
|
||||
{
|
||||
kind : "caldav";
|
||||
kind : "ics_feed";
|
||||
data : {
|
||||
url : string;
|
||||
read_only : boolean;
|
||||
from_fucked_up_wordpress ?: boolean;
|
||||
};
|
||||
}
|
||||
|
|
@ -68,10 +68,12 @@ async function data_init(
|
|||
"user": {},
|
||||
"calendar": {},
|
||||
};
|
||||
for await (const user_raw of data.users) {
|
||||
for await (const user_raw of data.users)
|
||||
{
|
||||
const user_object : _zeitbild.type_user_object = {
|
||||
"name": user_raw.name,
|
||||
"email_address": user_raw.email_address,
|
||||
"dav_token": user_raw.dav_token,
|
||||
};
|
||||
const user_id : _zeitbild.type_user_id = await _zeitbild.service.user.add(
|
||||
user_object
|
||||
|
|
@ -82,11 +84,14 @@ async function data_init(
|
|||
);
|
||||
track.user[user_raw.id] = user_id;
|
||||
}
|
||||
for await (const calendar_raw of data.calendars) {
|
||||
for await (const calendar_raw of data.calendars)
|
||||
{
|
||||
let resource_object : _zeitbild.type_resource_object;
|
||||
let resource_id : _zeitbild.type_resource_id;
|
||||
switch (calendar_raw.resource.kind) {
|
||||
case "local": {
|
||||
switch (calendar_raw.resource.kind)
|
||||
{
|
||||
case "local":
|
||||
{
|
||||
resource_object = {
|
||||
"kind": "local",
|
||||
"data": {
|
||||
|
|
@ -104,12 +109,12 @@ async function data_init(
|
|||
);
|
||||
break;
|
||||
}
|
||||
case "caldav": {
|
||||
case "ics_feed":
|
||||
{
|
||||
resource_object = {
|
||||
"kind": "caldav",
|
||||
"kind": "ics_feed",
|
||||
"data": {
|
||||
"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),
|
||||
}
|
||||
};
|
||||
|
|
@ -119,7 +124,8 @@ async function data_init(
|
|||
break;
|
||||
}
|
||||
}
|
||||
const calendar_object : _zeitbild.type_calendar_object = {
|
||||
const calendar_object : _zeitbild.type_calendar_object =
|
||||
{
|
||||
"name": calendar_raw.name,
|
||||
"access": {
|
||||
"public": (calendar_raw.access.public ?? false),
|
||||
|
|
@ -313,14 +319,18 @@ async function main(
|
|||
}
|
||||
)
|
||||
);
|
||||
_zeitbild.cache = lib_plankton.cache.chest.implementation<any>(
|
||||
lib_plankton.cache.chest.make<any>(
|
||||
{
|
||||
"chest": lib_plankton.storage.memory.implementation_chest<any>({}),
|
||||
}
|
||||
)
|
||||
);
|
||||
await _zeitbild.cache.init();
|
||||
{
|
||||
_zeitbild.cache_regular = lib_plankton.cache.make<any>();
|
||||
await lib_plankton.cache.init(_zeitbild.cache_regular);
|
||||
}
|
||||
{
|
||||
_zeitbild.cache_external_resources = lib_plankton.cache.make<any>();
|
||||
await lib_plankton.cache.init(_zeitbild.cache_external_resources);
|
||||
}
|
||||
{
|
||||
_zeitbild.cache_templates = lib_plankton.cache.make<any>();
|
||||
await lib_plankton.cache.init(_zeitbild.cache_templates);
|
||||
}
|
||||
|
||||
// exec
|
||||
if (args["help"]) {
|
||||
|
|
@ -373,10 +383,10 @@ async function main(
|
|||
}
|
||||
case "api-doc": {
|
||||
lib_plankton.log.set_main_logger([]);
|
||||
const rest_subject : lib_plankton.rest_caldav.type_rest = _zeitbild.api.make();
|
||||
const rest_subject : lib_plankton.rest_http.type_rest = _zeitbild.api.make();
|
||||
process.stdout.write(
|
||||
JSON.stringify(
|
||||
lib_plankton.rest_caldav.to_oas(rest_subject),
|
||||
lib_plankton.rest_http.to_oas(rest_subject),
|
||||
undefined,
|
||||
"\t"
|
||||
)
|
||||
|
|
@ -428,11 +438,11 @@ async function main(
|
|||
|
||||
await _zeitbild.auth.init();
|
||||
|
||||
const rest_subject : lib_plankton.rest_caldav.type_rest = _zeitbild.api.make();
|
||||
const rest_subject : lib_plankton.rest_http.type_rest = _zeitbild.api.make();
|
||||
const server : lib_plankton.server.type_subject = lib_plankton.server.make(
|
||||
async (input, metadata) => {
|
||||
const http_request : lib_plankton.caldav.type_request = lib_plankton.caldav.decode_request(input.toString());
|
||||
const http_response : lib_plankton.caldav.type_response = await lib_plankton.rest_caldav.call(
|
||||
const http_request : lib_plankton.http.type_request = lib_plankton.http.decode_request(input.toString());
|
||||
const http_response : lib_plankton.http.type_response = await lib_plankton.rest_http.call(
|
||||
rest_subject,
|
||||
http_request,
|
||||
{
|
||||
|
|
@ -442,7 +452,7 @@ async function main(
|
|||
"set_content_length": false,
|
||||
}
|
||||
);
|
||||
const output : string = lib_plankton.caldav.encode_response(http_response);
|
||||
const output : string = lib_plankton.http.encode_response(http_response);
|
||||
return output;
|
||||
},
|
||||
{
|
||||
|
|
|
|||
|
|
@ -251,7 +251,7 @@ namespace _zeitbild.repository.calendar
|
|||
{"level": access_attributed_row["level"]}
|
||||
);
|
||||
}
|
||||
await _zeitbild.cache.clear();
|
||||
await lib_plankton.cache.clear(_zeitbild.cache_regular);
|
||||
return Promise.resolve<_zeitbild.type_calendar_id>(calendar_id);
|
||||
}
|
||||
|
||||
|
|
@ -313,7 +313,7 @@ namespace _zeitbild.repository.calendar
|
|||
);
|
||||
}
|
||||
}
|
||||
await _zeitbild.cache.clear();
|
||||
await lib_plankton.cache.clear(_zeitbild.cache_regular);
|
||||
return Promise.resolve<void>(undefined);
|
||||
}
|
||||
|
||||
|
|
@ -325,7 +325,7 @@ namespace _zeitbild.repository.calendar
|
|||
calendar_id : _zeitbild.type_calendar_id
|
||||
) : Promise<void>
|
||||
{
|
||||
await _zeitbild.cache.clear();
|
||||
await lib_plankton.cache.clear(_zeitbild.cache_regular);
|
||||
const core_store = get_core_store();
|
||||
const access_attributed_chest = get_access_attributed_chest();
|
||||
// attributed access
|
||||
|
|
@ -375,11 +375,12 @@ namespace _zeitbild.repository.calendar
|
|||
>
|
||||
{
|
||||
return lib_plankton.cache.get_complex<any, Array<type_overview_entry>>(
|
||||
_zeitbild.cache,
|
||||
_zeitbild.cache_regular,
|
||||
"calendar_overview",
|
||||
{
|
||||
"user_id": user_id,
|
||||
},
|
||||
null,
|
||||
() => (
|
||||
lib_plankton.file.read("sql/calendar_overview.sql")
|
||||
.then(
|
||||
|
|
|
|||
|
|
@ -42,7 +42,7 @@ namespace _zeitbild.repository.resource
|
|||
|
||||
/**
|
||||
*/
|
||||
var _caldav_resource_store : (
|
||||
var _ics_feed_resource_store : (
|
||||
null
|
||||
|
|
||||
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<
|
||||
int,
|
||||
Record<string, any>,
|
||||
|
|
@ -135,11 +135,11 @@ namespace _zeitbild.repository.resource
|
|||
Record<string, any>
|
||||
>
|
||||
{
|
||||
if (_caldav_resource_store === null) {
|
||||
_caldav_resource_store = lib_plankton.storage.sql_table_autokey_store(
|
||||
if (_ics_feed_resource_store === null) {
|
||||
_ics_feed_resource_store = lib_plankton.storage.sql_table_autokey_store(
|
||||
{
|
||||
"database_implementation": _zeitbild.database.get_implementation(),
|
||||
"table_name": "caldav_resources",
|
||||
"table_name": "ics_feed_resources",
|
||||
"key_name": "id",
|
||||
}
|
||||
);
|
||||
|
|
@ -147,7 +147,7 @@ namespace _zeitbild.repository.resource
|
|||
else {
|
||||
// do nothing
|
||||
}
|
||||
return _caldav_resource_store;
|
||||
return _ics_feed_resource_store;
|
||||
}
|
||||
|
||||
|
||||
|
|
@ -358,15 +358,14 @@ namespace _zeitbild.repository.resource
|
|||
}
|
||||
);
|
||||
}
|
||||
case "caldav": {
|
||||
const dataset_extra_caldav : Record<string, any> = await get_caldav_resource_store().read(dataset_core.sub_id);
|
||||
case "ics_feed": {
|
||||
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>(
|
||||
{
|
||||
"kind": "caldav",
|
||||
"kind": "ics_feed",
|
||||
"data": {
|
||||
"url": dataset_extra_caldav["url"],
|
||||
"read_only": dataset_extra_caldav["read_only"],
|
||||
"from_fucked_up_wordpress": dataset_extra_caldav["from_fucked_up_wordpress"],
|
||||
"url": dataset_extra_ics_feed["url"],
|
||||
"from_fucked_up_wordpress": dataset_extra_ics_feed["from_fucked_up_wordpress"],
|
||||
}
|
||||
}
|
||||
);
|
||||
|
|
@ -401,25 +400,24 @@ namespace _zeitbild.repository.resource
|
|||
"sub_id": local_resource_id,
|
||||
}
|
||||
);
|
||||
await _zeitbild.cache.clear();
|
||||
await lib_plankton.cache.clear(_zeitbild.cache_regular);
|
||||
return Promise.resolve<_zeitbild.type_resource_id>(resource_id);
|
||||
break;
|
||||
}
|
||||
case "caldav": {
|
||||
const caldav_resource_id : int = await get_caldav_resource_store().create(
|
||||
case "ics_feed": {
|
||||
const ics_feed_resource_id : int = await get_ics_feed_resource_store().create(
|
||||
{
|
||||
"url": resource_object.data.url,
|
||||
"read_only": resource_object.data.read_only,
|
||||
"from_fucked_up_wordpress": resource_object.data.from_fucked_up_wordpress,
|
||||
}
|
||||
);
|
||||
const resource_id : _zeitbild.type_resource_id = await get_resource_core_store().create(
|
||||
{
|
||||
"kind": "caldav",
|
||||
"sub_id": caldav_resource_id,
|
||||
"kind": "ics_feed",
|
||||
"sub_id": ics_feed_resource_id,
|
||||
}
|
||||
);
|
||||
await _zeitbild.cache.clear();
|
||||
await lib_plankton.cache.clear(_zeitbild.cache_regular);
|
||||
return Promise.resolve<_zeitbild.type_resource_id>(resource_id);
|
||||
break;
|
||||
}
|
||||
|
|
@ -491,15 +489,15 @@ namespace _zeitbild.repository.resource
|
|||
*/
|
||||
break;
|
||||
}
|
||||
case "caldav": {
|
||||
await get_caldav_resource_store().update(
|
||||
case "ics_feed": {
|
||||
await get_ics_feed_resource_store().update(
|
||||
dataset_core["sub_id"],
|
||||
{
|
||||
"url": resource_object.data.url,
|
||||
"read_only": resource_object.data.read_only,
|
||||
"from_fucked_up_wordpress": resource_object.data.from_fucked_up_wordpress,
|
||||
}
|
||||
);
|
||||
await _zeitbild.cache.clear();
|
||||
await lib_plankton.cache.clear(_zeitbild.cache_regular);
|
||||
break;
|
||||
}
|
||||
default: {
|
||||
|
|
@ -561,7 +559,7 @@ namespace _zeitbild.repository.resource
|
|||
}
|
||||
)
|
||||
);
|
||||
await _zeitbild.cache.clear();
|
||||
await lib_plankton.cache.clear(_zeitbild.cache_regular);
|
||||
return Promise.resolve(local_resource_event_id);
|
||||
}
|
||||
}
|
||||
|
|
@ -589,7 +587,7 @@ namespace _zeitbild.repository.resource
|
|||
}
|
||||
)
|
||||
);
|
||||
await _zeitbild.cache.clear();
|
||||
await lib_plankton.cache.clear(_zeitbild.cache_regular);
|
||||
return Promise.resolve<void>(undefined);
|
||||
}
|
||||
}
|
||||
|
|
@ -602,7 +600,7 @@ namespace _zeitbild.repository.resource
|
|||
local_resource_event_id : _zeitbild.type_local_resource_event_id
|
||||
) : Promise<void>
|
||||
{
|
||||
await _zeitbild.cache.clear();
|
||||
await lib_plankton.cache.clear(_zeitbild.cache_regular);
|
||||
const dataset_core : Record<string, any> = await get_resource_core_store().read(resource_id);
|
||||
if (! (dataset_core.kind === "local")) {
|
||||
throw (new Error("not a local resource"));
|
||||
|
|
|
|||
|
|
@ -53,6 +53,7 @@ namespace _zeitbild.repository.user
|
|||
return {
|
||||
"name": user_object.name,
|
||||
"email_address": user_object.email_address,
|
||||
"dav_token": user_object.dav_token,
|
||||
};
|
||||
}
|
||||
|
||||
|
|
@ -66,6 +67,7 @@ namespace _zeitbild.repository.user
|
|||
return {
|
||||
"name": row["name"],
|
||||
"email_address": row["email_address"],
|
||||
"dav_token": row["dav_token"],
|
||||
};
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -1,5 +0,0 @@
|
|||
|
||||
namespace _zeitbild.service.caldav
|
||||
{
|
||||
|
||||
}
|
||||
|
|
@ -1,508 +0,0 @@
|
|||
|
||||
namespace _zeitbild.service.caldav
|
||||
{
|
||||
|
||||
/**
|
||||
*/
|
||||
function get_answers(
|
||||
) : Record<
|
||||
string,
|
||||
(stuff : any) => lib_plankton.webdav.type_data_prop_value
|
||||
>
|
||||
{
|
||||
return {
|
||||
// RFC2518
|
||||
|
||||
/**
|
||||
* @see https://datatracker.ietf.org/doc/html/rfc2518#section-13.2
|
||||
*/
|
||||
"displayname": (stuff) => ({
|
||||
"kind": "primitive",
|
||||
"data": stuff["name"]
|
||||
}),
|
||||
/**
|
||||
* @see https://datatracker.ietf.org/doc/html/rfc2518#section-13.4
|
||||
*/
|
||||
/*
|
||||
"getcontentlength": {
|
||||
"kind": "none",
|
||||
"data": null
|
||||
},
|
||||
*/
|
||||
/**
|
||||
* @see https://datatracker.ietf.org/doc/html/rfc2518#section-13.5
|
||||
*/
|
||||
"getcontenttype": (stuff) => ({
|
||||
"kind": "primitive",
|
||||
"data": stuff["content_type"]
|
||||
}),
|
||||
/**
|
||||
* @see https://datatracker.ietf.org/doc/html/rfc2518#section-13.7
|
||||
*/
|
||||
/*
|
||||
"getlastmodified": {
|
||||
"kind": "none",
|
||||
"data": null
|
||||
},
|
||||
*/
|
||||
/**
|
||||
* @see https://datatracker.ietf.org/doc/html/rfc2518#section-13.9
|
||||
*/
|
||||
"resourcetype": (stuff) => ({
|
||||
"kind": "resourcetype",
|
||||
"data": {
|
||||
"kind": "collection",
|
||||
"type": "calendar",
|
||||
}
|
||||
}),
|
||||
|
||||
// RFCP3744
|
||||
|
||||
/**
|
||||
* @see https://datatracker.ietf.org/doc/html/rfc3744#section-4.2
|
||||
*/
|
||||
"principal-url": (stuff) => ({
|
||||
"kind": "href",
|
||||
"data": "/caldav"
|
||||
}),
|
||||
/**
|
||||
* @see https://datatracker.ietf.org/doc/html/rfc3744#section-5.1
|
||||
*/
|
||||
"owner": (stuff) => ({
|
||||
"kind": "primitive",
|
||||
"data": ""
|
||||
}),
|
||||
/**
|
||||
* @see https://datatracker.ietf.org/doc/html/rfc3744#section-5.4
|
||||
*/
|
||||
"current-user-privilege-set": (stuff) => ({
|
||||
"kind": "privileges",
|
||||
"data": [
|
||||
"read"
|
||||
]
|
||||
}),
|
||||
|
||||
// RFC4791
|
||||
|
||||
/**
|
||||
* @see https://datatracker.ietf.org/doc/html/rfc4791#section-5.2.3
|
||||
*/
|
||||
"supported-calendar-component-set": (stuff) => ({
|
||||
"kind": "component_set",
|
||||
"data": {
|
||||
"name": "C:supported-calendar-component-set",
|
||||
"items": [
|
||||
"VCALENDAR"
|
||||
]
|
||||
}
|
||||
}),
|
||||
/**
|
||||
* @see https://datatracker.ietf.org/doc/html/rfc4791#section-6.2.1
|
||||
*/
|
||||
"calendar-home-set": (stuff) => ({
|
||||
"kind": "href",
|
||||
"data": "/caldav/project"
|
||||
}),
|
||||
|
||||
// RFC4918
|
||||
|
||||
/**
|
||||
* @see https://datatracker.ietf.org/doc/html/rfc4918#section-15.6
|
||||
*/
|
||||
"getetag": (stuff) => ({
|
||||
"kind": "primitive",
|
||||
"data": ""
|
||||
}),
|
||||
|
||||
// RFC5397
|
||||
|
||||
/**
|
||||
* @see https://datatracker.ietf.org/doc/html/rfc5397#section-3
|
||||
*/
|
||||
"current-user-principal": (stuff) => ({
|
||||
"kind": "href",
|
||||
"data": "/caldav"
|
||||
}),
|
||||
|
||||
// RFC6638
|
||||
|
||||
/**
|
||||
* @see https://datatracker.ietf.org/doc/html/rfc6638#section-2.4.1
|
||||
*/
|
||||
"calendar-user-address-set": (stuff) => ({
|
||||
"kind": "primitive",
|
||||
"data": ""
|
||||
}),
|
||||
|
||||
// unknown
|
||||
|
||||
/*
|
||||
"calendar-color": {
|
||||
"kind": "none",
|
||||
"data": null
|
||||
},
|
||||
"executable": {
|
||||
"kind": "none",
|
||||
"data": null
|
||||
},
|
||||
"checked-in": {
|
||||
"kind": "none",
|
||||
"data": null
|
||||
},
|
||||
"checked-out": {
|
||||
"kind": "none",
|
||||
"data": null
|
||||
},
|
||||
*/
|
||||
};
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* @todo use pod for output
|
||||
* @todo get api paths in props from config
|
||||
* @todo consider to outsorce to plankton
|
||||
*/
|
||||
export function probe(
|
||||
input : (null | lib_plankton.xml.type_node_data),
|
||||
{
|
||||
"force_props": force_props = null,
|
||||
} : {
|
||||
force_props ?: (null | Array<string>);
|
||||
} = {
|
||||
}
|
||||
) : (null | lib_plankton.xml.type_node_data)
|
||||
{
|
||||
const http_protocol : string = "HTTP/1.1";
|
||||
let props : (null | Array<string>);
|
||||
if (force_props) {
|
||||
props = force_props;
|
||||
}
|
||||
else {
|
||||
if (
|
||||
(input !== null)
|
||||
&&
|
||||
(input.kind === "complex")
|
||||
&&
|
||||
(
|
||||
(input.data.tag.toLowerCase() === "d:propfind")
|
||||
||
|
||||
(input.data.tag.toLowerCase() === "propfind")
|
||||
)
|
||||
&&
|
||||
(input.data.children.length === 1)
|
||||
&&
|
||||
(input.data.children[0].kind === "complex")
|
||||
&&
|
||||
(
|
||||
(input.data.children[0].data.tag.toLowerCase() === "d:prop")
|
||||
||
|
||||
(input.data.children[0].data.tag.toLowerCase() === "prop")
|
||||
)
|
||||
) {
|
||||
props = input.data.children[0].data.children.map(
|
||||
node => {
|
||||
switch (node.kind) {
|
||||
case "complex": {
|
||||
return node.data.tag;
|
||||
break;
|
||||
}
|
||||
default: {
|
||||
throw (new Error("unexpected node type for prop"));
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
);
|
||||
props.sort();
|
||||
}
|
||||
else {
|
||||
props = null;
|
||||
}
|
||||
}
|
||||
if (props === null) {
|
||||
lib_plankton.log.notice(
|
||||
"service.caldav.probe.unexpected_input",
|
||||
{
|
||||
"input": input,
|
||||
}
|
||||
);
|
||||
return null;
|
||||
}
|
||||
else {
|
||||
const answers : Record<
|
||||
string,
|
||||
(stuff : any) => lib_plankton.webdav.type_data_prop_value
|
||||
> = get_answers();
|
||||
return {
|
||||
"kind": "root",
|
||||
"data": {
|
||||
"version": "1.0",
|
||||
"encoding": "utf-8",
|
||||
"content": lib_plankton.webdav.data_multistatus_encode_xml(
|
||||
{
|
||||
"responses": [
|
||||
{
|
||||
"href": "/caldav/project",
|
||||
"body": {
|
||||
/**
|
||||
* @todo maybe propstats needs to be filled with props (.map …)
|
||||
*/
|
||||
"propstats": (
|
||||
false
|
||||
?
|
||||
[
|
||||
{
|
||||
"prop": (props ?? []).map(
|
||||
(prop) => {
|
||||
const prop_parts : Array<string> = prop.toLowerCase().split(":");
|
||||
const prop_normalized : string = ((prop_parts.length <= 1) ? prop_parts[0] : prop_parts.slice(1).join(":"));
|
||||
if (! (prop_normalized in answers)) {
|
||||
lib_plankton.log.error(
|
||||
"api.caldav_probe.unhandled_prop",
|
||||
prop_normalized
|
||||
);
|
||||
throw (new Error("unhandled prop: " + prop_normalized));
|
||||
}
|
||||
else {
|
||||
return {
|
||||
"name": prop,
|
||||
"value": (
|
||||
answers[prop_normalized]({"name": "projects", "content_type": "text/xml"})
|
||||
??
|
||||
{
|
||||
"kind": "none",
|
||||
"data": null,
|
||||
}
|
||||
),
|
||||
};
|
||||
}
|
||||
}
|
||||
),
|
||||
"status": (http_protocol + " 200 OK"),
|
||||
"description": null,
|
||||
},
|
||||
]
|
||||
:
|
||||
props.map(
|
||||
(prop) => {
|
||||
const prop_parts : Array<string> = prop.toLowerCase().split(":");
|
||||
const prop_normalized : string = (
|
||||
(prop_parts.length <= 1)
|
||||
?
|
||||
prop_parts[0]
|
||||
:
|
||||
prop_parts.slice(1).join(":")
|
||||
);
|
||||
if (! (prop_normalized in answers)) {
|
||||
lib_plankton.log.notice(
|
||||
"api.caldav_probe.unhandled_prop",
|
||||
prop_normalized
|
||||
);
|
||||
/*
|
||||
throw (new Error("unhandled prop: " + prop_normalized));
|
||||
*/
|
||||
return {
|
||||
"prop": [
|
||||
{
|
||||
"name": prop,
|
||||
"value": {
|
||||
"kind": "none",
|
||||
"data": null,
|
||||
}
|
||||
},
|
||||
],
|
||||
"status": (http_protocol + " 404 Not Found"),
|
||||
"description": null,
|
||||
};
|
||||
}
|
||||
else {
|
||||
return {
|
||||
"prop": [
|
||||
{
|
||||
"name": prop,
|
||||
"value": answers[prop_normalized]({"name": "projects", "content_type": "text/xml"}),
|
||||
},
|
||||
],
|
||||
"status": (http_protocol + " 200 OK"),
|
||||
"description": null,
|
||||
};
|
||||
};
|
||||
}
|
||||
)
|
||||
)
|
||||
},
|
||||
"description": null,
|
||||
}
|
||||
],
|
||||
"description": null,
|
||||
}
|
||||
)
|
||||
}
|
||||
};
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* @todo heed input properly
|
||||
*/
|
||||
export function projects(
|
||||
input : lib_plankton.xml.type_node_data,
|
||||
user_id : type_user_id
|
||||
) : Promise<lib_plankton.xml.type_node_data>
|
||||
{
|
||||
const answers : Record<
|
||||
string,
|
||||
(stuff : any) => lib_plankton.webdav.type_data_prop_value
|
||||
> = get_answers();
|
||||
/**
|
||||
* @todo remove
|
||||
*/
|
||||
lib_plankton.log.info(
|
||||
"service.caldav.input",
|
||||
input
|
||||
);
|
||||
/**
|
||||
* @todo check data structure
|
||||
*/
|
||||
if (
|
||||
! (
|
||||
(input.kind === "complex")
|
||||
&&
|
||||
(input.data.tag === "propfind")
|
||||
&&
|
||||
(input.data.children.length === 1)
|
||||
&&
|
||||
(input.data.children[0].kind === "complex")
|
||||
&&
|
||||
(input.data.children[0].data.tag === "prop")
|
||||
&&
|
||||
input.data.children[0].data.children.every(
|
||||
node => (node.kind === "complex")
|
||||
)
|
||||
)
|
||||
) {
|
||||
throw (new Error("wrong input structure"));
|
||||
}
|
||||
else {
|
||||
const props : Array<string> = (
|
||||
input
|
||||
.data.children
|
||||
[0]
|
||||
.data.children
|
||||
.map(
|
||||
(node) => node.data.tag
|
||||
)
|
||||
);
|
||||
/**
|
||||
* @todo remove
|
||||
*/
|
||||
lib_plankton.log.info(
|
||||
"service.caldav.props",
|
||||
props
|
||||
);
|
||||
return (
|
||||
_zeitbild.service.calendar.overview(user_id)
|
||||
.then(
|
||||
(data_raw) => Promise.resolve(
|
||||
data_raw
|
||||
.map(
|
||||
(entry) => ({
|
||||
"id": entry.id,
|
||||
"name": entry.name,
|
||||
"access_level": _zeitbild.value_object.access_level.to_string(entry.access_level),
|
||||
})
|
||||
)
|
||||
)
|
||||
)
|
||||
.then(
|
||||
(data) => Promise.resolve(
|
||||
{
|
||||
"kind": "root",
|
||||
"data": {
|
||||
"version": "1.0",
|
||||
"encoding": "utf-8",
|
||||
"content": lib_plankton.webdav.data_multistatus_encode_xml(
|
||||
{
|
||||
"responses": data.map(
|
||||
(entry) => ({
|
||||
"href": lib_plankton.string.coin(
|
||||
"/caldav/project/{{id}}",
|
||||
{
|
||||
"id": entry.id.toFixed(0),
|
||||
}
|
||||
),
|
||||
"body": {
|
||||
"propstats": (
|
||||
lib_plankton.call.wrap<Array<string>>(props)
|
||||
.convey<Array<{found : boolean; prop : lib_plankton.webdav.type_data_prop;}>>(
|
||||
(props_raw) => props_raw.map(
|
||||
(prop_raw) => {
|
||||
const prop_parts : Array<string> = prop_raw.toLowerCase().split(":");
|
||||
const prop_normalized : string = ((prop_parts.length <= 1) ? prop_parts[0] : prop_parts.slice(1).join(":"));
|
||||
return (
|
||||
(prop_normalized in answers)
|
||||
?
|
||||
{
|
||||
"found": true,
|
||||
"prop": {
|
||||
"name": prop_raw,
|
||||
"value": answers[prop_normalized]({"name": entry.name, "content_type": "text/calendar"}),
|
||||
}
|
||||
}
|
||||
:
|
||||
{
|
||||
"found": false,
|
||||
"prop": {
|
||||
"name": prop_raw,
|
||||
"value": {"kind": "none", "data": null}
|
||||
}
|
||||
}
|
||||
);
|
||||
}
|
||||
)
|
||||
)
|
||||
.convey<Array<Array<{found : boolean; prop : lib_plankton.webdav.type_data_prop;}>>>(
|
||||
(props_transformed) => lib_plankton.list.group(
|
||||
props_transformed,
|
||||
(x, y) => (x.found === y.found)
|
||||
)
|
||||
)
|
||||
.convey<Array<lib_plankton.webdav.type_data_propstat>>(
|
||||
(props_grouped) => props_grouped.map(
|
||||
group => (
|
||||
group[0].found
|
||||
?
|
||||
{
|
||||
"prop": group.map(member => member.prop),
|
||||
"status": "HTTP/1.1 200 OK",
|
||||
"description": null,
|
||||
}
|
||||
:
|
||||
{
|
||||
"prop": group.map(member => member.prop),
|
||||
"status": "HTTP/1.1 404 Not Found",
|
||||
"description": null,
|
||||
}
|
||||
)
|
||||
)
|
||||
)
|
||||
.cull()
|
||||
),
|
||||
},
|
||||
"description": null,
|
||||
})
|
||||
),
|
||||
"description": null,
|
||||
}
|
||||
)
|
||||
}
|
||||
}
|
||||
)
|
||||
)
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
|
@ -327,47 +327,54 @@ namespace _zeitbild.service.calendar
|
|||
);
|
||||
break;
|
||||
}
|
||||
case "caldav": {
|
||||
case "ics_feed": {
|
||||
// TODO readonly
|
||||
const url : lib_plankton.url.type_url = lib_plankton.url.decode(
|
||||
resource_object.data.url
|
||||
);
|
||||
const http_request : lib_plankton.http.type_request = {
|
||||
"version": "HTTP/2",
|
||||
"scheme": ((url.scheme === "https") ? "https" : "http"),
|
||||
"host": url.host,
|
||||
"path": (url.path ?? "/"),
|
||||
"query": url.query,
|
||||
"method": lib_plankton.http.enum_method.get,
|
||||
"headers": {},
|
||||
"body": null,
|
||||
};
|
||||
// TODO: cache?
|
||||
const http_response : lib_plankton.http.type_response = await lib_plankton.http.call(
|
||||
http_request,
|
||||
{
|
||||
const vcalendar : lib_plankton.ical.type_vcalendar = await lib_plankton.cache.get<lib_plankton.ical.type_vcalendar>(
|
||||
_zeitbild.cache_external_resources,
|
||||
resource_object.data.url,
|
||||
_zeitbild.conf.get().external_resources.lifetime,
|
||||
async () => {
|
||||
const url : lib_plankton.url.type_url = lib_plankton.url.decode(
|
||||
resource_object.data.url
|
||||
);
|
||||
const http_request : lib_plankton.http.type_request = {
|
||||
"version": "HTTP/2",
|
||||
"scheme": ((url.scheme === "https") ? "https" : "http"),
|
||||
"host": url.host,
|
||||
"path": (url.path ?? "/"),
|
||||
"query": url.query,
|
||||
"method": lib_plankton.http.enum_method.get,
|
||||
"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 === 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(
|
||||
vcalendar.vevents
|
||||
.map(
|
||||
|
|
@ -382,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": (
|
||||
(vevent.dtend !== undefined)
|
||||
?
|
||||
_zeitbild.helpers.ical_dt_to_own_datetime(vevent.dtend)
|
||||
_zeitbild.helpers.icalendar_dt_to_own_datetime(vevent.dtend)
|
||||
:
|
||||
null
|
||||
),
|
||||
|
|
@ -447,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(
|
||||
|
|
@ -467,7 +461,7 @@ namespace _zeitbild.service.calendar
|
|||
from_pit : lib_plankton.pit.type_pit,
|
||||
to_pit : lib_plankton.pit.type_pit,
|
||||
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> = (
|
||||
(await overview(user_id))
|
||||
|
|
@ -489,8 +483,8 @@ namespace _zeitbild.service.calendar
|
|||
)
|
||||
);
|
||||
calendar_ids.sort();
|
||||
return lib_plankton.cache.get_complex<any, type_gather_events_result>(
|
||||
_zeitbild.cache,
|
||||
return lib_plankton.cache.get_complex<any, Array<_zeitbild.type_event_extended>>(
|
||||
_zeitbild.cache_regular,
|
||||
"gather_events",
|
||||
{
|
||||
"user_id": user_id,
|
||||
|
|
@ -498,6 +492,10 @@ namespace _zeitbild.service.calendar
|
|||
"to_pit": to_pit,
|
||||
"calendar_ids": calendar_ids,
|
||||
},
|
||||
/**
|
||||
* @todo expire?
|
||||
*/
|
||||
null,
|
||||
() => (
|
||||
Promise.all(
|
||||
calendar_ids
|
||||
|
|
|
|||
|
|
@ -31,7 +31,7 @@ namespace _zeitbild.service.resource
|
|||
return Promise.resolve<_zeitbild.type_event_object>(event_object);
|
||||
break;
|
||||
}
|
||||
case "caldav": {
|
||||
case "ics_feed": {
|
||||
// TODO
|
||||
return Promise.reject(new Error("not implemented"));
|
||||
break;
|
||||
|
|
@ -63,14 +63,8 @@ namespace _zeitbild.service.resource
|
|||
return Promise.resolve<_zeitbild.type_local_resource_event_id>(local_resource_event_id);
|
||||
break;
|
||||
}
|
||||
case "caldav": {
|
||||
if (resource_object.data.read_only) {
|
||||
return Promise.reject(new Error("can not add event to read only caldav resource"));
|
||||
}
|
||||
else {
|
||||
// TODO
|
||||
return Promise.reject(new Error("not implemented"));
|
||||
}
|
||||
case "ics_feed": {
|
||||
return Promise.reject(new Error("unavailable"));
|
||||
break;
|
||||
}
|
||||
default: {
|
||||
|
|
@ -102,14 +96,8 @@ namespace _zeitbild.service.resource
|
|||
return Promise.resolve<void>(undefined);
|
||||
break;
|
||||
}
|
||||
case "caldav": {
|
||||
if (resource_object.data.read_only) {
|
||||
return Promise.reject(new Error("can not change event of read only caldav resource"));
|
||||
}
|
||||
else {
|
||||
// TODO
|
||||
return Promise.reject(new Error("not implemented"));
|
||||
}
|
||||
case "ics_feed": {
|
||||
return Promise.reject(new Error("unavailable"));
|
||||
break;
|
||||
}
|
||||
default: {
|
||||
|
|
@ -139,14 +127,8 @@ namespace _zeitbild.service.resource
|
|||
return Promise.resolve<void>(undefined);
|
||||
break;
|
||||
}
|
||||
case "caldav": {
|
||||
if (resource_object.data.read_only) {
|
||||
return Promise.reject(new Error("can not delete event from read only caldav resource"));
|
||||
}
|
||||
else {
|
||||
// TODO
|
||||
return Promise.reject(new Error("not implemented"));
|
||||
}
|
||||
case "ics_feed": {
|
||||
return Promise.reject(new Error("unavailable"));
|
||||
break;
|
||||
}
|
||||
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(
|
||||
|
|
|
|||
|
|
@ -28,6 +28,11 @@ namespace _zeitbild
|
|||
|
|
||||
string
|
||||
);
|
||||
dav_token : (
|
||||
null
|
||||
|
|
||||
string
|
||||
);
|
||||
};
|
||||
|
||||
|
||||
|
|
@ -82,10 +87,9 @@ namespace _zeitbild
|
|||
}
|
||||
|
|
||||
{
|
||||
kind : "caldav";
|
||||
kind : "ics_feed";
|
||||
data : {
|
||||
url : string;
|
||||
read_only : boolean;
|
||||
from_fucked_up_wordpress : boolean;
|
||||
};
|
||||
}
|
||||
|
|
@ -112,4 +116,15 @@ namespace _zeitbild
|
|||
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;
|
||||
};
|
||||
|
||||
}
|
||||
|
|
|
|||
|
|
@ -56,7 +56,6 @@ ${dir_temp}/zeitbild-unlinked.js: \
|
|||
${dir_source}/services/user.ts \
|
||||
${dir_source}/services/resource.ts \
|
||||
${dir_source}/services/calendar.ts \
|
||||
${dir_source}/services/caldav.ts \
|
||||
${dir_source}/api/base.ts \
|
||||
${dir_source}/api/transformations/datetime.ts \
|
||||
${dir_source}/api/actions/meta_ping.ts \
|
||||
|
|
@ -76,13 +75,7 @@ ${dir_temp}/zeitbild-unlinked.js: \
|
|||
${dir_source}/api/actions/calendar_event_change.ts \
|
||||
${dir_source}/api/actions/calendar_event_remove.ts \
|
||||
${dir_source}/api/actions/events.ts \
|
||||
${dir_source}/api/actions/export_ical.ts \
|
||||
${dir_source}/api/actions/caldav_sniff.ts \
|
||||
${dir_source}/api/actions/caldav_put.ts \
|
||||
${dir_source}/api/actions/caldav_probe.ts \
|
||||
${dir_source}/api/actions/caldav_probe_via_well_known.ts \
|
||||
${dir_source}/api/actions/caldav_projects.ts \
|
||||
${dir_source}/api/actions/caldav_get.ts \
|
||||
${dir_source}/api/actions/export_ics.ts \
|
||||
${dir_source}/api/functions.ts \
|
||||
${dir_source}/main.ts
|
||||
@ ${cmd_log} "compile …"
|
||||
|
|
|
|||
|
|
@ -2,7 +2,7 @@
|
|||
|
||||
## consts
|
||||
|
||||
dir=lib/plankton
|
||||
dir=$(pwd)/lib/plankton
|
||||
|
||||
modules=""
|
||||
modules="${modules} base"
|
||||
|
|
@ -21,12 +21,12 @@ modules="${modules} order"
|
|||
modules="${modules} ical"
|
||||
modules="${modules} url"
|
||||
modules="${modules} http"
|
||||
modules="${modules} webdav"
|
||||
modules="${modules} caldav"
|
||||
# modules="${modules} webdav"
|
||||
# modules="${modules} caldav"
|
||||
modules="${modules} api"
|
||||
# modules="${modules} rest_http"
|
||||
modules="${modules} rest_http"
|
||||
# modules="${modules} rest_webdav"
|
||||
modules="${modules} rest_caldav"
|
||||
# modules="${modules} rest_caldav"
|
||||
modules="${modules} server"
|
||||
modules="${modules} args"
|
||||
modules="${modules} bcrypt"
|
||||
|
|
@ -38,6 +38,13 @@ modules="${modules} sha256"
|
|||
|
||||
## exec
|
||||
|
||||
mkdir /tmp/sandbox -p
|
||||
cd /tmp/sandbox
|
||||
ptk fetch node ${modules}
|
||||
schwamm --include=plankton.swm.json --output=dump:logic-decl > ${dir}/plankton.d.ts
|
||||
schwamm --include=plankton.swm.json --output=dump:logic-impl > ${dir}/plankton.js
|
||||
exit
|
||||
|
||||
mkdir -p ${dir}
|
||||
cd ${dir}
|
||||
ptk bundle node ${modules}
|
||||
|
|
|
|||
Loading…
Reference in a new issue