126 lines
3.0 KiB
TypeScript
126 lines
3.0 KiB
TypeScript
import type { FastifyInstance } from 'fastify'
|
|
import type { RegisterOptions } from 'fastify/types/register.js'
|
|
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)
|
|
|
|
cookie.attributes.secure = false
|
|
|
|
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 })
|
|
}
|
|
})
|
|
}
|
|
|
|
const autoConfig: RegisterOptions = {
|
|
prefix: '/chad',
|
|
}
|