fix(studio): send new API keys on apikey header in edge function invoke snippet

This commit is contained in:
Tomas Pozo committed 2026-06-04 11:00:44 -05:00
1 parent a776b54863
commit 276a60cdf0
3 files changed
+52 -5

No files matched your search

@@ -0,0 +1,40 @@
import { describe, expect, it } from 'vitest'
import { INVOCATION_TABS } from './EdgeFunctionDetails.constants'
const curlTab = INVOCATION_TABS.find((tab) => tab.id === 'curl')!
const baseProps = {
showKey: true,
functionUrl: 'https://project-ref.supabase.co/functions/v1/health',
functionName: 'health',
}
describe('cURL invocation snippet', () => {
it('sends a publishable key on the apikey header, not Authorization', () => {
const code = curlTab.code({ ...baseProps, apiKey: 'sb_publishable_abc123' })
expect(code).toContain("-H 'apikey: sb_publishable_abc123'")
expect(code).not.toContain('Authorization')
})
it('sends a legacy anon key on the Authorization header, not apikey', () => {
const anonJwt = 'eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.anon'
const code = curlTab.code({ ...baseProps, apiKey: anonJwt })
expect(code).toContain(`-H 'Authorization: Bearer ${anonJwt}'`)
expect(code).not.toContain('apikey:')
})
it('obfuscates the key name when showKey is false', () => {
const publishable = curlTab.code({
...baseProps,
showKey: false,
apiKey: 'sb_publishable_abc123',
})
expect(publishable).toContain("-H 'apikey: SUPABASE_PUBLISHABLE_KEY'")
const anon = curlTab.code({ ...baseProps, showKey: false, apiKey: 'eyJ.anon' })
expect(anon).toContain("-H 'Authorization: Bearer SUPABASE_ANON_KEY'")
})
})
@@ -17,13 +17,19 @@ export const INVOCATION_TABS: InvocationTab[] = [
label: 'cURL',
language: 'bash',
code: ({ showKey, functionUrl, apiKey }) => {
const obfuscatedName = apiKey.includes('publishable')
? 'SUPABASE_PUBLISHABLE_KEY'
: 'SUPABASE_ANON_KEY'
const isPublishableKey = apiKey.includes('publishable')
const obfuscatedName = isPublishableKey ? 'SUPABASE_PUBLISHABLE_KEY' : 'SUPABASE_ANON_KEY'
const keyValue = showKey ? apiKey : obfuscatedName
// Publishable and secret keys aren't JWTs, so they must be sent on the `apikey`
// header. Passing them on `Authorization: Bearer` makes the platform reject the
// request with `Invalid JWT`. Legacy `anon` keys are JWTs and use `Authorization`.
const authHeader = isPublishableKey
? `-H 'apikey: ${keyValue}'`
: `-H 'Authorization: Bearer ${keyValue}'`
return `curl -L -X POST '${functionUrl}' \\
-H 'Authorization: Bearer ${keyValue}' \\${apiKey.includes('publishable') ? `\n -H 'apikey: ${keyValue}' \\` : ''}
${authHeader} \\
-H 'Content-Type: application/json' \\
--data '{"name":"Functions"}'`
},
@@ -101,6 +101,7 @@ export const EdgeFunctionDetails = () => {
const { anonKey, publishableKey } = getKeys(apiKeys)
const apiKey = publishableKey?.api_key ?? anonKey?.api_key ?? '[YOUR ANON KEY]'
const apiKeyLabel = publishableKey?.api_key ? 'publishable key' : 'anon key'
const { managementCommands } = generateCLICommands({
selectedFunction,
@@ -263,7 +264,7 @@ export const EdgeFunctionDetails = () => {
className="ml-auto -translate-y-2 translate-x-3"
onClick={() => setShowKey(!showKey)}
>
{showKey ? 'Hide' : 'Show'} anon key
{showKey ? 'Hide' : 'Show'} {apiKeyLabel}
</Button>
)}
</TabsList>