Files
iptvnator/apps/web-e2e/src/provider-target-route.ts
T
4gray 32cc0b74e8 feat: add self-hosted PWA backend runtime (#944)
* feat(web-backend): add self-hosted proxy app

* feat(web): enable runtime PWA configuration

* test(web-e2e): cover self-hosted backend proxy

* test(web-e2e): clean self-hosted lint warnings

* fix(web-backend): validate proxied provider URLs

* fix(web-backend): proxy through registered provider targets

* fix(web-backend): document CodeQL SSRF validation boundary

* test(web-e2e): mock provider target registration

* fix(web): address self-hosted review feedback
2026-05-16 00:10:03 +02:00

81 lines
2.2 KiB
TypeScript

import { type Page } from '@playwright/test';
interface ProviderTargetPayload {
readonly url: string;
}
const BACKEND_ORIGIN = 'http://localhost:3000';
const CORS_HEADERS = {
'access-control-allow-headers': 'content-type',
'access-control-allow-methods': 'POST, OPTIONS',
'access-control-allow-origin': 'http://localhost:4200',
} as const;
export async function interceptProviderTargetRegistration(
page: Page
): Promise<Map<string, string>> {
const providerTargets = new Map<string, string>();
await page.route(`${BACKEND_ORIGIN}/provider-targets**`, async (route) => {
if (route.request().method() === 'OPTIONS') {
await route.fulfill({
body: '',
headers: CORS_HEADERS,
status: 200,
});
return;
}
const providerUrl = getProviderUrl(route.request().postDataJSON());
if (!providerUrl) {
await route.fulfill({
body: JSON.stringify({
message: 'Missing url',
status: 400,
}),
contentType: 'application/json',
headers: CORS_HEADERS,
status: 400,
});
return;
}
const targetId = Buffer.from(providerUrl).toString('base64url');
providerTargets.set(targetId, providerUrl);
await route.fulfill({
body: JSON.stringify({ targetId }),
contentType: 'application/json',
headers: CORS_HEADERS,
status: 200,
});
});
return providerTargets;
}
export function getRegisteredProviderUrl(
url: URL,
providerTargets: ReadonlyMap<string, string>
): string | null {
const targetId = url.searchParams.get('targetId');
if (!targetId) {
return url.searchParams.get('url');
}
return providerTargets.get(targetId) ?? null;
}
function getProviderUrl(value: unknown): string | null {
if (
value &&
typeof value === 'object' &&
'url' in value &&
typeof (value as Partial<ProviderTargetPayload>).url === 'string'
) {
return (value as ProviderTargetPayload).url;
}
return null;
}