Files
Cozy-Den/src/lib/auth.ts
T

74 lines
1.9 KiB
TypeScript

import { createHash, randomBytes } from 'node:crypto';
import db from './db';
function getSecretKey(): string {
const key = process.env.SECRET_KEY;
if (!key) throw new Error('SECRET_KEY environment variable is required');
return key;
}
export function hashIP(ip: string): string {
return createHash('sha256').update(getSecretKey() + ':' + ip).digest('hex').slice(0, 16);
}
export function generateId(): string {
return randomBytes(32).toString('hex');
}
export interface AdminSession {
id: string;
user_id: string;
created_at: string;
expires_at: string;
}
export function createSession(userId: string): string {
const sessionId = generateId();
const expiresAt = new Date(Date.now() + 24 * 60 * 60 * 1000).toISOString();
db.prepare(
`INSERT INTO admin_sessions (id, user_id, expires_at) VALUES (?, ?, ?)`
).run(sessionId, userId, expiresAt);
return sessionId;
}
export function getSession(sessionId: string): AdminSession | undefined {
return db
.prepare(
`SELECT * FROM admin_sessions
WHERE id = ? AND expires_at > strftime('%Y-%m-%dT%H:%M:%SZ', 'now')`
)
.get(sessionId) as AdminSession | undefined;
}
export function deleteSession(sessionId: string): void {
db.prepare(`DELETE FROM admin_sessions WHERE id = ?`).run(sessionId);
}
export function cleanExpiredSessions(): void {
db.prepare(
`DELETE FROM admin_sessions WHERE expires_at <= strftime('%Y-%m-%dT%H:%M:%SZ', 'now')`
).run();
}
export const SESSION_COOKIE = 'admin_session';
function shouldUseSecureCookies(): boolean {
const secureOverride = process.env.COOKIE_SECURE?.trim().toLowerCase();
if (secureOverride === 'true') return true;
if (secureOverride === 'false') return false;
return process.env.NODE_ENV === 'production';
}
export function sessionCookieOptions(maxAge: number) {
return {
httpOnly: true,
secure: shouldUseSecureCookies(),
sameSite: 'strict' as const,
path: '/',
maxAge,
};
}