51 lines
2.0 KiB
JavaScript
51 lines
2.0 KiB
JavaScript
import { z } from 'zod';
|
|
import { prisma } from '../index.js';
|
|
import crypto from 'crypto';
|
|
const userSchema = z.object({
|
|
username: z.string().min(3).max(50),
|
|
password: z.string().min(6).max(100),
|
|
});
|
|
function hashPassword(password) {
|
|
return crypto.createHash('sha256').update(password).digest('hex');
|
|
}
|
|
export async function authRoutes(fastify) {
|
|
fastify.post('/register', async (request, reply) => {
|
|
const result = userSchema.safeParse(request.body);
|
|
if (!result.success) {
|
|
return reply.status(400).send({ error: 'Invalid input', details: result.error.errors });
|
|
}
|
|
const { username, password } = result.data;
|
|
const existing = await prisma.user.findUnique({ where: { username } });
|
|
if (existing) {
|
|
return reply.status(409).send({ error: 'Username already exists' });
|
|
}
|
|
const user = await prisma.user.create({
|
|
data: {
|
|
username,
|
|
password: hashPassword(password),
|
|
},
|
|
});
|
|
const token = fastify.jwt.sign({ id: user.id, username: user.username });
|
|
return { token, user: { id: user.id, username: user.username } };
|
|
});
|
|
fastify.post('/login', async (request, reply) => {
|
|
const result = userSchema.safeParse(request.body);
|
|
if (!result.success) {
|
|
return reply.status(400).send({ error: 'Invalid input' });
|
|
}
|
|
const { username, password } = result.data;
|
|
const user = await prisma.user.findUnique({ where: { username } });
|
|
if (!user || user.password !== hashPassword(password)) {
|
|
return reply.status(401).send({ error: 'Invalid credentials' });
|
|
}
|
|
const token = fastify.jwt.sign({ id: user.id, username: user.username });
|
|
return { token, user: { id: user.id, username: user.username } };
|
|
});
|
|
fastify.get('/me', {
|
|
onRequest: [fastify.authenticate],
|
|
}, async (request) => {
|
|
const user = request.user;
|
|
return { id: user.id, username: user.username };
|
|
});
|
|
}
|