nodejs-typescript-service/src/http/content-security-policy.ts
2023-07-23 16:04:49 -07:00

64 lines
1.6 KiB
TypeScript

import { pino } from 'pino';
import { HttpConfig } from './server';
import * as sch from '../utilities/json-schema';
import { FastifyReply, FastifyInstance, FastifyRequest, RouteShorthandOptions } from 'fastify';
export const default_policy = `default-src 'self'`;
export const csp_report_schema = sch.obj({
'csp-report': sch.obj({
'document-uri': sch.str(),
'referrer': sch.str(),
'blocked-uri': sch.str(),
'violated-directive': sch.str(),
'original-policy': sch.str(),
'disposition': sch.str(),
'effective-directive': sch.str(),
'script-sample': sch.str(),
'status-code': sch.int(),
}, { additionalProperties: true })
});
export interface CSPReport {
'csp-report': {
'document-uri': string;
'referrer': string;
'blocked-uri': string;
'violated-directive': string;
'original-policy': string;
'disposition': string;
'effective-directive': string;
'script-sample': string;
'status-code': number;
};
}
export interface Dependencies {
logger: pino.Logger;
}
export function register_csp_report_endpoint(http_server: FastifyInstance, conf: HttpConfig, { logger }: Dependencies) {
const opts: RouteShorthandOptions = {
schema: {
response: {
204: { },
},
body: csp_report_schema
}
};
type Req = FastifyRequest<{
Body: CSPReport;
}>;
http_server.post('/.csp-report', opts, async (req: Req, res) => {
logger.warn(req.body['csp-report'], 'received content security policy report');
res.status(204);
});
}
export function csp_headers(res: FastifyReply, server_url: string, policy: string = default_policy) {
res.header('Content-Security-Policy', `${policy}; report-uri ${server_url}/.csp-report`);
}