const MAX_WORKS_PLAY_URL_LENGTH = 1_024; function isLoopbackHostname(hostname: string): boolean { const normalized = hostname.toLowerCase().replace(/^\[|\]$/g, ''); return normalized === 'localhost' || normalized.endsWith('.localhost') || normalized === '::' || normalized === '::1' || normalized.startsWith('::ffff:127.') || normalized.startsWith('::ffff:7f00:') || normalized === '0.0.0.0' || normalized.startsWith('127.'); } function trustedWorksHttpsUrl(value: string, worksBase: URL): URL | null { try { const target = new URL(value, worksBase); if ( target.toString().length > MAX_WORKS_PLAY_URL_LENGTH || worksBase.protocol !== 'https:' || target.protocol !== 'https:' || target.origin !== worksBase.origin || Boolean(target.username || target.password) || isLoopbackHostname(target.hostname) ) { return null; } return target; } catch { return null; } } export function trustedWorksProjectPlayUrl( value: string, worksBase: URL, appId: string, ): string | null { const normalizedAppId = appId.trim(); if (!normalizedAppId) return null; const target = trustedWorksHttpsUrl(value, worksBase); if ( !target || target.pathname !== `/apps/${encodeURIComponent(normalizedAppId)}/` || target.search || target.hash ) { return null; } return target.toString(); } export function trustedWorksReleasePreviewUrl( value: string, worksBase: URL, releaseId: string, ): string | null { const target = trustedWorksHttpsUrl(value, worksBase); if (!target) return null; const expectedPrefix = `/previews/${encodeURIComponent(releaseId)}/`; return target.pathname.startsWith(expectedPrefix) ? target.toString() : null; }