mirror of
https://github.com/moltbot/moltbot.git
synced 2026-03-29 16:54:30 +00:00
fix(mattermost): align slash allowlist normalization + register callbackUrl pathname
- normalizeAllowList/isSenderAllowed in slash-http.ts now matches the websocket monitor: strips mattermost:/user:/@ prefixes and supports the '*' wildcard, so configs that work for WS also work for slash cmds - registerSlashCommandRoute extracts pathname from explicit callbackUrl and registers it alongside callbackPath, so callbacks hit a registered route even when callbackUrl uses a non-default pathname Addresses Codex review round 5 (P1 + P2).
This commit is contained in:
committed by
Muhammed Mukhthar CM
parent
d486f208a2
commit
81087ecb6b
@@ -70,11 +70,26 @@ function sendJsonResponse(
|
||||
res.end(JSON.stringify(body));
|
||||
}
|
||||
|
||||
/**
|
||||
* Normalize a single allowlist entry, matching the websocket monitor behaviour.
|
||||
* Strips `mattermost:`, `user:`, and `@` prefixes, and preserves the `*` wildcard.
|
||||
*/
|
||||
function normalizeAllowEntry(entry: string): string {
|
||||
const trimmed = entry.trim();
|
||||
if (!trimmed) {
|
||||
return "";
|
||||
}
|
||||
if (trimmed === "*") {
|
||||
return "*";
|
||||
}
|
||||
return trimmed
|
||||
.replace(/^(mattermost|user):/i, "")
|
||||
.replace(/^@/, "")
|
||||
.toLowerCase();
|
||||
}
|
||||
|
||||
function normalizeAllowList(entries: Array<string | number>): string[] {
|
||||
const normalized = entries
|
||||
.map((entry) => String(entry).trim())
|
||||
.filter(Boolean)
|
||||
.map((entry) => entry.toLowerCase());
|
||||
const normalized = entries.map((entry) => normalizeAllowEntry(String(entry))).filter(Boolean);
|
||||
return Array.from(new Set(normalized));
|
||||
}
|
||||
|
||||
@@ -83,12 +98,16 @@ function isSenderAllowed(params: { senderId: string; senderName: string; allowFr
|
||||
if (allowFrom.length === 0) {
|
||||
return false;
|
||||
}
|
||||
if (allowFrom.includes("*")) {
|
||||
return true;
|
||||
}
|
||||
|
||||
const allowed = new Set(allowFrom.map((v) => v.toLowerCase()));
|
||||
const id = senderId.trim().toLowerCase();
|
||||
const name = senderName.trim().toLowerCase();
|
||||
const normalizedId = normalizeAllowEntry(senderId);
|
||||
const normalizedName = senderName ? normalizeAllowEntry(senderName) : "";
|
||||
|
||||
return allowed.has(id) || allowed.has(name);
|
||||
return allowFrom.some(
|
||||
(entry) => entry === normalizedId || (normalizedName && entry === normalizedName),
|
||||
);
|
||||
}
|
||||
|
||||
type SlashInvocationAuth = {
|
||||
|
||||
@@ -120,12 +120,31 @@ export function registerSlashCommandRoute(api: OpenClawPluginApi) {
|
||||
// Collect callback paths from both top-level and per-account config.
|
||||
// Command registration uses account.config.commands, so the HTTP route
|
||||
// registration must include any account-specific callbackPath overrides.
|
||||
// Also extract the pathname from an explicit callbackUrl when it differs
|
||||
// from callbackPath, so that Mattermost callbacks hit a registered route.
|
||||
const callbackPaths = new Set<string>();
|
||||
|
||||
const addCallbackPaths = (
|
||||
raw: Partial<import("./slash-commands.js").MattermostSlashCommandConfig> | undefined,
|
||||
) => {
|
||||
const resolved = resolveSlashCommandConfig(raw);
|
||||
callbackPaths.add(resolved.callbackPath);
|
||||
if (resolved.callbackUrl) {
|
||||
try {
|
||||
const urlPath = new URL(resolved.callbackUrl).pathname;
|
||||
if (urlPath && urlPath !== resolved.callbackPath) {
|
||||
callbackPaths.add(urlPath);
|
||||
}
|
||||
} catch {
|
||||
// Invalid URL — ignore, will be caught during registration
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
const commandsRaw = mmConfig?.commands as
|
||||
| Partial<import("./slash-commands.js").MattermostSlashCommandConfig>
|
||||
| undefined;
|
||||
callbackPaths.add(resolveSlashCommandConfig(commandsRaw).callbackPath);
|
||||
addCallbackPaths(commandsRaw);
|
||||
|
||||
const accountsRaw = (mmConfig?.accounts ?? {}) as Record<string, unknown>;
|
||||
for (const accountId of Object.keys(accountsRaw)) {
|
||||
@@ -133,7 +152,7 @@ export function registerSlashCommandRoute(api: OpenClawPluginApi) {
|
||||
const accountCommandsRaw = accountCfg?.commands as
|
||||
| Partial<import("./slash-commands.js").MattermostSlashCommandConfig>
|
||||
| undefined;
|
||||
callbackPaths.add(resolveSlashCommandConfig(accountCommandsRaw).callbackPath);
|
||||
addCallbackPaths(accountCommandsRaw);
|
||||
}
|
||||
|
||||
const routeHandler = async (req: IncomingMessage, res: ServerResponse) => {
|
||||
|
||||
Reference in New Issue
Block a user