Files
web-cad/backend/src/routes/auth.ts
T

83 lines
2.9 KiB
TypeScript
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
/**
* Auth Routes Registration, Login, Logout, Profile
*/
import type { FastifyInstance } from 'fastify';
import type { AuthService } from '../auth/AuthService.js';
export function registerAuthRoutes(fastify: FastifyInstance, authService: AuthService) {
// Register new user
fastify.post('/api/auth/register', async (request, reply) => {
const { email, password, name, role } = request.body as {
email?: string; password?: string; name?: string; role?: string;
};
if (!email || !password || !name) {
return reply.code(400).send({ error: 'Email, password and name are required' });
}
try {
const result = await authService.register(email, password, name, role);
return reply.code(201).send(result);
} catch (err: any) { return reply.code(409).send({ error: err.message });
}
});
// Login
fastify.post('/api/auth/login', async (request, reply) => {
const { email, password } = request.body as { email?: string; password?: string };
if (!email || !password) {
return reply.code(400).send({ error: 'Email and password are required' });
}
try {
const result = await authService.login(email, password);
return reply.send(result);
} catch {
return reply.code(401).send({ error: 'Invalid credentials' });
}
});
// Logout
fastify.post('/api/auth/logout', async (request, reply) => {
const token = extractToken(request);
if (token) {
authService.destroySession(token);
}
return reply.code(204).send();
});
// Get current user profile
fastify.get('/api/auth/me', async (request, reply) => {
const token = extractToken(request);
if (!token) return reply.code(401).send({ error: 'Not authenticated' });
const user = authService.getUserFromSession(token);
if (!user) return reply.code(401).send({ error: 'Invalid or expired session' });
const { password_hash, ...safe } = user;
return safe;
});
// Change password
fastify.patch('/api/auth/password', async (request, reply) => {
const token = extractToken(request);
if (!token) return reply.code(401).send({ error: 'Not authenticated' });
const user = authService.getUserFromSession(token);
if (!user) return reply.code(401).send({ error: 'Invalid or expired session' });
const { oldPassword, newPassword } = request.body as { oldPassword?: string; newPassword?: string };
if (!oldPassword || !newPassword) {
return reply.code(400).send({ error: 'oldPassword and newPassword are required' });
}
try {
await authService.changePassword(user.id, oldPassword, newPassword);
return reply.code(204).send();
} catch (err: any) {
return reply.code(400).send({ error: err.message });
}
});
}
function extractToken(request: any): string | null {
const auth = request.headers?.authorization;
if (auth && auth.startsWith('Bearer ')) {
return auth.slice(7);
}
return null;
}