mirror of
https://github.com/BradNut/AdelieStack
synced 2025-09-08 17:40:20 +00:00
Adding profile update for username, firstname, and lastname.
This commit is contained in:
parent
da0df78c05
commit
c5e310bf95
14 changed files with 268 additions and 50 deletions
|
|
@ -40,7 +40,7 @@
|
|||
"@storybook/test": "^8.4.7",
|
||||
"@sveltejs/adapter-node": "^5.2.9",
|
||||
"@sveltejs/enhanced-img": "^0.4.4",
|
||||
"@sveltejs/kit": "^2.15.1",
|
||||
"@sveltejs/kit": "^2.15.2",
|
||||
"@sveltejs/vite-plugin-svelte": "^5.0.3",
|
||||
"@types/cookie": "^1.0.0",
|
||||
"@types/node": "^22.10.5",
|
||||
|
|
@ -63,7 +63,7 @@
|
|||
"svelte-preprocess": "^6.0.3",
|
||||
"svelte-sequential-preprocessor": "^2.0.2",
|
||||
"svelte-sonner": "^0.3.28",
|
||||
"sveltekit-flash-message": "^2.4.4",
|
||||
"sveltekit-flash-message": "^2.4.5",
|
||||
"sveltekit-superforms": "^2.22.1",
|
||||
"tailwind-merge": "^2.6.0",
|
||||
"tailwind-variants": "^0.3.0",
|
||||
|
|
@ -92,8 +92,8 @@
|
|||
"@oslojs/webauthn": "^1.0.0",
|
||||
"@scalar/hono-api-reference": "^0.5.162",
|
||||
"@tailwindcss/container-queries": "^0.1.1",
|
||||
"@tailwindcss/forms": "^0.5.9",
|
||||
"@tailwindcss/typography": "^0.5.15",
|
||||
"@tailwindcss/forms": "^0.5.10",
|
||||
"@tailwindcss/typography": "^0.5.16",
|
||||
"arctic": "^3.1.0",
|
||||
"argon2": "^0.41.1",
|
||||
"dayjs": "^1.11.13",
|
||||
|
|
|
|||
|
|
@ -19,7 +19,7 @@ importers:
|
|||
version: 0.4.2(hono@4.6.16)(zod@3.24.1)
|
||||
'@inlang/paraglide-sveltekit':
|
||||
specifier: ^0.15.4
|
||||
version: 0.15.4(@sveltejs/kit@2.15.1(@sveltejs/vite-plugin-svelte@5.0.3(svelte@5.16.5)(vite@6.0.7(@types/node@22.10.5)(jiti@1.21.7)(tsx@4.19.2)(yaml@2.7.0)))(svelte@5.16.5)(vite@6.0.7(@types/node@22.10.5)(jiti@1.21.7)(tsx@4.19.2)(yaml@2.7.0)))
|
||||
version: 0.15.4(@sveltejs/kit@2.15.2(@sveltejs/vite-plugin-svelte@5.0.3(svelte@5.16.5)(vite@6.0.7(@types/node@22.10.5)(jiti@1.21.7)(tsx@4.19.2)(yaml@2.7.0)))(svelte@5.16.5)(vite@6.0.7(@types/node@22.10.5)(jiti@1.21.7)(tsx@4.19.2)(yaml@2.7.0)))
|
||||
'@internationalized/date':
|
||||
specifier: ^3.5.5
|
||||
version: 3.6.0
|
||||
|
|
@ -54,11 +54,11 @@ importers:
|
|||
specifier: ^0.1.1
|
||||
version: 0.1.1(tailwindcss@3.4.17)
|
||||
'@tailwindcss/forms':
|
||||
specifier: ^0.5.9
|
||||
version: 0.5.9(tailwindcss@3.4.17)
|
||||
specifier: ^0.5.10
|
||||
version: 0.5.10(tailwindcss@3.4.17)
|
||||
'@tailwindcss/typography':
|
||||
specifier: ^0.5.15
|
||||
version: 0.5.15(tailwindcss@3.4.17)
|
||||
specifier: ^0.5.16
|
||||
version: 0.5.16(tailwindcss@3.4.17)
|
||||
arctic:
|
||||
specifier: ^3.1.0
|
||||
version: 3.1.0
|
||||
|
|
@ -170,13 +170,13 @@ importers:
|
|||
version: 8.4.7(storybook@8.4.7)
|
||||
'@sveltejs/adapter-node':
|
||||
specifier: ^5.2.9
|
||||
version: 5.2.11(@sveltejs/kit@2.15.1(@sveltejs/vite-plugin-svelte@5.0.3(svelte@5.16.5)(vite@6.0.7(@types/node@22.10.5)(jiti@1.21.7)(tsx@4.19.2)(yaml@2.7.0)))(svelte@5.16.5)(vite@6.0.7(@types/node@22.10.5)(jiti@1.21.7)(tsx@4.19.2)(yaml@2.7.0)))
|
||||
version: 5.2.11(@sveltejs/kit@2.15.2(@sveltejs/vite-plugin-svelte@5.0.3(svelte@5.16.5)(vite@6.0.7(@types/node@22.10.5)(jiti@1.21.7)(tsx@4.19.2)(yaml@2.7.0)))(svelte@5.16.5)(vite@6.0.7(@types/node@22.10.5)(jiti@1.21.7)(tsx@4.19.2)(yaml@2.7.0)))
|
||||
'@sveltejs/enhanced-img':
|
||||
specifier: ^0.4.4
|
||||
version: 0.4.4(rollup@4.29.1)(svelte@5.16.5)(vite@6.0.7(@types/node@22.10.5)(jiti@1.21.7)(tsx@4.19.2)(yaml@2.7.0))
|
||||
'@sveltejs/kit':
|
||||
specifier: ^2.15.1
|
||||
version: 2.15.1(@sveltejs/vite-plugin-svelte@5.0.3(svelte@5.16.5)(vite@6.0.7(@types/node@22.10.5)(jiti@1.21.7)(tsx@4.19.2)(yaml@2.7.0)))(svelte@5.16.5)(vite@6.0.7(@types/node@22.10.5)(jiti@1.21.7)(tsx@4.19.2)(yaml@2.7.0))
|
||||
specifier: ^2.15.2
|
||||
version: 2.15.2(@sveltejs/vite-plugin-svelte@5.0.3(svelte@5.16.5)(vite@6.0.7(@types/node@22.10.5)(jiti@1.21.7)(tsx@4.19.2)(yaml@2.7.0)))(svelte@5.16.5)(vite@6.0.7(@types/node@22.10.5)(jiti@1.21.7)(tsx@4.19.2)(yaml@2.7.0))
|
||||
'@sveltejs/vite-plugin-svelte':
|
||||
specifier: ^5.0.3
|
||||
version: 5.0.3(svelte@5.16.5)(vite@6.0.7(@types/node@22.10.5)(jiti@1.21.7)(tsx@4.19.2)(yaml@2.7.0))
|
||||
|
|
@ -212,7 +212,7 @@ importers:
|
|||
version: 0.30.1
|
||||
formsnap:
|
||||
specifier: ^2.0.0
|
||||
version: 2.0.0(svelte@5.16.5)(sveltekit-superforms@2.22.1(@sveltejs/kit@2.15.1(@sveltejs/vite-plugin-svelte@5.0.3(svelte@5.16.5)(vite@6.0.7(@types/node@22.10.5)(jiti@1.21.7)(tsx@4.19.2)(yaml@2.7.0)))(svelte@5.16.5)(vite@6.0.7(@types/node@22.10.5)(jiti@1.21.7)(tsx@4.19.2)(yaml@2.7.0)))(@types/json-schema@7.0.15)(svelte@5.16.5)(typescript@5.7.2))
|
||||
version: 2.0.0(svelte@5.16.5)(sveltekit-superforms@2.22.1(@sveltejs/kit@2.15.2(@sveltejs/vite-plugin-svelte@5.0.3(svelte@5.16.5)(vite@6.0.7(@types/node@22.10.5)(jiti@1.21.7)(tsx@4.19.2)(yaml@2.7.0)))(svelte@5.16.5)(vite@6.0.7(@types/node@22.10.5)(jiti@1.21.7)(tsx@4.19.2)(yaml@2.7.0)))(@types/json-schema@7.0.15)(svelte@5.16.5)(typescript@5.7.2))
|
||||
lucide-svelte:
|
||||
specifier: ^0.469.0
|
||||
version: 0.469.0(svelte@5.16.5)
|
||||
|
|
@ -241,11 +241,11 @@ importers:
|
|||
specifier: ^0.3.28
|
||||
version: 0.3.28(svelte@5.16.5)
|
||||
sveltekit-flash-message:
|
||||
specifier: ^2.4.4
|
||||
version: 2.4.4(@sveltejs/kit@2.15.1(@sveltejs/vite-plugin-svelte@5.0.3(svelte@5.16.5)(vite@6.0.7(@types/node@22.10.5)(jiti@1.21.7)(tsx@4.19.2)(yaml@2.7.0)))(svelte@5.16.5)(vite@6.0.7(@types/node@22.10.5)(jiti@1.21.7)(tsx@4.19.2)(yaml@2.7.0)))(svelte@5.16.5)
|
||||
specifier: ^2.4.5
|
||||
version: 2.4.5(@sveltejs/kit@2.15.2(@sveltejs/vite-plugin-svelte@5.0.3(svelte@5.16.5)(vite@6.0.7(@types/node@22.10.5)(jiti@1.21.7)(tsx@4.19.2)(yaml@2.7.0)))(svelte@5.16.5)(vite@6.0.7(@types/node@22.10.5)(jiti@1.21.7)(tsx@4.19.2)(yaml@2.7.0)))(svelte@5.16.5)
|
||||
sveltekit-superforms:
|
||||
specifier: ^2.22.1
|
||||
version: 2.22.1(@sveltejs/kit@2.15.1(@sveltejs/vite-plugin-svelte@5.0.3(svelte@5.16.5)(vite@6.0.7(@types/node@22.10.5)(jiti@1.21.7)(tsx@4.19.2)(yaml@2.7.0)))(svelte@5.16.5)(vite@6.0.7(@types/node@22.10.5)(jiti@1.21.7)(tsx@4.19.2)(yaml@2.7.0)))(@types/json-schema@7.0.15)(svelte@5.16.5)(typescript@5.7.2)
|
||||
version: 2.22.1(@sveltejs/kit@2.15.2(@sveltejs/vite-plugin-svelte@5.0.3(svelte@5.16.5)(vite@6.0.7(@types/node@22.10.5)(jiti@1.21.7)(tsx@4.19.2)(yaml@2.7.0)))(svelte@5.16.5)(vite@6.0.7(@types/node@22.10.5)(jiti@1.21.7)(tsx@4.19.2)(yaml@2.7.0)))(@types/json-schema@7.0.15)(svelte@5.16.5)(typescript@5.7.2)
|
||||
tailwind-merge:
|
||||
specifier: ^2.6.0
|
||||
version: 2.6.0
|
||||
|
|
@ -2206,8 +2206,8 @@ packages:
|
|||
svelte: ^5.0.0
|
||||
vite: '>= 5.0.0'
|
||||
|
||||
'@sveltejs/kit@2.15.1':
|
||||
resolution: {integrity: sha512-8t7D3hQHbUDMiaQ2RVnjJJ/+Ur4Fn/tkeySJCsHtX346Q9cp3LAnav8xXdfuqYNJwpUGX0x3BqF1uvbmXQw93A==}
|
||||
'@sveltejs/kit@2.15.2':
|
||||
resolution: {integrity: sha512-p208T1kdM6zd8k4YXIUM60pLWQ8dZqehXSiqn4NulXHyHibX53uIAL2xtNL8GjxX2IVPqPRT978MwVYhCKExdQ==}
|
||||
engines: {node: '>=18.13'}
|
||||
hasBin: true
|
||||
peerDependencies:
|
||||
|
|
@ -2238,15 +2238,15 @@ packages:
|
|||
peerDependencies:
|
||||
tailwindcss: '>=3.2.0'
|
||||
|
||||
'@tailwindcss/forms@0.5.9':
|
||||
resolution: {integrity: sha512-tM4XVr2+UVTxXJzey9Twx48c1gcxFStqn1pQz0tRsX8o3DvxhN5oY5pvyAbUx7VTaZxpej4Zzvc6h+1RJBzpIg==}
|
||||
'@tailwindcss/forms@0.5.10':
|
||||
resolution: {integrity: sha512-utI1ONF6uf/pPNO68kmN1b8rEwNXv3czukalo8VtJH8ksIkZXr3Q3VYudZLkCsDd4Wku120uF02hYK25XGPorw==}
|
||||
peerDependencies:
|
||||
tailwindcss: '>=3.0.0 || >= 3.0.0-alpha.1 || >= 4.0.0-alpha.20'
|
||||
tailwindcss: '>=3.0.0 || >= 3.0.0-alpha.1 || >= 4.0.0-alpha.20 || >= 4.0.0-beta.1'
|
||||
|
||||
'@tailwindcss/typography@0.5.15':
|
||||
resolution: {integrity: sha512-AqhlCXl+8grUz8uqExv5OTtgpjuVIwFTSXTrh8y9/pw6q2ek7fJ+Y8ZEVw7EB2DCcuCOtEjf9w3+J3rzts01uA==}
|
||||
'@tailwindcss/typography@0.5.16':
|
||||
resolution: {integrity: sha512-0wDLwCVF5V3x3b1SGXPCDcdsbDHMBe+lkFzBRaHeLvNi+nrrnZ1lA18u+OTWO8iSWU2GxUOCvlXtDuqftc1oiA==}
|
||||
peerDependencies:
|
||||
tailwindcss: '>=3.0.0 || insiders || >=4.0.0-alpha.20'
|
||||
tailwindcss: '>=3.0.0 || insiders || >=4.0.0-alpha.20 || >=4.0.0-beta.1'
|
||||
|
||||
'@testing-library/dom@10.4.0':
|
||||
resolution: {integrity: sha512-pemlzrSESWbdAloYml3bAJMEfNh1Z7EduzqPKprCH5S341frlpYnUEW0H72dLxa6IsYr+mPno20GiSm+h9dEdQ==}
|
||||
|
|
@ -4724,8 +4724,8 @@ packages:
|
|||
resolution: {integrity: sha512-sWJRa4qOfRdSORSVw9GhfDEwsbsYsegnDzBevUCF6k/Eis/QqCu9lJ6I0+d/E2wOWCjOhlcJ3+jl/Iur+5mmCw==}
|
||||
engines: {node: '>=10.0.0'}
|
||||
|
||||
sveltekit-flash-message@2.4.4:
|
||||
resolution: {integrity: sha512-CFN03chH/FMEJcBZ/8zKm7RqGee/pwb57Spbbx8QCQPhe7N9ofZHd9iYV2vVy4E9glBo/oQ1IG7VQje6L092wg==}
|
||||
sveltekit-flash-message@2.4.5:
|
||||
resolution: {integrity: sha512-CPJwgZbXkPs7Tsl8vK81d6FPqWO4NiuwAkx57zaOIuhDu9wSq0V4rc4TuRtVwWTjOmHwnXClRana+WCXwKHOFQ==}
|
||||
peerDependencies:
|
||||
'@sveltejs/kit': 1.x || 2.x
|
||||
svelte: 3.x || 4.x || >=5.0.0-next.51
|
||||
|
|
@ -5964,12 +5964,12 @@ snapshots:
|
|||
- debug
|
||||
- supports-color
|
||||
|
||||
'@inlang/paraglide-sveltekit@0.15.4(@sveltejs/kit@2.15.1(@sveltejs/vite-plugin-svelte@5.0.3(svelte@5.16.5)(vite@6.0.7(@types/node@22.10.5)(jiti@1.21.7)(tsx@4.19.2)(yaml@2.7.0)))(svelte@5.16.5)(vite@6.0.7(@types/node@22.10.5)(jiti@1.21.7)(tsx@4.19.2)(yaml@2.7.0)))':
|
||||
'@inlang/paraglide-sveltekit@0.15.4(@sveltejs/kit@2.15.2(@sveltejs/vite-plugin-svelte@5.0.3(svelte@5.16.5)(vite@6.0.7(@types/node@22.10.5)(jiti@1.21.7)(tsx@4.19.2)(yaml@2.7.0)))(svelte@5.16.5)(vite@6.0.7(@types/node@22.10.5)(jiti@1.21.7)(tsx@4.19.2)(yaml@2.7.0)))':
|
||||
dependencies:
|
||||
'@inlang/paraglide-js': 1.11.7
|
||||
'@inlang/paraglide-vite': 1.3.4
|
||||
'@lix-js/client': 2.2.1
|
||||
'@sveltejs/kit': 2.15.1(@sveltejs/vite-plugin-svelte@5.0.3(svelte@5.16.5)(vite@6.0.7(@types/node@22.10.5)(jiti@1.21.7)(tsx@4.19.2)(yaml@2.7.0)))(svelte@5.16.5)(vite@6.0.7(@types/node@22.10.5)(jiti@1.21.7)(tsx@4.19.2)(yaml@2.7.0))
|
||||
'@sveltejs/kit': 2.15.2(@sveltejs/vite-plugin-svelte@5.0.3(svelte@5.16.5)(vite@6.0.7(@types/node@22.10.5)(jiti@1.21.7)(tsx@4.19.2)(yaml@2.7.0)))(svelte@5.16.5)(vite@6.0.7(@types/node@22.10.5)(jiti@1.21.7)(tsx@4.19.2)(yaml@2.7.0))
|
||||
commander: 12.1.0
|
||||
dedent: 1.5.1
|
||||
devalue: 4.3.3
|
||||
|
|
@ -6851,12 +6851,12 @@ snapshots:
|
|||
dependencies:
|
||||
storybook: 8.4.7
|
||||
|
||||
'@sveltejs/adapter-node@5.2.11(@sveltejs/kit@2.15.1(@sveltejs/vite-plugin-svelte@5.0.3(svelte@5.16.5)(vite@6.0.7(@types/node@22.10.5)(jiti@1.21.7)(tsx@4.19.2)(yaml@2.7.0)))(svelte@5.16.5)(vite@6.0.7(@types/node@22.10.5)(jiti@1.21.7)(tsx@4.19.2)(yaml@2.7.0)))':
|
||||
'@sveltejs/adapter-node@5.2.11(@sveltejs/kit@2.15.2(@sveltejs/vite-plugin-svelte@5.0.3(svelte@5.16.5)(vite@6.0.7(@types/node@22.10.5)(jiti@1.21.7)(tsx@4.19.2)(yaml@2.7.0)))(svelte@5.16.5)(vite@6.0.7(@types/node@22.10.5)(jiti@1.21.7)(tsx@4.19.2)(yaml@2.7.0)))':
|
||||
dependencies:
|
||||
'@rollup/plugin-commonjs': 28.0.2(rollup@4.29.1)
|
||||
'@rollup/plugin-json': 6.1.0(rollup@4.29.1)
|
||||
'@rollup/plugin-node-resolve': 16.0.0(rollup@4.29.1)
|
||||
'@sveltejs/kit': 2.15.1(@sveltejs/vite-plugin-svelte@5.0.3(svelte@5.16.5)(vite@6.0.7(@types/node@22.10.5)(jiti@1.21.7)(tsx@4.19.2)(yaml@2.7.0)))(svelte@5.16.5)(vite@6.0.7(@types/node@22.10.5)(jiti@1.21.7)(tsx@4.19.2)(yaml@2.7.0))
|
||||
'@sveltejs/kit': 2.15.2(@sveltejs/vite-plugin-svelte@5.0.3(svelte@5.16.5)(vite@6.0.7(@types/node@22.10.5)(jiti@1.21.7)(tsx@4.19.2)(yaml@2.7.0)))(svelte@5.16.5)(vite@6.0.7(@types/node@22.10.5)(jiti@1.21.7)(tsx@4.19.2)(yaml@2.7.0))
|
||||
rollup: 4.29.1
|
||||
|
||||
'@sveltejs/enhanced-img@0.4.4(rollup@4.29.1)(svelte@5.16.5)(vite@6.0.7(@types/node@22.10.5)(jiti@1.21.7)(tsx@4.19.2)(yaml@2.7.0))':
|
||||
|
|
@ -6871,7 +6871,7 @@ snapshots:
|
|||
transitivePeerDependencies:
|
||||
- rollup
|
||||
|
||||
'@sveltejs/kit@2.15.1(@sveltejs/vite-plugin-svelte@5.0.3(svelte@5.16.5)(vite@6.0.7(@types/node@22.10.5)(jiti@1.21.7)(tsx@4.19.2)(yaml@2.7.0)))(svelte@5.16.5)(vite@6.0.7(@types/node@22.10.5)(jiti@1.21.7)(tsx@4.19.2)(yaml@2.7.0))':
|
||||
'@sveltejs/kit@2.15.2(@sveltejs/vite-plugin-svelte@5.0.3(svelte@5.16.5)(vite@6.0.7(@types/node@22.10.5)(jiti@1.21.7)(tsx@4.19.2)(yaml@2.7.0)))(svelte@5.16.5)(vite@6.0.7(@types/node@22.10.5)(jiti@1.21.7)(tsx@4.19.2)(yaml@2.7.0))':
|
||||
dependencies:
|
||||
'@sveltejs/vite-plugin-svelte': 5.0.3(svelte@5.16.5)(vite@6.0.7(@types/node@22.10.5)(jiti@1.21.7)(tsx@4.19.2)(yaml@2.7.0))
|
||||
'@types/cookie': 0.6.0
|
||||
|
|
@ -6919,12 +6919,12 @@ snapshots:
|
|||
dependencies:
|
||||
tailwindcss: 3.4.17
|
||||
|
||||
'@tailwindcss/forms@0.5.9(tailwindcss@3.4.17)':
|
||||
'@tailwindcss/forms@0.5.10(tailwindcss@3.4.17)':
|
||||
dependencies:
|
||||
mini-svg-data-uri: 1.4.4
|
||||
tailwindcss: 3.4.17
|
||||
|
||||
'@tailwindcss/typography@0.5.15(tailwindcss@3.4.17)':
|
||||
'@tailwindcss/typography@0.5.16(tailwindcss@3.4.17)':
|
||||
dependencies:
|
||||
lodash.castarray: 4.4.0
|
||||
lodash.isplainobject: 4.0.6
|
||||
|
|
@ -8070,11 +8070,11 @@ snapshots:
|
|||
combined-stream: 1.0.8
|
||||
mime-types: 2.1.35
|
||||
|
||||
formsnap@2.0.0(svelte@5.16.5)(sveltekit-superforms@2.22.1(@sveltejs/kit@2.15.1(@sveltejs/vite-plugin-svelte@5.0.3(svelte@5.16.5)(vite@6.0.7(@types/node@22.10.5)(jiti@1.21.7)(tsx@4.19.2)(yaml@2.7.0)))(svelte@5.16.5)(vite@6.0.7(@types/node@22.10.5)(jiti@1.21.7)(tsx@4.19.2)(yaml@2.7.0)))(@types/json-schema@7.0.15)(svelte@5.16.5)(typescript@5.7.2)):
|
||||
formsnap@2.0.0(svelte@5.16.5)(sveltekit-superforms@2.22.1(@sveltejs/kit@2.15.2(@sveltejs/vite-plugin-svelte@5.0.3(svelte@5.16.5)(vite@6.0.7(@types/node@22.10.5)(jiti@1.21.7)(tsx@4.19.2)(yaml@2.7.0)))(svelte@5.16.5)(vite@6.0.7(@types/node@22.10.5)(jiti@1.21.7)(tsx@4.19.2)(yaml@2.7.0)))(@types/json-schema@7.0.15)(svelte@5.16.5)(typescript@5.7.2)):
|
||||
dependencies:
|
||||
svelte: 5.16.5
|
||||
svelte-toolbelt: 0.5.0(svelte@5.16.5)
|
||||
sveltekit-superforms: 2.22.1(@sveltejs/kit@2.15.1(@sveltejs/vite-plugin-svelte@5.0.3(svelte@5.16.5)(vite@6.0.7(@types/node@22.10.5)(jiti@1.21.7)(tsx@4.19.2)(yaml@2.7.0)))(svelte@5.16.5)(vite@6.0.7(@types/node@22.10.5)(jiti@1.21.7)(tsx@4.19.2)(yaml@2.7.0)))(@types/json-schema@7.0.15)(svelte@5.16.5)(typescript@5.7.2)
|
||||
sveltekit-superforms: 2.22.1(@sveltejs/kit@2.15.2(@sveltejs/vite-plugin-svelte@5.0.3(svelte@5.16.5)(vite@6.0.7(@types/node@22.10.5)(jiti@1.21.7)(tsx@4.19.2)(yaml@2.7.0)))(svelte@5.16.5)(vite@6.0.7(@types/node@22.10.5)(jiti@1.21.7)(tsx@4.19.2)(yaml@2.7.0)))(@types/json-schema@7.0.15)(svelte@5.16.5)(typescript@5.7.2)
|
||||
|
||||
forwarded@0.2.0: {}
|
||||
|
||||
|
|
@ -9452,14 +9452,14 @@ snapshots:
|
|||
transitivePeerDependencies:
|
||||
- supports-color
|
||||
|
||||
sveltekit-flash-message@2.4.4(@sveltejs/kit@2.15.1(@sveltejs/vite-plugin-svelte@5.0.3(svelte@5.16.5)(vite@6.0.7(@types/node@22.10.5)(jiti@1.21.7)(tsx@4.19.2)(yaml@2.7.0)))(svelte@5.16.5)(vite@6.0.7(@types/node@22.10.5)(jiti@1.21.7)(tsx@4.19.2)(yaml@2.7.0)))(svelte@5.16.5):
|
||||
sveltekit-flash-message@2.4.5(@sveltejs/kit@2.15.2(@sveltejs/vite-plugin-svelte@5.0.3(svelte@5.16.5)(vite@6.0.7(@types/node@22.10.5)(jiti@1.21.7)(tsx@4.19.2)(yaml@2.7.0)))(svelte@5.16.5)(vite@6.0.7(@types/node@22.10.5)(jiti@1.21.7)(tsx@4.19.2)(yaml@2.7.0)))(svelte@5.16.5):
|
||||
dependencies:
|
||||
'@sveltejs/kit': 2.15.1(@sveltejs/vite-plugin-svelte@5.0.3(svelte@5.16.5)(vite@6.0.7(@types/node@22.10.5)(jiti@1.21.7)(tsx@4.19.2)(yaml@2.7.0)))(svelte@5.16.5)(vite@6.0.7(@types/node@22.10.5)(jiti@1.21.7)(tsx@4.19.2)(yaml@2.7.0))
|
||||
'@sveltejs/kit': 2.15.2(@sveltejs/vite-plugin-svelte@5.0.3(svelte@5.16.5)(vite@6.0.7(@types/node@22.10.5)(jiti@1.21.7)(tsx@4.19.2)(yaml@2.7.0)))(svelte@5.16.5)(vite@6.0.7(@types/node@22.10.5)(jiti@1.21.7)(tsx@4.19.2)(yaml@2.7.0))
|
||||
svelte: 5.16.5
|
||||
|
||||
sveltekit-superforms@2.22.1(@sveltejs/kit@2.15.1(@sveltejs/vite-plugin-svelte@5.0.3(svelte@5.16.5)(vite@6.0.7(@types/node@22.10.5)(jiti@1.21.7)(tsx@4.19.2)(yaml@2.7.0)))(svelte@5.16.5)(vite@6.0.7(@types/node@22.10.5)(jiti@1.21.7)(tsx@4.19.2)(yaml@2.7.0)))(@types/json-schema@7.0.15)(svelte@5.16.5)(typescript@5.7.2):
|
||||
sveltekit-superforms@2.22.1(@sveltejs/kit@2.15.2(@sveltejs/vite-plugin-svelte@5.0.3(svelte@5.16.5)(vite@6.0.7(@types/node@22.10.5)(jiti@1.21.7)(tsx@4.19.2)(yaml@2.7.0)))(svelte@5.16.5)(vite@6.0.7(@types/node@22.10.5)(jiti@1.21.7)(tsx@4.19.2)(yaml@2.7.0)))(@types/json-schema@7.0.15)(svelte@5.16.5)(typescript@5.7.2):
|
||||
dependencies:
|
||||
'@sveltejs/kit': 2.15.1(@sveltejs/vite-plugin-svelte@5.0.3(svelte@5.16.5)(vite@6.0.7(@types/node@22.10.5)(jiti@1.21.7)(tsx@4.19.2)(yaml@2.7.0)))(svelte@5.16.5)(vite@6.0.7(@types/node@22.10.5)(jiti@1.21.7)(tsx@4.19.2)(yaml@2.7.0))
|
||||
'@sveltejs/kit': 2.15.2(@sveltejs/vite-plugin-svelte@5.0.3(svelte@5.16.5)(vite@6.0.7(@types/node@22.10.5)(jiti@1.21.7)(tsx@4.19.2)(yaml@2.7.0)))(svelte@5.16.5)(vite@6.0.7(@types/node@22.10.5)(jiti@1.21.7)(tsx@4.19.2)(yaml@2.7.0))
|
||||
devalue: 5.1.1
|
||||
memoize-weak: 1.0.2
|
||||
svelte: 5.16.5
|
||||
|
|
|
|||
22
src/lib/dtos/settings/profile/update-profile.dto.ts
Normal file
22
src/lib/dtos/settings/profile/update-profile.dto.ts
Normal file
|
|
@ -0,0 +1,22 @@
|
|||
import { z } from 'zod';
|
||||
|
||||
const MAX_UPLOAD_SIZE = 1024 * 1024 * 3; // 3MB
|
||||
const ACCEPTED_FILE_TYPES = ['image/jpeg', 'image/jpg', 'image/png', 'image/webp'];
|
||||
|
||||
export const updateProfileDto = z.object({
|
||||
first_name: z
|
||||
.string()
|
||||
.trim()
|
||||
.min(1, { message: 'Must be at least 1 characters' })
|
||||
.max(50, { message: 'Must be less than 50 characters' })
|
||||
.optional(),
|
||||
last_name: z
|
||||
.string()
|
||||
.trim()
|
||||
.min(1, { message: 'Must be at least 1 characters' })
|
||||
.max(50, { message: 'Must be less than 50 characters' })
|
||||
.optional(),
|
||||
username: z.string().trim().min(3, { message: 'Must be at least 3 characters' }).max(50, { message: 'Must be less than 50 characters' }),
|
||||
});
|
||||
|
||||
export type UpdateProfileDto = z.infer<typeof updateProfileDto>;
|
||||
|
|
@ -3,7 +3,9 @@ import { userDto } from './user.dto';
|
|||
|
||||
export const updateUserDto = userDto
|
||||
.pick({
|
||||
avatar: true
|
||||
avatar: true,
|
||||
first_name: true,
|
||||
last_name: true
|
||||
})
|
||||
.optional();
|
||||
|
||||
|
|
|
|||
|
|
@ -6,6 +6,9 @@ const ACCEPTED_FILE_TYPES = ['image/jpeg', 'image/jpg', 'image/png', 'image/webp
|
|||
export const userDto = z.object({
|
||||
id: z.string(),
|
||||
email: z.string().email(),
|
||||
first_name: z.string().trim().min(1, { message: 'Must be at least 1 characters' }).max(50, { message: 'Must be less than 50 characters' }),
|
||||
last_name: z.string().trim().min(1, { message: 'Must be at least 1 characters' }).max(50, { message: 'Must be less than 50 characters' }),
|
||||
username: z.string().trim().min(3, { message: 'Must be at least 3 characters' }).max(50, { message: 'Must be less than 50 characters' }),
|
||||
avatar: z
|
||||
.instanceof(File)
|
||||
.optional()
|
||||
|
|
|
|||
|
|
@ -36,4 +36,8 @@ export class UserRolesRepository {
|
|||
async delete(id: string, db = this.drizzle.db) {
|
||||
return db.delete(user_roles_table).where(eq(user_roles_table.id, id)).returning().then(takeFirstOrThrow);
|
||||
}
|
||||
|
||||
async deleteAllByUserId(userId: string, db = this.drizzle.db) {
|
||||
return db.delete(user_roles_table).where(eq(user_roles_table.user_id, userId));
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -48,4 +48,13 @@ export class UserRolesService {
|
|||
trx,
|
||||
);
|
||||
}
|
||||
|
||||
async removeAllRolesFromUser(userId: string, trx: Transaction | null = null) {
|
||||
if (!trx) {
|
||||
return this.userRolesRepository.deleteAllByUserId(userId);
|
||||
}
|
||||
|
||||
return this.userRolesRepository.deleteAllByUserId(userId, trx);
|
||||
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -12,6 +12,7 @@ import { rateLimit } from '../common/middleware/rate-limit.middleware';
|
|||
import { changePasswordDto } from '$lib/dtos/settings/password/change-password.dto';
|
||||
import { StatusCodes } from '$lib/constants/status-codes';
|
||||
import { SessionsService } from '../iam/sessions/sessions.service';
|
||||
import { updateProfileDto } from '$lib/dtos/settings/profile/update-profile.dto';
|
||||
|
||||
@injectable()
|
||||
export class UsersController extends Controller {
|
||||
|
|
@ -67,6 +68,18 @@ export class UsersController extends Controller {
|
|||
console.error('Error updating password', error);
|
||||
return c.json({ error: 'Unable to update password' }, StatusCodes.INTERNAL_SERVER_ERROR);
|
||||
}
|
||||
})
|
||||
.put('/me/profile', authState('session'), zValidator('json', updateProfileDto), async (c) => {
|
||||
c.var.logger.debug(`Update profile: ${JSON.stringify(c.req.valid('json'))}`);
|
||||
await this.usersService.update(c.var.session.userId, c.req.valid('json'));
|
||||
const user = await this.usersRepository.findOneByIdOrThrow(c.var.session.userId);
|
||||
return c.json(user);
|
||||
})
|
||||
.delete('/me', authState('session'), async (c) => {
|
||||
await this.usersService.delete(c.var.session.userId);
|
||||
await this.sessionsService.invalidateSession('');
|
||||
this.sessionsService.deleteSessionCookie();
|
||||
return c.json({ message: 'User deleted' });
|
||||
});
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -8,7 +8,7 @@ import { DrizzleRepository } from '../common/factories/drizzle-repository.factor
|
|||
/* -------------------------------------------------------------------------- */
|
||||
/* Types */
|
||||
/* -------------------------------------------------------------------------- */
|
||||
type Create = Pick<InferSelectModel<typeof users_table>, 'avatar' | 'email' | 'username'>;
|
||||
type Create = Pick<InferSelectModel<typeof users_table>, 'avatar' | 'email' | 'username' | 'first_name' | 'last_name'>;
|
||||
type Update = Partial<Create>;
|
||||
|
||||
/* -------------------------------------------------------------------------- */
|
||||
|
|
@ -38,7 +38,9 @@ export class UsersRepository extends DrizzleRepository {
|
|||
|
||||
async findOneByIdOrThrow(id: string, db = this.drizzle.db) {
|
||||
const user = await this.findOneById(id, db);
|
||||
if (!user) throw NotFound('User not found');
|
||||
if (!user) {
|
||||
throw NotFound('User not found');
|
||||
}
|
||||
return user;
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -9,27 +9,33 @@ import { UsersRepository } from './users.repository';
|
|||
import { UserRolesService } from './user_roles.service';
|
||||
import { RoleName } from '../roles/tables/roles.table';
|
||||
import { BadRequest } from '../common/utils/exceptions';
|
||||
import { LoggerService } from '../common/services/logger.service';
|
||||
import type { UpdateProfileDto } from '$lib/dtos/settings/profile/update-profile.dto';
|
||||
|
||||
@injectable()
|
||||
export class UsersService {
|
||||
constructor(
|
||||
private drizzleService = inject(DrizzleService),
|
||||
private credentialsRepository = inject(CredentialsRepository),
|
||||
private loggerService = inject(LoggerService),
|
||||
private usersRepository = inject(UsersRepository),
|
||||
private userRoleService = inject(UserRolesService),
|
||||
private storageService = inject(StorageService),
|
||||
private tokenService = inject(TokensService)
|
||||
) {}
|
||||
|
||||
async update(userId: string, updateUserDto: UpdateUserDto) {
|
||||
async update(userId: string, updateUserDto: UpdateProfileDto) {
|
||||
let key: string | null = null;
|
||||
if (updateUserDto?.avatar) {
|
||||
const { key } = await this.storageService.upload({ file: updateUserDto.avatar });
|
||||
await this.usersRepository.update(userId, { avatar: key });
|
||||
const response = await this.storageService.upload({ file: updateUserDto.avatar });
|
||||
key = response?.key;
|
||||
}
|
||||
this.loggerService.log.info(`Updating user ${userId}, with avatar: ${key}, first_name: ${updateUserDto?.first_name}, last_name: ${updateUserDto?.last_name}`);
|
||||
await this.usersRepository.update(userId, { avatar: key, first_name: updateUserDto?.first_name ?? '', last_name: updateUserDto?.last_name ?? '' });
|
||||
}
|
||||
|
||||
async createEmail(email: string) {
|
||||
return this.usersRepository.create({ avatar: null, email, username: email });
|
||||
return this.usersRepository.create({ avatar: null, email, username: email, first_name: '', last_name: '' });
|
||||
}
|
||||
|
||||
async createWithPassword(username: string, password: string, email?: string | undefined) {
|
||||
|
|
@ -46,7 +52,7 @@ export class UsersService {
|
|||
|
||||
return await this.drizzleService.db.transaction(async (trx) => {
|
||||
const createdUser = await this.usersRepository.create(
|
||||
{ username, email: email || '', avatar: null },
|
||||
{ username, email: email || '', avatar: null, first_name: '', last_name: '' },
|
||||
trx,
|
||||
);
|
||||
|
||||
|
|
@ -104,4 +110,12 @@ export class UsersService {
|
|||
const { password } = data;
|
||||
return this.tokenService.verifyHashedToken(password, credential.secret_data);
|
||||
}
|
||||
|
||||
async delete(userId: string) {
|
||||
return await this.drizzleService.db.transaction(async (trx) => {
|
||||
const deletedUser = await this.usersRepository.delete(userId, trx);
|
||||
// await this.userRoleService.removeAllRolesFromUser(userId, trx);
|
||||
return deletedUser;
|
||||
});
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1,5 +1,5 @@
|
|||
<script lang="ts">
|
||||
import { page } from '$app/stores';
|
||||
import { page } from '$app/state';
|
||||
import { cn } from '@/utils/ui';
|
||||
|
||||
let { children } = $props();
|
||||
|
|
@ -17,11 +17,11 @@
|
|||
>
|
||||
<a
|
||||
href="/settings"
|
||||
class={cn($page.url.pathname === '/settings' && 'font-semibold text-primary')}>Profile</a
|
||||
class={cn(page.url.pathname === '/settings' && 'font-semibold text-primary')}>Profile</a
|
||||
>
|
||||
<a
|
||||
href="/settings/account"
|
||||
class={cn($page.url.pathname === '/settings/account' && 'font-semibold text-primary')}
|
||||
class={cn(page.url.pathname === '/settings/account' && 'font-semibold text-primary')}
|
||||
>Account</a
|
||||
>
|
||||
</nav>
|
||||
|
|
|
|||
59
src/routes/(app)/(protected)/settings/+page.server.ts
Normal file
59
src/routes/(app)/(protected)/settings/+page.server.ts
Normal file
|
|
@ -0,0 +1,59 @@
|
|||
import { notSignedInMessage } from '$lib/utils/flashMessages';
|
||||
import { redirect } from 'sveltekit-flash-message/server';
|
||||
import type { PageServerLoad } from './$types';
|
||||
import { fail, message, setError, superValidate } from 'sveltekit-superforms/server';
|
||||
import { zod } from 'sveltekit-superforms/adapters';
|
||||
import { updateProfileDto } from '$lib/dtos/settings/profile/update-profile.dto';
|
||||
import type { Actions } from '@sveltejs/kit';
|
||||
|
||||
export const load: PageServerLoad = async (event) => {
|
||||
const { parent } = event;
|
||||
const { authedUser } = await parent();
|
||||
|
||||
console.log('authedUser', authedUser);
|
||||
|
||||
if (!authedUser) {
|
||||
throw redirect(302, '/login', notSignedInMessage, event);
|
||||
}
|
||||
|
||||
const updateProfileForm = await superValidate(zod(updateProfileDto), {
|
||||
defaults: {
|
||||
first_name: authedUser?.first_name ?? '',
|
||||
last_name: authedUser?.last_name ?? '',
|
||||
username: authedUser?.username ?? '',
|
||||
},
|
||||
});
|
||||
|
||||
return {
|
||||
updateProfileForm,
|
||||
};
|
||||
};
|
||||
|
||||
export const actions: Actions = {
|
||||
updateProfile: async (event) => {
|
||||
const { locals } = event;
|
||||
const authedUser = await locals.getAuthedUser();
|
||||
|
||||
if (!authedUser) {
|
||||
throw redirect(302, '/login', notSignedInMessage, event);
|
||||
}
|
||||
|
||||
const form = await superValidate(event, zod(updateProfileDto));
|
||||
|
||||
if (!form.valid) {
|
||||
return fail(400, {
|
||||
form,
|
||||
});
|
||||
}
|
||||
|
||||
console.log('form data', form.data);
|
||||
|
||||
const { error } = await locals.api.users.me.profile.$put({ json: form.data }).then(locals.parseApiResponse);
|
||||
|
||||
if (error) {
|
||||
return setError(form, 'username', error);
|
||||
}
|
||||
|
||||
return message(form, { text: 'Profile updated', type: 'success' });
|
||||
},
|
||||
};
|
||||
|
|
@ -0,0 +1,7 @@
|
|||
<script>
|
||||
import UpdateProfileCard from './update-profile-card.svelte';
|
||||
|
||||
let { data } = $props();
|
||||
</script>
|
||||
|
||||
<UpdateProfileCard updateProfileForm={data.updateProfileForm} />
|
||||
|
|
@ -0,0 +1,83 @@
|
|||
<script lang="ts">
|
||||
import * as Card from '$lib/components/ui/card';
|
||||
import * as Form from '$lib/components/ui/form';
|
||||
import { Input } from '$lib/components/ui/input';
|
||||
import { updateProfileDto, type UpdateProfileDto } from '$lib/dtos/settings/profile/update-profile.dto.js';
|
||||
import { fileProxy, superForm } from 'sveltekit-superforms/client';
|
||||
import { zodClient } from 'sveltekit-superforms/adapters';
|
||||
|
||||
|
||||
const { updateProfileForm }: { updateProfileForm: UpdateProfileDto } = $props();
|
||||
|
||||
const sf_update_profile = superForm(updateProfileForm, {
|
||||
validators: zodClient(updateProfileDto),
|
||||
resetForm: false,
|
||||
});
|
||||
|
||||
const {
|
||||
form: updateProfileFormData,
|
||||
enhance: updateProfileEnhance,
|
||||
submit: updateProfileFormSubmit,
|
||||
} = sf_update_profile;
|
||||
|
||||
const avatar = fileProxy(updateProfileFormData, 'avatar')
|
||||
</script>
|
||||
|
||||
<svelte:head>
|
||||
<title>Acme | Settings</title>
|
||||
</svelte:head>
|
||||
|
||||
<Card.Root>
|
||||
<Card.Header>
|
||||
<Card.Title>Update Profile</Card.Title>
|
||||
</Card.Header>
|
||||
<Card.Content>
|
||||
<form method="POST" action="?/updateProfile" use:updateProfileEnhance>
|
||||
<h3>Your Profile</h3>
|
||||
<hr class="!border-t-2 mt-2 mb-6" />
|
||||
<Form.Field form={sf_update_profile} name="username">
|
||||
<Form.Control>
|
||||
{#snippet children({ props })}
|
||||
<Form.Label for="username">Username</Form.Label>
|
||||
<Input autocomplete="username" {...props} bind:value={$updateProfileFormData.username} />
|
||||
{/snippet}
|
||||
</Form.Control>
|
||||
<Form.Description />
|
||||
<Form.FieldErrors />
|
||||
</Form.Field>
|
||||
<Form.Field form={sf_update_profile} name="first_name">
|
||||
<Form.Control>
|
||||
{#snippet children({ props })}
|
||||
<Form.Label for="first_name">First Name</Form.Label>
|
||||
<Input {...props} bind:value={$updateProfileFormData.first_name} />
|
||||
{/snippet}
|
||||
</Form.Control>
|
||||
<Form.Description />
|
||||
<Form.FieldErrors />
|
||||
</Form.Field>
|
||||
<Form.Field form={sf_update_profile} name="last_name">
|
||||
<Form.Control>
|
||||
{#snippet children({ props })}
|
||||
<Form.Label for="last_name">Last Name</Form.Label>
|
||||
<Input {...props} bind:value={$updateProfileFormData.last_name} />
|
||||
{/snippet}
|
||||
</Form.Control>
|
||||
<Form.Description />
|
||||
<Form.FieldErrors />
|
||||
</Form.Field>
|
||||
<!-- <Form.Field form={sf_update_profile} name="avatar">
|
||||
<Form.Control>
|
||||
{#snippet children({ props })}
|
||||
<Form.Label for="avatar">Avatar</Form.Label>
|
||||
<Input type="file" accept="image/png, image/jpg, image/jpeg, image/webp" name="avatar" enctype="multipart/form-data" bind:files={$avatar} />
|
||||
{/snippet}
|
||||
</Form.Control>
|
||||
<Form.Description />
|
||||
<Form.FieldErrors />
|
||||
</Form.Field> -->
|
||||
</form>
|
||||
</Card.Content>
|
||||
<Card.Footer class="border-t px-6 py-4">
|
||||
<Form.Button onclick={() => updateProfileFormSubmit()}>Update Profile</Form.Button>
|
||||
</Card.Footer>
|
||||
</Card.Root>
|
||||
Loading…
Reference in a new issue