Skip to content

Commit 1301abc

Browse files
authored
fix(api): allow CORS preflight for stats export (#1601)
1 parent 60dc4b8 commit 1301abc

File tree

2 files changed

+24
-1
lines changed

2 files changed

+24
-1
lines changed

supabase/functions/_backend/private/stats.ts

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -73,7 +73,9 @@ const exportSchema = z.object({
7373

7474
export const app = new Hono<MiddlewareKeyVariables>()
7575

76-
app.use('/', useCors)
76+
// Browser clients call this endpoint and require CORS preflight (OPTIONS).
77+
// Use '*' so it also applies to sub-routes like '/export'.
78+
app.use('*', useCors)
7779

7880
app.post('/', middlewareV2(['read', 'write', 'all', 'upload']), async (c) => {
7981
const body = await parseBody<DataStats>(c)

tests/stats-export-cors.test.ts

Lines changed: 21 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,21 @@
1+
import { describe, expect, it } from 'vitest'
2+
3+
import { app } from '../supabase/functions/_backend/private/stats.ts'
4+
5+
describe('[OPTIONS] /private/stats/export', () => {
6+
it('responds to CORS preflight', async () => {
7+
const res = await app.request('http://local/export', {
8+
method: 'OPTIONS',
9+
headers: {
10+
'origin': 'http://localhost:5173',
11+
'access-control-request-method': 'POST',
12+
'access-control-request-headers': 'content-type,authorization',
13+
},
14+
})
15+
16+
expect(res.status).toBe(204)
17+
expect(res.headers.get('access-control-allow-origin')).toBe('*')
18+
expect(res.headers.get('access-control-allow-methods')).toContain('OPTIONS')
19+
expect(res.headers.get('access-control-allow-headers')?.toLowerCase()).toContain('authorization')
20+
})
21+
})

0 commit comments

Comments
 (0)