Visit svelte.dev/docs/kit to read the documentation
+ + +Your user ID is {data.user.id}.
+ diff --git a/src/routes/demo/lucia/login/+page.server.ts b/src/routes/demo/lucia/login/+page.server.ts new file mode 100644 index 0000000..f0844ab --- /dev/null +++ b/src/routes/demo/lucia/login/+page.server.ts @@ -0,0 +1,107 @@ +import { verify } from '@node-rs/argon2'; +import { encodeBase32LowerCase } from '@oslojs/encoding'; +import { fail, redirect } from '@sveltejs/kit'; +import { eq } from 'drizzle-orm'; +import * as auth from '$lib/server/auth'; +import { db } from '$lib/server/db'; +import * as table from '$lib/server/db/schema'; +import type { Actions, PageServerLoad } from './$types'; + +export const load: PageServerLoad = async (event) => { + if (event.locals.user) { + return redirect(302, '/demo/lucia'); + } + return {}; +}; + +export const actions: Actions = { + login: async (event) => { + const formData = await event.request.formData(); + const username = formData.get('username'); + const password = formData.get('password'); + + if (!validateUsername(username)) { + return fail(400, { + message: 'Invalid username (min 3, max 31 characters, alphanumeric only)' + }); + } + if (!validatePassword(password)) { + return fail(400, { message: 'Invalid password (min 6, max 255 characters)' }); + } + + const results = await db.select().from(table.user).where(eq(table.user.username, username)); + + const existingUser = results.at(0); + if (!existingUser) { + return fail(400, { message: 'Incorrect username or password' }); + } + + const validPassword = await verify(existingUser.passwordHash, password, { + memoryCost: 19456, + timeCost: 2, + outputLen: 32, + parallelism: 1 + }); + if (!validPassword) { + return fail(400, { message: 'Incorrect username or password' }); + } + + const sessionToken = auth.generateSessionToken(); + const session = await auth.createSession(sessionToken, existingUser.id); + auth.setSessionTokenCookie(event, sessionToken, session.expiresAt); + + return redirect(302, '/demo/lucia'); + } + /*register: async (event) => { + const formData = await event.request.formData(); + const username = formData.get('username'); + const password = formData.get('password'); + + if (!validateUsername(username)) { + return fail(400, { message: 'Invalid username' }); + } + if (!validatePassword(password)) { + return fail(400, { message: 'Invalid password' }); + } + + const userId = generateUserId(); + const passwordHash = await hash(password, { + // recommended minimum parameters + memoryCost: 19456, + timeCost: 2, + outputLen: 32, + parallelism: 1 + }); + + try { + await db.insert(table.user).values({ id: userId, username, passwordHash }); + + const sessionToken = auth.generateSessionToken(); + const session = await auth.createSession(sessionToken, userId); + auth.setSessionTokenCookie(event, sessionToken, session.expiresAt); + } catch (e) { + return fail(500, { message: 'An error has occurred' }); + } + return redirect(302, '/demo/lucia'); + }*/ +}; + +function generateUserId() { + // ID with 120 bits of entropy, or about the same as UUID v4. + const bytes = crypto.getRandomValues(new Uint8Array(15)); + const id = encodeBase32LowerCase(bytes); + return id; +} + +function validateUsername(username: unknown): username is string { + return ( + typeof username === 'string' && + username.length >= 3 && + username.length <= 31 && + /^[a-z0-9_-]+$/.test(username) + ); +} + +function validatePassword(password: unknown): password is string { + return typeof password === 'string' && password.length >= 6 && password.length <= 255; +} diff --git a/src/routes/demo/lucia/login/+page.svelte b/src/routes/demo/lucia/login/+page.svelte new file mode 100644 index 0000000..a3138d7 --- /dev/null +++ b/src/routes/demo/lucia/login/+page.svelte @@ -0,0 +1,21 @@ + + +{form?.message ?? ''}
diff --git a/src/routes/login/+page.svelte b/src/routes/login/+page.svelte new file mode 100644 index 0000000..2fb9f09 --- /dev/null +++ b/src/routes/login/+page.svelte @@ -0,0 +1 @@ +bruh
diff --git a/svelte.config.js b/svelte.config.js index 7adf49b..415a6c3 100644 --- a/svelte.config.js +++ b/svelte.config.js @@ -1,4 +1,4 @@ -import adapter from '@sveltejs/adapter-cloudflare'; +import adapter from '@sveltejs/adapter-node'; import { vitePreprocess } from '@sveltejs/vite-plugin-svelte'; const config = { diff --git a/wrangler.toml b/wrangler.toml deleted file mode 100644 index be2ecb0..0000000 --- a/wrangler.toml +++ /dev/null @@ -1,14 +0,0 @@ -name = "protogen-social-handles" -compatibility_date = "2025-01-01" -compatibility_flags = [ "nodejs_compat" ] -pages_build_output_dir = ".svelte-kit/cloudflare" - -[[ env.production.d1_databases ]] -binding = "HANDLES_DB" -database_name = "production-protogen-social-handles" -database_id = "b7e2740b-9f80-4a0a-b641-a1802339af67" - -[[ env.preview.d1_databases ]] -binding = "HANDLES_DB" -database_name = "preview-protogen-social-handles" -database_id = "9edbeba1-cec2-4f91-800f-5b82cb727717" \ No newline at end of file