test/origin.test.js
Rama main · réplica de lectura del repositorio original.
import { describe, it, expect, vi, afterEach } from 'vitest';
import { isAllowedOrigin } from '../server/state.js';
// The origin allowlist is the sole cross-origin defense for both HTTP
// (server/http.js checkOrigin) and WebSocket (server/ws.js verifyClient).
// These tests pin its truth table so a refactor can't silently open the boundary.
describe('isAllowedOrigin — default allowlist', () => {
it('allows requests with no Origin header (same-origin / curl / native WS)', () => {
expect(isAllowedOrigin(undefined)).toBe(true);
expect(isAllowedOrigin('')).toBe(true);
});
it('allows loopback origins on any port/scheme (incl. IPv6 [::1])', () => {
expect(isAllowedOrigin('http://localhost:7007')).toBe(true);
expect(isAllowedOrigin('https://localhost')).toBe(true);
expect(isAllowedOrigin('http://127.0.0.1:7007')).toBe(true);
expect(isAllowedOrigin('http://[::1]:7007')).toBe(true);
});
it('rejects a non-whitelisted host', () => {
expect(isAllowedOrigin('http://evil.example.com')).toBe(false);
expect(isAllowedOrigin('http://mac-mini.tailXXXX.ts.net:7007')).toBe(false);
});
it('rejects a malformed origin string', () => {
expect(isAllowedOrigin('not a url')).toBe(false);
expect(isAllowedOrigin('http://')).toBe(false);
});
});
describe('isAllowedOrigin — env-configured allowlist', () => {
// state.js reads process.env at module load, so re-import per case.
afterEach(() => { delete process.env.ALLOWED_ORIGINS; vi.resetModules(); });
async function load(val) {
process.env.ALLOWED_ORIGINS = val;
vi.resetModules();
return (await import('../server/state.js')).isAllowedOrigin;
}
it('allows a whitelisted bare hostname, still rejects others', async () => {
const fn = await load('mac-mini.tailXXXX.ts.net');
expect(fn('http://mac-mini.tailXXXX.ts.net:7007')).toBe(true);
expect(fn('http://other.example.com')).toBe(false);
});
it('allows a whitelisted host:port entry (regression: was a silent lockout)', async () => {
const fn = await load('mac-mini.ts.net:7007');
expect(fn('http://mac-mini.ts.net:7007')).toBe(true);
});
it('allows a whitelisted full origin (only the hostname is used)', async () => {
const fn = await load('https://mac-mini:7007');
expect(fn('http://mac-mini:9999')).toBe(true);
});
it('allows any origin when ALLOWED_ORIGINS contains "*"', async () => {
const fn = await load('*');
expect(fn('http://evil.example.com')).toBe(true);
expect(fn('garbage')).toBe(true);
});
});