WIP, I will provide screenshots after I finish all the tests and improvements
No way to inspect or manage users from the bot without typing commands
Type: enhancement
Area: Telegram bot
Addressed by: PR 3 of 4 (feat(telegram): interactive inline-keyboard menus)
Summary
The bot is entirely text-driven. Every action requires typing a command with
hand-supplied arguments, and there is no way to browse — you cannot see a list
of users and then act on one; you have to know the label, remember the command
and type both correctly.
There are currently zero inline keyboards in the codebase (reply_markup,
callback_query and answerCallbackQuery do not appear anywhere).
Impact
- Managing users from a phone keyboard is error-prone.
/mp_setlimit alice 5 2 10G
is a lot of typing on mobile, and a typo silently targets the wrong thing or
fails.
- Discovery requires memorisation. To disable a user you must already know
that /mp_disable <label> exists and what the label is. /mp_secrets prints
labels, but they must then be retyped by hand.
- Per-user state is scattered. Live connections come from
/mp_secrets,
quota and expiry from /mp_limits, traffic from /mp_traffic — three commands
to answer "how is alice doing?", and none of them shows all of it at once.
Proposal
Add inline keyboards so the common operations are reachable by tapping:
- A hub with buttons for the main views.
- A paginated user list — tap a user to open their card.
- A per-user card showing status, live connections, unique IPs, quota bar,
expiry countdown and traffic, with actions attached.
- A confirmation step before anything destructive.
- Button bars on existing replies (
/start, /mp_status, /mp_secrets,
/mp_traffic, /mp_help) so the views are reachable without typing.
Security requirements (important)
callback_data is entirely attacker-controlled — any user can send any payload
from any client. Therefore:
- Every tap must be re-authorised against the same rules
_process_cmd
applies. A button must never grant more than typing the equivalent command
would.
- Public actions run before any role check, exactly as public commands do.
- An unauthenticated chatter is answered but ignored silently (no edit, no
audit entry), mirroring the existing role == none behaviour.
- A recognised-but-underprivileged role is refused loudly, with a
SECURITY
line in audit.log.
- An unrecognised role string must fail closed to public-only.
admins.conf
is a plain file an operator can edit, so anything that is not exactly
superadmin or reseller must never exceed public.
- No chat id may travel in
callback_data — identity must come from
callback_query.message.chat.id, which Telegram authenticates. A chat id in
the payload would be an attacker-controlled privilege token.
- The payload must be treated as data, never a command, and the target
re-validated against secrets.conf before anything runs.
- Every tap must be acknowledged (
answerCallbackQuery) on every path,
including denial and error, or the client spinner hangs forever.
Destructive actions
⏸ Disable, ♻️ Rotate and 🗑 Remove must require an explicit second tap on a
confirmation button. Nothing destructive should be one mis-tap away.
Acceptance criteria
WIP, I will provide screenshots after I finish all the tests and improvements
No way to inspect or manage users from the bot without typing commands
Type: enhancement
Area: Telegram bot
Addressed by: PR 3 of 4 (
feat(telegram): interactive inline-keyboard menus)Summary
The bot is entirely text-driven. Every action requires typing a command with
hand-supplied arguments, and there is no way to browse — you cannot see a list
of users and then act on one; you have to know the label, remember the command
and type both correctly.
There are currently zero inline keyboards in the codebase (
reply_markup,callback_queryandanswerCallbackQuerydo not appear anywhere).Impact
/mp_setlimit alice 5 2 10Gis a lot of typing on mobile, and a typo silently targets the wrong thing or
fails.
that
/mp_disable <label>exists and what the label is./mp_secretsprintslabels, but they must then be retyped by hand.
/mp_secrets,quota and expiry from
/mp_limits, traffic from/mp_traffic— three commandsto answer "how is alice doing?", and none of them shows all of it at once.
Proposal
Add inline keyboards so the common operations are reachable by tapping:
expiry countdown and traffic, with actions attached.
/start,/mp_status,/mp_secrets,/mp_traffic,/mp_help) so the views are reachable without typing.Security requirements (important)
callback_datais entirely attacker-controlled — any user can send any payloadfrom any client. Therefore:
_process_cmdapplies. A button must never grant more than typing the equivalent command
would.
audit entry), mirroring the existing
role == nonebehaviour.SECURITYline in
audit.log.admins.confis a plain file an operator can edit, so anything that is not exactly
superadminorresellermust never exceed public.callback_data— identity must come fromcallback_query.message.chat.id, which Telegram authenticates. A chat id inthe payload would be an attacker-controlled privilege token.
re-validated against
secrets.confbefore anything runs.answerCallbackQuery) on every path,including denial and error, or the client spinner hangs forever.
Destructive actions
⏸ Disable,♻️ Rotateand🗑 Removemust require an explicit second tap on aconfirmation button. Nothing destructive should be one mis-tap away.
Acceptance criteria
/hub buttons opens the corresponding view in place.callback_datafrom a reseller is refused and audited.first tap.
callback_datastays within Telegram's 64-byte limit.