Skip to content

Commit 6ca8e6a

Browse files
committed
feat: implement secure backend proxy with Supabase Edge Functions
- Add generate-prompt Edge Function to prevent API key exposure - Move AI API calls from frontend to secure backend - Configure Deno runtime with TypeScript support - Add CORS headers for cross-origin requests - Implement fallback from Gemini to OpenRouter - Store API keys in Supabase Vault instead of frontend bundle
1 parent 4e9aaa1 commit 6ca8e6a

File tree

2 files changed

+27
-2
lines changed

2 files changed

+27
-2
lines changed

supabase/functions/deno.json

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,9 @@
1+
{
2+
"compilerOptions": {
3+
"strict": true,
4+
"lib": ["deno.window"]
5+
},
6+
"imports": {
7+
"std/": "https://deno.land/[email protected]/"
8+
}
9+
}

supabase/functions/generate-prompt/index.ts

Lines changed: 18 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,7 @@ import { serve } from 'https://deno.land/[email protected]/http/server.ts'
33
const GEMINI_API_KEY = Deno.env.get('GEMINI_API_KEY')
44
const OPENROUTER_API_KEY = Deno.env.get('OPENROUTER_API_KEY')
55

6-
serve(async (req) => {
6+
serve(async (req: Request) => {
77
// CORS headers
88
const corsHeaders = {
99
'Access-Control-Allow-Origin': '*',
@@ -51,9 +51,25 @@ serve(async (req) => {
5151
return new Response(JSON.stringify({ text, model: 'gemini' }), {
5252
headers: { ...corsHeaders, 'Content-Type': 'application/json' },
5353
})
54+
} else {
55+
const errorData = await response.text()
56+
console.error('Gemini API error:', response.status, errorData)
57+
58+
return new Response(JSON.stringify({
59+
error: `Gemini API failed: ${response.status} - ${errorData}`
60+
}), {
61+
status: 500,
62+
headers: { ...corsHeaders, 'Content-Type': 'application/json' },
63+
})
5464
}
5565
} catch (error) {
5666
console.error('Gemini error:', error)
67+
return new Response(JSON.stringify({
68+
error: `Gemini request failed: ${error instanceof Error ? error.message : 'Unknown error'}`
69+
}), {
70+
status: 500,
71+
headers: { ...corsHeaders, 'Content-Type': 'application/json' },
72+
})
5773
}
5874
}
5975

@@ -89,7 +105,7 @@ serve(async (req) => {
89105
})
90106

91107
} catch (error) {
92-
return new Response(JSON.stringify({ error: error.message }), {
108+
return new Response(JSON.stringify({ error: error instanceof Error ? error.message : 'Unknown error' }), {
93109
status: 500,
94110
headers: { ...corsHeaders, 'Content-Type': 'application/json' },
95111
})

0 commit comments

Comments
 (0)