@logto/connector-aws-ses 1.1.2 → 1.2.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -1,290 +0,0 @@
1
- import { P as ProviderError, aq as getHomeDir, ar as IniSectionType, as as CONFIG_PREFIX_SEPARATOR, at as slurpFile, au as getConfigFilepath, av as parseIni, g as getProfileName, C as CredentialsProviderError } from './index-s7VGoewj.js';
2
- import 'os';
3
- import { join } from 'path';
4
- import { createHash } from 'crypto';
5
- import { promises } from 'fs';
6
- import { p as parseKnownFiles } from './parseKnownFiles-DjQIrDWV.js';
7
- import '@logto/connector-kit';
8
- import 'zod';
9
- import 'buffer';
10
- import 'stream';
11
- import 'http';
12
- import 'https';
13
- import 'http2';
14
- import 'util';
15
- import 'process';
16
-
17
- class TokenProviderError extends ProviderError {
18
- constructor(message, tryNextLink = true) {
19
- super(message, tryNextLink);
20
- this.tryNextLink = tryNextLink;
21
- this.name = "TokenProviderError";
22
- Object.setPrototypeOf(this, TokenProviderError.prototype);
23
- }
24
- }
25
-
26
- const getSSOTokenFilepath = (id) => {
27
- const hasher = createHash("sha1");
28
- const cacheName = hasher.update(id).digest("hex");
29
- return join(getHomeDir(), ".aws", "sso", "cache", `${cacheName}.json`);
30
- };
31
-
32
- const { readFile } = promises;
33
- const getSSOTokenFromFile = async (id) => {
34
- const ssoTokenFilepath = getSSOTokenFilepath(id);
35
- const ssoTokenText = await readFile(ssoTokenFilepath, "utf8");
36
- return JSON.parse(ssoTokenText);
37
- };
38
-
39
- const getSsoSessionData = (data) => Object.entries(data)
40
- .filter(([key]) => key.startsWith(IniSectionType.SSO_SESSION + CONFIG_PREFIX_SEPARATOR))
41
- .reduce((acc, [key, value]) => ({ ...acc, [key.substring(key.indexOf(CONFIG_PREFIX_SEPARATOR) + 1)]: value }), {});
42
-
43
- const swallowError = () => ({});
44
- const loadSsoSessionData = async (init = {}) => slurpFile(init.configFilepath ?? getConfigFilepath())
45
- .then(parseIni)
46
- .then(getSsoSessionData)
47
- .catch(swallowError);
48
-
49
- const isSsoProfile = (arg) => arg &&
50
- (typeof arg.sso_start_url === "string" ||
51
- typeof arg.sso_account_id === "string" ||
52
- typeof arg.sso_session === "string" ||
53
- typeof arg.sso_region === "string" ||
54
- typeof arg.sso_role_name === "string");
55
-
56
- const EXPIRE_WINDOW_MS = 5 * 60 * 1000;
57
- const REFRESH_MESSAGE = `To refresh this SSO session run 'aws sso login' with the corresponding profile.`;
58
-
59
- const ssoOidcClientsHash = {};
60
- const getSsoOidcClient = async (ssoRegion) => {
61
- const { SSOOIDCClient } = await import('./loadSsoOidc-RJkBDJ78.js');
62
- if (ssoOidcClientsHash[ssoRegion]) {
63
- return ssoOidcClientsHash[ssoRegion];
64
- }
65
- const ssoOidcClient = new SSOOIDCClient({ region: ssoRegion });
66
- ssoOidcClientsHash[ssoRegion] = ssoOidcClient;
67
- return ssoOidcClient;
68
- };
69
-
70
- const getNewSsoOidcToken = async (ssoToken, ssoRegion) => {
71
- const { CreateTokenCommand } = await import('./loadSsoOidc-RJkBDJ78.js');
72
- const ssoOidcClient = await getSsoOidcClient(ssoRegion);
73
- return ssoOidcClient.send(new CreateTokenCommand({
74
- clientId: ssoToken.clientId,
75
- clientSecret: ssoToken.clientSecret,
76
- refreshToken: ssoToken.refreshToken,
77
- grantType: "refresh_token",
78
- }));
79
- };
80
-
81
- const validateTokenExpiry = (token) => {
82
- if (token.expiration && token.expiration.getTime() < Date.now()) {
83
- throw new TokenProviderError(`Token is expired. ${REFRESH_MESSAGE}`, false);
84
- }
85
- };
86
-
87
- const validateTokenKey = (key, value, forRefresh = false) => {
88
- if (typeof value === "undefined") {
89
- throw new TokenProviderError(`Value not present for '${key}' in SSO Token${forRefresh ? ". Cannot refresh" : ""}. ${REFRESH_MESSAGE}`, false);
90
- }
91
- };
92
-
93
- const { writeFile } = promises;
94
- const writeSSOTokenToFile = (id, ssoToken) => {
95
- const tokenFilepath = getSSOTokenFilepath(id);
96
- const tokenString = JSON.stringify(ssoToken, null, 2);
97
- return writeFile(tokenFilepath, tokenString);
98
- };
99
-
100
- const lastRefreshAttemptTime = new Date(0);
101
- const fromSso = (init = {}) => async () => {
102
- init.logger?.debug("@aws-sdk/token-providers", "fromSso");
103
- const profiles = await parseKnownFiles(init);
104
- const profileName = getProfileName(init);
105
- const profile = profiles[profileName];
106
- if (!profile) {
107
- throw new TokenProviderError(`Profile '${profileName}' could not be found in shared credentials file.`, false);
108
- }
109
- else if (!profile["sso_session"]) {
110
- throw new TokenProviderError(`Profile '${profileName}' is missing required property 'sso_session'.`);
111
- }
112
- const ssoSessionName = profile["sso_session"];
113
- const ssoSessions = await loadSsoSessionData(init);
114
- const ssoSession = ssoSessions[ssoSessionName];
115
- if (!ssoSession) {
116
- throw new TokenProviderError(`Sso session '${ssoSessionName}' could not be found in shared credentials file.`, false);
117
- }
118
- for (const ssoSessionRequiredKey of ["sso_start_url", "sso_region"]) {
119
- if (!ssoSession[ssoSessionRequiredKey]) {
120
- throw new TokenProviderError(`Sso session '${ssoSessionName}' is missing required property '${ssoSessionRequiredKey}'.`, false);
121
- }
122
- }
123
- ssoSession["sso_start_url"];
124
- const ssoRegion = ssoSession["sso_region"];
125
- let ssoToken;
126
- try {
127
- ssoToken = await getSSOTokenFromFile(ssoSessionName);
128
- }
129
- catch (e) {
130
- throw new TokenProviderError(`The SSO session token associated with profile=${profileName} was not found or is invalid. ${REFRESH_MESSAGE}`, false);
131
- }
132
- validateTokenKey("accessToken", ssoToken.accessToken);
133
- validateTokenKey("expiresAt", ssoToken.expiresAt);
134
- const { accessToken, expiresAt } = ssoToken;
135
- const existingToken = { token: accessToken, expiration: new Date(expiresAt) };
136
- if (existingToken.expiration.getTime() - Date.now() > EXPIRE_WINDOW_MS) {
137
- return existingToken;
138
- }
139
- if (Date.now() - lastRefreshAttemptTime.getTime() < 30 * 1000) {
140
- validateTokenExpiry(existingToken);
141
- return existingToken;
142
- }
143
- validateTokenKey("clientId", ssoToken.clientId, true);
144
- validateTokenKey("clientSecret", ssoToken.clientSecret, true);
145
- validateTokenKey("refreshToken", ssoToken.refreshToken, true);
146
- try {
147
- lastRefreshAttemptTime.setTime(Date.now());
148
- const newSsoOidcToken = await getNewSsoOidcToken(ssoToken, ssoRegion);
149
- validateTokenKey("accessToken", newSsoOidcToken.accessToken);
150
- validateTokenKey("expiresIn", newSsoOidcToken.expiresIn);
151
- const newTokenExpiration = new Date(Date.now() + newSsoOidcToken.expiresIn * 1000);
152
- try {
153
- await writeSSOTokenToFile(ssoSessionName, {
154
- ...ssoToken,
155
- accessToken: newSsoOidcToken.accessToken,
156
- expiresAt: newTokenExpiration.toISOString(),
157
- refreshToken: newSsoOidcToken.refreshToken,
158
- });
159
- }
160
- catch (error) {
161
- }
162
- return {
163
- token: newSsoOidcToken.accessToken,
164
- expiration: newTokenExpiration,
165
- };
166
- }
167
- catch (error) {
168
- validateTokenExpiry(existingToken);
169
- return existingToken;
170
- }
171
- };
172
-
173
- const SHOULD_FAIL_CREDENTIAL_CHAIN = false;
174
- const resolveSSOCredentials = async ({ ssoStartUrl, ssoSession, ssoAccountId, ssoRegion, ssoRoleName, ssoClient, clientConfig, profile, }) => {
175
- let token;
176
- const refreshMessage = `To refresh this SSO session run aws sso login with the corresponding profile.`;
177
- if (ssoSession) {
178
- try {
179
- const _token = await fromSso({ profile })();
180
- token = {
181
- accessToken: _token.token,
182
- expiresAt: new Date(_token.expiration).toISOString(),
183
- };
184
- }
185
- catch (e) {
186
- throw new CredentialsProviderError(e.message, SHOULD_FAIL_CREDENTIAL_CHAIN);
187
- }
188
- }
189
- else {
190
- try {
191
- token = await getSSOTokenFromFile(ssoStartUrl);
192
- }
193
- catch (e) {
194
- throw new CredentialsProviderError(`The SSO session associated with this profile is invalid. ${refreshMessage}`, SHOULD_FAIL_CREDENTIAL_CHAIN);
195
- }
196
- }
197
- if (new Date(token.expiresAt).getTime() - Date.now() <= 0) {
198
- throw new CredentialsProviderError(`The SSO session associated with this profile has expired. ${refreshMessage}`, SHOULD_FAIL_CREDENTIAL_CHAIN);
199
- }
200
- const { accessToken } = token;
201
- const { SSOClient, GetRoleCredentialsCommand } = await import('./loadSso-ChzknlEd.js');
202
- const sso = ssoClient ||
203
- new SSOClient(Object.assign({}, clientConfig ?? {}, {
204
- region: clientConfig?.region ?? ssoRegion,
205
- }));
206
- let ssoResp;
207
- try {
208
- ssoResp = await sso.send(new GetRoleCredentialsCommand({
209
- accountId: ssoAccountId,
210
- roleName: ssoRoleName,
211
- accessToken,
212
- }));
213
- }
214
- catch (e) {
215
- throw CredentialsProviderError.from(e, SHOULD_FAIL_CREDENTIAL_CHAIN);
216
- }
217
- const { roleCredentials: { accessKeyId, secretAccessKey, sessionToken, expiration, credentialScope } = {} } = ssoResp;
218
- if (!accessKeyId || !secretAccessKey || !sessionToken || !expiration) {
219
- throw new CredentialsProviderError("SSO returns an invalid temporary credential.", SHOULD_FAIL_CREDENTIAL_CHAIN);
220
- }
221
- return { accessKeyId, secretAccessKey, sessionToken, expiration: new Date(expiration), credentialScope };
222
- };
223
-
224
- const validateSsoProfile = (profile) => {
225
- const { sso_start_url, sso_account_id, sso_region, sso_role_name } = profile;
226
- if (!sso_start_url || !sso_account_id || !sso_region || !sso_role_name) {
227
- throw new CredentialsProviderError(`Profile is configured with invalid SSO credentials. Required parameters "sso_account_id", ` +
228
- `"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`, false);
229
- }
230
- return profile;
231
- };
232
-
233
- const fromSSO = (init = {}) => async () => {
234
- init.logger?.debug("@aws-sdk/credential-provider-sso", "fromSSO");
235
- const { ssoStartUrl, ssoAccountId, ssoRegion, ssoRoleName, ssoSession } = init;
236
- const { ssoClient } = init;
237
- const profileName = getProfileName(init);
238
- if (!ssoStartUrl && !ssoAccountId && !ssoRegion && !ssoRoleName && !ssoSession) {
239
- const profiles = await parseKnownFiles(init);
240
- const profile = profiles[profileName];
241
- if (!profile) {
242
- throw new CredentialsProviderError(`Profile ${profileName} was not found.`);
243
- }
244
- if (!isSsoProfile(profile)) {
245
- throw new CredentialsProviderError(`Profile ${profileName} is not configured with SSO credentials.`);
246
- }
247
- if (profile?.sso_session) {
248
- const ssoSessions = await loadSsoSessionData(init);
249
- const session = ssoSessions[profile.sso_session];
250
- const conflictMsg = ` configurations in profile ${profileName} and sso-session ${profile.sso_session}`;
251
- if (ssoRegion && ssoRegion !== session.sso_region) {
252
- throw new CredentialsProviderError(`Conflicting SSO region` + conflictMsg, false);
253
- }
254
- if (ssoStartUrl && ssoStartUrl !== session.sso_start_url) {
255
- throw new CredentialsProviderError(`Conflicting SSO start_url` + conflictMsg, false);
256
- }
257
- profile.sso_region = session.sso_region;
258
- profile.sso_start_url = session.sso_start_url;
259
- }
260
- const { sso_start_url, sso_account_id, sso_region, sso_role_name, sso_session } = validateSsoProfile(profile);
261
- return resolveSSOCredentials({
262
- ssoStartUrl: sso_start_url,
263
- ssoSession: sso_session,
264
- ssoAccountId: sso_account_id,
265
- ssoRegion: sso_region,
266
- ssoRoleName: sso_role_name,
267
- ssoClient: ssoClient,
268
- clientConfig: init.clientConfig,
269
- profile: profileName,
270
- });
271
- }
272
- else if (!ssoStartUrl || !ssoAccountId || !ssoRegion || !ssoRoleName) {
273
- throw new CredentialsProviderError("Incomplete configuration. The fromSSO() argument hash must include " +
274
- '"ssoStartUrl", "ssoAccountId", "ssoRegion", "ssoRoleName"');
275
- }
276
- else {
277
- return resolveSSOCredentials({
278
- ssoStartUrl,
279
- ssoSession,
280
- ssoAccountId,
281
- ssoRegion,
282
- ssoRoleName,
283
- ssoClient,
284
- clientConfig: init.clientConfig,
285
- profile: profileName,
286
- });
287
- }
288
- };
289
-
290
- export { fromSSO, isSsoProfile, validateSsoProfile };
@@ -1,355 +0,0 @@
1
- import { P as ProviderError, C as CredentialsProviderError, p as parseUrl, i as loadConfig } from './index-s7VGoewj.js';
2
- import { parse } from 'url';
3
- import { Buffer } from 'buffer';
4
- import { request } from 'http';
5
- import '@logto/connector-kit';
6
- import 'zod';
7
- import 'os';
8
- import 'path';
9
- import 'crypto';
10
- import 'fs';
11
- import 'stream';
12
- import 'https';
13
- import 'http2';
14
- import 'util';
15
- import 'process';
16
-
17
- function httpRequest(options) {
18
- return new Promise((resolve, reject) => {
19
- const req = request({
20
- method: "GET",
21
- ...options,
22
- hostname: options.hostname?.replace(/^\[(.+)\]$/, "$1"),
23
- });
24
- req.on("error", (err) => {
25
- reject(Object.assign(new ProviderError("Unable to connect to instance metadata service"), err));
26
- req.destroy();
27
- });
28
- req.on("timeout", () => {
29
- reject(new ProviderError("TimeoutError from instance metadata service"));
30
- req.destroy();
31
- });
32
- req.on("response", (res) => {
33
- const { statusCode = 400 } = res;
34
- if (statusCode < 200 || 300 <= statusCode) {
35
- reject(Object.assign(new ProviderError("Error response received from instance metadata service"), { statusCode }));
36
- req.destroy();
37
- }
38
- const chunks = [];
39
- res.on("data", (chunk) => {
40
- chunks.push(chunk);
41
- });
42
- res.on("end", () => {
43
- resolve(Buffer.concat(chunks));
44
- req.destroy();
45
- });
46
- });
47
- req.end();
48
- });
49
- }
50
-
51
- const isImdsCredentials = (arg) => Boolean(arg) &&
52
- typeof arg === "object" &&
53
- typeof arg.AccessKeyId === "string" &&
54
- typeof arg.SecretAccessKey === "string" &&
55
- typeof arg.Token === "string" &&
56
- typeof arg.Expiration === "string";
57
- const fromImdsCredentials = (creds) => ({
58
- accessKeyId: creds.AccessKeyId,
59
- secretAccessKey: creds.SecretAccessKey,
60
- sessionToken: creds.Token,
61
- expiration: new Date(creds.Expiration),
62
- });
63
-
64
- const DEFAULT_TIMEOUT = 1000;
65
- const DEFAULT_MAX_RETRIES = 0;
66
- const providerConfigFromInit = ({ maxRetries = DEFAULT_MAX_RETRIES, timeout = DEFAULT_TIMEOUT, }) => ({ maxRetries, timeout });
67
-
68
- const retry = (toRetry, maxRetries) => {
69
- let promise = toRetry();
70
- for (let i = 0; i < maxRetries; i++) {
71
- promise = promise.catch(toRetry);
72
- }
73
- return promise;
74
- };
75
-
76
- const ENV_CMDS_FULL_URI = "AWS_CONTAINER_CREDENTIALS_FULL_URI";
77
- const ENV_CMDS_RELATIVE_URI = "AWS_CONTAINER_CREDENTIALS_RELATIVE_URI";
78
- const ENV_CMDS_AUTH_TOKEN = "AWS_CONTAINER_AUTHORIZATION_TOKEN";
79
- const fromContainerMetadata = (init = {}) => {
80
- const { timeout, maxRetries } = providerConfigFromInit(init);
81
- return () => retry(async () => {
82
- const requestOptions = await getCmdsUri();
83
- const credsResponse = JSON.parse(await requestFromEcsImds(timeout, requestOptions));
84
- if (!isImdsCredentials(credsResponse)) {
85
- throw new CredentialsProviderError("Invalid response received from instance metadata service.");
86
- }
87
- return fromImdsCredentials(credsResponse);
88
- }, maxRetries);
89
- };
90
- const requestFromEcsImds = async (timeout, options) => {
91
- if (process.env[ENV_CMDS_AUTH_TOKEN]) {
92
- options.headers = {
93
- ...options.headers,
94
- Authorization: process.env[ENV_CMDS_AUTH_TOKEN],
95
- };
96
- }
97
- const buffer = await httpRequest({
98
- ...options,
99
- timeout,
100
- });
101
- return buffer.toString();
102
- };
103
- const CMDS_IP = "169.254.170.2";
104
- const GREENGRASS_HOSTS = {
105
- localhost: true,
106
- "127.0.0.1": true,
107
- };
108
- const GREENGRASS_PROTOCOLS = {
109
- "http:": true,
110
- "https:": true,
111
- };
112
- const getCmdsUri = async () => {
113
- if (process.env[ENV_CMDS_RELATIVE_URI]) {
114
- return {
115
- hostname: CMDS_IP,
116
- path: process.env[ENV_CMDS_RELATIVE_URI],
117
- };
118
- }
119
- if (process.env[ENV_CMDS_FULL_URI]) {
120
- const parsed = parse(process.env[ENV_CMDS_FULL_URI]);
121
- if (!parsed.hostname || !(parsed.hostname in GREENGRASS_HOSTS)) {
122
- throw new CredentialsProviderError(`${parsed.hostname} is not a valid container metadata service hostname`, false);
123
- }
124
- if (!parsed.protocol || !(parsed.protocol in GREENGRASS_PROTOCOLS)) {
125
- throw new CredentialsProviderError(`${parsed.protocol} is not a valid container metadata service protocol`, false);
126
- }
127
- return {
128
- ...parsed,
129
- port: parsed.port ? parseInt(parsed.port, 10) : undefined,
130
- };
131
- }
132
- throw new CredentialsProviderError("The container metadata credential provider cannot be used unless" +
133
- ` the ${ENV_CMDS_RELATIVE_URI} or ${ENV_CMDS_FULL_URI} environment` +
134
- " variable is set", false);
135
- };
136
-
137
- class InstanceMetadataV1FallbackError extends CredentialsProviderError {
138
- constructor(message, tryNextLink = true) {
139
- super(message, tryNextLink);
140
- this.tryNextLink = tryNextLink;
141
- this.name = "InstanceMetadataV1FallbackError";
142
- Object.setPrototypeOf(this, InstanceMetadataV1FallbackError.prototype);
143
- }
144
- }
145
-
146
- var Endpoint;
147
- (function (Endpoint) {
148
- Endpoint["IPv4"] = "http://169.254.169.254";
149
- Endpoint["IPv6"] = "http://[fd00:ec2::254]";
150
- })(Endpoint || (Endpoint = {}));
151
-
152
- const ENV_ENDPOINT_NAME = "AWS_EC2_METADATA_SERVICE_ENDPOINT";
153
- const CONFIG_ENDPOINT_NAME = "ec2_metadata_service_endpoint";
154
- const ENDPOINT_CONFIG_OPTIONS = {
155
- environmentVariableSelector: (env) => env[ENV_ENDPOINT_NAME],
156
- configFileSelector: (profile) => profile[CONFIG_ENDPOINT_NAME],
157
- default: undefined,
158
- };
159
-
160
- var EndpointMode;
161
- (function (EndpointMode) {
162
- EndpointMode["IPv4"] = "IPv4";
163
- EndpointMode["IPv6"] = "IPv6";
164
- })(EndpointMode || (EndpointMode = {}));
165
-
166
- const ENV_ENDPOINT_MODE_NAME = "AWS_EC2_METADATA_SERVICE_ENDPOINT_MODE";
167
- const CONFIG_ENDPOINT_MODE_NAME = "ec2_metadata_service_endpoint_mode";
168
- const ENDPOINT_MODE_CONFIG_OPTIONS = {
169
- environmentVariableSelector: (env) => env[ENV_ENDPOINT_MODE_NAME],
170
- configFileSelector: (profile) => profile[CONFIG_ENDPOINT_MODE_NAME],
171
- default: EndpointMode.IPv4,
172
- };
173
-
174
- const getInstanceMetadataEndpoint = async () => parseUrl((await getFromEndpointConfig()) || (await getFromEndpointModeConfig()));
175
- const getFromEndpointConfig = async () => loadConfig(ENDPOINT_CONFIG_OPTIONS)();
176
- const getFromEndpointModeConfig = async () => {
177
- const endpointMode = await loadConfig(ENDPOINT_MODE_CONFIG_OPTIONS)();
178
- switch (endpointMode) {
179
- case EndpointMode.IPv4:
180
- return Endpoint.IPv4;
181
- case EndpointMode.IPv6:
182
- return Endpoint.IPv6;
183
- default:
184
- throw new Error(`Unsupported endpoint mode: ${endpointMode}.` + ` Select from ${Object.values(EndpointMode)}`);
185
- }
186
- };
187
-
188
- const STATIC_STABILITY_REFRESH_INTERVAL_SECONDS = 5 * 60;
189
- const STATIC_STABILITY_REFRESH_INTERVAL_JITTER_WINDOW_SECONDS = 5 * 60;
190
- const STATIC_STABILITY_DOC_URL = "https://docs.aws.amazon.com/sdkref/latest/guide/feature-static-credentials.html";
191
- const getExtendedInstanceMetadataCredentials = (credentials, logger) => {
192
- const refreshInterval = STATIC_STABILITY_REFRESH_INTERVAL_SECONDS +
193
- Math.floor(Math.random() * STATIC_STABILITY_REFRESH_INTERVAL_JITTER_WINDOW_SECONDS);
194
- const newExpiration = new Date(Date.now() + refreshInterval * 1000);
195
- logger.warn("Attempting credential expiration extension due to a credential service availability issue. A refresh of these " +
196
- `credentials will be attempted after ${new Date(newExpiration)}.\nFor more information, please visit: ` +
197
- STATIC_STABILITY_DOC_URL);
198
- const originalExpiration = credentials.originalExpiration ?? credentials.expiration;
199
- return {
200
- ...credentials,
201
- ...(originalExpiration ? { originalExpiration } : {}),
202
- expiration: newExpiration,
203
- };
204
- };
205
-
206
- const staticStabilityProvider = (provider, options = {}) => {
207
- const logger = options?.logger || console;
208
- let pastCredentials;
209
- return async () => {
210
- let credentials;
211
- try {
212
- credentials = await provider();
213
- if (credentials.expiration && credentials.expiration.getTime() < Date.now()) {
214
- credentials = getExtendedInstanceMetadataCredentials(credentials, logger);
215
- }
216
- }
217
- catch (e) {
218
- if (pastCredentials) {
219
- logger.warn("Credential renew failed: ", e);
220
- credentials = getExtendedInstanceMetadataCredentials(pastCredentials, logger);
221
- }
222
- else {
223
- throw e;
224
- }
225
- }
226
- pastCredentials = credentials;
227
- return credentials;
228
- };
229
- };
230
-
231
- const IMDS_PATH = "/latest/meta-data/iam/security-credentials/";
232
- const IMDS_TOKEN_PATH = "/latest/api/token";
233
- const AWS_EC2_METADATA_V1_DISABLED = "AWS_EC2_METADATA_V1_DISABLED";
234
- const PROFILE_AWS_EC2_METADATA_V1_DISABLED = "ec2_metadata_v1_disabled";
235
- const X_AWS_EC2_METADATA_TOKEN = "x-aws-ec2-metadata-token";
236
- const fromInstanceMetadata = (init = {}) => staticStabilityProvider(getInstanceImdsProvider(init), { logger: init.logger });
237
- const getInstanceImdsProvider = (init) => {
238
- let disableFetchToken = false;
239
- const { logger, profile } = init;
240
- const { timeout, maxRetries } = providerConfigFromInit(init);
241
- const getCredentials = async (maxRetries, options) => {
242
- const isImdsV1Fallback = disableFetchToken || options.headers?.[X_AWS_EC2_METADATA_TOKEN] == null;
243
- if (isImdsV1Fallback) {
244
- let fallbackBlockedFromProfile = false;
245
- let fallbackBlockedFromProcessEnv = false;
246
- const configValue = await loadConfig({
247
- environmentVariableSelector: (env) => {
248
- const envValue = env[AWS_EC2_METADATA_V1_DISABLED];
249
- fallbackBlockedFromProcessEnv = !!envValue && envValue !== "false";
250
- if (envValue === undefined) {
251
- throw new CredentialsProviderError(`${AWS_EC2_METADATA_V1_DISABLED} not set in env, checking config file next.`);
252
- }
253
- return fallbackBlockedFromProcessEnv;
254
- },
255
- configFileSelector: (profile) => {
256
- const profileValue = profile[PROFILE_AWS_EC2_METADATA_V1_DISABLED];
257
- fallbackBlockedFromProfile = !!profileValue && profileValue !== "false";
258
- return fallbackBlockedFromProfile;
259
- },
260
- default: false,
261
- }, {
262
- profile,
263
- })();
264
- if (init.ec2MetadataV1Disabled || configValue) {
265
- const causes = [];
266
- if (init.ec2MetadataV1Disabled)
267
- causes.push("credential provider initialization (runtime option ec2MetadataV1Disabled)");
268
- if (fallbackBlockedFromProfile)
269
- causes.push(`config file profile (${PROFILE_AWS_EC2_METADATA_V1_DISABLED})`);
270
- if (fallbackBlockedFromProcessEnv)
271
- causes.push(`process environment variable (${AWS_EC2_METADATA_V1_DISABLED})`);
272
- throw new InstanceMetadataV1FallbackError(`AWS EC2 Metadata v1 fallback has been blocked by AWS SDK configuration in the following: [${causes.join(", ")}].`);
273
- }
274
- }
275
- const imdsProfile = (await retry(async () => {
276
- let profile;
277
- try {
278
- profile = await getProfile(options);
279
- }
280
- catch (err) {
281
- if (err.statusCode === 401) {
282
- disableFetchToken = false;
283
- }
284
- throw err;
285
- }
286
- return profile;
287
- }, maxRetries)).trim();
288
- return retry(async () => {
289
- let creds;
290
- try {
291
- creds = await getCredentialsFromProfile(imdsProfile, options);
292
- }
293
- catch (err) {
294
- if (err.statusCode === 401) {
295
- disableFetchToken = false;
296
- }
297
- throw err;
298
- }
299
- return creds;
300
- }, maxRetries);
301
- };
302
- return async () => {
303
- const endpoint = await getInstanceMetadataEndpoint();
304
- if (disableFetchToken) {
305
- logger?.debug("AWS SDK Instance Metadata", "using v1 fallback (no token fetch)");
306
- return getCredentials(maxRetries, { ...endpoint, timeout });
307
- }
308
- else {
309
- let token;
310
- try {
311
- token = (await getMetadataToken({ ...endpoint, timeout })).toString();
312
- }
313
- catch (error) {
314
- if (error?.statusCode === 400) {
315
- throw Object.assign(error, {
316
- message: "EC2 Metadata token request returned error",
317
- });
318
- }
319
- else if (error.message === "TimeoutError" || [403, 404, 405].includes(error.statusCode)) {
320
- disableFetchToken = true;
321
- }
322
- logger?.debug("AWS SDK Instance Metadata", "using v1 fallback (initial)");
323
- return getCredentials(maxRetries, { ...endpoint, timeout });
324
- }
325
- return getCredentials(maxRetries, {
326
- ...endpoint,
327
- headers: {
328
- [X_AWS_EC2_METADATA_TOKEN]: token,
329
- },
330
- timeout,
331
- });
332
- }
333
- };
334
- };
335
- const getMetadataToken = async (options) => httpRequest({
336
- ...options,
337
- path: IMDS_TOKEN_PATH,
338
- method: "PUT",
339
- headers: {
340
- "x-aws-ec2-metadata-token-ttl-seconds": "21600",
341
- },
342
- });
343
- const getProfile = async (options) => (await httpRequest({ ...options, path: IMDS_PATH })).toString();
344
- const getCredentialsFromProfile = async (profile, options) => {
345
- const credsResponse = JSON.parse((await httpRequest({
346
- ...options,
347
- path: IMDS_PATH + profile,
348
- })).toString());
349
- if (!isImdsCredentials(credsResponse)) {
350
- throw new CredentialsProviderError("Invalid response received from instance metadata service.");
351
- }
352
- return fromImdsCredentials(credsResponse);
353
- };
354
-
355
- export { DEFAULT_MAX_RETRIES, DEFAULT_TIMEOUT, ENV_CMDS_AUTH_TOKEN, ENV_CMDS_FULL_URI, ENV_CMDS_RELATIVE_URI, Endpoint, fromContainerMetadata, fromInstanceMetadata, getInstanceMetadataEndpoint, httpRequest, providerConfigFromInit };
@@ -1,40 +0,0 @@
1
- import { C as CredentialsProviderError } from './index-s7VGoewj.js';
2
- import '@logto/connector-kit';
3
- import 'zod';
4
- import 'os';
5
- import 'path';
6
- import 'crypto';
7
- import 'fs';
8
- import 'buffer';
9
- import 'stream';
10
- import 'http';
11
- import 'https';
12
- import 'http2';
13
- import 'util';
14
- import 'process';
15
-
16
- const ENV_KEY = "AWS_ACCESS_KEY_ID";
17
- const ENV_SECRET = "AWS_SECRET_ACCESS_KEY";
18
- const ENV_SESSION = "AWS_SESSION_TOKEN";
19
- const ENV_EXPIRATION = "AWS_CREDENTIAL_EXPIRATION";
20
- const ENV_CREDENTIAL_SCOPE = "AWS_CREDENTIAL_SCOPE";
21
- const fromEnv = (init) => async () => {
22
- init?.logger?.debug("@aws-sdk/credential-provider-env", "fromEnv");
23
- const accessKeyId = process.env[ENV_KEY];
24
- const secretAccessKey = process.env[ENV_SECRET];
25
- const sessionToken = process.env[ENV_SESSION];
26
- const expiry = process.env[ENV_EXPIRATION];
27
- const credentialScope = process.env[ENV_CREDENTIAL_SCOPE];
28
- if (accessKeyId && secretAccessKey) {
29
- return {
30
- accessKeyId,
31
- secretAccessKey,
32
- ...(sessionToken && { sessionToken }),
33
- ...(expiry && { expiration: new Date(expiry) }),
34
- ...(credentialScope && { credentialScope }),
35
- };
36
- }
37
- throw new CredentialsProviderError("Unable to find environment variable credentials.");
38
- };
39
-
40
- export { ENV_CREDENTIAL_SCOPE, ENV_EXPIRATION, ENV_KEY, ENV_SECRET, ENV_SESSION, fromEnv };