вложения, канальчики, бим-бим + бам-бам
This commit is contained in:
@@ -1,118 +1,146 @@
|
||||
import type { FastifyInstance } from 'fastify'
|
||||
import type { FastifyPluginAsyncTypebox } from '@fastify/type-provider-typebox'
|
||||
import bcrypt from 'bcrypt'
|
||||
import { z } from 'zod'
|
||||
import { auth } from '../auth/lucia.ts'
|
||||
import prisma from '../prisma/client.ts'
|
||||
import { Type } from 'typebox'
|
||||
import { CreateUserSchema, UserSchema } from '../schemas/auth.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({
|
||||
const plugin: FastifyPluginAsyncTypebox = async (fastify) => {
|
||||
fastify.post(
|
||||
'/auth/register',
|
||||
{
|
||||
schema: {
|
||||
summary: 'Register',
|
||||
tags: ['Auth'],
|
||||
operationId: 'auth.register',
|
||||
body: CreateUserSchema,
|
||||
response: {
|
||||
200: UserSchema,
|
||||
},
|
||||
},
|
||||
config: {
|
||||
skipAuth: true,
|
||||
},
|
||||
},
|
||||
async (req, reply) => {
|
||||
const hashed = await bcrypt.hash(req.body.password, 10)
|
||||
const user = await fastify.prisma.user.create({
|
||||
data: {
|
||||
username: input.username,
|
||||
username: req.body.username,
|
||||
password: hashed,
|
||||
displayName: input.username,
|
||||
displayName: req.body.username,
|
||||
UserPreferences: {
|
||||
create: {},
|
||||
},
|
||||
},
|
||||
})
|
||||
|
||||
const session = await auth.createSession(user.id, {})
|
||||
const cookie = auth.createSessionCookie(session.id)
|
||||
const session = await fastify.lucia.createSession(user.id, {})
|
||||
const cookie = fastify.lucia.createSessionCookie(session.id)
|
||||
|
||||
reply.setCookie(cookie.name, cookie.value, cookie.attributes)
|
||||
|
||||
return {
|
||||
id: user.id,
|
||||
username: user.username,
|
||||
displayName: user.displayName,
|
||||
displayName: user.username,
|
||||
createdAt: user.createdAt.toISOString(),
|
||||
}
|
||||
}
|
||||
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 },
|
||||
fastify.post(
|
||||
'/auth/login',
|
||||
{
|
||||
schema: {
|
||||
summary: 'Login',
|
||||
tags: ['Auth'],
|
||||
operationId: 'auth.login',
|
||||
body: Type.Object({
|
||||
username: Type.String({ minLength: 1 }),
|
||||
password: Type.String({ minLength: 1 }),
|
||||
}),
|
||||
response: {
|
||||
200: UserSchema,
|
||||
},
|
||||
},
|
||||
config: {
|
||||
skipAuth: true,
|
||||
},
|
||||
},
|
||||
async (req, reply) => {
|
||||
const user = await fastify.prisma.user.findFirst({
|
||||
where: { username: req.body.username },
|
||||
select: {
|
||||
id: true,
|
||||
username: true,
|
||||
displayName: true,
|
||||
createdAt: true,
|
||||
password: true,
|
||||
},
|
||||
})
|
||||
|
||||
if (!user) {
|
||||
return reply.code(404).send({ error: 'Incorrect username or password' })
|
||||
return reply.notFound('Incorrect username or password')
|
||||
}
|
||||
|
||||
const validPassword = await bcrypt.compare(input.password, user.password)
|
||||
const validPassword = await bcrypt.compare(req.body.password, user.password)
|
||||
if (!validPassword) {
|
||||
return reply.code(404).send({ error: 'Incorrect username or password' })
|
||||
return reply.notFound('Incorrect username or password')
|
||||
}
|
||||
|
||||
const session = await auth.createSession(user.id, {})
|
||||
const cookie = auth.createSessionCookie(session.id)
|
||||
const session = await fastify.lucia.createSession(user.id, {})
|
||||
const cookie = fastify.lucia.createSessionCookie(session.id)
|
||||
|
||||
reply.setCookie(cookie.name, cookie.value, cookie.attributes)
|
||||
|
||||
return {
|
||||
...user,
|
||||
createdAt: user.createdAt.toISOString(),
|
||||
}
|
||||
},
|
||||
)
|
||||
|
||||
fastify.get(
|
||||
'/auth/me',
|
||||
{
|
||||
schema: {
|
||||
summary: 'Me',
|
||||
tags: ['Auth'],
|
||||
operationId: 'auth.me',
|
||||
response: {
|
||||
200: UserSchema,
|
||||
},
|
||||
},
|
||||
},
|
||||
async (req) => {
|
||||
const user = req.user!
|
||||
|
||||
return {
|
||||
id: user.id,
|
||||
username: user.username,
|
||||
displayName: user.displayName,
|
||||
createdAt: user.createdAt.toISOString(),
|
||||
}
|
||||
}
|
||||
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 {
|
||||
fastify.post(
|
||||
'/auth/logout',
|
||||
{
|
||||
schema: {
|
||||
summary: 'Logout',
|
||||
tags: ['Auth'],
|
||||
operationId: 'auth.logout',
|
||||
},
|
||||
},
|
||||
async (req, reply) => {
|
||||
if (req.session)
|
||||
await auth.invalidateSession(req.session.id)
|
||||
await fastify.lucia.invalidateSession(req.session.id)
|
||||
|
||||
const blank = auth.createBlankSessionCookie()
|
||||
const blank = fastify.lucia.createBlankSessionCookie()
|
||||
|
||||
reply.setCookie(blank.name, blank.value, blank.attributes)
|
||||
|
||||
return true
|
||||
}
|
||||
catch (err) {
|
||||
fastify.log.error(err)
|
||||
reply.code(400).send({ error: err.message })
|
||||
}
|
||||
})
|
||||
},
|
||||
)
|
||||
}
|
||||
|
||||
export default plugin
|
||||
|
||||
Reference in New Issue
Block a user