import { createScopedDmSecurityResolver } from "openclaw/plugin-sdk/channel-config-helpers" ;
import { createOpenProviderConfiguredRouteWarningCollector } from "openclaw/plugin-sdk/channel-policy" ;
import type { ResolvedDiscordAccount } from "./accounts.js" ;
import type { ChannelPlugin } from "./channel-api.js" ;
const resolveDiscordDmPolicy = createScopedDmSecurityResolver<ResolvedDiscordAccount>({
channelKey: "discord" ,
resolvePolicy: (account) => account.config.dm?.policy,
resolveAllowFrom: (account) => account.config.dm?.allowFrom,
allowFromPathSuffix: "dm." ,
normalizeEntry: (raw) =>
raw
.trim()
.replace(/^(discord|user):/i, "" )
.replace(/^<@!?(\d+)>$/, "$1" ),
});
const collectDiscordSecurityWarnings =
createOpenProviderConfiguredRouteWarningCollector<ResolvedDiscordAccount>({
providerConfigPresent: (cfg) => cfg.channels?.discord !== undefined,
resolveGroupPolicy: (account) => account.config.groupPolicy,
resolveRouteAllowlistConfigured: (account) =>
Object.keys(account.config.guilds ?? {}).length > 0 ,
configureRouteAllowlist: {
surface: "Discord guilds" ,
openScope: "any channel not explicitly denied" ,
groupPolicyPath: "channels.discord.groupPolicy" ,
routeAllowlistPath: "channels.discord.guilds.<id>.channels" ,
},
missingRouteAllowlist: {
surface: "Discord guilds" ,
openBehavior: "with no guild/channel allowlist; any channel can trigger (mention-gated)" ,
remediation:
'Set channels.discord.groupPolicy="allowlist" and configure channels.discord.guilds.<id>.channels' ,
},
});
let discordSecurityAuditModulePromise:
| Promise<typeof import ("./security-audit.runtime.js" )>
| undefined;
async function loadDiscordSecurityAuditModule() {
discordSecurityAuditModulePromise ??= import ("./security-audit.runtime.js" );
return await discordSecurityAuditModulePromise;
}
export const discordSecurityAdapter = {
resolveDmPolicy: resolveDiscordDmPolicy,
collectWarnings: collectDiscordSecurityWarnings,
collectAuditFindings: async (params) =>
(await loadDiscordSecurityAuditModule()).collectDiscordSecurityAuditFindings(params),
} satisfies NonNullable<ChannelPlugin<ResolvedDiscordAccount>["security" ]>;
Messung V0.5 in Prozent C=100 H=100 G=100
[Verzeichnis aufwärts0.7unsichere VerbindungÜbersetzung europäischer Sprachen durch Browser2026-09-27]