From 3ac7de641f3618fa8ed9c2b0715ac8c605950498 Mon Sep 17 00:00:00 2001 From: Bradley Shellnut Date: Sun, 18 Aug 2024 20:28:15 -0700 Subject: [PATCH] Update shadcn, add biomejs, and implementing profile pages. --- biome.json | 52 +++ docker-compose.yaml | 33 +- package.json | 15 +- pnpm-lock.yaml | 329 +++++++++++------- policies/.cerbos.yaml | 8 + policies/ticket.yaml | 26 ++ policies/ticket_test.yaml | 43 +++ src/lib/components/ui/button/index.ts | 4 +- .../ui/form/form-description.svelte | 2 +- .../ui/form/form-field-errors.svelte | 2 +- src/lib/components/ui/form/form-legend.svelte | 2 +- src/lib/components/ui/input/index.ts | 6 +- src/lib/components/ui/input/input.svelte | 13 +- src/lib/dtos/signup-username-email.dto.ts | 10 +- src/lib/dtos/update-email.dto.ts | 11 + src/lib/dtos/update-profile.dto.ts | 23 ++ .../server/api/controllers/iam.controller.ts | 16 + .../infrastructure/database/seeds/roles.ts | 4 +- src/lib/server/api/services/iam.service.ts | 20 +- src/lib/server/api/services/users.service.ts | 6 +- .../(app)/(protected)/profile/+page.server.ts | 58 +-- .../(app)/(protected)/profile/+page.svelte | 6 +- src/routes/(auth)/sign-up/+page.server.ts | 14 - src/routes/(auth)/sign-up/+page.svelte | 3 +- 24 files changed, 512 insertions(+), 194 deletions(-) create mode 100644 biome.json create mode 100644 policies/.cerbos.yaml create mode 100644 policies/ticket.yaml create mode 100644 policies/ticket_test.yaml create mode 100644 src/lib/dtos/update-email.dto.ts create mode 100644 src/lib/dtos/update-profile.dto.ts diff --git a/biome.json b/biome.json new file mode 100644 index 0000000..7eaa0b2 --- /dev/null +++ b/biome.json @@ -0,0 +1,52 @@ +{ + "$schema": "https://biomejs.dev/schemas/1.8.3/schema.json", + "formatter": { + "enabled": true, + "formatWithErrors": false, + "indentStyle": "tab", + "indentWidth": 2, + "lineEnding": "lf", + "lineWidth": 100, + "attributePosition": "auto", + "ignore": [ + "**/.DS_Store", + "**/node_modules", + "./build", + "./.svelte-kit", + "./package", + "**/.env", + "**/.env.*", + "**/pnpm-lock.yaml", + "**/package-lock.json", + "**/yarn.lock" + ] + }, + "organizeImports": { "enabled": true }, + "linter": { "enabled": true, "rules": { "recommended": true } }, + "javascript": { + "formatter": { + "jsxQuoteStyle": "double", + "quoteProperties": "asNeeded", + "trailingCommas": "all", + "semicolons": "asNeeded", + "arrowParentheses": "always", + "bracketSpacing": true, + "bracketSameLine": false, + "quoteStyle": "single", + "attributePosition": "auto" + } + }, + "overrides": [ + { + "include": ["*.svelte"], + "linter": { + "rules": { + "style": { + "useConst": "off", + "useImportType": "off" + } + } + } + } + ] +} diff --git a/docker-compose.yaml b/docker-compose.yaml index 7cc5327..82b9871 100644 --- a/docker-compose.yaml +++ b/docker-compose.yaml @@ -15,20 +15,29 @@ services: - '6379:6379' volumes: - redis_data:/data - # caddy: - # image: caddy:latest - # restart: unless-stopped - # ports: - # - "80:80" - # - "443:443" - # - "443:443/udp" - # volumes: - # - ./Caddyfile:/etc/caddy/Caddyfile - # - ./site:/srv - # - caddy_data:/data - # - caddy_config:/config +# cerbos: +# image: ghcr.io/cerbos/cerbos:0.38.1 +# environment: +# CERBOS_NO_TELEMETRY: 1 +# ports: +# - '3592:3592' +# volumes: +# - ./policies:/policies +# caddy: +# image: caddy:latest +# restart: unless-stopped +# ports: +# - "80:80" +# - "443:443" +# - "443:443/udp" +# volumes: +# - ./Caddyfile:/etc/caddy/Caddyfile +# - ./site:/srv +# - caddy_data:/data +# - caddy_config:/config volumes: postgres_data: redis_data: +# policies_data: # caddy_data: # caddy_config: \ No newline at end of file diff --git a/package.json b/package.json index c8b2fa5..3829d3f 100644 --- a/package.json +++ b/package.json @@ -23,16 +23,17 @@ "test:unit": "vitest" }, "devDependencies": { + "@biomejs/biome": "1.8.3", "@faker-js/faker": "^8.4.1", "@melt-ui/pp": "^0.3.2", "@melt-ui/svelte": "^0.83.0", - "@playwright/test": "^1.46.0", + "@playwright/test": "^1.46.1", "@sveltejs/adapter-auto": "^3.2.4", "@sveltejs/enhanced-img": "^0.3.3", "@sveltejs/kit": "^2.5.22", "@sveltejs/vite-plugin-svelte": "^3.1.1", "@types/cookie": "^0.6.0", - "@types/node": "^20.14.15", + "@types/node": "^20.16.0", "@types/pg": "^8.11.6", "@typescript-eslint/eslint-plugin": "^7.18.0", "@typescript-eslint/parser": "^7.18.0", @@ -58,7 +59,7 @@ "svelte": "5.0.0-next.175", "svelte-check": "^3.8.5", "svelte-headless-table": "^0.18.2", - "svelte-meta-tags": "^3.1.2", + "svelte-meta-tags": "^3.1.3", "svelte-preprocess": "^6.0.2", "svelte-sequential-preprocessor": "^2.0.1", "sveltekit-flash-message": "^2.4.4", @@ -69,13 +70,13 @@ "tslib": "^2.6.3", "tsx": "^4.17.0", "typescript": "^5.5.4", - "vite": "^5.4.0", + "vite": "^5.4.1", "vitest": "^1.6.0", "zod": "^3.23.8" }, "type": "module", "dependencies": { - "@fontsource/fira-mono": "^5.0.13", + "@fontsource/fira-mono": "^5.0.14", "@hono/zod-validator": "^0.2.2", "@iconify-icons/line-md": "^1.2.30", "@iconify-icons/mdi": "^1.2.48", @@ -92,7 +93,7 @@ "arctic": "^1.9.2", "bits-ui": "^0.21.13", "boardgamegeekclient": "^1.9.1", - "bullmq": "^5.12.5", + "bullmq": "^5.12.9", "class-variance-authority": "^0.7.0", "clsx": "^2.1.1", "cookie": "^0.6.0", @@ -102,7 +103,7 @@ "feather-icons": "^4.29.2", "formsnap": "^1.0.1", "handlebars": "^4.7.8", - "hono": "^4.5.5", + "hono": "^4.5.6", "hono-rate-limiter": "^0.4.0", "html-entities": "^2.5.2", "iconify-icon": "^2.1.0", diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml index ba40219..f66fdcc 100644 --- a/pnpm-lock.yaml +++ b/pnpm-lock.yaml @@ -9,11 +9,11 @@ importers: .: dependencies: '@fontsource/fira-mono': - specifier: ^5.0.13 - version: 5.0.13 + specifier: ^5.0.14 + version: 5.0.14 '@hono/zod-validator': specifier: ^0.2.2 - version: 0.2.2(hono@4.5.5)(zod@3.23.8) + version: 0.2.2(hono@4.5.6)(zod@3.23.8) '@iconify-icons/line-md': specifier: ^1.2.30 version: 1.2.30 @@ -40,10 +40,10 @@ importers: version: 2.6.2 '@sveltejs/adapter-node': specifier: ^5.2.2 - version: 5.2.2(@sveltejs/kit@2.5.22(@sveltejs/vite-plugin-svelte@3.1.1(svelte@5.0.0-next.175)(vite@5.4.0(@types/node@20.14.15)(sass@1.77.8)))(svelte@5.0.0-next.175)(vite@5.4.0(@types/node@20.14.15)(sass@1.77.8))) + version: 5.2.2(@sveltejs/kit@2.5.22(@sveltejs/vite-plugin-svelte@3.1.1(svelte@5.0.0-next.175)(vite@5.4.1(@types/node@20.16.0)(sass@1.77.8)))(svelte@5.0.0-next.175)(vite@5.4.1(@types/node@20.16.0)(sass@1.77.8))) '@sveltejs/adapter-vercel': specifier: ^5.4.3 - version: 5.4.3(@sveltejs/kit@2.5.22(@sveltejs/vite-plugin-svelte@3.1.1(svelte@5.0.0-next.175)(vite@5.4.0(@types/node@20.14.15)(sass@1.77.8)))(svelte@5.0.0-next.175)(vite@5.4.0(@types/node@20.14.15)(sass@1.77.8))) + version: 5.4.3(@sveltejs/kit@2.5.22(@sveltejs/vite-plugin-svelte@3.1.1(svelte@5.0.0-next.175)(vite@5.4.1(@types/node@20.16.0)(sass@1.77.8)))(svelte@5.0.0-next.175)(vite@5.4.1(@types/node@20.16.0)(sass@1.77.8))) '@types/feather-icons': specifier: ^4.29.4 version: 4.29.4 @@ -60,8 +60,8 @@ importers: specifier: ^1.9.1 version: 1.9.1 bullmq: - specifier: ^5.12.5 - version: 5.12.5 + specifier: ^5.12.9 + version: 5.12.9 class-variance-authority: specifier: ^0.7.0 version: 0.7.0 @@ -85,16 +85,16 @@ importers: version: 4.29.2 formsnap: specifier: ^1.0.1 - version: 1.0.1(svelte@5.0.0-next.175)(sveltekit-superforms@2.17.0(@sveltejs/kit@2.5.22(@sveltejs/vite-plugin-svelte@3.1.1(svelte@5.0.0-next.175)(vite@5.4.0(@types/node@20.14.15)(sass@1.77.8)))(svelte@5.0.0-next.175)(vite@5.4.0(@types/node@20.14.15)(sass@1.77.8)))(svelte@5.0.0-next.175)) + version: 1.0.1(svelte@5.0.0-next.175)(sveltekit-superforms@2.17.0(@sveltejs/kit@2.5.22(@sveltejs/vite-plugin-svelte@3.1.1(svelte@5.0.0-next.175)(vite@5.4.1(@types/node@20.16.0)(sass@1.77.8)))(svelte@5.0.0-next.175)(vite@5.4.1(@types/node@20.16.0)(sass@1.77.8)))(svelte@5.0.0-next.175)) handlebars: specifier: ^4.7.8 version: 4.7.8 hono: - specifier: ^4.5.5 - version: 4.5.5 + specifier: ^4.5.6 + version: 4.5.6 hono-rate-limiter: specifier: ^0.4.0 - version: 0.4.0(hono@4.5.5) + version: 0.4.0(hono@4.5.6) html-entities: specifier: ^2.5.2 version: 2.5.2 @@ -148,10 +148,10 @@ importers: version: 2.5.2 tailwind-variants: specifier: ^0.2.1 - version: 0.2.1(tailwindcss@3.4.10(ts-node@10.9.2(@types/node@20.14.15)(typescript@5.5.4))) + version: 0.2.1(tailwindcss@3.4.10(ts-node@10.9.2(@types/node@20.16.0)(typescript@5.5.4))) tailwindcss-animate: specifier: ^1.0.7 - version: 1.0.7(tailwindcss@3.4.10(ts-node@10.9.2(@types/node@20.14.15)(typescript@5.5.4))) + version: 1.0.7(tailwindcss@3.4.10(ts-node@10.9.2(@types/node@20.16.0)(typescript@5.5.4))) tsyringe: specifier: ^4.8.0 version: 4.8.0 @@ -159,6 +159,9 @@ importers: specifier: ^3.23.2 version: 3.23.2(zod@3.23.8) devDependencies: + '@biomejs/biome': + specifier: 1.8.3 + version: 1.8.3 '@faker-js/faker': specifier: ^8.4.1 version: 8.4.1 @@ -169,26 +172,26 @@ importers: specifier: ^0.83.0 version: 0.83.0(svelte@5.0.0-next.175) '@playwright/test': - specifier: ^1.46.0 - version: 1.46.0 + specifier: ^1.46.1 + version: 1.46.1 '@sveltejs/adapter-auto': specifier: ^3.2.4 - version: 3.2.4(@sveltejs/kit@2.5.22(@sveltejs/vite-plugin-svelte@3.1.1(svelte@5.0.0-next.175)(vite@5.4.0(@types/node@20.14.15)(sass@1.77.8)))(svelte@5.0.0-next.175)(vite@5.4.0(@types/node@20.14.15)(sass@1.77.8))) + version: 3.2.4(@sveltejs/kit@2.5.22(@sveltejs/vite-plugin-svelte@3.1.1(svelte@5.0.0-next.175)(vite@5.4.1(@types/node@20.16.0)(sass@1.77.8)))(svelte@5.0.0-next.175)(vite@5.4.1(@types/node@20.16.0)(sass@1.77.8))) '@sveltejs/enhanced-img': specifier: ^0.3.3 - version: 0.3.3(rollup@4.18.1)(svelte@5.0.0-next.175)(vite@5.4.0(@types/node@20.14.15)(sass@1.77.8)) + version: 0.3.3(rollup@4.18.1)(svelte@5.0.0-next.175)(vite@5.4.1(@types/node@20.16.0)(sass@1.77.8)) '@sveltejs/kit': specifier: ^2.5.22 - version: 2.5.22(@sveltejs/vite-plugin-svelte@3.1.1(svelte@5.0.0-next.175)(vite@5.4.0(@types/node@20.14.15)(sass@1.77.8)))(svelte@5.0.0-next.175)(vite@5.4.0(@types/node@20.14.15)(sass@1.77.8)) + version: 2.5.22(@sveltejs/vite-plugin-svelte@3.1.1(svelte@5.0.0-next.175)(vite@5.4.1(@types/node@20.16.0)(sass@1.77.8)))(svelte@5.0.0-next.175)(vite@5.4.1(@types/node@20.16.0)(sass@1.77.8)) '@sveltejs/vite-plugin-svelte': specifier: ^3.1.1 - version: 3.1.1(svelte@5.0.0-next.175)(vite@5.4.0(@types/node@20.14.15)(sass@1.77.8)) + version: 3.1.1(svelte@5.0.0-next.175)(vite@5.4.1(@types/node@20.16.0)(sass@1.77.8)) '@types/cookie': specifier: ^0.6.0 version: 0.6.0 '@types/node': - specifier: ^20.14.15 - version: 20.14.15 + specifier: ^20.16.0 + version: 20.16.0 '@types/pg': specifier: ^8.11.6 version: 8.11.6 @@ -212,7 +215,7 @@ importers: version: 9.1.0(eslint@8.57.0) eslint-plugin-svelte: specifier: ^2.43.0 - version: 2.43.0(eslint@8.57.0)(svelte@5.0.0-next.175)(ts-node@10.9.2(@types/node@20.14.15)(typescript@5.5.4)) + version: 2.43.0(eslint@8.57.0)(svelte@5.0.0-next.175)(ts-node@10.9.2(@types/node@20.16.0)(typescript@5.5.4)) just-clone: specifier: ^6.2.0 version: 6.2.0 @@ -265,8 +268,8 @@ importers: specifier: ^0.18.2 version: 0.18.2(svelte@5.0.0-next.175) svelte-meta-tags: - specifier: ^3.1.2 - version: 3.1.2(svelte@5.0.0-next.175)(typescript@5.5.4) + specifier: ^3.1.3 + version: 3.1.3(svelte@5.0.0-next.175)(typescript@5.5.4) svelte-preprocess: specifier: ^6.0.2 version: 6.0.2(postcss-load-config@5.1.0(jiti@1.21.6)(postcss@8.4.41)(tsx@4.17.0))(postcss@8.4.41)(sass@1.77.8)(svelte@5.0.0-next.175)(typescript@5.5.4) @@ -275,19 +278,19 @@ importers: version: 2.0.1 sveltekit-flash-message: specifier: ^2.4.4 - version: 2.4.4(@sveltejs/kit@2.5.22(@sveltejs/vite-plugin-svelte@3.1.1(svelte@5.0.0-next.175)(vite@5.4.0(@types/node@20.14.15)(sass@1.77.8)))(svelte@5.0.0-next.175)(vite@5.4.0(@types/node@20.14.15)(sass@1.77.8)))(svelte@5.0.0-next.175) + version: 2.4.4(@sveltejs/kit@2.5.22(@sveltejs/vite-plugin-svelte@3.1.1(svelte@5.0.0-next.175)(vite@5.4.1(@types/node@20.16.0)(sass@1.77.8)))(svelte@5.0.0-next.175)(vite@5.4.1(@types/node@20.16.0)(sass@1.77.8)))(svelte@5.0.0-next.175) sveltekit-rate-limiter: specifier: ^0.5.2 - version: 0.5.2(@sveltejs/kit@2.5.22(@sveltejs/vite-plugin-svelte@3.1.1(svelte@5.0.0-next.175)(vite@5.4.0(@types/node@20.14.15)(sass@1.77.8)))(svelte@5.0.0-next.175)(vite@5.4.0(@types/node@20.14.15)(sass@1.77.8))) + version: 0.5.2(@sveltejs/kit@2.5.22(@sveltejs/vite-plugin-svelte@3.1.1(svelte@5.0.0-next.175)(vite@5.4.1(@types/node@20.16.0)(sass@1.77.8)))(svelte@5.0.0-next.175)(vite@5.4.1(@types/node@20.16.0)(sass@1.77.8))) sveltekit-superforms: specifier: ^2.17.0 - version: 2.17.0(@sveltejs/kit@2.5.22(@sveltejs/vite-plugin-svelte@3.1.1(svelte@5.0.0-next.175)(vite@5.4.0(@types/node@20.14.15)(sass@1.77.8)))(svelte@5.0.0-next.175)(vite@5.4.0(@types/node@20.14.15)(sass@1.77.8)))(svelte@5.0.0-next.175) + version: 2.17.0(@sveltejs/kit@2.5.22(@sveltejs/vite-plugin-svelte@3.1.1(svelte@5.0.0-next.175)(vite@5.4.1(@types/node@20.16.0)(sass@1.77.8)))(svelte@5.0.0-next.175)(vite@5.4.1(@types/node@20.16.0)(sass@1.77.8)))(svelte@5.0.0-next.175) tailwindcss: specifier: ^3.4.10 - version: 3.4.10(ts-node@10.9.2(@types/node@20.14.15)(typescript@5.5.4)) + version: 3.4.10(ts-node@10.9.2(@types/node@20.16.0)(typescript@5.5.4)) ts-node: specifier: ^10.9.2 - version: 10.9.2(@types/node@20.14.15)(typescript@5.5.4) + version: 10.9.2(@types/node@20.16.0)(typescript@5.5.4) tslib: specifier: ^2.6.3 version: 2.6.3 @@ -298,11 +301,11 @@ importers: specifier: ^5.5.4 version: 5.5.4 vite: - specifier: ^5.4.0 - version: 5.4.0(@types/node@20.14.15)(sass@1.77.8) + specifier: ^5.4.1 + version: 5.4.1(@types/node@20.16.0)(sass@1.77.8) vitest: specifier: ^1.6.0 - version: 1.6.0(@types/node@20.14.15)(sass@1.77.8) + version: 1.6.0(@types/node@20.16.0)(sass@1.77.8) zod: specifier: ^3.23.8 version: 3.23.8 @@ -327,6 +330,59 @@ packages: resolution: {integrity: sha512-5F7SDGs1T72ZczbRwbGO9lQi0NLjQxzl6i4lJxLxfW9U5UluCSyEJeniWvnhl3/euNiqQVbo8zruhsDfid0esA==} engines: {node: '>=6.9.0'} + '@biomejs/biome@1.8.3': + resolution: {integrity: sha512-/uUV3MV+vyAczO+vKrPdOW0Iaet7UnJMU4bNMinggGJTAnBPjCoLEYcyYtYHNnUNYlv4xZMH6hVIQCAozq8d5w==} + engines: {node: '>=14.21.3'} + hasBin: true + + '@biomejs/cli-darwin-arm64@1.8.3': + resolution: {integrity: sha512-9DYOjclFpKrH/m1Oz75SSExR8VKvNSSsLnVIqdnKexj6NwmiMlKk94Wa1kZEdv6MCOHGHgyyoV57Cw8WzL5n3A==} + engines: {node: '>=14.21.3'} + cpu: [arm64] + os: [darwin] + + '@biomejs/cli-darwin-x64@1.8.3': + resolution: {integrity: sha512-UeW44L/AtbmOF7KXLCoM+9PSgPo0IDcyEUfIoOXYeANaNXXf9mLUwV1GeF2OWjyic5zj6CnAJ9uzk2LT3v/wAw==} + engines: {node: '>=14.21.3'} + cpu: [x64] + os: [darwin] + + '@biomejs/cli-linux-arm64-musl@1.8.3': + resolution: {integrity: sha512-9yjUfOFN7wrYsXt/T/gEWfvVxKlnh3yBpnScw98IF+oOeCYb5/b/+K7YNqKROV2i1DlMjg9g/EcN9wvj+NkMuQ==} + engines: {node: '>=14.21.3'} + cpu: [arm64] + os: [linux] + + '@biomejs/cli-linux-arm64@1.8.3': + resolution: {integrity: sha512-fed2ji8s+I/m8upWpTJGanqiJ0rnlHOK3DdxsyVLZQ8ClY6qLuPc9uehCREBifRJLl/iJyQpHIRufLDeotsPtw==} + engines: {node: '>=14.21.3'} + cpu: [arm64] + os: [linux] + + '@biomejs/cli-linux-x64-musl@1.8.3': + resolution: {integrity: sha512-UHrGJX7PrKMKzPGoEsooKC9jXJMa28TUSMjcIlbDnIO4EAavCoVmNQaIuUSH0Ls2mpGMwUIf+aZJv657zfWWjA==} + engines: {node: '>=14.21.3'} + cpu: [x64] + os: [linux] + + '@biomejs/cli-linux-x64@1.8.3': + resolution: {integrity: sha512-I8G2QmuE1teISyT8ie1HXsjFRz9L1m5n83U1O6m30Kw+kPMPSKjag6QGUn+sXT8V+XWIZxFFBoTDEDZW2KPDDw==} + engines: {node: '>=14.21.3'} + cpu: [x64] + os: [linux] + + '@biomejs/cli-win32-arm64@1.8.3': + resolution: {integrity: sha512-J+Hu9WvrBevfy06eU1Na0lpc7uR9tibm9maHynLIoAjLZpQU3IW+OKHUtyL8p6/3pT2Ju5t5emReeIS2SAxhkQ==} + engines: {node: '>=14.21.3'} + cpu: [arm64] + os: [win32] + + '@biomejs/cli-win32-x64@1.8.3': + resolution: {integrity: sha512-/PJ59vA1pnQeKahemaQf4Nyj7IKUvGQSc3Ze1uIGi+Wvr1xF7rGobSrAAG01T/gUDG21vkDsZYM03NAmPiVkqg==} + engines: {node: '>=14.21.3'} + cpu: [x64] + os: [win32] + '@cspotcode/source-map-support@0.8.1': resolution: {integrity: sha512-IchNf6dN4tHoMFIn/7OE8LWZ19Y6q/67Bmf6vnGREv8RSbBVb9LPJxEcnwrcwX6ixSvaiGoomAUvu4YSxXrVgw==} engines: {node: '>=12'} @@ -1187,8 +1243,8 @@ packages: '@floating-ui/utils@0.2.4': resolution: {integrity: sha512-dWO2pw8hhi+WrXq1YJy2yCuWoL20PddgGaqTgVe4cOS9Q6qklXCiA1tJEqX6BEwRNSCP84/afac9hd4MS+zEUA==} - '@fontsource/fira-mono@5.0.13': - resolution: {integrity: sha512-fZDjR2BdAqmauEbTjcIT62zYzbOgDa5+IQH34D2k8Pxmy1T815mAqQkZciWZVQ9dc/BgdTtTUV9HJ2ulBNwchg==} + '@fontsource/fira-mono@5.0.14': + resolution: {integrity: sha512-4IKa+cuHipk/vr2frgZh4pyR2XcoQk/j3zmMlo8uuAGUB3IPLpQlgN6Qm5d3RfRZ7dXGlTn/PWiAJeU8bkmD4w==} '@gcornut/valibot-json-schema@0.31.0': resolution: {integrity: sha512-3xGptCurm23e7nuPQkdrE5rEs1FeTPHhAUsBuwwqG4/YeZLwJOoYZv+fmsppUEfo5y9lzUwNQrNqLS/q7HMc7g==} @@ -1642,8 +1698,8 @@ packages: resolution: {integrity: sha512-+1VkjdD0QBLPodGrJUeqarH8VAIvQODIbwh9XpP5Syisf7YoQgsJKPNFoqqLQlu+VQ/tVSshMR6loPMn8U+dPg==} engines: {node: '>=14'} - '@playwright/test@1.46.0': - resolution: {integrity: sha512-/QYft5VArOrGRP5pgkrfKksqsKA6CEFyGQ/gjNe6q0y4tZ1aaPfq4gIjudr1s3D+pXyrPRdsy4opKDrjBabE5w==} + '@playwright/test@1.46.1': + resolution: {integrity: sha512-Fq6SwLujA/DOIvNC2EL/SojJnkKf/rAwJ//APpJJHRyMi1PdKrY3Az+4XNQ51N4RTbItbIByQ0jgd1tayq1aeA==} engines: {node: '>=18'} hasBin: true @@ -2032,8 +2088,8 @@ packages: '@types/json-schema@7.0.15': resolution: {integrity: sha512-5+fP8P8MFNC+AyZCDxrB2pkZFPGzqQWUzpSeuuVLvm8VMcorNYavBqoFcxK8bQz4Qsbn4oUEEem4wDLfcysGHA==} - '@types/node@20.14.15': - resolution: {integrity: sha512-Fz1xDMCF/B00/tYSVMlmK7hVeLh7jE5f3B7X1/hmV0MJBwE27KlS7EvD/Yp+z1lm8mVhwV5w+n8jOZG8AfTlKw==} + '@types/node@20.16.0': + resolution: {integrity: sha512-vDxceJcoZhIVh67S568bm1UGZO0DX0hpplJZxzeXMKwIPLn190ec5RRxQ69BKhX44SUGIxxgMdDY557lGLKprQ==} '@types/pg@8.11.6': resolution: {integrity: sha512-/2WmmBXHLsfRqzfHW7BNZ8SbYzE8OSk7i3WjFYvfgRHj7S1xj+16Je5fUKv3lVdVzk/zn9TXOqf+avFCFIE0yQ==} @@ -2320,8 +2376,8 @@ packages: resolution: {integrity: sha512-zhaCDicdLuWN5UbN5IMnFqNMhNfo919sH85y2/ea+5Yg9TsTkeZxpL+JLbp6cgYFS4sRLp3YV4S6yDuqVWHYOw==} engines: {node: '>=6'} - bullmq@5.12.5: - resolution: {integrity: sha512-lchCvFuPdaIbq01qnyS7MOt2piPeCDHzCqIxNAQEgDSzZ+Eb4RBboUUMgmW90UtMjV46mEqsWY9B1l/7/C13SA==} + bullmq@5.12.9: + resolution: {integrity: sha512-34YW4NaC6IfuAtwdllNkBSEP9/sq9bjpvlvbdSv1JXQUzqbey1+DZTvecM8SdewsNKa0RxuwYx/KATe7iXvH7A==} bytes@3.1.2: resolution: {integrity: sha512-/Nf7TyzTx6S3yRJObOAV7956r8cr2+Oj8AC5dt8wSP3BQAoeX58NoHyCU8P8zGkNXStjTSi6fzO6F0pBdcYbEg==} @@ -3090,8 +3146,8 @@ packages: peerDependencies: hono: ^4.1.1 - hono@4.5.5: - resolution: {integrity: sha512-fXBXHqaVfimWofbelLXci8pZyIwBMkDIwCa4OwZvK+xVbEyYLELVP4DfbGaj1aEM6ZY3hHgs4qLvCO2ChkhgQw==} + hono@4.5.6: + resolution: {integrity: sha512-9SuUC/zLQv8YAcnIxJko0KCeLI0Q6menPsDWuJ9jaH+r8ZkVXeLqeLs1QJXCPKKbURAWj9x0SJBSFh803EnAUw==} engines: {node: '>=16.0.0'} html-entities@2.5.2: @@ -3732,13 +3788,13 @@ packages: pkg-types@1.1.0: resolution: {integrity: sha512-/RpmvKdxKf8uILTtoOhAgf30wYbP2Qw+L9p3Rvshx1JZVX+XQNZQFjlbmGHEGIm4CkVPlSn+NXmIM8+9oWQaSA==} - playwright-core@1.46.0: - resolution: {integrity: sha512-9Y/d5UIwuJk8t3+lhmMSAJyNP1BUC/DqP3cQJDQQL/oWqAiuPTLgy7Q5dzglmTLwcBRdetzgNM/gni7ckfTr6A==} + playwright-core@1.46.1: + resolution: {integrity: sha512-h9LqIQaAv+CYvWzsZ+h3RsrqCStkBHlgo6/TJlFst3cOTlLghBQlJwPOZKQJTKNaD3QIB7aAVQ+gfWbN3NXB7A==} engines: {node: '>=18'} hasBin: true - playwright@1.46.0: - resolution: {integrity: sha512-XYJ5WvfefWONh1uPAUAi0H2xXV5S3vrtcnXe6uAOgdGi3aSpqOSXX08IAjXW34xitfuOJsvXU5anXZxPSEQiJw==} + playwright@1.46.1: + resolution: {integrity: sha512-oPcr1yqoXLCkgKtD5eNUPLiN40rYEM39odNpIb6VE6S7/15gJmA1NzVv6zJYusV0e7tzvkU/utBFNa/Kpxmwng==} engines: {node: '>=18'} hasBin: true @@ -4402,8 +4458,8 @@ packages: svelte-lazy-loader@1.0.0: resolution: {integrity: sha512-AZD6R60vksyojn21FgXLglmBiBB9K5Dkdu0hdGrLbCaRCYT68IsWkZfRUqKhMx1IfzqWcZQ8X9y/f+Ih0oNQkQ==} - svelte-meta-tags@3.1.2: - resolution: {integrity: sha512-zw8xSA10ce7atFO1o0N1x41+qU+HBnpGx8KcVRAWPy5iiRdO6fvUFMg6VwJVgMhLSBEUTZXKAvMALLUssbCoCw==} + svelte-meta-tags@3.1.3: + resolution: {integrity: sha512-iIdJgxKdMUqFGR4m88jBE9KTSO2jdKE5CRjyRtAjdevW51jL4TtDZwL7GOtr5Fd2dw/+jyQIPD7APATP191qIA==} peerDependencies: svelte: ^3.55.0 || ^4.0.0 @@ -4688,8 +4744,8 @@ packages: ultrahtml@1.5.3: resolution: {integrity: sha512-GykOvZwgDWZlTQMtp5jrD4BVL+gNn2NVlVafjcFUJ7taY20tqYdwdoWBFy6GBJsNTZe1GkGPkSl5knQAjtgceg==} - undici-types@5.26.5: - resolution: {integrity: sha512-JlCMO+ehdEIKqlFxk6IfVoAUVmgz7cU7zD/h9XZ0qzeosSHmUJVOzSQvvYSYWXkFXC+IfLKSIffhv0sVZup6pA==} + undici-types@6.19.6: + resolution: {integrity: sha512-e/vggGopEfTKSvj4ihnOLTsqhrKRN3LeO6qSN/GxohhuRv8qH9bNQ4B8W7e/vFL+0XTnmHPB4/kegunZGA4Org==} unfetch@4.2.0: resolution: {integrity: sha512-F9p7yYCn6cIW9El1zi0HI6vqpeIvBsr3dSuRO6Xuppb1u5rXpCPmMvLSyECLhybr9isec8Ohl0hPekMVrEinDA==} @@ -4747,8 +4803,8 @@ packages: engines: {node: ^18.0.0 || >=20.0.0} hasBin: true - vite@5.4.0: - resolution: {integrity: sha512-5xokfMX0PIiwCMCMb9ZJcMyh5wbBun0zUzKib+L65vAZ8GY9ePZMXxFrHbr/Kyll2+LSCY7xtERPpxkBDKngwg==} + vite@5.4.1: + resolution: {integrity: sha512-1oE6yuNXssjrZdblI9AfBbHCC41nnyoVoEZxQnID6yvQZAFBzxxkqoFLtHUMkYunL8hwOLEjgTuxpkRxvba3kA==} engines: {node: ^18.0.0 || >=20.0.0} hasBin: true peerDependencies: @@ -4938,6 +4994,41 @@ snapshots: regenerator-runtime: 0.14.1 optional: true + '@biomejs/biome@1.8.3': + optionalDependencies: + '@biomejs/cli-darwin-arm64': 1.8.3 + '@biomejs/cli-darwin-x64': 1.8.3 + '@biomejs/cli-linux-arm64': 1.8.3 + '@biomejs/cli-linux-arm64-musl': 1.8.3 + '@biomejs/cli-linux-x64': 1.8.3 + '@biomejs/cli-linux-x64-musl': 1.8.3 + '@biomejs/cli-win32-arm64': 1.8.3 + '@biomejs/cli-win32-x64': 1.8.3 + + '@biomejs/cli-darwin-arm64@1.8.3': + optional: true + + '@biomejs/cli-darwin-x64@1.8.3': + optional: true + + '@biomejs/cli-linux-arm64-musl@1.8.3': + optional: true + + '@biomejs/cli-linux-arm64@1.8.3': + optional: true + + '@biomejs/cli-linux-x64-musl@1.8.3': + optional: true + + '@biomejs/cli-linux-x64@1.8.3': + optional: true + + '@biomejs/cli-win32-arm64@1.8.3': + optional: true + + '@biomejs/cli-win32-x64@1.8.3': + optional: true + '@cspotcode/source-map-support@0.8.1': dependencies: '@jridgewell/trace-mapping': 0.3.9 @@ -5537,7 +5628,7 @@ snapshots: '@floating-ui/utils@0.2.4': {} - '@fontsource/fira-mono@5.0.13': {} + '@fontsource/fira-mono@5.0.14': {} '@gcornut/valibot-json-schema@0.31.0': dependencies: @@ -5556,9 +5647,9 @@ snapshots: '@hapi/hoek': 9.3.0 optional: true - '@hono/zod-validator@0.2.2(hono@4.5.5)(zod@3.23.8)': + '@hono/zod-validator@0.2.2(hono@4.5.6)(zod@3.23.8)': dependencies: - hono: 4.5.5 + hono: 4.5.6 zod: 3.23.8 '@humanwhocodes/config-array@0.11.14': @@ -5925,9 +6016,9 @@ snapshots: '@pkgjs/parseargs@0.11.0': optional: true - '@playwright/test@1.46.0': + '@playwright/test@1.46.1': dependencies: - playwright: 1.46.0 + playwright: 1.46.1 '@polka/url@1.0.0-next.25': {} @@ -6148,41 +6239,41 @@ snapshots: '@sodaru/yup-to-json-schema@2.0.1': optional: true - '@sveltejs/adapter-auto@3.2.4(@sveltejs/kit@2.5.22(@sveltejs/vite-plugin-svelte@3.1.1(svelte@5.0.0-next.175)(vite@5.4.0(@types/node@20.14.15)(sass@1.77.8)))(svelte@5.0.0-next.175)(vite@5.4.0(@types/node@20.14.15)(sass@1.77.8)))': + '@sveltejs/adapter-auto@3.2.4(@sveltejs/kit@2.5.22(@sveltejs/vite-plugin-svelte@3.1.1(svelte@5.0.0-next.175)(vite@5.4.1(@types/node@20.16.0)(sass@1.77.8)))(svelte@5.0.0-next.175)(vite@5.4.1(@types/node@20.16.0)(sass@1.77.8)))': dependencies: - '@sveltejs/kit': 2.5.22(@sveltejs/vite-plugin-svelte@3.1.1(svelte@5.0.0-next.175)(vite@5.4.0(@types/node@20.14.15)(sass@1.77.8)))(svelte@5.0.0-next.175)(vite@5.4.0(@types/node@20.14.15)(sass@1.77.8)) + '@sveltejs/kit': 2.5.22(@sveltejs/vite-plugin-svelte@3.1.1(svelte@5.0.0-next.175)(vite@5.4.1(@types/node@20.16.0)(sass@1.77.8)))(svelte@5.0.0-next.175)(vite@5.4.1(@types/node@20.16.0)(sass@1.77.8)) import-meta-resolve: 4.1.0 - '@sveltejs/adapter-node@5.2.2(@sveltejs/kit@2.5.22(@sveltejs/vite-plugin-svelte@3.1.1(svelte@5.0.0-next.175)(vite@5.4.0(@types/node@20.14.15)(sass@1.77.8)))(svelte@5.0.0-next.175)(vite@5.4.0(@types/node@20.14.15)(sass@1.77.8)))': + '@sveltejs/adapter-node@5.2.2(@sveltejs/kit@2.5.22(@sveltejs/vite-plugin-svelte@3.1.1(svelte@5.0.0-next.175)(vite@5.4.1(@types/node@20.16.0)(sass@1.77.8)))(svelte@5.0.0-next.175)(vite@5.4.1(@types/node@20.16.0)(sass@1.77.8)))': dependencies: '@rollup/plugin-commonjs': 26.0.1(rollup@4.18.1) '@rollup/plugin-json': 6.1.0(rollup@4.18.1) '@rollup/plugin-node-resolve': 15.2.3(rollup@4.18.1) - '@sveltejs/kit': 2.5.22(@sveltejs/vite-plugin-svelte@3.1.1(svelte@5.0.0-next.175)(vite@5.4.0(@types/node@20.14.15)(sass@1.77.8)))(svelte@5.0.0-next.175)(vite@5.4.0(@types/node@20.14.15)(sass@1.77.8)) + '@sveltejs/kit': 2.5.22(@sveltejs/vite-plugin-svelte@3.1.1(svelte@5.0.0-next.175)(vite@5.4.1(@types/node@20.16.0)(sass@1.77.8)))(svelte@5.0.0-next.175)(vite@5.4.1(@types/node@20.16.0)(sass@1.77.8)) rollup: 4.18.1 - '@sveltejs/adapter-vercel@5.4.3(@sveltejs/kit@2.5.22(@sveltejs/vite-plugin-svelte@3.1.1(svelte@5.0.0-next.175)(vite@5.4.0(@types/node@20.14.15)(sass@1.77.8)))(svelte@5.0.0-next.175)(vite@5.4.0(@types/node@20.14.15)(sass@1.77.8)))': + '@sveltejs/adapter-vercel@5.4.3(@sveltejs/kit@2.5.22(@sveltejs/vite-plugin-svelte@3.1.1(svelte@5.0.0-next.175)(vite@5.4.1(@types/node@20.16.0)(sass@1.77.8)))(svelte@5.0.0-next.175)(vite@5.4.1(@types/node@20.16.0)(sass@1.77.8)))': dependencies: - '@sveltejs/kit': 2.5.22(@sveltejs/vite-plugin-svelte@3.1.1(svelte@5.0.0-next.175)(vite@5.4.0(@types/node@20.14.15)(sass@1.77.8)))(svelte@5.0.0-next.175)(vite@5.4.0(@types/node@20.14.15)(sass@1.77.8)) + '@sveltejs/kit': 2.5.22(@sveltejs/vite-plugin-svelte@3.1.1(svelte@5.0.0-next.175)(vite@5.4.1(@types/node@20.16.0)(sass@1.77.8)))(svelte@5.0.0-next.175)(vite@5.4.1(@types/node@20.16.0)(sass@1.77.8)) '@vercel/nft': 0.27.2 esbuild: 0.21.5 transitivePeerDependencies: - encoding - supports-color - '@sveltejs/enhanced-img@0.3.3(rollup@4.18.1)(svelte@5.0.0-next.175)(vite@5.4.0(@types/node@20.14.15)(sass@1.77.8))': + '@sveltejs/enhanced-img@0.3.3(rollup@4.18.1)(svelte@5.0.0-next.175)(vite@5.4.1(@types/node@20.16.0)(sass@1.77.8))': dependencies: magic-string: 0.30.10 svelte: 5.0.0-next.175 svelte-parse-markup: 0.1.5(svelte@5.0.0-next.175) - vite: 5.4.0(@types/node@20.14.15)(sass@1.77.8) + vite: 5.4.1(@types/node@20.16.0)(sass@1.77.8) vite-imagetools: 7.0.2(rollup@4.18.1) transitivePeerDependencies: - rollup - '@sveltejs/kit@2.5.22(@sveltejs/vite-plugin-svelte@3.1.1(svelte@5.0.0-next.175)(vite@5.4.0(@types/node@20.14.15)(sass@1.77.8)))(svelte@5.0.0-next.175)(vite@5.4.0(@types/node@20.14.15)(sass@1.77.8))': + '@sveltejs/kit@2.5.22(@sveltejs/vite-plugin-svelte@3.1.1(svelte@5.0.0-next.175)(vite@5.4.1(@types/node@20.16.0)(sass@1.77.8)))(svelte@5.0.0-next.175)(vite@5.4.1(@types/node@20.16.0)(sass@1.77.8))': dependencies: - '@sveltejs/vite-plugin-svelte': 3.1.1(svelte@5.0.0-next.175)(vite@5.4.0(@types/node@20.14.15)(sass@1.77.8)) + '@sveltejs/vite-plugin-svelte': 3.1.1(svelte@5.0.0-next.175)(vite@5.4.1(@types/node@20.16.0)(sass@1.77.8)) '@types/cookie': 0.6.0 cookie: 0.6.0 devalue: 5.0.0 @@ -6196,28 +6287,28 @@ snapshots: sirv: 2.0.4 svelte: 5.0.0-next.175 tiny-glob: 0.2.9 - vite: 5.4.0(@types/node@20.14.15)(sass@1.77.8) + vite: 5.4.1(@types/node@20.16.0)(sass@1.77.8) - '@sveltejs/vite-plugin-svelte-inspector@2.1.0(@sveltejs/vite-plugin-svelte@3.1.1(svelte@5.0.0-next.175)(vite@5.4.0(@types/node@20.14.15)(sass@1.77.8)))(svelte@5.0.0-next.175)(vite@5.4.0(@types/node@20.14.15)(sass@1.77.8))': + '@sveltejs/vite-plugin-svelte-inspector@2.1.0(@sveltejs/vite-plugin-svelte@3.1.1(svelte@5.0.0-next.175)(vite@5.4.1(@types/node@20.16.0)(sass@1.77.8)))(svelte@5.0.0-next.175)(vite@5.4.1(@types/node@20.16.0)(sass@1.77.8))': dependencies: - '@sveltejs/vite-plugin-svelte': 3.1.1(svelte@5.0.0-next.175)(vite@5.4.0(@types/node@20.14.15)(sass@1.77.8)) + '@sveltejs/vite-plugin-svelte': 3.1.1(svelte@5.0.0-next.175)(vite@5.4.1(@types/node@20.16.0)(sass@1.77.8)) debug: 4.3.4 svelte: 5.0.0-next.175 - vite: 5.4.0(@types/node@20.14.15)(sass@1.77.8) + vite: 5.4.1(@types/node@20.16.0)(sass@1.77.8) transitivePeerDependencies: - supports-color - '@sveltejs/vite-plugin-svelte@3.1.1(svelte@5.0.0-next.175)(vite@5.4.0(@types/node@20.14.15)(sass@1.77.8))': + '@sveltejs/vite-plugin-svelte@3.1.1(svelte@5.0.0-next.175)(vite@5.4.1(@types/node@20.16.0)(sass@1.77.8))': dependencies: - '@sveltejs/vite-plugin-svelte-inspector': 2.1.0(@sveltejs/vite-plugin-svelte@3.1.1(svelte@5.0.0-next.175)(vite@5.4.0(@types/node@20.14.15)(sass@1.77.8)))(svelte@5.0.0-next.175)(vite@5.4.0(@types/node@20.14.15)(sass@1.77.8)) + '@sveltejs/vite-plugin-svelte-inspector': 2.1.0(@sveltejs/vite-plugin-svelte@3.1.1(svelte@5.0.0-next.175)(vite@5.4.1(@types/node@20.16.0)(sass@1.77.8)))(svelte@5.0.0-next.175)(vite@5.4.1(@types/node@20.16.0)(sass@1.77.8)) debug: 4.3.4 deepmerge: 4.3.1 kleur: 4.1.5 magic-string: 0.30.10 svelte: 5.0.0-next.175 svelte-hmr: 0.16.0(svelte@5.0.0-next.175) - vite: 5.4.0(@types/node@20.14.15)(sass@1.77.8) - vitefu: 0.2.5(vite@5.4.0(@types/node@20.14.15)(sass@1.77.8)) + vite: 5.4.1(@types/node@20.16.0)(sass@1.77.8) + vitefu: 0.2.5(vite@5.4.1(@types/node@20.16.0)(sass@1.77.8)) transitivePeerDependencies: - supports-color @@ -6247,13 +6338,13 @@ snapshots: '@types/json-schema@7.0.15': optional: true - '@types/node@20.14.15': + '@types/node@20.16.0': dependencies: - undici-types: 5.26.5 + undici-types: 6.19.6 '@types/pg@8.11.6': dependencies: - '@types/node': 20.14.15 + '@types/node': 20.16.0 pg-protocol: 1.6.1 pg-types: 4.0.2 @@ -6600,7 +6691,7 @@ snapshots: builtin-modules@3.3.0: {} - bullmq@5.12.5: + bullmq@5.12.9: dependencies: cron-parser: 4.9.0 ioredis: 5.4.1 @@ -7035,7 +7126,7 @@ snapshots: dependencies: eslint: 8.57.0 - eslint-plugin-svelte@2.43.0(eslint@8.57.0)(svelte@5.0.0-next.175)(ts-node@10.9.2(@types/node@20.14.15)(typescript@5.5.4)): + eslint-plugin-svelte@2.43.0(eslint@8.57.0)(svelte@5.0.0-next.175)(ts-node@10.9.2(@types/node@20.16.0)(typescript@5.5.4)): dependencies: '@eslint-community/eslint-utils': 4.4.0(eslint@8.57.0) '@jridgewell/sourcemap-codec': 1.4.15 @@ -7044,7 +7135,7 @@ snapshots: esutils: 2.0.3 known-css-properties: 0.34.0 postcss: 8.4.41 - postcss-load-config: 3.1.4(postcss@8.4.41)(ts-node@10.9.2(@types/node@20.14.15)(typescript@5.5.4)) + postcss-load-config: 3.1.4(postcss@8.4.41)(ts-node@10.9.2(@types/node@20.16.0)(typescript@5.5.4)) postcss-safe-parser: 6.0.0(postcss@8.4.41) postcss-selector-parser: 6.1.0 semver: 7.6.2 @@ -7271,11 +7362,11 @@ snapshots: cross-spawn: 7.0.3 signal-exit: 4.1.0 - formsnap@1.0.1(svelte@5.0.0-next.175)(sveltekit-superforms@2.17.0(@sveltejs/kit@2.5.22(@sveltejs/vite-plugin-svelte@3.1.1(svelte@5.0.0-next.175)(vite@5.4.0(@types/node@20.14.15)(sass@1.77.8)))(svelte@5.0.0-next.175)(vite@5.4.0(@types/node@20.14.15)(sass@1.77.8)))(svelte@5.0.0-next.175)): + formsnap@1.0.1(svelte@5.0.0-next.175)(sveltekit-superforms@2.17.0(@sveltejs/kit@2.5.22(@sveltejs/vite-plugin-svelte@3.1.1(svelte@5.0.0-next.175)(vite@5.4.1(@types/node@20.16.0)(sass@1.77.8)))(svelte@5.0.0-next.175)(vite@5.4.1(@types/node@20.16.0)(sass@1.77.8)))(svelte@5.0.0-next.175)): dependencies: nanoid: 5.0.7 svelte: 5.0.0-next.175 - sveltekit-superforms: 2.17.0(@sveltejs/kit@2.5.22(@sveltejs/vite-plugin-svelte@3.1.1(svelte@5.0.0-next.175)(vite@5.4.0(@types/node@20.14.15)(sass@1.77.8)))(svelte@5.0.0-next.175)(vite@5.4.0(@types/node@20.14.15)(sass@1.77.8)))(svelte@5.0.0-next.175) + sveltekit-superforms: 2.17.0(@sveltejs/kit@2.5.22(@sveltejs/vite-plugin-svelte@3.1.1(svelte@5.0.0-next.175)(vite@5.4.1(@types/node@20.16.0)(sass@1.77.8)))(svelte@5.0.0-next.175)(vite@5.4.1(@types/node@20.16.0)(sass@1.77.8)))(svelte@5.0.0-next.175) forwarded@0.2.0: {} @@ -7407,11 +7498,11 @@ snapshots: hex-rgb@4.3.0: {} - hono-rate-limiter@0.4.0(hono@4.5.5): + hono-rate-limiter@0.4.0(hono@4.5.6): dependencies: - hono: 4.5.5 + hono: 4.5.6 - hono@4.5.5: {} + hono@4.5.6: {} html-entities@2.5.2: {} @@ -7996,11 +8087,11 @@ snapshots: mlly: 1.7.0 pathe: 1.1.2 - playwright-core@1.46.0: {} + playwright-core@1.46.1: {} - playwright@1.46.0: + playwright@1.46.1: dependencies: - playwright-core: 1.46.0 + playwright-core: 1.46.1 optionalDependencies: fsevents: 2.3.2 @@ -8126,21 +8217,21 @@ snapshots: '@csstools/utilities': 1.0.0(postcss@8.4.41) postcss: 8.4.41 - postcss-load-config@3.1.4(postcss@8.4.41)(ts-node@10.9.2(@types/node@20.14.15)(typescript@5.5.4)): + postcss-load-config@3.1.4(postcss@8.4.41)(ts-node@10.9.2(@types/node@20.16.0)(typescript@5.5.4)): dependencies: lilconfig: 2.1.0 yaml: 1.10.2 optionalDependencies: postcss: 8.4.41 - ts-node: 10.9.2(@types/node@20.14.15)(typescript@5.5.4) + ts-node: 10.9.2(@types/node@20.16.0)(typescript@5.5.4) - postcss-load-config@4.0.2(postcss@8.4.41)(ts-node@10.9.2(@types/node@20.14.15)(typescript@5.5.4)): + postcss-load-config@4.0.2(postcss@8.4.41)(ts-node@10.9.2(@types/node@20.16.0)(typescript@5.5.4)): dependencies: lilconfig: 3.1.1 yaml: 2.4.3 optionalDependencies: postcss: 8.4.41 - ts-node: 10.9.2(@types/node@20.14.15)(typescript@5.5.4) + ts-node: 10.9.2(@types/node@20.16.0)(typescript@5.5.4) postcss-load-config@5.1.0(jiti@1.21.6)(postcss@8.4.41)(tsx@4.17.0): dependencies: @@ -8771,7 +8862,7 @@ snapshots: svelte-lazy-loader@1.0.0: {} - svelte-meta-tags@3.1.2(svelte@5.0.0-next.175)(typescript@5.5.4): + svelte-meta-tags@3.1.3(svelte@5.0.0-next.175)(typescript@5.5.4): dependencies: schema-dts: 1.1.2(typescript@5.5.4) svelte: 5.0.0-next.175 @@ -8856,19 +8947,19 @@ snapshots: magic-string: 0.30.10 zimmerframe: 1.1.2 - sveltekit-flash-message@2.4.4(@sveltejs/kit@2.5.22(@sveltejs/vite-plugin-svelte@3.1.1(svelte@5.0.0-next.175)(vite@5.4.0(@types/node@20.14.15)(sass@1.77.8)))(svelte@5.0.0-next.175)(vite@5.4.0(@types/node@20.14.15)(sass@1.77.8)))(svelte@5.0.0-next.175): + sveltekit-flash-message@2.4.4(@sveltejs/kit@2.5.22(@sveltejs/vite-plugin-svelte@3.1.1(svelte@5.0.0-next.175)(vite@5.4.1(@types/node@20.16.0)(sass@1.77.8)))(svelte@5.0.0-next.175)(vite@5.4.1(@types/node@20.16.0)(sass@1.77.8)))(svelte@5.0.0-next.175): dependencies: - '@sveltejs/kit': 2.5.22(@sveltejs/vite-plugin-svelte@3.1.1(svelte@5.0.0-next.175)(vite@5.4.0(@types/node@20.14.15)(sass@1.77.8)))(svelte@5.0.0-next.175)(vite@5.4.0(@types/node@20.14.15)(sass@1.77.8)) + '@sveltejs/kit': 2.5.22(@sveltejs/vite-plugin-svelte@3.1.1(svelte@5.0.0-next.175)(vite@5.4.1(@types/node@20.16.0)(sass@1.77.8)))(svelte@5.0.0-next.175)(vite@5.4.1(@types/node@20.16.0)(sass@1.77.8)) svelte: 5.0.0-next.175 - sveltekit-rate-limiter@0.5.2(@sveltejs/kit@2.5.22(@sveltejs/vite-plugin-svelte@3.1.1(svelte@5.0.0-next.175)(vite@5.4.0(@types/node@20.14.15)(sass@1.77.8)))(svelte@5.0.0-next.175)(vite@5.4.0(@types/node@20.14.15)(sass@1.77.8))): + sveltekit-rate-limiter@0.5.2(@sveltejs/kit@2.5.22(@sveltejs/vite-plugin-svelte@3.1.1(svelte@5.0.0-next.175)(vite@5.4.1(@types/node@20.16.0)(sass@1.77.8)))(svelte@5.0.0-next.175)(vite@5.4.1(@types/node@20.16.0)(sass@1.77.8))): dependencies: '@isaacs/ttlcache': 1.4.1 - '@sveltejs/kit': 2.5.22(@sveltejs/vite-plugin-svelte@3.1.1(svelte@5.0.0-next.175)(vite@5.4.0(@types/node@20.14.15)(sass@1.77.8)))(svelte@5.0.0-next.175)(vite@5.4.0(@types/node@20.14.15)(sass@1.77.8)) + '@sveltejs/kit': 2.5.22(@sveltejs/vite-plugin-svelte@3.1.1(svelte@5.0.0-next.175)(vite@5.4.1(@types/node@20.16.0)(sass@1.77.8)))(svelte@5.0.0-next.175)(vite@5.4.1(@types/node@20.16.0)(sass@1.77.8)) - sveltekit-superforms@2.17.0(@sveltejs/kit@2.5.22(@sveltejs/vite-plugin-svelte@3.1.1(svelte@5.0.0-next.175)(vite@5.4.0(@types/node@20.14.15)(sass@1.77.8)))(svelte@5.0.0-next.175)(vite@5.4.0(@types/node@20.14.15)(sass@1.77.8)))(svelte@5.0.0-next.175): + sveltekit-superforms@2.17.0(@sveltejs/kit@2.5.22(@sveltejs/vite-plugin-svelte@3.1.1(svelte@5.0.0-next.175)(vite@5.4.1(@types/node@20.16.0)(sass@1.77.8)))(svelte@5.0.0-next.175)(vite@5.4.1(@types/node@20.16.0)(sass@1.77.8)))(svelte@5.0.0-next.175): dependencies: - '@sveltejs/kit': 2.5.22(@sveltejs/vite-plugin-svelte@3.1.1(svelte@5.0.0-next.175)(vite@5.4.0(@types/node@20.14.15)(sass@1.77.8)))(svelte@5.0.0-next.175)(vite@5.4.0(@types/node@20.14.15)(sass@1.77.8)) + '@sveltejs/kit': 2.5.22(@sveltejs/vite-plugin-svelte@3.1.1(svelte@5.0.0-next.175)(vite@5.4.1(@types/node@20.16.0)(sass@1.77.8)))(svelte@5.0.0-next.175)(vite@5.4.1(@types/node@20.16.0)(sass@1.77.8)) devalue: 5.0.0 just-clone: 6.2.0 memoize-weak: 1.0.2 @@ -8893,16 +8984,16 @@ snapshots: tailwind-merge@2.5.2: {} - tailwind-variants@0.2.1(tailwindcss@3.4.10(ts-node@10.9.2(@types/node@20.14.15)(typescript@5.5.4))): + tailwind-variants@0.2.1(tailwindcss@3.4.10(ts-node@10.9.2(@types/node@20.16.0)(typescript@5.5.4))): dependencies: tailwind-merge: 2.5.2 - tailwindcss: 3.4.10(ts-node@10.9.2(@types/node@20.14.15)(typescript@5.5.4)) + tailwindcss: 3.4.10(ts-node@10.9.2(@types/node@20.16.0)(typescript@5.5.4)) - tailwindcss-animate@1.0.7(tailwindcss@3.4.10(ts-node@10.9.2(@types/node@20.14.15)(typescript@5.5.4))): + tailwindcss-animate@1.0.7(tailwindcss@3.4.10(ts-node@10.9.2(@types/node@20.16.0)(typescript@5.5.4))): dependencies: - tailwindcss: 3.4.10(ts-node@10.9.2(@types/node@20.14.15)(typescript@5.5.4)) + tailwindcss: 3.4.10(ts-node@10.9.2(@types/node@20.16.0)(typescript@5.5.4)) - tailwindcss@3.4.10(ts-node@10.9.2(@types/node@20.14.15)(typescript@5.5.4)): + tailwindcss@3.4.10(ts-node@10.9.2(@types/node@20.16.0)(typescript@5.5.4)): dependencies: '@alloc/quick-lru': 5.2.0 arg: 5.0.2 @@ -8921,7 +9012,7 @@ snapshots: postcss: 8.4.41 postcss-import: 15.1.0(postcss@8.4.41) postcss-js: 4.0.1(postcss@8.4.41) - postcss-load-config: 4.0.2(postcss@8.4.41)(ts-node@10.9.2(@types/node@20.14.15)(typescript@5.5.4)) + postcss-load-config: 4.0.2(postcss@8.4.41)(ts-node@10.9.2(@types/node@20.16.0)(typescript@5.5.4)) postcss-nested: 6.0.1(postcss@8.4.41) postcss-selector-parser: 6.1.0 resolve: 1.22.8 @@ -8988,14 +9079,14 @@ snapshots: ts-interface-checker@0.1.13: {} - ts-node@10.9.2(@types/node@20.14.15)(typescript@5.5.4): + ts-node@10.9.2(@types/node@20.16.0)(typescript@5.5.4): dependencies: '@cspotcode/source-map-support': 0.8.1 '@tsconfig/node10': 1.0.11 '@tsconfig/node12': 1.0.11 '@tsconfig/node14': 1.0.3 '@tsconfig/node16': 1.0.4 - '@types/node': 20.14.15 + '@types/node': 20.16.0 acorn: 8.11.3 acorn-walk: 8.3.2 arg: 4.1.3 @@ -9049,7 +9140,7 @@ snapshots: ultrahtml@1.5.3: {} - undici-types@5.26.5: {} + undici-types@6.19.6: {} unfetch@4.2.0: {} @@ -9102,13 +9193,13 @@ snapshots: transitivePeerDependencies: - rollup - vite-node@1.6.0(@types/node@20.14.15)(sass@1.77.8): + vite-node@1.6.0(@types/node@20.16.0)(sass@1.77.8): dependencies: cac: 6.7.14 debug: 4.3.4 pathe: 1.1.2 picocolors: 1.0.0 - vite: 5.4.0(@types/node@20.14.15)(sass@1.77.8) + vite: 5.4.1(@types/node@20.16.0)(sass@1.77.8) transitivePeerDependencies: - '@types/node' - less @@ -9120,21 +9211,21 @@ snapshots: - supports-color - terser - vite@5.4.0(@types/node@20.14.15)(sass@1.77.8): + vite@5.4.1(@types/node@20.16.0)(sass@1.77.8): dependencies: esbuild: 0.21.5 postcss: 8.4.41 rollup: 4.17.2 optionalDependencies: - '@types/node': 20.14.15 + '@types/node': 20.16.0 fsevents: 2.3.3 sass: 1.77.8 - vitefu@0.2.5(vite@5.4.0(@types/node@20.14.15)(sass@1.77.8)): + vitefu@0.2.5(vite@5.4.1(@types/node@20.16.0)(sass@1.77.8)): optionalDependencies: - vite: 5.4.0(@types/node@20.14.15)(sass@1.77.8) + vite: 5.4.1(@types/node@20.16.0)(sass@1.77.8) - vitest@1.6.0(@types/node@20.14.15)(sass@1.77.8): + vitest@1.6.0(@types/node@20.16.0)(sass@1.77.8): dependencies: '@vitest/expect': 1.6.0 '@vitest/runner': 1.6.0 @@ -9153,11 +9244,11 @@ snapshots: strip-literal: 2.1.0 tinybench: 2.8.0 tinypool: 0.8.4 - vite: 5.4.0(@types/node@20.14.15)(sass@1.77.8) - vite-node: 1.6.0(@types/node@20.14.15)(sass@1.77.8) + vite: 5.4.1(@types/node@20.16.0)(sass@1.77.8) + vite-node: 1.6.0(@types/node@20.16.0)(sass@1.77.8) why-is-node-running: 2.2.2 optionalDependencies: - '@types/node': 20.14.15 + '@types/node': 20.16.0 transitivePeerDependencies: - less - lightningcss diff --git a/policies/.cerbos.yaml b/policies/.cerbos.yaml new file mode 100644 index 0000000..5c29127 --- /dev/null +++ b/policies/.cerbos.yaml @@ -0,0 +1,8 @@ +server: + httpListenAddr: ":3592" + +storage: + driver: "disk" + disk: + directory: /policies + watchForChanges: true diff --git a/policies/ticket.yaml b/policies/ticket.yaml new file mode 100644 index 0000000..9d9c583 --- /dev/null +++ b/policies/ticket.yaml @@ -0,0 +1,26 @@ +apiVersion: api.cerbos.dev/v1 +resourcePolicy: + version: default + resource: ticket + + rules: + - actions: + - "*" + effect: EFFECT_ALLOW + roles: + - admin + - actions: + - read + - update + effect: EFFECT_ALLOW + roles: + - customer + condition: + match: + expr: request.resource.attr.cust_id == request.principal.id + - actions: + - create + - delete + effect: EFFECT_DENY + roles: + - customer diff --git a/policies/ticket_test.yaml b/policies/ticket_test.yaml new file mode 100644 index 0000000..20ac4e5 --- /dev/null +++ b/policies/ticket_test.yaml @@ -0,0 +1,43 @@ +name: test ticket + +principals: + adminOne: + id: admin_1 + roles: + - admin + customerOne: + id: cust_1 + roles: + - customer + +resources: + ticketOne: + kind: ticket + id: ticket_1 + attr: + cust_id: cust_1 + +tests: + - name: test ticket + input: + principals: + - adminOne + - customerOne + resources: + - ticketOne + actions: + - create + - delete + + expected: + - principal: adminOne + resource: ticketOne + actions: + create: EFFECT_ALLOW + delete: EFFECT_ALLOW + + - principal: customerOne + resource: ticketOne + actions: + create: EFFECT_DENY + delete: EFFECT_DENY \ No newline at end of file diff --git a/src/lib/components/ui/button/index.ts b/src/lib/components/ui/button/index.ts index a927293..af1e188 100644 --- a/src/lib/components/ui/button/index.ts +++ b/src/lib/components/ui/button/index.ts @@ -3,13 +3,13 @@ import type { Button as ButtonPrimitive } from "bits-ui"; import Root from "./button.svelte"; const buttonVariants = tv({ - base: "inline-flex items-center justify-center whitespace-nowrap rounded-md text-sm font-medium ring-offset-background transition-colors focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-ring focus-visible:ring-offset-2 disabled:pointer-events-none disabled:opacity-50", + base: "ring-offset-background focus-visible:ring-ring inline-flex items-center justify-center whitespace-nowrap rounded-md text-sm font-medium transition-colors focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-offset-2 disabled:pointer-events-none disabled:opacity-50", variants: { variant: { default: "bg-primary text-primary-foreground hover:bg-primary/90", destructive: "bg-destructive text-destructive-foreground hover:bg-destructive/90", outline: - "border border-input bg-background hover:bg-accent hover:text-accent-foreground", + "border-input bg-background hover:bg-accent hover:text-accent-foreground border", secondary: "bg-secondary text-secondary-foreground hover:bg-secondary/80", ghost: "hover:bg-accent hover:text-accent-foreground", link: "text-primary underline-offset-4 hover:underline", diff --git a/src/lib/components/ui/form/form-description.svelte b/src/lib/components/ui/form/form-description.svelte index 7d36254..8877821 100644 --- a/src/lib/components/ui/form/form-description.svelte +++ b/src/lib/components/ui/form/form-description.svelte @@ -9,7 +9,7 @@ diff --git a/src/lib/components/ui/form/form-field-errors.svelte b/src/lib/components/ui/form/form-field-errors.svelte index 9395326..513fb90 100644 --- a/src/lib/components/ui/form/form-field-errors.svelte +++ b/src/lib/components/ui/form/form-field-errors.svelte @@ -12,7 +12,7 @@ diff --git a/src/lib/components/ui/input/index.ts b/src/lib/components/ui/input/index.ts index 17f4e22..75e3bc2 100644 --- a/src/lib/components/ui/input/index.ts +++ b/src/lib/components/ui/input/index.ts @@ -1,6 +1,6 @@ import Root from "./input.svelte"; -type FormInputEvent = T & { +export type FormInputEvent = T & { currentTarget: EventTarget & HTMLInputElement; }; export type InputEvents = { @@ -16,12 +16,14 @@ export type InputEvents = { mouseover: FormInputEvent; mouseenter: FormInputEvent; mouseleave: FormInputEvent; + mousemove: FormInputEvent; paste: FormInputEvent; input: FormInputEvent; + wheel: FormInputEvent; }; export { Root, // - Root as Input + Root as Input, }; diff --git a/src/lib/components/ui/input/input.svelte b/src/lib/components/ui/input/input.svelte index 54dff4a..cab1457 100644 --- a/src/lib/components/ui/input/input.svelte +++ b/src/lib/components/ui/input/input.svelte @@ -1,7 +1,7 @@ diff --git a/src/lib/dtos/signup-username-email.dto.ts b/src/lib/dtos/signup-username-email.dto.ts index b697777..81e259e 100644 --- a/src/lib/dtos/signup-username-email.dto.ts +++ b/src/lib/dtos/signup-username-email.dto.ts @@ -4,7 +4,11 @@ import { refinePasswords } from "$lib/validations/account"; export const signupUsernameEmailDto = z.object({ firstName: z.string().trim().optional(), lastName: z.string().trim().optional(), - email: z.string().trim().max(64, {message: 'Email must be less than 64 characters'}).optional(), + email: z.string() + .trim() + .max(64, {message: 'Email must be less than 64 characters'}) + .email({message: 'Please enter a valid email'}) + .optional(), username: z .string() .trim() @@ -13,8 +17,8 @@ export const signupUsernameEmailDto = z.object({ password: z.string({required_error: 'Password is required'}).trim(), confirm_password: z.string({required_error: 'Confirm Password is required'}).trim() }) - .superRefine(async ({ confirm_password, password }, ctx) => { - return await refinePasswords(confirm_password, password, ctx); + .superRefine(({ confirm_password, password }, ctx) => { + return refinePasswords(confirm_password, password, ctx); }); export type SignupUsernameEmailDto = z.infer diff --git a/src/lib/dtos/update-email.dto.ts b/src/lib/dtos/update-email.dto.ts new file mode 100644 index 0000000..45af50c --- /dev/null +++ b/src/lib/dtos/update-email.dto.ts @@ -0,0 +1,11 @@ +import { z } from "zod"; + +export const updateEmailDto = z.object({ + email: z + .string() + .trim() + .max(64, {message: 'Email must be less than 64 characters'}) + .email({message: 'Please enter a valid email'}) +}); + +export type UpdateEmailDto = z.infer; diff --git a/src/lib/dtos/update-profile.dto.ts b/src/lib/dtos/update-profile.dto.ts new file mode 100644 index 0000000..9ea0c6f --- /dev/null +++ b/src/lib/dtos/update-profile.dto.ts @@ -0,0 +1,23 @@ +import { z } from "zod"; + +export const updateProfileDto = z.object({ + firstName: z + .string() + .trim() + .min(3, {message: 'Must be at least 3 characters'}) + .max(50, {message: 'Must be less than 50 characters'}) + .optional(), + lastName: z + .string() + .trim() + .min(3, {message: 'Must be at least 3 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; diff --git a/src/lib/server/api/controllers/iam.controller.ts b/src/lib/server/api/controllers/iam.controller.ts index fdcc6d3..bf60910 100644 --- a/src/lib/server/api/controllers/iam.controller.ts +++ b/src/lib/server/api/controllers/iam.controller.ts @@ -1,11 +1,15 @@ import { Hono } from 'hono'; import { inject, injectable } from 'tsyringe'; import { setCookie } from 'hono/cookie'; +import { zValidator } from '@hono/zod-validator'; import type { HonoTypes } from '../types'; import { requireAuth } from "../middleware/auth.middleware"; import type { Controller } from '../interfaces/controller.interface'; import {IamService} from "$lib/server/api/services/iam.service"; import {LuciaProvider} from "$lib/server/api/providers"; +import {limiter} from "$lib/server/api/middleware/rate-limiter.middleware"; +import {updateProfileDto} from "$lib/dtos/update-profile.dto"; +import {updateEmailDto} from "$lib/dtos/update-email.dto"; @injectable() export class IamController implements Controller { @@ -22,6 +26,18 @@ export class IamController implements Controller { const user = c.var.user; return c.json({ user }); }) + .post('/update/profile', requireAuth, zValidator('json', updateProfileDto), limiter({ limit: 10, minutes: 60 }), async (c) => { + const user = c.var.user; + const { firstName, lastName, username } = c.req.valid('json'); + await this.iamService.updateProfile(user.id, { first_name: firstName, last_name: lastName, username }); + return c.json({ status: 'success' }); + }) + .post('/update/email', requireAuth, zValidator('json', updateEmailDto), limiter({ limit: 10, minutes: 60 }), async (c) => { + const user = c.var.user; + const { email } = c.req.valid('json'); + await this.iamService.updateEmail(user.id, email); + return c.json({ status: 'success' }); + }) .post('/logout', requireAuth, async (c) => { const sessionId = c.var.session.id; await this.iamService.logout(sessionId); diff --git a/src/lib/server/api/infrastructure/database/seeds/roles.ts b/src/lib/server/api/infrastructure/database/seeds/roles.ts index 46b94e0..20741ea 100644 --- a/src/lib/server/api/infrastructure/database/seeds/roles.ts +++ b/src/lib/server/api/infrastructure/database/seeds/roles.ts @@ -1,5 +1,5 @@ -import { type db } from '$db'; -import * as schema from '$db/schema'; +import { type db } from '$lib/server/api/infrastructure/database'; +import * as schema from '$lib/server/api/infrastructure/database/tables'; import roles from './data/roles.json'; export default async function seed(db: db) { diff --git a/src/lib/server/api/services/iam.service.ts b/src/lib/server/api/services/iam.service.ts index 84b44da..e3a33c2 100644 --- a/src/lib/server/api/services/iam.service.ts +++ b/src/lib/server/api/services/iam.service.ts @@ -1,5 +1,8 @@ import { inject, injectable } from 'tsyringe'; import { LuciaProvider } from '../providers/lucia.provider'; +import {UsersService} from "$lib/server/api/services/users.service"; +import type {UpdateProfileDto} from "$lib/dtos/update-profile.dto"; +import type {UpdateEmailDto} from "$lib/dtos/update-email.dto"; /* -------------------------------------------------------------------------- */ /* Service */ @@ -8,7 +11,7 @@ import { LuciaProvider } from '../providers/lucia.provider'; /* ---------------------------------- About --------------------------------- */ /* Services are responsible for handling business logic and data manipulation. -They genreally call on repositories or other services to complete a use-case. +They generally call on repositories or other services to complete a use-case. */ /* ---------------------------------- Notes --------------------------------- */ /* @@ -22,9 +25,24 @@ simple as possible. This makes the service easier to read, test and understand. export class IamService { constructor( @inject(LuciaProvider) private readonly lucia: LuciaProvider, + @inject(UsersService) private readonly usersService: UsersService ) { } async logout(sessionId: string) { return this.lucia.invalidateSession(sessionId); } + + async updateProfile(userId: string, data: UpdateProfileDto) { + return this.usersService.updateUser(userId, { + first_name: data.firstName, + last_name: data.lastName, + username: data.username + }); + } + + async updateEmail(userId: string, data: UpdateEmailDto) { + return this.usersService.updateUser(userId, { + email: data.email + }); + } } diff --git a/src/lib/server/api/services/users.service.ts b/src/lib/server/api/services/users.service.ts index 02c2d78..e22bad9 100644 --- a/src/lib/server/api/services/users.service.ts +++ b/src/lib/server/api/services/users.service.ts @@ -1,5 +1,5 @@ import { inject, injectable } from 'tsyringe'; -import { UsersRepository } from '../repositories/users.repository'; +import {type UpdateUser, UsersRepository} from '../repositories/users.repository'; import type {SignupUsernameEmailDto} from "$lib/dtos/signup-username-email.dto"; import {TokensService} from "$lib/server/api/services/tokens.service"; import {CredentialsRepository} from "$lib/server/api/repositories/credentials.repository"; @@ -53,6 +53,10 @@ export class UsersService { return user; } + async updateUser(userId: string, data: UpdateUser) { + return this.usersRepository.update(userId, data); + } + async findOneByUsername(username: string) { return this.usersRepository.findOneByUsername(username); } diff --git a/src/routes/(app)/(protected)/profile/+page.server.ts b/src/routes/(app)/(protected)/profile/+page.server.ts index 8157721..6c692fc 100644 --- a/src/routes/(app)/(protected)/profile/+page.server.ts +++ b/src/routes/(app)/(protected)/profile/+page.server.ts @@ -6,43 +6,49 @@ import { message, setError, superValidate } from 'sveltekit-superforms/server'; import { redirect } from 'sveltekit-flash-message/server'; import { changeEmailSchema, profileSchema } from '$lib/validations/account'; import { notSignedInMessage } from '$lib/flashMessages'; -import db from '../../../../db'; +import { db } from '$lib/server/api/infrastructure/database'; import type { PageServerLoad } from './$types'; -import { usersTable, twoFactor } from '$db/schema'; +import { usersTable, credentialsTable } from '$lib/server/api/infrastructure/database/tables'; import { userNotAuthenticated } from '$lib/server/auth-utils'; +import {updateProfileDto} from "$lib/dtos/update-profile.dto"; +import {updateEmailDto} from "$lib/dtos/update-email.dto"; export const load: PageServerLoad = async (event) => { const { locals } = event; - const { user, session } = locals; - if (userNotAuthenticated(user, session)) { - redirect(302, '/login', notSignedInMessage, event); - } - const dbUser = await db.query.usersTable.findFirst({ - where: eq(usersTable.id, user!.id!), - }); + const authedUser = await locals.getAuthedUser(); + if (!authedUser) { + throw redirect(302, '/login', notSignedInMessage, event); + } + // if (userNotAuthenticated(user, session)) { + // redirect(302, '/login', notSignedInMessage, event); + // } + // + // const dbUser = await db.query.usersTable.findFirst({ + // where: eq(usersTable.id, user!.id!), + // }); const profileForm = await superValidate(zod(profileSchema), { defaults: { - firstName: dbUser?.first_name ?? '', - lastName: dbUser?.last_name ?? '', - username: dbUser?.username ?? '', + firstName: authedUser?.first_name ?? '', + lastName: authedUser?.last_name ?? '', + username: authedUser?.username ?? '', }, }); const emailForm = await superValidate(zod(changeEmailSchema), { defaults: { - email: dbUser?.email ?? '', + email: authedUser?.email ?? '', }, }); - const twoFactorDetails = await db.query.twoFactor.findFirst({ - where: eq(twoFactor.userId, dbUser!.id!), - }); + // const twoFactorDetails = await db.query.twoFactor.findFirst({ + // where: eq(twoFactor.userId, authedUser!.id!), + // }); return { profileForm, emailForm, - hasSetupTwoFactor: !!twoFactorDetails?.enabled, + hasSetupTwoFactor: false //!!twoFactorDetails?.enabled, }; }; @@ -56,16 +62,24 @@ const changeEmailIfNotEmpty = z.object({ export const actions: Actions = { profileUpdate: async (event) => { - const form = await superValidate(event, zod(profileSchema)); + const { locals } = event; + + const authedUser = await locals.getAuthedUser(); + + if (!authedUser) { + redirect(302, '/login', notSignedInMessage, event); + } + + const form = await superValidate(event, zod(updateProfileDto)); + + const { error } = await locals.api.user.$post({ json: form.data }).then(locals.parseApiResponse); + if (error) return setError(form, 'username', error); if (!form.valid) { return fail(400, { form, }); } - if (!event.locals.user) { - redirect(302, '/login', notSignedInMessage, event); - } try { console.log('updating profile'); @@ -101,7 +115,7 @@ export const actions: Actions = { return message(form, { type: 'success', message: 'Profile updated successfully!' }); }, changeEmail: async (event) => { - const form = await superValidate(event, zod(changeEmailSchema)); + const form = await superValidate(event, zod(updateEmailDto)); const newEmail = form.data?.email; if ( diff --git a/src/routes/(app)/(protected)/profile/+page.svelte b/src/routes/(app)/(protected)/profile/+page.svelte index 9854af1..18dfd18 100644 --- a/src/routes/(app)/(protected)/profile/+page.svelte +++ b/src/routes/(app)/(protected)/profile/+page.svelte @@ -9,6 +9,8 @@ import { Label } from '$lib/components/ui/label'; import { Input } from '$components/ui/input'; import { Button } from '$components/ui/button'; + import { updateProfileDto } from '$lib/dtos/update-profile.dto'; + import { updateEmailDto } from '$lib/dtos/update-email.dto'; const { data } = $props(); @@ -16,7 +18,7 @@ const { form: profileForm, errors: profileErrors, enhance: profileEnhance } = superForm(data.profileForm, { taintedMessage: null, - validators: zodClient(profileSchema), + validators: zodClient(updateProfileDto), delayMs: 500, multipleSubmits: 'prevent', syncFlashMessage: true, @@ -27,7 +29,7 @@ const { form: emailForm, errors: emailErrors, enhance: emailEnhance } = superForm(data.emailForm, { taintedMessage: null, - validators: zodClient(changeEmailSchema), + validators: zodClient(updateEmailDto), delayMs: 500, multipleSubmits: 'prevent', syncFlashMessage: true, diff --git a/src/routes/(auth)/sign-up/+page.server.ts b/src/routes/(auth)/sign-up/+page.server.ts index ffd8016..abc18b3 100644 --- a/src/routes/(auth)/sign-up/+page.server.ts +++ b/src/routes/(auth)/sign-up/+page.server.ts @@ -1,24 +1,10 @@ import { fail, error, type Actions } from '@sveltejs/kit'; -import { Argon2id } from 'oslo/password'; -import { eq } from 'drizzle-orm'; import { zod } from 'sveltekit-superforms/adapters'; import { setError, superValidate } from 'sveltekit-superforms/server'; import { redirect } from 'sveltekit-flash-message/server'; -import { RateLimiter } from 'sveltekit-rate-limiter/server'; import type { PageServerLoad } from './$types'; -import { lucia } from '$lib/server/auth'; -import { signUpSchema } from '$lib/validations/auth'; -import { add_user_to_role } from '$server/roles'; -import db from '../../../db'; -import { collections, usersTable, wishlists } from '$db/schema'; -import { createId as cuid2 } from '@paralleldrive/cuid2'; import {signupUsernameEmailDto} from "$lib/dtos/signup-username-email.dto"; -const limiter = new RateLimiter({ - // A rate is defined by [number, unit] - IPUA: [5, 'm'], -}); - const signUpDefaults = { firstName: '', lastName: '', diff --git a/src/routes/(auth)/sign-up/+page.svelte b/src/routes/(auth)/sign-up/+page.svelte index 7c9551a..a126a5b 100644 --- a/src/routes/(auth)/sign-up/+page.svelte +++ b/src/routes/(auth)/sign-up/+page.svelte @@ -14,6 +14,7 @@ import * as Collapsible from '$lib/components/ui/collapsible'; import { send, receive } from '$lib/utils/pageCrossfade'; import { boredState } from '$lib/stores/boredState.js'; + import { signupUsernameEmailDto } from '$lib/dtos/signup-username-email.dto'; export let data; @@ -28,7 +29,7 @@ } }, taintedMessage: null, - validators: zodClient(signUpSchema), + validators: zodClient(signupUsernameEmailDto), delayMs: 0 });