diff --git a/packages/credential-provider-ini/src/fromIni.ts b/packages/credential-provider-ini/src/fromIni.ts index 52752eb96be9f..803c65bc158a1 100644 --- a/packages/credential-provider-ini/src/fromIni.ts +++ b/packages/credential-provider-ini/src/fromIni.ts @@ -1,11 +1,11 @@ import { AssumeRoleWithWebIdentityParams } from "@aws-sdk/credential-provider-web-identity"; -import { getProfileName, parseKnownFiles, SourceProfileInit } from "@aws-sdk/shared-ini-file-loader"; +import { getProfileName, parseKnownFiles } from "@aws-sdk/shared-ini-file-loader"; import { CredentialProvider, Credentials } from "@aws-sdk/types"; import { AssumeRoleParams } from "./resolveAssumeRoleCredentials"; import { resolveProfileData } from "./resolveProfileData"; -export interface FromIniInit extends SourceProfileInit { +export interface FromIniInit { /** * A function that returns a promise fulfilled with an MFA token code for * the provided MFA Serial code. If a profile requires an MFA code and @@ -42,6 +42,6 @@ export interface FromIniInit extends SourceProfileInit { export const fromIni = (init: FromIniInit = {}): CredentialProvider => async () => { - const profiles = await parseKnownFiles(init); - return resolveProfileData(getProfileName(init), profiles, init); + const profiles = await parseKnownFiles(); + return resolveProfileData(getProfileName(), profiles, init); }; diff --git a/packages/credential-provider-ini/src/resolveAssumeRoleCredentials.ts b/packages/credential-provider-ini/src/resolveAssumeRoleCredentials.ts index b0ea7926a26aa..c69e68bb09dea 100644 --- a/packages/credential-provider-ini/src/resolveAssumeRoleCredentials.ts +++ b/packages/credential-provider-ini/src/resolveAssumeRoleCredentials.ts @@ -83,7 +83,7 @@ export const resolveAssumeRoleCredentials = async ( if (source_profile && source_profile in visitedProfiles) { throw new CredentialsProviderError( `Detected a cycle attempting to resolve credentials for profile` + - ` ${getProfileName(options)}. Profiles visited: ` + + ` ${getProfileName()}. Profiles visited: ` + Object.keys(visitedProfiles).join(", "), false ); diff --git a/packages/credential-provider-node/src/defaultProvider.ts b/packages/credential-provider-node/src/defaultProvider.ts index 7efc5c8828d82..71977161e33ab 100644 --- a/packages/credential-provider-node/src/defaultProvider.ts +++ b/packages/credential-provider-node/src/defaultProvider.ts @@ -50,14 +50,14 @@ export const defaultProvider = ( const options = { profile: process.env[ENV_PROFILE], ...init, - ...(!init.loadedConfig && { loadedConfig: loadSharedConfigFiles(init) }), + ...(!init.loadedConfig && { loadedConfig: loadSharedConfigFiles() }), }; const providerChain = chain( ...(options.profile ? [] : [fromEnv()]), fromSSO(options), fromIni(options), - fromProcess(options), + fromProcess(), fromTokenFile(options), remoteProvider(options), async () => { diff --git a/packages/credential-provider-process/src/fromProcess.ts b/packages/credential-provider-process/src/fromProcess.ts index 037c5e5d8460a..600f19f3be4d0 100644 --- a/packages/credential-provider-process/src/fromProcess.ts +++ b/packages/credential-provider-process/src/fromProcess.ts @@ -1,17 +1,13 @@ -import { getProfileName, parseKnownFiles, SourceProfileInit } from "@aws-sdk/shared-ini-file-loader"; +import { getProfileName, parseKnownFiles } from "@aws-sdk/shared-ini-file-loader"; import { CredentialProvider } from "@aws-sdk/types"; import { resolveProcessCredentials } from "./resolveProcessCredentials"; -export interface FromProcessInit extends SourceProfileInit {} - /** * Creates a credential provider that will read from a credential_process specified * in ini files. */ -export const fromProcess = - (init: FromProcessInit = {}): CredentialProvider => - async () => { - const profiles = await parseKnownFiles(init); - return resolveProcessCredentials(getProfileName(init), profiles); - }; +export const fromProcess = (): CredentialProvider => async () => { + const profiles = await parseKnownFiles(); + return resolveProcessCredentials(getProfileName(), profiles); +}; diff --git a/packages/credential-provider-sso/src/fromSSO.ts b/packages/credential-provider-sso/src/fromSSO.ts index f57d4f4a788f4..27b761e433a96 100644 --- a/packages/credential-provider-sso/src/fromSSO.ts +++ b/packages/credential-provider-sso/src/fromSSO.ts @@ -1,6 +1,6 @@ import { SSOClient } from "@aws-sdk/client-sso"; import { CredentialsProviderError } from "@aws-sdk/property-provider"; -import { getProfileName, parseKnownFiles, SourceProfileInit } from "@aws-sdk/shared-ini-file-loader"; +import { getProfileName, parseKnownFiles } from "@aws-sdk/shared-ini-file-loader"; import { CredentialProvider } from "@aws-sdk/types"; import { isSsoProfile } from "./isSsoProfile"; @@ -29,7 +29,7 @@ export interface SsoCredentialsParameters { ssoRoleName: string; } -export interface FromSSOInit extends SourceProfileInit { +export interface FromSSOInit { ssoClient?: SSOClient; } @@ -43,8 +43,8 @@ export const fromSSO = const { ssoStartUrl, ssoAccountId, ssoRegion, ssoRoleName, ssoClient } = init; if (!ssoStartUrl && !ssoAccountId && !ssoRegion && !ssoRoleName) { // Load the SSO config from shared AWS config file. - const profiles = await parseKnownFiles(init); - const profileName = getProfileName(init); + const profiles = await parseKnownFiles(); + const profileName = getProfileName(); const profile = profiles[profileName]; if (!isSsoProfile(profile)) { diff --git a/packages/node-config-provider/src/configLoader.spec.ts b/packages/node-config-provider/src/configLoader.spec.ts index 7efe471350863..7e84fd132cbb6 100644 --- a/packages/node-config-provider/src/configLoader.spec.ts +++ b/packages/node-config-provider/src/configLoader.spec.ts @@ -10,10 +10,6 @@ jest.mock("./fromSharedConfigFiles"); jest.mock("@aws-sdk/property-provider"); describe("loadConfig", () => { - const configuration: SharedConfigInit = { - profile: "profile", - }; - afterEach(() => { jest.clearAllMocks(); }); @@ -28,18 +24,15 @@ describe("loadConfig", () => { const envVarSelector = (env: NodeJS.ProcessEnv) => env["AWS_CONFIG_FOO"]; const configKey = (profile: Profile) => profile["aws_config_foo"]; const defaultValue = "foo-value"; - loadConfig( - { - environmentVariableSelector: envVarSelector, - configFileSelector: configKey, - default: defaultValue, - }, - configuration - ); + loadConfig({ + environmentVariableSelector: envVarSelector, + configFileSelector: configKey, + default: defaultValue, + }); expect(fromEnv).toHaveBeenCalledTimes(1); expect(fromEnv).toHaveBeenCalledWith(envVarSelector); expect(fromSharedConfigFiles).toHaveBeenCalledTimes(1); - expect(fromSharedConfigFiles).toHaveBeenCalledWith(configKey, configuration); + expect(fromSharedConfigFiles).toHaveBeenCalledWith(configKey, {}); expect(fromStatic).toHaveBeenCalledTimes(1); expect(fromStatic).toHaveBeenCalledWith(defaultValue); expect(chain).toHaveBeenCalledTimes(1); diff --git a/packages/node-config-provider/src/fromSharedConfigFiles.spec.ts b/packages/node-config-provider/src/fromSharedConfigFiles.spec.ts index ed6680abada62..ec975fe264271 100644 --- a/packages/node-config-provider/src/fromSharedConfigFiles.spec.ts +++ b/packages/node-config-provider/src/fromSharedConfigFiles.spec.ts @@ -39,6 +39,7 @@ describe("fromSharedConfigFiles", () => { } & SharedConfigInit; const loadedConfigResolves: (LoadedConfigTestData & { + profile?: string; configValueToVerify: string; })[] = [ { @@ -97,7 +98,9 @@ describe("fromSharedConfigFiles", () => { }, ]; - const loadedConfigRejects: LoadedConfigTestData[] = [ + const loadedConfigRejects: (LoadedConfigTestData & { + profile?: string; + })[] = [ { message: "rejects if default profile is not present and profile value is not passed", iniDataInConfig: { @@ -123,9 +126,8 @@ describe("fromSharedConfigFiles", () => { configFile: iniDataInConfig, credentialsFile: iniDataInCredentials, }); - return expect(fromSharedConfigFiles(configGetter, { profile, preferredFile })()).resolves.toBe( - configValueToVerify - ); + if (profile) process.env[ENV_PROFILE] = profile; + return expect(fromSharedConfigFiles(configGetter, { preferredFile })()).resolves.toBe(configValueToVerify); }); } ); @@ -136,41 +138,14 @@ describe("fromSharedConfigFiles", () => { configFile: iniDataInConfig, credentialsFile: iniDataInCredentials, }); - return expect(fromSharedConfigFiles(configGetter, { profile, preferredFile })()).rejects.toMatchObject( + if (profile) process.env[ENV_PROFILE] = profile; + return expect(fromSharedConfigFiles(configGetter, { preferredFile })()).rejects.toMatchObject( getCredentialsProviderError(profile ?? "default", configGetter) ); }); }); }); - describe("uses pre-loaded config if supplied", () => { - loadedConfigResolves.forEach( - ({ message, iniDataInConfig, iniDataInCredentials, configValueToVerify, profile, preferredFile }) => { - it(`${message} from config file`, () => { - const loadedConfig = Promise.resolve({ - configFile: iniDataInConfig, - credentialsFile: iniDataInCredentials, - }); - return expect( - fromSharedConfigFiles(configGetter, { loadedConfig, profile, preferredFile })() - ).resolves.toBe(configValueToVerify); - }); - } - ); - - loadedConfigRejects.forEach(({ message, iniDataInConfig, iniDataInCredentials, profile, preferredFile }) => { - it(message, () => { - const loadedConfig = Promise.resolve({ - configFile: iniDataInConfig, - credentialsFile: iniDataInCredentials, - }); - return expect( - fromSharedConfigFiles(configGetter, { loadedConfig, profile, preferredFile })() - ).rejects.toMatchObject(getCredentialsProviderError(profile ?? "default", configGetter)); - }); - }); - }); - it("rejects if getter throws", () => { const message = "Cannot load config"; const failGetter = () => { @@ -194,19 +169,22 @@ describe("fromSharedConfigFiles", () => { default: { [configKey]: "credentialsFileDefault" }, }, }; - const loadedConfig = Promise.resolve(loadedConfigData); describe("when profile is not defined", () => { + beforeEach(() => { + (loadSharedConfigFiles as jest.Mock).mockResolvedValueOnce(loadedConfigData); + }); + it(`returns configValue from value in '${ENV_PROFILE}' env var if it is set`, () => { const profile = "foo"; process.env[ENV_PROFILE] = profile; - return expect(fromSharedConfigFiles(configGetter, { loadedConfig })()).resolves.toBe( + return expect(fromSharedConfigFiles(configGetter, {})()).resolves.toBe( loadedConfigData.configFile[profile][configKey] ); }); it(`returns configValue from default profile if '${ENV_PROFILE}' env var is not set`, () => { - return expect(fromSharedConfigFiles(configGetter, { loadedConfig })()).resolves.toBe( + return expect(fromSharedConfigFiles(configGetter, {})()).resolves.toBe( loadedConfigData.configFile.default[configKey] ); }); diff --git a/packages/node-config-provider/src/fromSharedConfigFiles.ts b/packages/node-config-provider/src/fromSharedConfigFiles.ts index 5094f16b00586..19257d349c26d 100644 --- a/packages/node-config-provider/src/fromSharedConfigFiles.ts +++ b/packages/node-config-provider/src/fromSharedConfigFiles.ts @@ -1,30 +1,17 @@ import { CredentialsProviderError } from "@aws-sdk/property-provider"; -import { loadSharedConfigFiles, SharedConfigInit as BaseSharedConfigInit } from "@aws-sdk/shared-ini-file-loader"; -import { Profile, Provider, SharedConfigFiles } from "@aws-sdk/types"; +import { loadSharedConfigFiles } from "@aws-sdk/shared-ini-file-loader"; +import { Profile, Provider } from "@aws-sdk/types"; const DEFAULT_PROFILE = "default"; export const ENV_PROFILE = "AWS_PROFILE"; -export interface SharedConfigInit extends BaseSharedConfigInit { - /** - * The configuration profile to use. - */ - profile?: string; - +export interface SharedConfigInit { /** * The preferred shared ini file to load the config. "config" option refers to * the shared config file(defaults to `~/.aws/config`). "credentials" option * refers to the shared credentials file(defaults to `~/.aws/credentials`) */ preferredFile?: "config" | "credentials"; - - /** - * A promise that will be resolved with loaded and parsed credentials files. - * Used to avoid loading shared config files multiple times. - * - * @internal - */ - loadedConfig?: Promise; } export type GetterFromConfig = (profile: Profile) => T | undefined; @@ -33,12 +20,10 @@ export type GetterFromConfig = (profile: Profile) => T | undefined; * Get config value from the shared config files with inferred profile name. */ export const fromSharedConfigFiles = - ( - configSelector: GetterFromConfig, - { preferredFile = "config", ...init }: SharedConfigInit = {} - ): Provider => + (configSelector: GetterFromConfig, { preferredFile = "config" }: SharedConfigInit = {}): Provider => async () => { - const { loadedConfig = loadSharedConfigFiles(init), profile = process.env[ENV_PROFILE] || DEFAULT_PROFILE } = init; + const loadedConfig = loadSharedConfigFiles(); + const profile = process.env[ENV_PROFILE] || DEFAULT_PROFILE; const { configFile, credentialsFile } = await loadedConfig; diff --git a/packages/shared-ini-file-loader/src/getProfileName.ts b/packages/shared-ini-file-loader/src/getProfileName.ts index 0844812c77a47..c884e8c8de0a9 100644 --- a/packages/shared-ini-file-loader/src/getProfileName.ts +++ b/packages/shared-ini-file-loader/src/getProfileName.ts @@ -1,5 +1,4 @@ export const ENV_PROFILE = "AWS_PROFILE"; export const DEFAULT_PROFILE = "default"; -export const getProfileName = (init: { profile?: string }): string => - init.profile || process.env[ENV_PROFILE] || DEFAULT_PROFILE; +export const getProfileName = (): string => process.env[ENV_PROFILE] || DEFAULT_PROFILE; diff --git a/packages/shared-ini-file-loader/src/loadSharedConfigFiles.ts b/packages/shared-ini-file-loader/src/loadSharedConfigFiles.ts index 895a73a5046c9..1a076ceb41b9b 100644 --- a/packages/shared-ini-file-loader/src/loadSharedConfigFiles.ts +++ b/packages/shared-ini-file-loader/src/loadSharedConfigFiles.ts @@ -9,29 +9,11 @@ import { slurpFile } from "./slurpFile"; export const ENV_CREDENTIALS_PATH = "AWS_SHARED_CREDENTIALS_FILE"; export const ENV_CONFIG_PATH = "AWS_CONFIG_FILE"; -export interface SharedConfigInit { - /** - * The path at which to locate the ini credentials file. Defaults to the - * value of the `AWS_SHARED_CREDENTIALS_FILE` environment variable (if - * defined) or `~/.aws/credentials` otherwise. - */ - filepath?: string; - - /** - * The path at which to locate the ini config file. Defaults to the value of - * the `AWS_CONFIG_FILE` environment variable (if defined) or - * `~/.aws/config` otherwise. - */ - configFilepath?: string; -} - const swallowError = () => ({}); -export const loadSharedConfigFiles = async (init: SharedConfigInit = {}): Promise => { - const { - filepath = process.env[ENV_CREDENTIALS_PATH] || join(getHomeDir(), ".aws", "credentials"), - configFilepath = process.env[ENV_CONFIG_PATH] || join(getHomeDir(), ".aws", "config"), - } = init; +export const loadSharedConfigFiles = async (): Promise => { + const filepath = process.env[ENV_CREDENTIALS_PATH] || join(getHomeDir(), ".aws", "credentials"); + const configFilepath = process.env[ENV_CONFIG_PATH] || join(getHomeDir(), ".aws", "config"); const parsedFiles = await Promise.all([ slurpFile(configFilepath).then(parseIni).then(normalizeConfigFile).catch(swallowError), diff --git a/packages/shared-ini-file-loader/src/parseKnownFiles.ts b/packages/shared-ini-file-loader/src/parseKnownFiles.ts index 3fd8e29dd029d..05b6fcef25b3f 100644 --- a/packages/shared-ini-file-loader/src/parseKnownFiles.ts +++ b/packages/shared-ini-file-loader/src/parseKnownFiles.ts @@ -1,21 +1,6 @@ -import { ParsedIniData, SharedConfigFiles } from "@aws-sdk/types"; +import { ParsedIniData } from "@aws-sdk/types"; -import { loadSharedConfigFiles, SharedConfigInit } from "./loadSharedConfigFiles"; - -export interface SourceProfileInit extends SharedConfigInit { - /** - * The configuration profile to use. - */ - profile?: string; - - /** - * A promise that will be resolved with loaded and parsed credentials files. - * Used to avoid loading shared config files multiple times. - * - * @internal - */ - loadedConfig?: Promise; -} +import { loadSharedConfigFiles } from "./loadSharedConfigFiles"; /** * Load profiles from credentials and config INI files and normalize them into a @@ -23,8 +8,8 @@ export interface SourceProfileInit extends SharedConfigInit { * * @internal */ -export const parseKnownFiles = async (init: SourceProfileInit): Promise => { - const { loadedConfig = loadSharedConfigFiles(init) } = init; +export const parseKnownFiles = async (): Promise => { + const loadedConfig = loadSharedConfigFiles(); const parsedFiles = await loadedConfig; return { diff --git a/packages/util-credentials/src/parse-known-profiles.ts b/packages/util-credentials/src/parse-known-profiles.ts index 4ed90b04568bf..bff1350903051 100644 --- a/packages/util-credentials/src/parse-known-profiles.ts +++ b/packages/util-credentials/src/parse-known-profiles.ts @@ -1,12 +1,4 @@ -import { - parseKnownFiles as __parseKnownFiles, - SourceProfileInit as __SourceProfileInit, -} from "@aws-sdk/shared-ini-file-loader"; - -/** - * @deprecated Use SourceProfileInit from "@aws-sdk/shared-ini-file-loader" instead. - */ -export interface SourceProfileInit extends __SourceProfileInit {} +import { parseKnownFiles as __parseKnownFiles } from "@aws-sdk/shared-ini-file-loader"; /** * @deprecated Use parseKnownFiles from "@aws-sdk/shared-ini-file-loader" instead.