From 673daeba332558af394dbe65a18d34e834fab423 Mon Sep 17 00:00:00 2001 From: Rahul Gautam Singh Date: Mon, 6 Jan 2025 14:58:07 +0530 Subject: [PATCH] handle encrypted config in presets --- lib/config/decrypt.spec.ts | 5 ++--- lib/config/decrypt.ts | 6 +++--- lib/workers/global/index.ts | 34 +++++++++++++++++++++++++++++++++- 3 files changed, 38 insertions(+), 7 deletions(-) diff --git a/lib/config/decrypt.spec.ts b/lib/config/decrypt.spec.ts index 3a056690dba2eb..7c45b73036f925 100644 --- a/lib/config/decrypt.spec.ts +++ b/lib/config/decrypt.spec.ts @@ -21,10 +21,10 @@ describe('config/decrypt', () => { expect(res).toMatchObject(config); }); - it('warns if no privateKey found', async () => { + it('warns if encryptedWarning is configured and encrypted object found', async () => { config.encrypted = { a: '1' }; GlobalConfig.set({ encryptedWarning: 'text' }); - + process.env.RENOVATE_X_ENCRYPTED_STRICT = 'false'; const res = await decryptConfig(config, repository); expect(logger.logger.once.warn).toHaveBeenCalledWith('text'); @@ -34,7 +34,6 @@ describe('config/decrypt', () => { it('throws exception if encrypted found but no privateKey', async () => { config.encrypted = { a: '1' }; - process.env.RENOVATE_X_ENCRYPTED_STRICT = 'true'; await expect(decryptConfig(config, repository)).rejects.toThrow( 'config-validation', diff --git a/lib/config/decrypt.ts b/lib/config/decrypt.ts index 80cddcd490830a..08853bf5a1446e 100644 --- a/lib/config/decrypt.ts +++ b/lib/config/decrypt.ts @@ -174,14 +174,14 @@ export async function decryptConfig( } } } else { - if (process.env.RENOVATE_X_ENCRYPTED_STRICT === 'true') { + if (process.env.RENOVATE_X_ENCRYPTED_STRICT === 'false') { + logger.error('Found encrypted data but no privateKey'); + } else { const error = new Error(CONFIG_VALIDATION); error.validationSource = 'config'; error.validationError = 'Encrypted config unsupported'; error.validationMessage = `This config contains an encrypted object at location \`$.${key}\` but no privateKey is configured. To support encrypted config, the Renovate administrator must configure a \`privateKey\` in Global Configuration.`; throw error; - } else { - logger.error('Found encrypted data but no privateKey'); } } delete decryptedConfig.encrypted; diff --git a/lib/workers/global/index.ts b/lib/workers/global/index.ts index 488be90108dfd7..bc9e3c1da46a4d 100644 --- a/lib/workers/global/index.ts +++ b/lib/workers/global/index.ts @@ -13,7 +13,10 @@ import type { RenovateConfig, RenovateRepository, } from '../../config/types'; -import { CONFIG_PRESETS_INVALID } from '../../constants/error-messages'; +import { + CONFIG_PRESETS_INVALID, + CONFIG_VALIDATION, +} from '../../constants/error-messages'; import { pkg } from '../../expose.cjs'; import { instrument } from '../../instrumentation'; import { exportStats, finalizeReport } from '../../instrumentation/reporting'; @@ -145,6 +148,9 @@ export async function start(): Promise { ); } + // istanbul ignore next + checkEncryptedObject(config); + // Set allowedHeaders in case hostRules headers are configured in file config GlobalConfig.set({ allowedHeaders: config.allowedHeaders, @@ -248,3 +254,29 @@ export async function start(): Promise { } return 0; } + +function checkEncryptedObject(config: AllConfig): void { + for (const [key, val] of Object.entries(config)) { + if (key === 'encrypted' && is.object(val)) { + if (!config.privateKey) { + if (process.env.RENOVATE_X_ENCRYPTED_STRICT === 'false') { + logger.error('Found encrypted data but no privateKey'); + } else { + const error = new Error(CONFIG_VALIDATION); + error.validationSource = 'config'; + error.validationError = 'Encrypted config unsupported'; + error.validationMessage = `This config contains an encrypted object at location \`$.${key}\` but no privateKey is configured. To support encrypted config, the Renovate administrator must configure a \`privateKey\` in Global Configuration.`; + throw error; + } + } + } else if (is.array(val)) { + for (const item of val) { + if (is.object(item) && !is.array(item)) { + checkEncryptedObject(item as AllConfig); + } + } + } else if (is.object(val) && key !== 'content') { + checkEncryptedObject(val as AllConfig); + } + } +}