65 lines
1.9 KiB
TypeScript
65 lines
1.9 KiB
TypeScript
import { afterEach, expect, test } from 'bun:test'
|
|
import { guardSceneApiRequest, sceneApiPreflight } from './scene-api-security'
|
|
|
|
const OLD_ENV = { ...process.env }
|
|
|
|
afterEach(() => {
|
|
restoreEnv('PASCAL_SCENE_API_TOKEN')
|
|
restoreEnv('PASCAL_SCENE_API_ORIGINS')
|
|
restoreEnv('PASCAL_SCENE_API_RATE_LIMIT')
|
|
})
|
|
|
|
function restoreEnv(key: keyof NodeJS.ProcessEnv): void {
|
|
if (OLD_ENV[key] === undefined) delete process.env[key]
|
|
else process.env[key] = OLD_ENV[key]
|
|
}
|
|
|
|
test('allows loopback scene API requests without a token', () => {
|
|
delete process.env.PASCAL_SCENE_API_TOKEN
|
|
const request = new Request('http://127.0.0.1:3000/api/scenes', {
|
|
headers: { host: '127.0.0.1:3000' },
|
|
})
|
|
|
|
expect(guardSceneApiRequest(request)).toBeNull()
|
|
})
|
|
|
|
test('requires a token for non-loopback scene API requests', async () => {
|
|
delete process.env.PASCAL_SCENE_API_TOKEN
|
|
const request = new Request('https://editor.example/api/scenes', {
|
|
headers: { host: 'editor.example' },
|
|
})
|
|
|
|
const response = guardSceneApiRequest(request)
|
|
|
|
expect(response?.status).toBe(503)
|
|
expect(await response?.json()).toEqual({ error: 'scene_api_token_required' })
|
|
})
|
|
|
|
test('accepts bearer token auth when configured', () => {
|
|
process.env.PASCAL_SCENE_API_TOKEN = 'secret'
|
|
const request = new Request('https://editor.example/api/scenes', {
|
|
headers: {
|
|
authorization: 'Bearer secret',
|
|
host: 'editor.example',
|
|
},
|
|
})
|
|
|
|
expect(guardSceneApiRequest(request)).toBeNull()
|
|
})
|
|
|
|
test('applies configured CORS origins for preflight', () => {
|
|
process.env.PASCAL_SCENE_API_ORIGINS = 'https://app.example'
|
|
const request = new Request('https://editor.example/api/scenes', {
|
|
method: 'OPTIONS',
|
|
headers: {
|
|
host: 'editor.example',
|
|
origin: 'https://app.example',
|
|
},
|
|
})
|
|
|
|
const response = sceneApiPreflight(request)
|
|
|
|
expect(response.status).toBe(204)
|
|
expect(response.headers.get('access-control-allow-origin')).toBe('https://app.example')
|
|
})
|