|
| 1 | +// Login with email/password and issue a custom API key via /key |
| 2 | +// Env required: |
| 3 | +// SUPABASE_URL=https://<ref>.supabase.co |
| 4 | +// SUPABASE_ANON_KEY=... |
| 5 | +// EMAIL=user@example.com |
| 6 | +// PASSWORD=secret |
| 7 | +// BASE_URL=https://<ref>.functions.supabase.co # backend base (no /openai) |
| 8 | +// Usage: |
| 9 | +// deno run -A backend/scripts/issue_custom_key.ts |
| 10 | + |
| 11 | +const supaUrl = Deno.env.get('SUPABASE_URL'); |
| 12 | +const anonKey = Deno.env.get('SUPABASE_ANON_KEY'); |
| 13 | +const email = Deno.env.get('EMAIL'); |
| 14 | +const password = Deno.env.get('PASSWORD'); |
| 15 | +const base = (Deno.env.get('BASE_URL') || '').replace(/\/$/, ''); |
| 16 | + |
| 17 | +if (!supaUrl || !anonKey || !email || !password || !base) { |
| 18 | + console.error('Missing env. Need SUPABASE_URL, SUPABASE_ANON_KEY, EMAIL, PASSWORD, BASE_URL'); |
| 19 | + Deno.exit(1); |
| 20 | +} |
| 21 | + |
| 22 | +const tokenEndpoint = `${supaUrl.replace(/\/$/, '')}/auth/v1/token?grant_type=password`; |
| 23 | +const authRes = await fetch(tokenEndpoint, { |
| 24 | + method: 'POST', |
| 25 | + headers: { 'Content-Type': 'application/json', apikey: anonKey }, |
| 26 | + body: JSON.stringify({ email, password }), |
| 27 | +}); |
| 28 | +if (!authRes.ok) { |
| 29 | + console.error('Auth failed:', authRes.status, await authRes.text()); |
| 30 | + Deno.exit(1); |
| 31 | +} |
| 32 | +const auth = await authRes.json(); |
| 33 | +const accessToken: string | undefined = auth?.access_token; |
| 34 | +const userId: string | undefined = auth?.user?.id; |
| 35 | +if (!accessToken) { |
| 36 | + console.error('No access_token in auth response'); |
| 37 | + console.log(JSON.stringify(auth, null, 2)); |
| 38 | + Deno.exit(1); |
| 39 | +} |
| 40 | +console.log('Logged in as:', userId || '(unknown)'); |
| 41 | + |
| 42 | +// Attempt to issue a new custom API key |
| 43 | +const keyEndpoint = `${base}/key`; |
| 44 | +const keyRes = await fetch(keyEndpoint, { |
| 45 | + method: 'POST', |
| 46 | + headers: { 'Content-Type': 'application/json', Authorization: `Bearer ${accessToken}` }, |
| 47 | +}); |
| 48 | + |
| 49 | +const bodyText = await keyRes.text(); |
| 50 | +if (keyRes.status === 402) { |
| 51 | + console.error('Subscription required to issue API key.'); |
| 52 | + console.error('Tip: activate a test subscription via backend/scripts/activate_subscription.ts'); |
| 53 | + Deno.exit(2); |
| 54 | +} |
| 55 | +if (!keyRes.ok) { |
| 56 | + console.error('Issuing key failed:', keyRes.status, bodyText); |
| 57 | + Deno.exit(1); |
| 58 | +} |
| 59 | + |
| 60 | +try { |
| 61 | + const data = JSON.parse(bodyText); |
| 62 | + if (data?.key && data?.prefix) { |
| 63 | + console.log('Issued custom API key:'); |
| 64 | + console.log('KEY=', data.key); |
| 65 | + console.log('PREFIX=', data.prefix); |
| 66 | + } else { |
| 67 | + console.log('Response:', data); |
| 68 | + } |
| 69 | +} catch { |
| 70 | + console.log('Response (raw):', bodyText); |
| 71 | +} |
| 72 | + |
0 commit comments