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
This commit is contained in:
Pete Bacon Darwin 2021-06-16 12:18:37 +01:00 committed by Jessica Janiuk
parent 8da6f66f7b
commit a3b6d65580
2 changed files with 41 additions and 5 deletions

View File

@ -25,6 +25,12 @@ export interface NgccProjectConfig<T = RawNgccPackageConfig> {
* Options that control how locking the process is handled. * Options that control how locking the process is handled.
*/ */
locking?: ProcessLockingConfiguration; 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 { private processProjectConfig(projectConfig: NgccProjectConfig): PartiallyProcessedConfig {
const processedConfig: PartiallyProcessedConfig = {packages: {}, locking: {}}; const processedConfig:
PartiallyProcessedConfig = {packages: {}, locking: {}, hashAlgorithm: 'md5'};
// locking configuration // locking configuration
if (projectConfig.locking !== undefined) { if (projectConfig.locking !== undefined) {
@ -317,6 +324,11 @@ export class NgccConfiguration {
} }
} }
// hash algorithm config
if (projectConfig.hashAlgorithm !== undefined) {
processedConfig.hashAlgorithm = projectConfig.hashAlgorithm;
}
return processedConfig; return processedConfig;
} }
@ -378,7 +390,9 @@ export class NgccConfiguration {
} }
private computeHash(): string { 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');
} }
} }

View File

@ -48,7 +48,7 @@ runInEachFileSystem(() => {
}]); }]);
const project1Conf = new NgccConfiguration(fs, project1); const project1Conf = new NgccConfiguration(fs, project1);
const expectedProject1Config = 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) expect(project1Conf.hash)
.toEqual(createHash('md5').update(expectedProject1Config).digest('hex')); .toEqual(createHash('md5').update(expectedProject1Config).digest('hex'));
@ -66,7 +66,7 @@ runInEachFileSystem(() => {
}]); }]);
const project2Conf = new NgccConfiguration(fs, project2); const project2Conf = new NgccConfiguration(fs, project2);
const expectedProject2Config = 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) expect(project2Conf.hash)
.toEqual(createHash('md5').update(expectedProject2Config).digest('hex')); .toEqual(createHash('md5').update(expectedProject2Config).digest('hex'));
}); });
@ -76,9 +76,31 @@ runInEachFileSystem(() => {
const configuration = new NgccConfiguration(fs, _Abs('/project-1')); const configuration = new NgccConfiguration(fs, _Abs('/project-1'));
expect(configuration.hash) expect(configuration.hash)
.toEqual(createHash('md5') .toEqual(createHash('md5')
.update(JSON.stringify({packages: {}, locking: {}})) .update(JSON.stringify({packages: {}, locking: {}, hashAlgorithm: 'md5'}))
.digest('hex')); .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()', () => { describe('getPackageConfig()', () => {