update
Before Width: | Height: | Size: 128 KiB After Width: | Height: | Size: 86 KiB |
Before Width: | Height: | Size: 193 KiB After Width: | Height: | Size: 215 KiB |
Before Width: | Height: | Size: 158 KiB After Width: | Height: | Size: 183 KiB |
@ -19,6 +19,7 @@
|
|||||||
"@types/crypto-js": "^4.1.3",
|
"@types/crypto-js": "^4.1.3",
|
||||||
"@types/jsonwebtoken": "^9.0.4",
|
"@types/jsonwebtoken": "^9.0.4",
|
||||||
"@types/node": "^20.8.10",
|
"@types/node": "^20.8.10",
|
||||||
|
"@types/qrcode": "^1.5.5",
|
||||||
"autoprefixer": "^10.4.16",
|
"autoprefixer": "^10.4.16",
|
||||||
"postcss": "^8.4.31",
|
"postcss": "^8.4.31",
|
||||||
"postcss-load-config": "^4.0.1",
|
"postcss-load-config": "^4.0.1",
|
||||||
@ -45,6 +46,7 @@
|
|||||||
"ioredis": "^5.3.2",
|
"ioredis": "^5.3.2",
|
||||||
"jsonwebtoken": "^9.0.2",
|
"jsonwebtoken": "^9.0.2",
|
||||||
"lucide-svelte": "^0.292.0",
|
"lucide-svelte": "^0.292.0",
|
||||||
|
"qrcode": "^1.5.3",
|
||||||
"tailwind-merge": "^2.0.0",
|
"tailwind-merge": "^2.0.0",
|
||||||
"tailwind-variants": "^0.1.18"
|
"tailwind-variants": "^0.1.18"
|
||||||
}
|
}
|
||||||
|
@ -32,6 +32,9 @@ dependencies:
|
|||||||
lucide-svelte:
|
lucide-svelte:
|
||||||
specifier: ^0.292.0
|
specifier: ^0.292.0
|
||||||
version: 0.292.0(svelte@4.2.2)
|
version: 0.292.0(svelte@4.2.2)
|
||||||
|
qrcode:
|
||||||
|
specifier: ^1.5.3
|
||||||
|
version: 1.5.3
|
||||||
tailwind-merge:
|
tailwind-merge:
|
||||||
specifier: ^2.0.0
|
specifier: ^2.0.0
|
||||||
version: 2.0.0
|
version: 2.0.0
|
||||||
@ -55,6 +58,9 @@ devDependencies:
|
|||||||
'@types/node':
|
'@types/node':
|
||||||
specifier: ^20.8.10
|
specifier: ^20.8.10
|
||||||
version: 20.8.10
|
version: 20.8.10
|
||||||
|
'@types/qrcode':
|
||||||
|
specifier: ^1.5.5
|
||||||
|
version: 1.5.5
|
||||||
autoprefixer:
|
autoprefixer:
|
||||||
specifier: ^10.4.16
|
specifier: ^10.4.16
|
||||||
version: 10.4.16(postcss@8.4.31)
|
version: 10.4.16(postcss@8.4.31)
|
||||||
@ -561,6 +567,12 @@ packages:
|
|||||||
resolution: {integrity: sha512-QzhsZ1dMGyJbn/D9V80zp4GIA4J4rfAjCCxc3MP+new0E8dyVdSkR735Lx+n3LIaHNFcjHL5+TbziccuT+fdoQ==}
|
resolution: {integrity: sha512-QzhsZ1dMGyJbn/D9V80zp4GIA4J4rfAjCCxc3MP+new0E8dyVdSkR735Lx+n3LIaHNFcjHL5+TbziccuT+fdoQ==}
|
||||||
dev: true
|
dev: true
|
||||||
|
|
||||||
|
/@types/qrcode@1.5.5:
|
||||||
|
resolution: {integrity: sha512-CdfBi/e3Qk+3Z/fXYShipBT13OJ2fDO2Q2w5CIP5anLTLIndQG9z6P1cnm+8zCWSpm5dnxMFd/uREtb0EXuQzg==}
|
||||||
|
dependencies:
|
||||||
|
'@types/node': 20.8.10
|
||||||
|
dev: true
|
||||||
|
|
||||||
/@types/resolve@1.20.2:
|
/@types/resolve@1.20.2:
|
||||||
resolution: {integrity: sha512-60BCwRFOZCQhDncwQdxxeOEEkbc5dIMccYLwbxsS4TUNeVECQ/pBJ0j09mrHOl/JJvpRPGwO9SvE4nR2Nb/a4Q==}
|
resolution: {integrity: sha512-60BCwRFOZCQhDncwQdxxeOEEkbc5dIMccYLwbxsS4TUNeVECQ/pBJ0j09mrHOl/JJvpRPGwO9SvE4nR2Nb/a4Q==}
|
||||||
dev: true
|
dev: true
|
||||||
@ -613,6 +625,18 @@ packages:
|
|||||||
engines: {node: '>=0.4.0'}
|
engines: {node: '>=0.4.0'}
|
||||||
hasBin: true
|
hasBin: true
|
||||||
|
|
||||||
|
/ansi-regex@5.0.1:
|
||||||
|
resolution: {integrity: sha512-quJQXlTSUGL2LH9SUXo8VwsY4soanhgo6LNSm84E1LBcE8s3O0wpdiRzyR9z/ZZJMlMWv37qOOb9pdJlMUEKFQ==}
|
||||||
|
engines: {node: '>=8'}
|
||||||
|
dev: false
|
||||||
|
|
||||||
|
/ansi-styles@4.3.0:
|
||||||
|
resolution: {integrity: sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg==}
|
||||||
|
engines: {node: '>=8'}
|
||||||
|
dependencies:
|
||||||
|
color-convert: 2.0.1
|
||||||
|
dev: false
|
||||||
|
|
||||||
/ansi-styles@5.2.0:
|
/ansi-styles@5.2.0:
|
||||||
resolution: {integrity: sha512-Cxwpt2SfTzTtXcfOlzGEee8O+c+MmUgGrNiBcXnuWxuFJHe6a5Hz7qwhwe5OgaSYI0IJvkLqWX1ASG+cJOkEiA==}
|
resolution: {integrity: sha512-Cxwpt2SfTzTtXcfOlzGEee8O+c+MmUgGrNiBcXnuWxuFJHe6a5Hz7qwhwe5OgaSYI0IJvkLqWX1ASG+cJOkEiA==}
|
||||||
engines: {node: '>=10'}
|
engines: {node: '>=10'}
|
||||||
@ -734,6 +758,11 @@ packages:
|
|||||||
resolution: {integrity: sha512-QOSvevhslijgYwRx6Rv7zKdMF8lbRmx+uQGx2+vDc+KI/eBnsy9kit5aj23AgGu3pa4t9AgwbnXWqS+iOY+2aA==}
|
resolution: {integrity: sha512-QOSvevhslijgYwRx6Rv7zKdMF8lbRmx+uQGx2+vDc+KI/eBnsy9kit5aj23AgGu3pa4t9AgwbnXWqS+iOY+2aA==}
|
||||||
engines: {node: '>= 6'}
|
engines: {node: '>= 6'}
|
||||||
|
|
||||||
|
/camelcase@5.3.1:
|
||||||
|
resolution: {integrity: sha512-L28STB170nwWS63UjtlEOE3dldQApaJXZkOI1uMFfzf3rRuPegHaHesyee+YxQ+W6SvRDQV6UrdOdRiR153wJg==}
|
||||||
|
engines: {node: '>=6'}
|
||||||
|
dev: false
|
||||||
|
|
||||||
/caniuse-lite@1.0.30001561:
|
/caniuse-lite@1.0.30001561:
|
||||||
resolution: {integrity: sha512-NTt0DNoKe958Q0BE0j0c1V9jbUzhBxHIEJy7asmGrpE0yG63KTV7PLHPnK2E1O9RsQrQ081I3NLuXGS6zht3cw==}
|
resolution: {integrity: sha512-NTt0DNoKe958Q0BE0j0c1V9jbUzhBxHIEJy7asmGrpE0yG63KTV7PLHPnK2E1O9RsQrQ081I3NLuXGS6zht3cw==}
|
||||||
dev: true
|
dev: true
|
||||||
@ -771,6 +800,14 @@ packages:
|
|||||||
optionalDependencies:
|
optionalDependencies:
|
||||||
fsevents: 2.3.3
|
fsevents: 2.3.3
|
||||||
|
|
||||||
|
/cliui@6.0.0:
|
||||||
|
resolution: {integrity: sha512-t6wbgtoCXvAzst7QgXxJYqPt0usEfbgQdftEPbLL/cvv6HPE5VgvqCuAIDR0NgU52ds6rFwqrgakNLrHEjCbrQ==}
|
||||||
|
dependencies:
|
||||||
|
string-width: 4.2.3
|
||||||
|
strip-ansi: 6.0.1
|
||||||
|
wrap-ansi: 6.2.0
|
||||||
|
dev: false
|
||||||
|
|
||||||
/clsx@2.0.0:
|
/clsx@2.0.0:
|
||||||
resolution: {integrity: sha512-rQ1+kcj+ttHG0MKVGBUXwayCCF1oh39BF5COIpRzuCEv8Mwjv0XucrI2ExNTOn9IlLifGClWQcU9BrZORvtw6Q==}
|
resolution: {integrity: sha512-rQ1+kcj+ttHG0MKVGBUXwayCCF1oh39BF5COIpRzuCEv8Mwjv0XucrI2ExNTOn9IlLifGClWQcU9BrZORvtw6Q==}
|
||||||
engines: {node: '>=6'}
|
engines: {node: '>=6'}
|
||||||
@ -790,6 +827,17 @@ packages:
|
|||||||
estree-walker: 3.0.3
|
estree-walker: 3.0.3
|
||||||
periscopic: 3.1.0
|
periscopic: 3.1.0
|
||||||
|
|
||||||
|
/color-convert@2.0.1:
|
||||||
|
resolution: {integrity: sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ==}
|
||||||
|
engines: {node: '>=7.0.0'}
|
||||||
|
dependencies:
|
||||||
|
color-name: 1.1.4
|
||||||
|
dev: false
|
||||||
|
|
||||||
|
/color-name@1.1.4:
|
||||||
|
resolution: {integrity: sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==}
|
||||||
|
dev: false
|
||||||
|
|
||||||
/commander@4.1.1:
|
/commander@4.1.1:
|
||||||
resolution: {integrity: sha512-NOKm8xhkzAjzFx8B2v5OAHT+u5pRQc2UCa2Vq9jYL/31o2wi9mxBA7LIFs3sV5VSC49z6pEhfbMULvShKj26WA==}
|
resolution: {integrity: sha512-NOKm8xhkzAjzFx8B2v5OAHT+u5pRQc2UCa2Vq9jYL/31o2wi9mxBA7LIFs3sV5VSC49z6pEhfbMULvShKj26WA==}
|
||||||
engines: {node: '>= 6'}
|
engines: {node: '>= 6'}
|
||||||
@ -832,6 +880,11 @@ packages:
|
|||||||
dependencies:
|
dependencies:
|
||||||
ms: 2.1.2
|
ms: 2.1.2
|
||||||
|
|
||||||
|
/decamelize@1.2.0:
|
||||||
|
resolution: {integrity: sha512-z2S+W9X73hAUUki+N+9Za2lBlun89zigOyGrsax+KUQ6wKW4ZoWpEYBkGhQjwAjjDCkWxhY0VKEhk8wzY7F5cA==}
|
||||||
|
engines: {node: '>=0.10.0'}
|
||||||
|
dev: false
|
||||||
|
|
||||||
/deep-eql@4.1.3:
|
/deep-eql@4.1.3:
|
||||||
resolution: {integrity: sha512-WaEtAOpRA1MQ0eohqZjpGD8zdI0Ovsm8mmFhaDN8dvDZzyoUMcYDnf5Y6iu7HTXxf8JDS23qWa4a+hKCDyOPzw==}
|
resolution: {integrity: sha512-WaEtAOpRA1MQ0eohqZjpGD8zdI0Ovsm8mmFhaDN8dvDZzyoUMcYDnf5Y6iu7HTXxf8JDS23qWa4a+hKCDyOPzw==}
|
||||||
engines: {node: '>=6'}
|
engines: {node: '>=6'}
|
||||||
@ -868,6 +921,10 @@ packages:
|
|||||||
engines: {node: ^14.15.0 || ^16.10.0 || >=18.0.0}
|
engines: {node: ^14.15.0 || ^16.10.0 || >=18.0.0}
|
||||||
dev: true
|
dev: true
|
||||||
|
|
||||||
|
/dijkstrajs@1.0.3:
|
||||||
|
resolution: {integrity: sha512-qiSlmBq9+BCdCA/L46dw8Uy93mloxsPSbwnm5yrKn2vMPiy8KyAskTF6zuV/j5BMsmOGZDPs7KjU+mjb670kfA==}
|
||||||
|
dev: false
|
||||||
|
|
||||||
/dlv@1.1.3:
|
/dlv@1.1.3:
|
||||||
resolution: {integrity: sha512-+HlytyjlPKnIG8XuRG8WvmBP8xs8P71y+SKKS6ZXWoEgLuePxtDoUEiH7WkdePWrQ5JBpE6aoVqfZfJUQkjXwA==}
|
resolution: {integrity: sha512-+HlytyjlPKnIG8XuRG8WvmBP8xs8P71y+SKKS6ZXWoEgLuePxtDoUEiH7WkdePWrQ5JBpE6aoVqfZfJUQkjXwA==}
|
||||||
|
|
||||||
@ -886,6 +943,14 @@ packages:
|
|||||||
resolution: {integrity: sha512-yXsZyXJfAqzWk1WKryr0Wl0MN2D47xodPvEEwlVePBnhU5E7raevLQR+E6b9JAD3GfL/7MbAL9ZtWQQPcLx7wA==}
|
resolution: {integrity: sha512-yXsZyXJfAqzWk1WKryr0Wl0MN2D47xodPvEEwlVePBnhU5E7raevLQR+E6b9JAD3GfL/7MbAL9ZtWQQPcLx7wA==}
|
||||||
dev: true
|
dev: true
|
||||||
|
|
||||||
|
/emoji-regex@8.0.0:
|
||||||
|
resolution: {integrity: sha512-MSjYzcWNOA0ewAHpz0MxpYFvwg6yjy1NG3xteoqz644VCo/RPgnr1/GGt+ic3iJTzQ8Eu3TdM14SawnVUmGE6A==}
|
||||||
|
dev: false
|
||||||
|
|
||||||
|
/encode-utf8@1.0.3:
|
||||||
|
resolution: {integrity: sha512-ucAnuBEhUK4boH2HjVYG5Q2mQyPorvv0u/ocS+zhdw0S8AlHYY+GOFhP1Gio5z4icpP2ivFSvhtFjQi8+T9ppw==}
|
||||||
|
dev: false
|
||||||
|
|
||||||
/es6-promise@3.3.1:
|
/es6-promise@3.3.1:
|
||||||
resolution: {integrity: sha512-SOp9Phqvqn7jtEUxPWdWfWoLmyt2VaJ6MpvP9Comy1MceMXqE6bxvaTu4iaxpYYPzhny28Lc+M87/c2cPK6lDg==}
|
resolution: {integrity: sha512-SOp9Phqvqn7jtEUxPWdWfWoLmyt2VaJ6MpvP9Comy1MceMXqE6bxvaTu4iaxpYYPzhny28Lc+M87/c2cPK6lDg==}
|
||||||
dev: true
|
dev: true
|
||||||
@ -957,6 +1022,14 @@ packages:
|
|||||||
dependencies:
|
dependencies:
|
||||||
to-regex-range: 5.0.1
|
to-regex-range: 5.0.1
|
||||||
|
|
||||||
|
/find-up@4.1.0:
|
||||||
|
resolution: {integrity: sha512-PpOwAdQ/YlXQ2vj8a3h8IipDuYRi3wceVQQGYWxNINccq40Anw7BlsEXCMbt1Zt+OLA6Fq9suIpIWD0OsnISlw==}
|
||||||
|
engines: {node: '>=8'}
|
||||||
|
dependencies:
|
||||||
|
locate-path: 5.0.0
|
||||||
|
path-exists: 4.0.0
|
||||||
|
dev: false
|
||||||
|
|
||||||
/focus-trap@7.5.4:
|
/focus-trap@7.5.4:
|
||||||
resolution: {integrity: sha512-N7kHdlgsO/v+iD/dMoJKtsSqs5Dz/dXZVebRgJw23LDk+jMi/974zyiOYDziY2JPp8xivq9BmUGwIJMiuSBi7w==}
|
resolution: {integrity: sha512-N7kHdlgsO/v+iD/dMoJKtsSqs5Dz/dXZVebRgJw23LDk+jMi/974zyiOYDziY2JPp8xivq9BmUGwIJMiuSBi7w==}
|
||||||
dependencies:
|
dependencies:
|
||||||
@ -992,6 +1065,11 @@ packages:
|
|||||||
/function-bind@1.1.2:
|
/function-bind@1.1.2:
|
||||||
resolution: {integrity: sha512-7XHNxH7qX9xG5mIwxkhumTox/MIRNcOgDrxWsMt2pAr23WHp6MrRlN7FBSFpCpr+oVO0F744iUgR82nJMfG2SA==}
|
resolution: {integrity: sha512-7XHNxH7qX9xG5mIwxkhumTox/MIRNcOgDrxWsMt2pAr23WHp6MrRlN7FBSFpCpr+oVO0F744iUgR82nJMfG2SA==}
|
||||||
|
|
||||||
|
/get-caller-file@2.0.5:
|
||||||
|
resolution: {integrity: sha512-DyFP3BM/3YHTQOCUL/w0OZHR0lpKeGrxotcHWcqNEdnltqFwXVfhEBQ94eIo34AfQpo0rGki4cyIiftY06h2Fg==}
|
||||||
|
engines: {node: 6.* || 8.* || >= 10.*}
|
||||||
|
dev: false
|
||||||
|
|
||||||
/get-func-name@2.0.2:
|
/get-func-name@2.0.2:
|
||||||
resolution: {integrity: sha512-8vXOvuE167CtIc3OyItco7N/dpRtBbYOsPsXCz7X/PMnlGjYjSGuZJgM1Y7mmew7BKf9BqvLX2tnOVy1BBUsxQ==}
|
resolution: {integrity: sha512-8vXOvuE167CtIc3OyItco7N/dpRtBbYOsPsXCz7X/PMnlGjYjSGuZJgM1Y7mmew7BKf9BqvLX2tnOVy1BBUsxQ==}
|
||||||
dev: true
|
dev: true
|
||||||
@ -1112,6 +1190,11 @@ packages:
|
|||||||
resolution: {integrity: sha512-SbKbANkN603Vi4jEZv49LeVJMn4yGwsbzZworEoyEiutsN3nJYdbO36zfhGJ6QEDpOZIFkDtnq5JRxmvl3jsoQ==}
|
resolution: {integrity: sha512-SbKbANkN603Vi4jEZv49LeVJMn4yGwsbzZworEoyEiutsN3nJYdbO36zfhGJ6QEDpOZIFkDtnq5JRxmvl3jsoQ==}
|
||||||
engines: {node: '>=0.10.0'}
|
engines: {node: '>=0.10.0'}
|
||||||
|
|
||||||
|
/is-fullwidth-code-point@3.0.0:
|
||||||
|
resolution: {integrity: sha512-zymm5+u+sCsSWyD9qNaejV3DFvhCKclKdizYaJUuHA83RLjb7nSuGnddCHGv0hk+KY7BMAlsWeK4Ueg6EV6XQg==}
|
||||||
|
engines: {node: '>=8'}
|
||||||
|
dev: false
|
||||||
|
|
||||||
/is-glob@4.0.3:
|
/is-glob@4.0.3:
|
||||||
resolution: {integrity: sha512-xelSayHH36ZgE7ZWhli7pW34hNbNl8Ojv5KVmkJD4hBdD3th8Tfk9vYasLM+mXWOZhFkgZfxhLSnrwRr4elSSg==}
|
resolution: {integrity: sha512-xelSayHH36ZgE7ZWhli7pW34hNbNl8Ojv5KVmkJD4hBdD3th8Tfk9vYasLM+mXWOZhFkgZfxhLSnrwRr4elSSg==}
|
||||||
engines: {node: '>=0.10.0'}
|
engines: {node: '>=0.10.0'}
|
||||||
@ -1195,6 +1278,13 @@ packages:
|
|||||||
/locate-character@3.0.0:
|
/locate-character@3.0.0:
|
||||||
resolution: {integrity: sha512-SW13ws7BjaeJ6p7Q6CO2nchbYEc3X3J6WrmTTDto7yMPqVSZTUyY5Tjbid+Ab8gLnATtygYtiDIJGQRRn2ZOiA==}
|
resolution: {integrity: sha512-SW13ws7BjaeJ6p7Q6CO2nchbYEc3X3J6WrmTTDto7yMPqVSZTUyY5Tjbid+Ab8gLnATtygYtiDIJGQRRn2ZOiA==}
|
||||||
|
|
||||||
|
/locate-path@5.0.0:
|
||||||
|
resolution: {integrity: sha512-t7hw9pI+WvuwNJXwk5zVHpyhIqzg2qTlklJOf0mVxGSbe3Fp2VieZcduNYjaLDoy6p9uGpQEGWG87WpMKlNq8g==}
|
||||||
|
engines: {node: '>=8'}
|
||||||
|
dependencies:
|
||||||
|
p-locate: 4.1.0
|
||||||
|
dev: false
|
||||||
|
|
||||||
/lodash.defaults@4.2.0:
|
/lodash.defaults@4.2.0:
|
||||||
resolution: {integrity: sha512-qjxPLHd3r5DnsdGacqOMU6pb/avJzdh9tFX2ymgoZE27BmjXrNy/y4LoaiTeAb+O3gL8AfpJGtqfX/ae2leYYQ==}
|
resolution: {integrity: sha512-qjxPLHd3r5DnsdGacqOMU6pb/avJzdh9tFX2ymgoZE27BmjXrNy/y4LoaiTeAb+O3gL8AfpJGtqfX/ae2leYYQ==}
|
||||||
dev: false
|
dev: false
|
||||||
@ -1381,6 +1471,13 @@ packages:
|
|||||||
dependencies:
|
dependencies:
|
||||||
wrappy: 1.0.2
|
wrappy: 1.0.2
|
||||||
|
|
||||||
|
/p-limit@2.3.0:
|
||||||
|
resolution: {integrity: sha512-//88mFWSJx8lxCzwdAABTJL2MyWB12+eIY7MDL2SqLmAkeKU9qxRvWuSyTjm3FUmpBEMuFfckAIqEaVGUDxb6w==}
|
||||||
|
engines: {node: '>=6'}
|
||||||
|
dependencies:
|
||||||
|
p-try: 2.2.0
|
||||||
|
dev: false
|
||||||
|
|
||||||
/p-limit@4.0.0:
|
/p-limit@4.0.0:
|
||||||
resolution: {integrity: sha512-5b0R4txpzjPWVw/cXXUResoD4hb6U/x9BH08L7nw+GN1sezDzPdxeRvpc9c433fZhBan/wusjbCsqwqm4EIBIQ==}
|
resolution: {integrity: sha512-5b0R4txpzjPWVw/cXXUResoD4hb6U/x9BH08L7nw+GN1sezDzPdxeRvpc9c433fZhBan/wusjbCsqwqm4EIBIQ==}
|
||||||
engines: {node: ^12.20.0 || ^14.13.1 || >=16.0.0}
|
engines: {node: ^12.20.0 || ^14.13.1 || >=16.0.0}
|
||||||
@ -1388,6 +1485,18 @@ packages:
|
|||||||
yocto-queue: 1.0.0
|
yocto-queue: 1.0.0
|
||||||
dev: true
|
dev: true
|
||||||
|
|
||||||
|
/p-locate@4.1.0:
|
||||||
|
resolution: {integrity: sha512-R79ZZ/0wAxKGu3oYMlz8jy/kbhsNrS7SKZ7PxEHBgJ5+F2mtFW2fK2cOtBh1cHYkQsbzFV7I+EoRKe6Yt0oK7A==}
|
||||||
|
engines: {node: '>=8'}
|
||||||
|
dependencies:
|
||||||
|
p-limit: 2.3.0
|
||||||
|
dev: false
|
||||||
|
|
||||||
|
/p-try@2.2.0:
|
||||||
|
resolution: {integrity: sha512-R4nPAVTAU0B9D35/Gk3uJf/7XYbQcyohSKdvAxIRSNghFl4e71hVoGnBNQz9cWaXxO2I10KTC+3jMdvvoKw6dQ==}
|
||||||
|
engines: {node: '>=6'}
|
||||||
|
dev: false
|
||||||
|
|
||||||
/parent-module@1.0.1:
|
/parent-module@1.0.1:
|
||||||
resolution: {integrity: sha512-GQ2EWRpQV8/o+Aw8YqtfZZPfNRWZYkbidE9k5rpl/hC3vtHHBfGm2Ifi6qWV+coDGkrUKZAxE3Lot5kcsRlh+g==}
|
resolution: {integrity: sha512-GQ2EWRpQV8/o+Aw8YqtfZZPfNRWZYkbidE9k5rpl/hC3vtHHBfGm2Ifi6qWV+coDGkrUKZAxE3Lot5kcsRlh+g==}
|
||||||
engines: {node: '>=6'}
|
engines: {node: '>=6'}
|
||||||
@ -1395,6 +1504,11 @@ packages:
|
|||||||
callsites: 3.1.0
|
callsites: 3.1.0
|
||||||
dev: true
|
dev: true
|
||||||
|
|
||||||
|
/path-exists@4.0.0:
|
||||||
|
resolution: {integrity: sha512-ak9Qy5Q7jYb2Wwcey5Fpvg2KoAc/ZIhLSLOSBmRmygPsGwkVVt0fZa0qrtMz+m6tJTAHfZQ8FnmB4MG4LWy7/w==}
|
||||||
|
engines: {node: '>=8'}
|
||||||
|
dev: false
|
||||||
|
|
||||||
/path-is-absolute@1.0.1:
|
/path-is-absolute@1.0.1:
|
||||||
resolution: {integrity: sha512-AVbw3UJ2e9bq64vSaS9Am0fje1Pa8pbGqTTsmXfaIiMpnr5DlDhfJOuLj9Sf95ZPVDAUerDfEk88MPmPe7UCQg==}
|
resolution: {integrity: sha512-AVbw3UJ2e9bq64vSaS9Am0fje1Pa8pbGqTTsmXfaIiMpnr5DlDhfJOuLj9Sf95ZPVDAUerDfEk88MPmPe7UCQg==}
|
||||||
engines: {node: '>=0.10.0'}
|
engines: {node: '>=0.10.0'}
|
||||||
@ -1440,6 +1554,11 @@ packages:
|
|||||||
pathe: 1.1.1
|
pathe: 1.1.1
|
||||||
dev: true
|
dev: true
|
||||||
|
|
||||||
|
/pngjs@5.0.0:
|
||||||
|
resolution: {integrity: sha512-40QW5YalBNfQo5yRYmiw7Yz6TKKVr3h6970B2YE+3fQpsWcrbj1PzJgxeJ19DRQjhMbKPIuMY8rFaXc8moolVw==}
|
||||||
|
engines: {node: '>=10.13.0'}
|
||||||
|
dev: false
|
||||||
|
|
||||||
/postcss-import@15.1.0(postcss@8.4.31):
|
/postcss-import@15.1.0(postcss@8.4.31):
|
||||||
resolution: {integrity: sha512-hpr+J05B2FVYUAXHeK1YyI267J/dDDhMU6B6civm8hSY1jYJnBXxzKDKDswzJmtLHryrjhnDjqqp/49t8FALew==}
|
resolution: {integrity: sha512-hpr+J05B2FVYUAXHeK1YyI267J/dDDhMU6B6civm8hSY1jYJnBXxzKDKDswzJmtLHryrjhnDjqqp/49t8FALew==}
|
||||||
engines: {node: '>=14.0.0'}
|
engines: {node: '>=14.0.0'}
|
||||||
@ -1528,6 +1647,17 @@ packages:
|
|||||||
react-is: 18.2.0
|
react-is: 18.2.0
|
||||||
dev: true
|
dev: true
|
||||||
|
|
||||||
|
/qrcode@1.5.3:
|
||||||
|
resolution: {integrity: sha512-puyri6ApkEHYiVl4CFzo1tDkAZ+ATcnbJrJ6RiBM1Fhctdn/ix9MTE3hRph33omisEbC/2fcfemsseiKgBPKZg==}
|
||||||
|
engines: {node: '>=10.13.0'}
|
||||||
|
hasBin: true
|
||||||
|
dependencies:
|
||||||
|
dijkstrajs: 1.0.3
|
||||||
|
encode-utf8: 1.0.3
|
||||||
|
pngjs: 5.0.0
|
||||||
|
yargs: 15.4.1
|
||||||
|
dev: false
|
||||||
|
|
||||||
/queue-microtask@1.2.3:
|
/queue-microtask@1.2.3:
|
||||||
resolution: {integrity: sha512-NuaNSa6flKT5JaSYQzJok04JzTL1CA6aGhv5rfLW3PgqA+M2ChpZQnAC8h8i4ZFkBS8X5RqkDBHA7r4hej3K9A==}
|
resolution: {integrity: sha512-NuaNSa6flKT5JaSYQzJok04JzTL1CA6aGhv5rfLW3PgqA+M2ChpZQnAC8h8i4ZFkBS8X5RqkDBHA7r4hej3K9A==}
|
||||||
|
|
||||||
@ -1562,6 +1692,15 @@ packages:
|
|||||||
resolution: {integrity: sha512-srw17NI0TUWHuGa5CFGGmhfNIeja30WMBfbslPNhf6JrqQlLN5gcrvig1oqPxiVaXb0oW0XRKtH6Nngs5lKCIA==}
|
resolution: {integrity: sha512-srw17NI0TUWHuGa5CFGGmhfNIeja30WMBfbslPNhf6JrqQlLN5gcrvig1oqPxiVaXb0oW0XRKtH6Nngs5lKCIA==}
|
||||||
dev: false
|
dev: false
|
||||||
|
|
||||||
|
/require-directory@2.1.1:
|
||||||
|
resolution: {integrity: sha512-fGxEI7+wsG9xrvdjsrlmL22OMTTiHRwAMroiEeMgq8gzoLC/PQr7RsRDSTLUg/bZAZtF+TVIkHc6/4RIKrui+Q==}
|
||||||
|
engines: {node: '>=0.10.0'}
|
||||||
|
dev: false
|
||||||
|
|
||||||
|
/require-main-filename@2.0.0:
|
||||||
|
resolution: {integrity: sha512-NKN5kMDylKuldxYLSUfrbo5Tuzh4hd+2E8NPPX02mZtn1VuREQToYe/ZdlJy+J3uCpfaiGF05e7B8W0iXbQHmg==}
|
||||||
|
dev: false
|
||||||
|
|
||||||
/resolve-from@4.0.0:
|
/resolve-from@4.0.0:
|
||||||
resolution: {integrity: sha512-pb/MYmXstAkysRFx8piNI1tGFNQIFA3vkE3Gq4EuA1dF6gHp/+vgZqsCGJapvy8N3Q+4o7FwvquPJcnZ7RYy4g==}
|
resolution: {integrity: sha512-pb/MYmXstAkysRFx8piNI1tGFNQIFA3vkE3Gq4EuA1dF6gHp/+vgZqsCGJapvy8N3Q+4o7FwvquPJcnZ7RYy4g==}
|
||||||
engines: {node: '>=4'}
|
engines: {node: '>=4'}
|
||||||
@ -1625,6 +1764,10 @@ packages:
|
|||||||
lru-cache: 6.0.0
|
lru-cache: 6.0.0
|
||||||
dev: false
|
dev: false
|
||||||
|
|
||||||
|
/set-blocking@2.0.0:
|
||||||
|
resolution: {integrity: sha512-KiKBS8AnWGEyLzofFfmvKwpdPzqiy16LvQfK3yv/fVH7Bj13/wl3JSR1J+rfgRE9q7xUJK4qvgS8raSOeLUehw==}
|
||||||
|
dev: false
|
||||||
|
|
||||||
/set-cookie-parser@2.6.0:
|
/set-cookie-parser@2.6.0:
|
||||||
resolution: {integrity: sha512-RVnVQxTXuerk653XfuliOxBP81Sf0+qfQE73LIYKcyMYHG94AuH0kgrQpRDuTZnSmjpysHmzxJXKNfa6PjFhyQ==}
|
resolution: {integrity: sha512-RVnVQxTXuerk653XfuliOxBP81Sf0+qfQE73LIYKcyMYHG94AuH0kgrQpRDuTZnSmjpysHmzxJXKNfa6PjFhyQ==}
|
||||||
|
|
||||||
@ -1666,6 +1809,22 @@ packages:
|
|||||||
resolution: {integrity: sha512-f9aPhy8fYBuMN+sNfakZV18U39PbalgjXG3lLB9WkaYTxijru61wb57V9wxxNthXM5Sd88ETBWi29qLAsHO52Q==}
|
resolution: {integrity: sha512-f9aPhy8fYBuMN+sNfakZV18U39PbalgjXG3lLB9WkaYTxijru61wb57V9wxxNthXM5Sd88ETBWi29qLAsHO52Q==}
|
||||||
dev: true
|
dev: true
|
||||||
|
|
||||||
|
/string-width@4.2.3:
|
||||||
|
resolution: {integrity: sha512-wKyQRQpjJ0sIp62ErSZdGsjMJWsap5oRNihHhu6G7JVO/9jIB6UyevL+tXuOqrng8j/cxKTWyWUwvSTriiZz/g==}
|
||||||
|
engines: {node: '>=8'}
|
||||||
|
dependencies:
|
||||||
|
emoji-regex: 8.0.0
|
||||||
|
is-fullwidth-code-point: 3.0.0
|
||||||
|
strip-ansi: 6.0.1
|
||||||
|
dev: false
|
||||||
|
|
||||||
|
/strip-ansi@6.0.1:
|
||||||
|
resolution: {integrity: sha512-Y38VPSHcqkFrCpFnQ9vuSXmquuv5oXOKpGeT6aGrr3o3Gc9AlVa6JBfUSOCnbxGGZF+/0ooI7KrPuUSztUdU5A==}
|
||||||
|
engines: {node: '>=8'}
|
||||||
|
dependencies:
|
||||||
|
ansi-regex: 5.0.1
|
||||||
|
dev: false
|
||||||
|
|
||||||
/strip-indent@3.0.0:
|
/strip-indent@3.0.0:
|
||||||
resolution: {integrity: sha512-laJTa3Jb+VQpaC6DseHhF7dXVqHTfJPCRDaEbid/drOhgitgYku/letMUqOXFoWV0zIIUbjpdH2t+tYj4bQMRQ==}
|
resolution: {integrity: sha512-laJTa3Jb+VQpaC6DseHhF7dXVqHTfJPCRDaEbid/drOhgitgYku/letMUqOXFoWV0zIIUbjpdH2t+tYj4bQMRQ==}
|
||||||
engines: {node: '>=8'}
|
engines: {node: '>=8'}
|
||||||
@ -2081,6 +2240,10 @@ packages:
|
|||||||
- terser
|
- terser
|
||||||
dev: true
|
dev: true
|
||||||
|
|
||||||
|
/which-module@2.0.1:
|
||||||
|
resolution: {integrity: sha512-iBdZ57RDvnOR9AGBhML2vFZf7h8vmBjhoaZqODJBFWHVtKkDmKuHai3cx5PgVMrX5YDNp27AofYbAwctSS+vhQ==}
|
||||||
|
dev: false
|
||||||
|
|
||||||
/why-is-node-running@2.2.2:
|
/why-is-node-running@2.2.2:
|
||||||
resolution: {integrity: sha512-6tSwToZxTOcotxHeA+qGCq1mVzKR3CwcJGmVcY+QE8SHy6TnpFnh8PAvPNHYr7EcuVeG0QSMxtYCuO1ta/G/oA==}
|
resolution: {integrity: sha512-6tSwToZxTOcotxHeA+qGCq1mVzKR3CwcJGmVcY+QE8SHy6TnpFnh8PAvPNHYr7EcuVeG0QSMxtYCuO1ta/G/oA==}
|
||||||
engines: {node: '>=8'}
|
engines: {node: '>=8'}
|
||||||
@ -2090,9 +2253,22 @@ packages:
|
|||||||
stackback: 0.0.2
|
stackback: 0.0.2
|
||||||
dev: true
|
dev: true
|
||||||
|
|
||||||
|
/wrap-ansi@6.2.0:
|
||||||
|
resolution: {integrity: sha512-r6lPcBGxZXlIcymEu7InxDMhdW0KDxpLgoFLcguasxCaJ/SOIZwINatK9KY/tf+ZrlywOKU0UDj3ATXUBfxJXA==}
|
||||||
|
engines: {node: '>=8'}
|
||||||
|
dependencies:
|
||||||
|
ansi-styles: 4.3.0
|
||||||
|
string-width: 4.2.3
|
||||||
|
strip-ansi: 6.0.1
|
||||||
|
dev: false
|
||||||
|
|
||||||
/wrappy@1.0.2:
|
/wrappy@1.0.2:
|
||||||
resolution: {integrity: sha512-l4Sp/DRseor9wL6EvV2+TuQn63dMkPjZ/sp9XkghTEbV9KlPS1xUsZ3u7/IQO4wxtcFB4bgpQPRcR3QCvezPcQ==}
|
resolution: {integrity: sha512-l4Sp/DRseor9wL6EvV2+TuQn63dMkPjZ/sp9XkghTEbV9KlPS1xUsZ3u7/IQO4wxtcFB4bgpQPRcR3QCvezPcQ==}
|
||||||
|
|
||||||
|
/y18n@4.0.3:
|
||||||
|
resolution: {integrity: sha512-JKhqTOwSrqNA1NY5lSztJ1GrBiUodLMmIZuLiDaMRJ+itFd+ABVE8XBjOvIWL+rSqNDC74LCSFmlb/U4UZ4hJQ==}
|
||||||
|
dev: false
|
||||||
|
|
||||||
/yallist@4.0.0:
|
/yallist@4.0.0:
|
||||||
resolution: {integrity: sha512-3wdGidZyq5PB084XLES5TpOSRA3wjXAlIWMhum2kRcv/41Sn2emQ0dycQW4uZXLejwKvg6EsvbdlVL+FYEct7A==}
|
resolution: {integrity: sha512-3wdGidZyq5PB084XLES5TpOSRA3wjXAlIWMhum2kRcv/41Sn2emQ0dycQW4uZXLejwKvg6EsvbdlVL+FYEct7A==}
|
||||||
dev: false
|
dev: false
|
||||||
@ -2101,6 +2277,31 @@ packages:
|
|||||||
resolution: {integrity: sha512-8aAvwVUSHpfEqTQ4w/KMlf3HcRdt50E5ODIQJBw1fQ5RL34xabzxtUlzTXVqc4rkZsPbvrXKWnABCD7kWSmocA==}
|
resolution: {integrity: sha512-8aAvwVUSHpfEqTQ4w/KMlf3HcRdt50E5ODIQJBw1fQ5RL34xabzxtUlzTXVqc4rkZsPbvrXKWnABCD7kWSmocA==}
|
||||||
engines: {node: '>= 14'}
|
engines: {node: '>= 14'}
|
||||||
|
|
||||||
|
/yargs-parser@18.1.3:
|
||||||
|
resolution: {integrity: sha512-o50j0JeToy/4K6OZcaQmW6lyXXKhq7csREXcDwk2omFPJEwUNOVtJKvmDr9EI1fAJZUyZcRF7kxGBWmRXudrCQ==}
|
||||||
|
engines: {node: '>=6'}
|
||||||
|
dependencies:
|
||||||
|
camelcase: 5.3.1
|
||||||
|
decamelize: 1.2.0
|
||||||
|
dev: false
|
||||||
|
|
||||||
|
/yargs@15.4.1:
|
||||||
|
resolution: {integrity: sha512-aePbxDmcYW++PaqBsJ+HYUFwCdv4LVvdnhBy78E57PIor8/OVvhMrADFFEDh8DHDFRv/O9i3lPhsENjO7QX0+A==}
|
||||||
|
engines: {node: '>=8'}
|
||||||
|
dependencies:
|
||||||
|
cliui: 6.0.0
|
||||||
|
decamelize: 1.2.0
|
||||||
|
find-up: 4.1.0
|
||||||
|
get-caller-file: 2.0.5
|
||||||
|
require-directory: 2.1.1
|
||||||
|
require-main-filename: 2.0.0
|
||||||
|
set-blocking: 2.0.0
|
||||||
|
string-width: 4.2.3
|
||||||
|
which-module: 2.0.1
|
||||||
|
y18n: 4.0.3
|
||||||
|
yargs-parser: 18.1.3
|
||||||
|
dev: false
|
||||||
|
|
||||||
/yocto-queue@1.0.0:
|
/yocto-queue@1.0.0:
|
||||||
resolution: {integrity: sha512-9bnSc/HEW2uRy67wc+T8UwauLuPJVn28jb+GtJY16iiKWyvmYJRXVT4UamsAEGQfPohgr2q4Tq0sQbQlxTfi1g==}
|
resolution: {integrity: sha512-9bnSc/HEW2uRy67wc+T8UwauLuPJVn28jb+GtJY16iiKWyvmYJRXVT4UamsAEGQfPohgr2q4Tq0sQbQlxTfi1g==}
|
||||||
engines: {node: '>=12.20'}
|
engines: {node: '>=12.20'}
|
||||||
|
@ -1,18 +0,0 @@
|
|||||||
<svg width="32" height="32" version="1.1" viewBox="0 0 32 32" xmlns="http://www.w3.org/2000/svg">
|
|
||||||
<defs>
|
|
||||||
<linearGradient x1="50%" y1="100%" x2="50%" y2="0%" id="linearGradient-1">
|
|
||||||
<stop stop-color="#420C5D" offset="0%"></stop>
|
|
||||||
<stop stop-color="#951AD1" offset="100%"></stop>
|
|
||||||
</linearGradient>
|
|
||||||
</defs>
|
|
||||||
<g transform="translate(-58.12 -303.3)" fill="url(#linearGradient-1)" fill-rule="evenodd">
|
|
||||||
<path d="m77.15 303.3c-1.608 1.868-0.09027 2.972-0.9891 4.84 1.514-2.129 5.034-2.862 7.328-3.643-3.051 2.72-5.457 6.326-8.489 9.009l-1.975-0.8374c-0.4647-4.514-1.736-4.705 4.125-9.369z"
|
|
||||||
fill-rule="evenodd"/>
|
|
||||||
<path d="m74.04 313.1 2.932 0.9454c-0.615 2.034 0.3559 2.791 0.9472 3.123 1.324 0.7332 2.602 1.49 3.619 2.412 1.916 1.75 3.004 4.21 3.004 6.812 0 2.578-1.183 5.061-3.169 6.717-1.868 1.561-4.446 2.223-6.953 2.223-1.561 0-2.956-0.0708-4.47-0.5677-3.453-1.159-6.031-4.115-6.244-7.663-0.1893-2.767 0.4257-4.872 2.578-7.072 1.111-1.159 2.563-2.749 4.1-3.813 0.757-0.5204 1.119-1.191-0.4183-3.958l1.28-1.076 2.795 1.918-2.352-0.3007c0.1656 0.2366 1.189 0.7706 1.284 1.078 0.2128 0.8751-0.1911 1.771-0.3804 2.149-0.9696 1.75-1.86 2.275-3.066 3.268-2.129 1.75-4.27 2.836-4.01 7.637 0.1183 2.365 1.433 5.295 4.2 6.643 1.561 0.757 2.859 1.189 4.68 1.284 1.632 0.071 4.754-0.8988 6.457-2.318 1.821-1.514 2.838-3.808 2.838-6.149 0-2.365-0.9461-4.612-2.72-6.197-1.017-0.9223-2.696-2.034-3.737-2.625-1.041-0.5912-2.782-2.06-2.356-3.645z"/>
|
|
||||||
<path d="m73.41 316.6c-0.186 1.088-0.4177 3.117-0.8909 3.917-0.3293 0.5488-0.4126 0.8101-0.7846 1.094-1.09 1.535-1.45 1.761-2.132 4.552-0.1447 0.5914-0.3832 1.516-0.2591 2.107 0.372 1.703 0.6612 2.874 1.316 4.103 0 0 0.1271 0.1217 0.1271 0.169 0.6821 0.9225 0.6264 1.05 2.665 2.246l-0.06204 0.3313c-1.55-0.4729-2.604-0.9591-3.41-2.024 0-0.0236-0.1513-0.1558-0.1513-0.1558-0.868-1.135-1.753-2.788-2.021-4.546-0.1447-0.7097-0.0769-1.341 0.08833-2.075 0.7026-2.885 1.415-4.093 2.744-5.543 0.3514-0.2601 0.6704-0.6741 1.001-1.092 0.4859-0.6764 1.462-2.841 1.814-4.189z"/>
|
|
||||||
<path d="m74.09 318.6c0.0237 1.04 0.0078 3.036 0.3389 3.796 0.0945 0.2599 0.3274 1.414 0.9422 2.794 0.4258 0.96 0.5418 1.933 0.6128 2.193 0.2838 1.14-0.4002 3.086-0.8734 4.906-0.2364 0.98-0.6051 1.773-1.371 2.412l0.2796 0.3593c0.5204-0.02 1.954-1.096 2.403-2.416 0.757-2.24 1.328-3.317 0.9729-5.797-0.0473-0.2402-0.2094-1.134-0.6588-2.014-0.6622-1.34-1.474-2.614-1.592-2.874-0.213-0.4198-1.007-2.119-1.054-3.359z"/>
|
|
||||||
<path d="m74.88 313.9 0.9727 0.4962c-0.09145 0.6403 0.04572 2.059 0.686 2.424 2.836 1.761 5.512 3.683 6.565 5.604 3.751 6.771-2.63 13.04-8.143 12.44 2.996-2.219 4.428-6.583 3.307-11.55-0.4574-1.944-1.729-3.893-2.987-5.883-0.545-0.9768-0.3547-2.188-0.4006-3.538z"
|
|
||||||
fill-rule="evenodd"/>
|
|
||||||
<rect x="73.07" y="312.8" width="1" height="22"/>
|
|
||||||
</g>
|
|
||||||
</svg>
|
|
Before Width: | Height: | Size: 2.8 KiB |
74
web/src/lib/components/qrcode-dialog/QRCodeDialog.svelte
Normal file
@ -0,0 +1,74 @@
|
|||||||
|
<script lang="ts">
|
||||||
|
import {
|
||||||
|
Dialog,
|
||||||
|
DialogContent,
|
||||||
|
DialogFooter,
|
||||||
|
DialogHeader,
|
||||||
|
DialogTitle,
|
||||||
|
DialogTrigger,
|
||||||
|
} from '$lib/components/ui/dialog';
|
||||||
|
import { Skeleton } from '$lib/components/ui/skeleton';
|
||||||
|
import { Dialog as DialogPrimitive } from 'bits-ui';
|
||||||
|
import { Button } from '$lib/components/ui/button';
|
||||||
|
import type { SafeReturn } from '$lib/typings';
|
||||||
|
|
||||||
|
const DialogClose = DialogPrimitive.Close;
|
||||||
|
|
||||||
|
let loading: boolean = true;
|
||||||
|
let error: boolean = false;
|
||||||
|
let imageData: string | undefined = undefined;
|
||||||
|
|
||||||
|
export let content: string | undefined;
|
||||||
|
|
||||||
|
const getImageData = async (content: string): Promise<SafeReturn<string>> => {
|
||||||
|
const resp = await fetch('/api/qrcode', {
|
||||||
|
method: 'POST',
|
||||||
|
body: content,
|
||||||
|
headers: {
|
||||||
|
'Content-Type': 'text/plain',
|
||||||
|
},
|
||||||
|
});
|
||||||
|
if (resp.statusText !== 'OK') {
|
||||||
|
return { error: new Error('request failed') };
|
||||||
|
}
|
||||||
|
const data = await resp.text();
|
||||||
|
return { data };
|
||||||
|
};
|
||||||
|
|
||||||
|
$: if (typeof content === 'string') {
|
||||||
|
(async () => {
|
||||||
|
const { data, error: e } = await getImageData(content);
|
||||||
|
loading = false;
|
||||||
|
if (!data || e) {
|
||||||
|
error = true;
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
imageData = data;
|
||||||
|
})();
|
||||||
|
}
|
||||||
|
</script>
|
||||||
|
|
||||||
|
<Dialog>
|
||||||
|
<DialogTrigger asChild let:builder>
|
||||||
|
<slot {builder} />
|
||||||
|
</DialogTrigger>
|
||||||
|
<DialogContent>
|
||||||
|
<DialogHeader>
|
||||||
|
<DialogTitle>QRCode</DialogTitle>
|
||||||
|
</DialogHeader>
|
||||||
|
<div class="flex items-center justify-center">
|
||||||
|
{#if loading}
|
||||||
|
<Skeleton class="w-[280px] h-[280px] rounded-lg" />
|
||||||
|
{:else if error || !imageData}
|
||||||
|
<div>!!ERROR!!</div>
|
||||||
|
{:else}
|
||||||
|
<img src={imageData} alt="QRCode" width="300" height="300" />
|
||||||
|
{/if}
|
||||||
|
</div>
|
||||||
|
<DialogFooter>
|
||||||
|
<DialogClose>
|
||||||
|
<Button size="sm">Close</Button>
|
||||||
|
</DialogClose>
|
||||||
|
</DialogFooter>
|
||||||
|
</DialogContent>
|
||||||
|
</Dialog>
|
7
web/src/lib/components/qrcode-dialog/index.ts
Normal file
@ -0,0 +1,7 @@
|
|||||||
|
import Root from './QRCodeDialog.svelte';
|
||||||
|
|
||||||
|
export {
|
||||||
|
Root,
|
||||||
|
//
|
||||||
|
Root as QRCodeDialog,
|
||||||
|
};
|
@ -2,6 +2,7 @@ import { Dialog as DialogPrimitive } from 'bits-ui';
|
|||||||
|
|
||||||
const Root = DialogPrimitive.Root;
|
const Root = DialogPrimitive.Root;
|
||||||
const Trigger = DialogPrimitive.Trigger;
|
const Trigger = DialogPrimitive.Trigger;
|
||||||
|
const Close = DialogPrimitive.Close;
|
||||||
|
|
||||||
import Title from './dialog-title.svelte';
|
import Title from './dialog-title.svelte';
|
||||||
import Portal from './dialog-portal.svelte';
|
import Portal from './dialog-portal.svelte';
|
||||||
@ -18,6 +19,7 @@ export {
|
|||||||
Footer,
|
Footer,
|
||||||
Header,
|
Header,
|
||||||
Trigger,
|
Trigger,
|
||||||
|
Close,
|
||||||
Overlay,
|
Overlay,
|
||||||
Content,
|
Content,
|
||||||
Description,
|
Description,
|
||||||
@ -28,6 +30,7 @@ export {
|
|||||||
Footer as DialogFooter,
|
Footer as DialogFooter,
|
||||||
Header as DialogHeader,
|
Header as DialogHeader,
|
||||||
Trigger as DialogTrigger,
|
Trigger as DialogTrigger,
|
||||||
|
Close as DialogClose,
|
||||||
Overlay as DialogOverlay,
|
Overlay as DialogOverlay,
|
||||||
Content as DialogContent,
|
Content as DialogContent,
|
||||||
Description as DialogDescription,
|
Description as DialogDescription,
|
||||||
|
7
web/src/lib/components/ui/skeleton/index.ts
Normal file
@ -0,0 +1,7 @@
|
|||||||
|
import Root from "./skeleton.svelte";
|
||||||
|
|
||||||
|
export {
|
||||||
|
Root,
|
||||||
|
//
|
||||||
|
Root as Skeleton
|
||||||
|
};
|
14
web/src/lib/components/ui/skeleton/skeleton.svelte
Normal file
@ -0,0 +1,14 @@
|
|||||||
|
<script lang="ts">
|
||||||
|
import { cn } from "$lib/utils";
|
||||||
|
import type { HTMLAttributes } from "svelte/elements";
|
||||||
|
|
||||||
|
type $$Props = HTMLAttributes<HTMLDivElement>;
|
||||||
|
|
||||||
|
let className: $$Props["class"] = undefined;
|
||||||
|
export { className as class };
|
||||||
|
</script>
|
||||||
|
|
||||||
|
<div
|
||||||
|
class={cn("animate-pulse rounded-md bg-muted", className)}
|
||||||
|
{...$$restProps}
|
||||||
|
/>
|
@ -76,4 +76,10 @@ export type APISuccessResponse<D> = {
|
|||||||
result: D;
|
result: D;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
export type SafeReturn<T, K = any> = LeastOne<{
|
||||||
|
data: T,
|
||||||
|
error: K
|
||||||
|
}>
|
||||||
|
|
||||||
export type LeastOne<T, U = { [K in keyof T]: Pick<T, K> }> = Partial<T> & U[keyof U];
|
export type LeastOne<T, U = { [K in keyof T]: Pick<T, K> }> = Partial<T> & U[keyof U];
|
||||||
|
|
||||||
|
@ -525,13 +525,13 @@ export async function isConfigIdReserved(id: number): Promise<boolean> {
|
|||||||
}
|
}
|
||||||
|
|
||||||
export async function getNextFreeConfId(): Promise<number> {
|
export async function getNextFreeConfId(): Promise<number> {
|
||||||
let id = maxConfId();
|
let id = maxConfId() + 1;
|
||||||
for (let i = 0; i < 1_000; i++) {
|
for (let i = id; i < 1_000; i++) {
|
||||||
if (!(await isConfigIdReserved(id))) {
|
if (!(await isConfigIdReserved(i))) {
|
||||||
return id;
|
return i;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
throw new Error('Could not find a free config id');
|
throw new Error('WireGuard: Error: Could not find a free config id');
|
||||||
}
|
}
|
||||||
|
|
||||||
export function getConfigHash(confId: number): string | undefined {
|
export function getConfigHash(confId: number): string | undefined {
|
||||||
|
@ -8,7 +8,6 @@
|
|||||||
import fetchAction from '$lib/fetch-action';
|
import fetchAction from '$lib/fetch-action';
|
||||||
|
|
||||||
export let data: PageData;
|
export let data: PageData;
|
||||||
export let isOpen = false;
|
|
||||||
|
|
||||||
const handleRename = async (id: string, name: string) => {
|
const handleRename = async (id: string, name: string) => {
|
||||||
const resp = await fetchAction({
|
const resp = await fetchAction({
|
||||||
@ -32,10 +31,13 @@
|
|||||||
<BasePage showLogout={true}>
|
<BasePage showLogout={true}>
|
||||||
<div class={'flex items-center justify-between py-3 px-2'}>
|
<div class={'flex items-center justify-between py-3 px-2'}>
|
||||||
<h2 class={'font-bold text-xl'}>Hello there 👋</h2>
|
<h2 class={'font-bold text-xl'}>Hello there 👋</h2>
|
||||||
<Button on:click={() => (isOpen = true)}>
|
|
||||||
<i class="fas fa-plus mr-2"></i>
|
<CreateServerDialog let:builder>
|
||||||
Create Server
|
<Button builders={[builder]}>
|
||||||
</Button>
|
<i class="fas fa-plus mr-2"></i>
|
||||||
|
Create Server
|
||||||
|
</Button>
|
||||||
|
</CreateServerDialog>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<div class="space-y-3.5">
|
<div class="space-y-3.5">
|
||||||
@ -58,5 +60,3 @@
|
|||||||
{/if}
|
{/if}
|
||||||
</div>
|
</div>
|
||||||
</BasePage>
|
</BasePage>
|
||||||
|
|
||||||
<CreateServerDialog {isOpen} />
|
|
||||||
|
@ -1,7 +1,14 @@
|
|||||||
<script lang="ts">
|
<script lang="ts">
|
||||||
import { CreateServerSchema, type CreateServerSchemaType } from './schema';
|
import { CreateServerSchema, type CreateServerSchemaType } from './schema';
|
||||||
import type { SuperValidated } from 'sveltekit-superforms';
|
import type { SuperValidated } from 'sveltekit-superforms';
|
||||||
import { Dialog, DialogContent, DialogFooter, DialogHeader, DialogTitle } from '$lib/components/ui/dialog';
|
import {
|
||||||
|
Dialog,
|
||||||
|
DialogContent,
|
||||||
|
DialogFooter,
|
||||||
|
DialogHeader,
|
||||||
|
DialogTitle,
|
||||||
|
DialogTrigger,
|
||||||
|
} from '$lib/components/ui/dialog';
|
||||||
import {
|
import {
|
||||||
Form,
|
Form,
|
||||||
FormButton,
|
FormButton,
|
||||||
@ -18,13 +25,15 @@
|
|||||||
import { Collapsible, CollapsibleContent, CollapsibleTrigger } from '$lib/components/ui/collapsible';
|
import { Collapsible, CollapsibleContent, CollapsibleTrigger } from '$lib/components/ui/collapsible';
|
||||||
import { Button } from '$lib/components/ui/button';
|
import { Button } from '$lib/components/ui/button';
|
||||||
|
|
||||||
export let isOpen = false;
|
|
||||||
let loading: boolean = false;
|
let loading: boolean = false;
|
||||||
|
|
||||||
let form: SuperValidated<CreateServerSchemaType>;
|
let form: SuperValidated<CreateServerSchemaType>;
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
<Dialog open={isOpen}>
|
<Dialog>
|
||||||
|
<DialogTrigger asChild let:builder>
|
||||||
|
<slot {builder} />
|
||||||
|
</DialogTrigger>
|
||||||
<DialogContent>
|
<DialogContent>
|
||||||
<DialogHeader>
|
<DialogHeader>
|
||||||
<DialogTitle>Create Server</DialogTitle>
|
<DialogTitle>Create Server</DialogTitle>
|
||||||
|
@ -18,7 +18,9 @@
|
|||||||
<div class="w-full md:w-2/3 flex items-center gap-x-2">
|
<div class="w-full md:w-2/3 flex items-center gap-x-2">
|
||||||
<div class="flex grow">
|
<div class="flex grow">
|
||||||
<div class={'w-12 aspect-square flex items-center justify-center mr-4 rounded-full bg-gray-200 max-md:hidden'}>
|
<div class={'w-12 aspect-square flex items-center justify-center mr-4 rounded-full bg-gray-200 max-md:hidden'}>
|
||||||
<i class={'fa-solid fa-server text-gray-400 text-xl'} />
|
<i
|
||||||
|
class={cn(server.tor ? 'fa-solid fa-onion text-purple-700' : 'fa-solid fa-server text-gray-400', 'text-xl')}
|
||||||
|
/>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<div class="h-full flex flex-col justify-between col-span-4 gap-y-1.5">
|
<div class="h-full flex flex-col justify-between col-span-4 gap-y-1.5">
|
||||||
|
@ -13,7 +13,6 @@
|
|||||||
import { goto, invalidateAll } from '$app/navigation';
|
import { goto, invalidateAll } from '$app/navigation';
|
||||||
|
|
||||||
export let data: PageData;
|
export let data: PageData;
|
||||||
export let dialogOpen: boolean = false;
|
|
||||||
|
|
||||||
const handleRename = async (peerId: string, name: string) => {
|
const handleRename = async (peerId: string, name: string) => {
|
||||||
const resp = await fetchAction({
|
const resp = await fetchAction({
|
||||||
@ -76,8 +75,6 @@
|
|||||||
};
|
};
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
<CreatePeerDialog open={dialogOpen} on:close={() => (dialogOpen = false)} />
|
|
||||||
|
|
||||||
<Card>
|
<Card>
|
||||||
<CardHeader>
|
<CardHeader>
|
||||||
<CardTitle>Server</CardTitle>
|
<CardTitle>Server</CardTitle>
|
||||||
@ -166,12 +163,16 @@
|
|||||||
{/each}
|
{/each}
|
||||||
</CardContent>
|
</CardContent>
|
||||||
<CardFooter>
|
<CardFooter>
|
||||||
<Button on:click={() => (dialogOpen = true)}>Add Client</Button>
|
<CreatePeerDialog let:builder>
|
||||||
|
<Button size="sm" builders={[builder]}>Add Client</Button>
|
||||||
|
</CreatePeerDialog>
|
||||||
</CardFooter>
|
</CardFooter>
|
||||||
{:else}
|
{:else}
|
||||||
<CardContent>
|
<CardContent>
|
||||||
<div>No Clients!</div>
|
<div>No Clients!</div>
|
||||||
<Button on:click={() => (dialogOpen = true)}>Add Client</Button>
|
<CreatePeerDialog let:builder>
|
||||||
|
<Button size="sm" builders={[builder]}>Add Client</Button>
|
||||||
|
</CreatePeerDialog>
|
||||||
</CardContent>
|
</CardContent>
|
||||||
{/if}
|
{/if}
|
||||||
</Card>
|
</Card>
|
||||||
|
@ -1,7 +1,14 @@
|
|||||||
<script lang="ts">
|
<script lang="ts">
|
||||||
import { CreatePeerSchema, type CreatePeerSchemaType } from './schema';
|
import { CreatePeerSchema, type CreatePeerSchemaType } from './schema';
|
||||||
import type { SuperValidated } from 'sveltekit-superforms';
|
import type { SuperValidated } from 'sveltekit-superforms';
|
||||||
import { Dialog, DialogContent, DialogFooter, DialogHeader, DialogTitle } from '$lib/components/ui/dialog';
|
import {
|
||||||
|
Dialog,
|
||||||
|
DialogContent,
|
||||||
|
DialogFooter,
|
||||||
|
DialogHeader,
|
||||||
|
DialogTitle,
|
||||||
|
DialogTrigger,
|
||||||
|
} from '$lib/components/ui/dialog';
|
||||||
import { Form, FormButton, FormField, FormInput, FormLabel, FormValidation } from '$lib/components/ui/form';
|
import { Form, FormButton, FormField, FormInput, FormLabel, FormValidation } from '$lib/components/ui/form';
|
||||||
import { FormItem } from '$lib/components/ui/form/index.js';
|
import { FormItem } from '$lib/components/ui/form/index.js';
|
||||||
import { cn } from '$lib/utils';
|
import { cn } from '$lib/utils';
|
||||||
@ -10,7 +17,6 @@
|
|||||||
|
|
||||||
const dispatch = createEventDispatcher();
|
const dispatch = createEventDispatcher();
|
||||||
|
|
||||||
export let open = false;
|
|
||||||
let loading: boolean = false;
|
let loading: boolean = false;
|
||||||
|
|
||||||
let form: SuperValidated<CreatePeerSchemaType>;
|
let form: SuperValidated<CreatePeerSchemaType>;
|
||||||
@ -21,7 +27,10 @@
|
|||||||
};
|
};
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
<Dialog {open}>
|
<Dialog>
|
||||||
|
<DialogTrigger asChild let:builder>
|
||||||
|
<slot {builder} />
|
||||||
|
</DialogTrigger>
|
||||||
<DialogContent>
|
<DialogContent>
|
||||||
<DialogHeader>
|
<DialogHeader>
|
||||||
<DialogTitle>Create Peer</DialogTitle>
|
<DialogTitle>Create Peer</DialogTitle>
|
||||||
|
@ -6,6 +6,7 @@
|
|||||||
import PeerActionButton from './PeerActionButton.svelte';
|
import PeerActionButton from './PeerActionButton.svelte';
|
||||||
import { createEventDispatcher, onMount } from 'svelte';
|
import { createEventDispatcher, onMount } from 'svelte';
|
||||||
import { getPeerConf } from '$lib/wireguard/utils';
|
import { getPeerConf } from '$lib/wireguard/utils';
|
||||||
|
import { QRCodeDialog } from '$lib/components/qrcode-dialog';
|
||||||
|
|
||||||
export let peer: Peer;
|
export let peer: Peer;
|
||||||
|
|
||||||
@ -15,7 +16,7 @@
|
|||||||
|
|
||||||
export let conf: string | undefined = undefined;
|
export let conf: string | undefined = undefined;
|
||||||
|
|
||||||
export let isLoading: boolean = false;
|
let isLoading: boolean = false;
|
||||||
|
|
||||||
onMount(async () => {
|
onMount(async () => {
|
||||||
conf = await getPeerConf({
|
conf = await getPeerConf({
|
||||||
@ -35,7 +36,7 @@
|
|||||||
}
|
}
|
||||||
console.log('conf', conf);
|
console.log('conf', conf);
|
||||||
// create a blob
|
// create a blob
|
||||||
const blob = new Blob([conf], { type: 'text/plain' });
|
const blob = new Blob([ conf ], { type: 'text/plain' });
|
||||||
// create a link
|
// create a link
|
||||||
const link = document.createElement('a');
|
const link = document.createElement('a');
|
||||||
link.href = window.URL.createObjectURL(blob);
|
link.href = window.URL.createObjectURL(blob);
|
||||||
@ -46,8 +47,6 @@
|
|||||||
link.remove();
|
link.remove();
|
||||||
};
|
};
|
||||||
|
|
||||||
const handleQRCode = async () => {};
|
|
||||||
|
|
||||||
const handleRename = (value: string) => {
|
const handleRename = (value: string) => {
|
||||||
dispatch('rename', value);
|
dispatch('rename', value);
|
||||||
};
|
};
|
||||||
@ -58,7 +57,7 @@
|
|||||||
</script>
|
</script>
|
||||||
|
|
||||||
<div class="flex items-center justify-between p-4 border border-neutral-200/60 rounded-md hover:border-neutral-200">
|
<div class="flex items-center justify-between p-4 border border-neutral-200/60 rounded-md hover:border-neutral-200">
|
||||||
<div class="flex items-center gap-2.5">
|
<div class="flex items-center gap-x-2">
|
||||||
<div class={'w-12 aspect-square flex items-center justify-center mr-4 rounded-full bg-gray-200 max-md:hidden'}>
|
<div class={'w-12 aspect-square flex items-center justify-center mr-4 rounded-full bg-gray-200 max-md:hidden'}>
|
||||||
<i class={'fas fa-user text-gray-400 text-lg'} />
|
<i class={'fas fa-user text-gray-400 text-lg'} />
|
||||||
</div>
|
</div>
|
||||||
@ -80,16 +79,18 @@
|
|||||||
</div>
|
</div>
|
||||||
<div class="flex items-center justify-center gap-x-3">
|
<div class="flex items-center justify-center gap-x-3">
|
||||||
<!-- QRCode -->
|
<!-- QRCode -->
|
||||||
<PeerActionButton disabled={isLoading} on:click={handleQRCode}>
|
<QRCodeDialog let:builder content={conf}>
|
||||||
<i class={'fal text-neutral-700 group-hover:text-primary fa-qrcode'} />
|
<PeerActionButton builders={[builder]} disabled={isLoading}>
|
||||||
</PeerActionButton>
|
<i class={'fal text-neutral-700 group-hover:text-primary fa-qrcode'} />
|
||||||
|
</PeerActionButton>
|
||||||
|
</QRCodeDialog>
|
||||||
|
|
||||||
<!-- Download -->
|
<!-- Download -->
|
||||||
<PeerActionButton disabled={isLoading} on:click={handleDownload}>
|
<PeerActionButton disabled={isLoading} on:click={handleDownload}>
|
||||||
<i class={'fal text-neutral-700 group-hover:text-primary fa-download'} />
|
<i class={'fal text-neutral-700 group-hover:text-primary fa-download'} />
|
||||||
</PeerActionButton>
|
</PeerActionButton>
|
||||||
|
|
||||||
<!-- Download -->
|
<!-- Remove -->
|
||||||
<PeerActionButton loading={isLoading} on:click={handleRemove}>
|
<PeerActionButton loading={isLoading} on:click={handleRemove}>
|
||||||
<i class={'fal text-neutral-700 group-hover:text-primary text-lg fa-trash-can'} />
|
<i class={'fal text-neutral-700 group-hover:text-primary text-lg fa-trash-can'} />
|
||||||
</PeerActionButton>
|
</PeerActionButton>
|
||||||
|
@ -1,9 +1,16 @@
|
|||||||
<script lang="ts">
|
<script lang="ts">
|
||||||
import { cn } from '$lib/utils';
|
import { cn } from '$lib/utils';
|
||||||
import { createEventDispatcher } from 'svelte';
|
import { createEventDispatcher } from 'svelte';
|
||||||
|
import { Button } from 'bits-ui';
|
||||||
|
|
||||||
|
type $$Props = Button.Props & {
|
||||||
|
disabled?: boolean;
|
||||||
|
loading?: boolean;
|
||||||
|
};
|
||||||
|
|
||||||
export let disabled: boolean = false;
|
export let disabled: boolean = false;
|
||||||
export let loading: boolean = false;
|
export let loading: boolean = false;
|
||||||
|
export let builders: $$Props['builders'] = [];
|
||||||
|
|
||||||
const dispatch = createEventDispatcher();
|
const dispatch = createEventDispatcher();
|
||||||
|
|
||||||
@ -13,10 +20,9 @@
|
|||||||
}
|
}
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
<div
|
<Button.Root
|
||||||
aria-roledescription="Action"
|
{builders}
|
||||||
role="button"
|
{...$$restProps}
|
||||||
tabindex="0"
|
|
||||||
class={cn(
|
class={cn(
|
||||||
'group flex items-center justify-center w-10 aspect-square rounded-md',
|
'group flex items-center justify-center w-10 aspect-square rounded-md',
|
||||||
'bg-gray-200/80 hover:bg-gray-100/50',
|
'bg-gray-200/80 hover:bg-gray-100/50',
|
||||||
@ -31,5 +37,9 @@
|
|||||||
if (e.key === 'Enter') handleClick();
|
if (e.key === 'Enter') handleClick();
|
||||||
}}
|
}}
|
||||||
>
|
>
|
||||||
<slot />
|
{#if loading}
|
||||||
</div>
|
<i class="far fa-spinner-third fa-spin" />
|
||||||
|
{:else}
|
||||||
|
<slot />
|
||||||
|
{/if}
|
||||||
|
</Button.Root>
|
||||||
|
16
web/src/routes/api/qrcode/+server.ts
Normal file
@ -0,0 +1,16 @@
|
|||||||
|
import type { RequestHandler } from '@sveltejs/kit';
|
||||||
|
import QRCode from 'qrcode';
|
||||||
|
|
||||||
|
export const POST: RequestHandler = async ({ request }) => {
|
||||||
|
if (!request.headers.has('Content-Type') || request.headers.get('Content-Type') !== 'text/plain') {
|
||||||
|
return new Response(null, { status: 400, headers: { 'Content-Type': 'text/plain' } });
|
||||||
|
}
|
||||||
|
|
||||||
|
const body = await request.text();
|
||||||
|
const data = await QRCode.toDataURL(body, {
|
||||||
|
errorCorrectionLevel: 'H',
|
||||||
|
width: 500,
|
||||||
|
});
|
||||||
|
|
||||||
|
return new Response(data, { status: 200, headers: { 'Content-Type': 'text/plain' } });
|
||||||
|
};
|
@ -28,7 +28,6 @@ export const actions: Actions = {
|
|||||||
const receivedHashed = Buffer.from(password.toString()).toString('hex').toLowerCase();
|
const receivedHashed = Buffer.from(password.toString()).toString('hex').toLowerCase();
|
||||||
|
|
||||||
if (hashed !== receivedHashed) {
|
if (hashed !== receivedHashed) {
|
||||||
console.log('[+] TEST ONLY', password, hashed, receivedHashed);
|
|
||||||
return setError(form, 'password', 'Incorrect password.');
|
return setError(form, 'password', 'Incorrect password.');
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -41,20 +40,16 @@ export const actions: Actions = {
|
|||||||
|
|
||||||
const { ORIGIN } = process.env;
|
const { ORIGIN } = process.env;
|
||||||
if (ORIGIN) {
|
if (ORIGIN) {
|
||||||
console.log('[+] TEST ONLY', 'ORIGIN', ORIGIN);
|
|
||||||
|
|
||||||
const secure = ORIGIN.startsWith('https://');
|
const secure = ORIGIN.startsWith('https://');
|
||||||
event.cookies.set('authorization', token, {
|
event.cookies.set('authorization', token, {
|
||||||
secure,
|
secure,
|
||||||
httpOnly: true,
|
httpOnly: true,
|
||||||
path: '/'
|
path: '/',
|
||||||
});
|
});
|
||||||
|
|
||||||
} else {
|
} else {
|
||||||
event.cookies.set('authorization', token);
|
event.cookies.set('authorization', token);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
return { ok: true };
|
return { ok: true };
|
||||||
},
|
},
|
||||||
};
|
};
|
||||||
|