From 690d3ff7244a8295b6f53e390981cb28c1bd6b77 Mon Sep 17 00:00:00 2001 From: rayz1065 Date: Wed, 6 Aug 2025 19:35:13 +0200 Subject: [PATCH 1/2] Allow anonymous admins to use admin scoped commands --- src/utils/checks.ts | 13 +++++++++++-- test/command.test.ts | 39 +++++++++++++++++++++++++++++++++++++++ 2 files changed, 50 insertions(+), 2 deletions(-) diff --git a/src/utils/checks.ts b/src/utils/checks.ts index d6ed870..cb63c1c 100644 --- a/src/utils/checks.ts +++ b/src/utils/checks.ts @@ -1,8 +1,17 @@ -import { Composer, Context, Middleware } from "../deps.deno.ts"; +import { + ChatTypeContext, + Composer, + Context, + Middleware, +} from "../deps.deno.ts"; import { CommandOptions } from "../types.ts"; import { MaybeArray } from "./array.ts"; -export function isAdmin(ctx: Context) { +export function isAdmin(ctx: ChatTypeContext) { + if (ctx.senderChat?.id === ctx.chat.id) { + // anonymous admin + return true; + } return ctx .getAuthor() .then((author) => ["administrator", "creator"].includes(author.status)); diff --git a/test/command.test.ts b/test/command.test.ts index 162e85c..8c7be58 100644 --- a/test/command.test.ts +++ b/test/command.test.ts @@ -932,6 +932,19 @@ describe("Command", () => { assertSpyCalls(chatAdministratorsSpy, 1); }); + it("should call chatAdministrators for anonymous admin", async () => { + chatMember = { status: "member" } as ChatMember; // unused + + assertSpyCalls(chatAdministratorsSpy, 1); + await mw(makeContext({ + chat: { id: -123, type: "group" }, + from: { id: 789 }, + sender_chat: { id: -123, type: "group" }, + text: "/a", + } as Message)); + assertSpyCalls(chatAdministratorsSpy, 2); + }); + it("should call chat", async () => { assertSpyCalls(chatSpy, 0); await mw(makeContext({ @@ -964,6 +977,19 @@ describe("Command", () => { assertSpyCalls(allChatAdministratorsSpy, 1); }); + it("should call allChatAdministrators for anonymous admin", async () => { + chatMember = { status: "administrator" } as ChatMember; // unused + + assertSpyCalls(allChatAdministratorsSpy, 1); + await mw(makeContext({ + chat: { id: -124, type: "group" }, + from: { id: 789 }, + sender_chat: { id: -124, type: "group" }, + text: "/a", + } as Message)); + assertSpyCalls(allChatAdministratorsSpy, 2); + }); + it("should call allGroupChats", async () => { chatMember = { status: "member" } as ChatMember; @@ -995,5 +1021,18 @@ describe("Command", () => { } as Message)); assertSpyCalls(defaultSpy, 1); }); + + it("should call group on sender_chat", async () => { + chatMember = { status: "member" } as ChatMember; + + assertSpyCalls(allGroupChatsSpy, 1); + await mw(makeContext({ + chat: { id: -124, type: "group" }, + from: { id: 789 }, + sender_chat: { id: -123, type: "channel" }, + text: "/a", + } as Message)); + assertSpyCalls(allGroupChatsSpy, 2); + }); }); }); From 74d955bd4c83780b381cc7245dae8c4272b13321 Mon Sep 17 00:00:00 2001 From: rayz <37779815+rayz1065@users.noreply.github.com> Date: Wed, 13 Aug 2025 13:19:32 +0000 Subject: [PATCH 2/2] Apply suggestions from code review Remove `from` field when `sender_chat` is specified in test Co-authored-by: Hero Protagonist --- test/command.test.ts | 2 -- 1 file changed, 2 deletions(-) diff --git a/test/command.test.ts b/test/command.test.ts index 8c7be58..4abd002 100644 --- a/test/command.test.ts +++ b/test/command.test.ts @@ -938,7 +938,6 @@ describe("Command", () => { assertSpyCalls(chatAdministratorsSpy, 1); await mw(makeContext({ chat: { id: -123, type: "group" }, - from: { id: 789 }, sender_chat: { id: -123, type: "group" }, text: "/a", } as Message)); @@ -983,7 +982,6 @@ describe("Command", () => { assertSpyCalls(allChatAdministratorsSpy, 1); await mw(makeContext({ chat: { id: -124, type: "group" }, - from: { id: 789 }, sender_chat: { id: -124, type: "group" }, text: "/a", } as Message));