refactor: add approval auth capabilities to more channels

This commit is contained in:
Peter Steinberger
2026-03-30 09:03:41 +09:00
parent 63cbc097b5
commit c2cbdea28c
37 changed files with 697 additions and 0 deletions

View File

@@ -0,0 +1,24 @@
import { describe, expect, it } from "vitest";
import { googleChatApprovalAuth } from "./approval-auth.js";
describe("googleChatApprovalAuth", () => {
it("authorizes stable users/* ids and ignores email-style approvers", () => {
expect(
googleChatApprovalAuth.authorizeActorAction({
cfg: { channels: { googlechat: { dm: { allowFrom: ["users/123"] } } } },
senderId: "users/123",
action: "approve",
approvalKind: "exec",
}),
).toEqual({ authorized: true });
expect(
googleChatApprovalAuth.authorizeActorAction({
cfg: { channels: { googlechat: { dm: { allowFrom: ["owner@example.com"] } } } },
senderId: "users/attacker",
action: "approve",
approvalKind: "exec",
}),
).toEqual({ authorized: true });
});
});

View File

@@ -0,0 +1,31 @@
import {
createResolvedApproverActionAuthAdapter,
resolveApprovalApprovers,
} from "openclaw/plugin-sdk/approval-runtime";
import { resolveGoogleChatAccount } from "./accounts.js";
import { isGoogleChatUserTarget, normalizeGoogleChatTarget } from "./targets.js";
function normalizeGoogleChatApproverId(value: string | number): string | undefined {
const normalized = normalizeGoogleChatTarget(String(value));
if (!normalized || !isGoogleChatUserTarget(normalized)) {
return undefined;
}
const suffix = normalized.slice("users/".length).trim().toLowerCase();
if (!suffix || suffix.includes("@")) {
return undefined;
}
return `users/${suffix}`;
}
export const googleChatApprovalAuth = createResolvedApproverActionAuthAdapter({
channelLabel: "Google Chat",
resolveApprovers: ({ cfg, accountId }) => {
const account = resolveGoogleChatAccount({ cfg, accountId }).config;
return resolveApprovalApprovers({
allowFrom: account.dm?.allowFrom,
defaultTo: account.defaultTo,
normalizeApprover: normalizeGoogleChatApproverId,
});
},
normalizeSenderId: (value) => normalizeGoogleChatApproverId(value),
});

View File

@@ -46,6 +46,7 @@ import {
type ResolvedGoogleChatAccount,
} from "./accounts.js";
import { googlechatMessageActions } from "./actions.js";
import { googleChatApprovalAuth } from "./approval-auth.js";
import { resolveGoogleChatGroupRequireMention } from "./group-policy.js";
import { getGoogleChatRuntime } from "./runtime.js";
import { googlechatSetupAdapter } from "./setup-core.js";
@@ -163,6 +164,7 @@ export const googlechatPlugin = createChatChannelPlugin({
},
}),
},
auth: googleChatApprovalAuth,
groups: {
resolveRequireMention: resolveGoogleChatGroupRequireMention,
},