'use strict'; var propertyProvider = require('@smithy/property-provider'); var sharedIniFileLoader = require('@smithy/shared-ini-file-loader'); var client = require('@aws-sdk/core/client'); var tokenProviders = require('@aws-sdk/token-providers'); const isSsoProfile = (arg) => arg && (typeof arg.sso_start_url === "string" || typeof arg.sso_account_id === "string" || typeof arg.sso_session === "string" || typeof arg.sso_region === "string" || typeof arg.sso_role_name === "string"); const SHOULD_FAIL_CREDENTIAL_CHAIN = false; const resolveSSOCredentials = async ({ ssoStartUrl, ssoSession, ssoAccountId, ssoRegion, ssoRoleName, ssoClient, clientConfig, parentClientConfig, profile, filepath, configFilepath, ignoreCache, logger, }) => { let token; const refreshMessage = `To refresh this SSO session run aws sso login with the corresponding profile.`; if (ssoSession) { try { const _token = await tokenProviders.fromSso({ profile, filepath, configFilepath, ignoreCache, })(); token = { accessToken: _token.token, expiresAt: new Date(_token.expiration).toISOString(), }; } catch (e) { throw new propertyProvider.CredentialsProviderError(e.message, { tryNextLink: SHOULD_FAIL_CREDENTIAL_CHAIN, logger, }); } } else { try { token = await sharedIniFileLoader.getSSOTokenFromFile(ssoStartUrl); } catch (e) { throw new propertyProvider.CredentialsProviderError(`The SSO session associated with this profile is invalid. ${refreshMessage}`, { tryNextLink: SHOULD_FAIL_CREDENTIAL_CHAIN, logger, }); } } if (new Date(token.expiresAt).getTime() - Date.now() <= 0) { throw new propertyProvider.CredentialsProviderError(`The SSO session associated with this profile has expired. ${refreshMessage}`, { tryNextLink: SHOULD_FAIL_CREDENTIAL_CHAIN, logger, }); } const { accessToken } = token; const { SSOClient, GetRoleCredentialsCommand } = await Promise.resolve().then(function () { return require('./loadSso-CVy8iqsZ.js'); }); const sso = ssoClient || new SSOClient(Object.assign({}, clientConfig ?? {}, { logger: clientConfig?.logger ?? parentClientConfig?.logger, region: clientConfig?.region ?? ssoRegion, })); let ssoResp; try { ssoResp = await sso.send(new GetRoleCredentialsCommand({ accountId: ssoAccountId, roleName: ssoRoleName, accessToken, })); } catch (e) { throw new propertyProvider.CredentialsProviderError(e, { tryNextLink: SHOULD_FAIL_CREDENTIAL_CHAIN, logger, }); } const { roleCredentials: { accessKeyId, secretAccessKey, sessionToken, expiration, credentialScope, accountId } = {}, } = ssoResp; if (!accessKeyId || !secretAccessKey || !sessionToken || !expiration) { throw new propertyProvider.CredentialsProviderError("SSO returns an invalid temporary credential.", { tryNextLink: SHOULD_FAIL_CREDENTIAL_CHAIN, logger, }); } const credentials = { accessKeyId, secretAccessKey, sessionToken, expiration: new Date(expiration), ...(credentialScope && { credentialScope }), ...(accountId && { accountId }), }; if (ssoSession) { client.setCredentialFeature(credentials, "CREDENTIALS_SSO", "s"); } else { client.setCredentialFeature(credentials, "CREDENTIALS_SSO_LEGACY", "u"); } return credentials; }; const validateSsoProfile = (profile, logger) => { const { sso_start_url, sso_account_id, sso_region, sso_role_name } = profile; if (!sso_start_url || !sso_account_id || !sso_region || !sso_role_name) { throw new propertyProvider.CredentialsProviderError(`Profile is configured with invalid SSO credentials. Required parameters "sso_account_id", ` + `"sso_region", "sso_role_name", "sso_start_url". Got ${Object.keys(profile).join(", ")}\nReference: https://docs.aws.amazon.com/cli/latest/userguide/cli-configure-sso.html`, { tryNextLink: false, logger }); } return profile; }; const fromSSO = (init = {}) => async ({ callerClientConfig } = {}) => { init.logger?.debug("@aws-sdk/credential-provider-sso - fromSSO"); const { ssoStartUrl, ssoAccountId, ssoRegion, ssoRoleName, ssoSession } = init; const { ssoClient } = init; const profileName = sharedIniFileLoader.getProfileName({ profile: init.profile ?? callerClientConfig?.profile, }); if (!ssoStartUrl && !ssoAccountId && !ssoRegion && !ssoRoleName && !ssoSession) { const profiles = await sharedIniFileLoader.parseKnownFiles(init); const profile = profiles[profileName]; if (!profile) { throw new propertyProvider.CredentialsProviderError(`Profile ${profileName} was not found.`, { logger: init.logger }); } if (!isSsoProfile(profile)) { throw new propertyProvider.CredentialsProviderError(`Profile ${profileName} is not configured with SSO credentials.`, { logger: init.logger, }); } if (profile?.sso_session) { const ssoSessions = await sharedIniFileLoader.loadSsoSessionData(init); const session = ssoSessions[profile.sso_session]; const conflictMsg = ` configurations in profile ${profileName} and sso-session ${profile.sso_session}`; if (ssoRegion && ssoRegion !== session.sso_region) { throw new propertyProvider.CredentialsProviderError(`Conflicting SSO region` + conflictMsg, { tryNextLink: false, logger: init.logger, }); } if (ssoStartUrl && ssoStartUrl !== session.sso_start_url) { throw new propertyProvider.CredentialsProviderError(`Conflicting SSO start_url` + conflictMsg, { tryNextLink: false, logger: init.logger, }); } profile.sso_region = session.sso_region; profile.sso_start_url = session.sso_start_url; } const { sso_start_url, sso_account_id, sso_region, sso_role_name, sso_session } = validateSsoProfile(profile, init.logger); return resolveSSOCredentials({ ssoStartUrl: sso_start_url, ssoSession: sso_session, ssoAccountId: sso_account_id, ssoRegion: sso_region, ssoRoleName: sso_role_name, ssoClient: ssoClient, clientConfig: init.clientConfig, parentClientConfig: init.parentClientConfig, profile: profileName, filepath: init.filepath, configFilepath: init.configFilepath, ignoreCache: init.ignoreCache, logger: init.logger, }); } else if (!ssoStartUrl || !ssoAccountId || !ssoRegion || !ssoRoleName) { throw new propertyProvider.CredentialsProviderError("Incomplete configuration. The fromSSO() argument hash must include " + '"ssoStartUrl", "ssoAccountId", "ssoRegion", "ssoRoleName"', { tryNextLink: false, logger: init.logger }); } else { return resolveSSOCredentials({ ssoStartUrl, ssoSession, ssoAccountId, ssoRegion, ssoRoleName, ssoClient, clientConfig: init.clientConfig, parentClientConfig: init.parentClientConfig, profile: profileName, filepath: init.filepath, configFilepath: init.configFilepath, ignoreCache: init.ignoreCache, logger: init.logger, }); } }; exports.fromSSO = fromSSO; exports.isSsoProfile = isSsoProfile; exports.validateSsoProfile = validateSsoProfile;