feat: T27 AuthService DB session persistence - replace in-memory Map with SQLite sessions table

This commit is contained in:
2026-06-26 14:55:38 +02:00
parent 04271d4cbd
commit 1d6c2cb30e
4 changed files with 59 additions and 17 deletions
+23 -1
View File
@@ -5,9 +5,10 @@ import Database from 'better-sqlite3';
import { readFileSync } from 'fs';
import { join, dirname } from 'path';
import { fileURLToPath } from 'url';
import { randomUUID } from 'crypto';
import type {
DatabaseInterface, DBProject, DBDrawing, DBLayer,
DBElement, DBBlock, DBSetting, DBUser,
DBElement, DBBlock, DBSetting, DBUser, DBSession,
} from './DatabaseInterface.js';
const __dirname = dirname(fileURLToPath(import.meta.url));
@@ -243,4 +244,25 @@ export class SqliteAdapter implements DatabaseInterface {
"INSERT INTO settings (key, value, updated_at) VALUES (?, ?, datetime('now')) ON CONFLICT(key) DO UPDATE SET value = excluded.value, updated_at = datetime('now')",
).run(key, value);
}
// ─── Sessions ───────────────────────────────────────
createSession(data: Partial<DBSession>): DBSession {
const token = data.token ?? randomUUID();
this.db.prepare(
'INSERT INTO sessions (token, user_id, expires_at) VALUES (?, ?, ?)',
).run(token, data.user_id!, data.expires_at!);
return this.getSession(token)!;
}
getSession(token: string): DBSession | null {
return (this.db.prepare('SELECT * FROM sessions WHERE token = ?').get(token) as DBSession) ?? null;
}
deleteSession(token: string): boolean {
return this.db.prepare('DELETE FROM sessions WHERE token = ?').run(token).changes > 0;
}
deleteExpiredSessions(): void {
this.db.prepare('DELETE FROM sessions WHERE expires_at < ?').run(Date.now());
}
}