mirror of
https://github.com/GitbookIO/gitbook.git
synced 2026-09-17 08:05:19 +00:00
56143277b7
* Expose window.GitBook to integrations * Simplify * Oups * Use basic script to load integrations * Preload the scripts
66 lines
2.3 KiB
TypeScript
66 lines
2.3 KiB
TypeScript
import { SpaceIntegrationScript } from '@gitbook/api';
|
|
import { merge } from 'content-security-policy-merger';
|
|
import { headers } from 'next/headers';
|
|
|
|
import { filterOutNullable } from './typescript';
|
|
|
|
let assetsDomain = '';
|
|
if (process.env.GITBOOK_ASSETS_PREFIX) {
|
|
const parsed = new URL(process.env.GITBOOK_ASSETS_PREFIX);
|
|
assetsDomain = `${parsed.protocol}//${parsed.host}`;
|
|
}
|
|
|
|
/**
|
|
* Get the current nonce for the current request.
|
|
*/
|
|
export function getContentSecurityPolicyNonce(): string {
|
|
const headersList = headers();
|
|
const nonce = headersList.get('x-nonce');
|
|
if (!nonce) {
|
|
throw new Error('No nonce found in headers');
|
|
}
|
|
|
|
return nonce;
|
|
}
|
|
|
|
/**
|
|
* Create a nonce for a Content Security Policy.
|
|
*/
|
|
export function createContentSecurityPolicyNonce(): string {
|
|
const nonce = Buffer.from(crypto.randomUUID()).toString('base64');
|
|
return nonce;
|
|
}
|
|
|
|
/**
|
|
* Generate a Content Security Policy header for a space.
|
|
*/
|
|
export function getContentSecurityPolicy(scripts: SpaceIntegrationScript[], nonce: string): string {
|
|
// We need to allow loading any image or download any file
|
|
// to support image and OpenAPI blocks where the content reference could be external.
|
|
//
|
|
// Since I can't get the nonce to work for inline styles, we need to allow unsafe-inline
|
|
const defaultCSP = `
|
|
default-src 'self' ${assetsDomain};
|
|
script-src 'self' 'nonce-${nonce}' 'strict-dynamic' 'unsafe-inline' 'unsafe-eval' ${assetsDomain} https://integrations.gitbook.com https://cdn.iframe.ly;
|
|
style-src 'self' ${assetsDomain} fonts.googleapis.com 'unsafe-inline';
|
|
img-src * 'self' blob: data: files.gitbook.com ${assetsDomain};
|
|
connect-src * 'self' integrations.gitbook.com app.gitbook.com ${assetsDomain};
|
|
font-src 'self' fonts.gstatic.com ${assetsDomain};
|
|
frame-src *;
|
|
object-src 'none';
|
|
base-uri 'self' ${assetsDomain};
|
|
form-action 'self' ${assetsDomain};
|
|
frame-ancestors 'none';
|
|
`;
|
|
|
|
const result = scripts
|
|
.map(({ contentSecurityPolicy }) => contentSecurityPolicy)
|
|
.filter(filterOutNullable)
|
|
.reduce((csp, policy) => merge(csp, policy), defaultCSP);
|
|
|
|
return result
|
|
.replace(/\n/g, ' ')
|
|
.replace(/\s{2,}/g, ' ')
|
|
.trim();
|
|
}
|