UNPKG

postman-runtime

Version:

Underlying library of executing Postman Collections

131 lines (112 loc) 4.33 kB
var _ = require('lodash'), { resolveUrlString } = require('./util'); /** * Extract all variables with secret === true from a variable scope. * * @param {VariableScope|Object} scope - scope * @returns {Array} - variables */ function extractSecretVariables (scope) { if (!scope) { return []; } var values = _.get(scope, 'values'), secretVariables = []; if (!values || typeof values.each !== 'function') { return []; } values.each(function (variable) { if (variable && variable.secret === true) { secretVariables.push(variable); } }); return secretVariables; } /** * Build context object for resolver function * * @param {Object} payload - Request payload * @param {String} variableKey - The key of the variable being resolved * @returns {Object} - Context object */ function buildResolverContext (payload, variableKey) { return { item: payload.item, variableKey: variableKey }; } /** * Scans variable scopes for secrets and invokes the secretResolver with them. * Consumer returns array of { resolvedValue, error, allowedInScript }; runtime applies values. * * @param {Object} payload - Request payload * @param {Object} payload.item - The request item * @param {Object} payload.environment - Environment scope * @param {Object} payload.globals - Globals scope * @param {Object} payload.collectionVariables - Collection variables scope * @param {Object} payload.vaultSecrets - Vault secrets scope * @param {Object} payload._variables - Local variables scope * @param {Object} payload.data - Iteration data * @param {Function} secretResolver - Function({ secrets, urlString }, callback) that resolves secrets. * Callback is (err, result) where result is Array<{ resolvedValue?: string, error?: Error, * allowedInScript?: boolean }>. * @param {Function} callback - callback(err, secretResolutionErrors, forbiddenSecretKeys) */ function resolveSecrets (payload, secretResolver, callback) { if (!secretResolver || typeof secretResolver !== 'function') { return callback(); } var scopesToScan = [ { name: 'environment', scope: payload.environment }, { name: 'globals', scope: payload.globals }, { name: 'collectionVariables', scope: payload.collectionVariables } ], secrets = [], url = resolveUrlString(payload.item, payload), urlString = typeof url.toString === 'function' ? url.toString() : String(url); scopesToScan.forEach(function (scopeInfo) { var secretVars = extractSecretVariables(scopeInfo.scope); secretVars.forEach(function (variable) { secrets.push({ scopeName: scopeInfo.name, scope: scopeInfo.scope, variable: variable, context: buildResolverContext(payload, variable.key) }); }); }); if (secrets.length === 0) { return callback(); } secretResolver({ secrets, urlString }, function (err, result) { if (err) { return callback(err); } if (result && Array.isArray(result)) { result.forEach(function (entry, i) { var hasResolvedValue = entry && entry.resolvedValue !== undefined && typeof entry.resolvedValue === 'string'; if (i < secrets.length && hasResolvedValue) { secrets[i].variable.set(entry.resolvedValue); } }); } var secretResolutionErrors = (result && Array.isArray(result)) ? result.filter(function (entry) { return entry && entry.error; }) .map(function (entry) { return entry.error; }) : [], forbiddenSecretKeys = new Set(); if (result && Array.isArray(result)) { result.forEach(function (entry, i) { if (i < secrets.length && entry && entry.allowedInScript === false) { forbiddenSecretKeys.add(secrets[i].scopeName + ':' + secrets[i].variable.key); } }); } callback(null, secretResolutionErrors, forbiddenSecretKeys); }); } module.exports = { resolveSecrets, extractSecretVariables };