[int]
This commit is contained in:
parent
64652af779
commit
00f416a126
14 changed files with 418 additions and 21 deletions
|
@ -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"
|
||||
}
|
||||
],
|
||||
|
|
75
source/api/actions/davina_calendars.ts
Normal file
75
source/api/actions/davina_calendars.ts
Normal file
|
@ -0,0 +1,75 @@
|
|||
|
||||
namespace _zeitbild.api
|
||||
{
|
||||
|
||||
/**
|
||||
*/
|
||||
export function register_davina_calendars(
|
||||
rest_subject : lib_plankton.rest_caldav.type_rest
|
||||
) : void
|
||||
{
|
||||
register<
|
||||
null,
|
||||
null | Array<
|
||||
{
|
||||
id : int;
|
||||
name : string;
|
||||
access_level : string;
|
||||
}
|
||||
>
|
||||
>
|
||||
(
|
||||
rest_subject,
|
||||
lib_plankton.http.enum_method.get,
|
||||
"/davina/calendars",
|
||||
{
|
||||
"input_schema": () => ({
|
||||
"nullable": true,
|
||||
}),
|
||||
"output_schema": () => ({
|
||||
"nullable": false,
|
||||
"type": "boolean",
|
||||
}),
|
||||
"query_parameters": () => ([
|
||||
{
|
||||
"name": "username",
|
||||
"required": true,
|
||||
"description": "username",
|
||||
},
|
||||
]),
|
||||
/**
|
||||
* @todo
|
||||
*/
|
||||
"restriction": restriction_none,
|
||||
"execution": async ({"query_parameters": query_parameters}) => {
|
||||
const username : string = query_parameters["username"];
|
||||
const user_id : _zeitbild.type_user_id = await _zeitbild.service.user.identify(username);
|
||||
|
||||
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({
|
||||
"status_code": 200,
|
||||
"data": data,
|
||||
})
|
||||
)
|
||||
);
|
||||
},
|
||||
}
|
||||
);
|
||||
}
|
||||
|
||||
}
|
||||
|
57
source/api/actions/davina_check.ts
Normal file
57
source/api/actions/davina_check.ts
Normal file
|
@ -0,0 +1,57 @@
|
|||
|
||||
namespace _zeitbild.api
|
||||
{
|
||||
|
||||
/**
|
||||
*/
|
||||
export function register_davina_check(
|
||||
rest_subject : lib_plankton.rest_caldav.type_rest
|
||||
) : void
|
||||
{
|
||||
register<
|
||||
null,
|
||||
boolean
|
||||
>
|
||||
(
|
||||
rest_subject,
|
||||
lib_plankton.http.enum_method.get,
|
||||
"/davina/check",
|
||||
{
|
||||
"input_schema": () => ({
|
||||
"nullable": true,
|
||||
}),
|
||||
"output_schema": () => ({
|
||||
"nullable": false,
|
||||
"type": "boolean",
|
||||
}),
|
||||
"query_parameters": () => ([
|
||||
{
|
||||
"name": "username",
|
||||
"required": true,
|
||||
"description": "username",
|
||||
},
|
||||
{
|
||||
"name": "password",
|
||||
"required": true,
|
||||
"description": "password",
|
||||
},
|
||||
]),
|
||||
"restriction": restriction_none,
|
||||
"execution": async ({"query_parameters": query_parameters}) => {
|
||||
const username : string = query_parameters["username"];
|
||||
const password : string = query_parameters["password"];
|
||||
/**
|
||||
* @todo [important] rectify
|
||||
*/
|
||||
const valid : boolean = (username === password);
|
||||
return Promise.resolve({
|
||||
"status_code": 200,
|
||||
"data": valid,
|
||||
});
|
||||
},
|
||||
}
|
||||
);
|
||||
}
|
||||
|
||||
}
|
||||
|
78
source/api/actions/davina_event_get.ts
Normal file
78
source/api/actions/davina_event_get.ts
Normal file
|
@ -0,0 +1,78 @@
|
|||
|
||||
namespace _zeitbild.api
|
||||
{
|
||||
|
||||
/**
|
||||
*/
|
||||
export function register_davina_event_get(
|
||||
rest_subject : lib_plankton.rest_caldav.type_rest
|
||||
) : void
|
||||
{
|
||||
register<
|
||||
null,
|
||||
lib_plankton.ical.type_vcalendar
|
||||
>(
|
||||
rest_subject,
|
||||
lib_plankton.http.enum_method.get,
|
||||
"/davina/event_get",
|
||||
{
|
||||
"query_parameters": () => ([
|
||||
{
|
||||
"name": "username",
|
||||
"required": true,
|
||||
"description": "user name",
|
||||
},
|
||||
{
|
||||
"name": "calendar_id",
|
||||
"required": true,
|
||||
"description": "calendar ID",
|
||||
},
|
||||
{
|
||||
"name": "event_id",
|
||||
"required": true,
|
||||
"description": "event ID",
|
||||
},
|
||||
]),
|
||||
"output_schema": () => ({
|
||||
"nullable": false,
|
||||
"type": "string",
|
||||
}),
|
||||
"response_body_mimetype": "text/calendar",
|
||||
"response_body_encode": (output) => Buffer.from(
|
||||
(typeof(output) === "string")
|
||||
?
|
||||
output
|
||||
:
|
||||
(
|
||||
lib_plankton.ical.ics_encode(output)
|
||||
/**
|
||||
* @todo add event encoder function to plankton
|
||||
*/
|
||||
// .replace(new RegExp("[\\s\\S]*BEGIN:VEVENT([\\s\\S]*)END:VEVENT[\\s\\S]*", "m"), "BEGIN:VEVENT$1END:VEVENT")
|
||||
)
|
||||
),
|
||||
/**
|
||||
* @todo
|
||||
*/
|
||||
"restriction": restriction_none,
|
||||
"execution": async (stuff) => {
|
||||
const username : string = stuff.query_parameters["username"];
|
||||
const user_id : _zeitbild.type_user_id = await _zeitbild.service.user.identify(username);
|
||||
|
||||
const calendar_id : int = parseInt(stuff.query_parameters["calendar_id"]);
|
||||
const calendar_object : _zeitbild.type_calendar_object = await _zeitbild.service.calendar.get(calendar_id, user_id);
|
||||
const event_id : int = parseInt(stuff.query_parameters["event_id"]);
|
||||
const event_object : _zeitbild.type_event_object = await _zeitbild.service.resource.event_get(calendar_object.resource_id, event_id);
|
||||
|
||||
return Promise.resolve(
|
||||
{
|
||||
"status_code": 200,
|
||||
"data": _zeitbild.helpers.ical_vcalendar_from_own_event_list([event_object]),
|
||||
}
|
||||
);
|
||||
}
|
||||
}
|
||||
);
|
||||
}
|
||||
|
||||
}
|
114
source/api/actions/davina_event_list.ts
Normal file
114
source/api/actions/davina_event_list.ts
Normal file
|
@ -0,0 +1,114 @@
|
|||
|
||||
namespace _zeitbild.api
|
||||
{
|
||||
|
||||
/**
|
||||
*/
|
||||
export function register_davina_event_list(
|
||||
rest_subject : lib_plankton.rest_caldav.type_rest
|
||||
) : void
|
||||
{
|
||||
register<
|
||||
null,
|
||||
(
|
||||
Array<
|
||||
{
|
||||
event_id : (null | int);
|
||||
event_name : string;
|
||||
}
|
||||
>
|
||||
|
|
||||
string
|
||||
)
|
||||
>(
|
||||
rest_subject,
|
||||
lib_plankton.http.enum_method.get,
|
||||
"/davina/event_list",
|
||||
{
|
||||
"query_parameters": () => ([
|
||||
{
|
||||
"name": "username",
|
||||
"required": true,
|
||||
"description": "user name",
|
||||
},
|
||||
{
|
||||
"name": "calendar_id",
|
||||
"required": true,
|
||||
"description": "calendar ID",
|
||||
},
|
||||
]),
|
||||
"output_schema": () => ({
|
||||
"type": "array",
|
||||
"items": {
|
||||
"nullable": false,
|
||||
"type": "object",
|
||||
"additionalProperties": false,
|
||||
"properties": {
|
||||
"event_id": {
|
||||
"nullable": true,
|
||||
"type": "number",
|
||||
},
|
||||
"event_name": {
|
||||
"nullable": false,
|
||||
"type": "string",
|
||||
},
|
||||
},
|
||||
"required": [
|
||||
"event_id",
|
||||
"event_name",
|
||||
],
|
||||
}
|
||||
}),
|
||||
/**
|
||||
* @todo
|
||||
*/
|
||||
"restriction": restriction_none,
|
||||
"execution": async (stuff) => {
|
||||
const username : string = stuff.query_parameters["username"];
|
||||
const user_id : _zeitbild.type_user_id = await _zeitbild.service.user.identify(username);
|
||||
|
||||
/**
|
||||
* @todo
|
||||
*/
|
||||
const from : lib_plankton.pit.type_pit = 0;
|
||||
const to : lib_plankton.pit.type_pit = 1800000000;
|
||||
const calendar_id : int = parseInt(stuff.query_parameters["calendar_id"]);
|
||||
|
||||
return (
|
||||
_zeitbild.service.calendar.gather_events(
|
||||
[calendar_id],
|
||||
from,
|
||||
to,
|
||||
user_id
|
||||
)
|
||||
.then(
|
||||
(data) => Promise.resolve(
|
||||
{
|
||||
"status_code": 200,
|
||||
"data": (
|
||||
data
|
||||
.map(
|
||||
(entry) => ({
|
||||
"event_id": entry.event_id,
|
||||
"event_name": entry.event_object.name,
|
||||
})
|
||||
)
|
||||
),
|
||||
}
|
||||
)
|
||||
)
|
||||
.catch(
|
||||
(reason) => Promise.resolve(
|
||||
{
|
||||
"status_code": 403,
|
||||
"data": String(reason),
|
||||
}
|
||||
)
|
||||
)
|
||||
);
|
||||
}
|
||||
}
|
||||
);
|
||||
}
|
||||
|
||||
}
|
|
@ -29,7 +29,13 @@ namespace _zeitbild.api
|
|||
* @todo outsource?
|
||||
*/
|
||||
export async function web_auth(
|
||||
authorization_string : (null | string)
|
||||
authorization_string : (null | string),
|
||||
{
|
||||
"via_dav_token": via_dav_token = false,
|
||||
} : {
|
||||
via_dav_token ?: boolean;
|
||||
} = {
|
||||
}
|
||||
) : Promise<(null | _zeitbild.type_user_id)>
|
||||
{
|
||||
if (authorization_string === null) {
|
||||
|
@ -68,9 +74,16 @@ namespace _zeitbild.api
|
|||
return Promise.resolve<(null | _zeitbild.type_user_id)>(null);
|
||||
}
|
||||
else {
|
||||
const password_shall : string = lib_plankton.sha256.get(
|
||||
username,
|
||||
_zeitbild.conf.get()["misc"]["auth_salt"]
|
||||
const user_object : _zeitbild.type_user_object = await _zeitbild.service.user.get(user_id);
|
||||
const password_shall : string = (
|
||||
via_dav_token
|
||||
?
|
||||
user_object.dav_token
|
||||
:
|
||||
lib_plankton.sha256.get(
|
||||
username,
|
||||
_zeitbild.conf.get()["misc"]["auth_salt"]
|
||||
)
|
||||
);
|
||||
if (! (password_is === password_shall)) {
|
||||
/**
|
||||
|
@ -96,6 +109,13 @@ namespace _zeitbild.api
|
|||
}
|
||||
|
||||
|
||||
/**
|
||||
*/
|
||||
export const restriction_none : lib_plankton.rest_caldav.type_restriction<any> = (
|
||||
(stuff) => Promise.resolve<boolean>(true)
|
||||
);
|
||||
|
||||
|
||||
/**
|
||||
*/
|
||||
export const restriction_logged_in : lib_plankton.rest_caldav.type_restriction<any> = (
|
||||
|
@ -112,11 +132,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
|
||||
(
|
||||
stuff.headers["Authorization"]
|
||||
??
|
||||
stuff.headers["authorization"]
|
||||
??
|
||||
null
|
||||
),
|
||||
{
|
||||
"via_dav_token": false,
|
||||
}
|
||||
)
|
||||
.then<boolean>(
|
||||
(user_id) => Promise.resolve<boolean>(
|
||||
|
@ -129,8 +154,26 @@ namespace _zeitbild.api
|
|||
|
||||
/**
|
||||
*/
|
||||
export const restriction_none : lib_plankton.rest_caldav.type_restriction<any> = (
|
||||
(stuff) => Promise.resolve<boolean>(true)
|
||||
export const restriction_dav_token : lib_plankton.rest_caldav.type_restriction<any> = (
|
||||
(stuff) => (
|
||||
web_auth(
|
||||
(
|
||||
stuff.headers["Authorization"]
|
||||
??
|
||||
stuff.headers["authorization"]
|
||||
??
|
||||
null
|
||||
),
|
||||
{
|
||||
"via_dav_token": true,
|
||||
}
|
||||
)
|
||||
.then<boolean>(
|
||||
(user_id) => Promise.resolve<boolean>(
|
||||
(user_id !== null)
|
||||
)
|
||||
)
|
||||
)
|
||||
);
|
||||
|
||||
|
||||
|
|
|
@ -59,6 +59,13 @@ namespace _zeitbild.api
|
|||
_zeitbild.api.register_caldav_projects(rest_subject);
|
||||
_zeitbild.api.register_caldav_get(rest_subject);
|
||||
}
|
||||
// davina
|
||||
{
|
||||
_zeitbild.api.register_davina_check(rest_subject);
|
||||
_zeitbild.api.register_davina_calendars(rest_subject);
|
||||
_zeitbild.api.register_davina_event_list(rest_subject);
|
||||
_zeitbild.api.register_davina_event_get(rest_subject);
|
||||
}
|
||||
// misc
|
||||
{
|
||||
_zeitbild.api.register_users(rest_subject);
|
||||
|
|
|
@ -8,6 +8,7 @@ type type_data = {
|
|||
id : int;
|
||||
name : string;
|
||||
email_address : string;
|
||||
dav_token : (null | string);
|
||||
password : string;
|
||||
}
|
||||
>;
|
||||
|
@ -72,6 +73,7 @@ async function data_init(
|
|||
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
|
||||
|
|
|
@ -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
|
||||
{
|
||||
|
||||
}
|
|
@ -251,6 +251,7 @@ namespace _zeitbild.service.caldav
|
|||
"propstats": (
|
||||
false
|
||||
?
|
||||
// probably the wrong way
|
||||
[
|
||||
{
|
||||
"prop": (props ?? []).map(
|
||||
|
@ -284,6 +285,7 @@ namespace _zeitbild.service.caldav
|
|||
},
|
||||
]
|
||||
:
|
||||
// probably the right way
|
||||
props.map(
|
||||
(prop) => {
|
||||
const prop_parts : Array<string> = prop.toLowerCase().split(":");
|
||||
|
@ -352,6 +354,7 @@ namespace _zeitbild.service.caldav
|
|||
user_id : type_user_id
|
||||
) : Promise<lib_plankton.xml.type_node_data>
|
||||
{
|
||||
const http_protocol : string = "HTTP/1.1";
|
||||
const answers : Record<
|
||||
string,
|
||||
(stuff : any) => lib_plankton.webdav.type_data_prop_value
|
||||
|
@ -476,13 +479,13 @@ namespace _zeitbild.service.caldav
|
|||
?
|
||||
{
|
||||
"prop": group.map(member => member.prop),
|
||||
"status": "HTTP/1.1 200 OK",
|
||||
"status": (http_protocol + " 200 OK"),
|
||||
"description": null,
|
||||
}
|
||||
:
|
||||
{
|
||||
"prop": group.map(member => member.prop),
|
||||
"status": "HTTP/1.1 404 Not Found",
|
||||
"status": (http_protocol + " 404 Not Found"),
|
||||
"description": null,
|
||||
}
|
||||
)
|
||||
|
|
|
@ -28,6 +28,11 @@ namespace _zeitbild
|
|||
|
|
||||
string
|
||||
);
|
||||
dav_token : (
|
||||
null
|
||||
|
|
||||
string
|
||||
);
|
||||
};
|
||||
|
||||
|
||||
|
@ -82,6 +87,9 @@ namespace _zeitbild
|
|||
}
|
||||
|
|
||||
{
|
||||
/**
|
||||
* @todo rename to "ics_feed" or sth.
|
||||
*/
|
||||
kind : "caldav";
|
||||
data : {
|
||||
url : string;
|
||||
|
|
|
@ -83,6 +83,10 @@ ${dir_temp}/zeitbild-unlinked.js: \
|
|||
${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/davina_check.ts \
|
||||
${dir_source}/api/actions/davina_calendars.ts \
|
||||
${dir_source}/api/actions/davina_event_list.ts \
|
||||
${dir_source}/api/actions/davina_event_get.ts \
|
||||
${dir_source}/api/functions.ts \
|
||||
${dir_source}/main.ts
|
||||
@ ${cmd_log} "compile …"
|
||||
|
|
Loading…
Add table
Reference in a new issue