✨ Added session-management with a map!
This commit is contained in:
@@ -4,6 +4,8 @@ FROM node:17.8-bullseye as builder
|
||||
# ENV API_URL=http://api:80
|
||||
ENV API_URL=https://mawoka.eu
|
||||
ENV REDIS_URL=CHANGE_ME
|
||||
ENV VITE_MAPBOX_ACCESS_TOKEN=pk.eyJ1IjoibWF3b2thIiwiYSI6ImNsMjBob3d4ZjBhcGszYnE0bWp4aXB1ZW4ifQ.IByxV1qeIuEWpHCWsuB88A
|
||||
# This Mpbox-token is restricted to the following urls: classquiz.de, classquiz.mawoka.eu, test.com
|
||||
ENV VITE_HCAPTCHA=ee81b2a1-acf3-4d20-b2a4-a7ea94c7eba5
|
||||
ENV VITE_SENTRY=https://4981de1f72f24fd7b5e21b8913b93a02@o661934.ingest.sentry.io/6254641
|
||||
# change working directory
|
||||
|
||||
@@ -14,6 +14,7 @@
|
||||
"translations-scan": "i18next-scanner --config i18next-scanner.config.engine.cjs src/**/*.svelte"
|
||||
},
|
||||
"devDependencies": {
|
||||
"@beyonk/svelte-mapbox": "^8.1.4",
|
||||
"@felte/validator-yup": "^1.0.3",
|
||||
"@fontsource/marck-script": "^4.5.5",
|
||||
"@sentry/browser": "^6.19.6",
|
||||
@@ -25,6 +26,7 @@
|
||||
"@types/cookie": "^0.4.1",
|
||||
"@types/js-cookie": "^3.0.1",
|
||||
"@types/luxon": "^2.3.1",
|
||||
"@types/ua-parser-js": "^0.7.36",
|
||||
"@types/yup": "^0.29.13",
|
||||
"@typescript-eslint/eslint-plugin": "^5.19.0",
|
||||
"@typescript-eslint/parser": "^5.19.0",
|
||||
@@ -39,7 +41,9 @@
|
||||
"i18next-browser-languagedetector": "^6.1.4",
|
||||
"ioredis": "^5.0.4",
|
||||
"js-cookie": "^3.0.1",
|
||||
"leaflet": "^1.7.1",
|
||||
"luxon": "^2.3.1",
|
||||
"mapbox-gl": "^2.8.1",
|
||||
"node-fetch": "^3.2.3",
|
||||
"postcss": "^8.4.12",
|
||||
"postcss-load-config": "^3.1.4",
|
||||
@@ -49,6 +53,7 @@
|
||||
"socket.io-client": "^4.4.1",
|
||||
"svelte": "^3.47.0",
|
||||
"svelte-check": "^2.6.0",
|
||||
"svelte-leafletjs": "^0.8.2",
|
||||
"svelte-preprocess": "^4.10.5",
|
||||
"svelte-tippy": "^1.3.2",
|
||||
"swiper": "^8.1.0",
|
||||
@@ -56,6 +61,8 @@
|
||||
"tippy.js": "^6.3.7",
|
||||
"tslib": "^2.3.1",
|
||||
"typescript": "~4.6",
|
||||
"ua-parser-js": "^1.0.2",
|
||||
"vite-plugin-iso-import": "^0.1.3",
|
||||
"yup": "^0.32.11"
|
||||
},
|
||||
"type": "module",
|
||||
|
||||
Generated
+318
@@ -1,6 +1,7 @@
|
||||
lockfileVersion: 5.3
|
||||
|
||||
specifiers:
|
||||
'@beyonk/svelte-mapbox': ^8.1.4
|
||||
'@felte/validator-yup': ^1.0.3
|
||||
'@fontsource/marck-script': ^4.5.5
|
||||
'@sentry/browser': ^6.19.6
|
||||
@@ -12,6 +13,7 @@ specifiers:
|
||||
'@types/cookie': ^0.4.1
|
||||
'@types/js-cookie': ^3.0.1
|
||||
'@types/luxon': ^2.3.1
|
||||
'@types/ua-parser-js': ^0.7.36
|
||||
'@types/yup': ^0.29.13
|
||||
'@typescript-eslint/eslint-plugin': ^5.19.0
|
||||
'@typescript-eslint/parser': ^5.19.0
|
||||
@@ -27,7 +29,9 @@ specifiers:
|
||||
i18next-browser-languagedetector: ^6.1.4
|
||||
ioredis: ^5.0.4
|
||||
js-cookie: ^3.0.1
|
||||
leaflet: ^1.7.1
|
||||
luxon: ^2.3.1
|
||||
mapbox-gl: ^2.8.1
|
||||
node-fetch: ^3.2.3
|
||||
postcss: ^8.4.12
|
||||
postcss-load-config: ^3.1.4
|
||||
@@ -37,6 +41,7 @@ specifiers:
|
||||
socket.io-client: ^4.4.1
|
||||
svelte: ^3.47.0
|
||||
svelte-check: ^2.6.0
|
||||
svelte-leafletjs: ^0.8.2
|
||||
svelte-preprocess: ^4.10.5
|
||||
svelte-tippy: ^1.3.2
|
||||
swiper: ^8.1.0
|
||||
@@ -44,12 +49,15 @@ specifiers:
|
||||
tippy.js: ^6.3.7
|
||||
tslib: ^2.3.1
|
||||
typescript: ~4.6
|
||||
ua-parser-js: ^1.0.2
|
||||
vite-plugin-iso-import: ^0.1.3
|
||||
yup: ^0.32.11
|
||||
|
||||
dependencies:
|
||||
i18next: 21.6.16
|
||||
|
||||
devDependencies:
|
||||
'@beyonk/svelte-mapbox': 8.1.4
|
||||
'@felte/validator-yup': 1.0.3_yup@0.32.11
|
||||
'@fontsource/marck-script': 4.5.5
|
||||
'@sentry/browser': 6.19.6
|
||||
@@ -61,6 +69,7 @@ devDependencies:
|
||||
'@types/cookie': 0.4.1
|
||||
'@types/js-cookie': 3.0.1
|
||||
'@types/luxon': 2.3.1
|
||||
'@types/ua-parser-js': 0.7.36
|
||||
'@types/yup': 0.29.13
|
||||
'@typescript-eslint/eslint-plugin': 5.19.0_f34adc8488d2e4f014fe61432d70cbf2
|
||||
'@typescript-eslint/parser': 5.19.0_eslint@8.13.0+typescript@4.6.3
|
||||
@@ -75,7 +84,9 @@ devDependencies:
|
||||
i18next-browser-languagedetector: 6.1.4
|
||||
ioredis: 5.0.4
|
||||
js-cookie: 3.0.1
|
||||
leaflet: 1.7.1
|
||||
luxon: 2.3.1
|
||||
mapbox-gl: 2.8.1
|
||||
node-fetch: 3.2.3
|
||||
postcss: 8.4.12
|
||||
postcss-load-config: 3.1.4_postcss@8.4.12
|
||||
@@ -85,6 +96,7 @@ devDependencies:
|
||||
socket.io-client: 4.4.1
|
||||
svelte: 3.47.0
|
||||
svelte-check: 2.6.0_1b6d41eb44819e98e49be8cacdc96c52
|
||||
svelte-leafletjs: 0.8.2
|
||||
svelte-preprocess: 4.10.5_f6bc70e70cf1a2fde5bc22fd7000ea23
|
||||
svelte-tippy: 1.3.2
|
||||
swiper: 8.1.0
|
||||
@@ -92,6 +104,8 @@ devDependencies:
|
||||
tippy.js: 6.3.7
|
||||
tslib: 2.3.1
|
||||
typescript: 4.6.3
|
||||
ua-parser-js: 1.0.2
|
||||
vite-plugin-iso-import: 0.1.3
|
||||
yup: 0.32.11
|
||||
|
||||
packages:
|
||||
@@ -104,6 +118,13 @@ packages:
|
||||
dependencies:
|
||||
regenerator-runtime: 0.13.9
|
||||
|
||||
/@beyonk/svelte-mapbox/8.1.4:
|
||||
resolution:
|
||||
{
|
||||
integrity: sha512-H7c5i+iWReb3try5Vk2rIeIXJ6BqmO3eb8OeBntrdKAiKEA0ye7n5t4C13Ne4vvMrfqqzyHuV6kGsM0y/g+lJg==
|
||||
}
|
||||
dev: true
|
||||
|
||||
/@eslint/eslintrc/1.2.1:
|
||||
resolution:
|
||||
{
|
||||
@@ -197,6 +218,68 @@ packages:
|
||||
}
|
||||
dev: true
|
||||
|
||||
/@mapbox/geojson-rewind/0.5.1:
|
||||
resolution:
|
||||
{
|
||||
integrity: sha512-eL7fMmfTBKjrb+VFHXCGv9Ot0zc3C0U+CwXo1IrP+EPwDczLoXv34Tgq3y+2mPSFNVUXgU42ILWJTC7145KPTA==
|
||||
}
|
||||
hasBin: true
|
||||
dependencies:
|
||||
get-stream: 6.0.1
|
||||
minimist: 1.2.6
|
||||
dev: true
|
||||
|
||||
/@mapbox/geojson-types/1.0.2:
|
||||
resolution:
|
||||
{
|
||||
integrity: sha512-e9EBqHHv3EORHrSfbR9DqecPNn+AmuAoQxV6aL8Xu30bJMJR1o8PZLZzpk1Wq7/NfCbuhmakHTPYRhoqLsXRnw==
|
||||
}
|
||||
dev: true
|
||||
|
||||
/@mapbox/jsonlint-lines-primitives/2.0.2:
|
||||
resolution: { integrity: sha1-zlblOfg1UrWNENZy6k1vya3HsjQ= }
|
||||
engines: { node: '>= 0.6' }
|
||||
dev: true
|
||||
|
||||
/@mapbox/mapbox-gl-supported/2.0.1:
|
||||
resolution:
|
||||
{
|
||||
integrity: sha512-HP6XvfNIzfoMVfyGjBckjiAOQK9WfX0ywdLubuPMPv+Vqf5fj0uCbgBQYpiqcWZT6cbyyRnTSXDheT1ugvF6UQ==
|
||||
}
|
||||
dev: true
|
||||
|
||||
/@mapbox/point-geometry/0.1.0:
|
||||
resolution: { integrity: sha1-ioP5M1x4YO/6Lu7KJUMyqgru2PI= }
|
||||
dev: true
|
||||
|
||||
/@mapbox/tiny-sdf/2.0.5:
|
||||
resolution:
|
||||
{
|
||||
integrity: sha512-OhXt2lS//WpLdkqrzo/KwB7SRD8AiNTFFzuo9n14IBupzIMa67yGItcK7I2W9D8Ghpa4T04Sw9FWsKCJG50Bxw==
|
||||
}
|
||||
dev: true
|
||||
|
||||
/@mapbox/unitbezier/0.0.0:
|
||||
resolution: { integrity: sha1-FWUb1VOme4WB+zmIEMmK2Go0Uk4= }
|
||||
dev: true
|
||||
|
||||
/@mapbox/vector-tile/1.3.1:
|
||||
resolution:
|
||||
{
|
||||
integrity: sha512-MCEddb8u44/xfQ3oD+Srl/tNcQoqTw3goGk2oLsrFxOTc3dUp+kAnby3PvAeeBYSMSjSPD1nd1AJA6W49WnoUw==
|
||||
}
|
||||
dependencies:
|
||||
'@mapbox/point-geometry': 0.1.0
|
||||
dev: true
|
||||
|
||||
/@mapbox/whoots-js/3.1.0:
|
||||
resolution:
|
||||
{
|
||||
integrity: sha512-Es6WcD0nO5l+2BOQS4uLfNPYQaNDfbot3X1XUoloz+x0mPDS3eeORZJl06HXjwBG1fOGwCRnzK88LMdxKRrd6Q==
|
||||
}
|
||||
engines: { node: '>=6.0.0' }
|
||||
dev: true
|
||||
|
||||
/@nodelib/fs.scandir/2.1.5:
|
||||
resolution:
|
||||
{
|
||||
@@ -521,6 +604,13 @@ packages:
|
||||
'@types/node': 17.0.23
|
||||
dev: true
|
||||
|
||||
/@types/ua-parser-js/0.7.36:
|
||||
resolution:
|
||||
{
|
||||
integrity: sha512-N1rW+njavs70y2cApeIw1vLMYXRwfBy+7trgavGuuTfOd7j1Yh7QTRc/yqsPl6ncokt72ZXuxEU0PiCp9bSwNQ==
|
||||
}
|
||||
dev: true
|
||||
|
||||
/@types/yup/0.29.13:
|
||||
resolution:
|
||||
{
|
||||
@@ -808,6 +898,17 @@ packages:
|
||||
postcss-value-parser: 4.2.0
|
||||
dev: true
|
||||
|
||||
/axios/0.25.0:
|
||||
resolution:
|
||||
{
|
||||
integrity: sha512-cD8FOb0tRH3uuEe6+evtAbgJtfxr7ly3fQjYcMcuPlgkwVS9xboaVIpcDV+cYQe+yGykgwZCs1pzjntcGa6l5g==
|
||||
}
|
||||
dependencies:
|
||||
follow-redirects: 1.14.9
|
||||
transitivePeerDependencies:
|
||||
- debug
|
||||
dev: true
|
||||
|
||||
/backo2/1.0.2:
|
||||
resolution: { integrity: sha1-MasayLEpNjRj41s+u2n038+6eUc= }
|
||||
dev: true
|
||||
@@ -1042,6 +1143,10 @@ packages:
|
||||
engines: { node: '>= 6' }
|
||||
dev: true
|
||||
|
||||
/csscolorparser/1.0.3:
|
||||
resolution: { integrity: sha1-s085HupNqPPpgjHizNjfnAQfFxs= }
|
||||
dev: true
|
||||
|
||||
/cssesc/3.0.0:
|
||||
resolution:
|
||||
{
|
||||
@@ -1274,6 +1379,13 @@ packages:
|
||||
domhandler: 4.3.1
|
||||
dev: true
|
||||
|
||||
/earcut/2.2.3:
|
||||
resolution:
|
||||
{
|
||||
integrity: sha512-iRDI1QeCQIhMCZk48DRDMVgQSSBDmbzzNhnxIo+pwx3swkfjMh6vh0nWLq1NdvGHLKH6wIrAM3vQWeTj6qeoug==
|
||||
}
|
||||
dev: true
|
||||
|
||||
/electron-to-chromium/1.4.107:
|
||||
resolution:
|
||||
{
|
||||
@@ -1319,6 +1431,13 @@ packages:
|
||||
}
|
||||
dev: true
|
||||
|
||||
/es-module-lexer/0.9.3:
|
||||
resolution:
|
||||
{
|
||||
integrity: sha512-1HQ2M2sPtxwnvOvT1ZClHyQDiggdNjURWpY2we6aMKCQiUVxTmVs2UYPLIrD84sS+kMdUwfBSylbJPwNnBrnHQ==
|
||||
}
|
||||
dev: true
|
||||
|
||||
/es6-promise/3.3.1:
|
||||
resolution: { integrity: sha1-oIzd6EzNvzTQJ6FFG8kdS80ophM= }
|
||||
dev: true
|
||||
@@ -1900,6 +2019,19 @@ packages:
|
||||
}
|
||||
dev: true
|
||||
|
||||
/follow-redirects/1.14.9:
|
||||
resolution:
|
||||
{
|
||||
integrity: sha512-MQDfihBQYMcyy5dhRDJUHcw7lb2Pv/TuE6xP1vyraLukNDHKbDxDNaOE3NbCAdKQApno+GPRyo1YAp89yCjK4w==
|
||||
}
|
||||
engines: { node: '>=4.0' }
|
||||
peerDependencies:
|
||||
debug: '*'
|
||||
peerDependenciesMeta:
|
||||
debug:
|
||||
optional: true
|
||||
dev: true
|
||||
|
||||
/formdata-polyfill/4.0.10:
|
||||
resolution:
|
||||
{
|
||||
@@ -1943,6 +2075,28 @@ packages:
|
||||
resolution: { integrity: sha1-GwqzvVU7Kg1jmdKcDj6gslIHgyc= }
|
||||
dev: true
|
||||
|
||||
/geojson-vt/3.2.1:
|
||||
resolution:
|
||||
{
|
||||
integrity: sha512-EvGQQi/zPrDA6zr6BnJD/YhwAkBP8nnJ9emh3EnHQKVMfg/MRVtPbMYdgVy/IaEmn4UfagD2a6fafPDL5hbtwg==
|
||||
}
|
||||
dev: true
|
||||
|
||||
/get-stream/6.0.1:
|
||||
resolution:
|
||||
{
|
||||
integrity: sha512-ts6Wi+2j3jQjqi70w5AlN8DFnkSwC+MqmxEzdEALB2qXZYV3X/b1CTfgPLGJNMeAWxdPfU8FO1ms3NUfaHCPYg==
|
||||
}
|
||||
engines: { node: '>=10' }
|
||||
dev: true
|
||||
|
||||
/gl-matrix/3.4.3:
|
||||
resolution:
|
||||
{
|
||||
integrity: sha512-wcCp8vu8FT22BnvKVPjXa/ICBWRq/zjFfdofZy1WSpQZpphblv12/bOQLBC1rMM7SGOFS9ltVmKOHil5+Ml7gA==
|
||||
}
|
||||
dev: true
|
||||
|
||||
/glob-parent/5.1.2:
|
||||
resolution:
|
||||
{
|
||||
@@ -2023,6 +2177,13 @@ packages:
|
||||
}
|
||||
dev: true
|
||||
|
||||
/grid-index/1.1.0:
|
||||
resolution:
|
||||
{
|
||||
integrity: sha512-HZRwumpOGUrHyxO5bqKZL0B0GlUpwtCAzZ42sgxUPniu33R1LSFH5yrIcBCHjkctCAh3mtWKcKd9J4vDDdeVHA==
|
||||
}
|
||||
dev: true
|
||||
|
||||
/has-cors/1.1.0:
|
||||
resolution: { integrity: sha1-XkdHk/fqmEPRu5nCPu9J/xJv/zk= }
|
||||
dev: true
|
||||
@@ -2071,6 +2232,13 @@ packages:
|
||||
'@babel/runtime': 7.17.9
|
||||
dev: false
|
||||
|
||||
/ieee754/1.2.1:
|
||||
resolution:
|
||||
{
|
||||
integrity: sha512-dcyqhDvX1C46lXZcVqCpK+FtMRQVdIMN6/Df5js2zouUsqG7I6sFxitIC+7KYK29KdXOLHdu9zL4sFnoVQnqaA==
|
||||
}
|
||||
dev: true
|
||||
|
||||
/ignore/5.2.0:
|
||||
resolution:
|
||||
{
|
||||
@@ -2211,6 +2379,13 @@ packages:
|
||||
resolution: { integrity: sha1-nbe1lJatPzz+8wp1FC0tkwrXJlE= }
|
||||
dev: true
|
||||
|
||||
/kdbush/3.0.0:
|
||||
resolution:
|
||||
{
|
||||
integrity: sha512-hRkd6/XW4HTsA9vjVpY9tuXJYLSlelnkTmVFu4M9/7MIYQtFcHpbugAU7UbOfjOiVSVYl2fqgBuJ32JUmRo5Ew==
|
||||
}
|
||||
dev: true
|
||||
|
||||
/kleur/4.1.4:
|
||||
resolution:
|
||||
{
|
||||
@@ -2219,6 +2394,13 @@ packages:
|
||||
engines: { node: '>=6' }
|
||||
dev: true
|
||||
|
||||
/leaflet/1.7.1:
|
||||
resolution:
|
||||
{
|
||||
integrity: sha512-/xwPEBidtg69Q3HlqPdU3DnrXQOvQU/CCHA1tcDQVzOwm91YMYaILjNp7L4Eaw5Z4sOYdbBz6koWyibppd8Zqw==
|
||||
}
|
||||
dev: true
|
||||
|
||||
/levn/0.4.1:
|
||||
resolution:
|
||||
{
|
||||
@@ -2320,6 +2502,37 @@ packages:
|
||||
sourcemap-codec: 1.4.8
|
||||
dev: true
|
||||
|
||||
/mapbox-gl/2.8.1:
|
||||
resolution:
|
||||
{
|
||||
integrity: sha512-AmttsfvuWonyuOu7HcwM6Ok738A0yVYx5h3tjCAFrAsivY8SiCvF/stK2CXhSw2/6/BbZ3qe/S03J7GvisNskA==
|
||||
}
|
||||
dependencies:
|
||||
'@mapbox/geojson-rewind': 0.5.1
|
||||
'@mapbox/geojson-types': 1.0.2
|
||||
'@mapbox/jsonlint-lines-primitives': 2.0.2
|
||||
'@mapbox/mapbox-gl-supported': 2.0.1
|
||||
'@mapbox/point-geometry': 0.1.0
|
||||
'@mapbox/tiny-sdf': 2.0.5
|
||||
'@mapbox/unitbezier': 0.0.0
|
||||
'@mapbox/vector-tile': 1.3.1
|
||||
'@mapbox/whoots-js': 3.1.0
|
||||
csscolorparser: 1.0.3
|
||||
earcut: 2.2.3
|
||||
geojson-vt: 3.2.1
|
||||
gl-matrix: 3.4.3
|
||||
grid-index: 1.1.0
|
||||
minimist: 1.2.6
|
||||
murmurhash-js: 1.0.0
|
||||
pbf: 3.2.1
|
||||
potpack: 1.0.2
|
||||
quickselect: 2.0.0
|
||||
rw: 1.3.3
|
||||
supercluster: 7.1.5
|
||||
tinyqueue: 2.0.3
|
||||
vt-pbf: 3.1.3
|
||||
dev: true
|
||||
|
||||
/mdn-data/2.0.14:
|
||||
resolution:
|
||||
{
|
||||
@@ -2403,6 +2616,10 @@ packages:
|
||||
}
|
||||
dev: true
|
||||
|
||||
/murmurhash-js/1.0.0:
|
||||
resolution: { integrity: sha1-sGJ44h/Gw3+lMTcysEEry2rhX1E= }
|
||||
dev: true
|
||||
|
||||
/nanoclone/0.2.1:
|
||||
resolution:
|
||||
{
|
||||
@@ -2561,6 +2778,17 @@ packages:
|
||||
engines: { node: '>=8' }
|
||||
dev: true
|
||||
|
||||
/pbf/3.2.1:
|
||||
resolution:
|
||||
{
|
||||
integrity: sha512-ClrV7pNOn7rtmoQVF4TS1vyU0WhYRnP92fzbfF75jAIwpnzdJXf8iTd4CMEqO4yUenH6NDqLiwjqlh6QgZzgLQ==
|
||||
}
|
||||
hasBin: true
|
||||
dependencies:
|
||||
ieee754: 1.2.1
|
||||
resolve-protobuf-schema: 2.1.0
|
||||
dev: true
|
||||
|
||||
/picocolors/1.0.0:
|
||||
resolution:
|
||||
{
|
||||
@@ -3014,6 +3242,13 @@ packages:
|
||||
source-map-js: 1.0.2
|
||||
dev: true
|
||||
|
||||
/potpack/1.0.2:
|
||||
resolution:
|
||||
{
|
||||
integrity: sha512-choctRBIV9EMT9WGAZHn3V7t0Z2pMQyl0EZE6pFc/6ml3ssw7Dlf/oAOvFwjm1HVsqfQN8GfeFyJ+d8tRzqueQ==
|
||||
}
|
||||
dev: true
|
||||
|
||||
/prelude-ls/1.2.1:
|
||||
resolution:
|
||||
{
|
||||
@@ -3051,6 +3286,13 @@ packages:
|
||||
}
|
||||
dev: true
|
||||
|
||||
/protocol-buffers-schema/3.6.0:
|
||||
resolution:
|
||||
{
|
||||
integrity: sha512-TdDRD+/QNdrCGCE7v8340QyuXd4kIWIgapsE2+n/SaGiSSbomYl4TjHlvIoCWRpE7wFt02EpB35VVA2ImcBVqw==
|
||||
}
|
||||
dev: true
|
||||
|
||||
/punycode/2.1.1:
|
||||
resolution:
|
||||
{
|
||||
@@ -3074,6 +3316,13 @@ packages:
|
||||
engines: { node: '>=10' }
|
||||
dev: true
|
||||
|
||||
/quickselect/2.0.0:
|
||||
resolution:
|
||||
{
|
||||
integrity: sha512-RKJ22hX8mHe3Y6wH/N3wCM6BWtjaxIyyUIkpHOvfFnxdI4yD4tBXEBKSbriGujF6jnSVkJrffuo6vxACiSSxIw==
|
||||
}
|
||||
dev: true
|
||||
|
||||
/readdirp/3.6.0:
|
||||
resolution:
|
||||
{
|
||||
@@ -3126,6 +3375,15 @@ packages:
|
||||
engines: { node: '>=4' }
|
||||
dev: true
|
||||
|
||||
/resolve-protobuf-schema/2.1.0:
|
||||
resolution:
|
||||
{
|
||||
integrity: sha512-kI5ffTiZWmJaS/huM8wZfEMer1eRd7oJQhDuxeCLe3t7N7mX3z94CN0xPxBQxFYQTSNz9T0i+v6inKqSdK8xrQ==
|
||||
}
|
||||
dependencies:
|
||||
protocol-buffers-schema: 3.6.0
|
||||
dev: true
|
||||
|
||||
/resolve/1.22.0:
|
||||
resolution:
|
||||
{
|
||||
@@ -3186,6 +3444,10 @@ packages:
|
||||
queue-microtask: 1.2.3
|
||||
dev: true
|
||||
|
||||
/rw/1.3.3:
|
||||
resolution: { integrity: sha1-P4Yt+pGrdmsUiF700BEkv9oHT7Q= }
|
||||
dev: true
|
||||
|
||||
/sade/1.8.1:
|
||||
resolution:
|
||||
{
|
||||
@@ -3391,6 +3653,15 @@ packages:
|
||||
postcss-selector-parser: 6.0.10
|
||||
dev: true
|
||||
|
||||
/supercluster/7.1.5:
|
||||
resolution:
|
||||
{
|
||||
integrity: sha512-EulshI3pGUM66o6ZdH3ReiFcvHpM3vAigyK+vcxdjpJyEbIIrtbmBdY23mGgnI24uXiGFvrGq9Gkum/8U7vJWg==
|
||||
}
|
||||
dependencies:
|
||||
kdbush: 3.0.0
|
||||
dev: true
|
||||
|
||||
/supports-color/7.2.0:
|
||||
resolution:
|
||||
{
|
||||
@@ -3452,6 +3723,18 @@ packages:
|
||||
svelte: 3.47.0
|
||||
dev: true
|
||||
|
||||
/svelte-leafletjs/0.8.2:
|
||||
resolution:
|
||||
{
|
||||
integrity: sha512-TCywmwL2Dis28xKJacT6vC7OT0+tt40fbHLaavS8r9uItJOWrOM89qyeXrIMP/QbcJI/8OLfNrm6NuE3C0s8Ow==
|
||||
}
|
||||
dependencies:
|
||||
axios: 0.25.0
|
||||
leaflet: 1.7.1
|
||||
transitivePeerDependencies:
|
||||
- debug
|
||||
dev: true
|
||||
|
||||
/svelte-preprocess/4.10.5_f6bc70e70cf1a2fde5bc22fd7000ea23:
|
||||
resolution:
|
||||
{
|
||||
@@ -3602,6 +3885,13 @@ packages:
|
||||
globrex: 0.1.2
|
||||
dev: true
|
||||
|
||||
/tinyqueue/2.0.3:
|
||||
resolution:
|
||||
{
|
||||
integrity: sha512-ppJZNDuKGgxzkHihX8v9v9G5f+18gzaTfrukGrq6ueg0lmH4nqVnA2IPG0AEH3jKEk2GRJCUhDoqpoiw3PHLBA==
|
||||
}
|
||||
dev: true
|
||||
|
||||
/tippy.js/6.3.7:
|
||||
resolution:
|
||||
{
|
||||
@@ -3679,6 +3969,13 @@ packages:
|
||||
hasBin: true
|
||||
dev: true
|
||||
|
||||
/ua-parser-js/1.0.2:
|
||||
resolution:
|
||||
{
|
||||
integrity: sha512-00y/AXhx0/SsnI51fTc0rLRmafiGOM4/O+ny10Ps7f+j/b8p/ZY11ytMgznXkOVo4GQ+KwQG5UQLkLGirsACRg==
|
||||
}
|
||||
dev: true
|
||||
|
||||
/uri-js/4.4.1:
|
||||
resolution:
|
||||
{
|
||||
@@ -3699,6 +3996,16 @@ packages:
|
||||
}
|
||||
dev: true
|
||||
|
||||
/vite-plugin-iso-import/0.1.3:
|
||||
resolution:
|
||||
{
|
||||
integrity: sha512-gMReA6eqfdSKMhNml0B8lT8VGHOY2FxLmq8rIJWStfuoLQItRzHKb2ntB+zNn8VWWeMe5/jtthfSxrzpgjhCMQ==
|
||||
}
|
||||
dependencies:
|
||||
es-module-lexer: 0.9.3
|
||||
magic-string: 0.25.9
|
||||
dev: true
|
||||
|
||||
/vite/2.9.2_sass@1.50.0:
|
||||
resolution:
|
||||
{
|
||||
@@ -3727,6 +4034,17 @@ packages:
|
||||
fsevents: 2.3.2
|
||||
dev: true
|
||||
|
||||
/vt-pbf/3.1.3:
|
||||
resolution:
|
||||
{
|
||||
integrity: sha512-2LzDFzt0mZKZ9IpVF2r69G9bXaP2Q2sArJCmcCgvfTdCCZzSyz4aCLoQyUilu37Ll56tCblIZrXFIjNUpGIlmA==
|
||||
}
|
||||
dependencies:
|
||||
'@mapbox/point-geometry': 0.1.0
|
||||
'@mapbox/vector-tile': 1.3.1
|
||||
pbf: 3.2.1
|
||||
dev: true
|
||||
|
||||
/web-streams-polyfill/3.2.1:
|
||||
resolution:
|
||||
{
|
||||
|
||||
@@ -0,0 +1,17 @@
|
||||
<script lang="ts">
|
||||
import { browser } from '$app/env';
|
||||
import { Map, Marker } from '@beyonk/svelte-mapbox';
|
||||
|
||||
export let lng: number;
|
||||
export let lat: number;
|
||||
export let markerText: string;
|
||||
export let zoom = 12;
|
||||
let center: [number, number];
|
||||
$: center = [lng, lat];
|
||||
</script>
|
||||
|
||||
{#if browser}
|
||||
<Map accessToken={import.meta.env.VITE_MAPBOX_ACCESS_TOKEN} bind:center bind:zoom>
|
||||
<Marker bind:lat bind:lng bind:label={markerText} />
|
||||
</Map>
|
||||
{/if}
|
||||
@@ -0,0 +1,10 @@
|
||||
<svg class="h-8 w-8 animate-spin mx-auto my-20" viewBox="3 3 18 18">
|
||||
<path
|
||||
class="fill-black"
|
||||
d="M12 5C8.13401 5 5 8.13401 5 12C5 15.866 8.13401 19 12 19C15.866 19 19 15.866 19 12C19 8.13401 15.866 5 12 5ZM3 12C3 7.02944 7.02944 3 12 3C16.9706 3 21 7.02944 21 12C21 16.9706 16.9706 21 12 21C7.02944 21 3 16.9706 3 12Z"
|
||||
/>
|
||||
<path
|
||||
class="fill-blue-100"
|
||||
d="M16.9497 7.05015C14.2161 4.31648 9.78392 4.31648 7.05025 7.05015C6.65973 7.44067 6.02656 7.44067 5.63604 7.05015C5.24551 6.65962 5.24551 6.02646 5.63604 5.63593C9.15076 2.12121 14.8492 2.12121 18.364 5.63593C18.7545 6.02646 18.7545 6.65962 18.364 7.05015C17.9734 7.44067 17.3403 7.44067 16.9497 7.05015Z"
|
||||
/>
|
||||
</svg>
|
||||
|
After Width: | Height: | Size: 680 B |
@@ -3,7 +3,7 @@
|
||||
if (!session.authenticated) {
|
||||
return {
|
||||
status: 302,
|
||||
redirect: '/account/login'
|
||||
redirect: '/account/login?returnTo=/account/settings'
|
||||
};
|
||||
}
|
||||
return {
|
||||
@@ -16,9 +16,14 @@
|
||||
|
||||
<script lang="ts">
|
||||
import { getLocalization } from '$lib/i18n';
|
||||
import { DateTime } from 'luxon';
|
||||
import { UAParser } from 'ua-parser-js';
|
||||
import Spinner from '$lib/Spinner.svelte';
|
||||
|
||||
const { t } = getLocalization();
|
||||
|
||||
let showMap = false;
|
||||
|
||||
interface UserAccount {
|
||||
id: string;
|
||||
email: string;
|
||||
@@ -39,6 +44,9 @@
|
||||
newPasswordConfirm: ''
|
||||
};
|
||||
|
||||
let locationData;
|
||||
let this_session;
|
||||
|
||||
let passwordChangeDataValid = false;
|
||||
const checkPasswords = (data: ChangePasswordData): void => {
|
||||
passwordChangeDataValid =
|
||||
@@ -83,19 +91,52 @@
|
||||
window.location.replace('/account/login');
|
||||
}
|
||||
};
|
||||
const formatDate = (date: string): string => {
|
||||
const dt = DateTime.fromISO(date);
|
||||
return dt.toLocaleString(DateTime.DATETIME_MED);
|
||||
};
|
||||
|
||||
const getSessions = async () => {
|
||||
const res = await fetch('/api/v1/users/sessions/list');
|
||||
if (res.status === 200) {
|
||||
const res2 = await fetch('/api/v1/users/session');
|
||||
if (res2.status === 200) {
|
||||
this_session = await res2.json();
|
||||
}
|
||||
return await res.json();
|
||||
} else {
|
||||
window.location.replace('/account/login?returnTo=/account/settings');
|
||||
}
|
||||
return await res.json();
|
||||
};
|
||||
|
||||
const getFormattedUserAgent = (userAgent: string): string => {
|
||||
const parser = new UAParser(userAgent);
|
||||
const result = parser.getResult();
|
||||
return `${result.browser.name} ${result.browser.version} (${result.os.name})`;
|
||||
};
|
||||
|
||||
const checkLocation = async (session_ip: string) => {
|
||||
const res = await fetch(`/api/v1/utils/ip-lookup/${session_ip}`);
|
||||
if (res.status === 200) {
|
||||
locationData = await res.json();
|
||||
console.log(locationData.lat, locationData.lon);
|
||||
showMap = true;
|
||||
}
|
||||
};
|
||||
|
||||
const deleteSession = async (session_id: string) => {
|
||||
const res = await fetch(`/api/v1/users/sessions/${session_id}`, {
|
||||
method: 'DELETE'
|
||||
});
|
||||
if (res.status === 200) {
|
||||
window.location.reload();
|
||||
}
|
||||
};
|
||||
</script>
|
||||
|
||||
{#await getUser()}
|
||||
<svg class="h-8 w-8 animate-spin mx-auto my-20" viewBox="3 3 18 18">
|
||||
<path
|
||||
class="fill-black"
|
||||
d="M12 5C8.13401 5 5 8.13401 5 12C5 15.866 8.13401 19 12 19C15.866 19 19 15.866 19 12C19 8.13401 15.866 5 12 5ZM3 12C3 7.02944 7.02944 3 12 3C16.9706 3 21 7.02944 21 12C21 16.9706 16.9706 21 12 21C7.02944 21 3 16.9706 3 12Z"
|
||||
/>
|
||||
<path
|
||||
class="fill-blue-100"
|
||||
d="M16.9497 7.05015C14.2161 4.31648 9.78392 4.31648 7.05025 7.05015C6.65973 7.44067 6.02656 7.44067 5.63604 7.05015C5.24551 6.65962 5.24551 6.02646 5.63604 5.63593C9.15076 2.12121 14.8492 2.12121 18.364 5.63593C18.7545 6.02646 18.7545 6.65962 18.364 7.05015C17.9734 7.44067 17.3403 7.44067 16.9497 7.05015Z"
|
||||
/>
|
||||
</svg>
|
||||
<Spinner />
|
||||
{:then user}
|
||||
<div class="w-full">
|
||||
<div class="sm:flex space-x-7 md:items-start items-center">
|
||||
@@ -146,3 +187,120 @@
|
||||
</div>
|
||||
</div>
|
||||
{/await}
|
||||
{#await getSessions()}
|
||||
<Spinner />
|
||||
{:then sessions}
|
||||
<table class="min-w-full">
|
||||
<thead class="bg-gray-50 dark:bg-gray-700">
|
||||
<tr>
|
||||
<th
|
||||
scope="col"
|
||||
class="py-3 px-6 text-xs font-medium tracking-wider text-left text-gray-700 uppercase dark:text-gray-400"
|
||||
>
|
||||
{$t('overview_page.created_at')}
|
||||
</th>
|
||||
<th
|
||||
scope="col"
|
||||
class="py-3 px-6 text-xs font-medium tracking-wider text-left text-gray-700 uppercase dark:text-gray-400"
|
||||
>
|
||||
Last seen
|
||||
</th>
|
||||
<th
|
||||
scope="col"
|
||||
class="py-3 px-6 text-xs font-medium tracking-wider text-left text-gray-700 uppercase dark:text-gray-400"
|
||||
>
|
||||
Browser
|
||||
</th>
|
||||
<th
|
||||
scope="col"
|
||||
class="py-3 px-6 text-xs font-medium tracking-wider text-left text-gray-700 uppercase dark:text-gray-400"
|
||||
>
|
||||
Check location
|
||||
</th>
|
||||
<th
|
||||
scope="col"
|
||||
class="py-3 px-6 text-xs font-medium tracking-wider text-left text-gray-700 uppercase dark:text-gray-400"
|
||||
>
|
||||
Delete this session
|
||||
</th>
|
||||
<th
|
||||
scope="col"
|
||||
class="py-3 px-6 text-xs font-medium tracking-wider text-left text-gray-700 uppercase dark:text-gray-400"
|
||||
>
|
||||
This session?
|
||||
</th>
|
||||
</tr>
|
||||
</thead>
|
||||
<tbody>
|
||||
{#each sessions as session}
|
||||
<tr class="bg-white border-b dark:bg-gray-800 dark:border-gray-700">
|
||||
<td
|
||||
class="py-4 px-6 text-sm text-gray-500 whitespace-nowrap dark:text-gray-400"
|
||||
>
|
||||
{formatDate(session.created_at)}
|
||||
</td>
|
||||
<td
|
||||
class="py-4 px-6 text-sm text-gray-500 whitespace-nowrap dark:text-gray-400"
|
||||
>
|
||||
{formatDate(session.last_seen)}
|
||||
</td>
|
||||
<td
|
||||
class="py-4 px-6 text-sm text-gray-500 whitespace-nowrap dark:text-gray-400"
|
||||
>
|
||||
{getFormattedUserAgent(session.user_agent)}
|
||||
</td>
|
||||
<td
|
||||
class="py-4 px-6 text-sm text-gray-500 whitespace-nowrap dark:text-gray-400"
|
||||
>
|
||||
<button
|
||||
on:click={() => {
|
||||
checkLocation(session.ip_address);
|
||||
}}>View</button
|
||||
>
|
||||
</td>
|
||||
<td
|
||||
class="py-4 px-6 text-sm text-gray-500 whitespace-nowrap dark:text-gray-400"
|
||||
>
|
||||
<button
|
||||
on:click={() => {
|
||||
deleteSession(session.id);
|
||||
}}>Delete</button
|
||||
>
|
||||
</td>
|
||||
<td
|
||||
class="py-4 px-6 text-sm text-gray-500 whitespace-nowrap dark:text-gray-400"
|
||||
>
|
||||
{#if session.id === this_session.id}
|
||||
✅
|
||||
{:else}
|
||||
❌
|
||||
{/if}
|
||||
</td>
|
||||
</tr>
|
||||
{/each}
|
||||
</tbody>
|
||||
</table>
|
||||
{/await}
|
||||
|
||||
<div class="w-5/6 h-5/6 z-20 absolute top-10 pt-16 left-28" class:hidden={!showMap}>
|
||||
{#if showMap}
|
||||
{#await import('$lib/Map.svelte')}
|
||||
<Spinner />
|
||||
{:then c}
|
||||
<button
|
||||
on:click={() => {
|
||||
showMap = false;
|
||||
}}
|
||||
class="bg-black text-white rounded-t-lg px-1">Close</button
|
||||
>
|
||||
<div class="w-full h-full">
|
||||
<svelte:component
|
||||
this={c.default}
|
||||
lat={locationData.lat}
|
||||
lng={locationData.lon}
|
||||
markerText={'Somewhere here was this session registered.'}
|
||||
/>
|
||||
</div>
|
||||
{/await}
|
||||
{/if}
|
||||
</div>
|
||||
|
||||
@@ -23,6 +23,7 @@
|
||||
<li><a href="https://redis.io/">Redis</a></li>
|
||||
<li><a href="https://meilisearch.com">Meilisearch</a></li>
|
||||
<li><a href="https://caddyserver.com"><i>(Optional) Caddy</i></a></li>
|
||||
<li>Linux</li>
|
||||
</ul>
|
||||
|
||||
<h4>Frontend</h4>
|
||||
@@ -62,6 +63,11 @@
|
||||
</li>
|
||||
</ul>
|
||||
</li>
|
||||
<li>
|
||||
Add the following line to your <code>/etc/hosts</code>-file, so you can visit ClassQuiz
|
||||
via <code>test.com</code> (Required for the Captcha and Mapbox)
|
||||
<pre><code>127.0.0.1 test.com</code></pre>
|
||||
</li>
|
||||
<li>
|
||||
Set your config up in your .env-file. What you have to set up can you see in the
|
||||
<code>classquiz/config.py</code>-file. The things you have to set are the following:
|
||||
|
||||
@@ -30,6 +30,7 @@
|
||||
</p>
|
||||
|
||||
<h2>Requirements</h2>
|
||||
<h3>Software</h3>
|
||||
<ul>
|
||||
<li><a href="https://docker.com">Docker</a></li>
|
||||
<li><a href="https://git-scm.com/">Git</a></li>
|
||||
@@ -38,6 +39,16 @@
|
||||
<a href="https://upstash.com">Upstash</a>)
|
||||
</li>
|
||||
</ul>
|
||||
<h3>3rd-Parties</h3>
|
||||
<h4>Required</h4>
|
||||
<ul>
|
||||
<li><a href="https://hcaptcha.com">hCaptcha (Captcha)</a></li>
|
||||
<li><a href="https://www.mapbox.com/">Mapbox (Maps)</a></li>
|
||||
</ul>
|
||||
<h4>Optional</h4>
|
||||
<ul>
|
||||
<li><a href="https://sentry.io">Sentry (Error-Logging)</a></li>
|
||||
</ul>
|
||||
|
||||
<h2>Installation</h2>
|
||||
<p>At first, clone the repo:</p>
|
||||
@@ -52,6 +63,15 @@
|
||||
<p>
|
||||
You must set a valid hCaptcha-Sitekey in the <code>frontend/Dockerfile</code>.
|
||||
</p>
|
||||
<p>
|
||||
You'll also have to provide a valid <code>VITE_MAPBOX_ACCESS_TOKEN</code> in
|
||||
<code>frontend/Dockerfile</code>. The provided token only works on the following urls:
|
||||
</p>
|
||||
<ul>
|
||||
<li><code>classquiz.mawoka.eu</code></li>
|
||||
<li><code>classquiz.de</code></li>
|
||||
<li><code><b>test.com</b></code></li>
|
||||
</ul>
|
||||
|
||||
<h2>Configuration</h2>
|
||||
<h3>Storage Provider</h3>
|
||||
@@ -113,6 +133,7 @@ services:
|
||||
MAIL_PORT: "587" # SMTP-Port
|
||||
REDIS: "redis://redis:6379/0?decode_responses=True" # decode_response is important!
|
||||
SECRET_KEY: "ghfvfgjgvjgvbh" # openssl rand -hex 32
|
||||
MEILISEARCH_URL: "http://meilisearch:7700"
|
||||
ACCESS_TOKEN_EXPIRE_MINUTES: 30
|
||||
HCAPTCHA_KEY: "" # Private hCaptcha key for verification
|
||||
STORAGE_BACKEND: "deta" # MUST BE EITHER "deta" OR "local"
|
||||
@@ -151,9 +172,20 @@ services:
|
||||
ports:
|
||||
- "8000:8080" # Adjust the 8000 to your needs
|
||||
|
||||
meilisearch:
|
||||
image: getmeili/meilisearch:latest
|
||||
restart: always
|
||||
environment:
|
||||
MEILI_NO_ANALYTICS: true
|
||||
volumes:
|
||||
- meilisearch-data:/data.ms
|
||||
volumes:
|
||||
data:
|
||||
meilisearch-data:
|
||||
</code></pre>
|
||||
<p>Now build and deploy:</p>
|
||||
<pre><code class="language-bash">docker compose build && docker compose up -d</code></pre>
|
||||
<pre><code>docker compose build && docker compose up -d</code></pre>
|
||||
<p>You'll have to create an index in Meilisearch with the following command:</p>
|
||||
<pre><code>docker compose exec api python3 import_to_meili.py</code></pre>
|
||||
<p><b>Enjoy! ❤️</b></p>
|
||||
</article>
|
||||
|
||||
@@ -1,5 +1,6 @@
|
||||
import adapter from '@sveltejs/adapter-node';
|
||||
import preprocess from 'svelte-preprocess';
|
||||
import { isoImport } from 'vite-plugin-iso-import';
|
||||
|
||||
/** @type {import('@sveltejs/kit').Config} */
|
||||
const config = {
|
||||
@@ -22,7 +23,8 @@ const config = {
|
||||
},
|
||||
build: {
|
||||
sourcemap: true
|
||||
}
|
||||
},
|
||||
plugins: [isoImport()]
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
Reference in New Issue
Block a user