import { hashPassword, verifyPassword } from "../lib/auth.js"; import { httpError } from "../lib/httpErrors.js"; import { userRowToDto } from "../lib/rows.js"; export async function authRoutes(app) { app.post("/auth/register", async (req) => { const { email, password } = req.body || {}; if (!email || !password) throw httpError(400, "email and password required"); if (String(password).length < 8) throw httpError(400, "password too short"); const passwordHash = await hashPassword(password); try { const res = await app.pg.query( "insert into users (email, password_hash) values ($1, $2) returning id, email, role, created_at, updated_at", [email, passwordHash] ); const user = userRowToDto(res.rows[0]); const token = await app.jwt.sign({ sub: user.id, role: user.role }); return { token, user }; } catch (err) { if (String(err?.code) === "23505") throw httpError(409, "email already exists"); throw err; } }); app.post("/auth/login", async (req) => { const { email, password } = req.body || {}; if (!email || !password) throw httpError(400, "email and password required"); const res = await app.pg.query( "select id, email, role, password_hash, created_at, updated_at from users where email=$1", [email] ); const row = res.rows[0]; if (!row) throw httpError(401, "invalid credentials"); const ok = await verifyPassword(password, row.password_hash); if (!ok) throw httpError(401, "invalid credentials"); const user = userRowToDto(row); const token = await app.jwt.sign({ sub: user.id, role: user.role }); return { token, user }; }); app.get( "/auth/me", { preHandler: [app.authenticate] }, async (req) => { const userId = req.user.sub; const res = await app.pg.query( "select id, email, role, created_at, updated_at from users where id=$1", [userId] ); const row = res.rows[0]; if (!row) throw httpError(404, "user not found"); return userRowToDto(row); } ); }