Lines 25-65javascript
25 3 network GET {WEB_BASE}/api/config. The rotation-repair path.
26 4 stale An expired cache beats the literal: it is strictly newer.
27 5 baked The legacy literal. First-ever boot with no network. Never fails.
29 TWO INVARIANTS, both tested in supabase-key.test.mjs:
31 · A service-shaped key is NEVER adopted, from any source. The network is an
32 input we do not control; a compromised or misconfigured config surface
33 must not be able to hand a user's laptop an RLS-bypassing client.
34 · No key material is ever logged. We log the SOURCE and the SHAPE. (C16.) */
36import os from 'node:os'
37import fs from 'node:fs'
38import path from 'node:path'
39import { classifyKey, isClientSafeKey } from './key-shape.mjs'
41export { classifyKey, isClientSafeKey }
43/* The legacy anon key. Public by design (the web bundle ships it), but now a
44 FALLBACK rather than the source of truth. Do not add new readers. */
45export const BAKED_ANON_KEY = 'eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJpc3MiOiJzdXBhYmFzZSIsInJlZiI6ImRheXR2dGFrbWxpeHBmYmJxempkIiwicm9sZSI6ImFub24iLCJpYXQiOjE3NzgwNTMxNzEsImV4cCI6MjA5MzYyOTE3MX0.zYmz8bHUNEY4STUr2JuXChAsKwxNwkwFHe1Hd0Betqo'
CriticalCritical Secret
Package contains a critical-looking secret pattern.
supabase-key.mjsView on unpkg · L45 CriticalSecret Pattern
Supabase service role key (JWT) in supabase-key.mjs
supabase-key.mjsView on unpkg · L45 47export const DEFAULT_SUPABASE_URL = 'https://daytvtakmlixpfbbqzjd.supabase.co'
48export const DEFAULT_WEB_BASE = 'https://thinkpool.io'
50const CACHE_FILE = path.join(os.homedir(), '.thinkpool-pair', 'supabase-key.json')
51const CACHE_TTL_MS = 6 * 60 * 60 * 1000 // 6h — a rotation reaches a rebooting bridge same-day
52const FETCH_TIMEOUT_MS = 2000 // boot latency budget; the literal is right there
54// ── the on-disk cache ──────────────────────────────────────────────────────
55// Sits beside auth.json / dirs.json / served.json in ~/.thinkpool-pair.
56// Contains no secret (a publishable key), so no chmod dance — unlike auth.json.
57export function readCacheFile() {
59 const rec = JSON.parse(fs.readFileSync(CACHE_FILE, 'utf8'))
60 if (!rec || typeof rec.key !== 'string' || typeof rec.url !== 'string') return null
61 return { key: rec.key, url: rec.url, at: Number(rec.at) || 0 }
62 } catch { return null }
65export function writeCacheFile(rec) {