UNPKG

openclaw

Version:

Multi-channel AI gateway with extensible messaging integrations

222 lines (221 loc) 10.5 kB
import { i as registerSecretValueForRedaction } from "./secret-redaction-registry-BOLC6DkF.js"; import { t as formatErrorMessage } from "./errors-Db3Ymjlb.js"; import { a as isKnownSecretTargetId, i as isKnownCoreSecretTargetId } from "./target-registry-query-qVhyD-Hq.js"; import "./target-registry-BHDUOLUU.js"; import { n as SecretStoreValidationError } from "./secret-store-validation-error-Bzzf_1MN.js"; import { i as listSecretStoreEntries, o as purgeExpiredSecretStoreEntries, r as deleteSecretStoreEntry, u as writeSecretStoreEntry } from "./secret-store-CC1e6gjb.js"; import { t as ErrorCodes } from "./gateway-error-details-w0nAGBBp.js"; import { _r as validateSecretsStoreMutationResult, fr as validateSecretsResolveParams, gr as validateSecretsStoreListResult, hr as validateSecretsStoreListParams, mr as validateSecretsStoreDeleteParams, pr as validateSecretsResolveResult, vr as validateSecretsStoreSetParams } from "./src-BiL5aQto.js"; import { d as errorShape } from "./error-codes-Bo8q2D1o.js"; import { i as collectSecretStoreRefKeysInSnapshot, l as getActiveSecretsRuntimeSnapshotState } from "./runtime-state-C4aJ8Hzz.js"; import { t as holdGatewayPolicyResponse } from "./ws-policy-close-CZEENNh9.js"; import { t as assertValidParams } from "./validation-pzrlzFvo.js"; import { n as createAgentRuntimeAuthorityGuard } from "./agent-runtime-authority-BkcmfdKo.js"; //#region src/gateway/server-methods/secrets.ts const teamScope = { kind: "team" }; function toProtocolStoreEntry(entry) { const metadata = { name: entry.name, scopeKind: "team", scopeId: "", createdAtMs: entry.createdAtMs, updatedAtMs: entry.updatedAtMs, ...entry.updatedBy ? { updatedBy: entry.updatedBy } : {} }; if (entry.kind === "env") { if (typeof entry.valuePreview !== "string") throw new Error(`Secret store env metadata is missing its value for ${entry.name}.`); return { ...metadata, kind: "env", value: entry.valuePreview }; } return { ...metadata, kind: "secret", allowedHosts: entry.allowedHosts ?? [] }; } function storeUpdatedBy(client) { return client?.authenticatedUserProfile?.displayName?.trim() || client?.connect?.client?.displayName?.trim() || client?.connect?.client?.id?.trim() || "gateway"; } /** Owns redaction-first store writes and the runtime refresh shared by Gateway RPCs. */ function createSecretStoreWriteService(params) { const purgeRetention = () => { try { purgeExpiredSecretStoreEntries(); } catch (error) { params.log?.warn?.(`secrets.store retention purge failed: ${formatErrorMessage(error)}`); } }; const reloadReference = async (name) => { purgeRetention(); const snapshot = getActiveSecretsRuntimeSnapshotState(); const refKeys = snapshot ? collectSecretStoreRefKeysInSnapshot(snapshot, name) : /* @__PURE__ */ new Set(); if (refKeys.size === 0) return { reloaded: false }; try { return { reloaded: true, warningCount: (await params.reloadSecrets({ forceColdRefKeys: refKeys, joinInFlight: false })).warningCount }; } catch (error) { params.log?.warn?.(`secrets.store runtime refresh failed: ${formatErrorMessage(error)}`); throw error; } }; return { resolveUpdatedBy: storeUpdatedBy, reloadReference, write(input) { registerSecretValueForRedaction(input.value); writeSecretStoreEntry({ scope: teamScope, ...input }); } }; } function invalidSecretsResolveField(errors) { for (const issue of errors ?? []) { const instancePath = issue.instancePath ?? ""; if (instancePath === "/commandName" || instancePath === "" && (String(issue.params?.missingProperty) === "commandName" || Array.isArray(issue.params?.requiredProperties) && issue.params.requiredProperties.includes("commandName"))) return "commandName"; if (instancePath.startsWith("/allowedPaths")) return "allowedPaths"; if (instancePath.startsWith("/forcedActivePaths")) return "forcedActivePaths"; if (instancePath.startsWith("/optionalActivePaths")) return "optionalActivePaths"; if (instancePath.startsWith("/providerOverrides")) return "providerOverrides"; } return "targetIds"; } function createSecretsHandlers(params) { return { "secrets.reload": async ({ respond }) => { try { holdGatewayPolicyResponse(respond); respond(true, { ok: true, warningCount: (await params.reloadSecrets()).warningCount }); } catch (error) { params.log?.warn?.(`secrets.reload failed: ${formatErrorMessage(error)}`); respond(false, void 0, errorShape(ErrorCodes.UNAVAILABLE, "secrets.reload failed")); } }, "secrets.resolve": async ({ params: requestParams, respond }) => { if (!validateSecretsResolveParams(requestParams)) { const field = invalidSecretsResolveField(validateSecretsResolveParams.errors); respond(false, void 0, errorShape(ErrorCodes.INVALID_REQUEST, `invalid secrets.resolve params: ${field}`)); return; } const commandName = requestParams.commandName.trim(); if (!commandName) { respond(false, void 0, errorShape(ErrorCodes.INVALID_REQUEST, "invalid secrets.resolve params: commandName")); return; } const targetIds = requestParams.targetIds.map((entry) => entry.trim()).filter((entry) => entry.length > 0); const allowedPaths = requestParams.allowedPaths?.map((entry) => entry.trim()).filter((entry) => entry.length > 0); const forcedActivePaths = requestParams.forcedActivePaths?.map((entry) => entry.trim()).filter((entry) => entry.length > 0); const optionalActivePaths = requestParams.optionalActivePaths?.map((entry) => entry.trim()).filter((entry) => entry.length > 0); const providerOverrides = { ...requestParams.providerOverrides?.webSearch?.trim() ? { webSearch: requestParams.providerOverrides.webSearch.trim() } : {}, ...requestParams.providerOverrides?.webFetch?.trim() ? { webFetch: requestParams.providerOverrides.webFetch.trim() } : {} }; for (const targetId of targetIds) if (!isKnownCoreSecretTargetId(targetId) && !isKnownSecretTargetId(targetId)) { respond(false, void 0, errorShape(ErrorCodes.INVALID_REQUEST, `invalid secrets.resolve params: unknown target id "${String(targetId)}"`)); return; } try { const result = await params.resolveSecrets({ commandName, targetIds, ...allowedPaths ? { allowedPaths } : {}, ...forcedActivePaths ? { forcedActivePaths } : {}, ...optionalActivePaths ? { optionalActivePaths } : {}, ...Object.keys(providerOverrides).length > 0 ? { providerOverrides } : {} }); const payload = { ok: true, assignments: result.assignments, diagnostics: result.diagnostics, inactiveRefPaths: result.inactiveRefPaths }; if (!validateSecretsResolveResult(payload)) throw new Error("secrets.resolve returned invalid payload."); respond(true, payload); } catch (error) { params.log?.warn?.(`secrets.resolve failed: ${formatErrorMessage(error)}`); respond(false, void 0, errorShape(ErrorCodes.UNAVAILABLE, "secrets.resolve failed")); } }, "secrets.store.list": ({ params: requestParams, respond }) => { if (!assertValidParams(requestParams, validateSecretsStoreListParams, "secrets.store.list", respond)) return; try { const result = { entries: listSecretStoreEntries({ scope: teamScope }).map(toProtocolStoreEntry) }; if (!validateSecretsStoreListResult(result)) throw new Error("secrets.store.list returned invalid payload."); respond(true, result); } catch (error) { params.log?.warn?.(`secrets.store.list failed: ${formatErrorMessage(error)}`); respond(false, void 0, errorShape(ErrorCodes.UNAVAILABLE, "secrets.store.list failed")); } }, "secrets.store.set": async ({ params: requestParams, respond, client }) => { if (!assertValidParams(requestParams, validateSecretsStoreSetParams, "secrets.store.set", respond)) return; let saved = false; try { holdGatewayPolicyResponse(respond); params.storeWriteService.write({ name: requestParams.name, value: requestParams.value, kind: requestParams.kind, ...requestParams.allowedHosts !== void 0 ? { allowedHosts: requestParams.allowedHosts } : {}, updatedBy: params.storeWriteService.resolveUpdatedBy(client) }); saved = true; const result = { ok: true, ...await params.storeWriteService.reloadReference(requestParams.name) }; if (!validateSecretsStoreMutationResult(result)) throw new Error("secrets.store.set returned invalid payload."); respond(true, result); } catch (error) { if (!saved && error instanceof SecretStoreValidationError) { respond(false, void 0, errorShape(ErrorCodes.INVALID_REQUEST, error.message)); return; } params.log?.warn?.(`secrets.store.set failed: ${formatErrorMessage(error)}`); respond(false, void 0, errorShape(ErrorCodes.UNAVAILABLE, saved ? "Secret store entry was saved, but post-write runtime refresh failed. Resolve provider errors and retry secrets.reload." : "secrets.store.set failed")); } }, "secrets.store.delete": async ({ params: requestParams, respond, client, context }) => { if (!assertValidParams(requestParams, validateSecretsStoreDeleteParams, "secrets.store.delete", respond)) return; let deleted = false; try { const agentId = client?.internal?.agentRuntimeIdentity?.agentId; if (agentId) params.log?.debug?.(`secrets.store.delete requested by agent:${agentId}`); if (!createAgentRuntimeAuthorityGuard(client, context, respond).ensureActive()) return; holdGatewayPolicyResponse(respond); deleteSecretStoreEntry({ scope: teamScope, name: requestParams.name }); deleted = true; const result = { ok: true, ...await params.storeWriteService.reloadReference(requestParams.name) }; if (!validateSecretsStoreMutationResult(result)) throw new Error("secrets.store.delete returned invalid payload."); respond(true, result); } catch (error) { if (!deleted && error instanceof SecretStoreValidationError) { respond(false, void 0, errorShape(ErrorCodes.INVALID_REQUEST, error.message)); return; } params.log?.warn?.(`secrets.store.delete failed: ${formatErrorMessage(error)}`); respond(false, void 0, errorShape(ErrorCodes.UNAVAILABLE, deleted ? "Secret store entry was deleted, but the active runtime could not refresh. Update the config reference or restore the entry, then retry secrets.reload." : "secrets.store.delete failed")); } } }; } //#endregion export { createSecretStoreWriteService, createSecretsHandlers };