UNPKG

openclaw

Version:

Multi-channel AI gateway with extensible messaging integrations

430 lines (429 loc) 21.5 kB
import { a as __toCommonJS, i as __require, o as __toESM, t as __commonJSMin } from "./chunk-CNf5ZN-e.js"; import { n as init_client, t as client_exports } from "./client-48bOJus2.js"; import { A as config_exports, j as init_config } from "./serde-CssnHFxP.js"; import { n as protocols_exports, t as init_protocols } from "./protocols-Lf8trFei.js"; //#region node_modules/@aws-sdk/credential-provider-login/dist-cjs/index.js var require_dist_cjs$1 = /* @__PURE__ */ __commonJSMin(((exports) => { var client = (init_client(), __toCommonJS(client_exports)); var config = (init_config(), __toCommonJS(config_exports)); var protocols = (init_protocols(), __toCommonJS(protocols_exports)); var node_crypto = __require("node:crypto"); var node_fs = __require("node:fs"); var node_os = __require("node:os"); var node_path = __require("node:path"); var LoginCredentialsFetcher = class LoginCredentialsFetcher { profileData; init; callerClientConfig; static REFRESH_THRESHOLD = 300 * 1e3; constructor(profileData, init, callerClientConfig) { this.profileData = profileData; this.init = init; this.callerClientConfig = callerClientConfig; } async loadCredentials() { const token = await this.loadToken(); if (!token) throw new config.CredentialsProviderError(`Failed to load a token for session ${this.loginSession}, please re-authenticate using aws login`, { tryNextLink: false, logger: this.logger }); const accessToken = token.accessToken; const now = Date.now(); if (new Date(accessToken.expiresAt).getTime() - now <= LoginCredentialsFetcher.REFRESH_THRESHOLD) return this.refresh(token); return { accessKeyId: accessToken.accessKeyId, secretAccessKey: accessToken.secretAccessKey, sessionToken: accessToken.sessionToken, accountId: accessToken.accountId, expiration: new Date(accessToken.expiresAt) }; } get logger() { return this.init?.logger; } get loginSession() { return this.profileData.login_session; } async refresh(token) { const { SigninClient, CreateOAuth2TokenCommand } = await import("./signin-D1pSafJ8.js"); const { logger, userAgentAppId } = this.callerClientConfig ?? {}; const isH2 = (requestHandler) => { return requestHandler?.metadata?.handlerProtocol === "h2"; }; const requestHandler = isH2(this.callerClientConfig?.requestHandler) ? void 0 : this.callerClientConfig?.requestHandler; const client = new SigninClient({ credentials: { accessKeyId: "", secretAccessKey: "" }, region: this.profileData.region ?? await this.callerClientConfig?.region?.() ?? process.env.AWS_REGION, requestHandler, logger, userAgentAppId, ...this.init?.clientConfig }); this.createDPoPInterceptor(client.middlewareStack); const commandInput = { tokenInput: { clientId: token.clientId, refreshToken: token.refreshToken, grantType: "refresh_token" } }; try { const response = await client.send(new CreateOAuth2TokenCommand(commandInput)); const { accessKeyId, secretAccessKey, sessionToken } = response.tokenOutput?.accessToken ?? {}; const { refreshToken, expiresIn } = response.tokenOutput ?? {}; if (!accessKeyId || !secretAccessKey || !sessionToken || !refreshToken) throw new config.CredentialsProviderError("Token refresh response missing required fields", { logger: this.logger, tryNextLink: false }); const expiresInMs = (expiresIn ?? 900) * 1e3; const expiration = new Date(Date.now() + expiresInMs); const updatedToken = { ...token, accessToken: { ...token.accessToken, accessKeyId, secretAccessKey, sessionToken, expiresAt: expiration.toISOString() }, refreshToken }; await this.saveToken(updatedToken); const newAccessToken = updatedToken.accessToken; return { accessKeyId: newAccessToken.accessKeyId, secretAccessKey: newAccessToken.secretAccessKey, sessionToken: newAccessToken.sessionToken, accountId: newAccessToken.accountId, expiration }; } catch (error) { if (error.name === "AccessDeniedException") { const errorType = error.error; let message; switch (errorType) { case "TOKEN_EXPIRED": message = "Your session has expired. Please reauthenticate."; break; case "USER_CREDENTIALS_CHANGED": message = "Unable to refresh credentials because of a change in your password. Please reauthenticate with your new password."; break; case "INSUFFICIENT_PERMISSIONS": message = "Unable to refresh credentials due to insufficient permissions. You may be missing permission for the 'CreateOAuth2Token' action."; break; default: message = `Failed to refresh token: ${String(error)}. Please re-authenticate using \`aws login\``; } throw new config.CredentialsProviderError(message, { logger: this.logger, tryNextLink: false }); } throw new config.CredentialsProviderError(`Failed to refresh token: ${String(error)}. Please re-authenticate using aws login`, { logger: this.logger }); } } async loadToken() { const tokenFilePath = this.getTokenFilePath(); try { let tokenData; try { tokenData = await config.readFile(tokenFilePath, { ignoreCache: this.init?.ignoreCache }); } catch { tokenData = await node_fs.promises.readFile(tokenFilePath, "utf8"); } const token = JSON.parse(tokenData); const missingFields = [ "accessToken", "clientId", "refreshToken", "dpopKey" ].filter((k) => !token[k]); if (!token.accessToken?.accountId) missingFields.push("accountId"); if (missingFields.length > 0) throw new config.CredentialsProviderError(`Token validation failed, missing fields: ${missingFields.join(", ")}`, { logger: this.logger, tryNextLink: false }); return token; } catch (error) { throw new config.CredentialsProviderError(`Failed to load token from ${tokenFilePath}: ${String(error)}`, { logger: this.logger, tryNextLink: false }); } } async saveToken(token) { const tokenFilePath = this.getTokenFilePath(); const directory = node_path.dirname(tokenFilePath); try { await node_fs.promises.mkdir(directory, { recursive: true }); } catch (error) {} await node_fs.promises.writeFile(tokenFilePath, JSON.stringify(token, null, 2), "utf8"); } getTokenFilePath() { const directory = process.env.AWS_LOGIN_CACHE_DIRECTORY ?? node_path.join(node_os.homedir(), ".aws", "login", "cache"); const loginSessionBytes = Buffer.from(this.loginSession, "utf8"); const loginSessionSha256 = node_crypto.createHash("sha256").update(loginSessionBytes).digest("hex"); return node_path.join(directory, `${loginSessionSha256}.json`); } derToRawSignature(derSignature) { let offset = 2; if (derSignature[offset] !== 2) throw new Error("Invalid DER signature"); offset++; const rLength = derSignature[offset++]; let r = derSignature.subarray(offset, offset + rLength); offset += rLength; if (derSignature[offset] !== 2) throw new Error("Invalid DER signature"); offset++; const sLength = derSignature[offset++]; let s = derSignature.subarray(offset, offset + sLength); r = r[0] === 0 ? r.subarray(1) : r; s = s[0] === 0 ? s.subarray(1) : s; const rPadded = Buffer.concat([Buffer.alloc(32 - r.length), r]); const sPadded = Buffer.concat([Buffer.alloc(32 - s.length), s]); return Buffer.concat([rPadded, sPadded]); } createDPoPInterceptor(middlewareStack) { middlewareStack.add((next) => async (args) => { if (protocols.HttpRequest.isInstance(args.request)) { const request = args.request; const actualEndpoint = `${request.protocol}//${request.hostname}${request.port ? `:${request.port}` : ""}${request.path}`; const dpop = await this.generateDpop(request.method, actualEndpoint); request.headers = { ...request.headers, DPoP: dpop }; } return next(args); }, { step: "finalizeRequest", name: "dpopInterceptor", override: true }); } async generateDpop(method = "POST", endpoint) { const token = await this.loadToken(); try { const privateKey = node_crypto.createPrivateKey({ key: token.dpopKey, format: "pem", type: "sec1" }); const publicDer = node_crypto.createPublicKey(privateKey).export({ format: "der", type: "spki" }); let pointStart = -1; for (let i = 0; i < publicDer.length; i++) if (publicDer[i] === 4) { pointStart = i; break; } const x = publicDer.slice(pointStart + 1, pointStart + 33); const y = publicDer.slice(pointStart + 33, pointStart + 65); const header = { alg: "ES256", typ: "dpop+jwt", jwk: { kty: "EC", crv: "P-256", x: x.toString("base64url"), y: y.toString("base64url") } }; const payload = { jti: crypto.randomUUID(), htm: method, htu: endpoint, iat: Math.floor(Date.now() / 1e3) }; const message = `${Buffer.from(JSON.stringify(header)).toString("base64url")}.${Buffer.from(JSON.stringify(payload)).toString("base64url")}`; const asn1Signature = node_crypto.sign("sha256", Buffer.from(message), privateKey); return `${message}.${this.derToRawSignature(asn1Signature).toString("base64url")}`; } catch (error) { throw new config.CredentialsProviderError(`Failed to generate Dpop proof: ${error instanceof Error ? error.message : String(error)}`, { logger: this.logger, tryNextLink: false }); } } }; const fromLoginCredentials = (init) => async ({ callerClientConfig } = {}) => { init?.logger?.debug?.("@aws-sdk/credential-providers - fromLoginCredentials"); const profiles = await config.parseKnownFiles(init || {}); const profileName = config.getProfileName({ profile: init?.profile ?? callerClientConfig?.profile }); const profile = profiles[profileName]; if (!profile?.login_session) throw new config.CredentialsProviderError(`Profile ${profileName} does not contain login_session.`, { tryNextLink: true, logger: init?.logger }); const credentials = await new LoginCredentialsFetcher(profile, init, callerClientConfig).loadCredentials(); return client.setCredentialFeature(credentials, "CREDENTIALS_LOGIN", "AD"); }; exports.fromLoginCredentials = fromLoginCredentials; })); //#endregion //#region node_modules/@aws-sdk/credential-provider-ini/dist-cjs/index.js var require_dist_cjs = /* @__PURE__ */ __commonJSMin(((exports) => { var config = (init_config(), __toCommonJS(config_exports)); var client = (init_client(), __toCommonJS(client_exports)); var credentialProviderLogin = require_dist_cjs$1(); const resolveCredentialSource = (credentialSource, profileName, logger) => { const sourceProvidersMap = { EcsContainer: async (options) => { const { fromHttp } = await import("./dist-cjs-Bp0J3E_X.js").then((m) => /* @__PURE__ */ __toESM(m.default)); const { fromContainerMetadata } = await import("./dist-cjs-DG_yopAP.js").then((m) => /* @__PURE__ */ __toESM(m.default)); logger?.debug("@aws-sdk/credential-provider-ini - credential_source is EcsContainer"); return async () => config.chain(fromHttp(options ?? {}), fromContainerMetadata(options))().then(setNamedProvider); }, Ec2InstanceMetadata: async (options) => { logger?.debug("@aws-sdk/credential-provider-ini - credential_source is Ec2InstanceMetadata"); const { fromInstanceMetadata } = await import("./dist-cjs-DG_yopAP.js").then((m) => /* @__PURE__ */ __toESM(m.default)); return async () => fromInstanceMetadata(options)().then(setNamedProvider); }, Environment: async (options) => { logger?.debug("@aws-sdk/credential-provider-ini - credential_source is Environment"); const { fromEnv } = await import("./dist-cjs-2Kev6nxC.js").then((m) => /* @__PURE__ */ __toESM(m.default)); return async () => fromEnv(options)().then(setNamedProvider); } }; if (credentialSource in sourceProvidersMap) return sourceProvidersMap[credentialSource]; else throw new config.CredentialsProviderError(`Unsupported credential source in profile ${profileName}. Got ${credentialSource}, expected EcsContainer or Ec2InstanceMetadata or Environment.`, { logger }); }; const setNamedProvider = (creds) => client.setCredentialFeature(creds, "CREDENTIALS_PROFILE_NAMED_PROVIDER", "p"); const isAssumeRoleProfile = (arg, { profile = "default", logger } = {}) => { return Boolean(arg) && typeof arg === "object" && typeof arg.role_arn === "string" && ["undefined", "string"].indexOf(typeof arg.role_session_name) > -1 && ["undefined", "string"].indexOf(typeof arg.external_id) > -1 && ["undefined", "string"].indexOf(typeof arg.mfa_serial) > -1 && (isAssumeRoleWithSourceProfile(arg, { profile, logger }) || isCredentialSourceProfile(arg, { profile, logger })); }; const isAssumeRoleWithSourceProfile = (arg, { profile, logger }) => { const withSourceProfile = typeof arg.source_profile === "string" && typeof arg.credential_source === "undefined"; if (withSourceProfile) logger?.debug?.(` ${profile} isAssumeRoleWithSourceProfile source_profile=${arg.source_profile}`); return withSourceProfile; }; const isCredentialSourceProfile = (arg, { profile, logger }) => { const withProviderProfile = typeof arg.credential_source === "string" && typeof arg.source_profile === "undefined"; if (withProviderProfile) logger?.debug?.(` ${profile} isCredentialSourceProfile credential_source=${arg.credential_source}`); return withProviderProfile; }; const resolveAssumeRoleCredentials = async (profileName, profiles, options, callerClientConfig, visitedProfiles = {}, resolveProfileData) => { options.logger?.debug("@aws-sdk/credential-provider-ini - resolveAssumeRoleCredentials (STS)"); const profileData = profiles[profileName]; const { source_profile, region } = profileData; if (!options.roleAssumer) { const { getDefaultRoleAssumer } = await import("./sts-LYlzGSjF.js"); options.roleAssumer = getDefaultRoleAssumer({ ...options.clientConfig, credentialProviderLogger: options.logger, parentClientConfig: { ...callerClientConfig, ...options?.parentClientConfig, region: region ?? options?.parentClientConfig?.region ?? callerClientConfig?.region } }, options.clientPlugins); } if (source_profile && source_profile in visitedProfiles) throw new config.CredentialsProviderError(`Detected a cycle attempting to resolve credentials for profile ${config.getProfileName(options)}. Profiles visited: ` + Object.keys(visitedProfiles).join(", "), { logger: options.logger }); options.logger?.debug(`@aws-sdk/credential-provider-ini - finding credential resolver using ${source_profile ? `source_profile=[${source_profile}]` : `profile=[${profileName}]`}`); const sourceCredsProvider = source_profile ? resolveProfileData(source_profile, profiles, options, callerClientConfig, { ...visitedProfiles, [source_profile]: true }, isCredentialSourceWithoutRoleArn(profiles[source_profile] ?? {})) : (await resolveCredentialSource(profileData.credential_source, profileName, options.logger)(options))(); if (isCredentialSourceWithoutRoleArn(profileData)) return sourceCredsProvider.then((creds) => client.setCredentialFeature(creds, "CREDENTIALS_PROFILE_SOURCE_PROFILE", "o")); else { const params = { RoleArn: profileData.role_arn, RoleSessionName: profileData.role_session_name || `aws-sdk-js-${Date.now()}`, ExternalId: profileData.external_id, DurationSeconds: parseInt(profileData.duration_seconds || "3600", 10) }; const { mfa_serial } = profileData; if (mfa_serial) { if (!options.mfaCodeProvider) throw new config.CredentialsProviderError(`Profile ${profileName} requires multi-factor authentication, but no MFA code callback was provided.`, { logger: options.logger, tryNextLink: false }); params.SerialNumber = mfa_serial; params.TokenCode = await options.mfaCodeProvider(mfa_serial); } const sourceCreds = await sourceCredsProvider; return options.roleAssumer(sourceCreds, params).then((creds) => client.setCredentialFeature(creds, "CREDENTIALS_PROFILE_SOURCE_PROFILE", "o")); } }; const isCredentialSourceWithoutRoleArn = (section) => { return !section.role_arn && !!section.credential_source; }; const isLoginProfile = (data) => { return Boolean(data && data.login_session); }; const resolveLoginCredentials = async (profileName, options, callerClientConfig) => { const credentials = await credentialProviderLogin.fromLoginCredentials({ ...options, profile: profileName })({ callerClientConfig }); return client.setCredentialFeature(credentials, "CREDENTIALS_PROFILE_LOGIN", "AC"); }; const isProcessProfile = (arg) => Boolean(arg) && typeof arg === "object" && typeof arg.credential_process === "string"; const resolveProcessCredentials = async (options, profile) => import("./dist-cjs-DJBb9-fe.js").then((m) => /* @__PURE__ */ __toESM(m.default)).then(({ fromProcess }) => fromProcess({ ...options, profile })().then((creds) => client.setCredentialFeature(creds, "CREDENTIALS_PROFILE_PROCESS", "v"))); const resolveSsoCredentials = async (profile, profileData, options = {}, callerClientConfig) => { const { fromSSO } = await import("./dist-cjs-DEahOQo0.js").then((m) => /* @__PURE__ */ __toESM(m.default)); return fromSSO({ profile, logger: options.logger, parentClientConfig: options.parentClientConfig, clientConfig: options.clientConfig })({ callerClientConfig }).then((creds) => { if (profileData.sso_session) return client.setCredentialFeature(creds, "CREDENTIALS_PROFILE_SSO", "r"); else return client.setCredentialFeature(creds, "CREDENTIALS_PROFILE_SSO_LEGACY", "t"); }); }; 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 isStaticCredsProfile = (arg) => Boolean(arg) && typeof arg === "object" && typeof arg.aws_access_key_id === "string" && typeof arg.aws_secret_access_key === "string" && ["undefined", "string"].indexOf(typeof arg.aws_session_token) > -1 && ["undefined", "string"].indexOf(typeof arg.aws_account_id) > -1; const resolveStaticCredentials = async (profile, options) => { options?.logger?.debug("@aws-sdk/credential-provider-ini - resolveStaticCredentials"); const credentials = { accessKeyId: profile.aws_access_key_id, secretAccessKey: profile.aws_secret_access_key, sessionToken: profile.aws_session_token, ...profile.aws_credential_scope && { credentialScope: profile.aws_credential_scope }, ...profile.aws_account_id && { accountId: profile.aws_account_id } }; return client.setCredentialFeature(credentials, "CREDENTIALS_PROFILE", "n"); }; const isWebIdentityProfile = (arg) => Boolean(arg) && typeof arg === "object" && typeof arg.web_identity_token_file === "string" && typeof arg.role_arn === "string" && ["undefined", "string"].indexOf(typeof arg.role_session_name) > -1; const resolveWebIdentityCredentials = async (profile, options, callerClientConfig) => import("./dist-cjs-096yFk39.js").then((m) => /* @__PURE__ */ __toESM(m.default)).then(({ fromTokenFile }) => fromTokenFile({ webIdentityTokenFile: profile.web_identity_token_file, roleArn: profile.role_arn, roleSessionName: profile.role_session_name, roleAssumerWithWebIdentity: options.roleAssumerWithWebIdentity, logger: options.logger, parentClientConfig: options.parentClientConfig })({ callerClientConfig }).then((creds) => client.setCredentialFeature(creds, "CREDENTIALS_PROFILE_STS_WEB_ID_TOKEN", "q"))); const resolveProfileData = async (profileName, profiles, options, callerClientConfig, visitedProfiles = {}, isAssumeRoleRecursiveCall = false) => { const data = profiles[profileName]; if (Object.keys(visitedProfiles).length > 0 && isStaticCredsProfile(data)) return resolveStaticCredentials(data, options); if (isAssumeRoleRecursiveCall || isAssumeRoleProfile(data, { profile: profileName, logger: options.logger })) return resolveAssumeRoleCredentials(profileName, profiles, options, callerClientConfig, visitedProfiles, resolveProfileData); if (isStaticCredsProfile(data)) return resolveStaticCredentials(data, options); if (isWebIdentityProfile(data)) return resolveWebIdentityCredentials(data, options, callerClientConfig); if (isProcessProfile(data)) return resolveProcessCredentials(options, profileName); if (isSsoProfile(data)) return await resolveSsoCredentials(profileName, data, options, callerClientConfig); if (isLoginProfile(data)) return resolveLoginCredentials(profileName, options, callerClientConfig); throw new config.CredentialsProviderError(`Could not resolve credentials using profile: [${profileName}] in configuration/credentials file(s).`, { logger: options.logger }); }; const fromIni = (init = {}) => async ({ callerClientConfig } = {}) => { init.logger?.debug("@aws-sdk/credential-provider-ini - fromIni"); const profiles = await config.parseKnownFiles(init); return resolveProfileData(config.getProfileName({ profile: init.profile ?? callerClientConfig?.profile }), profiles, init, callerClientConfig); }; exports.fromIni = fromIni; })); //#endregion export default require_dist_cjs(); export {};