61 lines
2.0 KiB
JavaScript
61 lines
2.0 KiB
JavaScript
|
|
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);
|
||
|
|
}
|
||
|
|
);
|
||
|
|
}
|