From db00a24b3c00b30d29690bb50e032c494cc44c4e Mon Sep 17 00:00:00 2001 From: Bjarki Date: Thu, 24 Sep 2020 12:44:37 +0000 Subject: [PATCH] feat(@angular-devkit/build-angular): support custom headers in dev-server Make it possible to configure dev-server to send custom HTTP headers on every client request. These headers can be specified as a key-value map under the new "headers" property of the dev-server builder in angular.json. These headers are then passed on to the webpack devserver. An example use case for this is to enable various security features, such as CSP and Trusted Types, both in local application development and in integration tests, by setting appropriate HTTP headers. This is part of an effort to add support for Trusted Types in Angular. The ability to enforce Trusted Types during development and integration tests is essential, as this can help detect Trusted Types violations that might otherwise break applications when they're pushed to production where such security features may be enforced. --- .../build_angular/src/dev-server/index.ts | 7 +++++-- .../build_angular/src/dev-server/schema.json | 10 ++++++++++ .../build_angular/src/dev-server/works_spec.ts | 10 ++++++++++ 3 files changed, 25 insertions(+), 2 deletions(-) diff --git a/packages/angular_devkit/build_angular/src/dev-server/index.ts b/packages/angular_devkit/build_angular/src/dev-server/index.ts index 5e41084c2e75..bd91913e9c02 100644 --- a/packages/angular_devkit/build_angular/src/dev-server/index.ts +++ b/packages/angular_devkit/build_angular/src/dev-server/index.ts @@ -397,10 +397,13 @@ export function buildServerConfig( const servePath = buildServePath(serverOptions, browserOptions, logger); const { styles, scripts } = normalizeOptimization(browserOptions.optimization); - const config: WebpackDevServer.Configuration & { logLevel: string } = { + const config: WebpackDevServer.Configuration&{logLevel: string} = { host: serverOptions.host, port: serverOptions.port, - headers: { 'Access-Control-Allow-Origin': '*' }, + headers: { + 'Access-Control-Allow-Origin': '*', + ...serverOptions.headers, + }, historyApiFallback: !!browserOptions.index && { index: `${servePath}/${getIndexOutputFile(browserOptions)}`, disableDotRule: true, diff --git a/packages/angular_devkit/build_angular/src/dev-server/schema.json b/packages/angular_devkit/build_angular/src/dev-server/schema.json index c8a224e71e7e..28fd67c84ed8 100644 --- a/packages/angular_devkit/build_angular/src/dev-server/schema.json +++ b/packages/angular_devkit/build_angular/src/dev-server/schema.json @@ -36,6 +36,16 @@ "type": "string", "description": "SSL certificate to use for serving HTTPS." }, + "headers": { + "type": "object", + "description": "Custom HTTP headers to serve.", + "propertyNames": { + "pattern": "^[-_A-Za-z0-9]+$" + }, + "additionalProperties": { + "type": "string" + } + }, "open": { "type": "boolean", "description": "Opens the url in default browser.", diff --git a/packages/angular_devkit/build_angular/src/dev-server/works_spec.ts b/packages/angular_devkit/build_angular/src/dev-server/works_spec.ts index 4cbf32ce5841..c8ec85604300 100644 --- a/packages/angular_devkit/build_angular/src/dev-server/works_spec.ts +++ b/packages/angular_devkit/build_angular/src/dev-server/works_spec.ts @@ -102,4 +102,14 @@ describe('Dev Server Builder', () => { expect(hasSourceMaps).toBe(false, `Expected emitted files not to contain '.map' files.`); }); + it('serves custom headers', async () => { + const run = await architect.scheduleTarget( + target, {headers: {'X-Header': 'Hello World'}}); + runs.push(run); + const output = await run.result as DevServerBuilderOutput; + expect(output.success).toBe(true); + const response = await fetch('http://localhost:4200/index.html'); + expect(response.headers.get('X-Header')).toBe('Hello World'); + }, 30000); + });