diff --git a/Caddyfile b/Caddyfile new file mode 100644 index 0000000..e9a1ab9 --- /dev/null +++ b/Caddyfile @@ -0,0 +1,3 @@ +boredgame.localhost { + reverse_proxy / localhost:4173 +} \ No newline at end of file diff --git a/docker-compose.yaml b/docker-compose.yaml index 1d1d5ac..7cc5327 100644 --- a/docker-compose.yaml +++ b/docker-compose.yaml @@ -15,6 +15,20 @@ 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 volumes: postgres_data: redis_data: + # caddy_data: + # caddy_config: \ No newline at end of file diff --git a/package.json b/package.json index 3b14949..1d103b0 100644 --- a/package.json +++ b/package.json @@ -22,11 +22,13 @@ "site:update": "pnpm update -i -L", "test:unit": "vitest" }, + "engines": { + "node": "22.x" + }, "devDependencies": { "@melt-ui/pp": "^0.3.2", "@melt-ui/svelte": "^0.83.0", "@playwright/test": "^1.45.3", - "@resvg/resvg-js": "^2.6.2", "@sveltejs/adapter-auto": "^3.2.2", "@sveltejs/enhanced-img": "^0.3.1", "@sveltejs/kit": "^2.5.18", @@ -46,7 +48,6 @@ "lucia": "3.2.0", "lucide-svelte": "^0.408.0", "nodemailer": "^6.9.14", - "oslo": "^1.2.1", "postcss": "^8.4.40", "postcss-import": "^16.1.0", "postcss-load-config": "^5.1.0", @@ -85,6 +86,7 @@ "@lukeed/uuid": "^2.0.1", "@neondatabase/serverless": "^0.9.4", "@paralleldrive/cuid2": "^2.2.2", + "@sveltejs/adapter-node": "^5.2.0", "@sveltejs/adapter-vercel": "^5.4.1", "@types/feather-icons": "^4.29.4", "@vercel/og": "^0.5.20", @@ -110,12 +112,14 @@ "just-kebab-case": "^4.2.0", "loader": "^2.1.1", "open-props": "^1.7.5", + "oslo": "^1.2.1", "pg": "^8.12.0", "postgres": "^3.4.4", "qrcode": "^1.5.3", "radix-svelte": "^0.9.0", "rate-limit-redis": "^4.2.0", "reflect-metadata": "^0.2.2", + "@resvg/resvg-js": "^2.6.2", "svelte-french-toast": "^1.2.0", "svelte-lazy-loader": "^1.0.0", "tailwind-merge": "^2.4.0", diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml index 632134c..4b9fcca 100644 --- a/pnpm-lock.yaml +++ b/pnpm-lock.yaml @@ -35,6 +35,12 @@ importers: '@paralleldrive/cuid2': specifier: ^2.2.2 version: 2.2.2 + '@resvg/resvg-js': + specifier: ^2.6.2 + version: 2.6.2 + '@sveltejs/adapter-node': + specifier: ^5.2.0 + version: 5.2.0(@sveltejs/kit@2.5.18(@sveltejs/vite-plugin-svelte@3.1.1(svelte@5.0.0-next.175)(vite@5.3.5(@types/node@20.14.13)(sass@1.77.8)))(svelte@5.0.0-next.175)(vite@5.3.5(@types/node@20.14.13)(sass@1.77.8))) '@sveltejs/adapter-vercel': specifier: ^5.4.1 version: 5.4.1(@sveltejs/kit@2.5.18(@sveltejs/vite-plugin-svelte@3.1.1(svelte@5.0.0-next.175)(vite@5.3.5(@types/node@20.14.13)(sass@1.77.8)))(svelte@5.0.0-next.175)(vite@5.3.5(@types/node@20.14.13)(sass@1.77.8))) @@ -110,6 +116,9 @@ importers: open-props: specifier: ^1.7.5 version: 1.7.5 + oslo: + specifier: ^1.2.1 + version: 1.2.1 pg: specifier: ^8.12.0 version: 8.12.0 @@ -156,9 +165,6 @@ importers: '@playwright/test': specifier: ^1.45.3 version: 1.45.3 - '@resvg/resvg-js': - specifier: ^2.6.2 - version: 2.6.2 '@sveltejs/adapter-auto': specifier: ^3.2.2 version: 3.2.2(@sveltejs/kit@2.5.18(@sveltejs/vite-plugin-svelte@3.1.1(svelte@5.0.0-next.175)(vite@5.3.5(@types/node@20.14.13)(sass@1.77.8)))(svelte@5.0.0-next.175)(vite@5.3.5(@types/node@20.14.13)(sass@1.77.8))) @@ -216,9 +222,6 @@ importers: nodemailer: specifier: ^6.9.14 version: 6.9.14 - oslo: - specifier: ^1.2.1 - version: 1.2.1 postcss: specifier: ^8.4.40 version: 8.4.40 @@ -1717,6 +1720,33 @@ packages: resolution: {integrity: sha512-iDkBM6Ivex8nULtBu8cX670/lfsGxq8U1cuqE+qS9xFpPQP1enPdVm/33Kq3+B+bAldA+AHNZnCgpmlHo/fZrQ==} engines: {node: '>= 10'} + '@rollup/plugin-commonjs@26.0.1': + resolution: {integrity: sha512-UnsKoZK6/aGIH6AdkptXhNvhaqftcjq3zZdT+LY5Ftms6JR06nADcDsYp5hTU9E2lbJUEOhdlY5J4DNTneM+jQ==} + engines: {node: '>=16.0.0 || 14 >= 14.17'} + peerDependencies: + rollup: ^2.68.0||^3.0.0||^4.0.0 + peerDependenciesMeta: + rollup: + optional: true + + '@rollup/plugin-json@6.1.0': + resolution: {integrity: sha512-EGI2te5ENk1coGeADSIwZ7G2Q8CJS2sF120T7jLw4xFw9n7wIOXHo+kIYRAoVpJAN+kmqZSoO3Fp4JtoNF4ReA==} + engines: {node: '>=14.0.0'} + peerDependencies: + rollup: ^1.20.0||^2.0.0||^3.0.0||^4.0.0 + peerDependenciesMeta: + rollup: + optional: true + + '@rollup/plugin-node-resolve@15.2.3': + resolution: {integrity: sha512-j/lym8nf5E21LwBT4Df1VD6hRO2L2iwUeUmP7litikRsVp1H6NWx20NEp0Y7su+7XGc476GnXXc4kFeZNGmaSQ==} + engines: {node: '>=14.0.0'} + peerDependencies: + rollup: ^2.78.0||^3.0.0||^4.0.0 + peerDependenciesMeta: + rollup: + optional: true + '@rollup/pluginutils@4.2.1': resolution: {integrity: sha512-iKnFXr7NkdZAIHiIWE+BX5ULi/ucVFYWD6TbAV+rZctiRTY2PL6tsIKhoIOaoskiWAkgu+VsbXgUVDNLHf+InQ==} engines: {node: '>= 8.0.0'} @@ -1918,6 +1948,11 @@ packages: peerDependencies: '@sveltejs/kit': ^2.0.0 + '@sveltejs/adapter-node@5.2.0': + resolution: {integrity: sha512-HVZoei2078XSyPmvdTHE03VXDUD0ytTvMuMHMQP0j6zX4nPDpCcKrgvU7baEblMeCCMdM/shQvstFxOJPQKlUQ==} + peerDependencies: + '@sveltejs/kit': ^2.4.0 + '@sveltejs/adapter-vercel@5.4.1': resolution: {integrity: sha512-JLcD1OgMnu9lQ8EssxVGxv7w0waWuyVzItTT1eqIH98Krufd9qfr1uC9zgo82z3dJ9v1AfPEbvIX5tonceg7XQ==} peerDependencies: @@ -1992,6 +2027,9 @@ packages: '@types/pug@2.0.10': resolution: {integrity: sha512-Sk/uYFOBAB7mb74XcpizmH0KOR2Pv3D2Hmrh1Dmy5BmK3MpdSa5kqZcg6EKBdklU0bFXX9gCfzvpnyUehrPIuA==} + '@types/resolve@1.20.2': + resolution: {integrity: sha512-60BCwRFOZCQhDncwQdxxeOEEkbc5dIMccYLwbxsS4TUNeVECQ/pBJ0j09mrHOl/JJvpRPGwO9SvE4nR2Nb/a4Q==} + '@types/validator@13.12.0': resolution: {integrity: sha512-nH45Lk7oPIJ1RVOF6JgFI6Dy0QpHEzq4QecZhvguxYPDwT8c93prCMqAtiIttm39voZ+DDR+qkNnMpJmMBRqag==} @@ -2264,6 +2302,10 @@ packages: buffer-from@1.1.2: resolution: {integrity: sha512-E+XQCRwSbaaiChtv6k6Dwgc+bx+Bs6vuKJHHl5kox/BaKbhiXzqQOwK4cO22yElGp2OCmjwVhT3HmxgyPGnJfQ==} + builtin-modules@3.3.0: + resolution: {integrity: sha512-zhaCDicdLuWN5UbN5IMnFqNMhNfo919sH85y2/ea+5Yg9TsTkeZxpL+JLbp6cgYFS4sRLp3YV4S6yDuqVWHYOw==} + engines: {node: '>=6'} + bullmq@5.11.0: resolution: {integrity: sha512-qVzyWGZqie3VHaYEgRXhId/j8ebfmj6MExEJyUByMsUJA5pVciVle3hKLer5fyMwtQ8lTMP7GwhXV/NZ+HzlRA==} @@ -2369,6 +2411,9 @@ packages: resolution: {integrity: sha512-NOKm8xhkzAjzFx8B2v5OAHT+u5pRQc2UCa2Vq9jYL/31o2wi9mxBA7LIFs3sV5VSC49z6pEhfbMULvShKj26WA==} engines: {node: '>= 6'} + commondir@1.0.1: + resolution: {integrity: sha512-W9pAhw0ja1Edb5GVdIF1mjZw/ASI0AlShXM83UUGe2DVr5TdAPEA1OA8m/g8zWp9x6On7gqufY+FatDbC3MDQg==} + concat-map@0.0.1: resolution: {integrity: sha512-/Srv4dswyQNBfohGpz9o6Yb3Gz3SrUDqBH5rTuhGR7ahtlbYKnVxw2bCFMRljaA7EXHaXZ8wsHdodFvbkhKmqg==} @@ -3094,6 +3139,10 @@ packages: resolution: {integrity: sha512-ZMERYes6pDydyuGidse7OsHxtbI7WVeUEozgR/g7rd0xUimYNlvZRE/K2MgZTjWy725IfelLeVcEM97mmtRGXw==} engines: {node: '>=8'} + is-builtin-module@3.2.1: + resolution: {integrity: sha512-BSLE3HnV2syZ0FK0iMA/yUGplUeMmNz4AW5fnTunbCIqZi4vG3WjJT9FHMy5D69xmAYBHXQhJdALdpwVxV501A==} + engines: {node: '>=6'} + is-core-module@2.13.1: resolution: {integrity: sha512-hHrIjvZsftOsvKSn2TRYl63zvxsgE0K+0mYMoH6gD4omR5IWB2KynivBQczo3+wF1cCkjzvptnI9Q0sPU66ilw==} @@ -3109,6 +3158,9 @@ packages: resolution: {integrity: sha512-xelSayHH36ZgE7ZWhli7pW34hNbNl8Ojv5KVmkJD4hBdD3th8Tfk9vYasLM+mXWOZhFkgZfxhLSnrwRr4elSSg==} engines: {node: '>=0.10.0'} + is-module@1.0.0: + resolution: {integrity: sha512-51ypPSPCoTEIN9dy5Oy+h4pShgJmPCygKfyRCISBI+JoWT/2oJvK8QPxmwv7b/p239jXrm9M1mlQbyKJ5A152g==} + is-number@7.0.0: resolution: {integrity: sha512-41Cifkg6e8TylSpdtTpeLVMqvSBEVzTttHvERD741+pnZ8ANv0004MRL43QKPDlK9cGvNp6NZWZUBlbGXYxxng==} engines: {node: '>=0.12.0'} @@ -3117,6 +3169,9 @@ packages: resolution: {integrity: sha512-Fd4gABb+ycGAmKou8eMftCupSir5lRxqf4aD/vd0cD2qc4HL07OjCeuHMr8Ro4CoMaeCKDB0/ECBOVWjTwUvPQ==} engines: {node: '>=8'} + is-reference@1.2.1: + resolution: {integrity: sha512-U82MsXXiFIrjCK4otLT+o2NA2Cd2g5MLoOVXUZjIOhLurrRxpEXzI8O0KZHr3IjLvlAH1kTPYSuqer5T9ZVBKQ==} + is-reference@3.0.2: resolution: {integrity: sha512-v3rht/LgVcsdZa3O2Nqs+NMowLOxeOm7Ay9+/ARQ2F+qEoANRcqrjAZKGN0v8ymUetZGgkp26LTnGT7H0Qo9Pg==} @@ -5900,6 +5955,34 @@ snapshots: '@resvg/resvg-wasm@2.6.0': {} + '@rollup/plugin-commonjs@26.0.1(rollup@4.18.1)': + dependencies: + '@rollup/pluginutils': 5.1.0(rollup@4.18.1) + commondir: 1.0.1 + estree-walker: 2.0.2 + glob: 10.4.1 + is-reference: 1.2.1 + magic-string: 0.30.10 + optionalDependencies: + rollup: 4.18.1 + + '@rollup/plugin-json@6.1.0(rollup@4.18.1)': + dependencies: + '@rollup/pluginutils': 5.1.0(rollup@4.18.1) + optionalDependencies: + rollup: 4.18.1 + + '@rollup/plugin-node-resolve@15.2.3(rollup@4.18.1)': + dependencies: + '@rollup/pluginutils': 5.1.0(rollup@4.18.1) + '@types/resolve': 1.20.2 + deepmerge: 4.3.1 + is-builtin-module: 3.2.1 + is-module: 1.0.0 + resolve: 1.22.8 + optionalDependencies: + rollup: 4.18.1 + '@rollup/pluginutils@4.2.1': dependencies: estree-walker: 2.0.2 @@ -6038,6 +6121,14 @@ snapshots: '@sveltejs/kit': 2.5.18(@sveltejs/vite-plugin-svelte@3.1.1(svelte@5.0.0-next.175)(vite@5.3.5(@types/node@20.14.13)(sass@1.77.8)))(svelte@5.0.0-next.175)(vite@5.3.5(@types/node@20.14.13)(sass@1.77.8)) import-meta-resolve: 4.1.0 + '@sveltejs/adapter-node@5.2.0(@sveltejs/kit@2.5.18(@sveltejs/vite-plugin-svelte@3.1.1(svelte@5.0.0-next.175)(vite@5.3.5(@types/node@20.14.13)(sass@1.77.8)))(svelte@5.0.0-next.175)(vite@5.3.5(@types/node@20.14.13)(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.18(@sveltejs/vite-plugin-svelte@3.1.1(svelte@5.0.0-next.175)(vite@5.3.5(@types/node@20.14.13)(sass@1.77.8)))(svelte@5.0.0-next.175)(vite@5.3.5(@types/node@20.14.13)(sass@1.77.8)) + rollup: 4.18.1 + '@sveltejs/adapter-vercel@5.4.1(@sveltejs/kit@2.5.18(@sveltejs/vite-plugin-svelte@3.1.1(svelte@5.0.0-next.175)(vite@5.3.5(@types/node@20.14.13)(sass@1.77.8)))(svelte@5.0.0-next.175)(vite@5.3.5(@types/node@20.14.13)(sass@1.77.8)))': dependencies: '@sveltejs/kit': 2.5.18(@sveltejs/vite-plugin-svelte@3.1.1(svelte@5.0.0-next.175)(vite@5.3.5(@types/node@20.14.13)(sass@1.77.8)))(svelte@5.0.0-next.175)(vite@5.3.5(@types/node@20.14.13)(sass@1.77.8)) @@ -6136,6 +6227,8 @@ snapshots: '@types/pug@2.0.10': {} + '@types/resolve@1.20.2': {} + '@types/validator@13.12.0': optional: true @@ -6473,6 +6566,8 @@ snapshots: buffer-from@1.1.2: {} + builtin-modules@3.3.0: {} + bullmq@5.11.0: dependencies: cron-parser: 4.9.0 @@ -6591,6 +6686,8 @@ snapshots: commander@4.1.1: {} + commondir@1.0.1: {} + concat-map@0.0.1: {} confbox@0.1.7: {} @@ -7355,6 +7452,10 @@ snapshots: dependencies: binary-extensions: 2.3.0 + is-builtin-module@3.2.1: + dependencies: + builtin-modules: 3.3.0 + is-core-module@2.13.1: dependencies: hasown: 2.0.2 @@ -7367,10 +7468,16 @@ snapshots: dependencies: is-extglob: 2.1.1 + is-module@1.0.0: {} + is-number@7.0.0: {} is-path-inside@3.0.3: {} + is-reference@1.2.1: + dependencies: + '@types/estree': 1.0.5 + is-reference@3.0.2: dependencies: '@types/estree': 1.0.5 @@ -8327,7 +8434,6 @@ snapshots: '@rollup/rollup-win32-ia32-msvc': 4.18.1 '@rollup/rollup-win32-x64-msvc': 4.18.1 fsevents: 2.3.3 - optional: true run-parallel@1.2.0: dependencies: diff --git a/src/hooks.server.ts b/src/hooks.server.ts index f2b081b..f1e2dd8 100644 --- a/src/hooks.server.ts +++ b/src/hooks.server.ts @@ -1,4 +1,5 @@ // import * as Sentry from '@sentry/sveltekit'; +import 'reflect-metadata' import { hc } from 'hono/client'; import { sequence } from '@sveltejs/kit/hooks'; import { redirect, type Handle } from '@sveltejs/kit'; diff --git a/src/lib/server/api/controllers/login.controller.ts b/src/lib/server/api/controllers/login.controller.ts index 15e4b37..996e98e 100644 --- a/src/lib/server/api/controllers/login.controller.ts +++ b/src/lib/server/api/controllers/login.controller.ts @@ -1,3 +1,4 @@ +import 'reflect-metadata'; import { Hono } from 'hono'; import { zValidator } from '@hono/zod-validator'; import { inject, injectable } from 'tsyringe'; @@ -5,14 +6,14 @@ import type { HonoTypes } from '../types'; import { limiter } from '../middleware/rate-limiter.middleware'; import type { Controller } from '../interfaces/controller.interface'; import { signInEmailDto } from '$lib/dtos/signin-email.dto'; -import type { LoginRequestsService } from '../services/loginrequest.service'; +import { LoginRequestsService } from '../services/loginrequest.service'; @injectable() export class LoginController implements Controller { controller = new Hono(); constructor( - @inject('LoginRequestsService') private readonly loginRequestsService: LoginRequestsService + @inject(LoginRequestsService) private readonly loginRequestsService: LoginRequestsService ) { } routes() { diff --git a/src/lib/server/api/controllers/user.controller.ts b/src/lib/server/api/controllers/user.controller.ts index dc23cde..4ac575b 100644 --- a/src/lib/server/api/controllers/user.controller.ts +++ b/src/lib/server/api/controllers/user.controller.ts @@ -1,9 +1,7 @@ +import 'reflect-metadata'; import { Hono } from 'hono'; -import { zValidator } from '@hono/zod-validator'; -import { inject, injectable } from 'tsyringe'; +import { injectable } from 'tsyringe'; import { requireAuth } from "../middleware/auth.middleware"; -import { registerEmailPasswordDto } from '$lib/dtos/register-emailpassword.dto'; -import { limiter } from '../middleware/rate-limiter.middleware'; import type { HonoTypes } from '../types'; import type { Controller } from '../interfaces/controller.interface'; @@ -12,7 +10,6 @@ export class UserController implements Controller { controller = new Hono(); constructor( - @inject('LoginRequestsService') private readonly loginRequestsService: LoginRequestsService ) { } routes() { @@ -24,11 +21,6 @@ export class UserController implements Controller { .get('/user', requireAuth, async (c) => { const user = c.var.user; return c.json({ user }); - }) - .post('/login/request', zValidator('json', registerEmailPasswordDto), limiter({ limit: 10, minutes: 60 }), async (c) => { - const { email } = c.req.valid('json'); - await this.loginRequestsService.create({ email }); - return c.json({ message: 'Verification email sent' }); }); } } diff --git a/src/lib/server/api/index.ts b/src/lib/server/api/index.ts index 3e53e76..2a9ed1b 100644 --- a/src/lib/server/api/index.ts +++ b/src/lib/server/api/index.ts @@ -1,10 +1,13 @@ +import 'reflect-metadata' import { Hono } from 'hono'; import { hc } from 'hono/client'; import { cors } from 'hono/cors'; import { logger } from 'hono/logger'; import { validateAuthSession, verifyOrigin } from './middleware/auth.middleware'; -import users from './controllers/user.controller'; import { config } from './common/config'; +import { container } from 'tsyringe'; +import { IamController } from './controllers/iam.controller'; +import { LoginController } from './controllers/login.controller'; /* ----------------------------------- Api ---------------------------------- */ const app = new Hono().basePath('/api'); @@ -31,7 +34,8 @@ app.use( /* --------------------------------- Routes --------------------------------- */ const routes = app - .route('/user', users) + .route('/user', container.resolve(IamController).routes()) + .route('/login', container.resolve(LoginController).routes()) .get('/', (c) => c.json({ message: 'Server is healthy' })); /* -------------------------------------------------------------------------- */ diff --git a/src/lib/server/api/infrastructure/database/tables/collections.ts b/src/lib/server/api/infrastructure/database/tables/collections.ts index 1a56443..58b8297 100644 --- a/src/lib/server/api/infrastructure/database/tables/collections.ts +++ b/src/lib/server/api/infrastructure/database/tables/collections.ts @@ -1,7 +1,7 @@ import { pgTable, text, timestamp, uuid } from 'drizzle-orm/pg-core'; import { createId as cuid2 } from '@paralleldrive/cuid2'; import { type InferSelectModel, relations } from 'drizzle-orm'; -import usersTable from './users.table'; +import { usersTable } from './users.table'; import { timestamps } from '../utils'; const collections = pgTable('collections', { diff --git a/src/lib/server/api/infrastructure/database/tables/index.ts b/src/lib/server/api/infrastructure/database/tables/index.ts index e7bf9ff..9b59c1e 100644 --- a/src/lib/server/api/infrastructure/database/tables/index.ts +++ b/src/lib/server/api/infrastructure/database/tables/index.ts @@ -1,4 +1,4 @@ -export { default as usersTable, userRelations as user_relations, type Users } from './users.table'; +export { usersTable, userRelations as user_relations, type Users } from './users.table'; export { default as recoveryCodes, type RecoveryCodes } from './recoveryCodes'; export { default as password_reset_tokens, diff --git a/src/lib/server/api/infrastructure/database/tables/passwordResetTokens.ts b/src/lib/server/api/infrastructure/database/tables/passwordResetTokens.ts index a849bc1..143ee28 100644 --- a/src/lib/server/api/infrastructure/database/tables/passwordResetTokens.ts +++ b/src/lib/server/api/infrastructure/database/tables/passwordResetTokens.ts @@ -1,7 +1,7 @@ import { pgTable, text, timestamp, uuid } from 'drizzle-orm/pg-core'; import { createId as cuid2 } from '@paralleldrive/cuid2'; import { type InferSelectModel, relations } from 'drizzle-orm'; -import usersTable from './users.table'; +import { usersTable } from './users.table'; import { timestamps } from '../utils'; const password_reset_tokens = pgTable('password_reset_tokens', { diff --git a/src/lib/server/api/infrastructure/database/tables/recoveryCodes.ts b/src/lib/server/api/infrastructure/database/tables/recoveryCodes.ts index b63c167..9a7ee8e 100644 --- a/src/lib/server/api/infrastructure/database/tables/recoveryCodes.ts +++ b/src/lib/server/api/infrastructure/database/tables/recoveryCodes.ts @@ -1,6 +1,6 @@ import { boolean, pgTable, text, uuid } from 'drizzle-orm/pg-core'; import type { InferSelectModel } from 'drizzle-orm'; -import usersTable from './users.table'; +import { usersTable } from './users.table'; import { timestamps } from '../utils'; const recovery_codes = pgTable('recovery_codes', { diff --git a/src/lib/server/api/infrastructure/database/tables/sessions.table.ts b/src/lib/server/api/infrastructure/database/tables/sessions.table.ts index 813b2b8..823eb19 100644 --- a/src/lib/server/api/infrastructure/database/tables/sessions.table.ts +++ b/src/lib/server/api/infrastructure/database/tables/sessions.table.ts @@ -1,6 +1,6 @@ import { boolean, pgTable, text, timestamp, uuid } from 'drizzle-orm/pg-core'; import { relations, type InferSelectModel } from 'drizzle-orm'; -import usersTable from './users.table'; +import { usersTable } from './users.table'; const sessionsTable = pgTable('sessions', { id: text('id').primaryKey(), diff --git a/src/lib/server/api/infrastructure/database/tables/two-factor.table.ts b/src/lib/server/api/infrastructure/database/tables/two-factor.table.ts index d488c1d..b523a16 100644 --- a/src/lib/server/api/infrastructure/database/tables/two-factor.table.ts +++ b/src/lib/server/api/infrastructure/database/tables/two-factor.table.ts @@ -2,7 +2,7 @@ import { createId as cuid2 } from '@paralleldrive/cuid2'; import { type InferSelectModel, relations } from 'drizzle-orm'; import { boolean, pgTable, text, timestamp, uuid } from 'drizzle-orm/pg-core'; import { timestamps } from '../utils'; -import usersTable from './users.table'; +import { usersTable } from './users.table'; const twoFactorTable = pgTable('two_factor', { id: uuid('id').primaryKey().defaultRandom(), diff --git a/src/lib/server/api/infrastructure/database/tables/userRoles.ts b/src/lib/server/api/infrastructure/database/tables/userRoles.ts index d241788..46489a0 100644 --- a/src/lib/server/api/infrastructure/database/tables/userRoles.ts +++ b/src/lib/server/api/infrastructure/database/tables/userRoles.ts @@ -1,7 +1,7 @@ import { boolean, pgTable, text, uuid } from 'drizzle-orm/pg-core'; import { createId as cuid2 } from '@paralleldrive/cuid2'; import { type InferSelectModel, relations } from 'drizzle-orm'; -import usersTable from './users.table'; +import { usersTable } from './users.table'; import roles from './roles'; import { timestamps } from '../utils'; diff --git a/src/lib/server/api/infrastructure/database/tables/users.table.ts b/src/lib/server/api/infrastructure/database/tables/users.table.ts index e520f2e..0e90b66 100644 --- a/src/lib/server/api/infrastructure/database/tables/users.table.ts +++ b/src/lib/server/api/infrastructure/database/tables/users.table.ts @@ -10,7 +10,6 @@ export const usersTable = pgTable('users', { .unique() .$defaultFn(() => cuid2()), username: text('username').unique(), - hashed_password: text('hashed_password'), email: text('email').unique(), first_name: text('first_name'), last_name: text('last_name'), diff --git a/src/lib/server/api/infrastructure/database/tables/wishlists.ts b/src/lib/server/api/infrastructure/database/tables/wishlists.ts index 673308a..83cd754 100644 --- a/src/lib/server/api/infrastructure/database/tables/wishlists.ts +++ b/src/lib/server/api/infrastructure/database/tables/wishlists.ts @@ -1,7 +1,7 @@ import { pgTable, text, uuid } from 'drizzle-orm/pg-core'; import { createId as cuid2 } from '@paralleldrive/cuid2'; import { type InferSelectModel, relations } from 'drizzle-orm'; -import usersTable from './users.table'; +import { usersTable } from './users.table'; import { timestamps } from '../utils'; const wishlists = pgTable('wishlists', { diff --git a/src/lib/server/api/services/loginrequest.service.ts b/src/lib/server/api/services/loginrequest.service.ts index 852b422..f2138b3 100644 --- a/src/lib/server/api/services/loginrequest.service.ts +++ b/src/lib/server/api/services/loginrequest.service.ts @@ -6,7 +6,6 @@ import { TokensService } from './tokens.service'; import { LuciaProvider } from '../providers/lucia.provider'; import { UsersRepository } from '../repositories/users.repository'; import type { SignInEmailDto } from '../../../dtos/signin-email.dto'; -import type { RegisterEmailDto } from '../../../dtos/register-email.dto'; import { CredentialsRepository } from '../repositories/credentials.repository'; import type { HonoRequest } from 'hono'; @@ -21,17 +20,17 @@ export class LoginRequestsService { @inject(CredentialsRepository) private readonly credentialsRepository: CredentialsRepository, ) { } - async create(data: RegisterEmailDto) { - // generate a token, expiry date, and hash - const { token, expiry, hashedToken } = await this.tokensService.generateTokenWithExpiryAndHash(15, 'm'); - // save the login request to the database - ensuring we save the hashedToken - await this.loginRequestsRepository.create({ email: data.email, hashedToken, expiresAt: expiry }); - // send the login request email - await this.mailerService.sendLoginRequest({ - to: data.email, - props: { token: token } - }); - } + // async create(data: RegisterEmailDto) { + // // generate a token, expiry date, and hash + // const { token, expiry, hashedToken } = await this.tokensService.generateTokenWithExpiryAndHash(15, 'm'); + // // save the login request to the database - ensuring we save the hashedToken + // await this.loginRequestsRepository.create({ email: data.email, hashedToken, expiresAt: expiry }); + // // send the login request email + // await this.mailerService.sendLoginRequest({ + // to: data.email, + // props: { token: token } + // }); + // } async verify(data: SignInEmailDto, req: HonoRequest) { const requestIpAddress = req.header('x-real-ip'); @@ -74,19 +73,19 @@ export class LoginRequestsService { } // Fetch a valid request from the database, verify the token and burn the request if it is valid - private async fetchValidRequest(email: string, token: string) { - return await this.db.transaction(async (trx) => { - // fetch the login request - const loginRequest = await this.loginRequestsRepository.trxHost(trx).findOneByEmail(email) - if (!loginRequest) return null; + // private async fetchValidRequest(email: string, token: string) { + // return await this.db.transaction(async (trx) => { + // // fetch the login request + // const loginRequest = await this.loginRequestsRepository.trxHost(trx).findOneByEmail(email) + // if (!loginRequest) return null; - // check if the token is valid - const isValidRequest = await this.tokensService.verifyHashedToken(loginRequest.hashedToken, token); - if (!isValidRequest) return null + // // check if the token is valid + // const isValidRequest = await this.tokensService.verifyHashedToken(loginRequest.hashedToken, token); + // if (!isValidRequest) return null - // if the token is valid, burn the request - await this.loginRequestsRepository.trxHost(trx).deleteById(loginRequest.id); - return loginRequest - }) - } + // // if the token is valid, burn the request + // await this.loginRequestsRepository.trxHost(trx).deleteById(loginRequest.id); + // return loginRequest + // }) + // } } \ No newline at end of file diff --git a/src/lib/server/api/tests/login-requests.service.test.ts b/src/lib/server/api/tests/login-requests.service.test.ts new file mode 100644 index 0000000..33329e5 --- /dev/null +++ b/src/lib/server/api/tests/login-requests.service.test.ts @@ -0,0 +1,72 @@ +// import 'reflect-metadata'; +// import { LoginRequestsService } from '../services/login-requests.service'; +// import { afterAll, beforeAll, describe, expect, it, vi } from 'vitest'; +// import { TokensService } from '../services/tokens.service'; +// import { MailerService } from '../services/mailer.service'; +// import { UsersRepository } from '../repositories/users.repository'; +// import { DatabaseProvider, LuciaProvider } from '../providers'; +// import { LoginRequestsRepository } from '../repositories/login-requests.repository'; +// import { PgDatabase } from 'drizzle-orm/pg-core'; +// import { container } from 'tsyringe'; + +// describe('LoginRequestService', () => { +// let service: LoginRequestsService; +// let tokensService = vi.mocked(TokensService.prototype) +// let mailerService = vi.mocked(MailerService.prototype); +// let usersRepository = vi.mocked(UsersRepository.prototype); +// let loginRequestsRepository = vi.mocked(LoginRequestsRepository.prototype); +// let luciaProvider = vi.mocked(LuciaProvider); +// let databaseProvider = vi.mocked(PgDatabase); + +// beforeAll(() => { +// service = container +// .register(TokensService, { useValue: tokensService }) +// .register(MailerService, { useValue: mailerService }) +// .register(UsersRepository, { useValue: usersRepository }) +// .register(LoginRequestsRepository, { useValue: loginRequestsRepository }) +// .register(LuciaProvider, { useValue: luciaProvider }) +// .register(DatabaseProvider, { useValue: databaseProvider }) +// .resolve(LoginRequestsService); +// }); + + +// afterAll(() => { +// vi.resetAllMocks() +// }) + +// describe('Create', () => { +// tokensService.generateTokenWithExpiryAndHash = vi.fn().mockResolvedValue({ +// token: "1", +// expiry: new Date(), +// hashedToken: "xyz" +// } satisfies Awaited>) + +// loginRequestsRepository.create = vi.fn().mockResolvedValue({ +// createdAt: new Date(), +// email: 'me@test.com', +// expiresAt: new Date(), +// hashedToken: '111', +// id: '1', +// updatedAt: new Date() +// } satisfies Awaited>) + +// mailerService.sendLoginRequest = vi.fn().mockResolvedValue(null) + +// const spy_mailerService_sendLoginRequest = vi.spyOn(mailerService, 'sendLoginRequest') +// const spy_tokensService_generateTokenWithExpiryAndHash = vi.spyOn(tokensService, 'generateTokenWithExpiryAndHash') +// const spy_loginRequestsRepository_create = vi.spyOn(loginRequestsRepository, 'create') + +// it('should resolve', async () => { +// await expect(service.create({ email: "test" })).resolves.toBeUndefined() +// }) +// it('should generate a token with expiry and hash', async () => { +// expect(spy_tokensService_generateTokenWithExpiryAndHash).toBeCalledTimes(1) +// }) +// it('should send an email with token', async () => { +// expect(spy_mailerService_sendLoginRequest).toHaveBeenCalledTimes(1) +// }) +// it('should create a new login request record', async () => { +// expect(spy_loginRequestsRepository_create).toBeCalledTimes(1) +// }) +// }) +// }); diff --git a/src/routes/(app)/(protected)/admin/users/[id]/+page.server.ts b/src/routes/(app)/(protected)/admin/users/[id]/+page.server.ts index d641278..5d18bf0 100644 --- a/src/routes/(app)/(protected)/admin/users/[id]/+page.server.ts +++ b/src/routes/(app)/(protected)/admin/users/[id]/+page.server.ts @@ -3,7 +3,7 @@ import { redirect } from 'sveltekit-flash-message/server'; import type { PageServerLoad } from './$types'; import { forbiddenMessage, notSignedInMessage } from '$lib/flashMessages'; import db from '../../../../../../db'; -import { roles, userRoles, users } from '$db/schema'; +import { roles, userRoles, usersTable } from '$db/schema'; export const load: PageServerLoad = async (event) => { const { params } = event; @@ -14,10 +14,10 @@ export const load: PageServerLoad = async (event) => { redirect(302, '/login', notSignedInMessage, event); } - const foundUser = await db.query.users.findFirst({ - where: eq(users.cuid, id), + const foundUser = await db.query.usersTable.findFirst({ + where: eq(usersTable.cuid, id), with: { - userRoles: { + user_roles: { with: { role: { columns: { @@ -30,7 +30,7 @@ export const load: PageServerLoad = async (event) => { }, }); - const containsAdminRole = foundUser?.userRoles?.some( + const containsAdminRole = foundUser?.user_roles?.some( (user_role) => user_role?.role?.name === 'admin', ); if (!containsAdminRole) { @@ -38,7 +38,7 @@ export const load: PageServerLoad = async (event) => { redirect(302, '/login', notSignedInMessage, event); } - const currentRoleIds = foundUser?.userRoles?.map((user_role) => user_role?.role.cuid) || []; + const currentRoleIds = foundUser?.user_roles?.map((user_role) => user_role?.role.cuid) || []; let availableRoles: { name: string; cuid: string }[] = []; if (currentRoleIds?.length > 0) { availableRoles = await db.query.roles.findMany({ @@ -65,7 +65,7 @@ export const actions = { redirect(302, '/login', notSignedInMessage, event); } - const userRoles = await db.query.userRoles.findMany({ + const userRolesList = await db.query.userRoles.findMany({ where: eq(userRoles.user_id, user.id), with: { role: { @@ -77,9 +77,9 @@ export const actions = { }, }); - console.log('userRoles', userRoles); + console.log('userRoles', userRolesList); - const containsAdminRole = userRoles.some((user_role) => user_role?.role?.name === 'admin'); + const containsAdminRole = userRolesList.some((user_role) => user_role?.role?.name === 'admin'); console.log('containsAdminRole', containsAdminRole); if (!containsAdminRole) { redirect(302, '/', forbiddenMessage, event); @@ -108,7 +108,7 @@ export const actions = { redirect(302, '/login', notSignedInMessage, event); } - const userRoles = await db.query.userRoles.findMany({ + const userRolesList = await db.query.userRoles.findMany({ where: eq(userRoles.user_id, user.id), with: { role: { @@ -120,7 +120,7 @@ export const actions = { }, }); - const containsAdminRole = userRoles.some((user_role) => user_role?.role?.name === 'admin'); + const containsAdminRole = userRolesList.some((user_role) => user_role?.role?.name === 'admin'); if (!containsAdminRole) { redirect(302, '/', forbiddenMessage, event); } diff --git a/src/routes/(app)/(protected)/profile/+page.server.ts b/src/routes/(app)/(protected)/profile/+page.server.ts index 18ea6ad..8157721 100644 --- a/src/routes/(app)/(protected)/profile/+page.server.ts +++ b/src/routes/(app)/(protected)/profile/+page.server.ts @@ -8,7 +8,7 @@ import { changeEmailSchema, profileSchema } from '$lib/validations/account'; import { notSignedInMessage } from '$lib/flashMessages'; import db from '../../../../db'; import type { PageServerLoad } from './$types'; -import { users, twoFactor } from '$db/schema'; +import { usersTable, twoFactor } from '$db/schema'; import { userNotAuthenticated } from '$lib/server/auth-utils'; export const load: PageServerLoad = async (event) => { @@ -18,8 +18,8 @@ export const load: PageServerLoad = async (event) => { redirect(302, '/login', notSignedInMessage, event); } - const dbUser = await db.query.users.findFirst({ - where: eq(users.id, user!.id!), + const dbUser = await db.query.usersTable.findFirst({ + where: eq(usersTable.id, user!.id!), }); const profileForm = await superValidate(zod(profileSchema), { @@ -72,8 +72,8 @@ export const actions: Actions = { const user = event.locals.user; const newUsername = form.data.username; - const existingUser = await db.query.users.findFirst({ - where: eq(users.username, newUsername), + const existingUser = await db.query.usersTable.findFirst({ + where: eq(usersTable.username, newUsername), }); if (existingUser && existingUser.id !== user.id) { @@ -81,13 +81,13 @@ export const actions: Actions = { } await db - .update(users) + .update(usersTable) .set({ first_name: form.data.firstName, last_name: form.data.lastName, username: form.data.username, }) - .where(eq(users.id, user.id)); + .where(eq(usersTable.id, user.id)); } catch (e) { // @ts-expect-error if (e.message === `AUTH_INVALID_USER_ID`) { @@ -119,17 +119,17 @@ export const actions: Actions = { } const user = event.locals.user; - const existingUser = await db.query.users.findFirst({ - where: eq(users.email, newEmail), + const existingUser = await db.query.usersTable.findFirst({ + where: eq(usersTable.email, newEmail), }); if (existingUser && existingUser.id !== user.id) { return setError(form, 'email', 'That email is already taken'); } - await db.update(users).set({ email: form.data.email }).where(eq(users.id, user.id)); + await db.update(usersTable).set({ email: form.data.email }).where(eq(usersTable.id, user.id)); - if (user.email !== form.data.email) { + // if (user.email !== form.data.email) { // Send email to confirm new email? // auth.update // await locals.prisma.key.update({ @@ -143,7 +143,7 @@ export const actions: Actions = { // auth.updateUserAttributes(user.user_id, { // receiveEmail: false // }); - } + // } return message(form, { type: 'success', message: 'Email updated successfully!' }); }, diff --git a/src/routes/(app)/(protected)/profile/security/password/change/+page.server.ts b/src/routes/(app)/(protected)/profile/security/password/change/+page.server.ts index 8d6ef62..baa9ee0 100644 --- a/src/routes/(app)/(protected)/profile/security/password/change/+page.server.ts +++ b/src/routes/(app)/(protected)/profile/security/password/change/+page.server.ts @@ -8,7 +8,7 @@ import type { PageServerLoad } from '../../../$types'; import db from '../../../../../../../db'; import { changeUserPasswordSchema } from '$lib/validations/account'; import { lucia } from '$lib/server/auth.js'; -import { users } from '$db/schema'; +import { usersTable } from '$db/schema'; import { notSignedInMessage } from '$lib/flashMessages'; import type { Cookie } from 'lucia'; import { userNotAuthenticated } from '$lib/server/auth-utils'; @@ -56,8 +56,8 @@ export const actions: Actions = { return fail(401); } - const dbUser = await db.query.users.findFirst({ - where: eq(users.id, user!.id), + const dbUser = await db.query.usersTable.findFirst({ + where: eq(usersTable.id, user!.id), }); if (!dbUser?.hashed_password) { @@ -87,9 +87,9 @@ export const actions: Actions = { const hashedPassword = await new Argon2id().hash(form.data.password); await lucia.invalidateUserSessions(user.id); await db - .update(users) + .update(usersTable) .set({ hashed_password: hashedPassword }) - .where(eq(users.id, user.id)); + .where(eq(usersTable.id, user.id)); await lucia.createSession(user.id, { country: event.locals.session?.ipCountry ?? 'unknown', }); diff --git a/src/routes/(app)/(protected)/profile/security/two-factor/+page.server.ts b/src/routes/(app)/(protected)/profile/security/two-factor/+page.server.ts index 38bca3d..d119b43 100644 --- a/src/routes/(app)/(protected)/profile/security/two-factor/+page.server.ts +++ b/src/routes/(app)/(protected)/profile/security/two-factor/+page.server.ts @@ -13,7 +13,7 @@ import type { PageServerLoad } from '../../$types'; import { addTwoFactorSchema, removeTwoFactorSchema } from '$lib/validations/account'; import { notSignedInMessage } from '$lib/flashMessages'; import db from '../../../../../../db'; -import { recoveryCodes, twoFactor, users } from '$db/schema'; +import { recoveryCodes, twoFactor, usersTable } from '$db/schema'; import { userNotAuthenticated } from '$lib/server/auth-utils'; import env from '../../../../../../env'; @@ -27,8 +27,8 @@ export const load: PageServerLoad = async (event) => { redirect(302, '/login', notSignedInMessage, event); } - const dbUser = await db.query.users.findFirst({ - where: eq(users.id, user!.id!), + const dbUser = await db.query.usersTable.findFirst({ + where: eq(usersTable.id, user!.id!), }); const twoFactorDetails = await db.query.twoFactor.findFirst({ @@ -111,8 +111,8 @@ export const actions: Actions = { return fail(401); } - const dbUser = await db.query.users.findFirst({ - where: eq(users.id, user!.id!), + const dbUser = await db.query.usersTable.findFirst({ + where: eq(usersTable.id, user!.id!), }); if (!dbUser?.hashed_password) { @@ -190,8 +190,8 @@ export const actions: Actions = { }); } - const dbUser = await db.query.users.findFirst({ - where: eq(users.id, user.id), + const dbUser = await db.query.usersTable.findFirst({ + where: eq(usersTable.id, user.id), }); if (!dbUser?.hashed_password) { diff --git a/src/routes/(app)/(protected)/profile/security/two-factor/recovery-codes/+page.server.ts b/src/routes/(app)/(protected)/profile/security/two-factor/recovery-codes/+page.server.ts index 74a2820..fb8b009 100644 --- a/src/routes/(app)/(protected)/profile/security/two-factor/recovery-codes/+page.server.ts +++ b/src/routes/(app)/(protected)/profile/security/two-factor/recovery-codes/+page.server.ts @@ -5,7 +5,7 @@ import { alphabet, generateRandomString } from 'oslo/crypto'; import { redirect } from 'sveltekit-flash-message/server'; import { notSignedInMessage } from '$lib/flashMessages'; import type { PageServerLoad } from '../../../$types'; -import {recoveryCodes, twoFactor, users} from '$db/schema'; +import {recoveryCodes, twoFactor, usersTable} from '$db/schema'; import { userNotAuthenticated } from '$lib/server/auth-utils'; export const load: PageServerLoad = async (event) => { @@ -15,8 +15,8 @@ export const load: PageServerLoad = async (event) => { redirect(302, '/login', notSignedInMessage, event); } - const dbUser = await db.query.users.findFirst({ - where: eq(users.id, user!.id), + const dbUser = await db.query.usersTable.findFirst({ + where: eq(usersTable.id, user!.id), }); const twoFactorDetails = await db.query.twoFactor.findFirst({ diff --git a/src/routes/(app)/+page.server.ts b/src/routes/(app)/+page.server.ts index be5f150..190bd71 100644 --- a/src/routes/(app)/+page.server.ts +++ b/src/routes/(app)/+page.server.ts @@ -2,7 +2,7 @@ import type { MetaTagsProps } from 'svelte-meta-tags'; import { eq } from 'drizzle-orm'; import type { PageServerLoad } from './$types'; import db from '../../db'; -import { collections, users, wishlists } from '$db/schema'; +import { collections, usersTable, wishlists } from '$db/schema'; import { userFullyAuthenticated } from '$lib/server/auth-utils'; export const load: PageServerLoad = async (event) => { @@ -42,8 +42,8 @@ export const load: PageServerLoad = async (event) => { }); if (userFullyAuthenticated(user, session)) { - const dbUser = await db.query.users.findFirst({ - where: eq(users.id, user!.id!), + const dbUser = await db.query.usersTable.findFirst({ + where: eq(usersTable.id, user!.id!), }); console.log('Sending back user details'); diff --git a/src/routes/(app)/about/+page.ts b/src/routes/(app)/about/+page.ts index 3e13462..763e9db 100644 --- a/src/routes/(app)/about/+page.ts +++ b/src/routes/(app)/about/+page.ts @@ -1,9 +1,9 @@ -import { dev } from '$app/environment'; +// import { dev } from '$app/environment'; -// we don't need any JS on this page, though we'll load -// it in dev so that we get hot module replacement... -export const csr = dev; +// // we don't need any JS on this page, though we'll load +// // it in dev so that we get hot module replacement... +// export const csr = dev; -// since there's no dynamic data here, we can prerender -// it so that it gets served as a static asset in prod -export const prerender = true; +// // since there's no dynamic data here, we can prerender +// // it so that it gets served as a static asset in prod +// export const prerender = true; diff --git a/src/routes/(app)/privacy/+page.server.ts b/src/routes/(app)/privacy/+page.server.ts index c8cacf0..10cfeb3 100644 --- a/src/routes/(app)/privacy/+page.server.ts +++ b/src/routes/(app)/privacy/+page.server.ts @@ -1 +1 @@ -export const prerender = true; \ No newline at end of file +// export const prerender = true; \ No newline at end of file diff --git a/src/routes/(app)/terms/+page.server.ts b/src/routes/(app)/terms/+page.server.ts index 189f71e..4973a60 100644 --- a/src/routes/(app)/terms/+page.server.ts +++ b/src/routes/(app)/terms/+page.server.ts @@ -1 +1 @@ -export const prerender = true; +// export const prerender = true; diff --git a/src/routes/(auth)/login/+page.server.ts b/src/routes/(auth)/login/+page.server.ts index 6d91a2a..5da474b 100644 --- a/src/routes/(auth)/login/+page.server.ts +++ b/src/routes/(auth)/login/+page.server.ts @@ -8,7 +8,7 @@ import { RateLimiter } from 'sveltekit-rate-limiter/server'; import db from '../../../db'; import { lucia } from '$lib/server/auth'; import { signInSchema } from '$lib/validations/auth'; -import { twoFactor, users, type Users } from '$db/schema'; +import { twoFactor, usersTable, type Users } from '$db/schema'; import type { PageServerLoad } from './$types'; import { userFullyAuthenticated, userNotFullyAuthenticated } from '$lib/server/auth-utils'; @@ -57,8 +57,8 @@ export const actions: Actions = { let session; let sessionCookie; - const user: Users | undefined = await db.query.users.findFirst({ - where: or(eq(users.username, form.data.username), eq(users.email, form.data.username)), + const user: Users | undefined = await db.query.usersTable.findFirst({ + where: or(eq(usersTable.username, form.data.username), eq(usersTable.email, form.data.username)), }); if (!user) { diff --git a/src/routes/(auth)/sign-up/+page.server.ts b/src/routes/(auth)/sign-up/+page.server.ts index 1e5d73a..73b05d0 100644 --- a/src/routes/(auth)/sign-up/+page.server.ts +++ b/src/routes/(auth)/sign-up/+page.server.ts @@ -10,7 +10,7 @@ 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, users, wishlists } from '$db/schema'; +import { collections, usersTable, wishlists } from '$db/schema'; import { createId as cuid2 } from '@paralleldrive/cuid2'; import { userFullyAuthenticated, userNotFullyAuthenticated } from '$lib/server/auth-utils'; @@ -76,8 +76,8 @@ export const actions: Actions = { // Adding user to the db console.log('Check if user already exists'); - const existing_user = await db.query.users.findFirst({ - where: eq(users.username, form.data.username), + const existing_user = await db.query.usersTable.findFirst({ + where: eq(usersTable.username, form.data.username), }); if (existing_user) { @@ -89,7 +89,7 @@ export const actions: Actions = { const hashedPassword = await new Argon2id().hash(form.data.password); const user = await db - .insert(users) + .insert(usersTable) .values({ username: form.data.username, hashed_password: hashedPassword, diff --git a/src/routes/(auth)/totp/+page.server.ts b/src/routes/(auth)/totp/+page.server.ts index 5892599..4e6f719 100644 --- a/src/routes/(auth)/totp/+page.server.ts +++ b/src/routes/(auth)/totp/+page.server.ts @@ -10,7 +10,7 @@ import { RateLimiter } from 'sveltekit-rate-limiter/server'; import db from '../../../db'; import { lucia } from '$lib/server/auth'; import { recoveryCodeSchema, totpSchema } from '$lib/validations/auth'; -import { users, twoFactor, recoveryCodes } from '$db/schema'; +import { usersTable, twoFactor, recoveryCodes } from '$db/schema'; import type {PageServerLoad, RequestEvent} from './$types'; import { notSignedInMessage } from '$lib/flashMessages'; import env from '../../../env'; @@ -24,8 +24,8 @@ export const load: PageServerLoad = async (event) => { } if (user && session) { - const dbUser = await db.query.users.findFirst({ - where: eq(users.username, user.username), + const dbUser = await db.query.usersTable.findFirst({ + where: eq(usersTable.username, user.username), }); const twoFactorDetails = await db.query.twoFactor.findFirst({ @@ -262,8 +262,8 @@ async function validateUserData(event: RequestEvent, locals: App.Locals) { throw fail(401); } - const dbUser = await db.query.users.findFirst({ - where: eq(users.username, user.username), + const dbUser = await db.query.usersTable.findFirst({ + where: eq(usersTable.username, user.username), }); if (!dbUser) { diff --git a/src/routes/api/auth/reset-password/+server.ts b/src/routes/api/auth/reset-password/+server.ts index a36eebf..d793b58 100644 --- a/src/routes/api/auth/reset-password/+server.ts +++ b/src/routes/api/auth/reset-password/+server.ts @@ -1,7 +1,7 @@ import db from '../../../../db'; import { error } from '@sveltejs/kit'; import { eq } from 'drizzle-orm'; -import { users } from '$db/schema'; +import { usersTable } from '$db/schema'; import { createPasswordResetToken } from '$lib/server/auth-utils.js'; import { PUBLIC_SITE_URL } from '$env/static/public'; @@ -12,8 +12,8 @@ export async function POST({ locals, request }) { error(401, { message: 'Unauthorized' }); } - const user = await db.query.users.findFirst({ - where: eq(users.email, email), + const user = await db.query.usersTable.findFirst({ + where: eq(usersTable.email, email), }); if (!user) { diff --git a/src/routes/api/auth/reset-password/[token]/+server.ts b/src/routes/api/auth/reset-password/[token]/+server.ts index 5bb7bfb..d1d4ecf 100644 --- a/src/routes/api/auth/reset-password/[token]/+server.ts +++ b/src/routes/api/auth/reset-password/[token]/+server.ts @@ -1,9 +1,9 @@ -import db from '../../../../../db'; import { eq } from 'drizzle-orm'; -import { password_reset_tokens, users } from '$db/schema'; +import { password_reset_tokens, usersTable } from '$db/schema'; import { isWithinExpirationDate } from 'oslo'; import { lucia } from '$lib/server/auth.js'; import { Argon2id } from 'oslo/password'; +import db from '$db'; export async function POST({ request, params }) { const { password } = await request.json(); @@ -34,7 +34,7 @@ export async function POST({ request, params }) { await lucia.invalidateUserSessions(token.user_id); const hashPassword = await new Argon2id().hash(password); - await db.update(users).set({ hashed_password: hashPassword }).where(eq(users.id, token.user_id)); + await db.update(usersTable).set({ hashed_password: hashPassword }).where(eq(usersTable.id, token.user_id)); const session = await lucia.createSession(token.user_id, {}); const sessionCookie = lucia.createSessionCookie(session.id); diff --git a/src/routes/api/collection/[id]/search/+server.ts b/src/routes/api/collection/[id]/search/+server.ts index 2a338d5..046f107 100644 --- a/src/routes/api/collection/[id]/search/+server.ts +++ b/src/routes/api/collection/[id]/search/+server.ts @@ -1,7 +1,7 @@ import { error, json } from '@sveltejs/kit'; import { eq } from 'drizzle-orm'; import db from '../../../../../db'; -import { collection_items, users } from '$db/schema'; +import { collection_items, usersTable } from '$db/schema'; // Search a user's collection export async function GET({ url, locals, params }) { @@ -20,7 +20,7 @@ export async function GET({ url, locals, params }) { } const collection = await db.query.collections.findFirst({ - where: eq(users.id, locals?.user?.id), + where: eq(usersTable.id, locals?.user?.id), }); console.log('collection', collection); diff --git a/src/server/users.ts b/src/server/users.ts index 9a61736..e29b14c 100644 --- a/src/server/users.ts +++ b/src/server/users.ts @@ -1,17 +1,17 @@ import db from '../db'; import { eq } from 'drizzle-orm'; -import { users, type Users } from '$db/schema'; +import { usersTable, type Users } from '$db/schema'; import { add_user_to_role } from './roles'; export function create_user(user: Users) { - return db.insert(users).values({ + return db.insert(usersTable).values({ username: user.username, }); } export async function find_or_create_user(user: Users) { - const existing_user = await db.query.users.findFirst({ - where: eq(users.username, user.username), + const existing_user = await db.query.usersTable.findFirst({ + where: eq(usersTable.username, user.username), }); if (existing_user) { return existing_user; @@ -23,8 +23,8 @@ export async function find_or_create_user(user: Users) { } export async function find_user_with_roles(user_id: string) { - const user_with_roles = await db.query.users.findFirst({ - where: eq(users.id, user_id), + const user_with_roles = await db.query.usersTable.findFirst({ + where: eq(usersTable.id, user_id), with: { user_roles: { with: { diff --git a/svelte.config.js b/svelte.config.js index 9f0b43e..435efb8 100644 --- a/svelte.config.js +++ b/svelte.config.js @@ -1,3 +1,4 @@ +import 'reflect-metadata' import adapter from '@sveltejs/adapter-vercel'; import { vitePreprocess } from '@sveltejs/vite-plugin-svelte'; import { preprocessMeltUI } from '@melt-ui/pp'; diff --git a/vite.config.ts.timestamp-1722555436409-2175218f70ffd.mjs b/vite.config.ts.timestamp-1722555436409-2175218f70ffd.mjs new file mode 100644 index 0000000..4b25ada --- /dev/null +++ b/vite.config.ts.timestamp-1722555436409-2175218f70ffd.mjs @@ -0,0 +1,41 @@ +// vite.config.ts +import { sveltekit } from "file:///home/bshellnu/projects/websites/boredgame/node_modules/.pnpm/@sveltejs+kit@2.5.18_@sveltejs+vite-plugin-svelte@3.1.1_svelte@5.0.0-next.175_vite@5.3.5_@typ_ps3ubydtq463bedtodypwfb5fu/node_modules/@sveltejs/kit/src/exports/vite/index.js"; +import { defineConfig } from "file:///home/bshellnu/projects/websites/boredgame/node_modules/.pnpm/vite@5.3.5_@types+node@20.14.13_sass@1.77.8/node_modules/vite/dist/node/index.js"; +var vite_config_default = defineConfig({ + plugins: [ + // sentrySvelteKit({ + // sourceMapsUploadOptions: { + // org: process.env.SENTRY_ORG, + // project: process.env.SENTRY_PROJECT, + // authToken: process.env.SENTRY_AUTH_TOKEN, + // cleanArtifacts: true, + // } + // }), + sveltekit() + ], + test: { + include: ["src/**/*.{test,spec}.{js,ts}"] + }, + css: { + devSourcemap: true, + preprocessorOptions: { + postcss: { + additionalData: ` + @custom-media --below_small (width < 400px); + @custom-media --below_med (width < 700px); + @custom-media --below_large (width < 900px); + @custom-media --below_xlarge (width < 1200px); + + @custom-media --above_small (width > 400px); + @custom-media --above_med (width > 700px); + @custom-media --above_large (width > 900px); + @custom-media --above_xlarge (width > 1200px); + ` + } + } + } +}); +export { + vite_config_default as default +}; +//# sourceMappingURL=data:application/json;base64,ewogICJ2ZXJzaW9uIjogMywKICAic291cmNlcyI6IFsidml0ZS5jb25maWcudHMiXSwKICAic291cmNlc0NvbnRlbnQiOiBbImNvbnN0IF9fdml0ZV9pbmplY3RlZF9vcmlnaW5hbF9kaXJuYW1lID0gXCIvaG9tZS9ic2hlbGxudS9wcm9qZWN0cy93ZWJzaXRlcy9ib3JlZGdhbWVcIjtjb25zdCBfX3ZpdGVfaW5qZWN0ZWRfb3JpZ2luYWxfZmlsZW5hbWUgPSBcIi9ob21lL2JzaGVsbG51L3Byb2plY3RzL3dlYnNpdGVzL2JvcmVkZ2FtZS92aXRlLmNvbmZpZy50c1wiO2NvbnN0IF9fdml0ZV9pbmplY3RlZF9vcmlnaW5hbF9pbXBvcnRfbWV0YV91cmwgPSBcImZpbGU6Ly8vaG9tZS9ic2hlbGxudS9wcm9qZWN0cy93ZWJzaXRlcy9ib3JlZGdhbWUvdml0ZS5jb25maWcudHNcIjsvLyBpbXBvcnQgeyBzZW50cnlTdmVsdGVLaXQgfSBmcm9tIFwiQHNlbnRyeS9zdmVsdGVraXRcIjtcbmltcG9ydCB7IHN2ZWx0ZWtpdCB9IGZyb20gJ0BzdmVsdGVqcy9raXQvdml0ZSc7XG5pbXBvcnQgeyBkZWZpbmVDb25maWcgfSBmcm9tICd2aXRlJztcblxuLy8gVE9ETzogRml4IFNlbnRyeVxuZXhwb3J0IGRlZmF1bHQgZGVmaW5lQ29uZmlnKHtcblx0cGx1Z2luczogW1xuXHRcdC8vIHNlbnRyeVN2ZWx0ZUtpdCh7XG5cdFx0Ly8gXHRzb3VyY2VNYXBzVXBsb2FkT3B0aW9uczoge1xuXHRcdC8vIFx0XHRvcmc6IHByb2Nlc3MuZW52LlNFTlRSWV9PUkcsXG5cdFx0Ly8gXHRcdHByb2plY3Q6IHByb2Nlc3MuZW52LlNFTlRSWV9QUk9KRUNULFxuXHRcdC8vIFx0XHRhdXRoVG9rZW46IHByb2Nlc3MuZW52LlNFTlRSWV9BVVRIX1RPS0VOLFxuXHRcdC8vIFx0XHRjbGVhbkFydGlmYWN0czogdHJ1ZSxcblx0XHQvLyBcdH1cblx0XHQvLyB9KSxcblx0XHRzdmVsdGVraXQoKVxuXHRdLFxuXHR0ZXN0OiB7XG5cdFx0aW5jbHVkZTogWydzcmMvKiovKi57dGVzdCxzcGVjfS57anMsdHN9J11cblx0fSxcblx0Y3NzOiB7XG5cdFx0ZGV2U291cmNlbWFwOiB0cnVlLFxuXHRcdHByZXByb2Nlc3Nvck9wdGlvbnM6IHtcblx0XHRcdHBvc3Rjc3M6IHtcblx0XHRcdFx0YWRkaXRpb25hbERhdGE6IGBcblx0XHRcdFx0QGN1c3RvbS1tZWRpYSAtLWJlbG93X3NtYWxsICh3aWR0aCA8IDQwMHB4KTtcblx0XHRcdFx0QGN1c3RvbS1tZWRpYSAtLWJlbG93X21lZCAod2lkdGggPCA3MDBweCk7XG5cdFx0XHRcdEBjdXN0b20tbWVkaWEgLS1iZWxvd19sYXJnZSAod2lkdGggPCA5MDBweCk7XG5cdFx0XHRcdEBjdXN0b20tbWVkaWEgLS1iZWxvd194bGFyZ2UgKHdpZHRoIDwgMTIwMHB4KTtcblxuXHRcdFx0XHRAY3VzdG9tLW1lZGlhIC0tYWJvdmVfc21hbGwgKHdpZHRoID4gNDAwcHgpO1xuXHRcdFx0XHRAY3VzdG9tLW1lZGlhIC0tYWJvdmVfbWVkICh3aWR0aCA+IDcwMHB4KTtcblx0XHRcdFx0QGN1c3RvbS1tZWRpYSAtLWFib3ZlX2xhcmdlICh3aWR0aCA+IDkwMHB4KTtcblx0XHRcdFx0QGN1c3RvbS1tZWRpYSAtLWFib3ZlX3hsYXJnZSAod2lkdGggPiAxMjAwcHgpO1xuXHRcdFx0XHRgXG5cdFx0XHR9XG5cdFx0fVxuXHR9LFxufSk7XG4iXSwKICAibWFwcGluZ3MiOiAiO0FBQ0EsU0FBUyxpQkFBaUI7QUFDMUIsU0FBUyxvQkFBb0I7QUFHN0IsSUFBTyxzQkFBUSxhQUFhO0FBQUEsRUFDM0IsU0FBUztBQUFBO0FBQUE7QUFBQTtBQUFBO0FBQUE7QUFBQTtBQUFBO0FBQUE7QUFBQSxJQVNSLFVBQVU7QUFBQSxFQUNYO0FBQUEsRUFDQSxNQUFNO0FBQUEsSUFDTCxTQUFTLENBQUMsOEJBQThCO0FBQUEsRUFDekM7QUFBQSxFQUNBLEtBQUs7QUFBQSxJQUNKLGNBQWM7QUFBQSxJQUNkLHFCQUFxQjtBQUFBLE1BQ3BCLFNBQVM7QUFBQSxRQUNSLGdCQUFnQjtBQUFBO0FBQUE7QUFBQTtBQUFBO0FBQUE7QUFBQTtBQUFBO0FBQUE7QUFBQTtBQUFBO0FBQUEsTUFXakI7QUFBQSxJQUNEO0FBQUEsRUFDRDtBQUNELENBQUM7IiwKICAibmFtZXMiOiBbXQp9Cg==