[mod]
This commit is contained in:
parent
aea08efed6
commit
9e077fe362
23 changed files with 4156 additions and 5361 deletions
|
@ -2,5 +2,8 @@
|
||||||
"version": 1,
|
"version": 1,
|
||||||
"log": [
|
"log": [
|
||||||
{"kind": "stdout", "data": {"threshold": "info"}}
|
{"kind": "stdout", "data": {"threshold": "info"}}
|
||||||
]
|
],
|
||||||
|
"session_management": {
|
||||||
|
"in_memory": false
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -2,120 +2,51 @@
|
||||||
"users": [
|
"users": [
|
||||||
{
|
{
|
||||||
"id": 1,
|
"id": 1,
|
||||||
"object": {
|
"name": "alice",
|
||||||
"name": "christian.frass"
|
"email_address": "alice@example.org",
|
||||||
}
|
"password": "alice"
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"id": 2,
|
"id": 2,
|
||||||
"object": {
|
"name": "bob",
|
||||||
"name": "andre.weichert"
|
"email_address": "bob@example.org",
|
||||||
}
|
"password": "bob"
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"id": 3,
|
"id": 3,
|
||||||
"object": {
|
"name": "charlie",
|
||||||
"name": "steffen.doegnitz"
|
"email_address": "charlie@example.org",
|
||||||
}
|
"password": "charlie"
|
||||||
},
|
|
||||||
{
|
|
||||||
"id": 4,
|
|
||||||
"object": {
|
|
||||||
"name": "frank.dietrich"
|
|
||||||
}
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"id": 5,
|
|
||||||
"object": {
|
|
||||||
"name": "michael.berger"
|
|
||||||
}
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"id": 6,
|
|
||||||
"object": {
|
|
||||||
"name": "roland.schroeder"
|
|
||||||
}
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"id": 7,
|
|
||||||
"object": {
|
|
||||||
"name": "rene.hahn"
|
|
||||||
}
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"id": 8,
|
|
||||||
"object": {
|
|
||||||
"name": "max.meierhof"
|
|
||||||
}
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"id": 9,
|
|
||||||
"object": {
|
|
||||||
"name": "klaus.kleba"
|
|
||||||
}
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"id": 10,
|
|
||||||
"object": {
|
|
||||||
"name": "tim.detzner"
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
],
|
],
|
||||||
"calendars": [
|
"calendars": [
|
||||||
{
|
{
|
||||||
"id": 1,
|
"id": 1,
|
||||||
"object": {
|
"name": "house",
|
||||||
"kind": "concrete",
|
"public": false,
|
||||||
|
"members": [
|
||||||
|
{
|
||||||
|
"user_id": 1,
|
||||||
|
"role": "editor"
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"resource": {
|
||||||
|
"kind": "local",
|
||||||
"data": {
|
"data": {
|
||||||
"name": "BV",
|
|
||||||
"private": false,
|
|
||||||
"hue": 0.0000000000000000,
|
|
||||||
"users": [
|
|
||||||
],
|
|
||||||
"events": [
|
"events": [
|
||||||
{
|
{
|
||||||
"name": "9. Bundesparteitag | 1. Sitzung | Tag 1",
|
"name": "clean floors",
|
||||||
"begin": {
|
"begin": {
|
||||||
"timezone_shift": 2,
|
"timezone_shift": 2,
|
||||||
"date": {"year": 2024, "month": 10, "day": 18},
|
"date": {"year": 2024, "month": 9, "day": 21},
|
||||||
"time": {"hour": 10, "minute": 0, "second": 0}
|
"time": {"hour": 10, "minute": 0, "second": 0}
|
||||||
},
|
},
|
||||||
"end": {
|
"end": {
|
||||||
"timezone_shift": 2,
|
"timezone_shift": 2,
|
||||||
"date": {"year": 2024, "month": 10, "day": 18},
|
"date": {"year": 2024, "month": 9, "day": 21},
|
||||||
"time": {"hour": 18, "minute": 0, "second": 0}
|
"time": {"hour": 11, "minute": 0, "second": 0}
|
||||||
},
|
},
|
||||||
"location": "Halle",
|
"location": "1st floor",
|
||||||
"description": null
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"name": "9. Bundesparteitag | 1. Sitzung | Tag 2",
|
|
||||||
"begin": {
|
|
||||||
"timezone_shift": 2,
|
|
||||||
"date": {"year": 2024, "month": 10, "day": 19},
|
|
||||||
"time": {"hour": 10, "minute": 0, "second": 0}
|
|
||||||
},
|
|
||||||
"end": {
|
|
||||||
"timezone_shift": 2,
|
|
||||||
"date": {"year": 2024, "month": 10, "day": 19},
|
|
||||||
"time": {"hour": 18, "minute": 0, "second": 0}
|
|
||||||
},
|
|
||||||
"location": "Halle",
|
|
||||||
"description": null
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"name": "9. Bundesparteitag | 1. Sitzung | Tag 3",
|
|
||||||
"begin": {
|
|
||||||
"timezone_shift": 2,
|
|
||||||
"date": {"year": 2024, "month": 10, "day": 20},
|
|
||||||
"time": {"hour": 10, "minute": 0, "second": 0}
|
|
||||||
},
|
|
||||||
"end": {
|
|
||||||
"timezone_shift": 2,
|
|
||||||
"date": {"year": 2024, "month": 10, "day": 20},
|
|
||||||
"time": {"hour": 18, "minute": 0, "second": 0}
|
|
||||||
},
|
|
||||||
"location": "Halle",
|
|
||||||
"description": null
|
"description": null
|
||||||
}
|
}
|
||||||
]
|
]
|
||||||
|
@ -124,73 +55,35 @@
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"id": 2,
|
"id": 2,
|
||||||
"object": {
|
"name": "turf",
|
||||||
"kind": "concrete",
|
"public": false,
|
||||||
|
"members": [
|
||||||
|
{
|
||||||
|
"user_id": 1,
|
||||||
|
"role": "viewer"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"user_id": 2,
|
||||||
|
"role": "editor"
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"resource": {
|
||||||
|
"kind": "local",
|
||||||
"data": {
|
"data": {
|
||||||
"name": "LV Sachsen",
|
|
||||||
"private": false,
|
|
||||||
"hue": 0.6180339887498949,
|
|
||||||
"users": [
|
|
||||||
{
|
|
||||||
"id": 9,
|
|
||||||
"role": "editor"
|
|
||||||
}
|
|
||||||
],
|
|
||||||
"events": [
|
"events": [
|
||||||
{
|
{
|
||||||
"name": "Sören Pellmann zu den Landtagswahlen im Osten",
|
"name": "garden party",
|
||||||
"begin": {
|
"begin": {
|
||||||
"timezone_shift": 2,
|
"timezone_shift": 2,
|
||||||
"date": {"year": 2024, "month": 9, "day": 11},
|
"date": {"year": 2024, "month": 9, "day": 21},
|
||||||
"time": {"hour": 18, "minute": 0, "second": 0}
|
"time": {"hour": 18, "minute": 0, "second": 0}
|
||||||
},
|
},
|
||||||
"end": null,
|
|
||||||
"location": "online: https://v2202002113208108062.supersrv.de/b/har-jbu-lxy-rx1",
|
|
||||||
"description": null
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"name": "Erinnern versammeln. Praktiken für die Zukünfte einer Gesellschaft der Vielen.",
|
|
||||||
"begin": {
|
|
||||||
"timezone_shift": 2,
|
|
||||||
"date": {"year": 2024, "month": 9, "day": 13},
|
|
||||||
"time": {"hour": 17, "minute": 0, "second": 0}
|
|
||||||
},
|
|
||||||
"end": {
|
"end": {
|
||||||
"timezone_shift": 2,
|
"timezone_shift": 2,
|
||||||
"date": {"year": 2024, "month": 9, "day": 15},
|
"date": {"year": 2024, "month": 9, "day": 21},
|
||||||
"time": null
|
"time": {"hour": 23, "minute": 0, "second": 0}
|
||||||
},
|
},
|
||||||
"location": "Weltecho, Annaberger Straße 24, 09111 Chemnitz",
|
"location": "bob's garden",
|
||||||
"description": null
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"name": "Parteikonvent zur Auswertung des Wahljahres",
|
|
||||||
"begin": {
|
|
||||||
"timezone_shift": 2,
|
|
||||||
"date": {"year": 2024, "month": 9, "day": 14},
|
|
||||||
"time": {"hour": 10, "minute": 0, "second": 0}
|
|
||||||
},
|
|
||||||
"end": {
|
|
||||||
"timezone_shift": 2,
|
|
||||||
"date": {"year": 2024, "month": 9, "day": 14},
|
|
||||||
"time": {"hour": 16, "minute": 30, "second": 0}
|
|
||||||
},
|
|
||||||
"location": "Veranstaltungs- und Kulturforum STADTPARK | Hammertal 3 | 09669 Frankenberg/Sachsen",
|
|
||||||
"description": null
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"name": "Ist die extreme Rechte noch zu stoppen?",
|
|
||||||
"begin": {
|
|
||||||
"timezone_shift": 2,
|
|
||||||
"date": {"year": 2024, "month": 9, "day": 19},
|
|
||||||
"time": {"hour": 19, "minute": 0, "second": 0}
|
|
||||||
},
|
|
||||||
"end": {
|
|
||||||
"timezone_shift": 2,
|
|
||||||
"date": {"year": 2024, "month": 9, "day": 19},
|
|
||||||
"time": {"hour": 21, "minute": 0, "second": 0}
|
|
||||||
},
|
|
||||||
"location": "online: https://www.dielinke-sachsen.de/termine/?termin_ort=digital-internet-stream",
|
|
||||||
"description": null
|
"description": null
|
||||||
}
|
}
|
||||||
]
|
]
|
||||||
|
@ -199,149 +92,44 @@
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"id": 3,
|
"id": 3,
|
||||||
"object": {
|
"name": "town",
|
||||||
"kind": "concrete",
|
"public": true,
|
||||||
"data": {
|
"members": [
|
||||||
"name": "KV Zwickau",
|
{
|
||||||
"private": false,
|
"user_id": 1,
|
||||||
"hue": 0.4721359549995796,
|
"role": "viewer"
|
||||||
"events": [
|
},
|
||||||
{
|
{
|
||||||
"name": "Vorstands-Sitzung",
|
"user_id": 2,
|
||||||
"begin": {
|
"role": "viewer"
|
||||||
"timezone_shift": 2,
|
},
|
||||||
"date": {"year": 2024, "month": 9, "day": 5},
|
{
|
||||||
"time": {"hour": 18, "minute": 0, "second": 0}
|
"user_id": 3,
|
||||||
},
|
"role": "editor"
|
||||||
"end": {
|
|
||||||
"timezone_shift": 2,
|
|
||||||
"date": {"year": 2024, "month": 9, "day": 5},
|
|
||||||
"time": {"hour": 21, "minute": 0, "second": 0}
|
|
||||||
},
|
|
||||||
"location": "Zwickau, Innere Schneeberger Straße 17",
|
|
||||||
"description": null
|
|
||||||
}
|
|
||||||
]
|
|
||||||
}
|
}
|
||||||
}
|
],
|
||||||
},
|
"resource": {
|
||||||
{
|
"kind": "local",
|
||||||
"id": 4,
|
|
||||||
"object": {
|
|
||||||
"kind": "concrete",
|
|
||||||
"data": {
|
"data": {
|
||||||
"name": "OV Glauchau",
|
|
||||||
"private": false,
|
|
||||||
"users": [
|
|
||||||
{
|
|
||||||
"id": 1,
|
|
||||||
"role": "editor"
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"id": 5,
|
|
||||||
"role": "editor"
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"id": 6,
|
|
||||||
"role": "editor"
|
|
||||||
}
|
|
||||||
],
|
|
||||||
"hue": 0.09016994374947451,
|
|
||||||
"events": [
|
"events": [
|
||||||
{
|
{
|
||||||
"name": "Kinderspieletag",
|
"name": "ting",
|
||||||
"begin": {
|
"begin": {
|
||||||
"timezone_shift": 2,
|
"timezone_shift": 2,
|
||||||
"date": {"year": 2024, "month": 9, "day": 8},
|
"date": {"year": 2024, "month": 9, "day": 23},
|
||||||
"time": {"hour": 12, "minute": 0, "second": 0}
|
|
||||||
},
|
|
||||||
"end": {
|
|
||||||
"timezone_shift": 2,
|
|
||||||
"date": {"year": 2024, "month": 9, "day": 8},
|
|
||||||
"time": {"hour": 16, "minute": 0, "second": 0}
|
"time": {"hour": 16, "minute": 0, "second": 0}
|
||||||
},
|
},
|
||||||
"location": null,
|
|
||||||
"description": null
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"name": "Mitglieder-Sitzung",
|
|
||||||
"begin": {
|
|
||||||
"timezone_shift": 2,
|
|
||||||
"date": {"year": 2024, "month": 9, "day": 19},
|
|
||||||
"time": {"hour": 17, "minute": 30, "second": 0}
|
|
||||||
},
|
|
||||||
"end": {
|
"end": {
|
||||||
"timezone_shift": 2,
|
"timezone_shift": 2,
|
||||||
"date": {"year": 2024, "month": 9, "day": 19},
|
"date": {"year": 2024, "month": 9, "day": 23},
|
||||||
"time": {"hour": 19, "minute": 0, "second": 0}
|
"time": {"hour": 18, "minute": 0, "second": 0}
|
||||||
},
|
},
|
||||||
"location": null,
|
"location": "market square",
|
||||||
"description": null
|
"description": null
|
||||||
}
|
}
|
||||||
]
|
]
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
},
|
|
||||||
{
|
|
||||||
"id": 5,
|
|
||||||
"object": {
|
|
||||||
"kind": "concrete",
|
|
||||||
"data": {
|
|
||||||
"name": "OV Zwickau",
|
|
||||||
"private": false,
|
|
||||||
"hue": 0.09016994374947451,
|
|
||||||
"users": [
|
|
||||||
{
|
|
||||||
"id": 7,
|
|
||||||
"role": "editor"
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"id": 8,
|
|
||||||
"role": "viewer"
|
|
||||||
}
|
|
||||||
],
|
|
||||||
"events": [
|
|
||||||
{
|
|
||||||
"name": "4ter Christopher Street Day",
|
|
||||||
"begin": {
|
|
||||||
"timezone_shift": 2,
|
|
||||||
"date": {"year": 2024, "month": 8, "day": 31},
|
|
||||||
"time": {"hour": 10, "minute": 0, "second": 0}
|
|
||||||
},
|
|
||||||
"end": {
|
|
||||||
"timezone_shift": 2,
|
|
||||||
"date": {"year": 2024, "month": 8, "day": 31},
|
|
||||||
"time": {"hour": 17, "minute": 0, "second": 0}
|
|
||||||
},
|
|
||||||
"location": "Zwickau",
|
|
||||||
"description": null
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"name": "Regionaltreffen Westsachsen: Schule ohne Rassismus – Schule mit Courage",
|
|
||||||
"begin": {
|
|
||||||
"timezone_shift": 2,
|
|
||||||
"date": {"year": 2024, "month": 9, "day": 19},
|
|
||||||
"time": {"hour": 9, "minute": 0, "second": 0}
|
|
||||||
},
|
|
||||||
"end": null,
|
|
||||||
"location": null,
|
|
||||||
"description": null
|
|
||||||
}
|
|
||||||
]
|
|
||||||
}
|
|
||||||
}
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"id": 6,
|
|
||||||
"object": {
|
|
||||||
"kind": "caldav",
|
|
||||||
"data": {
|
|
||||||
"name": "Lixer",
|
|
||||||
"private": true,
|
|
||||||
"url": "https://export.kalender.digital/ics/0/3e10dae66950379d4cc8/gesamterkalender.ics?past_months=3&future_months=36",
|
|
||||||
"read_only": true
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
]
|
]
|
||||||
}
|
}
|
||||||
|
|
347
data/linke.json
Normal file
347
data/linke.json
Normal file
|
@ -0,0 +1,347 @@
|
||||||
|
{
|
||||||
|
"users": [
|
||||||
|
{
|
||||||
|
"id": 1,
|
||||||
|
"object": {
|
||||||
|
"name": "christian.frass"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"id": 2,
|
||||||
|
"object": {
|
||||||
|
"name": "andre.weichert"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"id": 3,
|
||||||
|
"object": {
|
||||||
|
"name": "steffen.doegnitz"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"id": 4,
|
||||||
|
"object": {
|
||||||
|
"name": "frank.dietrich"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"id": 5,
|
||||||
|
"object": {
|
||||||
|
"name": "michael.berger"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"id": 6,
|
||||||
|
"object": {
|
||||||
|
"name": "roland.schroeder"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"id": 7,
|
||||||
|
"object": {
|
||||||
|
"name": "rene.hahn"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"id": 8,
|
||||||
|
"object": {
|
||||||
|
"name": "max.meierhof"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"id": 9,
|
||||||
|
"object": {
|
||||||
|
"name": "klaus.kleba"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"id": 10,
|
||||||
|
"object": {
|
||||||
|
"name": "tim.detzner"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"calendars": [
|
||||||
|
{
|
||||||
|
"id": 1,
|
||||||
|
"object": {
|
||||||
|
"kind": "concrete",
|
||||||
|
"data": {
|
||||||
|
"name": "BV",
|
||||||
|
"private": false,
|
||||||
|
"hue": 0.0000000000000000,
|
||||||
|
"users": [
|
||||||
|
],
|
||||||
|
"events": [
|
||||||
|
{
|
||||||
|
"name": "9. Bundesparteitag | 1. Sitzung | Tag 1",
|
||||||
|
"begin": {
|
||||||
|
"timezone_shift": 2,
|
||||||
|
"date": {"year": 2024, "month": 10, "day": 18},
|
||||||
|
"time": {"hour": 10, "minute": 0, "second": 0}
|
||||||
|
},
|
||||||
|
"end": {
|
||||||
|
"timezone_shift": 2,
|
||||||
|
"date": {"year": 2024, "month": 10, "day": 18},
|
||||||
|
"time": {"hour": 18, "minute": 0, "second": 0}
|
||||||
|
},
|
||||||
|
"location": "Halle",
|
||||||
|
"description": null
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"name": "9. Bundesparteitag | 1. Sitzung | Tag 2",
|
||||||
|
"begin": {
|
||||||
|
"timezone_shift": 2,
|
||||||
|
"date": {"year": 2024, "month": 10, "day": 19},
|
||||||
|
"time": {"hour": 10, "minute": 0, "second": 0}
|
||||||
|
},
|
||||||
|
"end": {
|
||||||
|
"timezone_shift": 2,
|
||||||
|
"date": {"year": 2024, "month": 10, "day": 19},
|
||||||
|
"time": {"hour": 18, "minute": 0, "second": 0}
|
||||||
|
},
|
||||||
|
"location": "Halle",
|
||||||
|
"description": null
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"name": "9. Bundesparteitag | 1. Sitzung | Tag 3",
|
||||||
|
"begin": {
|
||||||
|
"timezone_shift": 2,
|
||||||
|
"date": {"year": 2024, "month": 10, "day": 20},
|
||||||
|
"time": {"hour": 10, "minute": 0, "second": 0}
|
||||||
|
},
|
||||||
|
"end": {
|
||||||
|
"timezone_shift": 2,
|
||||||
|
"date": {"year": 2024, "month": 10, "day": 20},
|
||||||
|
"time": {"hour": 18, "minute": 0, "second": 0}
|
||||||
|
},
|
||||||
|
"location": "Halle",
|
||||||
|
"description": null
|
||||||
|
}
|
||||||
|
]
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"id": 2,
|
||||||
|
"object": {
|
||||||
|
"kind": "concrete",
|
||||||
|
"data": {
|
||||||
|
"name": "LV Sachsen",
|
||||||
|
"private": false,
|
||||||
|
"hue": 0.6180339887498949,
|
||||||
|
"users": [
|
||||||
|
{
|
||||||
|
"id": 9,
|
||||||
|
"role": "editor"
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"events": [
|
||||||
|
{
|
||||||
|
"name": "Sören Pellmann zu den Landtagswahlen im Osten",
|
||||||
|
"begin": {
|
||||||
|
"timezone_shift": 2,
|
||||||
|
"date": {"year": 2024, "month": 9, "day": 11},
|
||||||
|
"time": {"hour": 18, "minute": 0, "second": 0}
|
||||||
|
},
|
||||||
|
"end": null,
|
||||||
|
"location": "online: https://v2202002113208108062.supersrv.de/b/har-jbu-lxy-rx1",
|
||||||
|
"description": null
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"name": "Erinnern versammeln. Praktiken für die Zukünfte einer Gesellschaft der Vielen.",
|
||||||
|
"begin": {
|
||||||
|
"timezone_shift": 2,
|
||||||
|
"date": {"year": 2024, "month": 9, "day": 13},
|
||||||
|
"time": {"hour": 17, "minute": 0, "second": 0}
|
||||||
|
},
|
||||||
|
"end": {
|
||||||
|
"timezone_shift": 2,
|
||||||
|
"date": {"year": 2024, "month": 9, "day": 15},
|
||||||
|
"time": null
|
||||||
|
},
|
||||||
|
"location": "Weltecho, Annaberger Straße 24, 09111 Chemnitz",
|
||||||
|
"description": null
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"name": "Parteikonvent zur Auswertung des Wahljahres",
|
||||||
|
"begin": {
|
||||||
|
"timezone_shift": 2,
|
||||||
|
"date": {"year": 2024, "month": 9, "day": 14},
|
||||||
|
"time": {"hour": 10, "minute": 0, "second": 0}
|
||||||
|
},
|
||||||
|
"end": {
|
||||||
|
"timezone_shift": 2,
|
||||||
|
"date": {"year": 2024, "month": 9, "day": 14},
|
||||||
|
"time": {"hour": 16, "minute": 30, "second": 0}
|
||||||
|
},
|
||||||
|
"location": "Veranstaltungs- und Kulturforum STADTPARK | Hammertal 3 | 09669 Frankenberg/Sachsen",
|
||||||
|
"description": null
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"name": "Ist die extreme Rechte noch zu stoppen?",
|
||||||
|
"begin": {
|
||||||
|
"timezone_shift": 2,
|
||||||
|
"date": {"year": 2024, "month": 9, "day": 19},
|
||||||
|
"time": {"hour": 19, "minute": 0, "second": 0}
|
||||||
|
},
|
||||||
|
"end": {
|
||||||
|
"timezone_shift": 2,
|
||||||
|
"date": {"year": 2024, "month": 9, "day": 19},
|
||||||
|
"time": {"hour": 21, "minute": 0, "second": 0}
|
||||||
|
},
|
||||||
|
"location": "online: https://www.dielinke-sachsen.de/termine/?termin_ort=digital-internet-stream",
|
||||||
|
"description": null
|
||||||
|
}
|
||||||
|
]
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"id": 3,
|
||||||
|
"object": {
|
||||||
|
"kind": "concrete",
|
||||||
|
"data": {
|
||||||
|
"name": "KV Zwickau",
|
||||||
|
"private": false,
|
||||||
|
"hue": 0.4721359549995796,
|
||||||
|
"events": [
|
||||||
|
{
|
||||||
|
"name": "Vorstands-Sitzung",
|
||||||
|
"begin": {
|
||||||
|
"timezone_shift": 2,
|
||||||
|
"date": {"year": 2024, "month": 9, "day": 5},
|
||||||
|
"time": {"hour": 18, "minute": 0, "second": 0}
|
||||||
|
},
|
||||||
|
"end": {
|
||||||
|
"timezone_shift": 2,
|
||||||
|
"date": {"year": 2024, "month": 9, "day": 5},
|
||||||
|
"time": {"hour": 21, "minute": 0, "second": 0}
|
||||||
|
},
|
||||||
|
"location": "Zwickau, Innere Schneeberger Straße 17",
|
||||||
|
"description": null
|
||||||
|
}
|
||||||
|
]
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"id": 4,
|
||||||
|
"object": {
|
||||||
|
"kind": "concrete",
|
||||||
|
"data": {
|
||||||
|
"name": "OV Glauchau",
|
||||||
|
"private": false,
|
||||||
|
"users": [
|
||||||
|
{
|
||||||
|
"id": 1,
|
||||||
|
"role": "editor"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"id": 5,
|
||||||
|
"role": "editor"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"id": 6,
|
||||||
|
"role": "editor"
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"hue": 0.09016994374947451,
|
||||||
|
"events": [
|
||||||
|
{
|
||||||
|
"name": "Kinderspieletag",
|
||||||
|
"begin": {
|
||||||
|
"timezone_shift": 2,
|
||||||
|
"date": {"year": 2024, "month": 9, "day": 8},
|
||||||
|
"time": {"hour": 12, "minute": 0, "second": 0}
|
||||||
|
},
|
||||||
|
"end": {
|
||||||
|
"timezone_shift": 2,
|
||||||
|
"date": {"year": 2024, "month": 9, "day": 8},
|
||||||
|
"time": {"hour": 16, "minute": 0, "second": 0}
|
||||||
|
},
|
||||||
|
"location": null,
|
||||||
|
"description": null
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"name": "Mitglieder-Sitzung",
|
||||||
|
"begin": {
|
||||||
|
"timezone_shift": 2,
|
||||||
|
"date": {"year": 2024, "month": 9, "day": 19},
|
||||||
|
"time": {"hour": 17, "minute": 30, "second": 0}
|
||||||
|
},
|
||||||
|
"end": {
|
||||||
|
"timezone_shift": 2,
|
||||||
|
"date": {"year": 2024, "month": 9, "day": 19},
|
||||||
|
"time": {"hour": 19, "minute": 0, "second": 0}
|
||||||
|
},
|
||||||
|
"location": null,
|
||||||
|
"description": null
|
||||||
|
}
|
||||||
|
]
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"id": 5,
|
||||||
|
"object": {
|
||||||
|
"kind": "concrete",
|
||||||
|
"data": {
|
||||||
|
"name": "OV Zwickau",
|
||||||
|
"private": false,
|
||||||
|
"hue": 0.09016994374947451,
|
||||||
|
"users": [
|
||||||
|
{
|
||||||
|
"id": 7,
|
||||||
|
"role": "editor"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"id": 8,
|
||||||
|
"role": "viewer"
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"events": [
|
||||||
|
{
|
||||||
|
"name": "4ter Christopher Street Day",
|
||||||
|
"begin": {
|
||||||
|
"timezone_shift": 2,
|
||||||
|
"date": {"year": 2024, "month": 8, "day": 31},
|
||||||
|
"time": {"hour": 10, "minute": 0, "second": 0}
|
||||||
|
},
|
||||||
|
"end": {
|
||||||
|
"timezone_shift": 2,
|
||||||
|
"date": {"year": 2024, "month": 8, "day": 31},
|
||||||
|
"time": {"hour": 17, "minute": 0, "second": 0}
|
||||||
|
},
|
||||||
|
"location": "Zwickau",
|
||||||
|
"description": null
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"name": "Regionaltreffen Westsachsen: Schule ohne Rassismus – Schule mit Courage",
|
||||||
|
"begin": {
|
||||||
|
"timezone_shift": 2,
|
||||||
|
"date": {"year": 2024, "month": 9, "day": 19},
|
||||||
|
"time": {"hour": 9, "minute": 0, "second": 0}
|
||||||
|
},
|
||||||
|
"end": null,
|
||||||
|
"location": null,
|
||||||
|
"description": null
|
||||||
|
}
|
||||||
|
]
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"id": 6,
|
||||||
|
"object": {
|
||||||
|
"kind": "caldav",
|
||||||
|
"data": {
|
||||||
|
"name": "Lixer",
|
||||||
|
"private": true,
|
||||||
|
"url": "https://export.kalender.digital/ics/0/3e10dae66950379d4cc8/gesamterkalender.ics?past_months=3&future_months=36",
|
||||||
|
"read_only": true
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
]
|
||||||
|
}
|
2014
lib/plankton/plankton.d.ts
vendored
2014
lib/plankton/plankton.d.ts
vendored
File diff suppressed because it is too large
Load diff
File diff suppressed because it is too large
Load diff
|
@ -58,16 +58,21 @@ namespace _zeitbild.api
|
||||||
],
|
],
|
||||||
}
|
}
|
||||||
}),
|
}),
|
||||||
"restriction": restriction_none, // TODO
|
"restriction": restriction_logged_in,
|
||||||
"execution": () => (
|
"execution": async (stuff) => {
|
||||||
_zeitbild.service.calendar.overview(2) // TODO: user_id
|
const session : {key : string; value : lib_plankton.session.type_session;} = await session_from_stuff(stuff);
|
||||||
.then(
|
const user_id : _zeitbild.type.user_id = await _zeitbild.service.user.identify(session.value.name);
|
||||||
data => Promise.resolve({
|
|
||||||
"status_code": 200,
|
return (
|
||||||
"data": data,
|
_zeitbild.service.calendar.overview(user_id)
|
||||||
})
|
.then(
|
||||||
)
|
data => Promise.resolve({
|
||||||
)
|
"status_code": 200,
|
||||||
|
"data": data,
|
||||||
|
})
|
||||||
|
)
|
||||||
|
);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
|
@ -102,6 +102,9 @@ namespace _zeitbild.api
|
||||||
}),
|
}),
|
||||||
"restriction": restriction_none, // TODO
|
"restriction": restriction_none, // TODO
|
||||||
"execution": async (stuff) => {
|
"execution": async (stuff) => {
|
||||||
|
const session : {key : string; value : lib_plankton.session.type_session;} = await session_from_stuff(stuff);
|
||||||
|
const user_id : _zeitbild.type.user_id = await _zeitbild.service.user.identify(session.value.name);
|
||||||
|
|
||||||
const from : _zeitbild.helpers.type_pit = parseInt(stuff.query_parameters["from"]);
|
const from : _zeitbild.helpers.type_pit = parseInt(stuff.query_parameters["from"]);
|
||||||
const to : _zeitbild.helpers.type_pit = parseInt(stuff.query_parameters["to"]);
|
const to : _zeitbild.helpers.type_pit = parseInt(stuff.query_parameters["to"]);
|
||||||
const calendar_ids_wanted : Array<_zeitbild.type.calendar_id> = (
|
const calendar_ids_wanted : Array<_zeitbild.type.calendar_id> = (
|
||||||
|
@ -123,7 +126,7 @@ namespace _zeitbild.api
|
||||||
null
|
null
|
||||||
);
|
);
|
||||||
const calendar_ids_allowed : Array<_zeitbild.type.calendar_id> = (
|
const calendar_ids_allowed : Array<_zeitbild.type.calendar_id> = (
|
||||||
(await _zeitbild.service.calendar.overview(0)) // TODO: user_id
|
(await _zeitbild.service.calendar.overview(user_id))
|
||||||
.map((x : any) => x.id)
|
.map((x : any) => x.id)
|
||||||
);
|
);
|
||||||
const calendar_ids : Array<_zeitbild.type.calendar_id> = (
|
const calendar_ids : Array<_zeitbild.type.calendar_id> = (
|
||||||
|
|
|
@ -50,15 +50,15 @@ namespace _zeitbild.api
|
||||||
return Promise.reject(new Error("impossible"));
|
return Promise.reject(new Error("impossible"));
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
const admin : (null | _zeitbild.service.admin.type_value) = await _zeitbild.service.admin.login(input.name, input.password);
|
const passed : boolean = await _zeitbild.service.auth_internal.check(input.name, input.password);
|
||||||
if (admin === null) {
|
if (! passed) {
|
||||||
return Promise.resolve({
|
return Promise.resolve({
|
||||||
"status_code": 403,
|
"status_code": 403,
|
||||||
"data": null,
|
"data": null,
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
const session_key : string = await lib_plankton.session.begin(admin.name);
|
const session_key : string = await lib_plankton.session.begin(input.name);
|
||||||
return Promise.resolve({
|
return Promise.resolve({
|
||||||
"status_code": 201,
|
"status_code": 201,
|
||||||
"data": session_key,
|
"data": session_key,
|
||||||
|
|
|
@ -13,7 +13,7 @@ namespace _zeitbild.api
|
||||||
lib_plankton.http.enum_method.delete,
|
lib_plankton.http.enum_method.delete,
|
||||||
"/session/oidc",
|
"/session/oidc",
|
||||||
{
|
{
|
||||||
"description": "beendet eine Sitzung",
|
"description": "verarbeitet einen OIDC login callback",
|
||||||
"input_schema": () => ({
|
"input_schema": () => ({
|
||||||
"type": "null",
|
"type": "null",
|
||||||
}),
|
}),
|
||||||
|
@ -22,8 +22,15 @@ namespace _zeitbild.api
|
||||||
}),
|
}),
|
||||||
"restriction": restriction_logged_in,
|
"restriction": restriction_logged_in,
|
||||||
"execution": async (stuff) => {
|
"execution": async (stuff) => {
|
||||||
const session : {key : string; value : lib_plankton.session.type_session} = await session_from_stuff(stuff);
|
// do NOT wait
|
||||||
await lib_plankton.session.end(session.key);
|
_zeitbild.auth.control(
|
||||||
|
{
|
||||||
|
"kind": "authorization_callback",
|
||||||
|
"data": {
|
||||||
|
"http_request": http_request
|
||||||
|
}
|
||||||
|
}
|
||||||
|
);
|
||||||
return Promise.resolve({
|
return Promise.resolve({
|
||||||
"status_code": 200,
|
"status_code": 200,
|
||||||
"data": null,
|
"data": null,
|
||||||
|
|
|
@ -13,11 +13,10 @@ namespace _zeitbild.api
|
||||||
name : string;
|
name : string;
|
||||||
password : string;
|
password : string;
|
||||||
},
|
},
|
||||||
(
|
{
|
||||||
null
|
kind : string;
|
||||||
|
|
data : any;
|
||||||
string
|
}
|
||||||
)
|
|
||||||
>(
|
>(
|
||||||
rest_subject,
|
rest_subject,
|
||||||
lib_plankton.http.enum_method.get,
|
lib_plankton.http.enum_method.get,
|
||||||
|
@ -28,25 +27,15 @@ namespace _zeitbild.api
|
||||||
"nullable": true,
|
"nullable": true,
|
||||||
}),
|
}),
|
||||||
"output_schema": () => ({
|
"output_schema": () => ({
|
||||||
"type": "string",
|
"nullable": false
|
||||||
"description": "der Sitzungs-Schlüssel, der als Header 'X-Session-Key' gesetzt werden muss um Erlaubnis zur Ausführung geschützter Aktionen zu erhalten",
|
|
||||||
}),
|
}),
|
||||||
"restriction": restriction_none,
|
"restriction": restriction_none,
|
||||||
"execution": async () => {
|
"execution": async () => {
|
||||||
const admin : (null | _zeitbild.service.admin.type_value) = await _zeitbild.service.admin.login(input.name, input.password);
|
const preparation = await _zeitbild.auth.prepare();
|
||||||
if (admin === null) {
|
return Promise.resolve({
|
||||||
return Promise.resolve({
|
"status_code": 200,
|
||||||
"status_code": 403,
|
"data": preparation,
|
||||||
"data": null,
|
});
|
||||||
});
|
|
||||||
}
|
|
||||||
else {
|
|
||||||
const session_key : string = await lib_plankton.session.begin(admin.name);
|
|
||||||
return Promise.resolve({
|
|
||||||
"status_code": 201,
|
|
||||||
"data": session_key,
|
|
||||||
});
|
|
||||||
}
|
|
||||||
},
|
},
|
||||||
}
|
}
|
||||||
);
|
);
|
||||||
|
|
|
@ -26,8 +26,10 @@ namespace _zeitbild.api
|
||||||
}
|
}
|
||||||
// session
|
// session
|
||||||
{
|
{
|
||||||
|
// _zeitbild.api.register_session_prepare(rest_subject);
|
||||||
_zeitbild.api.register_session_begin(rest_subject);
|
_zeitbild.api.register_session_begin(rest_subject);
|
||||||
_zeitbild.api.register_session_end(rest_subject);
|
_zeitbild.api.register_session_end(rest_subject);
|
||||||
|
// _zeitbild.api.register_session_oidc(rest_subject);
|
||||||
}
|
}
|
||||||
// calendar
|
// calendar
|
||||||
{
|
{
|
||||||
|
|
93
source/auth.ts
Normal file
93
source/auth.ts
Normal file
|
@ -0,0 +1,93 @@
|
||||||
|
|
||||||
|
namespace _zeitbild.auth
|
||||||
|
{
|
||||||
|
|
||||||
|
/**
|
||||||
|
let _subject : (
|
||||||
|
null
|
||||||
|
|
|
||||||
|
lib_plankton.auth.type_auth<any, any>
|
||||||
|
) = null;
|
||||||
|
*/
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
*/
|
||||||
|
export function init(
|
||||||
|
) : Promise<void>
|
||||||
|
{
|
||||||
|
/*
|
||||||
|
switch (_zeitbild.conf.get().auth.kind) {
|
||||||
|
case "internal": {
|
||||||
|
_subject = lib_plankton.auth.internal.implementation_auth(
|
||||||
|
{
|
||||||
|
// "password_image_chest": password_image_chest,
|
||||||
|
// "check_password": (image, input) => Promise.resolve<boolean>(image === get_password_image(input)),
|
||||||
|
}
|
||||||
|
);
|
||||||
|
}
|
||||||
|
case "oidc": {
|
||||||
|
_subject = lib_plankton.auth.oidc.implementation_auth(
|
||||||
|
{
|
||||||
|
"url_authorization": _zeitbild.conf.get().auth.data.url_authorization,
|
||||||
|
"url_token": _zeitbild.conf.get().auth.data.url_token,
|
||||||
|
"url_userinfo": _zeitbild.conf.get().auth.data.url_userinfo,
|
||||||
|
"client_id": _zeitbild.conf.get().auth.data.client_id,
|
||||||
|
"client_secret": _zeitbild.conf.get().auth.data.client_secret,
|
||||||
|
"url_redirect": "/session/begin",
|
||||||
|
"scopes": [
|
||||||
|
"openid",
|
||||||
|
"profile",
|
||||||
|
"email",
|
||||||
|
],
|
||||||
|
"login_url_mode": "open",
|
||||||
|
}
|
||||||
|
);
|
||||||
|
}
|
||||||
|
default: {
|
||||||
|
// do nothing
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
*/
|
||||||
|
return Promise.resolve<void>(undefined);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
export function prepare(
|
||||||
|
) : Promise<{kind : string; data : any;}>
|
||||||
|
{
|
||||||
|
return (
|
||||||
|
_subject.prepare()
|
||||||
|
.then(
|
||||||
|
(data) => ({
|
||||||
|
"kind": _zeitbild.conf.get().auth.kind,
|
||||||
|
"data": data,
|
||||||
|
})
|
||||||
|
)
|
||||||
|
);
|
||||||
|
}
|
||||||
|
*/
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
export function execute(
|
||||||
|
input : any
|
||||||
|
) : Promise<string>
|
||||||
|
{
|
||||||
|
return _subject.execute(input);
|
||||||
|
}
|
||||||
|
*/
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
export function control(
|
||||||
|
input : any
|
||||||
|
) : Promise<void>
|
||||||
|
{
|
||||||
|
return _subject.control(input);
|
||||||
|
}
|
||||||
|
*/
|
||||||
|
|
||||||
|
}
|
427
source/conf.ts
427
source/conf.ts
|
@ -4,245 +4,214 @@ namespace _zeitbild.conf
|
||||||
|
|
||||||
/**
|
/**
|
||||||
*/
|
*/
|
||||||
type type_log_threshold = (
|
const _schema : lib_plankton.conf.type_schema = {
|
||||||
"debug"
|
"nullable": false,
|
||||||
|
|
"type": "object",
|
||||||
"info"
|
"properties": {
|
||||||
|
|
"version": {
|
||||||
"notice"
|
"nullable": false,
|
||||||
|
|
"type": "integer",
|
||||||
"warning"
|
"enum": [1]
|
||||||
|
|
},
|
||||||
"error"
|
"log": {
|
||||||
);
|
"nullable": false,
|
||||||
|
"type": "array",
|
||||||
|
"items": {
|
||||||
/**
|
"anyOf": [
|
||||||
*/
|
{
|
||||||
type type_log_format = (
|
"type": "object",
|
||||||
"jsonl"
|
"properties": {
|
||||||
|
|
"kind": {
|
||||||
"human_readable"
|
"nullable": false,
|
||||||
);
|
"type": "string",
|
||||||
|
"enum": ["stdout"]
|
||||||
|
},
|
||||||
/**
|
"data": {
|
||||||
*/
|
"nullable": false,
|
||||||
export type type_conf = {
|
"type": "object",
|
||||||
general : {
|
"properties": {
|
||||||
language : (null | string);
|
"threshold": {
|
||||||
};
|
"nullable": false,
|
||||||
log : Array<
|
"type": "string",
|
||||||
{
|
"enum": [
|
||||||
kind : "stdout";
|
"debug",
|
||||||
data : {
|
"info",
|
||||||
threshold : type_log_threshold;
|
"notice",
|
||||||
};
|
"warning",
|
||||||
|
"error"
|
||||||
|
],
|
||||||
|
"default": "info"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"required": [
|
||||||
|
]
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
]
|
||||||
|
},
|
||||||
|
"default": [
|
||||||
|
{
|
||||||
|
"kind": "stdout",
|
||||||
|
"data": {
|
||||||
|
"threshold": "info"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
]
|
||||||
|
},
|
||||||
|
"server": {
|
||||||
|
"nullable": false,
|
||||||
|
"type": "object",
|
||||||
|
"properties": {
|
||||||
|
"address": {
|
||||||
|
"nullable": false,
|
||||||
|
"type": "string",
|
||||||
|
"default": "::"
|
||||||
|
},
|
||||||
|
"port": {
|
||||||
|
"nullable": false,
|
||||||
|
"type": "integer",
|
||||||
|
"default": 7845
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"required": [
|
||||||
|
],
|
||||||
|
"additionalProperties": false,
|
||||||
|
"default": {
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"database": {
|
||||||
|
"anyOf": [
|
||||||
|
{
|
||||||
|
"type": "object",
|
||||||
|
"properties": {
|
||||||
|
"kind": {
|
||||||
|
"nullable": false,
|
||||||
|
"type": "string",
|
||||||
|
"enum": ["sqlite"]
|
||||||
|
},
|
||||||
|
"data": {
|
||||||
|
"nullable": false,
|
||||||
|
"type": "object",
|
||||||
|
"properties": {
|
||||||
|
"path": {
|
||||||
|
"nullable": false,
|
||||||
|
"type": "string",
|
||||||
|
"default": "data.sqlite"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"required": [
|
||||||
|
],
|
||||||
|
"default": {}
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"required": [
|
||||||
|
"kind"
|
||||||
|
]
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"type": "object",
|
||||||
|
"properties": {
|
||||||
|
"kind": {
|
||||||
|
"nullable": false,
|
||||||
|
"type": "string",
|
||||||
|
"enum": ["postgresql"]
|
||||||
|
},
|
||||||
|
"data": {
|
||||||
|
"nullable": false,
|
||||||
|
"type": "object",
|
||||||
|
"properties": {
|
||||||
|
"host": {
|
||||||
|
"nullable": false,
|
||||||
|
"type": "string"
|
||||||
|
},
|
||||||
|
"port": {
|
||||||
|
"nullable": false,
|
||||||
|
"type": "integer",
|
||||||
|
"default": 5432
|
||||||
|
},
|
||||||
|
"username": {
|
||||||
|
"nullable": false,
|
||||||
|
"type": "string"
|
||||||
|
},
|
||||||
|
"password": {
|
||||||
|
"nullable": false,
|
||||||
|
"type": "string"
|
||||||
|
},
|
||||||
|
"scheme": {
|
||||||
|
"nullable": false,
|
||||||
|
"type": "string"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"required": [
|
||||||
|
"host",
|
||||||
|
"username",
|
||||||
|
"password",
|
||||||
|
"scheme"
|
||||||
|
]
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"required": [
|
||||||
|
"kind",
|
||||||
|
"data"
|
||||||
|
]
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"default": {
|
||||||
|
"kind": "sqlite"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"session_management": {
|
||||||
|
"nullable": false,
|
||||||
|
"type": "object",
|
||||||
|
"properties": {
|
||||||
|
"in_memory": {
|
||||||
|
"nullable": false,
|
||||||
|
"type": "boolean",
|
||||||
|
"default": true
|
||||||
|
},
|
||||||
|
"drop_all_at_start": {
|
||||||
|
"nullable": false,
|
||||||
|
"type": "boolean",
|
||||||
|
"default": true
|
||||||
|
},
|
||||||
|
"lifetime": {
|
||||||
|
"nullable": false,
|
||||||
|
"type": "integer",
|
||||||
|
"default": 900
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"required": [
|
||||||
|
],
|
||||||
|
"additionalProperties": false,
|
||||||
|
"default": {}
|
||||||
}
|
}
|
||||||
|
|
},
|
||||||
{
|
"required": [
|
||||||
kind : "file";
|
"version"
|
||||||
data : {
|
],
|
||||||
threshold : type_log_threshold;
|
"additionalProperties": false
|
||||||
path : string;
|
|
||||||
};
|
|
||||||
}
|
|
||||||
|
|
|
||||||
{
|
|
||||||
kind : "email";
|
|
||||||
data : {
|
|
||||||
threshold : type_log_threshold;
|
|
||||||
smtp_credentials : {
|
|
||||||
host : string;
|
|
||||||
port : int;
|
|
||||||
username : string;
|
|
||||||
password : string;
|
|
||||||
};
|
|
||||||
sender : string;
|
|
||||||
receivers : Array<string>;
|
|
||||||
};
|
|
||||||
}
|
|
||||||
>;
|
|
||||||
server : {
|
|
||||||
host : string;
|
|
||||||
port : int;
|
|
||||||
path_base : string;
|
|
||||||
};
|
|
||||||
database : (
|
|
||||||
{
|
|
||||||
kind : "sqlite";
|
|
||||||
data : {
|
|
||||||
path : string;
|
|
||||||
};
|
|
||||||
}
|
|
||||||
|
|
|
||||||
{
|
|
||||||
kind : "postgresql";
|
|
||||||
data : {
|
|
||||||
host : string;
|
|
||||||
port ?: int;
|
|
||||||
username : string;
|
|
||||||
password : string;
|
|
||||||
schema : string;
|
|
||||||
};
|
|
||||||
}
|
|
||||||
);
|
|
||||||
authentication : (
|
|
||||||
{
|
|
||||||
kind : "internal";
|
|
||||||
data : {
|
|
||||||
};
|
|
||||||
}
|
|
||||||
|
|
|
||||||
{
|
|
||||||
kind : "oidc";
|
|
||||||
data : {
|
|
||||||
client_id : string;
|
|
||||||
client_secret : string;
|
|
||||||
url_authorization : string;
|
|
||||||
url_token : string;
|
|
||||||
url_userinfo : string;
|
|
||||||
};
|
|
||||||
}
|
|
||||||
);
|
|
||||||
session_management : {
|
|
||||||
in_memory : boolean;
|
|
||||||
drop_all_at_start : boolean;
|
|
||||||
lifetime : int;
|
|
||||||
};
|
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
*/
|
*/
|
||||||
var _data : (null | type_conf) = null;
|
var _data : (null | any) = null;
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
*/
|
*/
|
||||||
export function inject(
|
export function schema(
|
||||||
conf_raw : any
|
) : lib_plankton.conf.type_schema
|
||||||
) : void
|
|
||||||
{
|
{
|
||||||
const version : int = (conf_raw["version"] ?? 1);
|
return _schema;
|
||||||
_data = {
|
|
||||||
"general": (
|
|
||||||
((node_general) => ({
|
|
||||||
"language": (node_general["language"] ?? null),
|
|
||||||
})) (conf_raw["general"] ?? {})
|
|
||||||
),
|
|
||||||
"log": (
|
|
||||||
(() => {
|
|
||||||
const node_log = (
|
|
||||||
conf_raw["log"]
|
|
||||||
??
|
|
||||||
[
|
|
||||||
{
|
|
||||||
"kind": "stdout",
|
|
||||||
"data": {
|
|
||||||
}
|
|
||||||
},
|
|
||||||
]
|
|
||||||
);
|
|
||||||
return (
|
|
||||||
node_log.map(
|
|
||||||
(node_log_entry : any) => ({
|
|
||||||
"kind": node_log_entry["kind"],
|
|
||||||
"data": Object.assign(
|
|
||||||
{
|
|
||||||
"format": "human_readable",
|
|
||||||
"threshold": "notice",
|
|
||||||
},
|
|
||||||
(node_log_entry["data"] ?? {})
|
|
||||||
)
|
|
||||||
})
|
|
||||||
)
|
|
||||||
);
|
|
||||||
}) ()
|
|
||||||
),
|
|
||||||
"server": (
|
|
||||||
((node_server) => ({
|
|
||||||
"host": (() => {
|
|
||||||
return (node_server["host"] ?? "::");
|
|
||||||
}) (),
|
|
||||||
"port": (node_server["port"] ?? 7845),
|
|
||||||
"path_base": (node_server["path_base"] ?? ""),
|
|
||||||
})) (conf_raw["server"] ?? {})
|
|
||||||
),
|
|
||||||
"database": (
|
|
||||||
((node_database) => {
|
|
||||||
const kind : string = (node_database["kind"] ?? "sqlite");
|
|
||||||
const node_database_data_raw = (node_database["data"] ?? {});
|
|
||||||
switch (kind) {
|
|
||||||
case "sqlite": {
|
|
||||||
return {
|
|
||||||
"kind": kind,
|
|
||||||
"data": {
|
|
||||||
"path": (node_database_data_raw["path"] ?? "data.sqlite"),
|
|
||||||
}
|
|
||||||
};
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
case "postgresql": {
|
|
||||||
return {
|
|
||||||
"kind": kind,
|
|
||||||
"data": node_database_data_raw,
|
|
||||||
};
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
default: {
|
|
||||||
throw (new Error("unhandled"));
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}) (conf_raw["database"] ?? {})
|
|
||||||
),
|
|
||||||
"session_management": (
|
|
||||||
((node_session_management) => ({
|
|
||||||
"in_memory": (node_session_management["in_memory"] ?? true),
|
|
||||||
"drop_all_at_start": (node_session_management["drop_all_at_start"] ?? true),
|
|
||||||
"lifetime": (node_session_management["lifetime"] ?? 900),
|
|
||||||
})) (conf_raw["session_management"] ?? {})
|
|
||||||
),
|
|
||||||
};
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @todo mandatory fields
|
|
||||||
*/
|
|
||||||
export async function load(
|
|
||||||
path : string
|
|
||||||
) : Promise<void>
|
|
||||||
{
|
|
||||||
let conf_raw : any;
|
|
||||||
if (! (await lib_plankton.file.exists(path))) {
|
|
||||||
// return Promise.reject<void>(new Error("configuration file not found: " + path + "; using fallback"));
|
|
||||||
conf_raw = {};
|
|
||||||
}
|
|
||||||
else {
|
|
||||||
try {
|
|
||||||
conf_raw = lib_plankton.json.decode(await lib_plankton.file.read(path));
|
|
||||||
}
|
|
||||||
catch (error) {
|
|
||||||
conf_raw = null;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
if (conf_raw === null) {
|
|
||||||
return Promise.reject<void>("configuration file could not be read");
|
|
||||||
}
|
|
||||||
else {
|
|
||||||
inject(conf_raw);
|
|
||||||
// process.stderr.write(JSON.stringify(_data, undefined, "\t"));
|
|
||||||
return Promise.resolve<void>(undefined);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
*/
|
*/
|
||||||
export function get(
|
export function get(
|
||||||
) : type_conf
|
) : any
|
||||||
{
|
{
|
||||||
if (_data === null) {
|
if (_data === null) {
|
||||||
throw (new Error("conf not loaded yet"));
|
throw (new Error("conf not loaded yet"));
|
||||||
|
@ -252,4 +221,18 @@ namespace _zeitbild.conf
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
*/
|
||||||
|
export async function init(
|
||||||
|
path : string
|
||||||
|
) : Promise<void>
|
||||||
|
{
|
||||||
|
_data = await lib_plankton.conf.load(
|
||||||
|
_schema,
|
||||||
|
path
|
||||||
|
);
|
||||||
|
return Promise.resolve<void>(undefined);
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
136
source/main.ts
136
source/main.ts
|
@ -1,4 +1,90 @@
|
||||||
|
|
||||||
|
/**
|
||||||
|
*/
|
||||||
|
type type_data = {
|
||||||
|
users : Array<
|
||||||
|
{
|
||||||
|
id : int;
|
||||||
|
name : string;
|
||||||
|
email_address : string;
|
||||||
|
password : string;
|
||||||
|
}
|
||||||
|
>;
|
||||||
|
calendars : Array<
|
||||||
|
{
|
||||||
|
id : int;
|
||||||
|
name : string;
|
||||||
|
public : boolean;
|
||||||
|
members : Array<
|
||||||
|
{
|
||||||
|
user_id : int;
|
||||||
|
role : _zeitbild.type.role;
|
||||||
|
}
|
||||||
|
>;
|
||||||
|
resource : _zeitbild.type.resource_object;
|
||||||
|
}
|
||||||
|
>;
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
*/
|
||||||
|
async function data_init(
|
||||||
|
data : type_data
|
||||||
|
) : Promise<void>
|
||||||
|
{
|
||||||
|
let track : {
|
||||||
|
user : Record<
|
||||||
|
int,
|
||||||
|
_zeitbild.type.user_id
|
||||||
|
>;
|
||||||
|
calendar : Record<
|
||||||
|
int,
|
||||||
|
_zeitbild.type.user_id
|
||||||
|
>;
|
||||||
|
} = {
|
||||||
|
"user": {},
|
||||||
|
"calendar": {},
|
||||||
|
};
|
||||||
|
for await (const user_raw of data.users) {
|
||||||
|
const user_id : _zeitbild.type.user_id = await _zeitbild.service.user.add(
|
||||||
|
{
|
||||||
|
"name": user_raw.name,
|
||||||
|
"email_address": user_raw.email_address,
|
||||||
|
}
|
||||||
|
);
|
||||||
|
await _zeitbild.service.auth_internal.set(
|
||||||
|
user_raw.name,
|
||||||
|
user_raw.password
|
||||||
|
);
|
||||||
|
track.user[user_raw.id] = user_id;
|
||||||
|
}
|
||||||
|
for await (const calendar_raw of data.calendars) {
|
||||||
|
const resource_id : _zeitbild.type.resource_id = await _zeitbild.service.resource.add(
|
||||||
|
calendar_raw.resource
|
||||||
|
);
|
||||||
|
const calendar_id : _zeitbild.type.calendar_id = await _zeitbild.service.calendar.add(
|
||||||
|
{
|
||||||
|
"name": calendar_raw.name,
|
||||||
|
"public": calendar_raw.public,
|
||||||
|
"members": (
|
||||||
|
calendar_raw.members
|
||||||
|
.map(
|
||||||
|
(member_raw) => ({
|
||||||
|
"user_id": track.user[member_raw.user_id],
|
||||||
|
"role": member_raw.role,
|
||||||
|
})
|
||||||
|
)
|
||||||
|
),
|
||||||
|
"resource_id": resource_id,
|
||||||
|
}
|
||||||
|
);
|
||||||
|
track.calendar[calendar_raw.id] = calendar_id;
|
||||||
|
}
|
||||||
|
return Promise.resolve<void>(undefined);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
*/
|
*/
|
||||||
async function main(
|
async function main(
|
||||||
|
@ -35,8 +121,16 @@ async function main(
|
||||||
"description": "api-doc"
|
"description": "api-doc"
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"name": "expose-conf",
|
"name": "conf-schema",
|
||||||
"description": "expose-conf"
|
"description": "conf-schema"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"name": "conf-expose",
|
||||||
|
"description": "conf-expose"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"name": "fill",
|
||||||
|
"description": "fill"
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"name": "help",
|
"name": "help",
|
||||||
|
@ -88,10 +182,12 @@ async function main(
|
||||||
const args : Record<string, any> = arg_handler.read(lib_plankton.args.enum_environment.cli, args_raw.join(" "));
|
const args : Record<string, any> = arg_handler.read(lib_plankton.args.enum_environment.cli, args_raw.join(" "));
|
||||||
|
|
||||||
// init2
|
// init2
|
||||||
await _zeitbild.conf.load(args["conf_path"]);
|
await _zeitbild.conf.init(
|
||||||
|
args["conf_path"]
|
||||||
|
);
|
||||||
lib_plankton.log.conf_push(
|
lib_plankton.log.conf_push(
|
||||||
_zeitbild.conf.get().log.map(
|
_zeitbild.conf.get().log.map(
|
||||||
log_output => lib_plankton.log.channel_make(
|
(log_output : any) => lib_plankton.log.channel_make(
|
||||||
{
|
{
|
||||||
"kind": log_output.kind,
|
"kind": log_output.kind,
|
||||||
"data": log_output.data
|
"data": log_output.data
|
||||||
|
@ -125,7 +221,19 @@ async function main(
|
||||||
);
|
);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
case "expose-conf": {
|
case "conf-schema": {
|
||||||
|
process.stdout.write(
|
||||||
|
JSON.stringify(
|
||||||
|
_zeitbild.conf.schema(),
|
||||||
|
undefined,
|
||||||
|
"\t"
|
||||||
|
)
|
||||||
|
+
|
||||||
|
"\n"
|
||||||
|
);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
case "conf-expose": {
|
||||||
process.stdout.write(
|
process.stdout.write(
|
||||||
JSON.stringify(
|
JSON.stringify(
|
||||||
_zeitbild.conf.get(),
|
_zeitbild.conf.get(),
|
||||||
|
@ -150,6 +258,15 @@ async function main(
|
||||||
);
|
);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
case "fill": {
|
||||||
|
await data_init(
|
||||||
|
lib_plankton.json.decode(
|
||||||
|
await lib_plankton.file.read(args.data_path)
|
||||||
|
)
|
||||||
|
);
|
||||||
|
process.stdout.write("-- done\n");
|
||||||
|
break;
|
||||||
|
}
|
||||||
case "serve": {
|
case "serve": {
|
||||||
// prepare database
|
// prepare database
|
||||||
await _zeitbild.database.check();
|
await _zeitbild.database.check();
|
||||||
|
@ -184,6 +301,8 @@ async function main(
|
||||||
}
|
}
|
||||||
);
|
);
|
||||||
|
|
||||||
|
await _zeitbild.auth.init();
|
||||||
|
|
||||||
const rest_subject : lib_plankton.rest.type_rest = _zeitbild.api.make();
|
const rest_subject : lib_plankton.rest.type_rest = _zeitbild.api.make();
|
||||||
const server : lib_plankton.server.type_subject = lib_plankton.server.make(
|
const server : lib_plankton.server.type_subject = lib_plankton.server.make(
|
||||||
async (input, metadata) => {
|
async (input, metadata) => {
|
||||||
|
@ -219,9 +338,12 @@ async function main(
|
||||||
(
|
(
|
||||||
main(process.argv.slice(2))
|
main(process.argv.slice(2))
|
||||||
.then(
|
.then(
|
||||||
() => {}
|
() => {
|
||||||
|
}
|
||||||
)
|
)
|
||||||
.catch(
|
.catch(
|
||||||
(error) => {process.stderr.write(String(error) + "\n");}
|
(error) => {
|
||||||
|
process.stderr.write(String(error) + "\n");
|
||||||
|
}
|
||||||
)
|
)
|
||||||
);
|
);
|
||||||
|
|
77
source/repositories/auth_internal.ts
Normal file
77
source/repositories/auth_internal.ts
Normal file
|
@ -0,0 +1,77 @@
|
||||||
|
|
||||||
|
namespace _zeitbild.repository.auth_internal
|
||||||
|
{
|
||||||
|
|
||||||
|
/**
|
||||||
|
*/
|
||||||
|
var _chest : (
|
||||||
|
null
|
||||||
|
|
|
||||||
|
lib_plankton.storage.type_chest<
|
||||||
|
Array<string>,
|
||||||
|
Record<string, any>,
|
||||||
|
lib_plankton.database.type_description_create_table,
|
||||||
|
lib_plankton.storage.sql_table_common.type_sql_table_common_search_term,
|
||||||
|
Record<string, any>
|
||||||
|
>
|
||||||
|
) = null;
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
*/
|
||||||
|
function get_chest(
|
||||||
|
) : lib_plankton.storage.type_chest<
|
||||||
|
Array<string>,
|
||||||
|
Record<string, any>,
|
||||||
|
lib_plankton.database.type_description_create_table,
|
||||||
|
lib_plankton.storage.sql_table_common.type_sql_table_common_search_term,
|
||||||
|
Record<string, any>
|
||||||
|
>
|
||||||
|
{
|
||||||
|
if (_chest === null) {
|
||||||
|
_chest = lib_plankton.storage.sql_table_common.chest(
|
||||||
|
{
|
||||||
|
"database_implementation": _zeitbild.database.get_implementation(),
|
||||||
|
"table_name": "auth_internal",
|
||||||
|
"key_names": ["name"],
|
||||||
|
}
|
||||||
|
);
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
// do nothing
|
||||||
|
}
|
||||||
|
return _chest;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
*/
|
||||||
|
export function read(
|
||||||
|
name : string
|
||||||
|
) : Promise<string>
|
||||||
|
{
|
||||||
|
return (
|
||||||
|
get_chest().read([name])
|
||||||
|
.then(
|
||||||
|
(row) => Promise.resolve<string>(row["password_image"])
|
||||||
|
)
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
*/
|
||||||
|
export function write(
|
||||||
|
name : string,
|
||||||
|
password_image : string
|
||||||
|
) : Promise<void>
|
||||||
|
{
|
||||||
|
return (
|
||||||
|
get_chest().write([name], {"password_image": password_image})
|
||||||
|
.then(
|
||||||
|
() => Promise.resolve<void>(undefined)
|
||||||
|
)
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
|
@ -210,6 +210,92 @@ namespace _zeitbild.repository.resource
|
||||||
*/
|
*/
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
*/
|
||||||
|
function encode_event(
|
||||||
|
event : _zeitbild.type.event_object,
|
||||||
|
local_resource_id : int
|
||||||
|
) : Record<string, any>
|
||||||
|
{
|
||||||
|
/*
|
||||||
|
const decode_datetime : ((datetime_raw : string) => _zeitbild.helpers.type_datetime) = ((datetime_raw) => {
|
||||||
|
const parts : Array<string> = datetime_raw.split("|");
|
||||||
|
const timezone_shift : int = parseInt(parts[0]);
|
||||||
|
if (parts[1].length <= 10) {
|
||||||
|
return {
|
||||||
|
"timezone_shift": timezone_shift,
|
||||||
|
"date": {
|
||||||
|
"year": parseInt(parts[1].slice(0, 4)),
|
||||||
|
"month": parseInt(parts[1].slice(5, 7)),
|
||||||
|
"day": parseInt(parts[1].slice(8, 10)),
|
||||||
|
},
|
||||||
|
"time": null
|
||||||
|
};
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
return {
|
||||||
|
"timezone_shift": timezone_shift,
|
||||||
|
"date": {
|
||||||
|
"year": parseInt(parts[1].slice(0, 4)),
|
||||||
|
"month": parseInt(parts[1].slice(5, 7)),
|
||||||
|
"day": parseInt(parts[1].slice(8, 10)),
|
||||||
|
},
|
||||||
|
"time": {
|
||||||
|
"hour": parseInt(parts[1].slice(11, 13)),
|
||||||
|
"minute": parseInt(parts[1].slice(14, 16)),
|
||||||
|
"second": parseInt(parts[1].slice(17, 19)),
|
||||||
|
}
|
||||||
|
};
|
||||||
|
}
|
||||||
|
});
|
||||||
|
*/
|
||||||
|
const encode_datetime : ((datetime : _zeitbild.helpers.type_datetime) => string) = ((datetime) => {
|
||||||
|
return lib_plankton.string.coin(
|
||||||
|
"{{timezone_shift}}|{{date}}{{macro_time}}",
|
||||||
|
{
|
||||||
|
"timezone_shift": datetime.timezone_shift.toFixed(0).padStart(2, "0"),
|
||||||
|
"date": lib_plankton.string.coin(
|
||||||
|
"{{year}}-{{month}}-{{day}}",
|
||||||
|
{
|
||||||
|
"year": datetime.date.year.toFixed(0).padStart(4, "0"),
|
||||||
|
"month": datetime.date.month.toFixed(0).padStart(2, "0"),
|
||||||
|
"day": datetime.date.day.toFixed(0).padStart(2, "0"),
|
||||||
|
}
|
||||||
|
),
|
||||||
|
"macro_time": (
|
||||||
|
(datetime.time === null)
|
||||||
|
?
|
||||||
|
""
|
||||||
|
:
|
||||||
|
lib_plankton.string.coin(
|
||||||
|
"T{{hour}}:{{minute}}:{{second}}",
|
||||||
|
{
|
||||||
|
"hour": datetime.time.hour.toFixed(0).padStart(2, "0"),
|
||||||
|
"minute": datetime.time.minute.toFixed(0).padStart(2, "0"),
|
||||||
|
"second": datetime.time.second.toFixed(0).padStart(2, "0"),
|
||||||
|
}
|
||||||
|
)
|
||||||
|
),
|
||||||
|
}
|
||||||
|
);
|
||||||
|
});
|
||||||
|
return {
|
||||||
|
"local_resource_id": local_resource_id,
|
||||||
|
"name": event.name,
|
||||||
|
"begin": encode_datetime(event.begin),
|
||||||
|
"end": (
|
||||||
|
(event.end === null)
|
||||||
|
?
|
||||||
|
null
|
||||||
|
:
|
||||||
|
encode_datetime(event.end)
|
||||||
|
),
|
||||||
|
"location": event.location,
|
||||||
|
"description": event.description,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
*/
|
*/
|
||||||
function decode_event(
|
function decode_event(
|
||||||
|
@ -311,4 +397,58 @@ namespace _zeitbild.repository.resource
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
*/
|
||||||
|
export async function create(
|
||||||
|
resource_object : _zeitbild.type.resource_object
|
||||||
|
) : Promise<_zeitbild.type.resource_id>
|
||||||
|
{
|
||||||
|
switch (resource_object.kind) {
|
||||||
|
case "local": {
|
||||||
|
const local_resource_id : int = await get_local_resource_core_store().create(
|
||||||
|
{
|
||||||
|
"_dummy": null,
|
||||||
|
}
|
||||||
|
);
|
||||||
|
for await (const event of resource_object.data.events) {
|
||||||
|
get_local_resource_event_store().create(
|
||||||
|
encode_event(
|
||||||
|
event,
|
||||||
|
local_resource_id
|
||||||
|
)
|
||||||
|
)
|
||||||
|
}
|
||||||
|
const resource_id : _zeitbild.type.resource_id = await get_resource_core_store().create(
|
||||||
|
{
|
||||||
|
"kind": "local",
|
||||||
|
"sub_id": local_resource_id,
|
||||||
|
}
|
||||||
|
);
|
||||||
|
return Promise.resolve<_zeitbild.type.resource_id>(resource_id);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
case "caldav": {
|
||||||
|
const caldav_resource_id : int = await get_caldav_resource_store().create(
|
||||||
|
{
|
||||||
|
"url": resource_object.data.url,
|
||||||
|
"read_only": resource_object.data.read_only,
|
||||||
|
}
|
||||||
|
);
|
||||||
|
const resource_id : _zeitbild.type.resource_id = await get_local_resource_core_store().create(
|
||||||
|
{
|
||||||
|
"kind": "caldav",
|
||||||
|
"sub_id": caldav_resource_id,
|
||||||
|
}
|
||||||
|
);
|
||||||
|
return Promise.resolve<_zeitbild.type.resource_id>(resource_id);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
default: {
|
||||||
|
throw (new Error("not implemended"));
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
119
source/repositories/user.ts
Normal file
119
source/repositories/user.ts
Normal file
|
@ -0,0 +1,119 @@
|
||||||
|
|
||||||
|
namespace _zeitbild.repository.user
|
||||||
|
{
|
||||||
|
|
||||||
|
/**
|
||||||
|
*/
|
||||||
|
var _store : (
|
||||||
|
null
|
||||||
|
|
|
||||||
|
lib_plankton.storage.type_store<
|
||||||
|
_zeitbild.type.user_id,
|
||||||
|
Record<string, any>,
|
||||||
|
{},
|
||||||
|
lib_plankton.storage.type_sql_table_autokey_search_term,
|
||||||
|
Record<string, any>
|
||||||
|
>
|
||||||
|
) = null;
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
*/
|
||||||
|
function get_store(
|
||||||
|
) : lib_plankton.storage.type_store<
|
||||||
|
_zeitbild.type.user_id,
|
||||||
|
Record<string, any>,
|
||||||
|
{},
|
||||||
|
lib_plankton.storage.type_sql_table_autokey_search_term,
|
||||||
|
Record<string, any>
|
||||||
|
>
|
||||||
|
{
|
||||||
|
if (_store === null) {
|
||||||
|
_store = lib_plankton.storage.sql_table_autokey_store(
|
||||||
|
{
|
||||||
|
"database_implementation": _zeitbild.database.get_implementation(),
|
||||||
|
"table_name": "users",
|
||||||
|
"key_name": "id",
|
||||||
|
}
|
||||||
|
);
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
// do nothing
|
||||||
|
}
|
||||||
|
return _store;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
*/
|
||||||
|
function encode(
|
||||||
|
user_object : _zeitbild.type.user_object
|
||||||
|
) : Record<string, any>
|
||||||
|
{
|
||||||
|
return {
|
||||||
|
"name": user_object.name,
|
||||||
|
"email_address": user_object.email_address,
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
*/
|
||||||
|
function decode(
|
||||||
|
row : Record<string, any>
|
||||||
|
) : _zeitbild.type.user_object
|
||||||
|
{
|
||||||
|
return {
|
||||||
|
"name": row["name"],
|
||||||
|
"email_address": row["email_address"],
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
*/
|
||||||
|
export async function read(
|
||||||
|
user_id : _zeitbild.type.user_id
|
||||||
|
) : Promise<_zeitbild.type.user_object>
|
||||||
|
{
|
||||||
|
const row : Record<string, any> = await get_store().read(user_id);
|
||||||
|
const user_object : _zeitbild.type.user_object = decode(row);
|
||||||
|
return Promise.resolve<_zeitbild.type.user_object>(user_object);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
*/
|
||||||
|
export async function create(
|
||||||
|
user_object : _zeitbild.type.user_object
|
||||||
|
) : Promise<_zeitbild.type.user_id>
|
||||||
|
{
|
||||||
|
const row : Record<string, any> = encode(user_object);
|
||||||
|
const user_id : _zeitbild.type.user_id = await get_store().create(row);
|
||||||
|
return Promise.resolve<_zeitbild.type.user_id>(user_id);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
*/
|
||||||
|
export async function identify(
|
||||||
|
name : string
|
||||||
|
) : Promise<_zeitbild.type.user_id>
|
||||||
|
{
|
||||||
|
const hits : Array<{key : _zeitbild.type.user_id; preview : any;}> = await get_store().search(
|
||||||
|
{
|
||||||
|
"expression": "(name = $name)",
|
||||||
|
"arguments": {
|
||||||
|
"name": name,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
);
|
||||||
|
if (hits.length <= 0) {
|
||||||
|
return Promise.reject<_zeitbild.type.user_id>(new Error("not found"));
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
return Promise.resolve<_zeitbild.type.user_id>(hits[0].key);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
40
source/services/auth_internal.ts
Normal file
40
source/services/auth_internal.ts
Normal file
|
@ -0,0 +1,40 @@
|
||||||
|
|
||||||
|
namespace _zeitbild.service.auth_internal
|
||||||
|
{
|
||||||
|
|
||||||
|
/**
|
||||||
|
*/
|
||||||
|
export function set(
|
||||||
|
name : string,
|
||||||
|
password : string
|
||||||
|
) : Promise<void>
|
||||||
|
{
|
||||||
|
return (
|
||||||
|
lib_plankton.bcrypt.compute(password)
|
||||||
|
.then<void>(
|
||||||
|
(password_image) => _zeitbild.repository.auth_internal.write(name, password_image)
|
||||||
|
)
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
*/
|
||||||
|
export async function check(
|
||||||
|
name : string,
|
||||||
|
password : string
|
||||||
|
) : Promise<boolean>
|
||||||
|
{
|
||||||
|
try {
|
||||||
|
const password_image : string = await _zeitbild.repository.auth_internal.read(name);
|
||||||
|
return lib_plankton.bcrypt.compare(
|
||||||
|
password_image,
|
||||||
|
password
|
||||||
|
);
|
||||||
|
}
|
||||||
|
catch (error) {
|
||||||
|
return Promise.resolve<boolean>(false);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
|
@ -2,6 +2,16 @@
|
||||||
namespace _zeitbild.service.calendar
|
namespace _zeitbild.service.calendar
|
||||||
{
|
{
|
||||||
|
|
||||||
|
/**
|
||||||
|
*/
|
||||||
|
export function add(
|
||||||
|
calendar_object : _zeitbild.type.calendar_object
|
||||||
|
) : Promise<_zeitbild.type.calendar_id>
|
||||||
|
{
|
||||||
|
return _zeitbild.repository.calendar.create(calendar_object);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
*/
|
*/
|
||||||
export async function list(
|
export async function list(
|
||||||
|
|
14
source/services/resource.ts
Normal file
14
source/services/resource.ts
Normal file
|
@ -0,0 +1,14 @@
|
||||||
|
|
||||||
|
namespace _zeitbild.service.resource
|
||||||
|
{
|
||||||
|
|
||||||
|
/**
|
||||||
|
*/
|
||||||
|
export function add(
|
||||||
|
resource_object : _zeitbild.type.resource_object
|
||||||
|
) : Promise<_zeitbild.type.resource_id>
|
||||||
|
{
|
||||||
|
return _zeitbild.repository.resource.create(resource_object);
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
24
source/services/user.ts
Normal file
24
source/services/user.ts
Normal file
|
@ -0,0 +1,24 @@
|
||||||
|
|
||||||
|
namespace _zeitbild.service.user
|
||||||
|
{
|
||||||
|
|
||||||
|
/**
|
||||||
|
*/
|
||||||
|
export function add(
|
||||||
|
user_object : _zeitbild.type.user_object
|
||||||
|
) : Promise<_zeitbild.type.user_id>
|
||||||
|
{
|
||||||
|
return _zeitbild.repository.user.create(user_object);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
*/
|
||||||
|
export function identify(
|
||||||
|
name : string
|
||||||
|
) : Promise<_zeitbild.type.user_id>
|
||||||
|
{
|
||||||
|
return _zeitbild.repository.user.identify(name);
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
|
@ -18,16 +18,32 @@ cmd_tsc := ${dir_tools}/typescript/node_modules/.bin/tsc
|
||||||
## rules
|
## rules
|
||||||
|
|
||||||
.PHONY: default
|
.PHONY: default
|
||||||
default: ${dir_build}/zeitbild
|
default: ${dir_build}/zeitbild node_modules
|
||||||
|
|
||||||
|
.PHONY: node_modules
|
||||||
|
node_modules:
|
||||||
|
@ cd ${dir_build} && npm install sqlite3 bcrypt
|
||||||
|
|
||||||
|
${dir_temp}/conf.ts: \
|
||||||
|
${dir_source}/conf.ts.tpl \
|
||||||
|
${dir_source}/conf.schema.json
|
||||||
|
@ ${cmd_mkdir} $(dir $@)
|
||||||
|
${dir_tools}/coin $@
|
||||||
|
|
||||||
${dir_temp}/zeitbild-unlinked.js: \
|
${dir_temp}/zeitbild-unlinked.js: \
|
||||||
${dir_lib}/plankton/plankton.d.ts \
|
${dir_lib}/plankton/plankton.d.ts \
|
||||||
${dir_source}/helpers.ts \
|
${dir_source}/helpers.ts \
|
||||||
${dir_source}/conf.ts \
|
${dir_source}/conf.ts \
|
||||||
${dir_source}/database.ts \
|
${dir_source}/database.ts \
|
||||||
|
${dir_source}/auth.ts \
|
||||||
${dir_source}/types.ts \
|
${dir_source}/types.ts \
|
||||||
|
${dir_source}/repositories/auth_internal.ts \
|
||||||
|
${dir_source}/repositories/user.ts \
|
||||||
${dir_source}/repositories/resource.ts \
|
${dir_source}/repositories/resource.ts \
|
||||||
${dir_source}/repositories/calendar.ts \
|
${dir_source}/repositories/calendar.ts \
|
||||||
|
${dir_source}/services/auth_internal.ts \
|
||||||
|
${dir_source}/services/user.ts \
|
||||||
|
${dir_source}/services/resource.ts \
|
||||||
${dir_source}/services/calendar.ts \
|
${dir_source}/services/calendar.ts \
|
||||||
${dir_source}/api/base.ts \
|
${dir_source}/api/base.ts \
|
||||||
${dir_source}/api/actions/meta_ping.ts \
|
${dir_source}/api/actions/meta_ping.ts \
|
||||||
|
|
|
@ -8,21 +8,23 @@ modules=""
|
||||||
modules="${modules} base"
|
modules="${modules} base"
|
||||||
modules="${modules} call"
|
modules="${modules} call"
|
||||||
modules="${modules} log"
|
modules="${modules} log"
|
||||||
|
modules="${modules} conf"
|
||||||
modules="${modules} storage"
|
modules="${modules} storage"
|
||||||
modules="${modules} database"
|
modules="${modules} database"
|
||||||
modules="${modules} session"
|
modules="${modules} session"
|
||||||
modules="${modules} file"
|
modules="${modules} file"
|
||||||
modules="${modules} string"
|
modules="${modules} string"
|
||||||
modules="${modules} structures"
|
|
||||||
modules="${modules} json"
|
modules="${modules} json"
|
||||||
modules="${modules} ical"
|
modules="${modules} ical"
|
||||||
modules="${modules} url"
|
modules="${modules} url"
|
||||||
modules="${modules} http"
|
modules="${modules} http"
|
||||||
modules="${modules} api"
|
modules="${modules} api"
|
||||||
modules="${modules} rest"
|
modules="${modules} rest"
|
||||||
|
modules="${modules} rest"
|
||||||
modules="${modules} server"
|
modules="${modules} server"
|
||||||
modules="${modules} args"
|
modules="${modules} args"
|
||||||
modules="${modules} auth"
|
# modules="${modules} auth"
|
||||||
|
modules="${modules} bcrypt"
|
||||||
|
|
||||||
|
|
||||||
## exec
|
## exec
|
||||||
|
|
Loading…
Add table
Reference in a new issue