fabro/apps/arc-web/app/lib/db.server.ts
Bryan Helmkamp 1fd9a8ebfe SQLite-backed sessions with GitHub email and app manifest fix
Replace cookie-based sessions with SQLite-backed storage using
better-sqlite3 and React Router's createSessionStorage. Sessions are
now stored in ~/.arc/arc-web.db with a session ID cookie, enabling
larger payloads and server-side revocation.

- Add db.server.ts (lazy singleton, WAL mode, web_sessions table)
- Add session-storage.server.ts (CRUD ops, probabilistic cleanup)
- Fetch primary verified email from /user/emails during OAuth
- Add emails:read to GitHub App manifest default_permissions
- Expand session data: userUrl, githubId, githubNodeId, email
- Default ARC_API_BASE_URL to localhost:3000
- Whitelist better-sqlite3 in trustedDependencies
- Externalize better-sqlite3 from Vite SSR bundling

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-03-02 21:05:59 -05:00

29 lines
792 B
TypeScript

import Database from "better-sqlite3";
import path from "node:path";
import os from "node:os";
import fs from "node:fs";
let db: Database.Database | null = null;
export function getDatabase(): Database.Database {
if (db) return db;
const arcDir = path.join(os.homedir(), ".arc");
fs.mkdirSync(arcDir, { recursive: true });
db = new Database(path.join(arcDir, "arc-web.db"));
db.pragma("journal_mode = WAL");
db.exec(`
CREATE TABLE IF NOT EXISTS web_sessions (
id TEXT PRIMARY KEY,
user_url TEXT NOT NULL,
data TEXT NOT NULL,
expires_at INTEGER
);
CREATE INDEX IF NOT EXISTS idx_web_sessions_user_url ON web_sessions (user_url);
CREATE INDEX IF NOT EXISTS idx_web_sessions_expires_at ON web_sessions (expires_at);
`);
return db;
}