zappier-edge/src/db/session-repo.ts

51 lines
1.6 KiB
TypeScript

import Database from 'better-sqlite3';
import { newSessionToken, PortalSession, SessionRepo } from '../accounts';
/** SQLite-backed portal sessions; survives server restarts. */
export class SqliteSessionRepo implements SessionRepo {
constructor(private db: Database.Database) {
this.db.exec(`
CREATE TABLE IF NOT EXISTS portal_sessions (
token TEXT PRIMARY KEY,
customer_id TEXT NOT NULL,
created_ms INTEGER NOT NULL,
expires_ms INTEGER NOT NULL
)
`);
}
create(customerId: string, ttlMs: number): PortalSession {
const now = Date.now();
const session: PortalSession = {
token: newSessionToken(),
customerId,
createdMs: now,
expiresMs: now + ttlMs,
};
this.db
.prepare(
'INSERT INTO portal_sessions (token, customer_id, created_ms, expires_ms) VALUES (?, ?, ?, ?)',
)
.run(session.token, session.customerId, session.createdMs, session.expiresMs);
return session;
}
get(token: string, nowMs = Date.now()): PortalSession | undefined {
const r = this.db
.prepare('SELECT * FROM portal_sessions WHERE token = ?')
.get(token) as
| { token: string; customer_id: string; created_ms: number; expires_ms: number }
| undefined;
if (!r || r.expires_ms <= nowMs) return undefined;
return {
token: r.token,
customerId: r.customer_id,
createdMs: r.created_ms,
expiresMs: r.expires_ms,
};
}
delete(token: string): void {
this.db.prepare('DELETE FROM portal_sessions WHERE token = ?').run(token);
}
}