fix login
Build & Deploy / Build & Push Docker Image (push) Failing after 48s
Build & Deploy / Deploy to VPS (push) Has been skipped
Test / API Unit Tests (push) Failing after 5m2s
Test / Marketplace Unit Tests (push) Failing after 4m56s
Test / Admin Unit Tests (push) Successful in 9m36s
Test / Dashboard Unit Tests (push) Successful in 9m37s
Test / API Integration Tests (push) Successful in 9m54s
Build & Deploy / Build & Push Docker Image (push) Failing after 48s
Build & Deploy / Deploy to VPS (push) Has been skipped
Test / API Unit Tests (push) Failing after 5m2s
Test / Marketplace Unit Tests (push) Failing after 4m56s
Test / Admin Unit Tests (push) Successful in 9m36s
Test / Dashboard Unit Tests (push) Successful in 9m37s
Test / API Integration Tests (push) Successful in 9m54s
This commit is contained in:
@@ -2,17 +2,25 @@ export function createNonce(): string {
|
|||||||
return crypto.randomUUID().replaceAll('-', '');
|
return crypto.randomUUID().replaceAll('-', '');
|
||||||
}
|
}
|
||||||
|
|
||||||
export function buildContentSecurityPolicy(nonce: string, development: boolean): string {
|
export function buildContentSecurityPolicy(
|
||||||
|
nonce: string,
|
||||||
|
development: boolean,
|
||||||
|
apiOrigin?: string,
|
||||||
|
): string {
|
||||||
const scriptSources = ["'self'", `'nonce-${nonce}'`, "'strict-dynamic'"];
|
const scriptSources = ["'self'", `'nonce-${nonce}'`, "'strict-dynamic'"];
|
||||||
if (development) scriptSources.push("'unsafe-eval'");
|
if (development) scriptSources.push("'unsafe-eval'");
|
||||||
|
|
||||||
|
const connectSources = ["'self'"];
|
||||||
|
if (development) connectSources.push('ws:', 'wss:');
|
||||||
|
if (apiOrigin) connectSources.push(apiOrigin);
|
||||||
|
|
||||||
const directives = [
|
const directives = [
|
||||||
"default-src 'self'",
|
"default-src 'self'",
|
||||||
`script-src ${scriptSources.join(' ')}`,
|
`script-src ${scriptSources.join(' ')}`,
|
||||||
`style-src 'self'${development ? " 'unsafe-inline'" : ` 'nonce-${nonce}'`}`,
|
`style-src 'self'${development ? " 'unsafe-inline'" : ` 'nonce-${nonce}'`}`,
|
||||||
"img-src 'self' data: blob:",
|
"img-src 'self' data: blob:",
|
||||||
"font-src 'self' data:",
|
"font-src 'self' data:",
|
||||||
`connect-src 'self'${development ? ' ws: wss:' : ''}`,
|
`connect-src ${connectSources.join(' ')}`,
|
||||||
"media-src 'self'",
|
"media-src 'self'",
|
||||||
"object-src 'none'",
|
"object-src 'none'",
|
||||||
"base-uri 'self'",
|
"base-uri 'self'",
|
||||||
|
|||||||
@@ -19,9 +19,25 @@ function applySecurityHeaders(response: NextResponse, contentSecurityPolicy: str
|
|||||||
return response;
|
return response;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
function resolveApiOrigin(): string | undefined {
|
||||||
|
const origins = new Set<string>();
|
||||||
|
const urls = [process.env.API_INTERNAL_URL, process.env.NEXT_PUBLIC_API_URL];
|
||||||
|
for (const url of urls) {
|
||||||
|
if (!url) continue;
|
||||||
|
try {
|
||||||
|
origins.add(new URL(url).origin);
|
||||||
|
} catch {
|
||||||
|
// ignore malformed URLs
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return origins.size > 0 ? Array.from(origins).join(' ') : undefined;
|
||||||
|
}
|
||||||
|
|
||||||
export function proxy(request: NextRequest): NextResponse {
|
export function proxy(request: NextRequest): NextResponse {
|
||||||
const nonce = createNonce();
|
const nonce = createNonce();
|
||||||
const csp = buildContentSecurityPolicy(nonce, process.env.NODE_ENV !== 'production');
|
const isDev = process.env.NODE_ENV !== 'production';
|
||||||
|
const apiOrigin = resolveApiOrigin();
|
||||||
|
const csp = buildContentSecurityPolicy(nonce, isDev, apiOrigin);
|
||||||
const requestHeaders = new Headers(request.headers);
|
const requestHeaders = new Headers(request.headers);
|
||||||
requestHeaders.set('x-nonce', nonce);
|
requestHeaders.set('x-nonce', nonce);
|
||||||
requestHeaders.set('Content-Security-Policy', csp);
|
requestHeaders.set('Content-Security-Policy', csp);
|
||||||
|
|||||||
Reference in New Issue
Block a user