From 1f0a1f14fe5baabffab258dd505cae2c34ff7d6c Mon Sep 17 00:00:00 2001 From: rmtshnik Date: Wed, 28 Oct 2026 11:45:06 +0300 Subject: [PATCH 1/2] fix: preserve global Telegram confirmation callback targets --- README.md | 6 +++++ mtproxymax.sh | 9 +++++-- tests/test_telegram_callback_dispatch.sh | 31 ++++++++++++++++++++++++ 3 files changed, 44 insertions(+), 2 deletions(-) diff --git a/README.md b/README.md index 9659f7e..d84cbfb 100644 --- a/README.md +++ b/README.md @@ -496,6 +496,12 @@ The bot records rolling traffic samples under uses them for the analytics view and the periodic report. Samples are stored as **deltas**, so an engine restart or a traffic reset cannot corrupt a window. +History is separate from cumulative traffic totals: recording starts when the +history sampler is enabled and cannot reconstruct earlier daily usage from a +total. If all available samples are less than 24 hours old, the 24-hour, 7-day, +and 30-day windows can show the same traffic. A full 30-day window requires +`TELEGRAM_HISTORY_RETENTION_DAYS=30` (or higher) and 30 days of collected samples. + ```bash mtproxymax telegram history status # sample counts, date range, retention mtproxymax telegram history prune # apply retention now diff --git a/mtproxymax.sh b/mtproxymax.sh index aa6d31c..90b8c6b 100644 --- a/mtproxymax.sh +++ b/mtproxymax.sh @@ -14243,11 +14243,16 @@ _cb_render_confirm() { *) _CB_TOAST="Unknown action"; return 1 ;; esac + local callback_target="$label" cancel_data="u:s:${label}:${page}" # The global verbs are targetless. "_" is their placeholder, and it is # matched here rather than treated as a label so that a secret genuinely # named "_" is still a secret for enable/disable/rotate/remove. case "$verb" in - rotall|restart|update|lockdown) label="" ;; + rotall|restart|update|lockdown) + label="" + callback_target="${callback_target:-_}" + cancel_data="g" + ;; esac [ -n "$label" ] && ! _cb_secret_exists "$label" && { _CB_TOAST="Secret '$label' not found"; return 1; } @@ -14269,7 +14274,7 @@ _cb_render_confirm() { esac local _msg="⚠️ *${pretty} $(_esc "$label")?*${_extra}" _kb_reset - _kb_row "✅ Yes, ${pretty,,}|c:${verb}:${label}" "❌ Cancel|u:s:${label}:${page}" + _kb_row "✅ Yes, ${pretty,,}|c:${verb}:${callback_target}" "❌ Cancel|${cancel_data}" _cb_edit "$_msg" "$(_kb_json)" } diff --git a/tests/test_telegram_callback_dispatch.sh b/tests/test_telegram_callback_dispatch.sh index 521ed63..5286eae 100644 --- a/tests/test_telegram_callback_dispatch.sh +++ b/tests/test_telegram_callback_dispatch.sh @@ -274,5 +274,36 @@ assert_eq "capability table matches _process_cmd's gates" "" "$(cap_leaks)" assert_contains "capability table covers a:disable" "a:disable=admin" "$TG_CB_CAPS" assert_contains "capability table covers c:remove" "c:remove=superadmin" "$TG_CB_CAPS" +# Exercise the payload actually emitted by each global confirmation rather +# than constructing a valid c: payload by hand. Empty fields fail _cb_dec. +for _spec in restart:_ update:_ rotall:_ lockdown:on lockdown:off; do + _verb="${_spec%%:*}"; _target="${_spec#*:}" + run_cb superadmin 111 "a:${_spec}" + assert_eq "global prompt ${_spec} does not execute" "" "$(cat "$CALLS")" + _confirm=$(sed -n 's/.*"callback_data":"\(c:[^"]*\)".*/\1/p' "$EDITS") + assert_eq "global prompt preserves target ${_spec}" "c:${_spec}" "$_confirm" + _cb_dec "$_confirm" + assert_eq "global confirmation ${_spec} decodes" 0 "$?" + assert_contains "global cancel returns to tools ${_spec}" '"callback_data":"g"' "$(cat "$EDITS")" + + case "$_verb" in + restart) _expected="restart" ;; + update) _expected="update" ;; + rotall) _expected="secret rotate --all" ;; + lockdown) _expected="lockdown ${_target}" ;; + esac + run_cb superadmin 111 "$_confirm" + assert_eq "rendered global confirmation executes ${_spec}" "$_expected" "$(cat "$CALLS")" + assert_eq "rendered global confirmation answered once ${_spec}" 1 "$(wc -l < "$ANSWERS" | tr -d ' ')" + + run_cb reseller 333 "$_confirm" + assert_eq "rendered global confirmation denies reseller ${_spec}" "" "$(cat "$CALLS")" + assert_contains "global denial is visible ${_spec}" "Permission denied" "$(cat "$ANSWERS")" + + run_cb superadmin 111 "g" + assert_eq "global cancel does not execute ${_spec}" "" "$(cat "$CALLS")" + assert_eq "global cancel renders tools ${_spec}" 1 "$(wc -l < "$EDITS" | tr -d ' ')" +done + printf '\n%d tests, %d failures\n' "$TESTS_RUN" "$TESTS_FAILED" [ "$TESTS_FAILED" -eq 0 ] From c7a7738e92998bc22ed49b729535603d806680d1 Mon Sep 17 00:00:00 2001 From: rmtshnik Date: Wed, 28 Oct 2026 11:46:15 +0300 Subject: [PATCH 2/2] test: count rendered messages independently of text lines --- tests/test_telegram_callback_dispatch.sh | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/tests/test_telegram_callback_dispatch.sh b/tests/test_telegram_callback_dispatch.sh index 5286eae..81d00d9 100644 --- a/tests/test_telegram_callback_dispatch.sh +++ b/tests/test_telegram_callback_dispatch.sh @@ -302,7 +302,7 @@ for _spec in restart:_ update:_ rotall:_ lockdown:on lockdown:off; do run_cb superadmin 111 "g" assert_eq "global cancel does not execute ${_spec}" "" "$(cat "$CALLS")" - assert_eq "global cancel renders tools ${_spec}" 1 "$(wc -l < "$EDITS" | tr -d ' ')" + assert_eq "global cancel renders tools ${_spec}" 1 "$(grep -c '^edit|' "$EDITS")" done printf '\n%d tests, %d failures\n' "$TESTS_RUN" "$TESTS_FAILED"