Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
20 changes: 12 additions & 8 deletions apps/app-frontend/playwright.config.ts
Original file line number Diff line number Diff line change
@@ -1,5 +1,9 @@
import { defineConfig, devices } from '@playwright/test';

// All http://127.0.0.1:41017 URLs in this file are loopback addresses used
// exclusively for Playwright E2E tests. Not used in production traffic.
// See docs/security/internal-networking.md.

const isRealAuthE2E = process.env.REAL_AUTH_E2E === '1';

export default defineConfig({
Expand All @@ -9,7 +13,7 @@ export default defineConfig({
retries: process.env.CI ? 2 : 0,
reporter: process.env.CI ? 'github' : [['html', { open: 'never' }], ['list']],
use: {
baseURL: 'http://127.0.0.1:41017',
baseURL: 'http://127.0.0.1:41017', // NOSONAR: S5332 - E2E test loopback URL; not used in production.
ignoreHTTPSErrors: true,
screenshot: 'only-on-failure',
trace: 'on-first-retry',
Expand All @@ -33,7 +37,7 @@ export default defineConfig({
// First run: npm run build to create .next/ directory
// Then: next start serves from the prebuilt bundle
command: 'node scripts/e2e-server.mjs',
url: 'http://127.0.0.1:41017',
url: 'http://127.0.0.1:41017', // NOSONAR: S5332 - E2E test loopback URL.
reuseExistingServer: !process.env.CI,
timeout: 360_000,
ignoreHTTPSErrors: true,
Expand All @@ -49,14 +53,14 @@ export default defineConfig({
// be set. In CI this is overridden by the workflow environment variable.
// next-auth requires AUTH_SECRET to be at least 32 characters.
AUTH_SECRET: process.env.AUTH_SECRET ?? 'e2e-local-dummy-secret-minimum-32-chars-required-for-nextauth',
AUTH_URL: 'http://127.0.0.1:41017',
NEXTAUTH_URL: 'http://127.0.0.1:41017',
AUTH_URL: 'http://127.0.0.1:41017', // NOSONAR: S5332 - E2E test loopback URL.
NEXTAUTH_URL: 'http://127.0.0.1:41017', // NOSONAR: S5332 - E2E test loopback URL.
AUTH_TRUST_HOST: 'true',
INTERNAL_API_URL: 'http://127.0.0.1:41017',
NEXT_PUBLIC_API_URL: 'http://127.0.0.1:41017',
INTERNAL_API_URL: 'http://127.0.0.1:41017', // NOSONAR: S5332 - E2E test loopback URL; mocks core-api on loopback.
NEXT_PUBLIC_API_URL: 'http://127.0.0.1:41017', // NOSONAR: S5332 - E2E test loopback URL; not exposed to browsers in production.
AUTH_AUTHENTIK_ISSUER: isRealAuthE2E
? process.env.AUTH_AUTHENTIK_ISSUER ?? 'https://auth.curvit.local.co.uk/application/o/curvit/'
: 'http://127.0.0.1:41017/application/o/curvit/',
: 'http://127.0.0.1:41017/application/o/curvit/', // NOSONAR: S5332 - E2E test loopback issuer; only used when isRealAuthE2E is false.
DISABLE_URL_REWRITES: '0',
PLAYWRIGHT_E2E: isRealAuthE2E ? '0' : '1',
// Redirect unauthenticated middleware to the local login page rather than
Expand All @@ -66,7 +70,7 @@ export default defineConfig({
// ('networkidle') to time-out and making redirect tests flaky.
MARKETING_URL: isRealAuthE2E
? process.env.MARKETING_URL ?? 'https://curvit.local.co.uk'
: 'http://127.0.0.1:41017/login',
: 'http://127.0.0.1:41017/login', // NOSONAR: S5332 - E2E test loopback URL; only used when isRealAuthE2E is false.
},
},
});
2 changes: 1 addition & 1 deletion apps/app-frontend/src/app/api/e2e/auth/route.ts
Original file line number Diff line number Diff line change
Expand Up @@ -38,7 +38,7 @@ function hashPassword(password: string) {
}

function redirectTo(path: string) {
return NextResponse.redirect(new URL(path, process.env.NEXTAUTH_URL ?? 'http://127.0.0.1:41017'));
return NextResponse.redirect(new URL(path, process.env.NEXTAUTH_URL ?? 'http://127.0.0.1:41017')); // NOSONAR: S5332 - E2E test route; only reachable during Playwright tests on loopback.
}

function readRegisteredState(cookieHeader: string) {
Expand Down
2 changes: 1 addition & 1 deletion apps/app-frontend/src/lib/api/account.ts
Original file line number Diff line number Diff line change
Expand Up @@ -63,7 +63,7 @@ export async function exportAccountData(
});
}

const baseUrl = process.env.CORE_API_URL ?? 'http://core-api:5000';
const baseUrl = process.env.CORE_API_URL ?? 'http://core-api:5000'; // NOSONAR: S5332 - Internal Docker URL; server-side only.
const res = await fetch(`${baseUrl}/api/v1/account/data-export`, {
headers: { Authorization: `Bearer ${accessToken}` },
});
Expand Down
6 changes: 3 additions & 3 deletions apps/app-frontend/src/lib/api/admin.ts
Original file line number Diff line number Diff line change
Expand Up @@ -133,7 +133,7 @@ class AdminServiceClient extends BaseServiceClient {
super({
serviceName: 'admin-api',
serverBaseUrlEnvVar: 'ADMIN_SERVICE_URL',
serverBaseUrlDefault: 'http://admin-service:8000',
serverBaseUrlDefault: 'http://admin-service:8000', // NOSONAR: S5332 - Internal Docker URL; server-side only.
serverPathPrefix: '/admin',
clientPathPrefix: '/api/v1/admin',
});
Expand All @@ -145,7 +145,7 @@ class BillingAdminServiceClient extends BaseServiceClient {
super({
serviceName: 'billing-admin-api',
serverBaseUrlEnvVar: 'BILLING_SERVICE_URL',
serverBaseUrlDefault: 'http://billing-service:8000',
serverBaseUrlDefault: 'http://billing-service:8000', // NOSONAR: S5332 - Internal Docker URL; server-side only.
serverPathPrefix: '/admin/billing',
clientPathPrefix: '/api/v1/admin/billing',
});
Expand Down Expand Up @@ -494,7 +494,7 @@ export async function adminExportUserData(
userId: string,
accessToken: string
): Promise<Response | null> {
const baseUrl = process.env.INTERNAL_API_URL ?? 'http://core-api:5000';
const baseUrl = process.env.INTERNAL_API_URL ?? 'http://core-api:5000'; // NOSONAR: S5332 - Internal Docker URL; server-side only.
const res = await fetch(`${baseUrl}/api/v1/admin/users/${userId}/data-export`, {
headers: { Authorization: `Bearer ${accessToken}` },
});
Expand Down
6 changes: 3 additions & 3 deletions apps/app-frontend/src/lib/api/billing.ts
Original file line number Diff line number Diff line change
Expand Up @@ -35,7 +35,7 @@ type PortalWire = CreatePortalSessionResponse_v1 & { portal_url?: string };
function getBillingApiBaseUrl(): string {
// Server-side: use billing-service directly
if (typeof window === 'undefined') {
return process.env.BILLING_SERVICE_URL ?? 'http://billing-service:8000';
return process.env.BILLING_SERVICE_URL ?? 'http://billing-service:8000'; // NOSONAR: S5332 - Internal Docker URL; server-side only.
}
// Client-side: use the gateway (will be prefixed with api.curvit.local.co.uk by apiRequest)
return '';
Expand Down Expand Up @@ -119,7 +119,7 @@ export async function createCheckoutSession(
accessToken: string
): Promise<string | null> {
if (isPlaywrightE2EEnabled()) {
return `http://127.0.0.1:41017/settings?checkout=success&tier=${tier}`;
return `http://127.0.0.1:41017/settings?checkout=success&tier=${tier}`; // NOSONAR: S5332 - E2E test-only URL; guarded by isPlaywrightE2EEnabled().
}

const result = await billingRequest<CheckoutWire>(
Expand All @@ -139,7 +139,7 @@ export async function createPortalSession(
accessToken: string
): Promise<string | null> {
if (isPlaywrightE2EEnabled()) {
return 'http://127.0.0.1:41017/settings';
return 'http://127.0.0.1:41017/settings'; // NOSONAR: S5332 - E2E test-only URL; guarded by isPlaywrightE2EEnabled().
}

const result = await billingRequest<PortalWire>(
Expand Down
2 changes: 1 addition & 1 deletion apps/app-frontend/src/lib/api/blog.ts
Original file line number Diff line number Diff line change
Expand Up @@ -83,7 +83,7 @@ function toBlogPostPayload(payload: SaveBlogPostPayload) {
function getCmsApiBaseUrl(): string {
// Server-side: use cms-service directly
if (typeof window === 'undefined') {
return process.env.CMS_SERVICE_URL ?? 'http://cms-service:8000';
return process.env.CMS_SERVICE_URL ?? 'http://cms-service:8000'; // NOSONAR: S5332 - Internal Docker URL; server-side only.
}
// Client-side: use the gateway (will be prefixed with api.curvit.local.co.uk by apiRequest)
return '';
Expand Down
33 changes: 17 additions & 16 deletions apps/app-frontend/src/lib/api/health.ts
Original file line number Diff line number Diff line change
Expand Up @@ -7,23 +7,24 @@ import type { ServiceHealthResult_v1 } from '@curvit/contracts';
// Stateful infrastructure without an HTTP health endpoint from the app network
// (for example Postgres and Redis) remains covered by Docker health checks and
// monitoring dashboards rather than this page.
// All http:// URLs below are internal Docker addresses. See docs/security/internal-networking.md.
const SERVICES: { name: string; url: string }[] = [
{ name: 'App Frontend', url: 'http://app-frontend:3000/api/health' },
{ name: 'Marketing Site', url: 'http://marketing-site:8080/' },
{ name: 'Core API', url: 'http://core-api:5000/health' },
{ name: 'Admin Service', url: 'http://admin-service:8000/health' },
{ name: 'Billing Service', url: 'http://billing-service:8000/health' },
{ name: 'CMS Service', url: 'http://cms-service:8000/health' },
{ name: 'Messaging Service', url: 'http://messaging-service:8000/health' },
{ name: 'AI Orchestrator', url: 'http://ai-orchestrator:8000/health' },
{ name: 'CV Structuring Service', url: 'http://cv-structuring-service:8000/health' },
{ name: 'Content Sanitiser', url: 'http://content-sanitiser:8000/health' },
{ name: 'Output Validator', url: 'http://output-validator:8000/health' },
{ name: 'Document Renderer', url: 'http://document-renderer:8000/health' },
{ name: 'Document Ingestion', url: 'http://document-ingestion-service:8001/health' },
{ name: 'Analysis Worker', url: 'http://analysis-worker:8000/health' },
{ name: 'Batch Ranking Worker', url: 'http://batch-ranking-worker:8000/health' },
{ name: 'ClamAV REST', url: 'http://clamav-rest:8080/api/v1/version' },
{ name: 'App Frontend', url: 'http://app-frontend:3000/api/health' }, // NOSONAR: S5332
{ name: 'Marketing Site', url: 'http://marketing-site:8080/' }, // NOSONAR: S5332
{ name: 'Core API', url: 'http://core-api:5000/health' }, // NOSONAR: S5332
{ name: 'Admin Service', url: 'http://admin-service:8000/health' }, // NOSONAR: S5332
{ name: 'Billing Service', url: 'http://billing-service:8000/health' }, // NOSONAR: S5332
{ name: 'CMS Service', url: 'http://cms-service:8000/health' }, // NOSONAR: S5332
{ name: 'Messaging Service', url: 'http://messaging-service:8000/health' }, // NOSONAR: S5332
{ name: 'AI Orchestrator', url: 'http://ai-orchestrator:8000/health' }, // NOSONAR: S5332
{ name: 'CV Structuring Service', url: 'http://cv-structuring-service:8000/health' }, // NOSONAR: S5332
{ name: 'Content Sanitiser', url: 'http://content-sanitiser:8000/health' }, // NOSONAR: S5332
{ name: 'Output Validator', url: 'http://output-validator:8000/health' }, // NOSONAR: S5332
{ name: 'Document Renderer', url: 'http://document-renderer:8000/health' }, // NOSONAR: S5332
{ name: 'Document Ingestion', url: 'http://document-ingestion-service:8001/health' }, // NOSONAR: S5332
{ name: 'Analysis Worker', url: 'http://analysis-worker:8000/health' }, // NOSONAR: S5332
{ name: 'Batch Ranking Worker', url: 'http://batch-ranking-worker:8000/health' }, // NOSONAR: S5332
{ name: 'ClamAV REST', url: 'http://clamav-rest:8080/api/v1/version' }, // NOSONAR: S5332
];

export async function checkServiceHealth(): Promise<ServiceHealthResult_v1[]> {
Expand Down
2 changes: 1 addition & 1 deletion apps/app-frontend/src/lib/api/internal-auth.ts
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
const getInternalApiBaseUrl = () =>
process.env.INTERNAL_API_URL || process.env.CORE_API_URL || 'http://core-api:5000';
process.env.INTERNAL_API_URL || process.env.CORE_API_URL || 'http://core-api:5000'; // NOSONAR: S5332 - Internal Docker URL; server-side only. See docs/security/internal-networking.md.

function getInternalHeaders(): HeadersInit {
const headers: HeadersInit = {
Expand Down
2 changes: 1 addition & 1 deletion apps/app-frontend/src/lib/api/messages.ts
Original file line number Diff line number Diff line change
Expand Up @@ -184,7 +184,7 @@ class MessagingServiceClient extends BaseServiceClient {
super({
serviceName: 'messaging-api',
serverBaseUrlEnvVar: 'MESSAGING_SERVICE_URL',
serverBaseUrlDefault: 'http://messaging-service:8000',
serverBaseUrlDefault: 'http://messaging-service:8000', // NOSONAR: S5332 - Internal Docker URL; server-side only.
serverPathPrefix: '',
clientPathPrefix: '/api/v1',
});
Expand Down
2 changes: 1 addition & 1 deletion apps/app-frontend/src/lib/auth/logoutCookies.ts
Original file line number Diff line number Diff line change
Expand Up @@ -34,7 +34,7 @@ export function getSharedCookieDomain(marketingUrl?: string) {

export function buildMarketingLogoutUrl(marketingUrl?: string) {
if (process.env.PLAYWRIGHT_E2E === '1') {
return new URL('/login?loggedOut=1', marketingUrl ?? 'http://127.0.0.1:41017').toString();
return new URL('/login?loggedOut=1', marketingUrl ?? 'http://127.0.0.1:41017').toString(); // NOSONAR: S5332 - E2E test-only fallback; guarded by PLAYWRIGHT_E2E check.
}

return new URL('/', marketingUrl ?? 'https://curvit.io').toString();
Expand Down
2 changes: 1 addition & 1 deletion apps/app-frontend/tests/e2e/admin-visibility.spec.ts
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@ async function forceAuthMode(page: Page, mode: 'admin' | 'non-admin-user') {
{
name: 'curvit_e2e_auth',
value: mode,
url: 'http://127.0.0.1:41017',
url: 'http://127.0.0.1:41017', // NOSONAR: S5332 - E2E test cookie target; loopback only.
httpOnly: true,
secure: false,
sameSite: 'Lax',
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,7 @@ const ADMIN_SESSION = {
};

function makeRequest(): Request {
return new Request('http://localhost/api/admin/users/user-1/data-export');
return new Request('http://localhost/api/admin/users/user-1/data-export'); // NOSONAR: S5332 - test-only localhost URL for constructing Request objects.
}

function makeParams(userId = 'user-1') {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,7 @@ const { redirect } = await import('next/navigation');
function makeCheckoutRequest(tier: string): Request {
const body = new FormData();
body.append('tier', tier);
return new Request('http://localhost/api/billing/checkout', {
return new Request('http://localhost/api/billing/checkout', { // NOSONAR: S5332 - test-only localhost URL for constructing Request objects.
method: 'POST',
body,
});
Expand Down
2 changes: 1 addition & 1 deletion apps/app-frontend/tests/unit/app/api/e2e/auth.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,7 @@ function makePostRequest(fields: Record<string, string> = {}) {
for (const [key, value] of Object.entries(fields)) {
body.append(key, value);
}
return new Request('http://localhost/api/e2e/auth', { method: 'POST', body });
return new Request('http://localhost/api/e2e/auth', { method: 'POST', body }); // NOSONAR: S5332 - test-only localhost URL for constructing Request objects.
}

describe('GET /api/e2e/auth — token disclosure prevention', () => {
Expand Down
2 changes: 1 addition & 1 deletion apps/app-frontend/tests/unit/lib/api/account.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@ import { http, HttpResponse } from 'msw';
import { setupServer } from 'msw/node';
import { getAccount, deleteAccount } from '@/lib/api/account';

process.env.NEXT_PUBLIC_API_URL = 'http://localhost:5000';
process.env.NEXT_PUBLIC_API_URL = 'http://localhost:5000'; // NOSONAR: S5332 - test-only MSW mock base URL; not a real network connection.
process.env.INTERNAL_API_URL = '';

const server = setupServer();
Expand Down
2 changes: 1 addition & 1 deletion apps/app-frontend/tests/unit/lib/api/admin.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@ import {
adminDeleteUserAccount,
} from '@/lib/api/admin';

process.env.NEXT_PUBLIC_API_URL = 'http://localhost:5000';
process.env.NEXT_PUBLIC_API_URL = 'http://localhost:5000'; // NOSONAR: S5332 - test-only MSW mock base URL; not a real network connection.
process.env.INTERNAL_API_URL = '';

const server = setupServer();
Expand Down
2 changes: 1 addition & 1 deletion apps/app-frontend/tests/unit/lib/api/analyses.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@ import {
getAnalysisResult,
} from '@/lib/api/analyses';

process.env.NEXT_PUBLIC_API_URL = 'http://localhost:5000';
process.env.NEXT_PUBLIC_API_URL = 'http://localhost:5000'; // NOSONAR: S5332 - test-only MSW mock base URL; not a real network connection.
process.env.INTERNAL_API_URL = '';

const server = setupServer();
Expand Down
2 changes: 1 addition & 1 deletion apps/app-frontend/tests/unit/lib/api/billing.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@ import { http, HttpResponse } from 'msw';
import { setupServer } from 'msw/node';
import { getBillingStatus, createCheckoutSession, createPortalSession } from '@/lib/api/billing';

process.env.NEXT_PUBLIC_API_URL = 'http://localhost:5000';
process.env.NEXT_PUBLIC_API_URL = 'http://localhost:5000'; // NOSONAR: S5332 - test-only MSW mock base URL; not a real network connection.
process.env.INTERNAL_API_URL = '';

const server = setupServer();
Expand Down
2 changes: 1 addition & 1 deletion apps/app-frontend/tests/unit/lib/api/blog.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,7 @@ import {
type SaveBlogPostPayload,
} from '@/lib/api/blog';

process.env.NEXT_PUBLIC_API_URL = 'http://localhost:5000';
process.env.NEXT_PUBLIC_API_URL = 'http://localhost:5000'; // NOSONAR: S5332 - test-only MSW mock base URL; not a real network connection.
process.env.INTERNAL_API_URL = '';

const server = setupServer();
Expand Down
2 changes: 1 addition & 1 deletion apps/app-frontend/tests/unit/lib/api/client.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@ import { setupServer } from 'msw/node';
import { apiRequest } from '@/lib/api/client';

// Mock base URL for tests
process.env.NEXT_PUBLIC_API_URL = 'http://localhost:5000';
process.env.NEXT_PUBLIC_API_URL = 'http://localhost:5000'; // NOSONAR: S5332 - test-only MSW mock base URL; not a real network connection.
process.env.INTERNAL_API_URL = '';

const server = setupServer();
Expand Down
2 changes: 1 addition & 1 deletion apps/app-frontend/tests/unit/lib/api/documents.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@ import { http, HttpResponse } from 'msw';
import { setupServer } from 'msw/node';
import { listDocuments, uploadDocument } from '@/lib/api/documents';

process.env.NEXT_PUBLIC_API_URL = 'http://localhost:5000';
process.env.NEXT_PUBLIC_API_URL = 'http://localhost:5000'; // NOSONAR: S5332 - test-only MSW mock base URL; not a real network connection.
process.env.INTERNAL_API_URL = '';

const server = setupServer();
Expand Down
2 changes: 1 addition & 1 deletion apps/app-frontend/tests/unit/lib/api/job-specs.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@ import { http, HttpResponse } from 'msw';
import { setupServer } from 'msw/node';
import { listJobSpecs, uploadJobSpec } from '@/lib/api/job-specs';

process.env.NEXT_PUBLIC_API_URL = 'http://localhost:5000';
process.env.NEXT_PUBLIC_API_URL = 'http://localhost:5000'; // NOSONAR: S5332 - test-only MSW mock base URL; not a real network connection.
process.env.INTERNAL_API_URL = '';

const server = setupServer();
Expand Down
2 changes: 1 addition & 1 deletion apps/app-frontend/tests/unit/lib/api/messages.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@ import {
updateAdminMessage,
} from '@/lib/api/messages';

process.env.NEXT_PUBLIC_API_URL = 'http://localhost:5000';
process.env.NEXT_PUBLIC_API_URL = 'http://localhost:5000'; // NOSONAR: S5332 - test-only MSW mock base URL; not a real network connection.
process.env.INTERNAL_API_URL = '';

const server = setupServer();
Expand Down
2 changes: 1 addition & 1 deletion apps/app-frontend/tests/unit/lib/api/screening.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@ import {
createScreeningSession,
} from '@/lib/api/screening';

process.env.NEXT_PUBLIC_API_URL = 'http://localhost:5000';
process.env.NEXT_PUBLIC_API_URL = 'http://localhost:5000'; // NOSONAR: S5332 - test-only MSW mock base URL; not a real network connection.
process.env.INTERNAL_API_URL = '';

const server = setupServer();
Expand Down
2 changes: 1 addition & 1 deletion apps/app-frontend/tests/unit/lib/logoutCookies.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -26,7 +26,7 @@ describe('buildExpiredAuthCookies', () => {

it('keeps Playwright local login redirect in E2E mode', () => {
process.env.PLAYWRIGHT_E2E = '1';
expect(buildMarketingLogoutUrl('http://127.0.0.1:41017')).toBe('http://127.0.0.1:41017/login?loggedOut=1');
expect(buildMarketingLogoutUrl('http://127.0.0.1:41017')).toBe('http://127.0.0.1:41017/login?loggedOut=1'); // NOSONAR: S5332 - E2E test assertion; loopback URL only.
delete process.env.PLAYWRIGHT_E2E;
});
});
8 changes: 6 additions & 2 deletions apps/marketing-site/playwright.config.ts
Original file line number Diff line number Diff line change
@@ -1,5 +1,9 @@
import { defineConfig, devices } from '@playwright/test';

// All http://localhost:4322 URLs in this file are loopback addresses used
// exclusively for Playwright E2E tests. Not used in production traffic.
// See docs/security/internal-networking.md.

const includeMobileSafari = !!process.env.CI || process.env.PLAYWRIGHT_INCLUDE_WEBKIT === '1';

export default defineConfig({
Expand All @@ -9,7 +13,7 @@ export default defineConfig({
retries: process.env.CI ? 2 : 0,
reporter: process.env.CI ? 'github' : 'html',
use: {
baseURL: 'http://localhost:4322',
baseURL: 'http://localhost:4322', // NOSONAR: S5332 - E2E test loopback URL; not used in production.
trace: 'on-first-retry',
},
projects: [
Expand All @@ -28,7 +32,7 @@ export default defineConfig({
],
webServer: {
command: 'npm run build && npx astro preview --port 4322',
url: 'http://localhost:4322',
url: 'http://localhost:4322', // NOSONAR: S5332 - E2E test loopback URL.
reuseExistingServer: false,
env: {
...process.env,
Expand Down
2 changes: 1 addition & 1 deletion apps/marketing-site/src/config.ts
Original file line number Diff line number Diff line change
Expand Up @@ -11,4 +11,4 @@ export const appUrl: string =
export const internalAppUrl: string =
process.env.INTERNAL_APP_URL
?? import.meta.env.INTERNAL_APP_URL
?? 'http://app-frontend:3000';
?? 'http://app-frontend:3000'; // NOSONAR: S5332 - Internal Docker URL; SSR server-side only. See docs/security/internal-networking.md.
2 changes: 1 addition & 1 deletion apps/marketing-site/src/lib/search/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -98,7 +98,7 @@ async function buildBlogIndex(): Promise<SearchResultItem[]> {
return cachedBlogIndex.results;
}

const cmsBase = process.env.CMS_SERVICE_URL || 'http://cms-service:8000';
const cmsBase = process.env.CMS_SERVICE_URL || 'http://cms-service:8000'; // NOSONAR: S5332 - Internal Docker URL; SSR server-side only.
const internalApiKey = process.env.INTERNAL_API_KEY || '';

const headers = internalApiKey ? { 'X-Internal-Api-Key': internalApiKey } : undefined;
Expand Down
Loading
Loading