feat: initial commit web-cad-neu with docker-compose, frontend and backend
This commit is contained in:
@@ -0,0 +1,82 @@
|
||||
/**
|
||||
* 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;
|
||||
}
|
||||
Reference in New Issue
Block a user