Skip to content

Chore: log wrong-user captcha clicks to diagnose missing alert - #48

Merged
rezhajulio merged 4 commits into
rezhajulio:mainfrom
TayoBus:fix/captcha-wrong-user-log
Oct 8, 2026
Merged

rezhajulio merged 4 commits into
rezhajulio:mainfrom
TayoBus:fix/captcha-wrong-user-log

Conversation

@TayoBus

@TayoBus TayoBus commented Oct 8, 2026

Copy link
Copy Markdown
Contributor

Context

Reported: in the PTB build, clicking someone else's captcha button showed the "Tombol ini bukan untukmu" alert; in the current build nothing appears.

Investigation (no code bug found)

The wrong-user path was verified correct at every level before writing this:

  • captcha_callback_handler: callback_user_id != target_user_id → await query.answer(CAPTCHA_WRONG_USER_MESSAGE, show_alert=True) — unit-tested with a mocked query, the answer call fires with the right args.
  • Dispatch: only the captcha plugin's captcha_callback spec matches captcha_verify_… data — no other handler can swallow or double-answer the query.
  • API serialization: end-to-end check against a real aiogram 3.31 Bot confirms the emitted AnswerCallbackQuery carries the right callback_query_id, text, and show_alert=True.
  • Production: dispatch logs show captcha_callback matched and completed; no stale deaf instance is stealing updates (zero "not handled" since the 18:11 deploy); the PTB code for this path is byte-identical.

This PR

Adds logging to the wrong-user branch (clicker id, target id, group id) plus Telegram's answer() result, so the next occurrence leaves a definitive trace in Logfire distinguishing "branch not hit" from "answer rejected".

To verify after merge + deploy

Have a second account click an active captcha button; then check Logfire for captcha: user … clicked captcha button and the not-for-you alert answered= line.

/status (DM-only admin): render the operational summary as a native
rich message — per-group <table bordered striped> (Grup | Penegakan |
Captcha | Probation | Pending | Nonaktif, scoped to the caller's admin
groups) plus a key-value section (Uptime, Database, Refresh admin,
Auto-restrict). Any send_rich_message failure falls back to the
byte-identical Markdown message (verified empirically against the
pre-change output).

/trusted: drop the standalone User ID column — four columns forced
horizontal scrolling. The numeric ID is folded into the User cell as
name (@username)<br><code>id</code>, keeping it visible and copyable.
Markdown fallback untouched.

Dates: the /trusted Date column and the /status job timestamps now
render in WIB (Asia/Jakarta) instead of UTC, in both the rich output
and the Markdown fallback (shared display strings; new constants.WIB
single source of truth).

/check deliberately stays on Markdown: aiogram 3.31 has no
edit-to-rich equivalent, so its callback-query edit path could never
go rich and a rich-then-Markdown flip mid-flow would be worse than
consistent Markdown.
…operty

test_with_username_format asserts '(@' appears only via the username
suffix, but the name strategy allows punctuation, so Hypothesis can
generate name='(@' and fail the property through no fault of the code.
assume('(@' not in name) keeps the property's intent (username suffix
logic) while excluding the degenerate input. Pre-existing flake,
unrelated to the rich-text work.
The dm plugin registers before status in group 0, and its check
(private + text) matched /status DMs first, so handle_dm answered
with the unrestriction message and handle_status never ran
(first-match-wins).

The DM flow now owns free-text DMs and /start deep links only: its
check excludes any bot_command that isn't /start. /status (and any
future command registered after dm) falls through to its handler.
Diagnostic logging for the reported missing 'tombol ini bukan untukmu'
alert: the wrong-user branch is reachable and query.answer() is invoked
with show_alert=True (verified by unit test + API serialization check),
so log the click (clicker, target, group) and Telegram's answer result
to get a definitive production trace on the next occurrence.
@rezhajulio
rezhajulio merged commit b40510a into rezhajulio:main Oct 8, 2026
6 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants