import { describe, expect, it } from 'vitest' import { isAllowedExternalUrl, isAppOrigin } from '../src/url-policy' describe('isAllowedExternalUrl', () => { it('allows https and mailto by default', () => { expect(isAllowedExternalUrl('https://d3ro.chanpaca.net/app/billing')).toBe(true) expect(isAllowedExternalUrl('mailto:help@example.com')).toBe(true) }) it.each([ 'file:///C:/Windows/System32/calc.exe', 'javascript:alert(1)', 'search-ms:query=x&crumb=location:\\\\evil\\share', 'ms-msdt:/id PCWDiagnostic', '\\\\evil.example\\share\\payload.exe', '//evil.example/x', 'd3ro-voice://auth-callback#access_token=x', 'http://example.com', 'https://user:pass@example.com', '', 'not a url', ])('rejects %s', (url) => { expect(isAllowedExternalUrl(url)).toBe(false) }) it('allows extra exact origins (dev web app) without widening schemes', () => { const options = { allowOrigins: ['http://localhost:3000'] } expect(isAllowedExternalUrl('http://localhost:3000/app/billing?tier=pro', options)).toBe(true) expect(isAllowedExternalUrl('http://localhost:3001/app', options)).toBe(false) expect(isAllowedExternalUrl('http://evil.example', options)).toBe(false) }) }) describe('isAppOrigin', () => { it('matches the packaged file renderer and the dev server origin only', () => { const origins = ['file://', 'http://localhost:5173'] expect(isAppOrigin('file:///C:/app/resources/app.asar/out/renderer/index.html#/meetings', origins)).toBe(true) expect(isAppOrigin('http://localhost:5173/#/settings', origins)).toBe(true) expect(isAppOrigin('http://localhost:5174/', origins)).toBe(false) expect(isAppOrigin('https://evil.example/', origins)).toBe(false) }) it('does not treat file: as app origin unless allowed', () => { expect(isAppOrigin('file:///C:/x.html', ['http://localhost:5173'])).toBe(false) }) })