talkwho/src/routes/auth/+page.server.ts
2024-08-18 19:36:08 -04:00

80 lines
2.7 KiB
TypeScript

import { alphabet, generateRandomString } from 'oslo/crypto'
import { fail, message, setError, superValidate } from 'sveltekit-superforms'
import { zod } from 'sveltekit-superforms/adapters'
import { z } from 'zod'
import { hash, verify } from '@ts-rex/argon2'
import { db } from '$lib/server/db'
import { cookieController, cookieExpiration, createSessionForUser } from '$lib/server/auth'
import { createDate } from 'oslo'
import { redirect } from '@sveltejs/kit'
const schema = z.object({
username: z
.string()
.min(4, 'must be atleast 4 characters')
.max(32, 'must be less than 32 characters')
.regex(/^[a-z0-9_\-]+$/i, `must be alphanumeric, with the exception of "_" and "-"`),
password: z.string().min(8, 'must be atleast 8 characters').max(255)
})
export async function load({ locals }) {
if (locals.session) {
return redirect(302, '/app')
}
const form = await superValidate(zod(schema))
return { form }
}
export const actions = {
login: async ({ request, cookies }) => {
const form = await superValidate(request, zod(schema))
if (!form.valid) return fail(400, { form })
const { username, password } = form.data
const user = (await db.user.findByPrimaryIndex('username', username))?.flat()
if (!user) return setError(form, 'user does not exist')
if (!user.password)
return setError(form, 'this account does not have a password, maybe try a different method?')
const isvalid = verify(password, user.password)
if (!isvalid) return setError(form, 'incorrect password')
const session = await createSessionForUser(user.id)
if (session.isSome()) {
const sessionCookie = cookieController.createCookie(session.unwrap().id)
cookies.set(sessionCookie.name, sessionCookie.value, {
path: '.',
...sessionCookie.attributes
})
return redirect(302, '/app')
} else {
return fail(500, { form })
}
},
signup: async ({ request, cookies }) => {
const form = await superValidate(request, zod(schema))
if (!form.valid) return fail(400, { form })
const { username, password } = form.data
const userId = generateRandomString(10, alphabet('0-9', 'a-z'))
const passwordHash = hash(password)
const user = (await db.user.findByPrimaryIndex('username', username))?.flat()
if (user) return setError(form, 'username', 'username already exists')
await db.user.set(userId, {
displayName: username,
username,
id: userId,
password: passwordHash
})
const session = await createSessionForUser(userId)
if (session.isSome()) {
const sessionCookie = cookieController.createCookie(session.unwrap().id)
cookies.set(sessionCookie.name, sessionCookie.value, {
path: '.',
...sessionCookie.attributes
})
return redirect(302, '/app')
} else {
return fail(500, { form })
}
}
}