mirror of
https://github.com/openclaw/openclaw.git
synced 2026-07-21 10:16:44 +00:00
fix(discord): gate user allowlist name resolution [AI] (#79002)
* fix: gate discord user allowlist name resolution * docs: add changelog entry for PR merge
This commit is contained in:
@@ -172,6 +172,7 @@ Docs: https://docs.openclaw.ai
|
||||
|
||||
### Fixes
|
||||
|
||||
- fix(discord): gate user allowlist name resolution [AI]. (#79002) Thanks @pgondhi987.
|
||||
- fix(msteams): gate startup user allowlist resolution [AI]. (#79003) Thanks @pgondhi987.
|
||||
- Harden macOS shell wrapper allowlist parsing [AI]. (#78518) Thanks @pgondhi987.
|
||||
- Gateway/macOS: `openclaw gateway stop` now uses `launchctl bootout` by default instead of unconditionally calling `launchctl disable`, so KeepAlive auto-recovery still works after unexpected crashes; use the new `--disable` flag to opt into the persistent-disable behavior when a manual stop should survive reboots. Fixes #77934. Thanks @bmoran1022.
|
||||
|
||||
@@ -1,3 +1,4 @@
|
||||
import type { DiscordAccountConfig } from "openclaw/plugin-sdk/config-types";
|
||||
import { createNonExitingRuntimeEnv } from "openclaw/plugin-sdk/plugin-test-runtime";
|
||||
import { beforeEach, describe, expect, it, vi } from "vitest";
|
||||
import * as resolveChannelsModule from "../resolve-channels.js";
|
||||
@@ -44,6 +45,7 @@ describe("resolveDiscordAllowlistConfig", () => {
|
||||
},
|
||||
fetcher: vi.fn() as unknown as typeof fetch,
|
||||
runtime,
|
||||
discordConfig: { dangerouslyAllowNameMatching: true } as DiscordAccountConfig,
|
||||
});
|
||||
|
||||
expect(result.allowFrom).toEqual(["111", "*"]);
|
||||
@@ -76,6 +78,7 @@ describe("resolveDiscordAllowlistConfig", () => {
|
||||
},
|
||||
fetcher: vi.fn() as unknown as typeof fetch,
|
||||
runtime,
|
||||
discordConfig: { dangerouslyAllowNameMatching: true } as DiscordAccountConfig,
|
||||
});
|
||||
|
||||
const logs = (runtime.log as ReturnType<typeof vi.fn>).mock.calls
|
||||
@@ -135,6 +138,7 @@ describe("resolveDiscordAllowlistConfig", () => {
|
||||
},
|
||||
fetcher: vi.fn() as unknown as typeof fetch,
|
||||
runtime,
|
||||
discordConfig: {} as DiscordAccountConfig,
|
||||
});
|
||||
|
||||
const logs = (runtime.log as ReturnType<typeof vi.fn>).mock.calls
|
||||
@@ -146,4 +150,68 @@ describe("resolveDiscordAllowlistConfig", () => {
|
||||
"1456350064065904867/1456744319972282449 (guild:Friends of the Crustacean 🦞🤝; channel:maintainers)",
|
||||
);
|
||||
});
|
||||
|
||||
it("keeps user allowlist names unresolved unless name matching is enabled", async () => {
|
||||
const runtime = createNonExitingRuntimeEnv();
|
||||
const result = await resolveDiscordAllowlistConfig({
|
||||
token: "token",
|
||||
allowFrom: ["Alice", "111", "*"],
|
||||
guildEntries: {
|
||||
"*": {
|
||||
users: ["Bob", "999"],
|
||||
channels: {
|
||||
"*": {
|
||||
users: ["Carol", "888"],
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
fetcher: vi.fn() as unknown as typeof fetch,
|
||||
runtime,
|
||||
discordConfig: {} as DiscordAccountConfig,
|
||||
});
|
||||
|
||||
expect(result.allowFrom).toEqual(["Alice", "111", "*"]);
|
||||
expect(result.guildEntries?.["*"]?.users).toEqual(["Bob", "999"]);
|
||||
expect(result.guildEntries?.["*"]?.channels?.["*"]?.users).toEqual(["Carol", "888"]);
|
||||
expect(resolveUsersModule.resolveDiscordUserAllowlist).not.toHaveBeenCalled();
|
||||
});
|
||||
|
||||
it("still resolves guild and channel ids when name matching is disabled", async () => {
|
||||
vi.spyOn(resolveChannelsModule, "resolveDiscordChannelAllowlist").mockResolvedValueOnce([
|
||||
{
|
||||
input: "ops/general",
|
||||
resolved: true,
|
||||
guildId: "145",
|
||||
guildName: "Ops",
|
||||
channelId: "246",
|
||||
channelName: "general",
|
||||
},
|
||||
]);
|
||||
const runtime = createNonExitingRuntimeEnv();
|
||||
|
||||
const result = await resolveDiscordAllowlistConfig({
|
||||
token: "token",
|
||||
allowFrom: ["Alice"],
|
||||
guildEntries: {
|
||||
ops: {
|
||||
users: ["Bob"],
|
||||
channels: {
|
||||
general: {
|
||||
users: ["Carol"],
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
fetcher: vi.fn() as unknown as typeof fetch,
|
||||
runtime,
|
||||
discordConfig: {} as DiscordAccountConfig,
|
||||
});
|
||||
|
||||
expect(result.allowFrom).toEqual(["Alice"]);
|
||||
expect(result.guildEntries?.["145"]?.channels?.["246"]?.users).toEqual(["Carol"]);
|
||||
expect(result.guildEntries?.ops?.users).toEqual(["Bob"]);
|
||||
expect(resolveChannelsModule.resolveDiscordChannelAllowlist).toHaveBeenCalledTimes(1);
|
||||
expect(resolveUsersModule.resolveDiscordUserAllowlist).not.toHaveBeenCalled();
|
||||
});
|
||||
});
|
||||
|
||||
@@ -5,7 +5,8 @@ import {
|
||||
patchAllowlistUsersInConfigEntries,
|
||||
summarizeMapping,
|
||||
} from "openclaw/plugin-sdk/allow-from";
|
||||
import type { DiscordGuildEntry } from "openclaw/plugin-sdk/config-types";
|
||||
import type { DiscordAccountConfig, DiscordGuildEntry } from "openclaw/plugin-sdk/config-types";
|
||||
import { isDangerousNameMatchingEnabled } from "openclaw/plugin-sdk/dangerous-name-runtime";
|
||||
import type { RuntimeEnv } from "openclaw/plugin-sdk/runtime-env";
|
||||
import { formatErrorMessage } from "openclaw/plugin-sdk/ssrf-runtime";
|
||||
import { normalizeStringEntries } from "openclaw/plugin-sdk/text-runtime";
|
||||
@@ -356,6 +357,7 @@ export async function resolveDiscordAllowlistConfig(params: {
|
||||
token: string;
|
||||
guildEntries: unknown;
|
||||
allowFrom: unknown;
|
||||
discordConfig: DiscordAccountConfig;
|
||||
fetcher: typeof fetch;
|
||||
runtime: RuntimeEnv;
|
||||
}): Promise<{ guildEntries: GuildEntries | undefined; allowFrom: string[] | undefined }> {
|
||||
@@ -371,20 +373,22 @@ export async function resolveDiscordAllowlistConfig(params: {
|
||||
});
|
||||
}
|
||||
|
||||
allowFrom = await resolveAllowFromByUserAllowlist({
|
||||
token: params.token,
|
||||
allowFrom,
|
||||
fetcher: params.fetcher,
|
||||
runtime: params.runtime,
|
||||
});
|
||||
|
||||
if (hasGuildEntries(guildEntries)) {
|
||||
guildEntries = await resolveGuildEntriesByUserAllowlist({
|
||||
if (isDangerousNameMatchingEnabled(params.discordConfig)) {
|
||||
allowFrom = await resolveAllowFromByUserAllowlist({
|
||||
token: params.token,
|
||||
guildEntries,
|
||||
allowFrom,
|
||||
fetcher: params.fetcher,
|
||||
runtime: params.runtime,
|
||||
});
|
||||
|
||||
if (hasGuildEntries(guildEntries)) {
|
||||
guildEntries = await resolveGuildEntriesByUserAllowlist({
|
||||
token: params.token,
|
||||
guildEntries,
|
||||
fetcher: params.fetcher,
|
||||
runtime: params.runtime,
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
return {
|
||||
|
||||
@@ -279,6 +279,7 @@ export async function monitorDiscordProvider(opts: MonitorDiscordOpts = {}) {
|
||||
token,
|
||||
guildEntries,
|
||||
allowFrom,
|
||||
discordConfig: discordCfg,
|
||||
fetcher: discordRestFetch,
|
||||
runtime,
|
||||
});
|
||||
|
||||
Reference in New Issue
Block a user