'use strict'; var getHomeDir = require('./getHomeDir'); var getSSOTokenFilepath = require('./getSSOTokenFilepath'); var getSSOTokenFromFile = require('./getSSOTokenFromFile'); var path = require('path'); var types = require('@smithy/types'); var slurpFile = require('./slurpFile'); const ENV_PROFILE = "AWS_PROFILE"; const DEFAULT_PROFILE = "default"; const getProfileName = (init) => init.profile || process.env[ENV_PROFILE] || DEFAULT_PROFILE; const getConfigData = (data) => Object.entries(data) .filter(([key]) => { const indexOfSeparator = key.indexOf(CONFIG_PREFIX_SEPARATOR); if (indexOfSeparator === -1) { return false; } return Object.values(types.IniSectionType).includes(key.substring(0, indexOfSeparator)); }) .reduce((acc, [key, value]) => { const indexOfSeparator = key.indexOf(CONFIG_PREFIX_SEPARATOR); const updatedKey = key.substring(0, indexOfSeparator) === types.IniSectionType.PROFILE ? key.substring(indexOfSeparator + 1) : key; acc[updatedKey] = value; return acc; }, { ...(data.default && { default: data.default }), }); const ENV_CONFIG_PATH = "AWS_CONFIG_FILE"; const getConfigFilepath = () => process.env[ENV_CONFIG_PATH] || path.join(getHomeDir.getHomeDir(), ".aws", "config"); const ENV_CREDENTIALS_PATH = "AWS_SHARED_CREDENTIALS_FILE"; const getCredentialsFilepath = () => process.env[ENV_CREDENTIALS_PATH] || path.join(getHomeDir.getHomeDir(), ".aws", "credentials"); const prefixKeyRegex = /^([\w-]+)\s(["'])?([\w-@\+\.%:/]+)\2$/; const profileNameBlockList = ["__proto__", "profile __proto__"]; const parseIni = (iniData) => { const map = {}; let currentSection; let currentSubSection; for (const iniLine of iniData.split(/\r?\n/)) { const trimmedLine = iniLine.split(/(^|\s)[;#]/)[0].trim(); const isSection = trimmedLine[0] === "[" && trimmedLine[trimmedLine.length - 1] === "]"; if (isSection) { currentSection = undefined; currentSubSection = undefined; const sectionName = trimmedLine.substring(1, trimmedLine.length - 1); const matches = prefixKeyRegex.exec(sectionName); if (matches) { const [, prefix, , name] = matches; if (Object.values(types.IniSectionType).includes(prefix)) { currentSection = [prefix, name].join(CONFIG_PREFIX_SEPARATOR); } } else { currentSection = sectionName; } if (profileNameBlockList.includes(sectionName)) { throw new Error(`Found invalid profile name "${sectionName}"`); } } else if (currentSection) { const indexOfEqualsSign = trimmedLine.indexOf("="); if (![0, -1].includes(indexOfEqualsSign)) { const [name, value] = [ trimmedLine.substring(0, indexOfEqualsSign).trim(), trimmedLine.substring(indexOfEqualsSign + 1).trim(), ]; if (value === "") { currentSubSection = name; } else { if (currentSubSection && iniLine.trimStart() === iniLine) { currentSubSection = undefined; } map[currentSection] = map[currentSection] || {}; const key = currentSubSection ? [currentSubSection, name].join(CONFIG_PREFIX_SEPARATOR) : name; map[currentSection][key] = value; } } } } return map; }; const swallowError$1 = () => ({}); const CONFIG_PREFIX_SEPARATOR = "."; const loadSharedConfigFiles = async (init = {}) => { const { filepath = getCredentialsFilepath(), configFilepath = getConfigFilepath() } = init; const homeDir = getHomeDir.getHomeDir(); const relativeHomeDirPrefix = "~/"; let resolvedFilepath = filepath; if (filepath.startsWith(relativeHomeDirPrefix)) { resolvedFilepath = path.join(homeDir, filepath.slice(2)); } let resolvedConfigFilepath = configFilepath; if (configFilepath.startsWith(relativeHomeDirPrefix)) { resolvedConfigFilepath = path.join(homeDir, configFilepath.slice(2)); } const parsedFiles = await Promise.all([ slurpFile.slurpFile(resolvedConfigFilepath, { ignoreCache: init.ignoreCache, }) .then(parseIni) .then(getConfigData) .catch(swallowError$1), slurpFile.slurpFile(resolvedFilepath, { ignoreCache: init.ignoreCache, }) .then(parseIni) .catch(swallowError$1), ]); return { configFile: parsedFiles[0], credentialsFile: parsedFiles[1], }; }; const getSsoSessionData = (data) => Object.entries(data) .filter(([key]) => key.startsWith(types.IniSectionType.SSO_SESSION + CONFIG_PREFIX_SEPARATOR)) .reduce((acc, [key, value]) => ({ ...acc, [key.substring(key.indexOf(CONFIG_PREFIX_SEPARATOR) + 1)]: value }), {}); const swallowError = () => ({}); const loadSsoSessionData = async (init = {}) => slurpFile.slurpFile(init.configFilepath ?? getConfigFilepath()) .then(parseIni) .then(getSsoSessionData) .catch(swallowError); const mergeConfigFiles = (...files) => { const merged = {}; for (const file of files) { for (const [key, values] of Object.entries(file)) { if (merged[key] !== undefined) { Object.assign(merged[key], values); } else { merged[key] = values; } } } return merged; }; const parseKnownFiles = async (init) => { const parsedFiles = await loadSharedConfigFiles(init); return mergeConfigFiles(parsedFiles.configFile, parsedFiles.credentialsFile); }; const externalDataInterceptor = { getFileRecord() { return slurpFile.fileIntercept; }, interceptFile(path, contents) { slurpFile.fileIntercept[path] = Promise.resolve(contents); }, getTokenRecord() { return getSSOTokenFromFile.tokenIntercept; }, interceptToken(id, contents) { getSSOTokenFromFile.tokenIntercept[id] = contents; }, }; Object.defineProperty(exports, "getSSOTokenFromFile", { enumerable: true, get: function () { return getSSOTokenFromFile.getSSOTokenFromFile; } }); exports.CONFIG_PREFIX_SEPARATOR = CONFIG_PREFIX_SEPARATOR; exports.DEFAULT_PROFILE = DEFAULT_PROFILE; exports.ENV_PROFILE = ENV_PROFILE; exports.externalDataInterceptor = externalDataInterceptor; exports.getProfileName = getProfileName; exports.loadSharedConfigFiles = loadSharedConfigFiles; exports.loadSsoSessionData = loadSsoSessionData; exports.parseKnownFiles = parseKnownFiles; Object.keys(getHomeDir).forEach(function (k) { if (k !== 'default' && !Object.prototype.hasOwnProperty.call(exports, k)) Object.defineProperty(exports, k, { enumerable: true, get: function () { return getHomeDir[k]; } }); }); Object.keys(getSSOTokenFilepath).forEach(function (k) { if (k !== 'default' && !Object.prototype.hasOwnProperty.call(exports, k)) Object.defineProperty(exports, k, { enumerable: true, get: function () { return getSSOTokenFilepath[k]; } }); });