refactor(commands): unify repeated ACP and routing flows

This commit is contained in:
Peter Steinberger
2026-03-02 05:19:47 +00:00
parent 2d31126e6a
commit 6b78544f82
12 changed files with 333 additions and 442 deletions

View File

@@ -19,6 +19,26 @@ export type TelegramGroupBaseAccessResult =
| { allowed: true }
| { allowed: false; reason: TelegramGroupBaseBlockReason };
function isGroupAllowOverrideAuthorized(params: {
effectiveGroupAllow: NormalizedAllowFrom;
senderId?: string;
senderUsername?: string;
requireSenderForAllowOverride: boolean;
}): boolean {
if (!params.effectiveGroupAllow.hasEntries) {
return false;
}
const senderId = params.senderId ?? "";
if (params.requireSenderForAllowOverride && !senderId) {
return false;
}
return isSenderAllowed({
allow: params.effectiveGroupAllow,
senderId,
senderUsername: params.senderUsername ?? "",
});
}
export const evaluateTelegramGroupBaseAccess = (params: {
isGroup: boolean;
groupConfig?: TelegramGroupConfig | TelegramDirectConfig;
@@ -40,19 +60,14 @@ export const evaluateTelegramGroupBaseAccess = (params: {
if (!params.isGroup) {
// For DMs, check allowFrom override if present
if (params.enforceAllowOverride && params.hasGroupAllowOverride) {
if (!params.effectiveGroupAllow.hasEntries) {
return { allowed: false, reason: "group-override-unauthorized" };
}
const senderId = params.senderId ?? "";
if (params.requireSenderForAllowOverride && !senderId) {
return { allowed: false, reason: "group-override-unauthorized" };
}
const allowed = isSenderAllowed({
allow: params.effectiveGroupAllow,
senderId,
senderUsername: params.senderUsername ?? "",
});
if (!allowed) {
if (
!isGroupAllowOverrideAuthorized({
effectiveGroupAllow: params.effectiveGroupAllow,
senderId: params.senderId,
senderUsername: params.senderUsername,
requireSenderForAllowOverride: params.requireSenderForAllowOverride,
})
) {
return { allowed: false, reason: "group-override-unauthorized" };
}
}
@@ -62,22 +77,14 @@ export const evaluateTelegramGroupBaseAccess = (params: {
return { allowed: true };
}
// Explicit per-group/topic allowFrom override must fail closed when empty.
if (!params.effectiveGroupAllow.hasEntries) {
return { allowed: false, reason: "group-override-unauthorized" };
}
const senderId = params.senderId ?? "";
if (params.requireSenderForAllowOverride && !senderId) {
return { allowed: false, reason: "group-override-unauthorized" };
}
const allowed = isSenderAllowed({
allow: params.effectiveGroupAllow,
senderId,
senderUsername: params.senderUsername ?? "",
});
if (!allowed) {
if (
!isGroupAllowOverrideAuthorized({
effectiveGroupAllow: params.effectiveGroupAllow,
senderId: params.senderId,
senderUsername: params.senderUsername,
requireSenderForAllowOverride: params.requireSenderForAllowOverride,
})
) {
return { allowed: false, reason: "group-override-unauthorized" };
}
return { allowed: true };

View File

@@ -171,6 +171,17 @@ export function createLaneTextDeliverer(params: CreateLaneTextDelivererParams) {
previewMessageId: previewMessageIdOverride,
previewTextSnapshot,
}: TryUpdatePreviewParams): Promise<boolean> => {
const editPreview = (messageId: number, treatEditFailureAsDelivered: boolean) =>
tryEditPreviewMessage({
laneName,
messageId,
text,
context,
previewButtons,
updateLaneSnapshot,
lane,
treatEditFailureAsDelivered,
});
if (!lane.stream) {
return false;
}
@@ -198,16 +209,7 @@ export function createLaneTextDeliverer(params: CreateLaneTextDelivererParams) {
params.markDelivered();
return true;
}
return tryEditPreviewMessage({
laneName,
messageId: previewMessageId,
text,
context,
previewButtons,
updateLaneSnapshot,
lane,
treatEditFailureAsDelivered: true,
});
return editPreview(previewMessageId, true);
}
if (stopBeforeEdit) {
await params.stopDraftLane(lane);
@@ -230,16 +232,7 @@ export function createLaneTextDeliverer(params: CreateLaneTextDelivererParams) {
params.markDelivered();
return true;
}
return tryEditPreviewMessage({
laneName,
messageId: previewMessageId,
text,
context,
previewButtons,
updateLaneSnapshot,
lane,
treatEditFailureAsDelivered: false,
});
return editPreview(previewMessageId, false);
};
const consumeArchivedAnswerPreviewForFinal = async ({