public
anord
read
Ledger
Why work hard when you can work easier?
Languages
Repository composition by tracked source files.
TypeScript
86%
CSS
10%
SQL
3%
Shell
1%
HTML
0%
Trace
apps/api/src/services/auth.ts
Trace helps you understand code history line by line. See who changed each line, when it changed, and which commit introduced it.
Author
Date
Commit
Line
Code
1
import bcrypt from "bcryptjs";
2
import jwt from "jsonwebtoken";
3
import type { SessionUser } from "@ledger/shared";
4
import { env } from "../config/env.js";
5
import { pool } from "../db/pool.js";
7
export async function hashPassword(password: string): Promise<string> {
8
return bcrypt.hash(`${password}${env.PASSWORD_PEPPER}`, 12);
9
}
11
export async function verifyPassword(password: string, hash: string): Promise<boolean> {
12
return bcrypt.compare(`${password}${env.PASSWORD_PEPPER}`, hash);
13
}
15
export function createSessionToken(user: SessionUser): string {
16
return jwt.sign(user, env.JWT_SECRET, { expiresIn: "7d" });
17
}
19
export function verifySessionToken(token: string): SessionUser {
20
return jwt.verify(token, env.JWT_SECRET) as SessionUser;
21
}
23
export async function getUserForSession(userId: string): Promise<SessionUser | null> {
24
const result = await pool.query(
25
`
26
SELECT
27
u.id,
28
u.email,
29
u.display_name,
30
r.key AS role_key,
31
COALESCE(array_agg(gm.group_id) FILTER (WHERE gm.group_id IS NOT NULL), '{}') AS group_ids
32
FROM users u
33
JOIN roles r ON r.id = u.primary_role_id
34
LEFT JOIN group_memberships gm ON gm.user_id = u.id
35
WHERE u.id = $1 AND u.is_active = true
36
GROUP BY u.id, r.key
37
`,
38
[userId]
39
);
41
if (!result.rowCount) {
42
return null;
43
}
45
const row = result.rows[0];
46
return {
47
id: row.id,
48
email: row.email,
49
displayName: row.display_name,
50
role: row.role_key,
51
groupIds: row.group_ids
52
};
53
}