import type { FastifyInstance } from 'fastify' import bcrypt from 'bcrypt' import { z } from 'zod' import { auth } from '../auth/lucia.ts' import prisma from '../prisma/client.ts' export default function (fastify: FastifyInstance) { fastify.post('/register', async (req, reply) => { try { const schema = z.object({ username: z.string().min(1), password: z.string().min(6), }) const input = schema.parse(req.body) const hashed = await bcrypt.hash(input.password, 10) const user = await prisma.user.create({ data: { username: input.username, password: hashed, displayName: input.username, }, }) const session = await auth.createSession(user.id, {}) const cookie = auth.createSessionCookie(session.id) reply.setCookie(cookie.name, cookie.value, cookie.attributes) return { id: user.id, username: user.username, displayName: user.displayName, } } catch (err) { fastify.log.error(err) reply.code(400) if (err instanceof z.ZodError) { reply.send({ error: z.prettifyError(err) }) } else { reply.send({ error: err.message }) } } }) fastify.post('/login', async (req, reply) => { try { const schema = z.object({ username: z.string().min(1), password: z.string(), }) const input = schema.parse(req.body) const user = await prisma.user.findFirst({ where: { username: input.username }, }) if (!user) { return reply.code(404).send({ error: 'Incorrect username or password' }) } const validPassword = await bcrypt.compare(input.password, user.password) if (!validPassword) { return reply.code(404).send({ error: 'Incorrect username or password' }) } const session = await auth.createSession(user.id, {}) const cookie = auth.createSessionCookie(session.id) reply.setCookie(cookie.name, cookie.value, cookie.attributes) return { id: user.id, username: user.username, displayName: user.displayName, } } catch (err) { fastify.log.error(err) reply.code(400) if (err instanceof z.ZodError) { reply.send({ error: z.prettifyError(err) }) } else { reply.send({ error: err.message }) } } }) fastify.get('/me', async (req, reply) => { if (req.user) { return req.user } reply.code(401).send(false) }) fastify.post('/logout', async (req, reply) => { try { if (req.session) await auth.invalidateSession(req.session.id) const blank = auth.createBlankSessionCookie() reply.setCookie(blank.name, blank.value, blank.attributes) return true } catch (err) { fastify.log.error(err) reply.code(400).send({ error: err.message }) } }) }