46 lines
1.4 KiB
TypeScript
46 lines
1.4 KiB
TypeScript
if (process.env.NODE_ENV !== "test")
|
|
require("server-only");
|
|
import crypto from "node:crypto";
|
|
import bcrypt from "bcryptjs";
|
|
import getPool from "@/lib/server/db";
|
|
|
|
const defaultSessionDays = 30;
|
|
|
|
export function getSessionCookieName() {
|
|
return process.env.SESSION_COOKIE_NAME || "fiddy_session";
|
|
}
|
|
|
|
export function getSessionTtlMs() {
|
|
const days = Number(process.env.SESSION_TTL_DAYS || defaultSessionDays);
|
|
return Math.max(1, days) * 24 * 60 * 60 * 1000;
|
|
}
|
|
|
|
export function hashToken(token: string) {
|
|
return crypto.createHash("sha256").update(token).digest("hex");
|
|
}
|
|
|
|
export function createSessionToken() {
|
|
return crypto.randomBytes(32).toString("hex");
|
|
}
|
|
|
|
export async function hashPassword(password: string) {
|
|
return bcrypt.hash(password, 12);
|
|
}
|
|
|
|
export async function verifyPassword(password: string, hash: string) {
|
|
return bcrypt.compare(password, hash);
|
|
}
|
|
|
|
export async function createSession(userId: number, options?: { ttlMs?: number }) {
|
|
const token = createSessionToken();
|
|
const tokenHash = hashToken(token);
|
|
const ttlMs = options?.ttlMs ?? getSessionTtlMs();
|
|
const expiresAt = new Date(Date.now() + ttlMs);
|
|
const pool = getPool();
|
|
await pool.query(
|
|
"insert into sessions(user_id, token_hash, expires_at) values($1,$2,$3)",
|
|
[userId, tokenHash, expiresAt]
|
|
);
|
|
return { token, expiresAt, ttlMs };
|
|
}
|