From 2230924cccb2d5876a15b7409799dc419d232b76 Mon Sep 17 00:00:00 2001 From: SirMorfield Date: Sun, 1 Oct 2023 17:50:44 +0200 Subject: [PATCH 01/27] Add debug Co-authored-by: Mees Dekker --- .vscode/launch.json | 40 ++++++++++++++++++++++++++++++++++++++++ 1 file changed, 40 insertions(+) create mode 100644 .vscode/launch.json diff --git a/.vscode/launch.json b/.vscode/launch.json new file mode 100644 index 0000000..176fc92 --- /dev/null +++ b/.vscode/launch.json @@ -0,0 +1,40 @@ +{ + "version": "0.2.0", + "configurations": [ + { + "name": "Launch server", + "request": "launch", + "runtimeArgs": [ + "run", + "dev", + "--", + "--host", + ], + "runtimeExecutable": "npm", + "skipFiles": [ + "/**" + ], + "type": "node", + "console": "integratedTerminal", + "cwd": "${workspaceFolder}/frontend/", + }, + { + "type": "chrome", + "request": "launch", + "name": "Launch chrome", + "url": "http://localhost:5173", + "cwd": "${workspaceFolder}/frontend/", + "webRoot": "${workspaceFolder}/frontend/" + } + ], + "compounds": [ + { + "name": "Both", + "cwd": "${workspaceFolder}/frontend/", + "configurations": [ + "Launch server", + "Launch chrome" + ] + } + ] +} \ No newline at end of file From 8fc10070f3526767df89d72a5593502b43ca7c12 Mon Sep 17 00:00:00 2001 From: SirMorfield Date: Mon, 2 Oct 2023 23:24:08 +0200 Subject: [PATCH 02/27] Add helpers --- frontend/package.json | 2 ++ 1 file changed, 2 insertions(+) diff --git a/frontend/package.json b/frontend/package.json index 85b948a..4bbc898 100644 --- a/frontend/package.json +++ b/frontend/package.json @@ -8,6 +8,8 @@ "build": "vite build", "preview": "vite preview", "generate-schema": "drizzle-kit generate:pg --out db-migrations --schema src/lib/server/schemas.ts", + "migrate-last": "PGPASSWORD='postgres' /opt/homebrew/opt/postgresql@15/bin/psql -h localhost -U postgres -d postgres -a -f ./db-migrations/$(ls -A ./db-migrations | sort -r | tail -n 1)", + "nuke-db": "cd .. && docker compose down && rm -rf postgres-db && make start-deps", "test": "npx playwright test", "test:view": "npx playwright test --headed", "check": "svelte-kit sync && svelte-check --tsconfig ./tsconfig.json", From 93f58c7eaeff72ab0135d7df7c26f16613a51fba Mon Sep 17 00:00:00 2001 From: SirMorfield Date: Mon, 2 Oct 2023 23:28:18 +0200 Subject: [PATCH 03/27] Add test --- frontend/tests/load.spec.ts | 48 +++++++++++++++++++++++++++++++++++++ 1 file changed, 48 insertions(+) create mode 100644 frontend/tests/load.spec.ts diff --git a/frontend/tests/load.spec.ts b/frontend/tests/load.spec.ts new file mode 100644 index 0000000..1adc770 --- /dev/null +++ b/frontend/tests/load.spec.ts @@ -0,0 +1,48 @@ +import { expect, test, type Page } from '@playwright/test' +import { randomBytes } from 'crypto' + +test.describe.configure({ mode: 'parallel', timeout: 5000 }) + +const root = 'http://localhost:5173' +async function signup(page: Page, userName: string) { + await page.goto(`${root}/signup`) + await page.waitForSelector('button[type="submit"]') + + await page.evaluate(userName => { + ;(document.querySelector('input[name="username"]') as HTMLInputElement).value = userName + try { + ;(document.querySelector('#password') as HTMLInputElement).value = userName + ;(document.querySelector('#password-confirm') as HTMLInputElement).value = userName + } catch (e) { + /**/ + } + ;(document.querySelector('button[type="submit"]') as HTMLButtonElement).click() + }, userName) + await expect(page.locator('#header-username')).toHaveText(userName) +} + +function signupRand(page: Page) { + return signup(page, `joppe-loadtest-${randomBytes(10).toString('hex')}`) +} + +// For some reason I can't test this in a for loop +test('Load 1', ({ page }) => signupRand(page)) +test('Load 2', ({ page }) => signupRand(page)) +test('Load 3', ({ page }) => signupRand(page)) +test('Load 4', ({ page }) => signupRand(page)) +test('Load 5', ({ page }) => signupRand(page)) +test('Load 6', ({ page }) => signupRand(page)) +test('Load 7', ({ page }) => signupRand(page)) +test('Load 8', ({ page }) => signupRand(page)) +test('Load 9', ({ page }) => signupRand(page)) +test('Load 10', ({ page }) => signupRand(page)) +test('Load 11', ({ page }) => signupRand(page)) +test('Load 12', ({ page }) => signupRand(page)) +test('Load 13', ({ page }) => signupRand(page)) +test('Load 14', ({ page }) => signupRand(page)) +test('Load 15', ({ page }) => signupRand(page)) +test('Load 16', ({ page }) => signupRand(page)) +test('Load 17', ({ page }) => signupRand(page)) +test('Load 18', ({ page }) => signupRand(page)) +test('Load 19', ({ page }) => signupRand(page)) +test('Load 20', ({ page }) => signupRand(page)) From aaf658fde3b4ea91f9181112e5d4e64b70f07c2c Mon Sep 17 00:00:00 2001 From: SirMorfield Date: Mon, 2 Oct 2023 23:32:24 +0200 Subject: [PATCH 04/27] Add packages --- frontend/package.json | 7 ++- frontend/pnpm-lock.yaml | 130 +++++++++++++++++++++++++++++++++------- 2 files changed, 111 insertions(+), 26 deletions(-) diff --git a/frontend/package.json b/frontend/package.json index 4bbc898..07454b3 100644 --- a/frontend/package.json +++ b/frontend/package.json @@ -17,9 +17,11 @@ "lint:fix": "prettier --plugin-search-dir . --write . && DEBUG=eslint:cli-engine eslint --cache --cache-location node_modules/.eslintcache --fix ." }, "devDependencies": { + "@auth/core": "^0.16.0", + "@auth/drizzle-adapter": "^0.3.2", + "@auth/sveltekit": "^0.3.7", "@carlosv2/adapter-node-ws": "github:SirMorfield/adapter-node-ws#933fbd9506ebc2b2144e85e3dc018ada1cb432b5", "@fontsource/fira-mono": "^5.0.0", - "@lucia-auth/adapter-postgresql": "^1.0.1", "@neoconfetti/svelte": "^1.0.0", "@playwright/test": "^1.34.0", "@svelte-plugins/tooltips": "^0.1.6", @@ -41,7 +43,6 @@ "highlight.js": "^11.8.0", "hot-shots": "^10.0.0", "ioredis": "^5.3.2", - "lucia-auth": "^1.8.0", "memoizee": "^0.4.15", "pg": "^8.11.0", "postcss": "^8.4.23", @@ -67,4 +68,4 @@ "npm": ">=8.8.0", "pnpm": ">=7.0.0" } -} +} \ No newline at end of file diff --git a/frontend/pnpm-lock.yaml b/frontend/pnpm-lock.yaml index 755619a..a025325 100644 --- a/frontend/pnpm-lock.yaml +++ b/frontend/pnpm-lock.yaml @@ -5,15 +5,21 @@ settings: excludeLinksFromLockfile: false devDependencies: + '@auth/core': + specifier: ^0.16.0 + version: 0.16.0 + '@auth/drizzle-adapter': + specifier: ^0.3.2 + version: 0.3.2 + '@auth/sveltekit': + specifier: ^0.3.7 + version: 0.3.7(@sveltejs/kit@1.18.0)(svelte@3.59.1) '@carlosv2/adapter-node-ws': specifier: github:SirMorfield/adapter-node-ws#933fbd9506ebc2b2144e85e3dc018ada1cb432b5 version: github.com/SirMorfield/adapter-node-ws/933fbd9506ebc2b2144e85e3dc018ada1cb432b5 '@fontsource/fira-mono': specifier: ^5.0.0 version: 5.0.0 - '@lucia-auth/adapter-postgresql': - specifier: ^1.0.1 - version: 1.0.1(lucia-auth@1.8.0)(pg@8.11.0) '@neoconfetti/svelte': specifier: ^1.0.0 version: 1.0.0 @@ -77,9 +83,6 @@ devDependencies: ioredis: specifier: ^5.3.2 version: 5.3.2 - lucia-auth: - specifier: ^1.8.0 - version: 1.8.0 memoizee: specifier: ^0.4.15 version: 0.4.15 @@ -145,6 +148,75 @@ packages: engines: {node: '>=10'} dev: true + /@auth/core@0.12.0: + resolution: {integrity: sha512-XYipdAc/nKu014VOgpcPyLlj1ghWlnwyloaB1UjQd9ElZRZQ9YpSizzXGLON23t/a0FyabOBBl0/awD2tW58Rg==} + peerDependencies: + nodemailer: ^6.8.0 + peerDependenciesMeta: + nodemailer: + optional: true + dependencies: + '@panva/hkdf': 1.1.1 + cookie: 0.5.0 + jose: 4.14.6 + oauth4webapi: 2.3.0 + preact: 10.11.3 + preact-render-to-string: 5.2.3(preact@10.11.3) + dev: true + + /@auth/core@0.13.0: + resolution: {integrity: sha512-StjrzUenaKfMr68kmvhiqfY0xvxRvg8wllmem9JAULpPAAAt3uwRUDXICWOP/PfWB4OZ2wQT7rgfm0n42b+Mjg==} + peerDependencies: + nodemailer: ^6.8.0 + peerDependenciesMeta: + nodemailer: + optional: true + dependencies: + '@panva/hkdf': 1.1.1 + cookie: 0.5.0 + jose: 4.14.6 + oauth4webapi: 2.3.0 + preact: 10.11.3 + preact-render-to-string: 5.2.3(preact@10.11.3) + dev: true + + /@auth/core@0.16.0: + resolution: {integrity: sha512-g9Aj+N4dzGhZwOtR7qOW0T+OhpH7zbHa29tonLB5V+FxaQoWCsNTrZsjfzBVfvCI8VEkBqPbPHkIIyWSoTw0iA==} + peerDependencies: + nodemailer: ^6.8.0 + peerDependenciesMeta: + nodemailer: + optional: true + dependencies: + '@panva/hkdf': 1.1.1 + cookie: 0.5.0 + jose: 4.14.6 + oauth4webapi: 2.3.0 + preact: 10.11.3 + preact-render-to-string: 5.2.3(preact@10.11.3) + dev: true + + /@auth/drizzle-adapter@0.3.2: + resolution: {integrity: sha512-fHfzwaTomm/RKgFKBO5AJ8JTfR44rX1KX2ASaKRk+4jvVhDh9FCir5BV1Fv68b5ay7XBo9DtcNSQuZp4hbpLYw==} + dependencies: + '@auth/core': 0.12.0 + transitivePeerDependencies: + - nodemailer + dev: true + + /@auth/sveltekit@0.3.7(@sveltejs/kit@1.18.0)(svelte@3.59.1): + resolution: {integrity: sha512-2aIQbACu4F6oBUMgi9c1yCPVzOd3VQmMslk4y7U1Ec5A8CGstJfvMyL1N2J4zc3bemmvzhlrZ9ng0baKc695lg==} + peerDependencies: + '@sveltejs/kit': ^1.0.0 + svelte: ^3.54.0 || ^4.0.0 + dependencies: + '@auth/core': 0.13.0 + '@sveltejs/kit': 1.18.0(svelte@3.59.1)(vite@4.3.8) + svelte: 3.59.1 + transitivePeerDependencies: + - nodemailer + dev: true + /@esbuild-kit/core-utils@3.1.0: resolution: {integrity: sha512-Uuk8RpCg/7fdHSceR1M6XbSZFSuMrxcePFuGgyvsBn+u339dk5OeL4jv2EojwTN2st/unJGsVm4qHWjWNmJ/tw==} dependencies: @@ -688,19 +760,6 @@ packages: '@jridgewell/sourcemap-codec': 1.4.14 dev: true - /@lucia-auth/adapter-postgresql@1.0.1(lucia-auth@1.8.0)(pg@8.11.0): - resolution: {integrity: sha512-+5A5Yyl8itjHB2bqNQWIJAxNAMBkQsk/kad+WGBRkXmdDTwj+854fmC4nTYprsO2M0q92KfjNZhdCBh4UD2Sgg==} - peerDependencies: - lucia-auth: ^1.4.0 - pg: ^8.0.0 - peerDependenciesMeta: - pg: - optional: true - dependencies: - lucia-auth: 1.8.0 - pg: 8.11.0 - dev: true - /@neoconfetti/svelte@1.0.0: resolution: {integrity: sha512-SmksyaJAdSlMa9cTidVSIqYo1qti+WTsviNDwgjNVm+KQ3DRP2Df9umDIzC4vCcpEYY+chQe0i2IKnLw03AT8Q==} dev: true @@ -726,6 +785,10 @@ packages: fastq: 1.15.0 dev: true + /@panva/hkdf@1.1.1: + resolution: {integrity: sha512-dhPeilub1NuIG0X5Kvhh9lH4iW3ZsHlnzwgwbOlgwQ2wG1IqFzsgHqmKPk3WzsdWAeaxKJxgM0+W433RmN45GA==} + dev: true + /@playwright/test@1.34.0: resolution: {integrity: sha512-GIALJVODOIrMflLV54H3Cow635OfrTwOu24ZTDyKC66uchtFX2NcCRq83cLdakMjZKYK78lODNLQSYBj2OgaTw==} engines: {node: '>=14'} @@ -2187,6 +2250,10 @@ packages: hasBin: true dev: true + /jose@4.14.6: + resolution: {integrity: sha512-EqJPEUlZD0/CSUMubKtMaYUOtWe91tZXTWMJZoKSbLk+KtdhNdcvppH8lA9XwVu2V4Ailvsj0GBZJ2ZwDjfesQ==} + dev: true + /js-yaml@4.1.0: resolution: {integrity: sha512-wpxZs9NoxZaJESJGIZTyDEaYpl0FKSA+FB9aJiyemKhMwkxQg63h4T1KJgUGHpTqPDNRcmmYLugrRjJlBtWvRA==} hasBin: true @@ -2281,10 +2348,6 @@ packages: es5-ext: 0.10.62 dev: true - /lucia-auth@1.8.0: - resolution: {integrity: sha512-zI8gT2AOpxTPIxYzToEdgoht+GOflrduZiHPsOEmg4/2pThOyCW3o3lXh+Uwh20tJ9QoXwQe9/Omn6PlUG6efw==} - dev: true - /magic-string@0.27.0: resolution: {integrity: sha512-8UnnX2PeRAPZuN12svgR9j7M1uWMovg/CEnIwIG0LFkXSJJe4PdfUGiTGl8V9bsBHFUtfVINcSyYxd7q+kx9fA==} engines: {node: '>=12'} @@ -2443,6 +2506,10 @@ packages: engines: {node: '>=0.10.0'} dev: true + /oauth4webapi@2.3.0: + resolution: {integrity: sha512-JGkb5doGrwzVDuHwgrR4nHJayzN4h59VCed6EW8Tql6iHDfZIabCJvg6wtbn5q6pyB2hZruI3b77Nudvq7NmvA==} + dev: true + /object-assign@4.1.1: resolution: {integrity: sha512-rJgTQnkUnH1sFw8yT6VSU3zD3sWmu6sZhIseY8VX+GRu3P6F7Fu+JNDoXfklElbLJSnc3FUQHVe4cU5hj+BcUg==} engines: {node: '>=0.10.0'} @@ -2782,6 +2849,19 @@ packages: resolution: {integrity: sha512-VdlZoocy5lCP0c/t66xAfclglEapXPCIVhqqJRncYpvbCgImF0w67aPKfbqUMr72tO2k5q0TdTZwCLjPTI6C9g==} dev: true + /preact-render-to-string@5.2.3(preact@10.11.3): + resolution: {integrity: sha512-aPDxUn5o3GhWdtJtW0svRC2SS/l8D9MAgo2+AWml+BhDImb27ALf04Q2d+AHqUUOc6RdSXFIBVa2gxzgMKgtZA==} + peerDependencies: + preact: '>=10' + dependencies: + preact: 10.11.3 + pretty-format: 3.8.0 + dev: true + + /preact@10.11.3: + resolution: {integrity: sha512-eY93IVpod/zG3uMF22Unl8h9KkrcKIRs2EGar8hwLZZDU1lkjph303V9HZBwufh2s736U6VXuhD109LYqPoffg==} + dev: true + /prelude-ls@1.2.1: resolution: {integrity: sha512-vkcDPrRZo1QZLbn5RLGPpg/WmIQ65qoWWhcGKf/b5eplkkarX0m9z8ppCat4mlOqUsWpyNuYgO3VRyrYHSzX5g==} engines: {node: '>= 0.8.0'} @@ -2803,6 +2883,10 @@ packages: hasBin: true dev: true + /pretty-format@3.8.0: + resolution: {integrity: sha512-WuxUnVtlWL1OfZFQFuqvnvs6MiAGk9UNsBostyBOB0Is9wb5uRESevA6rnl/rkksXaGX3GzZhPup5d6Vp1nFew==} + dev: true + /punycode@2.3.0: resolution: {integrity: sha512-rRV+zQD8tVFys26lAGR9WUuS4iUAngJScM+ZRSKtvl5tKeZ2t5bvdNFdNHBW9FWR4guGHlgmsZ1G7BSm2wTbuA==} engines: {node: '>=6'} From 3dd7196c0e0282ae1084c82365de9a57ea7dcd7f Mon Sep 17 00:00:00 2001 From: SirMorfield Date: Tue, 3 Oct 2023 01:15:02 +0200 Subject: [PATCH 05/27] remove lucia --- frontend/src/app.d.ts | 6 ------ frontend/src/lib/server/auth.ts | 14 -------------- 2 files changed, 20 deletions(-) delete mode 100644 frontend/src/lib/server/auth.ts diff --git a/frontend/src/app.d.ts b/frontend/src/app.d.ts index 440fa2f..39eb4d6 100644 --- a/frontend/src/app.d.ts +++ b/frontend/src/app.d.ts @@ -3,16 +3,10 @@ import { StatsD } from './util/statsd' // See https://kit.svelte.dev/docs/types#app declare global { - declare namespace Lucia { - type Auth = import('./lib/server/auth').Auth - type UserAttributes = import('./lib/server/schemas').UserAttributes - } - declare namespace App { interface Locals { io: Server statsd: StatsD - auth: import('lucia-auth').AuthRequest } } } diff --git a/frontend/src/lib/server/auth.ts b/frontend/src/lib/server/auth.ts deleted file mode 100644 index af78a9e..0000000 --- a/frontend/src/lib/server/auth.ts +++ /dev/null @@ -1,14 +0,0 @@ -import lucia from 'lucia-auth' -import { sveltekit } from 'lucia-auth/middleware' -import { dev } from '$app/environment' -import { pg } from '@lucia-auth/adapter-postgresql' -import { pool } from './db' - -export const auth = lucia({ - adapter: pg(pool), - env: dev ? 'DEV' : 'PROD', - middleware: sveltekit(), - transformDatabaseUser: u => u -}) - -export type Auth = typeof auth From 599072a6d1cb5a4bd6ebe772270ed97a953835f4 Mon Sep 17 00:00:00 2001 From: SirMorfield Date: Tue, 3 Oct 2023 01:15:08 +0200 Subject: [PATCH 06/27] backup --- frontend/src/hooks.server.ts | 96 +++++++++++++++++-- frontend/src/lib/components/Header.svelte | 14 +-- frontend/src/lib/server/schemas.ts | 71 +++++++++----- .../src/routes/(auth)/login/+page.server.ts | 29 ++---- .../src/routes/(auth)/signup/+page.server.ts | 46 ++++----- .../src/routes/(auth)/signup/+page.svelte | 8 ++ .../src/routes/(protected)/+layout.server.ts | 8 +- .../src/routes/(protected)/test/+page.svelte | 21 ++++ frontend/src/routes/+layout.server.ts | 22 ++++- frontend/src/routes/+layout.svelte | 4 + 10 files changed, 222 insertions(+), 97 deletions(-) create mode 100644 frontend/src/routes/(protected)/test/+page.svelte diff --git a/frontend/src/hooks.server.ts b/frontend/src/hooks.server.ts index a3ea627..a98decd 100644 --- a/frontend/src/hooks.server.ts +++ b/frontend/src/hooks.server.ts @@ -1,11 +1,17 @@ import { getPixelMap } from '$lib/server/redis' -import { auth } from '$lib/server/auth' import type { Server } from '$lib/sharedTypes' import type { HandleWs } from '@carlosv2/adapter-node-ws' import type { Handle } from '@sveltejs/kit' import { publicEnv } from './publicEnv' import { StatsD } from './util/statsd' -import { pool } from '$lib/server/db' +import { DB, pool } from '$lib/server/db' +import { SvelteKitAuth } from '@auth/sveltekit' +import Auth from '@auth/core' +import Credentials from '@auth/core/providers/credentials' +import { sequence } from '@sveltejs/kit/hooks' +import { z } from 'zod' +import { DrizzleAdapter } from '@auth/drizzle-adapter' +import GitHub from '@auth/core/providers/github' let listenerCount = 0 let globalIo: Server | undefined = undefined @@ -53,14 +59,90 @@ export const handleWs: HandleWs = (io: Server) => { }) } -// Injecting global variables into the event object -export const handle: Handle = async ({ event, resolve }) => { +const User = z.object({ + name: z.string().min(1), + key: z.string().min(1) +}) +type User = z.infer + +const gh = GitHub({ clientId: 'e080da33865f31232b51', clientSecret: '4a8353fecf66a2a53e7fb13f1def12082b593599' }) +const credentials = Credentials({ + name: 'Credentials', + credentials: { + username: { label: 'Username' } + // key: { label: 'Key', type: 'text' } + }, + async authorize(credentials, _) { + // console.log(0, { credentials }) + const user = { id: '1', name: credentials.username, key: credentials.key } + + return user + // const parse = await LoginUserSchema.safeParseAsync(credentials) + // if (!parse.success) { + // console.log('invalid credentials', parse.error) + // return null + // } + // const user = await DB.user.getBy('name', parse.data.username) + // if (!user) { + // console.log('user not found') + // return null + // } + // return user + } +}) + +const authHandle = SvelteKitAuth({ + providers: [credentials], + pages: { + signIn: '/signup' // TODO: up or in + }, + secret: '126b402ae7264a6497882db7876ebdfa356fc8440bccfba7c742f0afbb4fd967', + callbacks: { + session({ session, token, user }) { + // console.log(1, { session, token, user }) + const u = { + name: token.name as string, + key: token['key'] as string + } satisfies User + + const s = { + ...session, + user: u + } + // console.log(2, { s }) + return s + }, + jwt({ token, account, user }) { + console.log(4, { token, account, user }) + if (account) { + token['id'] = user.id + token['name'] = user.name + // @ts-expect-error + token['key'] = user.key + } + return token + } + } + // session: { + // strategy: 'jwt' + // } + // trustHost: true + // adapter: DrizzleAdapter(db) +}) + +// TODO protect paths + +const otherHandle: Handle = ({ event, resolve }) => { event.locals.io = globalIo as Server event.locals.statsd = statsd - event.locals.auth = auth.handleRequest(event) // make sure the database is setup - await setupDBSingleton() - + // await setupDBSingleton() return resolve(event) } +const logHandle: Handle = ({ event, resolve }) => { + console.log(event.url.pathname + event.url.search, '|', event.route.id) + return resolve(event) +} +// Injecting global variables into the event object +export const handle: Handle = sequence(logHandle, authHandle, otherHandle) diff --git a/frontend/src/lib/components/Header.svelte b/frontend/src/lib/components/Header.svelte index 30a8c2b..69af7ad 100644 --- a/frontend/src/lib/components/Header.svelte +++ b/frontend/src/lib/components/Header.svelte @@ -4,19 +4,13 @@ import { page } from '$app/stores' import { slide } from 'svelte/transition' import { cubicOut } from 'svelte/easing' - import type { User } from 'lucia-auth' + import { signOut } from '@auth/sveltekit/client' - export let userData: User | undefined let showPopout = false function toggleLogout() { showPopout = !showPopout } - - async function logout() { - await fetch('/logout', { method: 'POST' }) - window.location.reload() - }