UNPKG

renovate

Version:

Automated dependency updates. Flexible so you don't need to be.

106 lines 4.4 kB
"use strict"; Object.defineProperty(exports, "__esModule", { value: true }); exports.validateConfigSecrets = validateConfigSecrets; exports.applySecretsToConfig = applySecretsToConfig; const tslib_1 = require("tslib"); const is_1 = tslib_1.__importDefault(require("@sindresorhus/is")); const error_messages_1 = require("../constants/error-messages"); const logger_1 = require("../logger"); const regex_1 = require("../util/regex"); const sanitize_1 = require("../util/sanitize"); const secretNamePattern = '[A-Za-z][A-Za-z0-9_]*'; const secretNameRegex = (0, regex_1.regEx)(`^${secretNamePattern}$`); const secretTemplateRegex = (0, regex_1.regEx)(`{{ secrets\\.(${secretNamePattern}) }}`); function validateSecrets(secrets_) { if (!secrets_) { return; } const validationErrors = []; if (is_1.default.plainObject(secrets_)) { for (const [secretName, secretValue] of Object.entries(secrets_)) { if (!secretNameRegex.test(secretName)) { validationErrors.push(`Invalid secret name "${secretName}"`); } if (!is_1.default.string(secretValue)) { validationErrors.push(`Secret values must be strings. Found type ${typeof secretValue} for secret ${secretName}`); } } } else { validationErrors.push(`Config secrets must be a plain object. Found: ${typeof secrets_}`); } if (validationErrors.length) { logger_1.logger.error({ validationErrors }, 'Invalid secrets configured'); throw new Error(error_messages_1.CONFIG_SECRETS_INVALID); } } function validateConfigSecrets(config) { validateSecrets(config.secrets); if (config.repositories) { for (const repository of config.repositories) { if (is_1.default.plainObject(repository)) { validateSecrets(repository.secrets); } } } } function replaceSecretsInString(key, value, secrets) { // do nothing if no secret template found if (!secretTemplateRegex.test(value)) { return value; } const disallowedPrefixes = ['branch', 'commit', 'group', 'pr', 'semantic']; if (disallowedPrefixes.some((prefix) => key.startsWith(prefix))) { const error = new Error(error_messages_1.CONFIG_VALIDATION); error.validationSource = 'config'; error.validationError = 'Disallowed secret substitution'; error.validationMessage = `The field \`${key}\` may not use secret substitution`; throw error; } return value.replace(secretTemplateRegex, (_, secretName) => { if (secrets?.[secretName]) { return secrets[secretName]; } const error = new Error(error_messages_1.CONFIG_VALIDATION); error.validationSource = 'config'; error.validationError = 'Unknown secret name'; error.validationMessage = `The following secret name was not found in config: ${String(secretName)}`; throw error; }); } function replaceSecretsInObject(config_, secrets, deleteSecrets) { const config = { ...config_ }; if (deleteSecrets) { delete config.secrets; } for (const [key, value] of Object.entries(config)) { if (is_1.default.plainObject(value)) { config[key] = replaceSecretsInObject(value, secrets, deleteSecrets); } if (is_1.default.string(value)) { config[key] = replaceSecretsInString(key, value, secrets); } if (is_1.default.array(value)) { for (const [arrayIndex, arrayItem] of value.entries()) { if (is_1.default.plainObject(arrayItem)) { value[arrayIndex] = replaceSecretsInObject(arrayItem, secrets, deleteSecrets); } else if (is_1.default.string(arrayItem)) { value[arrayIndex] = replaceSecretsInString(key, arrayItem, secrets); } } } } return config; } function applySecretsToConfig(config, secrets = config.secrets, deleteSecrets = true) { // Add all secrets to be sanitized if (is_1.default.plainObject(secrets)) { for (const secret of Object.values(secrets)) { (0, sanitize_1.addSecretForSanitizing)(secret); } } // TODO: fix types (#9610) return replaceSecretsInObject(config, secrets, deleteSecrets); } //# sourceMappingURL=secrets.js.map