From 68182da4cea8a874480982f1699494648cf13c3f Mon Sep 17 00:00:00 2001 From: Bradley Shellnut Date: Fri, 13 Sep 2024 12:11:41 -0700 Subject: [PATCH] Fixing iam service tests and formatting other code. --- package.json | 18 +- pnpm-lock.yaml | 334 +++++++++--------- .../repositories/credentials.repository.ts | 1 + .../server/api/tests/hashing.service.test.ts | 40 ++- src/lib/server/api/tests/iam.service.test.ts | 105 ++++++ .../server/api/tests/tokens.service.test.ts | 56 ++- .../server/api/tests/users.service.test.ts | 215 +++++++---- .../collections/[cuid]/+page.server.ts | 5 +- .../collections/[cuid]/+page.svelte | 4 +- .../security/change/password/+page.svelte | 6 +- .../security/mfa/totp/+page.server.ts | 4 +- .../settings/security/mfa/totp/+page.svelte | 4 +- .../settings/security/mfa/totp/schemas.ts | 4 +- .../(app)/(protected)/wishlists/+page.svelte | 32 +- .../(protected)/wishlists/[cuid]/+page.svelte | 39 +- src/routes/(app)/+page.svelte | 4 +- vite.config.ts | 3 +- 17 files changed, 540 insertions(+), 334 deletions(-) create mode 100644 src/lib/server/api/tests/iam.service.test.ts diff --git a/package.json b/package.json index bddfaf3..e04cff2 100644 --- a/package.json +++ b/package.json @@ -34,7 +34,7 @@ "@sveltejs/vite-plugin-svelte": "^3.1.2", "@types/cookie": "^0.6.0", "@types/node": "^20.16.5", - "@types/pg": "^8.11.8", + "@types/pg": "^8.11.9", "@typescript-eslint/eslint-plugin": "^7.18.0", "@typescript-eslint/parser": "^7.18.0", "autoprefixer": "^10.4.20", @@ -65,18 +65,18 @@ "sveltekit-flash-message": "^2.4.4", "sveltekit-rate-limiter": "^0.5.2", "sveltekit-superforms": "^2.17.0", - "tailwindcss": "^3.4.10", + "tailwindcss": "^3.4.11", "ts-node": "^10.9.2", "tslib": "^2.7.0", - "tsx": "^4.19.0", - "typescript": "^5.5.4", - "vite": "^5.4.3", + "tsx": "^4.19.1", + "typescript": "^5.6.2", + "vite": "^5.4.4", "vitest": "^1.6.0", "zod": "^3.23.8" }, "type": "module", "dependencies": { - "@fontsource/fira-mono": "^5.0.15", + "@fontsource/fira-mono": "^5.1.0", "@hono/swagger-ui": "^0.4.1", "@hono/zod-openapi": "^0.15.3", "@hono/zod-validator": "^0.2.2", @@ -95,7 +95,7 @@ "arctic": "^1.9.2", "bits-ui": "^0.21.13", "boardgamegeekclient": "^1.9.1", - "bullmq": "^5.12.14", + "bullmq": "^5.13.0", "class-variance-authority": "^0.7.0", "clsx": "^2.1.1", "cookie": "^0.6.0", @@ -106,7 +106,7 @@ "feather-icons": "^4.29.2", "formsnap": "^1.0.1", "handlebars": "^4.7.8", - "hono": "^4.5.11", + "hono": "^4.6.1", "hono-rate-limiter": "^0.4.0", "html-entities": "^2.5.2", "iconify-icon": "^2.1.0", @@ -128,6 +128,6 @@ "tailwind-variants": "^0.2.1", "tailwindcss-animate": "^1.0.7", "tsyringe": "^4.8.0", - "zod-to-json-schema": "^3.23.2" + "zod-to-json-schema": "^3.23.3" } } diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml index 94e8b55..1bcf7f5 100644 --- a/pnpm-lock.yaml +++ b/pnpm-lock.yaml @@ -9,17 +9,17 @@ importers: .: dependencies: '@fontsource/fira-mono': - specifier: ^5.0.15 - version: 5.0.15 + specifier: ^5.1.0 + version: 5.1.0 '@hono/swagger-ui': specifier: ^0.4.1 - version: 0.4.1(hono@4.5.11) + version: 0.4.1(hono@4.6.1) '@hono/zod-openapi': specifier: ^0.15.3 - version: 0.15.3(hono@4.5.11)(zod@3.23.8) + version: 0.15.3(hono@4.6.1)(zod@3.23.8) '@hono/zod-validator': specifier: ^0.2.2 - version: 0.2.2(hono@4.5.11)(zod@3.23.8) + version: 0.2.2(hono@4.6.1)(zod@3.23.8) '@iconify-icons/line-md': specifier: ^1.2.30 version: 1.2.30 @@ -31,7 +31,7 @@ importers: version: 3.5.5 '@lucia-auth/adapter-drizzle': specifier: ^1.1.0 - version: 1.1.0(drizzle-orm@0.32.2(@neondatabase/serverless@0.9.5)(@types/pg@8.11.8)(pg@8.12.0)(postgres@3.4.4))(lucia@3.2.0) + version: 1.1.0(drizzle-orm@0.32.2(@neondatabase/serverless@0.9.5)(@types/pg@8.11.9)(pg@8.12.0)(postgres@3.4.4))(lucia@3.2.0) '@lukeed/uuid': specifier: ^2.0.1 version: 2.0.1 @@ -46,10 +46,10 @@ importers: version: 2.6.2 '@sveltejs/adapter-node': specifier: ^5.2.2 - version: 5.2.2(@sveltejs/kit@2.5.26(@sveltejs/vite-plugin-svelte@3.1.2(svelte@5.0.0-next.175)(vite@5.4.3(@types/node@20.16.5)(sass@1.78.0)))(svelte@5.0.0-next.175)(vite@5.4.3(@types/node@20.16.5)(sass@1.78.0))) + version: 5.2.2(@sveltejs/kit@2.5.26(@sveltejs/vite-plugin-svelte@3.1.2(svelte@5.0.0-next.175)(vite@5.4.4(@types/node@20.16.5)(sass@1.78.0)))(svelte@5.0.0-next.175)(vite@5.4.4(@types/node@20.16.5)(sass@1.78.0))) '@sveltejs/adapter-vercel': specifier: ^5.4.3 - version: 5.4.3(@sveltejs/kit@2.5.26(@sveltejs/vite-plugin-svelte@3.1.2(svelte@5.0.0-next.175)(vite@5.4.3(@types/node@20.16.5)(sass@1.78.0)))(svelte@5.0.0-next.175)(vite@5.4.3(@types/node@20.16.5)(sass@1.78.0))) + version: 5.4.3(@sveltejs/kit@2.5.26(@sveltejs/vite-plugin-svelte@3.1.2(svelte@5.0.0-next.175)(vite@5.4.4(@types/node@20.16.5)(sass@1.78.0)))(svelte@5.0.0-next.175)(vite@5.4.4(@types/node@20.16.5)(sass@1.78.0))) '@types/feather-icons': specifier: ^4.29.4 version: 4.29.4 @@ -66,8 +66,8 @@ importers: specifier: ^1.9.1 version: 1.9.1 bullmq: - specifier: ^5.12.14 - version: 5.12.14 + specifier: ^5.13.0 + version: 5.13.0 class-variance-authority: specifier: ^0.7.0 version: 0.7.0 @@ -85,25 +85,25 @@ importers: version: 11.0.6 drizzle-orm: specifier: ^0.32.2 - version: 0.32.2(@neondatabase/serverless@0.9.5)(@types/pg@8.11.8)(pg@8.12.0)(postgres@3.4.4) + version: 0.32.2(@neondatabase/serverless@0.9.5)(@types/pg@8.11.9)(pg@8.12.0)(postgres@3.4.4) drizzle-zod: specifier: ^0.5.1 - version: 0.5.1(drizzle-orm@0.32.2(@neondatabase/serverless@0.9.5)(@types/pg@8.11.8)(pg@8.12.0)(postgres@3.4.4))(zod@3.23.8) + version: 0.5.1(drizzle-orm@0.32.2(@neondatabase/serverless@0.9.5)(@types/pg@8.11.9)(pg@8.12.0)(postgres@3.4.4))(zod@3.23.8) feather-icons: specifier: ^4.29.2 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.26(@sveltejs/vite-plugin-svelte@3.1.2(svelte@5.0.0-next.175)(vite@5.4.3(@types/node@20.16.5)(sass@1.78.0)))(svelte@5.0.0-next.175)(vite@5.4.3(@types/node@20.16.5)(sass@1.78.0)))(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.26(@sveltejs/vite-plugin-svelte@3.1.2(svelte@5.0.0-next.175)(vite@5.4.4(@types/node@20.16.5)(sass@1.78.0)))(svelte@5.0.0-next.175)(vite@5.4.4(@types/node@20.16.5)(sass@1.78.0)))(svelte@5.0.0-next.175)) handlebars: specifier: ^4.7.8 version: 4.7.8 hono: - specifier: ^4.5.11 - version: 4.5.11 + specifier: ^4.6.1 + version: 4.6.1 hono-rate-limiter: specifier: ^0.4.0 - version: 0.4.0(hono@4.5.11) + version: 0.4.0(hono@4.6.1) html-entities: specifier: ^2.5.2 version: 2.5.2 @@ -157,16 +157,16 @@ 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.16.5)(typescript@5.5.4))) + version: 0.2.1(tailwindcss@3.4.11(ts-node@10.9.2(@types/node@20.16.5)(typescript@5.6.2))) tailwindcss-animate: specifier: ^1.0.7 - version: 1.0.7(tailwindcss@3.4.10(ts-node@10.9.2(@types/node@20.16.5)(typescript@5.5.4))) + version: 1.0.7(tailwindcss@3.4.11(ts-node@10.9.2(@types/node@20.16.5)(typescript@5.6.2))) tsyringe: specifier: ^4.8.0 version: 4.8.0 zod-to-json-schema: - specifier: ^3.23.2 - version: 3.23.2(zod@3.23.8) + specifier: ^3.23.3 + version: 3.23.3(zod@3.23.8) devDependencies: '@biomejs/biome': specifier: 1.8.3 @@ -185,16 +185,16 @@ importers: version: 1.47.0 '@sveltejs/adapter-auto': specifier: ^3.2.4 - version: 3.2.4(@sveltejs/kit@2.5.26(@sveltejs/vite-plugin-svelte@3.1.2(svelte@5.0.0-next.175)(vite@5.4.3(@types/node@20.16.5)(sass@1.78.0)))(svelte@5.0.0-next.175)(vite@5.4.3(@types/node@20.16.5)(sass@1.78.0))) + version: 3.2.4(@sveltejs/kit@2.5.26(@sveltejs/vite-plugin-svelte@3.1.2(svelte@5.0.0-next.175)(vite@5.4.4(@types/node@20.16.5)(sass@1.78.0)))(svelte@5.0.0-next.175)(vite@5.4.4(@types/node@20.16.5)(sass@1.78.0))) '@sveltejs/enhanced-img': specifier: ^0.3.4 - version: 0.3.4(rollup@4.21.2)(svelte@5.0.0-next.175)(vite@5.4.3(@types/node@20.16.5)(sass@1.78.0)) + version: 0.3.4(rollup@4.21.2)(svelte@5.0.0-next.175)(vite@5.4.4(@types/node@20.16.5)(sass@1.78.0)) '@sveltejs/kit': specifier: ^2.5.26 - version: 2.5.26(@sveltejs/vite-plugin-svelte@3.1.2(svelte@5.0.0-next.175)(vite@5.4.3(@types/node@20.16.5)(sass@1.78.0)))(svelte@5.0.0-next.175)(vite@5.4.3(@types/node@20.16.5)(sass@1.78.0)) + version: 2.5.26(@sveltejs/vite-plugin-svelte@3.1.2(svelte@5.0.0-next.175)(vite@5.4.4(@types/node@20.16.5)(sass@1.78.0)))(svelte@5.0.0-next.175)(vite@5.4.4(@types/node@20.16.5)(sass@1.78.0)) '@sveltejs/vite-plugin-svelte': specifier: ^3.1.2 - version: 3.1.2(svelte@5.0.0-next.175)(vite@5.4.3(@types/node@20.16.5)(sass@1.78.0)) + version: 3.1.2(svelte@5.0.0-next.175)(vite@5.4.4(@types/node@20.16.5)(sass@1.78.0)) '@types/cookie': specifier: ^0.6.0 version: 0.6.0 @@ -202,14 +202,14 @@ importers: specifier: ^20.16.5 version: 20.16.5 '@types/pg': - specifier: ^8.11.8 - version: 8.11.8 + specifier: ^8.11.9 + version: 8.11.9 '@typescript-eslint/eslint-plugin': specifier: ^7.18.0 - version: 7.18.0(@typescript-eslint/parser@7.18.0(eslint@8.57.0)(typescript@5.5.4))(eslint@8.57.0)(typescript@5.5.4) + version: 7.18.0(@typescript-eslint/parser@7.18.0(eslint@8.57.0)(typescript@5.6.2))(eslint@8.57.0)(typescript@5.6.2) '@typescript-eslint/parser': specifier: ^7.18.0 - version: 7.18.0(eslint@8.57.0)(typescript@5.5.4) + version: 7.18.0(eslint@8.57.0)(typescript@5.6.2) autoprefixer: specifier: ^10.4.20 version: 10.4.20(postcss@8.4.45) @@ -224,7 +224,7 @@ importers: version: 9.1.0(eslint@8.57.0) eslint-plugin-svelte: specifier: 2.36.0-next.13 - version: 2.36.0-next.13(eslint@8.57.0)(svelte@5.0.0-next.175)(ts-node@10.9.2(@types/node@20.16.5)(typescript@5.5.4)) + version: 2.36.0-next.13(eslint@8.57.0)(svelte@5.0.0-next.175)(ts-node@10.9.2(@types/node@20.16.5)(typescript@5.6.2)) just-clone: specifier: ^6.2.0 version: 6.2.0 @@ -248,7 +248,7 @@ importers: version: 16.1.0(postcss@8.4.45) postcss-load-config: specifier: ^5.1.0 - version: 5.1.0(jiti@1.21.6)(postcss@8.4.45)(tsx@4.19.0) + version: 5.1.0(jiti@1.21.6)(postcss@8.4.45)(tsx@4.19.1) postcss-preset-env: specifier: ^9.6.0 version: 9.6.0(postcss@8.4.45) @@ -272,46 +272,46 @@ importers: version: 5.0.0-next.175 svelte-check: specifier: ^3.8.6 - version: 3.8.6(postcss-load-config@5.1.0(jiti@1.21.6)(postcss@8.4.45)(tsx@4.19.0))(postcss@8.4.45)(sass@1.78.0)(svelte@5.0.0-next.175) + version: 3.8.6(postcss-load-config@5.1.0(jiti@1.21.6)(postcss@8.4.45)(tsx@4.19.1))(postcss@8.4.45)(sass@1.78.0)(svelte@5.0.0-next.175) svelte-headless-table: specifier: ^0.18.2 version: 0.18.2(svelte@5.0.0-next.175) svelte-meta-tags: specifier: ^3.1.4 - version: 3.1.4(svelte@5.0.0-next.175)(typescript@5.5.4) + version: 3.1.4(svelte@5.0.0-next.175)(typescript@5.6.2) svelte-preprocess: specifier: ^6.0.2 - version: 6.0.2(postcss-load-config@5.1.0(jiti@1.21.6)(postcss@8.4.45)(tsx@4.19.0))(postcss@8.4.45)(sass@1.78.0)(svelte@5.0.0-next.175)(typescript@5.5.4) + version: 6.0.2(postcss-load-config@5.1.0(jiti@1.21.6)(postcss@8.4.45)(tsx@4.19.1))(postcss@8.4.45)(sass@1.78.0)(svelte@5.0.0-next.175)(typescript@5.6.2) svelte-sequential-preprocessor: specifier: ^2.0.1 version: 2.0.1 sveltekit-flash-message: specifier: ^2.4.4 - version: 2.4.4(@sveltejs/kit@2.5.26(@sveltejs/vite-plugin-svelte@3.1.2(svelte@5.0.0-next.175)(vite@5.4.3(@types/node@20.16.5)(sass@1.78.0)))(svelte@5.0.0-next.175)(vite@5.4.3(@types/node@20.16.5)(sass@1.78.0)))(svelte@5.0.0-next.175) + version: 2.4.4(@sveltejs/kit@2.5.26(@sveltejs/vite-plugin-svelte@3.1.2(svelte@5.0.0-next.175)(vite@5.4.4(@types/node@20.16.5)(sass@1.78.0)))(svelte@5.0.0-next.175)(vite@5.4.4(@types/node@20.16.5)(sass@1.78.0)))(svelte@5.0.0-next.175) sveltekit-rate-limiter: specifier: ^0.5.2 - version: 0.5.2(@sveltejs/kit@2.5.26(@sveltejs/vite-plugin-svelte@3.1.2(svelte@5.0.0-next.175)(vite@5.4.3(@types/node@20.16.5)(sass@1.78.0)))(svelte@5.0.0-next.175)(vite@5.4.3(@types/node@20.16.5)(sass@1.78.0))) + version: 0.5.2(@sveltejs/kit@2.5.26(@sveltejs/vite-plugin-svelte@3.1.2(svelte@5.0.0-next.175)(vite@5.4.4(@types/node@20.16.5)(sass@1.78.0)))(svelte@5.0.0-next.175)(vite@5.4.4(@types/node@20.16.5)(sass@1.78.0))) sveltekit-superforms: specifier: ^2.17.0 - version: 2.17.0(@sveltejs/kit@2.5.26(@sveltejs/vite-plugin-svelte@3.1.2(svelte@5.0.0-next.175)(vite@5.4.3(@types/node@20.16.5)(sass@1.78.0)))(svelte@5.0.0-next.175)(vite@5.4.3(@types/node@20.16.5)(sass@1.78.0)))(svelte@5.0.0-next.175) + version: 2.17.0(@sveltejs/kit@2.5.26(@sveltejs/vite-plugin-svelte@3.1.2(svelte@5.0.0-next.175)(vite@5.4.4(@types/node@20.16.5)(sass@1.78.0)))(svelte@5.0.0-next.175)(vite@5.4.4(@types/node@20.16.5)(sass@1.78.0)))(svelte@5.0.0-next.175) tailwindcss: - specifier: ^3.4.10 - version: 3.4.10(ts-node@10.9.2(@types/node@20.16.5)(typescript@5.5.4)) + specifier: ^3.4.11 + version: 3.4.11(ts-node@10.9.2(@types/node@20.16.5)(typescript@5.6.2)) ts-node: specifier: ^10.9.2 - version: 10.9.2(@types/node@20.16.5)(typescript@5.5.4) + version: 10.9.2(@types/node@20.16.5)(typescript@5.6.2) tslib: specifier: ^2.7.0 version: 2.7.0 tsx: - specifier: ^4.19.0 - version: 4.19.0 + specifier: ^4.19.1 + version: 4.19.1 typescript: - specifier: ^5.5.4 - version: 5.5.4 + specifier: ^5.6.2 + version: 5.6.2 vite: - specifier: ^5.4.3 - version: 5.4.3(@types/node@20.16.5)(sass@1.78.0) + specifier: ^5.4.4 + version: 5.4.4(@types/node@20.16.5)(sass@1.78.0) vitest: specifier: ^1.6.0 version: 1.6.0(@types/node@20.16.5)(sass@1.78.0) @@ -1245,8 +1245,8 @@ packages: '@floating-ui/utils@0.2.7': resolution: {integrity: sha512-X8R8Oj771YRl/w+c1HqAC1szL8zWQRwFvgDwT129k9ACdBoud/+/rX9V0qiMl6LWUdP9voC2nDVZYPMQQsb6eA==} - '@fontsource/fira-mono@5.0.15': - resolution: {integrity: sha512-wc3TpF2GBbtFDKNbb444BrC3mEKuoPLITSYCKweNIrqBvAalIfJGloY/MVrmSGaMNgaAKUpdgy4eAWPLkUVzaA==} + '@fontsource/fira-mono@5.1.0': + resolution: {integrity: sha512-6+nftSKApXyN0I9FC5GJuG5TUCh+in5OehtrXRIsHJvq38Pm//oA1kZZYNdXv99JYzLzJ3lzsTAavmS+xGLGDw==} '@gcornut/valibot-json-schema@0.31.0': resolution: {integrity: sha512-3xGptCurm23e7nuPQkdrE5rEs1FeTPHhAUsBuwwqG4/YeZLwJOoYZv+fmsppUEfo5y9lzUwNQrNqLS/q7HMc7g==} @@ -2022,8 +2022,8 @@ packages: '@types/pg@8.11.6': resolution: {integrity: sha512-/2WmmBXHLsfRqzfHW7BNZ8SbYzE8OSk7i3WjFYvfgRHj7S1xj+16Je5fUKv3lVdVzk/zn9TXOqf+avFCFIE0yQ==} - '@types/pg@8.11.8': - resolution: {integrity: sha512-IqpCf8/569txXN/HoP5i1LjXfKZWL76Yr2R77xgeIICUbAYHeoaEZFhYHo2uDftecLWrTJUq63JvQu8q3lnDyA==} + '@types/pg@8.11.9': + resolution: {integrity: sha512-M4mYeJZRBD9lCBCGa72F44uKSV9eJrAFfjlPJagdA6pgIr2OPJULFB7nqnZzOdqXG0qzHlgtZKzTdIgbmHitSg==} '@types/pug@2.0.10': resolution: {integrity: sha512-Sk/uYFOBAB7mb74XcpizmH0KOR2Pv3D2Hmrh1Dmy5BmK3MpdSa5kqZcg6EKBdklU0bFXX9gCfzvpnyUehrPIuA==} @@ -2295,8 +2295,8 @@ packages: resolution: {integrity: sha512-zhaCDicdLuWN5UbN5IMnFqNMhNfo919sH85y2/ea+5Yg9TsTkeZxpL+JLbp6cgYFS4sRLp3YV4S6yDuqVWHYOw==} engines: {node: '>=6'} - bullmq@5.12.14: - resolution: {integrity: sha512-mcSQHq9EY+DKtAP6XSmkP+0f1ifFithcpLTwo8WmUauArE9dxk45Gae3Fls1Nwf0Er9MoaDhPcglfe6LV/XCOg==} + bullmq@5.13.0: + resolution: {integrity: sha512-rE7v3jMZZGsEhfMhLZwADwuHdqJPTTGHBM8C+SpxF9GzyZ+7pvC80EP5bOZJPPRzbmyhvIPJCVd0bchUZiQF+w==} bytes@3.1.2: resolution: {integrity: sha512-/Nf7TyzTx6S3yRJObOAV7956r8cr2+Oj8AC5dt8wSP3BQAoeX58NoHyCU8P8zGkNXStjTSi6fzO6F0pBdcYbEg==} @@ -3043,8 +3043,8 @@ packages: peerDependencies: hono: ^4.1.1 - hono@4.5.11: - resolution: {integrity: sha512-62FcjLPtjAFwISVBUshryl+vbHOjg8rE4uIK/dxyR8GpLztunZpwFmfEvmJCUI7xoGh/Sr3CGCDPCmYxVw7wUQ==} + hono@4.6.1: + resolution: {integrity: sha512-6NGwvttY1+HAFii08VYiEKI6ETPAFbpLntpm2M/MogEsAFWdZV74UNT+2M4bmqX90cIQhjlpBSP+tO+CfB0uww==} engines: {node: '>=16.0.0'} html-entities@2.5.2: @@ -4476,8 +4476,8 @@ packages: peerDependencies: tailwindcss: '>=3.0.0 || insiders' - tailwindcss@3.4.10: - resolution: {integrity: sha512-KWZkVPm7yJRhdu4SRSl9d4AK2wM3a50UsvgHZO7xY77NQr2V+fIrEuoDGQcbvswWvFGbS2f6e+jC/6WJm1Dl0w==} + tailwindcss@3.4.11: + resolution: {integrity: sha512-qhEuBcLemjSJk5ajccN9xJFtM/h0AVCPaA6C92jNP+M2J8kX+eMJHI7R2HFKUvvAsMpcfLILMCFYSeDwpMmlUg==} engines: {node: '>=14.0.0'} hasBin: true @@ -4575,8 +4575,8 @@ packages: tslib@2.7.0: resolution: {integrity: sha512-gLXCKdN1/j47AiHiOkJN69hJmcbGTHI0ImLmbYLHykhgeN0jVGola9yVjFgzCUklsZQMW55o+dW7IXv3RCXDzA==} - tsx@4.19.0: - resolution: {integrity: sha512-bV30kM7bsLZKZIOCHeMNVMJ32/LuJzLVajkQI/qf92J2Qr08ueLQvW00PUZGiuLPP760UINwupgUj8qrSCPUKg==} + tsx@4.19.1: + resolution: {integrity: sha512-0flMz1lh74BR4wOvBjuh9olbnwqCPc35OOlfyzHba0Dc+QNUeWX/Gq2YTbnwcWPO3BMd8fkzRVrHcsR+a7z7rA==} engines: {node: '>=18.0.0'} hasBin: true @@ -4604,8 +4604,8 @@ packages: resolution: {integrity: sha512-TkRKr9sUTxEH8MdfuCSP7VizJyzRNMjj2J2do2Jr3Kym598JVdEksuzPQCnlFPW4ky9Q+iA+ma9BGm06XQBy8g==} engines: {node: '>= 0.6'} - typescript@5.5.4: - resolution: {integrity: sha512-Mtq29sKDAEYP7aljRgtPOpTvOfbwRWlS6dPRzwjdE+C0R4brX/GUyhHSecbHMFLNBLcJIPt9nl9yG5TZ1weH+Q==} + typescript@5.6.2: + resolution: {integrity: sha512-NW8ByodCSNCwZeghjN3o+JX5OFH0Ojg6sadjEKY4huZ52TqbJTJnDo5+Tw98lSy63NZvi4n+ez5m2u5d4PkZyw==} engines: {node: '>=14.17'} hasBin: true @@ -4679,8 +4679,8 @@ packages: engines: {node: ^18.0.0 || >=20.0.0} hasBin: true - vite@5.4.3: - resolution: {integrity: sha512-IH+nl64eq9lJjFqU+/yrRnrHPVTlgy42/+IzbOdaFDVlyLgI/wDlf+FCobXLX1cT0X5+7LMyH1mIy2xJdLfo8Q==} + vite@5.4.4: + resolution: {integrity: sha512-RHFCkULitycHVTtelJ6jQLd+KSAAzOgEYorV32R2q++M6COBjKJR6BxqClwp5sf0XaBDjVMuJ9wnNfyAJwjMkA==} engines: {node: ^18.0.0 || >=20.0.0} hasBin: true peerDependencies: @@ -4835,8 +4835,8 @@ packages: zimmerframe@1.1.2: resolution: {integrity: sha512-rAbqEGa8ovJy4pyBxZM70hg4pE6gDgaQ0Sl9M3enG3I0d6H4XSAM3GeNGLKnsBpuijUow064sf7ww1nutC5/3w==} - zod-to-json-schema@3.23.2: - resolution: {integrity: sha512-uSt90Gzc/tUfyNqxnjlfBs8W6WSGpNBv0rVsNxP/BVSMHMKGdthPYff4xtCHYloJGM0CFxFsb3NbC0eqPhfImw==} + zod-to-json-schema@3.23.3: + resolution: {integrity: sha512-TYWChTxKQbRJp5ST22o/Irt9KC5nj7CdBKYB/AosCRdj/wxEMvv4NNaj9XVUHDOIp53ZxArGhnw5HMZziPFjog==} peerDependencies: zod: ^3.23.3 @@ -5489,7 +5489,7 @@ snapshots: '@floating-ui/utils@0.2.7': {} - '@fontsource/fira-mono@5.0.15': {} + '@fontsource/fira-mono@5.1.0': {} '@gcornut/valibot-json-schema@0.31.0': dependencies: @@ -5508,20 +5508,20 @@ snapshots: '@hapi/hoek': 9.3.0 optional: true - '@hono/swagger-ui@0.4.1(hono@4.5.11)': + '@hono/swagger-ui@0.4.1(hono@4.6.1)': dependencies: - hono: 4.5.11 + hono: 4.6.1 - '@hono/zod-openapi@0.15.3(hono@4.5.11)(zod@3.23.8)': + '@hono/zod-openapi@0.15.3(hono@4.6.1)(zod@3.23.8)': dependencies: '@asteasolutions/zod-to-openapi': 7.1.1(zod@3.23.8) - '@hono/zod-validator': 0.2.2(hono@4.5.11)(zod@3.23.8) - hono: 4.5.11 + '@hono/zod-validator': 0.2.2(hono@4.6.1)(zod@3.23.8) + hono: 4.6.1 zod: 3.23.8 - '@hono/zod-validator@0.2.2(hono@4.5.11)(zod@3.23.8)': + '@hono/zod-validator@0.2.2(hono@4.6.1)(zod@3.23.8)': dependencies: - hono: 4.5.11 + hono: 4.6.1 zod: 3.23.8 '@humanwhocodes/config-array@0.11.14': @@ -5664,9 +5664,9 @@ snapshots: '@jridgewell/resolve-uri': 3.1.2 '@jridgewell/sourcemap-codec': 1.5.0 - '@lucia-auth/adapter-drizzle@1.1.0(drizzle-orm@0.32.2(@neondatabase/serverless@0.9.5)(@types/pg@8.11.8)(pg@8.12.0)(postgres@3.4.4))(lucia@3.2.0)': + '@lucia-auth/adapter-drizzle@1.1.0(drizzle-orm@0.32.2(@neondatabase/serverless@0.9.5)(@types/pg@8.11.9)(pg@8.12.0)(postgres@3.4.4))(lucia@3.2.0)': dependencies: - drizzle-orm: 0.32.2(@neondatabase/serverless@0.9.5)(@types/pg@8.11.8)(pg@8.12.0)(postgres@3.4.4) + drizzle-orm: 0.32.2(@neondatabase/serverless@0.9.5)(@types/pg@8.11.9)(pg@8.12.0)(postgres@3.4.4) lucia: 3.2.0 '@lukeed/csprng@1.1.0': {} @@ -6063,41 +6063,41 @@ snapshots: '@sodaru/yup-to-json-schema@2.0.1': optional: true - '@sveltejs/adapter-auto@3.2.4(@sveltejs/kit@2.5.26(@sveltejs/vite-plugin-svelte@3.1.2(svelte@5.0.0-next.175)(vite@5.4.3(@types/node@20.16.5)(sass@1.78.0)))(svelte@5.0.0-next.175)(vite@5.4.3(@types/node@20.16.5)(sass@1.78.0)))': + '@sveltejs/adapter-auto@3.2.4(@sveltejs/kit@2.5.26(@sveltejs/vite-plugin-svelte@3.1.2(svelte@5.0.0-next.175)(vite@5.4.4(@types/node@20.16.5)(sass@1.78.0)))(svelte@5.0.0-next.175)(vite@5.4.4(@types/node@20.16.5)(sass@1.78.0)))': dependencies: - '@sveltejs/kit': 2.5.26(@sveltejs/vite-plugin-svelte@3.1.2(svelte@5.0.0-next.175)(vite@5.4.3(@types/node@20.16.5)(sass@1.78.0)))(svelte@5.0.0-next.175)(vite@5.4.3(@types/node@20.16.5)(sass@1.78.0)) + '@sveltejs/kit': 2.5.26(@sveltejs/vite-plugin-svelte@3.1.2(svelte@5.0.0-next.175)(vite@5.4.4(@types/node@20.16.5)(sass@1.78.0)))(svelte@5.0.0-next.175)(vite@5.4.4(@types/node@20.16.5)(sass@1.78.0)) import-meta-resolve: 4.1.0 - '@sveltejs/adapter-node@5.2.2(@sveltejs/kit@2.5.26(@sveltejs/vite-plugin-svelte@3.1.2(svelte@5.0.0-next.175)(vite@5.4.3(@types/node@20.16.5)(sass@1.78.0)))(svelte@5.0.0-next.175)(vite@5.4.3(@types/node@20.16.5)(sass@1.78.0)))': + '@sveltejs/adapter-node@5.2.2(@sveltejs/kit@2.5.26(@sveltejs/vite-plugin-svelte@3.1.2(svelte@5.0.0-next.175)(vite@5.4.4(@types/node@20.16.5)(sass@1.78.0)))(svelte@5.0.0-next.175)(vite@5.4.4(@types/node@20.16.5)(sass@1.78.0)))': dependencies: '@rollup/plugin-commonjs': 26.0.1(rollup@4.21.2) '@rollup/plugin-json': 6.1.0(rollup@4.21.2) '@rollup/plugin-node-resolve': 15.2.3(rollup@4.21.2) - '@sveltejs/kit': 2.5.26(@sveltejs/vite-plugin-svelte@3.1.2(svelte@5.0.0-next.175)(vite@5.4.3(@types/node@20.16.5)(sass@1.78.0)))(svelte@5.0.0-next.175)(vite@5.4.3(@types/node@20.16.5)(sass@1.78.0)) + '@sveltejs/kit': 2.5.26(@sveltejs/vite-plugin-svelte@3.1.2(svelte@5.0.0-next.175)(vite@5.4.4(@types/node@20.16.5)(sass@1.78.0)))(svelte@5.0.0-next.175)(vite@5.4.4(@types/node@20.16.5)(sass@1.78.0)) rollup: 4.21.2 - '@sveltejs/adapter-vercel@5.4.3(@sveltejs/kit@2.5.26(@sveltejs/vite-plugin-svelte@3.1.2(svelte@5.0.0-next.175)(vite@5.4.3(@types/node@20.16.5)(sass@1.78.0)))(svelte@5.0.0-next.175)(vite@5.4.3(@types/node@20.16.5)(sass@1.78.0)))': + '@sveltejs/adapter-vercel@5.4.3(@sveltejs/kit@2.5.26(@sveltejs/vite-plugin-svelte@3.1.2(svelte@5.0.0-next.175)(vite@5.4.4(@types/node@20.16.5)(sass@1.78.0)))(svelte@5.0.0-next.175)(vite@5.4.4(@types/node@20.16.5)(sass@1.78.0)))': dependencies: - '@sveltejs/kit': 2.5.26(@sveltejs/vite-plugin-svelte@3.1.2(svelte@5.0.0-next.175)(vite@5.4.3(@types/node@20.16.5)(sass@1.78.0)))(svelte@5.0.0-next.175)(vite@5.4.3(@types/node@20.16.5)(sass@1.78.0)) + '@sveltejs/kit': 2.5.26(@sveltejs/vite-plugin-svelte@3.1.2(svelte@5.0.0-next.175)(vite@5.4.4(@types/node@20.16.5)(sass@1.78.0)))(svelte@5.0.0-next.175)(vite@5.4.4(@types/node@20.16.5)(sass@1.78.0)) '@vercel/nft': 0.27.4 esbuild: 0.21.5 transitivePeerDependencies: - encoding - supports-color - '@sveltejs/enhanced-img@0.3.4(rollup@4.21.2)(svelte@5.0.0-next.175)(vite@5.4.3(@types/node@20.16.5)(sass@1.78.0))': + '@sveltejs/enhanced-img@0.3.4(rollup@4.21.2)(svelte@5.0.0-next.175)(vite@5.4.4(@types/node@20.16.5)(sass@1.78.0))': dependencies: magic-string: 0.30.11 svelte: 5.0.0-next.175 svelte-parse-markup: 0.1.5(svelte@5.0.0-next.175) - vite: 5.4.3(@types/node@20.16.5)(sass@1.78.0) + vite: 5.4.4(@types/node@20.16.5)(sass@1.78.0) vite-imagetools: 7.0.4(rollup@4.21.2) transitivePeerDependencies: - rollup - '@sveltejs/kit@2.5.26(@sveltejs/vite-plugin-svelte@3.1.2(svelte@5.0.0-next.175)(vite@5.4.3(@types/node@20.16.5)(sass@1.78.0)))(svelte@5.0.0-next.175)(vite@5.4.3(@types/node@20.16.5)(sass@1.78.0))': + '@sveltejs/kit@2.5.26(@sveltejs/vite-plugin-svelte@3.1.2(svelte@5.0.0-next.175)(vite@5.4.4(@types/node@20.16.5)(sass@1.78.0)))(svelte@5.0.0-next.175)(vite@5.4.4(@types/node@20.16.5)(sass@1.78.0))': dependencies: - '@sveltejs/vite-plugin-svelte': 3.1.2(svelte@5.0.0-next.175)(vite@5.4.3(@types/node@20.16.5)(sass@1.78.0)) + '@sveltejs/vite-plugin-svelte': 3.1.2(svelte@5.0.0-next.175)(vite@5.4.4(@types/node@20.16.5)(sass@1.78.0)) '@types/cookie': 0.6.0 cookie: 0.6.0 devalue: 5.0.0 @@ -6111,28 +6111,28 @@ snapshots: sirv: 2.0.4 svelte: 5.0.0-next.175 tiny-glob: 0.2.9 - vite: 5.4.3(@types/node@20.16.5)(sass@1.78.0) + vite: 5.4.4(@types/node@20.16.5)(sass@1.78.0) - '@sveltejs/vite-plugin-svelte-inspector@2.1.0(@sveltejs/vite-plugin-svelte@3.1.2(svelte@5.0.0-next.175)(vite@5.4.3(@types/node@20.16.5)(sass@1.78.0)))(svelte@5.0.0-next.175)(vite@5.4.3(@types/node@20.16.5)(sass@1.78.0))': + '@sveltejs/vite-plugin-svelte-inspector@2.1.0(@sveltejs/vite-plugin-svelte@3.1.2(svelte@5.0.0-next.175)(vite@5.4.4(@types/node@20.16.5)(sass@1.78.0)))(svelte@5.0.0-next.175)(vite@5.4.4(@types/node@20.16.5)(sass@1.78.0))': dependencies: - '@sveltejs/vite-plugin-svelte': 3.1.2(svelte@5.0.0-next.175)(vite@5.4.3(@types/node@20.16.5)(sass@1.78.0)) + '@sveltejs/vite-plugin-svelte': 3.1.2(svelte@5.0.0-next.175)(vite@5.4.4(@types/node@20.16.5)(sass@1.78.0)) debug: 4.3.6 svelte: 5.0.0-next.175 - vite: 5.4.3(@types/node@20.16.5)(sass@1.78.0) + vite: 5.4.4(@types/node@20.16.5)(sass@1.78.0) transitivePeerDependencies: - supports-color - '@sveltejs/vite-plugin-svelte@3.1.2(svelte@5.0.0-next.175)(vite@5.4.3(@types/node@20.16.5)(sass@1.78.0))': + '@sveltejs/vite-plugin-svelte@3.1.2(svelte@5.0.0-next.175)(vite@5.4.4(@types/node@20.16.5)(sass@1.78.0))': dependencies: - '@sveltejs/vite-plugin-svelte-inspector': 2.1.0(@sveltejs/vite-plugin-svelte@3.1.2(svelte@5.0.0-next.175)(vite@5.4.3(@types/node@20.16.5)(sass@1.78.0)))(svelte@5.0.0-next.175)(vite@5.4.3(@types/node@20.16.5)(sass@1.78.0)) + '@sveltejs/vite-plugin-svelte-inspector': 2.1.0(@sveltejs/vite-plugin-svelte@3.1.2(svelte@5.0.0-next.175)(vite@5.4.4(@types/node@20.16.5)(sass@1.78.0)))(svelte@5.0.0-next.175)(vite@5.4.4(@types/node@20.16.5)(sass@1.78.0)) debug: 4.3.6 deepmerge: 4.3.1 kleur: 4.1.5 magic-string: 0.30.11 svelte: 5.0.0-next.175 svelte-hmr: 0.16.0(svelte@5.0.0-next.175) - vite: 5.4.3(@types/node@20.16.5)(sass@1.78.0) - vitefu: 0.2.5(vite@5.4.3(@types/node@20.16.5)(sass@1.78.0)) + vite: 5.4.4(@types/node@20.16.5)(sass@1.78.0) + vitefu: 0.2.5(vite@5.4.4(@types/node@20.16.5)(sass@1.78.0)) transitivePeerDependencies: - supports-color @@ -6172,7 +6172,7 @@ snapshots: pg-protocol: 1.6.1 pg-types: 4.0.2 - '@types/pg@8.11.8': + '@types/pg@8.11.9': dependencies: '@types/node': 20.16.5 pg-protocol: 1.6.1 @@ -6185,34 +6185,34 @@ snapshots: '@types/validator@13.12.1': optional: true - '@typescript-eslint/eslint-plugin@7.18.0(@typescript-eslint/parser@7.18.0(eslint@8.57.0)(typescript@5.5.4))(eslint@8.57.0)(typescript@5.5.4)': + '@typescript-eslint/eslint-plugin@7.18.0(@typescript-eslint/parser@7.18.0(eslint@8.57.0)(typescript@5.6.2))(eslint@8.57.0)(typescript@5.6.2)': dependencies: '@eslint-community/regexpp': 4.11.0 - '@typescript-eslint/parser': 7.18.0(eslint@8.57.0)(typescript@5.5.4) + '@typescript-eslint/parser': 7.18.0(eslint@8.57.0)(typescript@5.6.2) '@typescript-eslint/scope-manager': 7.18.0 - '@typescript-eslint/type-utils': 7.18.0(eslint@8.57.0)(typescript@5.5.4) - '@typescript-eslint/utils': 7.18.0(eslint@8.57.0)(typescript@5.5.4) + '@typescript-eslint/type-utils': 7.18.0(eslint@8.57.0)(typescript@5.6.2) + '@typescript-eslint/utils': 7.18.0(eslint@8.57.0)(typescript@5.6.2) '@typescript-eslint/visitor-keys': 7.18.0 eslint: 8.57.0 graphemer: 1.4.0 ignore: 5.3.2 natural-compare: 1.4.0 - ts-api-utils: 1.3.0(typescript@5.5.4) + ts-api-utils: 1.3.0(typescript@5.6.2) optionalDependencies: - typescript: 5.5.4 + typescript: 5.6.2 transitivePeerDependencies: - supports-color - '@typescript-eslint/parser@7.18.0(eslint@8.57.0)(typescript@5.5.4)': + '@typescript-eslint/parser@7.18.0(eslint@8.57.0)(typescript@5.6.2)': dependencies: '@typescript-eslint/scope-manager': 7.18.0 '@typescript-eslint/types': 7.18.0 - '@typescript-eslint/typescript-estree': 7.18.0(typescript@5.5.4) + '@typescript-eslint/typescript-estree': 7.18.0(typescript@5.6.2) '@typescript-eslint/visitor-keys': 7.18.0 debug: 4.3.6 eslint: 8.57.0 optionalDependencies: - typescript: 5.5.4 + typescript: 5.6.2 transitivePeerDependencies: - supports-color @@ -6221,21 +6221,21 @@ snapshots: '@typescript-eslint/types': 7.18.0 '@typescript-eslint/visitor-keys': 7.18.0 - '@typescript-eslint/type-utils@7.18.0(eslint@8.57.0)(typescript@5.5.4)': + '@typescript-eslint/type-utils@7.18.0(eslint@8.57.0)(typescript@5.6.2)': dependencies: - '@typescript-eslint/typescript-estree': 7.18.0(typescript@5.5.4) - '@typescript-eslint/utils': 7.18.0(eslint@8.57.0)(typescript@5.5.4) + '@typescript-eslint/typescript-estree': 7.18.0(typescript@5.6.2) + '@typescript-eslint/utils': 7.18.0(eslint@8.57.0)(typescript@5.6.2) debug: 4.3.6 eslint: 8.57.0 - ts-api-utils: 1.3.0(typescript@5.5.4) + ts-api-utils: 1.3.0(typescript@5.6.2) optionalDependencies: - typescript: 5.5.4 + typescript: 5.6.2 transitivePeerDependencies: - supports-color '@typescript-eslint/types@7.18.0': {} - '@typescript-eslint/typescript-estree@7.18.0(typescript@5.5.4)': + '@typescript-eslint/typescript-estree@7.18.0(typescript@5.6.2)': dependencies: '@typescript-eslint/types': 7.18.0 '@typescript-eslint/visitor-keys': 7.18.0 @@ -6244,18 +6244,18 @@ snapshots: is-glob: 4.0.3 minimatch: 9.0.5 semver: 7.6.3 - ts-api-utils: 1.3.0(typescript@5.5.4) + ts-api-utils: 1.3.0(typescript@5.6.2) optionalDependencies: - typescript: 5.5.4 + typescript: 5.6.2 transitivePeerDependencies: - supports-color - '@typescript-eslint/utils@7.18.0(eslint@8.57.0)(typescript@5.5.4)': + '@typescript-eslint/utils@7.18.0(eslint@8.57.0)(typescript@5.6.2)': dependencies: '@eslint-community/eslint-utils': 4.4.0(eslint@8.57.0) '@typescript-eslint/scope-manager': 7.18.0 '@typescript-eslint/types': 7.18.0 - '@typescript-eslint/typescript-estree': 7.18.0(typescript@5.5.4) + '@typescript-eslint/typescript-estree': 7.18.0(typescript@5.6.2) eslint: 8.57.0 transitivePeerDependencies: - supports-color @@ -6508,7 +6508,7 @@ snapshots: builtin-modules@3.3.0: {} - bullmq@5.12.14: + bullmq@5.13.0: dependencies: cron-parser: 4.9.0 ioredis: 5.4.1 @@ -6769,16 +6769,16 @@ snapshots: transitivePeerDependencies: - supports-color - drizzle-orm@0.32.2(@neondatabase/serverless@0.9.5)(@types/pg@8.11.8)(pg@8.12.0)(postgres@3.4.4): + drizzle-orm@0.32.2(@neondatabase/serverless@0.9.5)(@types/pg@8.11.9)(pg@8.12.0)(postgres@3.4.4): optionalDependencies: '@neondatabase/serverless': 0.9.5 - '@types/pg': 8.11.8 + '@types/pg': 8.11.9 pg: 8.12.0 postgres: 3.4.4 - drizzle-zod@0.5.1(drizzle-orm@0.32.2(@neondatabase/serverless@0.9.5)(@types/pg@8.11.8)(pg@8.12.0)(postgres@3.4.4))(zod@3.23.8): + drizzle-zod@0.5.1(drizzle-orm@0.32.2(@neondatabase/serverless@0.9.5)(@types/pg@8.11.9)(pg@8.12.0)(postgres@3.4.4))(zod@3.23.8): dependencies: - drizzle-orm: 0.32.2(@neondatabase/serverless@0.9.5)(@types/pg@8.11.8)(pg@8.12.0)(postgres@3.4.4) + drizzle-orm: 0.32.2(@neondatabase/serverless@0.9.5)(@types/pg@8.11.9)(pg@8.12.0)(postgres@3.4.4) zod: 3.23.8 eastasianwidth@0.2.0: {} @@ -6936,7 +6936,7 @@ snapshots: dependencies: eslint: 8.57.0 - eslint-plugin-svelte@2.36.0-next.13(eslint@8.57.0)(svelte@5.0.0-next.175)(ts-node@10.9.2(@types/node@20.16.5)(typescript@5.5.4)): + eslint-plugin-svelte@2.36.0-next.13(eslint@8.57.0)(svelte@5.0.0-next.175)(ts-node@10.9.2(@types/node@20.16.5)(typescript@5.6.2)): dependencies: '@eslint-community/eslint-utils': 4.4.0(eslint@8.57.0) '@jridgewell/sourcemap-codec': 1.5.0 @@ -6946,7 +6946,7 @@ snapshots: esutils: 2.0.3 known-css-properties: 0.30.0 postcss: 8.4.45 - postcss-load-config: 3.1.4(postcss@8.4.45)(ts-node@10.9.2(@types/node@20.16.5)(typescript@5.5.4)) + postcss-load-config: 3.1.4(postcss@8.4.45)(ts-node@10.9.2(@types/node@20.16.5)(typescript@5.6.2)) postcss-safe-parser: 6.0.0(postcss@8.4.45) postcss-selector-parser: 6.1.2 semver: 7.6.3 @@ -7170,11 +7170,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.26(@sveltejs/vite-plugin-svelte@3.1.2(svelte@5.0.0-next.175)(vite@5.4.3(@types/node@20.16.5)(sass@1.78.0)))(svelte@5.0.0-next.175)(vite@5.4.3(@types/node@20.16.5)(sass@1.78.0)))(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.26(@sveltejs/vite-plugin-svelte@3.1.2(svelte@5.0.0-next.175)(vite@5.4.4(@types/node@20.16.5)(sass@1.78.0)))(svelte@5.0.0-next.175)(vite@5.4.4(@types/node@20.16.5)(sass@1.78.0)))(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.26(@sveltejs/vite-plugin-svelte@3.1.2(svelte@5.0.0-next.175)(vite@5.4.3(@types/node@20.16.5)(sass@1.78.0)))(svelte@5.0.0-next.175)(vite@5.4.3(@types/node@20.16.5)(sass@1.78.0)))(svelte@5.0.0-next.175) + sveltekit-superforms: 2.17.0(@sveltejs/kit@2.5.26(@sveltejs/vite-plugin-svelte@3.1.2(svelte@5.0.0-next.175)(vite@5.4.4(@types/node@20.16.5)(sass@1.78.0)))(svelte@5.0.0-next.175)(vite@5.4.4(@types/node@20.16.5)(sass@1.78.0)))(svelte@5.0.0-next.175) forwarded@0.2.0: {} @@ -7307,11 +7307,11 @@ snapshots: hex-rgb@4.3.0: {} - hono-rate-limiter@0.4.0(hono@4.5.11): + hono-rate-limiter@0.4.0(hono@4.6.1): dependencies: - hono: 4.5.11 + hono: 4.6.1 - hono@4.5.11: {} + hono@4.6.1: {} html-entities@2.5.2: {} @@ -8014,30 +8014,30 @@ snapshots: '@csstools/utilities': 1.0.0(postcss@8.4.45) postcss: 8.4.45 - postcss-load-config@3.1.4(postcss@8.4.45)(ts-node@10.9.2(@types/node@20.16.5)(typescript@5.5.4)): + postcss-load-config@3.1.4(postcss@8.4.45)(ts-node@10.9.2(@types/node@20.16.5)(typescript@5.6.2)): dependencies: lilconfig: 2.1.0 yaml: 1.10.2 optionalDependencies: postcss: 8.4.45 - ts-node: 10.9.2(@types/node@20.16.5)(typescript@5.5.4) + ts-node: 10.9.2(@types/node@20.16.5)(typescript@5.6.2) - postcss-load-config@4.0.2(postcss@8.4.45)(ts-node@10.9.2(@types/node@20.16.5)(typescript@5.5.4)): + postcss-load-config@4.0.2(postcss@8.4.45)(ts-node@10.9.2(@types/node@20.16.5)(typescript@5.6.2)): dependencies: lilconfig: 3.1.2 yaml: 2.5.1 optionalDependencies: postcss: 8.4.45 - ts-node: 10.9.2(@types/node@20.16.5)(typescript@5.5.4) + ts-node: 10.9.2(@types/node@20.16.5)(typescript@5.6.2) - postcss-load-config@5.1.0(jiti@1.21.6)(postcss@8.4.45)(tsx@4.19.0): + postcss-load-config@5.1.0(jiti@1.21.6)(postcss@8.4.45)(tsx@4.19.1): dependencies: lilconfig: 3.1.2 yaml: 2.5.1 optionalDependencies: jiti: 1.21.6 postcss: 8.4.45 - tsx: 4.19.0 + tsx: 4.19.1 postcss-logical@7.0.1(postcss@8.4.45): dependencies: @@ -8386,9 +8386,9 @@ snapshots: postcss-value-parser: 4.2.0 yoga-wasm-web: 0.3.3 - schema-dts@1.1.2(typescript@5.5.4): + schema-dts@1.1.2(typescript@5.6.2): dependencies: - typescript: 5.5.4 + typescript: 5.6.2 semver@6.3.1: {} @@ -8578,15 +8578,15 @@ snapshots: supports-preserve-symlinks-flag@1.0.0: {} - svelte-check@3.8.6(postcss-load-config@5.1.0(jiti@1.21.6)(postcss@8.4.45)(tsx@4.19.0))(postcss@8.4.45)(sass@1.78.0)(svelte@5.0.0-next.175): + svelte-check@3.8.6(postcss-load-config@5.1.0(jiti@1.21.6)(postcss@8.4.45)(tsx@4.19.1))(postcss@8.4.45)(sass@1.78.0)(svelte@5.0.0-next.175): dependencies: '@jridgewell/trace-mapping': 0.3.25 chokidar: 3.6.0 picocolors: 1.1.0 sade: 1.8.1 svelte: 5.0.0-next.175 - svelte-preprocess: 5.1.4(postcss-load-config@5.1.0(jiti@1.21.6)(postcss@8.4.45)(tsx@4.19.0))(postcss@8.4.45)(sass@1.78.0)(svelte@5.0.0-next.175)(typescript@5.5.4) - typescript: 5.5.4 + svelte-preprocess: 5.1.4(postcss-load-config@5.1.0(jiti@1.21.6)(postcss@8.4.45)(tsx@4.19.1))(postcss@8.4.45)(sass@1.78.0)(svelte@5.0.0-next.175)(typescript@5.6.2) + typescript: 5.6.2 transitivePeerDependencies: - '@babel/core' - coffeescript @@ -8630,9 +8630,9 @@ snapshots: svelte-lazy-loader@1.0.0: {} - svelte-meta-tags@3.1.4(svelte@5.0.0-next.175)(typescript@5.5.4): + svelte-meta-tags@3.1.4(svelte@5.0.0-next.175)(typescript@5.6.2): dependencies: - schema-dts: 1.1.2(typescript@5.5.4) + schema-dts: 1.1.2(typescript@5.6.2) svelte: 5.0.0-next.175 transitivePeerDependencies: - typescript @@ -8641,7 +8641,7 @@ snapshots: dependencies: svelte: 5.0.0-next.175 - svelte-preprocess@5.1.4(postcss-load-config@5.1.0(jiti@1.21.6)(postcss@8.4.45)(tsx@4.19.0))(postcss@8.4.45)(sass@1.78.0)(svelte@5.0.0-next.175)(typescript@5.5.4): + svelte-preprocess@5.1.4(postcss-load-config@5.1.0(jiti@1.21.6)(postcss@8.4.45)(tsx@4.19.1))(postcss@8.4.45)(sass@1.78.0)(svelte@5.0.0-next.175)(typescript@5.6.2): dependencies: '@types/pug': 2.0.10 detect-indent: 6.1.0 @@ -8651,18 +8651,18 @@ snapshots: svelte: 5.0.0-next.175 optionalDependencies: postcss: 8.4.45 - postcss-load-config: 5.1.0(jiti@1.21.6)(postcss@8.4.45)(tsx@4.19.0) + postcss-load-config: 5.1.0(jiti@1.21.6)(postcss@8.4.45)(tsx@4.19.1) sass: 1.78.0 - typescript: 5.5.4 + typescript: 5.6.2 - svelte-preprocess@6.0.2(postcss-load-config@5.1.0(jiti@1.21.6)(postcss@8.4.45)(tsx@4.19.0))(postcss@8.4.45)(sass@1.78.0)(svelte@5.0.0-next.175)(typescript@5.5.4): + svelte-preprocess@6.0.2(postcss-load-config@5.1.0(jiti@1.21.6)(postcss@8.4.45)(tsx@4.19.1))(postcss@8.4.45)(sass@1.78.0)(svelte@5.0.0-next.175)(typescript@5.6.2): dependencies: svelte: 5.0.0-next.175 optionalDependencies: postcss: 8.4.45 - postcss-load-config: 5.1.0(jiti@1.21.6)(postcss@8.4.45)(tsx@4.19.0) + postcss-load-config: 5.1.0(jiti@1.21.6)(postcss@8.4.45)(tsx@4.19.1) sass: 1.78.0 - typescript: 5.5.4 + typescript: 5.6.2 svelte-render@2.0.1(svelte@5.0.0-next.175): dependencies: @@ -8715,19 +8715,19 @@ snapshots: magic-string: 0.30.11 zimmerframe: 1.1.2 - sveltekit-flash-message@2.4.4(@sveltejs/kit@2.5.26(@sveltejs/vite-plugin-svelte@3.1.2(svelte@5.0.0-next.175)(vite@5.4.3(@types/node@20.16.5)(sass@1.78.0)))(svelte@5.0.0-next.175)(vite@5.4.3(@types/node@20.16.5)(sass@1.78.0)))(svelte@5.0.0-next.175): + sveltekit-flash-message@2.4.4(@sveltejs/kit@2.5.26(@sveltejs/vite-plugin-svelte@3.1.2(svelte@5.0.0-next.175)(vite@5.4.4(@types/node@20.16.5)(sass@1.78.0)))(svelte@5.0.0-next.175)(vite@5.4.4(@types/node@20.16.5)(sass@1.78.0)))(svelte@5.0.0-next.175): dependencies: - '@sveltejs/kit': 2.5.26(@sveltejs/vite-plugin-svelte@3.1.2(svelte@5.0.0-next.175)(vite@5.4.3(@types/node@20.16.5)(sass@1.78.0)))(svelte@5.0.0-next.175)(vite@5.4.3(@types/node@20.16.5)(sass@1.78.0)) + '@sveltejs/kit': 2.5.26(@sveltejs/vite-plugin-svelte@3.1.2(svelte@5.0.0-next.175)(vite@5.4.4(@types/node@20.16.5)(sass@1.78.0)))(svelte@5.0.0-next.175)(vite@5.4.4(@types/node@20.16.5)(sass@1.78.0)) svelte: 5.0.0-next.175 - sveltekit-rate-limiter@0.5.2(@sveltejs/kit@2.5.26(@sveltejs/vite-plugin-svelte@3.1.2(svelte@5.0.0-next.175)(vite@5.4.3(@types/node@20.16.5)(sass@1.78.0)))(svelte@5.0.0-next.175)(vite@5.4.3(@types/node@20.16.5)(sass@1.78.0))): + sveltekit-rate-limiter@0.5.2(@sveltejs/kit@2.5.26(@sveltejs/vite-plugin-svelte@3.1.2(svelte@5.0.0-next.175)(vite@5.4.4(@types/node@20.16.5)(sass@1.78.0)))(svelte@5.0.0-next.175)(vite@5.4.4(@types/node@20.16.5)(sass@1.78.0))): dependencies: '@isaacs/ttlcache': 1.4.1 - '@sveltejs/kit': 2.5.26(@sveltejs/vite-plugin-svelte@3.1.2(svelte@5.0.0-next.175)(vite@5.4.3(@types/node@20.16.5)(sass@1.78.0)))(svelte@5.0.0-next.175)(vite@5.4.3(@types/node@20.16.5)(sass@1.78.0)) + '@sveltejs/kit': 2.5.26(@sveltejs/vite-plugin-svelte@3.1.2(svelte@5.0.0-next.175)(vite@5.4.4(@types/node@20.16.5)(sass@1.78.0)))(svelte@5.0.0-next.175)(vite@5.4.4(@types/node@20.16.5)(sass@1.78.0)) - sveltekit-superforms@2.17.0(@sveltejs/kit@2.5.26(@sveltejs/vite-plugin-svelte@3.1.2(svelte@5.0.0-next.175)(vite@5.4.3(@types/node@20.16.5)(sass@1.78.0)))(svelte@5.0.0-next.175)(vite@5.4.3(@types/node@20.16.5)(sass@1.78.0)))(svelte@5.0.0-next.175): + sveltekit-superforms@2.17.0(@sveltejs/kit@2.5.26(@sveltejs/vite-plugin-svelte@3.1.2(svelte@5.0.0-next.175)(vite@5.4.4(@types/node@20.16.5)(sass@1.78.0)))(svelte@5.0.0-next.175)(vite@5.4.4(@types/node@20.16.5)(sass@1.78.0)))(svelte@5.0.0-next.175): dependencies: - '@sveltejs/kit': 2.5.26(@sveltejs/vite-plugin-svelte@3.1.2(svelte@5.0.0-next.175)(vite@5.4.3(@types/node@20.16.5)(sass@1.78.0)))(svelte@5.0.0-next.175)(vite@5.4.3(@types/node@20.16.5)(sass@1.78.0)) + '@sveltejs/kit': 2.5.26(@sveltejs/vite-plugin-svelte@3.1.2(svelte@5.0.0-next.175)(vite@5.4.4(@types/node@20.16.5)(sass@1.78.0)))(svelte@5.0.0-next.175)(vite@5.4.4(@types/node@20.16.5)(sass@1.78.0)) devalue: 5.0.0 just-clone: 6.2.0 memoize-weak: 1.0.2 @@ -8746,22 +8746,22 @@ snapshots: valibot: 0.35.0 yup: 1.4.0 zod: 3.23.8 - zod-to-json-schema: 3.23.2(zod@3.23.8) + zod-to-json-schema: 3.23.3(zod@3.23.8) tabbable@6.2.0: {} tailwind-merge@2.5.2: {} - tailwind-variants@0.2.1(tailwindcss@3.4.10(ts-node@10.9.2(@types/node@20.16.5)(typescript@5.5.4))): + tailwind-variants@0.2.1(tailwindcss@3.4.11(ts-node@10.9.2(@types/node@20.16.5)(typescript@5.6.2))): dependencies: tailwind-merge: 2.5.2 - tailwindcss: 3.4.10(ts-node@10.9.2(@types/node@20.16.5)(typescript@5.5.4)) + tailwindcss: 3.4.11(ts-node@10.9.2(@types/node@20.16.5)(typescript@5.6.2)) - tailwindcss-animate@1.0.7(tailwindcss@3.4.10(ts-node@10.9.2(@types/node@20.16.5)(typescript@5.5.4))): + tailwindcss-animate@1.0.7(tailwindcss@3.4.11(ts-node@10.9.2(@types/node@20.16.5)(typescript@5.6.2))): dependencies: - tailwindcss: 3.4.10(ts-node@10.9.2(@types/node@20.16.5)(typescript@5.5.4)) + tailwindcss: 3.4.11(ts-node@10.9.2(@types/node@20.16.5)(typescript@5.6.2)) - tailwindcss@3.4.10(ts-node@10.9.2(@types/node@20.16.5)(typescript@5.5.4)): + tailwindcss@3.4.11(ts-node@10.9.2(@types/node@20.16.5)(typescript@5.6.2)): dependencies: '@alloc/quick-lru': 5.2.0 arg: 5.0.2 @@ -8780,7 +8780,7 @@ snapshots: postcss: 8.4.45 postcss-import: 15.1.0(postcss@8.4.45) postcss-js: 4.0.1(postcss@8.4.45) - postcss-load-config: 4.0.2(postcss@8.4.45)(ts-node@10.9.2(@types/node@20.16.5)(typescript@5.5.4)) + postcss-load-config: 4.0.2(postcss@8.4.45)(ts-node@10.9.2(@types/node@20.16.5)(typescript@5.6.2)) postcss-nested: 6.2.0(postcss@8.4.45) postcss-selector-parser: 6.1.2 resolve: 1.22.8 @@ -8839,15 +8839,15 @@ snapshots: ts-algebra@2.0.0: optional: true - ts-api-utils@1.3.0(typescript@5.5.4): + ts-api-utils@1.3.0(typescript@5.6.2): dependencies: - typescript: 5.5.4 + typescript: 5.6.2 ts-deepmerge@7.0.1: {} ts-interface-checker@0.1.13: {} - ts-node@10.9.2(@types/node@20.16.5)(typescript@5.5.4): + ts-node@10.9.2(@types/node@20.16.5)(typescript@5.6.2): dependencies: '@cspotcode/source-map-support': 0.8.1 '@tsconfig/node10': 1.0.11 @@ -8861,7 +8861,7 @@ snapshots: create-require: 1.1.1 diff: 4.0.2 make-error: 1.3.6 - typescript: 5.5.4 + typescript: 5.6.2 v8-compile-cache-lib: 3.0.1 yn: 3.1.1 @@ -8874,7 +8874,7 @@ snapshots: tslib@2.7.0: {} - tsx@4.19.0: + tsx@4.19.1: dependencies: esbuild: 0.23.1 get-tsconfig: 4.8.0 @@ -8901,7 +8901,7 @@ snapshots: media-typer: 0.3.0 mime-types: 2.1.35 - typescript@5.5.4: {} + typescript@5.6.2: {} ufo@1.5.4: {} @@ -8964,7 +8964,7 @@ snapshots: debug: 4.3.6 pathe: 1.1.2 picocolors: 1.1.0 - vite: 5.4.3(@types/node@20.16.5)(sass@1.78.0) + vite: 5.4.4(@types/node@20.16.5)(sass@1.78.0) transitivePeerDependencies: - '@types/node' - less @@ -8976,7 +8976,7 @@ snapshots: - supports-color - terser - vite@5.4.3(@types/node@20.16.5)(sass@1.78.0): + vite@5.4.4(@types/node@20.16.5)(sass@1.78.0): dependencies: esbuild: 0.21.5 postcss: 8.4.45 @@ -8986,9 +8986,9 @@ snapshots: fsevents: 2.3.3 sass: 1.78.0 - vitefu@0.2.5(vite@5.4.3(@types/node@20.16.5)(sass@1.78.0)): + vitefu@0.2.5(vite@5.4.4(@types/node@20.16.5)(sass@1.78.0)): optionalDependencies: - vite: 5.4.3(@types/node@20.16.5)(sass@1.78.0) + vite: 5.4.4(@types/node@20.16.5)(sass@1.78.0) vitest@1.6.0(@types/node@20.16.5)(sass@1.78.0): dependencies: @@ -9009,7 +9009,7 @@ snapshots: strip-literal: 2.1.0 tinybench: 2.9.0 tinypool: 0.8.4 - vite: 5.4.3(@types/node@20.16.5)(sass@1.78.0) + vite: 5.4.4(@types/node@20.16.5)(sass@1.78.0) vite-node: 1.6.0(@types/node@20.16.5)(sass@1.78.0) why-is-node-running: 2.3.0 optionalDependencies: @@ -9117,7 +9117,7 @@ snapshots: zimmerframe@1.1.2: {} - zod-to-json-schema@3.23.2(zod@3.23.8): + zod-to-json-schema@3.23.3(zod@3.23.8): dependencies: zod: 3.23.8 diff --git a/src/lib/server/api/repositories/credentials.repository.ts b/src/lib/server/api/repositories/credentials.repository.ts index 11f56c5..0671a40 100644 --- a/src/lib/server/api/repositories/credentials.repository.ts +++ b/src/lib/server/api/repositories/credentials.repository.ts @@ -7,6 +7,7 @@ import { takeFirstOrThrow } from '../common/utils/repository' export type CreateCredentials = InferInsertModel export type UpdateCredentials = Partial +export type DeleteCredentials = Pick @injectable() export class CredentialsRepository { diff --git a/src/lib/server/api/tests/hashing.service.test.ts b/src/lib/server/api/tests/hashing.service.test.ts index 94c7f89..d7fe080 100644 --- a/src/lib/server/api/tests/hashing.service.test.ts +++ b/src/lib/server/api/tests/hashing.service.test.ts @@ -1,32 +1,38 @@ -import 'reflect-metadata'; -import { container } from 'tsyringe'; -import { afterAll, beforeAll, describe, expect, it, vi } from 'vitest'; -import { HashingService } from '../services/hashing.service'; +import 'reflect-metadata' +import { container } from 'tsyringe' +import { afterAll, beforeAll, describe, expect, it, vi } from 'vitest' +import { HashingService } from '../services/hashing.service' describe('HashingService', () => { - let service: HashingService; + let service: HashingService beforeAll(() => { - service = container.resolve(HashingService); - }); + service = container.resolve(HashingService) + }) afterAll(() => { vi.resetAllMocks() - }); + }) describe('Create Hash', () => { it('should create a hash', async () => { - const hash = await service.hash('111'); - expect(hash).not.toBeUndefined(); - expect(hash).not.toBeNull(); - }); + const hash = await service.hash('111') + expect(hash).not.toBeUndefined() + expect(hash).not.toBeNull() + }) }) describe('Verify Hash', () => { it('should verify a hash', async () => { - const hash = await service.hash('111'); - const verifiable = await service.verify(hash, '111'); - expect(verifiable).toBeTruthy(); - }); + const hash = await service.hash('111') + const verifiable = await service.verify(hash, '111') + expect(verifiable).toBeTruthy() + }) + + it('should not verify a hash', async () => { + const hash = await service.hash('111') + const verifiable = await service.verify(hash, '222') + expect(verifiable).toBeFalsy() + }) }) -}) \ No newline at end of file +}) diff --git a/src/lib/server/api/tests/iam.service.test.ts b/src/lib/server/api/tests/iam.service.test.ts new file mode 100644 index 0000000..96d3174 --- /dev/null +++ b/src/lib/server/api/tests/iam.service.test.ts @@ -0,0 +1,105 @@ +import 'reflect-metadata' +import { IamService } from '$lib/server/api/services/iam.service' +import { LuciaService } from '$lib/server/api/services/lucia.service' +import { UsersService } from '$lib/server/api/services/users.service' +import { container } from 'tsyringe' +import { afterAll, beforeAll, beforeEach, describe, expect, it, vi } from 'vitest' + +describe('IamService', () => { + let service: IamService + const luciaService = vi.mocked(LuciaService.prototype) + const userService = vi.mocked(UsersService.prototype) + + beforeAll(() => { + service = container + .register(LuciaService, { useValue: luciaService }) + .register(UsersService, { useValue: userService }) + .resolve(IamService) + }) + + beforeEach(() => { + vi.resetAllMocks() + }) + + afterAll(() => { + vi.resetAllMocks() + }) + + describe('Update Profile', () => { + it('should resolve', async () => { + const timeStampDate = new Date() + userService.findOneById = vi.fn().mockResolvedValueOnce({ + id: '3e0e9f0f-0a0b-4f0b-8f0b-0a0b4f0b8f0b', + cuid: 'ciglo1j8q0000t9j4xq8d6p5e', + first_name: 'test', + last_name: 'test', + email: 'test@example.com', + username: 'test', + verified: false, + receive_email: false, + mfa_enabled: false, + theme: 'system', + createdAt: timeStampDate, + updatedAt: timeStampDate, + }) + userService.findOneByUsername = vi.fn().mockResolvedValue(undefined) + userService.updateUser = vi.fn().mockResolvedValue({ + id: '3e0e9f0f-0a0b-4f0b-8f0b-0a0b4f0b8f0b', + cuid: 'ciglo1j8q0000t9j4xq8d6p5e', + first_name: 'test', + last_name: 'test', + email: 'test@example.com', + username: 'test', + verified: false, + receive_email: false, + mfa_enabled: false, + theme: 'system', + createdAt: timeStampDate, + updatedAt: timeStampDate, + }) + + const spy_userService_findOneById = vi.spyOn(userService, 'findOneById') + const spy_userService_findOneByUsername = vi.spyOn(userService, 'findOneByUsername') + const spy_userService_updateUser = vi.spyOn(userService, 'updateUser') + await expect( + service.updateProfile('3e0e9f0f-0a0b-4f0b-8f0b-0a0b4f0b8f0b', { + username: 'test', + }), + ).resolves.toEqual({ + id: '3e0e9f0f-0a0b-4f0b-8f0b-0a0b4f0b8f0b', + cuid: 'ciglo1j8q0000t9j4xq8d6p5e', + first_name: 'test', + last_name: 'test', + email: 'test@example.com', + username: 'test', + verified: false, + receive_email: false, + mfa_enabled: false, + theme: 'system', + createdAt: timeStampDate, + updatedAt: timeStampDate, + }) + expect(spy_userService_findOneById).toBeCalledTimes(1) + expect(spy_userService_findOneByUsername).toBeCalledTimes(1) + expect(spy_userService_updateUser).toBeCalledTimes(1) + }) + + it('should error on no user found', async () => { + userService.findOneById = vi.fn().mockResolvedValueOnce(undefined) + + const spy_userService_findOneById = vi.spyOn(userService, 'findOneById') + const spy_userService_findOneByUsername = vi.spyOn(userService, 'findOneByUsername') + const spy_userService_updateUser = vi.spyOn(userService, 'updateUser') + await expect( + service.updateProfile('3e0e9f0f-0a0b-4f0b-8f0b-0a0b4f0b8f0b', { + username: 'test', + }), + ).resolves.toEqual({ + error: 'User not found', + }) + expect(spy_userService_findOneById).toBeCalledTimes(1) + expect(spy_userService_findOneByUsername).toBeCalledTimes(0) + expect(spy_userService_updateUser).toBeCalledTimes(0) + }) + }) +}) diff --git a/src/lib/server/api/tests/tokens.service.test.ts b/src/lib/server/api/tests/tokens.service.test.ts index 5c0e34e..ad0aa3b 100644 --- a/src/lib/server/api/tests/tokens.service.test.ts +++ b/src/lib/server/api/tests/tokens.service.test.ts @@ -1,49 +1,47 @@ -import 'reflect-metadata'; -import { container } from 'tsyringe'; -import { afterAll, beforeAll, describe, expect, it, vi } from 'vitest'; -import { TokensService } from '../services/tokens.service'; -import { HashingService } from '../services/hashing.service'; -import { Argon2id } from 'oslo/password'; +import 'reflect-metadata' +import { Argon2id } from 'oslo/password' +import { container } from 'tsyringe' +import { afterAll, beforeAll, describe, expect, it, vi } from 'vitest' +import { HashingService } from '../services/hashing.service' +import { TokensService } from '../services/tokens.service' describe('TokensService', () => { - let service: TokensService; - const hashingService = vi.mocked(HashingService.prototype); + let service: TokensService + const hashingService = vi.mocked(HashingService.prototype) beforeAll(() => { - service = container - .register(HashingService, { useValue: hashingService }) - .resolve(TokensService); - }); + service = container.register(HashingService, { useValue: hashingService }).resolve(TokensService) + }) afterAll(() => { vi.resetAllMocks() - }); + }) describe('Generate Token', () => { - const hashedPassword = new Argon2id().hash('111'); + const hashedPassword = new Argon2id().hash('111') - hashingService.hash = vi.fn().mockResolvedValue(hashedPassword); - hashingService.verify = vi.fn().mockResolvedValue(true); + hashingService.hash = vi.fn().mockResolvedValue(hashedPassword) + hashingService.verify = vi.fn().mockResolvedValue(true) - const spy_hashingService_hash = vi.spyOn(hashingService, 'hash'); - const spy_hashingService_verify = vi.spyOn(hashingService, 'verify'); + const spy_hashingService_hash = vi.spyOn(hashingService, 'hash') + const spy_hashingService_verify = vi.spyOn(hashingService, 'verify') it('should resolve', async () => { - await expect(service.createHashedToken('111')).resolves.string + expect(service.createHashedToken('111')).resolves.string }) it('should generate a token that is verifiable', async () => { - const token = await service.createHashedToken('111'); - expect(token).not.toBeUndefined(); - expect(token).not.toBeNull(); - const verifiable = await service.verifyHashedToken(token, '111'); - expect(verifiable).toBeTruthy(); - }); + const token = await service.createHashedToken('111') + expect(token).not.toBeUndefined() + expect(token).not.toBeNull() + const verifiable = await service.verifyHashedToken(token, '111') + expect(verifiable).toBeTruthy() + }) it('should generate a hashed token', async () => { - expect(spy_hashingService_hash).toHaveBeenCalledTimes(2); + expect(spy_hashingService_hash).toHaveBeenCalledTimes(2) }) it('should verify a hashed token', async () => { - expect(spy_hashingService_verify).toHaveBeenCalledTimes(1); + expect(spy_hashingService_verify).toHaveBeenCalledTimes(1) }) - }); -}); \ No newline at end of file + }) +}) diff --git a/src/lib/server/api/tests/users.service.test.ts b/src/lib/server/api/tests/users.service.test.ts index fb40e5f..ec551a2 100644 --- a/src/lib/server/api/tests/users.service.test.ts +++ b/src/lib/server/api/tests/users.service.test.ts @@ -1,44 +1,47 @@ -import 'reflect-metadata'; -import { container } from 'tsyringe'; -import { afterAll, beforeAll, describe, expect, it, vi } from 'vitest'; -import { UsersService } from '../services/users.service'; -import { CredentialsRepository } from '../repositories/credentials.repository'; -import { TokensService } from '../services/tokens.service'; -import { UserRolesService } from '../services/user_roles.service'; -import { UsersRepository } from '../repositories/users.repository'; -import { Argon2id } from 'oslo/password'; -import { WishlistsService } from '../services/wishlists.service'; -import { CollectionsService } from '../services/collections.service'; +import 'reflect-metadata' +import { CredentialsType } from '$lib/server/api/databases/tables' +import { Argon2id } from 'oslo/password' +import { container } from 'tsyringe' +import { afterAll, afterEach, beforeAll, beforeEach, describe, expect, it, vi } from 'vitest' +import { CredentialsRepository } from '../repositories/credentials.repository' +import { UsersRepository } from '../repositories/users.repository' +import { CollectionsService } from '../services/collections.service' +import { TokensService } from '../services/tokens.service' +import { UserRolesService } from '../services/user_roles.service' +import { UsersService } from '../services/users.service' +import { WishlistsService } from '../services/wishlists.service' describe('UsersService', () => { - let service: UsersService; - const credentialsRepository = vi.mocked(CredentialsRepository.prototype); - const tokensService = vi.mocked(TokensService.prototype); - const usersRepository = vi.mocked(UsersRepository.prototype); - const userRolesService = vi.mocked(UserRolesService.prototype); - const wishlistsService = vi.mocked(WishlistsService.prototype); - const collectionsService = vi.mocked(CollectionsService.prototype); + let service: UsersService + const credentialsRepository = vi.mocked(CredentialsRepository.prototype) + const tokensService = vi.mocked(TokensService.prototype) + const usersRepository = vi.mocked(UsersRepository.prototype) + const userRolesService = vi.mocked(UserRolesService.prototype) + const wishlistsService = vi.mocked(WishlistsService.prototype) + const collectionsService = vi.mocked(CollectionsService.prototype) - beforeAll(() => { - service = container - .register(CredentialsRepository, { useValue: credentialsRepository }) + beforeAll(() => { + service = container + .register(CredentialsRepository, { useValue: credentialsRepository }) .register(TokensService, { useValue: tokensService }) .register(UsersRepository, { useValue: usersRepository }) .register(UserRolesService, { useValue: userRolesService }) .register(WishlistsService, { useValue: wishlistsService }) .register(CollectionsService, { useValue: collectionsService }) - .resolve(UsersService); - }); + .resolve(UsersService) + }) - afterAll(() => { - vi.resetAllMocks() - }) + afterAll(() => { + vi.resetAllMocks() + }) describe('Create User', () => { - const hashedPassword = new Argon2id().hash('111'); - tokensService.createHashedToken = vi.fn().mockResolvedValue(hashedPassword) + const date = new Date() - usersRepository.create = vi.fn().mockResolvedValue({ + const hashedPassword = new Argon2id().hash('111') + tokensService.createHashedToken = vi.fn().mockResolvedValue(hashedPassword) + + usersRepository.create = vi.fn().mockResolvedValue({ id: '3e0e9f0f-0a0b-4f0b-8f0b-0a0b4f0b8f0b', cuid: 'ciglo1j8q0000t9j4xq8d6p5e', first_name: 'test', @@ -47,17 +50,18 @@ describe('UsersService', () => { username: 'test', verified: false, receive_email: false, + mfa_enabled: false, theme: 'system', - createdAt: new Date(), - updatedAt: new Date() - } satisfies Awaited>) + createdAt: date, + updatedAt: date, + } satisfies Awaited>) credentialsRepository.create = vi.fn().mockResolvedValue({ id: '3e0e9f0f-0a0b-4f0b-8f0b-0a0b4f0b8f0b', user_id: '3e0e9f0f-0a0b-4f0b-8f0b-0a0b4f0b8f0b', - type: 'PASSWORD', - secret_data: hashedPassword - }) + type: CredentialsType.PASSWORD, + secret_data: hashedPassword, + }) satisfies Awaited> userRolesService.addRoleToUser = vi.fn().mockResolvedValue(undefined) @@ -65,40 +69,121 @@ describe('UsersService', () => { collectionsService.createEmptyNoName = vi.fn().mockResolvedValue(undefined) - const spy_tokensService_createHashToken = vi.spyOn(tokensService, 'createHashedToken'); - const spy_usersRepository_create = vi.spyOn(usersRepository, 'create'); - const spy_credentialsRepository_create = vi.spyOn(credentialsRepository, 'create'); - const spy_userRolesService_addRoleToUser = vi.spyOn(userRolesService, 'addRoleToUser'); - const spy_wishlistsService_createEmptyNoName = vi.spyOn(wishlistsService, 'createEmptyNoName'); - const spy_collectionsService_createEmptyNoName = vi.spyOn(collectionsService, 'createEmptyNoName'); + const spy_tokensService_createHashToken = vi.spyOn(tokensService, 'createHashedToken') + const spy_usersRepository_create = vi.spyOn(usersRepository, 'create') + const spy_credentialsRepository_create = vi.spyOn(credentialsRepository, 'create') + const spy_userRolesService_addRoleToUser = vi.spyOn(userRolesService, 'addRoleToUser') + const spy_wishlistsService_createEmptyNoName = vi.spyOn(wishlistsService, 'createEmptyNoName') + const spy_collectionsService_createEmptyNoName = vi.spyOn(collectionsService, 'createEmptyNoName') - it('should resolve', async () => { - await expect(service.create({ - firstName: 'test', - lastName: 'test', + it('should resolve', async () => { + await expect( + service.create({ + firstName: 'test', + lastName: 'test', + email: 'test@example.com', + username: 'test', + password: '111', + confirm_password: '111', + }), + ).resolves.toEqual({ + id: '3e0e9f0f-0a0b-4f0b-8f0b-0a0b4f0b8f0b', + cuid: 'ciglo1j8q0000t9j4xq8d6p5e', + first_name: 'test', + last_name: 'test', email: 'test@example.com', username: 'test', - password: '111', - confirm_password: '111' - })).resolves.not.toThrow() - }) - it('should generate a hashed token', async () => { - expect(spy_tokensService_createHashToken).toBeCalledTimes(1) - }) - it('should create a new user', async () => { - expect(spy_usersRepository_create).toHaveBeenCalledTimes(1) - }) - it('should create a new credential', async () => { - expect(spy_credentialsRepository_create).toBeCalledTimes(1) + verified: false, + receive_email: false, + mfa_enabled: false, + theme: 'system', + createdAt: date, + updatedAt: date, + }) }) - it('should add role to user', async () => { - expect(spy_userRolesService_addRoleToUser).toBeCalledTimes(1) + // it('should generate a hashed token', async () => { + // expect(spy_tokensService_createHashToken).toBeCalledTimes(1) + // }) + // it('should create a new user', async () => { + // expect(spy_usersRepository_create).toBeCalledTimes(1) + // }) + // it('should create a new credential', async () => { + // expect(spy_credentialsRepository_create).toBeCalledTimes(1) + // }) + // it('should add role to user', async () => { + // expect(spy_userRolesService_addRoleToUser).toBeCalledTimes(1) + // }) + // it('should create a new wishlist', async () => { + // expect(spy_wishlistsService_createEmptyNoName).toBeCalledTimes(1) + // }) + // it('should create a new collection', async () => { + // expect(spy_collectionsService_createEmptyNoName).toBeCalledTimes(1) + // }) + }) + describe('Update User Password Exiting Credentials', () => { + const hashedPassword = new Argon2id().hash('111') + tokensService.createHashedToken = vi.fn().mockResolvedValue(hashedPassword) satisfies Awaited> + credentialsRepository.update = vi.fn().mockResolvedValue({ + id: '3e0e9f0f-0a0b-4f0b-8f0b-0a0b4f0b8f0b', + user_id: '3e0e9f0f-0a0b-4f0b-8f0b-0a0b4f0b8f0b', + type: 'PASSWORD', + secret_data: hashedPassword, + }) satisfies Awaited> + credentialsRepository.findPasswordCredentialsByUserId = vi.fn().mockResolvedValue({ + id: '3e0e9f0f-0a0b-4f0b-8f0b-0a0b4f0b8f0b', + user_id: '3e0e9f0f-0a0b-4f0b-8f0b-0a0b4f0b8f0b', + type: 'PASSWORD', + secret_data: hashedPassword, + }) satisfies Awaited> + + const spy_tokensService_createHashToken = vi.spyOn(tokensService, 'createHashedToken') + const spy_credentialsRepository_findPasswordCredentialsByUserId = vi.spyOn(credentialsRepository, 'findPasswordCredentialsByUserId') + const spy_credentialsRepository_update = vi.spyOn(credentialsRepository, 'update') + + it('should resolve', async () => { + await expect(service.updatePassword('3e0e9f0f-0a0b-4f0b-8f0b-0a0b4f0b8f0b', '111')).resolves.toBeUndefined() }) - it('should create a new wishlist', async () => { - expect(spy_wishlistsService_createEmptyNoName).toBeCalledTimes(1) + console.log(spy_tokensService_createHashToken.mock.calls) + it('should generate a hashed token', async () => { + expect(spy_tokensService_createHashToken).toBeCalledTimes(1) }) - it('should create a new collection', async () => { - expect(spy_collectionsService_createEmptyNoName).toBeCalledTimes(1) + console.log(spy_credentialsRepository_findPasswordCredentialsByUserId.mock.calls) + it('should call find password credentials by user id', async () => { + expect(spy_credentialsRepository_findPasswordCredentialsByUserId).toBeCalledTimes(1) }) - }) -}); + console.log(spy_credentialsRepository_update.mock.calls) + it('should update the credential when user has credential', async () => { + expect(spy_credentialsRepository_update).toBeCalledTimes(1) + }) + }) + describe('Update User Password No Existing Credentials', () => { + const hashedPassword = new Argon2id().hash('111') + tokensService.createHashedToken = vi.fn().mockResolvedValue(hashedPassword) satisfies Awaited> + credentialsRepository.findPasswordCredentialsByUserId = vi.fn().mockResolvedValue(null) satisfies Awaited< + ReturnType + > + credentialsRepository.create = vi.fn().mockResolvedValue({ + id: '3e0e9f0f-0a0b-4f0b-8f0b-0a0b4f0b8f0b', + user_id: '3e0e9f0f-0a0b-4f0b-8f0b-0a0b4f0b8f0b', + type: 'PASSWORD', + secret_data: hashedPassword, + }) satisfies Awaited> + + const spy_tokensService_createHashToken = vi.spyOn(tokensService, 'createHashedToken') + const spy_credentialsRepository_create = vi.spyOn(credentialsRepository, 'create') + const spy_credentialsRepository_findPasswordCredentialsByUserId = vi.spyOn(credentialsRepository, 'findPasswordCredentialsByUserId') + + it('should resolve with no current credential for user', async () => { + await expect(service.updatePassword('3e0e9f0f-0a0b-4f0b-8f0b-0a0b4f0b8f0b', '111')).resolves.not.toThrow() + }) + it('should generate a hashed token', async () => { + expect(spy_tokensService_createHashToken).toBeCalledTimes(1) + }) + it('should call find password credentials by user id', async () => { + expect(spy_credentialsRepository_findPasswordCredentialsByUserId).toBeCalledTimes(1) + }) + it('should create a new credential when user has no credential', async () => { + expect(spy_credentialsRepository_create).toHaveBeenCalledTimes(1) + }) + }) +}) diff --git a/src/routes/(app)/(protected)/collections/[cuid]/+page.server.ts b/src/routes/(app)/(protected)/collections/[cuid]/+page.server.ts index c394fa6..488fbb1 100644 --- a/src/routes/(app)/(protected)/collections/[cuid]/+page.server.ts +++ b/src/routes/(app)/(protected)/collections/[cuid]/+page.server.ts @@ -1,13 +1,12 @@ import { notSignedInMessage } from '$lib/flashMessages.js' +import { collection_items, collections, gamesTable } from '$lib/server/api/databases/tables' import { db } from '$lib/server/api/packages/drizzle' -import { userNotAuthenticated } from '$lib/server/auth-utils' import { modifyListGameSchema } from '$lib/validations/zod-schemas' -import { type Actions, error, fail } from '@sveltejs/kit' +import { type Actions, error } from '@sveltejs/kit' import { and, eq } from 'drizzle-orm' import { redirect } from 'sveltekit-flash-message/server' import { zod } from 'sveltekit-superforms/adapters' import { superValidate } from 'sveltekit-superforms/server' -import { collection_items, collections, gamesTable } from '../../../../../lib/server/api/databases/tables' export async function load(event) { const { params, locals } = event diff --git a/src/routes/(app)/(protected)/collections/[cuid]/+page.svelte b/src/routes/(app)/(protected)/collections/[cuid]/+page.svelte index b840239..450233c 100644 --- a/src/routes/(app)/(protected)/collections/[cuid]/+page.svelte +++ b/src/routes/(app)/(protected)/collections/[cuid]/+page.svelte @@ -3,10 +3,10 @@ import Game from '$components/Game.svelte' import type { UICollection } from '$lib/types' -export let data +const { data } = $props() +const { items = [] } = data console.log(`Page data: ${JSON.stringify(data)}`) let collection: UICollection = data?.collection ?? {} -let items = data?.items || [] console.log('items', items) // async function handleNextPageEvent(event: CustomEvent) { diff --git a/src/routes/(app)/(protected)/settings/security/change/password/+page.svelte b/src/routes/(app)/(protected)/settings/security/change/password/+page.svelte index fbc8215..e2f8c0f 100644 --- a/src/routes/(app)/(protected)/settings/security/change/password/+page.svelte +++ b/src/routes/(app)/(protected)/settings/security/change/password/+page.svelte @@ -53,7 +53,7 @@ const { form: formData, enhance } = form aria-label={`${hiddenCurrentPassword ? 'Show' : 'Hide'} Current Password}`} onPressedChange={() => (hiddenCurrentPassword = !hiddenCurrentPassword)} > - {#if hiddenCurrentPassword}{:else}{/if} + {#if hiddenCurrentPassword}{:else}{/if} @@ -73,7 +73,7 @@ const { form: formData, enhance } = form aria-label={`${hiddenPassword ? 'Show' : 'Hide'} Password}`} onPressedChange={() => (hiddenPassword = !hiddenPassword)} > - {#if hiddenPassword}{:else}{/if} + {#if hiddenPassword}{:else}{/if} @@ -93,7 +93,7 @@ const { form: formData, enhance } = form aria-label={`${hiddenConfirmPassword ? 'Show' : 'Hide'} Confirm Password}`} onPressedChange={() => (hiddenConfirmPassword = !hiddenConfirmPassword)} > - {#if hiddenConfirmPassword}{:else}{/if} + {#if hiddenConfirmPassword}{:else}{/if} diff --git a/src/routes/(app)/(protected)/settings/security/mfa/totp/+page.server.ts b/src/routes/(app)/(protected)/settings/security/mfa/totp/+page.server.ts index 4d6577a..1a45df9 100644 --- a/src/routes/(app)/(protected)/settings/security/mfa/totp/+page.server.ts +++ b/src/routes/(app)/(protected)/settings/security/mfa/totp/+page.server.ts @@ -102,7 +102,7 @@ export const actions: Actions = { const { error: verifyPasswordError } = await locals.api.me.verify.password .$post({ - json: { password: addTwoFactorForm.data.current_password }, + json: { password: addTwoFactorForm.data.password }, }) .then(locals.parseApiResponse) @@ -144,7 +144,7 @@ export const actions: Actions = { } const { error: verifyPasswordError } = await locals.api.me.verify.password .$post({ - json: { password: removeTwoFactorForm.data.current_password }, + json: { password: removeTwoFactorForm.data.password }, }) .then(locals.parseApiResponse) diff --git a/src/routes/(app)/(protected)/settings/security/mfa/totp/+page.svelte b/src/routes/(app)/(protected)/settings/security/mfa/totp/+page.svelte index b52ba0b..47672d4 100644 --- a/src/routes/(app)/(protected)/settings/security/mfa/totp/+page.svelte +++ b/src/routes/(app)/(protected)/settings/security/mfa/totp/+page.svelte @@ -42,7 +42,7 @@ const { form: removeTwoFactorFormData, enhance: removeTwoFactorEnhance } = remov Current Password - + Please enter your current password. @@ -64,7 +64,7 @@ const { form: removeTwoFactorFormData, enhance: removeTwoFactorEnhance } = remov Enter Password - + Please enter your current password. diff --git a/src/routes/(app)/(protected)/settings/security/mfa/totp/schemas.ts b/src/routes/(app)/(protected)/settings/security/mfa/totp/schemas.ts index fd14c28..6e05a49 100644 --- a/src/routes/(app)/(protected)/settings/security/mfa/totp/schemas.ts +++ b/src/routes/(app)/(protected)/settings/security/mfa/totp/schemas.ts @@ -1,14 +1,14 @@ import { z } from 'zod' export const addTwoFactorSchema = z.object({ - current_password: z.string({ required_error: 'Current Password is required' }), + password: z.string({ required_error: 'Current Password is required' }), two_factor_code: z.string({ required_error: 'Two Factor Code is required' }).trim(), }) export type AddTwoFactorSchema = typeof addTwoFactorSchema export const removeTwoFactorSchema = addTwoFactorSchema.pick({ - current_password: true, + password: true, }) export type RemoveTwoFactorSchema = typeof removeTwoFactorSchema diff --git a/src/routes/(app)/(protected)/wishlists/+page.svelte b/src/routes/(app)/(protected)/wishlists/+page.svelte index a65577f..ace0846 100644 --- a/src/routes/(app)/(protected)/wishlists/+page.svelte +++ b/src/routes/(app)/(protected)/wishlists/+page.svelte @@ -1,26 +1,28 @@ Your Wishlists | Bored Game -

Your wishlistsTable

+
+

Your wishlistsTable

-
-
- {#if wishlists.length === 0} -

You have no wishlistsTable

- {:else} - {#each wishlists as wishlist} -
-

{wishlist.name}

-

Created at: {new Date(wishlist.created_at).toLocaleString()}

-
- {/each} - {/if} +
+
+ {#if wishlists.length === 0} +

You have no wishlistsTable

+ {:else} + {#each wishlists as wishlist} +
+

{wishlist.name}

+

Created at: {new Date(wishlist.created_at).toLocaleString()}

+
+ {/each} + {/if} +
diff --git a/src/routes/(app)/(protected)/wishlists/[cuid]/+page.svelte b/src/routes/(app)/(protected)/wishlists/[cuid]/+page.svelte index 4eb0cca..784cbd7 100644 --- a/src/routes/(app)/(protected)/wishlists/[cuid]/+page.svelte +++ b/src/routes/(app)/(protected)/wishlists/[cuid]/+page.svelte @@ -1,35 +1,44 @@ {`Your Wishlist | Bored Game`} -

Your wishlist

+
+

Your wishlist

-
- {#if items.length > 0} - {#each items as item (item.id)} - - {/each} - {:else} -

Sorry no gamesTable found!

- {/if} +
+ {#if items.length > 0} + {#each items as item (item.id)} + + {/each} + {:else} +

Sorry no games found!

+ {/if} +
diff --git a/vite.config.ts b/vite.config.ts index 9ccc126..c484cfd 100644 --- a/vite.config.ts +++ b/vite.config.ts @@ -16,7 +16,8 @@ export default defineConfig({ sveltekit() ], test: { - include: ['src/**/*.{test,spec}.{js,ts}'] + include: ['src/**/*.{test,spec}.{js,ts}'], + mockReset: true, }, css: { devSourcemap: true,