mirror of
https://github.com/openclaw/openclaw.git
synced 2026-05-06 06:40:44 +00:00
refactor: derive CLI web credential targets
This commit is contained in:
@@ -20,14 +20,34 @@ describe("command secret targets module import", () => {
|
||||
expect(listSecretTargetRegistryEntries).not.toHaveBeenCalled();
|
||||
expect(mod.getModelsCommandSecretTargetIds().has("models.providers.*.apiKey")).toBe(true);
|
||||
expect(mod.getQrRemoteCommandSecretTargetIds().has("gateway.remote.token")).toBe(true);
|
||||
expect(
|
||||
mod.getAgentRuntimeCommandSecretTargetIds().has("agents.defaults.memorySearch.remote.apiKey"),
|
||||
).toBe(true);
|
||||
expect(listSecretTargetRegistryEntries).not.toHaveBeenCalled();
|
||||
expect(() => mod.getChannelsCommandSecretTargetIds()).toThrow("registry touched too early");
|
||||
expect(listSecretTargetRegistryEntries).toHaveBeenCalledTimes(1);
|
||||
});
|
||||
|
||||
it("loads registry lazily for agent runtime plugin credential targets", async () => {
|
||||
const listSecretTargetRegistryEntries = vi.fn(() => [
|
||||
{ id: "plugins.entries.example.config.webSearch.apiKey" },
|
||||
{ id: "plugins.entries.example.config.other.apiKey" },
|
||||
{ id: "channels.telegram.botToken" },
|
||||
]);
|
||||
|
||||
vi.doMock("../secrets/target-registry.js", () => ({
|
||||
discoverConfigSecretTargetsByIds: vi.fn(() => []),
|
||||
listSecretTargetRegistryEntries,
|
||||
}));
|
||||
|
||||
const mod = await import("./command-secret-targets.js");
|
||||
|
||||
expect(listSecretTargetRegistryEntries).not.toHaveBeenCalled();
|
||||
const ids = mod.getAgentRuntimeCommandSecretTargetIds();
|
||||
expect(ids.has("agents.defaults.memorySearch.remote.apiKey")).toBe(true);
|
||||
expect(ids.has("plugins.entries.example.config.webSearch.apiKey")).toBe(true);
|
||||
expect(ids.has("plugins.entries.example.config.other.apiKey")).toBe(false);
|
||||
expect(ids.has("channels.telegram.botToken")).toBe(false);
|
||||
expect(listSecretTargetRegistryEntries).toHaveBeenCalledTimes(1);
|
||||
});
|
||||
|
||||
it("can resolve configured-channel status targets without the full registry", async () => {
|
||||
const listSecretTargetRegistryEntries = vi.fn(() => {
|
||||
throw new Error("registry touched too early");
|
||||
|
||||
@@ -30,16 +30,6 @@ const STATIC_AGENT_RUNTIME_BASE_TARGET_IDS = [
|
||||
"messages.tts.providers.*.apiKey",
|
||||
"skills.entries.*.apiKey",
|
||||
"tools.web.search.apiKey",
|
||||
"plugins.entries.brave.config.webSearch.apiKey",
|
||||
"plugins.entries.google.config.webSearch.apiKey",
|
||||
"plugins.entries.exa.config.webSearch.apiKey",
|
||||
"plugins.entries.xai.config.webSearch.apiKey",
|
||||
"plugins.entries.moonshot.config.webSearch.apiKey",
|
||||
"plugins.entries.perplexity.config.webSearch.apiKey",
|
||||
"plugins.entries.firecrawl.config.webSearch.apiKey",
|
||||
"plugins.entries.firecrawl.config.webFetch.apiKey",
|
||||
"plugins.entries.tavily.config.webSearch.apiKey",
|
||||
"plugins.entries.minimax.config.webSearch.apiKey",
|
||||
] as const;
|
||||
const STATIC_STATUS_TARGET_IDS = [
|
||||
"agents.defaults.memorySearch.remote.apiKey",
|
||||
@@ -67,6 +57,7 @@ type CommandSecretTargets = {
|
||||
};
|
||||
|
||||
let cachedCommandSecretTargets: CommandSecretTargets | undefined;
|
||||
let cachedAgentRuntimeBaseTargetIds: string[] | undefined;
|
||||
let cachedChannelSecretTargetIds: string[] | undefined;
|
||||
|
||||
function getChannelSecretTargetIds(): string[] {
|
||||
@@ -74,6 +65,26 @@ function getChannelSecretTargetIds(): string[] {
|
||||
return cachedChannelSecretTargetIds;
|
||||
}
|
||||
|
||||
function isPluginWebCredentialTargetId(id: string): boolean {
|
||||
const segments = id.split(".");
|
||||
if (segments[0] !== "plugins" || segments[1] !== "entries" || segments[3] !== "config") {
|
||||
return false;
|
||||
}
|
||||
const configPath = segments.slice(4).join(".");
|
||||
return configPath === "webSearch.apiKey" || configPath === "webFetch.apiKey";
|
||||
}
|
||||
|
||||
function getAgentRuntimeBaseTargetIds(): string[] {
|
||||
cachedAgentRuntimeBaseTargetIds ??= [
|
||||
...STATIC_AGENT_RUNTIME_BASE_TARGET_IDS,
|
||||
...listSecretTargetRegistryEntries()
|
||||
.map((entry) => entry.id)
|
||||
.filter(isPluginWebCredentialTargetId)
|
||||
.toSorted(),
|
||||
];
|
||||
return cachedAgentRuntimeBaseTargetIds;
|
||||
}
|
||||
|
||||
function isScopedChannelSecretTargetEntry(params: {
|
||||
entry: {
|
||||
id: string;
|
||||
@@ -120,7 +131,7 @@ function buildCommandSecretTargets(): CommandSecretTargets {
|
||||
const channelTargetIds = getChannelSecretTargetIds();
|
||||
return {
|
||||
channels: channelTargetIds,
|
||||
agentRuntime: [...STATIC_AGENT_RUNTIME_BASE_TARGET_IDS, ...channelTargetIds],
|
||||
agentRuntime: [...getAgentRuntimeBaseTargetIds(), ...channelTargetIds],
|
||||
status: [...STATIC_STATUS_TARGET_IDS, ...channelTargetIds],
|
||||
securityAudit: [...STATIC_SECURITY_AUDIT_TARGET_IDS, ...channelTargetIds],
|
||||
};
|
||||
@@ -213,7 +224,7 @@ export function getAgentRuntimeCommandSecretTargetIds(params?: {
|
||||
includeChannelTargets?: boolean;
|
||||
}): Set<string> {
|
||||
if (params?.includeChannelTargets !== true) {
|
||||
return toTargetIdSet(STATIC_AGENT_RUNTIME_BASE_TARGET_IDS);
|
||||
return toTargetIdSet(getAgentRuntimeBaseTargetIds());
|
||||
}
|
||||
return toTargetIdSet(getCommandSecretTargets().agentRuntime);
|
||||
}
|
||||
|
||||
@@ -26,6 +26,12 @@ const CORE_SECRET_SURFACE_GUARDS = [
|
||||
/plugins\.entries\.(?:brave|google|exa|xai|moonshot|perplexity|firecrawl|tavily|minimax)\.config\.web(?:Search|Fetch)\.apiKey/,
|
||||
],
|
||||
},
|
||||
{
|
||||
path: "src/cli/command-secret-targets.ts",
|
||||
forbiddenPatterns: [
|
||||
/plugins\.entries\.(?:brave|google|exa|xai|moonshot|perplexity|firecrawl|tavily|minimax)\.config\.web(?:Search|Fetch)\.apiKey/,
|
||||
],
|
||||
},
|
||||
{
|
||||
path: "src/config/markdown-tables.ts",
|
||||
forbiddenPatterns: [/["']signal["']/, /["']whatsapp["']/, /["']mattermost["']/],
|
||||
|
||||
Reference in New Issue
Block a user