The Appview for the kipclip.com atproto bookmarking service

Fix OAuth state validation by enabling int64 mode in local SQLite

JavaScript timestamps (milliseconds since epoch) are larger than 32-bit integers can hold.
Without int64 mode, Deno SQLite truncates these to signed 32-bit values, causing negative timestamps.

This caused OAuth state lookups to fail because DrizzleStorage's expiration check (expires_at > now)
would compare negative values against current timestamps.

Solution: Enable int64 mode in Database constructor to properly store 64-bit INTEGER values.

Also improved DEVELOPMENT.md OAuth setup instructions.

+13 -4
+10 -3
DEVELOPMENT.md
··· 11 11 - ✅ **Database** - Local SQLite with migrations 12 12 - ⚠️ **OAuth Flow** - Requires public URL (see below) 13 13 14 - ### OAuth Limitations 14 + ### OAuth Setup with ngrok 15 15 16 16 ATProto OAuth requires a **publicly accessible** client metadata URL. For local 17 - development: 17 + development, use ngrok to expose your local server: 18 18 19 - **Option 1: Use ngrok (recommended for full OAuth testing)** 19 + **Setup Steps:** 20 20 21 21 ```bash 22 22 # In terminal 1: Start dev server ··· 27 27 28 28 # Update .env with ngrok URL 29 29 BASE_URL=https://your-random-id.ngrok.io 30 + 31 + # Restart dev server to pick up new BASE_URL 32 + # Ctrl+C in terminal 1, then: 33 + deno task dev 30 34 ``` 35 + 36 + **Important:** Always restart the dev server after changing `BASE_URL` in `.env` 37 + so OAuth redirects work correctly. 31 38 32 39 **Option 2: Mock authentication (recommended for API development)** 33 40
+3 -1
backend/database/local-sqlite.ts
··· 34 34 } 35 35 } 36 36 37 - const db = new Database(dbPath); 37 + // Create database with int64 mode to handle JavaScript timestamps (> 2^31) 38 + // Without this, timestamps get truncated to 32-bit signed integers 39 + const db = new Database(dbPath, { int64: true }); 38 40 39 41 return { 40 42 /**