From a3b6d65580b90c2ef68281f54fec0934869c1e4b Mon Sep 17 00:00:00 2001 From: Pete Bacon Darwin Date: Wed, 16 Jun 2021 12:18:37 +0100 Subject: [PATCH] refactor(compiler-cli): make ngcc configuration hash algorithm configurable! (#42582) The ngcc configuration gets hashed to be used when caching but it was hardcoded to use the `md5` algorithm, which is not FIPS compliant. Now the hash algorithm can be configured in the ngcc.config.js file at the project level. PR Close #42582 --- .../ngcc/src/packages/configuration.ts | 18 ++++++++++-- .../ngcc/test/packages/configuration_spec.ts | 28 +++++++++++++++++-- 2 files changed, 41 insertions(+), 5 deletions(-) diff --git a/packages/compiler-cli/ngcc/src/packages/configuration.ts b/packages/compiler-cli/ngcc/src/packages/configuration.ts index 93583509b1..1c1ef82b5e 100644 --- a/packages/compiler-cli/ngcc/src/packages/configuration.ts +++ b/packages/compiler-cli/ngcc/src/packages/configuration.ts @@ -25,6 +25,12 @@ export interface NgccProjectConfig { * Options that control how locking the process is handled. */ locking?: ProcessLockingConfiguration; + /** + * Name of hash algorithm used to generate hashes of the configuration. + * + * Defaults to `md5`. + */ + hashAlgorithm?: string; } /** @@ -299,7 +305,8 @@ export class NgccConfiguration { } private processProjectConfig(projectConfig: NgccProjectConfig): PartiallyProcessedConfig { - const processedConfig: PartiallyProcessedConfig = {packages: {}, locking: {}}; + const processedConfig: + PartiallyProcessedConfig = {packages: {}, locking: {}, hashAlgorithm: 'md5'}; // locking configuration if (projectConfig.locking !== undefined) { @@ -317,6 +324,11 @@ export class NgccConfiguration { } } + // hash algorithm config + if (projectConfig.hashAlgorithm !== undefined) { + processedConfig.hashAlgorithm = projectConfig.hashAlgorithm; + } + return processedConfig; } @@ -378,7 +390,9 @@ export class NgccConfiguration { } private computeHash(): string { - return createHash('md5').update(JSON.stringify(this.projectConfig)).digest('hex'); + return createHash(this.projectConfig.hashAlgorithm) + .update(JSON.stringify(this.projectConfig)) + .digest('hex'); } } diff --git a/packages/compiler-cli/ngcc/test/packages/configuration_spec.ts b/packages/compiler-cli/ngcc/test/packages/configuration_spec.ts index fe227ea6f3..93e57cec3f 100644 --- a/packages/compiler-cli/ngcc/test/packages/configuration_spec.ts +++ b/packages/compiler-cli/ngcc/test/packages/configuration_spec.ts @@ -48,7 +48,7 @@ runInEachFileSystem(() => { }]); const project1Conf = new NgccConfiguration(fs, project1); const expectedProject1Config = - `{"packages":{"package-1":[{"entryPoints":{"./entry-point-1":{}},"versionRange":"*"}]},"locking":{}}`; + `{"packages":{"package-1":[{"entryPoints":{"./entry-point-1":{}},"versionRange":"*"}]},"locking":{},"hashAlgorithm":"md5"}`; expect(project1Conf.hash) .toEqual(createHash('md5').update(expectedProject1Config).digest('hex')); @@ -66,7 +66,7 @@ runInEachFileSystem(() => { }]); const project2Conf = new NgccConfiguration(fs, project2); const expectedProject2Config = - `{"packages":{"package-1":[{"entryPoints":{"./entry-point-1":{"ignore":true}},"versionRange":"*"}]},"locking":{}}`; + `{"packages":{"package-1":[{"entryPoints":{"./entry-point-1":{"ignore":true}},"versionRange":"*"}]},"locking":{},"hashAlgorithm":"md5"}`; expect(project2Conf.hash) .toEqual(createHash('md5').update(expectedProject2Config).digest('hex')); }); @@ -76,9 +76,31 @@ runInEachFileSystem(() => { const configuration = new NgccConfiguration(fs, _Abs('/project-1')); expect(configuration.hash) .toEqual(createHash('md5') - .update(JSON.stringify({packages: {}, locking: {}})) + .update(JSON.stringify({packages: {}, locking: {}, hashAlgorithm: 'md5'})) .digest('hex')); }); + + it('should use a custom hash algorithm if specified in the config', () => { + const project1 = _Abs('/project-1'); + const project1Config = fs.resolve(project1, 'ngcc.config.js'); + + loadTestFiles([{ + name: project1Config, + contents: ` + module.exports = { + packages: { + 'package-1': {entryPoints: {'./entry-point-1': {}}}, + }, + hashAlgorithm: 'sha256', + };` + }]); + const project1Conf = new NgccConfiguration(fs, project1); + const expectedProject1Config = + `{"packages":{"package-1":[{"entryPoints":{"./entry-point-1":{}},"versionRange":"*"}]},"locking":{},"hashAlgorithm":"sha256"}`; + expect(JSON.stringify((project1Conf as any).projectConfig)).toEqual(expectedProject1Config); + expect(project1Conf.hash) + .toEqual(createHash('sha256').update(expectedProject1Config).digest('hex')); + }); }); describe('getPackageConfig()', () => {