ANProto over ATProto -- using Bluesky PDSes to store ANProto messages and blobs
at main 2.0 kB view raw
1import type { 2 NodeSavedSession, 3 NodeSavedSessionStore, 4 NodeSavedState, 5 NodeSavedStateStore, 6} from '@atproto/oauth-client-node' 7import { db } from './db' 8 9/** 10 * StateStore: 11 * Stores temporary "state" parameters used during the initial OAuth handshake (authorize -> callback). 12 * This prevents CSRF attacks by ensuring the callback comes from the same flow we started. 13 * These are short-lived and can be deleted after the callback is processed. 14 */ 15export class StateStore implements NodeSavedStateStore { 16 async get(key: string): Promise<NodeSavedState | undefined> { 17 const result = db.prepare('SELECT state FROM auth_state WHERE key = ?').get(key) as { state: string } | undefined 18 if (!result) return 19 return JSON.parse(result.state) as NodeSavedState 20 } 21 async set(key: string, val: NodeSavedState) { 22 const state = JSON.stringify(val) 23 db.prepare(` 24 INSERT INTO auth_state (key, state) VALUES (?, ?) 25 ON CONFLICT(key) DO UPDATE SET state = excluded.state 26 `).run(key, state) 27 } 28 async del(key: string) { 29 db.prepare('DELETE FROM auth_state WHERE key = ?').run(key) 30 } 31} 32 33/** 34 * SessionStore: 35 * Persists the long-term OAuth session data (Access Token, Refresh Token, DID). 36 * This allows the user to stay logged in even if the server restarts. 37 * Keys are usually mapped to the user's DID. 38 */ 39export class SessionStore implements NodeSavedSessionStore { 40 async get(key: string): Promise<NodeSavedSession | undefined> { 41 const result = db.prepare('SELECT session FROM auth_session WHERE key = ?').get(key) as { session: string } | undefined 42 if (!result) return 43 return JSON.parse(result.session) as NodeSavedSession 44 } 45 async set(key: string, val: NodeSavedSession) { 46 const session = JSON.stringify(val) 47 db.prepare(` 48 INSERT INTO auth_session (key, session) VALUES (?, ?) 49 ON CONFLICT(key) DO UPDATE SET session = excluded.session 50 `).run(key, session) 51 } 52 async del(key: string) { 53 db.prepare('DELETE FROM auth_session WHERE key = ?').run(key) 54 } 55}