File size: 4,358 Bytes
1f21206 | 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 | import { describe, expect, it } from 'bun:test'
import { corsHeaders, resolveCors } from './cors'
describe('corsHeaders', () => {
it('allows localhost browser origins', () => {
expect(corsHeaders('http://127.0.0.1:1420')['Access-Control-Allow-Origin']).toBe('http://127.0.0.1:1420')
expect(corsHeaders('http://localhost:3000')['Access-Control-Allow-Origin']).toBe('http://localhost:3000')
})
it('allows tauri webview origins used in production builds', () => {
expect(corsHeaders('http://tauri.localhost')['Access-Control-Allow-Origin']).toBe('http://tauri.localhost')
expect(corsHeaders('https://tauri.localhost')['Access-Control-Allow-Origin']).toBe('https://tauri.localhost')
expect(corsHeaders('tauri://localhost')['Access-Control-Allow-Origin']).toBe('tauri://localhost')
})
it('allows arbitrary origins while H5 access is open', () => {
expect(corsHeaders('https://example.com')['Access-Control-Allow-Origin']).toBe('https://example.com')
expect(corsHeaders(null)['Access-Control-Allow-Origin']).toBe('http://localhost:3000')
})
})
describe('resolveCors', () => {
it('allows arbitrary origins when H5 token mode is inactive', async () => {
const result = await resolveCors('https://example.com', 'http://127.0.0.1:3456')
expect(result).toEqual({
allowed: true,
rejected: false,
headers: {
'Access-Control-Allow-Origin': 'https://example.com',
'Access-Control-Allow-Methods': 'GET, POST, PUT, PATCH, DELETE, OPTIONS',
'Access-Control-Allow-Headers': 'Content-Type, Authorization',
'Access-Control-Max-Age': '86400',
Vary: 'Origin',
},
})
})
it('rejects blocked browser origins when H5 token mode is active', async () => {
const result = await resolveCors('https://blocked.example.com', 'http://192.168.0.20:3456', {
h5Enabled: true,
isOriginAllowed: async () => false,
})
expect(result).toEqual({
allowed: false,
rejected: true,
headers: {
'Access-Control-Allow-Methods': 'GET, POST, PUT, PATCH, DELETE, OPTIONS',
'Access-Control-Allow-Headers': 'Content-Type, Authorization',
'Access-Control-Max-Age': '86400',
Vary: 'Origin',
},
})
})
it('allows configured origins when H5 token mode is active', async () => {
const result = await resolveCors('https://allowed.example.com', 'http://192.168.0.20:3456', {
h5Enabled: true,
isOriginAllowed: async (origin) => origin === 'https://allowed.example.com',
})
expect(result).toEqual({
allowed: true,
rejected: false,
headers: {
'Access-Control-Allow-Origin': 'https://allowed.example.com',
'Access-Control-Allow-Methods': 'GET, POST, PUT, PATCH, DELETE, OPTIONS',
'Access-Control-Allow-Headers': 'Content-Type, Authorization',
'Access-Control-Max-Age': '86400',
Vary: 'Origin',
},
})
})
it('keeps trusted local desktop origins allowed when H5 token mode is active', async () => {
for (const origin of ['http://tauri.localhost', 'http://127.0.0.1:5179']) {
const result = await resolveCors(origin, 'http://192.168.0.20:3456', {
h5Enabled: true,
isOriginAllowed: async () => false,
})
expect(result.allowed).toBe(true)
expect(result.rejected).toBe(false)
expect(result.headers['Access-Control-Allow-Origin']).toBe(origin)
}
})
it('does not trust non-local same-origin requests unless explicitly configured', async () => {
const result = await resolveCors('http://192.168.0.20:3456', 'http://192.168.0.20:3456', {
h5Enabled: true,
isOriginAllowed: async () => false,
})
expect(result.allowed).toBe(false)
expect(result.rejected).toBe(true)
expect(result.headers['Access-Control-Allow-Origin']).toBeUndefined()
})
it('allows same-origin H5 browser requests only through the configured origin callback', async () => {
const result = await resolveCors('http://192.168.0.20:3456', 'http://192.168.0.20:3456', {
h5Enabled: true,
isOriginAllowed: async (origin) => origin === 'http://192.168.0.20:3456',
})
expect(result.allowed).toBe(true)
expect(result.rejected).toBe(false)
expect(result.headers['Access-Control-Allow-Origin']).toBe('http://192.168.0.20:3456')
})
})
|