mirror of
https://github.com/openclaw/openclaw.git
synced 2026-05-06 17:31:06 +00:00
perf: speed up security audit test imports
This commit is contained in:
6
extensions/discord/account-inspect-api.ts
Normal file
6
extensions/discord/account-inspect-api.ts
Normal file
@@ -0,0 +1,6 @@
|
||||
import type { OpenClawConfig } from "openclaw/plugin-sdk/config-runtime";
|
||||
import { inspectDiscordAccount } from "./src/account-inspect.js";
|
||||
|
||||
export function inspectDiscordReadOnlyAccount(cfg: OpenClawConfig, accountId?: string | null) {
|
||||
return inspectDiscordAccount({ cfg, accountId });
|
||||
}
|
||||
@@ -22,6 +22,10 @@ export default defineBundledChannelEntry({
|
||||
specifier: "./runtime-api.js",
|
||||
exportName: "setDiscordRuntime",
|
||||
},
|
||||
accountInspect: {
|
||||
specifier: "./account-inspect-api.js",
|
||||
exportName: "inspectDiscordReadOnlyAccount",
|
||||
},
|
||||
registerFull(api) {
|
||||
api.on("subagent_spawning", async (event) => {
|
||||
const { handleDiscordSubagentSpawning } = await loadDiscordSubagentHooksModule();
|
||||
|
||||
@@ -1 +1,81 @@
|
||||
export { collectFeishuSecurityAuditFindings } from "./src/security-audit.js";
|
||||
import type { OpenClawConfig } from "./runtime-api.js";
|
||||
|
||||
function asRecord(value: unknown): Record<string, unknown> | undefined {
|
||||
return value && typeof value === "object" && !Array.isArray(value)
|
||||
? (value as Record<string, unknown>)
|
||||
: undefined;
|
||||
}
|
||||
|
||||
function hasNonEmptyString(value: unknown): boolean {
|
||||
return typeof value === "string" && value.trim().length > 0;
|
||||
}
|
||||
|
||||
function hasConfiguredSecretInput(value: unknown): boolean {
|
||||
if (hasNonEmptyString(value)) {
|
||||
return true;
|
||||
}
|
||||
const record = asRecord(value);
|
||||
return (
|
||||
Boolean(record) &&
|
||||
hasNonEmptyString(record?.source) &&
|
||||
hasNonEmptyString(record?.provider) &&
|
||||
hasNonEmptyString(record?.id)
|
||||
);
|
||||
}
|
||||
|
||||
function isFeishuDocToolEnabled(cfg: OpenClawConfig): boolean {
|
||||
const channels = asRecord(cfg.channels);
|
||||
const feishu = asRecord(channels?.feishu);
|
||||
if (!feishu || feishu.enabled === false) {
|
||||
return false;
|
||||
}
|
||||
|
||||
const baseTools = asRecord(feishu.tools);
|
||||
const baseDocEnabled = baseTools?.doc !== false;
|
||||
const baseAppId = hasNonEmptyString(feishu.appId);
|
||||
const baseAppSecret = hasConfiguredSecretInput(feishu.appSecret);
|
||||
const baseConfigured = baseAppId && baseAppSecret;
|
||||
|
||||
const accounts = asRecord(feishu.accounts);
|
||||
if (!accounts || Object.keys(accounts).length === 0) {
|
||||
return baseDocEnabled && baseConfigured;
|
||||
}
|
||||
|
||||
for (const accountValue of Object.values(accounts)) {
|
||||
const account = asRecord(accountValue) ?? {};
|
||||
if (account.enabled === false) {
|
||||
continue;
|
||||
}
|
||||
const accountTools = asRecord(account.tools);
|
||||
const effectiveTools = accountTools ?? baseTools;
|
||||
const docEnabled = effectiveTools?.doc !== false;
|
||||
if (!docEnabled) {
|
||||
continue;
|
||||
}
|
||||
const accountConfigured =
|
||||
(hasNonEmptyString(account.appId) || baseAppId) &&
|
||||
(hasConfiguredSecretInput(account.appSecret) || baseAppSecret);
|
||||
if (accountConfigured) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
export function collectFeishuSecurityAuditFindings(params: { cfg: OpenClawConfig }) {
|
||||
if (!isFeishuDocToolEnabled(params.cfg)) {
|
||||
return [];
|
||||
}
|
||||
return [
|
||||
{
|
||||
checkId: "channels.feishu.doc_owner_open_id",
|
||||
severity: "warn" as const,
|
||||
title: "Feishu doc create can grant requester permissions",
|
||||
detail:
|
||||
'channels.feishu tools include "doc"; feishu_doc action "create" can grant document access to the trusted requesting Feishu user.',
|
||||
remediation:
|
||||
"Disable channels.feishu.tools.doc when not needed, and restrict tool access for untrusted prompts.",
|
||||
},
|
||||
];
|
||||
}
|
||||
|
||||
6
extensions/slack/account-inspect-api.ts
Normal file
6
extensions/slack/account-inspect-api.ts
Normal file
@@ -0,0 +1,6 @@
|
||||
import type { OpenClawConfig } from "openclaw/plugin-sdk/config-runtime";
|
||||
import { inspectSlackAccount } from "./src/account-inspect.js";
|
||||
|
||||
export function inspectSlackReadOnlyAccount(cfg: OpenClawConfig, accountId?: string | null) {
|
||||
return inspectSlackAccount({ cfg, accountId });
|
||||
}
|
||||
@@ -29,5 +29,9 @@ export default defineBundledChannelEntry({
|
||||
specifier: "./runtime-api.js",
|
||||
exportName: "setSlackRuntime",
|
||||
},
|
||||
accountInspect: {
|
||||
specifier: "./account-inspect-api.js",
|
||||
exportName: "inspectSlackReadOnlyAccount",
|
||||
},
|
||||
registerFull: registerSlackPluginHttpRoutes,
|
||||
});
|
||||
|
||||
6
extensions/telegram/account-inspect-api.ts
Normal file
6
extensions/telegram/account-inspect-api.ts
Normal file
@@ -0,0 +1,6 @@
|
||||
import type { OpenClawConfig } from "./runtime-api.js";
|
||||
import { inspectTelegramAccount } from "./src/account-inspect.js";
|
||||
|
||||
export function inspectTelegramReadOnlyAccount(cfg: OpenClawConfig, accountId?: string | null) {
|
||||
return inspectTelegramAccount({ cfg, accountId });
|
||||
}
|
||||
@@ -17,4 +17,8 @@ export default defineBundledChannelEntry({
|
||||
specifier: "./runtime-api.js",
|
||||
exportName: "setTelegramRuntime",
|
||||
},
|
||||
accountInspect: {
|
||||
specifier: "./account-inspect-api.js",
|
||||
exportName: "inspectTelegramReadOnlyAccount",
|
||||
},
|
||||
});
|
||||
|
||||
3
extensions/zalouser/channel-plugin-api.ts
Normal file
3
extensions/zalouser/channel-plugin-api.ts
Normal file
@@ -0,0 +1,3 @@
|
||||
// Keep bundled channel entry imports narrow so bootstrap/discovery paths do
|
||||
// not drag setup-only or tool runtime surfaces into lightweight plugin loads.
|
||||
export { zalouserPlugin } from "./src/channel.js";
|
||||
@@ -21,7 +21,7 @@ export default defineBundledChannelEntry({
|
||||
description: "Zalo personal account messaging via native zca-js integration",
|
||||
importMetaUrl: import.meta.url,
|
||||
plugin: {
|
||||
specifier: "./api.js",
|
||||
specifier: "./channel-plugin-api.js",
|
||||
exportName: "zalouserPlugin",
|
||||
},
|
||||
runtime: {
|
||||
|
||||
@@ -3,7 +3,7 @@ import { defineBundledChannelSetupEntry } from "openclaw/plugin-sdk/channel-entr
|
||||
export default defineBundledChannelSetupEntry({
|
||||
importMetaUrl: import.meta.url,
|
||||
plugin: {
|
||||
specifier: "./api.js",
|
||||
specifier: "./setup-plugin-api.js",
|
||||
exportName: "zalouserSetupPlugin",
|
||||
},
|
||||
});
|
||||
|
||||
2
extensions/zalouser/setup-plugin-api.ts
Normal file
2
extensions/zalouser/setup-plugin-api.ts
Normal file
@@ -0,0 +1,2 @@
|
||||
// Keep setup-entry imports narrow so setup loads do not pull tool surfaces.
|
||||
export { zalouserSetupPlugin } from "./src/channel.setup.js";
|
||||
@@ -27,12 +27,14 @@ import {
|
||||
} from "./channel.adapters.js";
|
||||
import { listZalouserDirectoryGroupMembers } from "./directory.js";
|
||||
import type { ZalouserProbeResult } from "./probe.js";
|
||||
import { zalouserSetupAdapter } from "./setup-core.js";
|
||||
import { zalouserSetupWizard } from "./setup-surface.js";
|
||||
import { createZalouserSetupWizardProxy, zalouserSetupAdapter } from "./setup-core.js";
|
||||
import { createZalouserPluginBase } from "./shared.js";
|
||||
import { collectZalouserStatusIssues } from "./status-issues.js";
|
||||
|
||||
const loadZalouserChannelRuntime = createLazyRuntimeModule(() => import("./channel.runtime.js"));
|
||||
const zalouserSetupWizardProxy = createZalouserSetupWizardProxy(
|
||||
async () => (await import("./setup-surface.js")).zalouserSetupWizard,
|
||||
);
|
||||
|
||||
function mapUser(params: {
|
||||
id: string;
|
||||
@@ -66,7 +68,7 @@ export const zalouserPlugin: ChannelPlugin<ResolvedZalouserAccount, ZalouserProb
|
||||
createChatChannelPlugin({
|
||||
base: {
|
||||
...createZalouserPluginBase({
|
||||
setupWizard: zalouserSetupWizard,
|
||||
setupWizard: zalouserSetupWizardProxy,
|
||||
setup: zalouserSetupAdapter,
|
||||
}),
|
||||
groups: zalouserGroupsAdapter,
|
||||
|
||||
@@ -1,4 +1,8 @@
|
||||
import { createPatchedAccountSetupAdapter } from "openclaw/plugin-sdk/setup-runtime";
|
||||
import {
|
||||
createDelegatedSetupWizardProxy,
|
||||
createPatchedAccountSetupAdapter,
|
||||
type ChannelSetupWizard,
|
||||
} from "openclaw/plugin-sdk/setup-runtime";
|
||||
|
||||
const channel = "zalouser" as const;
|
||||
|
||||
@@ -7,3 +11,23 @@ export const zalouserSetupAdapter = createPatchedAccountSetupAdapter({
|
||||
validateInput: () => null,
|
||||
buildPatch: () => ({}),
|
||||
});
|
||||
|
||||
export function createZalouserSetupWizardProxy(
|
||||
loadWizard: () => Promise<ChannelSetupWizard>,
|
||||
): ChannelSetupWizard {
|
||||
return createDelegatedSetupWizardProxy({
|
||||
channel,
|
||||
loadWizard,
|
||||
status: {
|
||||
configuredLabel: "logged in",
|
||||
unconfiguredLabel: "needs QR login",
|
||||
configuredHint: "recommended · logged in",
|
||||
unconfiguredHint: "recommended · QR login",
|
||||
configuredScore: 1,
|
||||
unconfiguredScore: 15,
|
||||
},
|
||||
credentials: [],
|
||||
delegatePrepare: true,
|
||||
delegateFinalize: true,
|
||||
});
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user