Skip to content

Commit 1b364c1

Browse files
committed
v1.0.1: Add batch secret management and --no-restart flag
Add secret add-batch/remove-batch commands for bulk operations with a single container restart. Support --no-restart flag on add/remove for scripting. Add TUI menu options [6] and [7].
1 parent 2562f02 commit 1b364c1

2 files changed

Lines changed: 142 additions & 8 deletions

File tree

README.md

Lines changed: 8 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,7 @@
55
One script. Full control. Zero hassle.
66
</p>
77
<p align="center">
8-
<img src="https://img.shields.io/badge/version-1.0.0-brightgreen" alt="Version"/>
8+
<img src="https://img.shields.io/badge/version-1.0.1-brightgreen" alt="Version"/>
99
<img src="https://img.shields.io/badge/license-MIT-blue" alt="License"/>
1010
<img src="https://img.shields.io/badge/engine-Rust_(telemt_3.x)-orange" alt="Engine"/>
1111
<img src="https://img.shields.io/badge/platform-Linux-lightgrey" alt="Platform"/>
@@ -500,6 +500,13 @@ mtproxymax telegram remove # Remove bot completely
500500

501501
## 📋 Changelog
502502

503+
### v1.0.1 — Batch Secret Management
504+
505+
- **Batch Add**`secret add-batch <l1> <l2> ...` adds multiple secrets with a single restart
506+
- **Batch Remove**`secret remove-batch <l1> <l2> ...` removes multiple secrets with a single restart
507+
- **`--no-restart` flag**`secret add/remove --no-restart` for scripting and automation
508+
- **TUI options** — Interactive menu options [6] and [7] for batch operations
509+
503510
### v1.0.0 — Engine v3.3.14
504511

505512
**Engine Upgrade (v3.3.3 → v3.3.14):**

mtproxymax.sh

Lines changed: 134 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -11,7 +11,7 @@ set -eo pipefail
1111
export LC_NUMERIC=C
1212

1313
# ── Section 1: Initialization ────────────────────────────────
14-
VERSION="1.0.0"
14+
VERSION="1.0.1"
1515
SCRIPT_NAME="mtproxymax"
1616
INSTALL_DIR="/opt/mtproxymax"
1717
CONFIG_DIR="${INSTALL_DIR}/mtproxy"
@@ -1278,7 +1278,7 @@ get_user_stats() {
12781278

12791279
# Add a new secret
12801280
secret_add() {
1281-
local label="$1" custom_secret="${2:-}"
1281+
local label="$1" custom_secret="${2:-}" no_restart="${3:-false}"
12821282

12831283
# Validate label
12841284
if [ -z "$label" ]; then
@@ -1330,7 +1330,7 @@ secret_add() {
13301330
save_secrets
13311331

13321332
# Restart if running (run_proxy_container regenerates config)
1333-
if is_proxy_running; then
1333+
if [ "$no_restart" != "true" ] && is_proxy_running; then
13341334
restart_proxy_container
13351335
fi
13361336

@@ -1351,7 +1351,7 @@ secret_add() {
13511351

13521352
# Remove a secret
13531353
secret_remove() {
1354-
local label="$1" force="${2:-false}"
1354+
local label="$1" force="${2:-false}" no_restart="${3:-false}"
13551355

13561356
local idx=-1
13571357
local i
@@ -1411,13 +1411,93 @@ secret_remove() {
14111411

14121412
save_secrets
14131413

1414-
if is_proxy_running; then
1414+
if [ "$no_restart" != "true" ] && is_proxy_running; then
14151415
restart_proxy_container
14161416
fi
14171417

14181418
log_success "Secret '${label}' removed"
14191419
}
14201420

1421+
# Batch add multiple secrets (single restart)
1422+
secret_add_batch() {
1423+
local labels=("$@")
1424+
1425+
if [ ${#labels[@]} -eq 0 ]; then
1426+
log_error "Usage: mtproxymax secret add-batch <label1> <label2> ..."
1427+
return 1
1428+
fi
1429+
1430+
local added=0 failed=0
1431+
for label in "${labels[@]}"; do
1432+
if secret_add "$label" "" "true"; then
1433+
added=$((added + 1))
1434+
else
1435+
failed=$((failed + 1))
1436+
fi
1437+
done
1438+
1439+
# Single restart after all additions
1440+
if [ $added -gt 0 ] && is_proxy_running; then
1441+
restart_proxy_container
1442+
fi
1443+
1444+
echo ""
1445+
log_success "Batch complete: ${added} added, ${failed} failed"
1446+
}
1447+
1448+
# Batch remove multiple secrets (single restart)
1449+
secret_remove_batch() {
1450+
local force="${1:-false}"
1451+
shift 2>/dev/null || true
1452+
local labels=("$@")
1453+
1454+
if [ ${#labels[@]} -eq 0 ]; then
1455+
log_error "Usage: mtproxymax secret remove-batch <label1> <label2> ..."
1456+
return 1
1457+
fi
1458+
1459+
# Count how many of the requested labels actually exist
1460+
local match_count=0
1461+
local l i
1462+
for l in "${labels[@]}"; do
1463+
for i in "${!SECRETS_LABELS[@]}"; do
1464+
[ "${SECRETS_LABELS[$i]}" = "$l" ] && { match_count=$((match_count + 1)); break; }
1465+
done
1466+
done
1467+
1468+
if [ $match_count -ge ${#SECRETS_LABELS[@]} ]; then
1469+
log_error "Cannot remove all secrets — proxy needs at least one"
1470+
return 1
1471+
fi
1472+
1473+
# Confirm unless forced
1474+
if [ "$force" != "true" ] && [ -t 0 ]; then
1475+
echo -e " ${YELLOW}Remove ${#labels[@]} secrets? Users with these keys will be disconnected.${NC}"
1476+
echo -e " ${DIM}Labels: ${labels[*]}${NC}"
1477+
echo -en " ${BOLD}Type 'yes' to confirm:${NC} "
1478+
local confirm
1479+
read -r confirm
1480+
[ "$confirm" != "yes" ] && { log_info "Cancelled"; return 0; }
1481+
fi
1482+
1483+
local removed=0 failed=0
1484+
for l in "${labels[@]}"; do
1485+
if secret_remove "$l" "true" "true"; then
1486+
removed=$((removed + 1))
1487+
else
1488+
failed=$((failed + 1))
1489+
fi
1490+
done
1491+
1492+
# Single restart after all removals
1493+
if [ $removed -gt 0 ] && is_proxy_running; then
1494+
restart_proxy_container
1495+
fi
1496+
1497+
echo ""
1498+
log_success "Batch complete: ${removed} removed, ${failed} failed"
1499+
}
1500+
14211501
# List all secrets
14221502
secret_list() {
14231503
load_secrets
@@ -3906,7 +3986,9 @@ show_cli_help() {
39063986
echo ""
39073987
echo -e " ${BOLD}Secret Management:${NC}"
39083988
echo -e " ${GREEN}secret add${NC} <label> Add a new secret"
3989+
echo -e " ${GREEN}secret add-batch${NC} <l1> <l2> ... Add multiple secrets (single restart)"
39093990
echo -e " ${GREEN}secret remove${NC} <label> Remove a secret"
3991+
echo -e " ${GREEN}secret remove-batch${NC} <l1> <l2> ... Remove multiple secrets (single restart)"
39103992
echo -e " ${GREEN}secret list${NC} List all secrets"
39113993
echo -e " ${GREEN}secret rotate${NC} <label> Rotate a secret"
39123994
echo -e " ${GREEN}secret link${NC} [label] Show proxy link"
@@ -3916,6 +3998,7 @@ show_cli_help() {
39163998
echo -e " ${GREEN}secret limits${NC} [label] Show user limits"
39173999
echo -e " ${GREEN}secret setlimit${NC} <label> conns|ips|quota|expires <value>"
39184000
echo -e " ${GREEN}secret setlimits${NC} <label> <conns> <ips> <quota> [expires]"
4001+
echo -e " ${DIM}Tip: add/remove support --no-restart flag for scripting${NC}"
39194002
echo ""
39204003
echo -e " ${BOLD}Upstream Routing:${NC}"
39214004
echo -e " ${GREEN}upstream list${NC} List upstreams"
@@ -4058,8 +4141,26 @@ cli_main() {
40584141
local subcmd="${1:-list}"
40594142
shift 2>/dev/null || true
40604143
case "$subcmd" in
4061-
add) check_root; secret_add "$1" "${2:-}" ;;
4062-
remove) check_root; secret_remove "$1" ;;
4144+
add)
4145+
check_root
4146+
local _no_restart="false"
4147+
[[ "${*}" == *"--no-restart"* ]] && _no_restart="true"
4148+
local _args=()
4149+
for _a in "$@"; do [[ "$_a" != "--no-restart" ]] && _args+=("$_a"); done
4150+
secret_add "${_args[0]:-}" "${_args[1]:-}" "$_no_restart"
4151+
;;
4152+
add-batch)
4153+
check_root; secret_add_batch "$@" ;;
4154+
remove)
4155+
check_root
4156+
local _no_restart="false"
4157+
[[ "${*}" == *"--no-restart"* ]] && _no_restart="true"
4158+
local _args=()
4159+
for _a in "$@"; do [[ "$_a" != "--no-restart" ]] && _args+=("$_a"); done
4160+
secret_remove "${_args[0]:-}" "false" "$_no_restart"
4161+
;;
4162+
remove-batch)
4163+
check_root; secret_remove_batch "false" "$@" ;;
40634164
list) secret_list ;;
40644165
rotate) check_root; secret_rotate "$1" ;;
40654166
link) get_proxy_link_https "${1:-}"; echo "" ;;
@@ -4726,6 +4827,8 @@ show_secrets_menu() {
47264827
echo -e " ${DIM}[3]${NC} Rotate a secret"
47274828
echo -e " ${DIM}[4]${NC} Enable/disable a secret"
47284829
echo -e " ${DIM}[5]${NC} Set user limits"
4830+
echo -e " ${DIM}[6]${NC} Batch add secrets"
4831+
echo -e " ${DIM}[7]${NC} Batch remove secrets"
47294832
echo -e " ${DIM}[0]${NC} Back"
47304833

47314834
local choice
@@ -4778,6 +4881,28 @@ show_secrets_menu() {
47784881
fi
47794882
press_any_key
47804883
;;
4884+
6)
4885+
echo -e " ${DIM}Enter labels separated by spaces${NC}"
4886+
echo -en " ${BOLD}Labels:${NC} "
4887+
local batch_labels
4888+
read -r batch_labels
4889+
if [ -n "$batch_labels" ]; then
4890+
# shellcheck disable=SC2086
4891+
secret_add_batch $batch_labels || true
4892+
fi
4893+
press_any_key
4894+
;;
4895+
7)
4896+
echo -e " ${DIM}Enter labels separated by spaces${NC}"
4897+
echo -en " ${BOLD}Labels to remove:${NC} "
4898+
local batch_labels
4899+
read -r batch_labels
4900+
if [ -n "$batch_labels" ]; then
4901+
# shellcheck disable=SC2086
4902+
secret_remove_batch "false" $batch_labels || true
4903+
fi
4904+
press_any_key
4905+
;;
47814906
0|"") return ;;
47824907
*) ;;
47834908
esac
@@ -5239,7 +5364,9 @@ show_info_multisecret() {
52395364
echo ""
52405365
echo -e " ${BOLD}Commands:${NC}"
52415366
echo -e " ${GREEN}mtproxymax secret add <label>${NC} Create a new secret"
5367+
echo -e " ${GREEN}mtproxymax secret add-batch <l1> <l2> ...${NC} Add multiple (single restart)"
52425368
echo -e " ${GREEN}mtproxymax secret remove <label>${NC} Delete a secret"
5369+
echo -e " ${GREEN}mtproxymax secret remove-batch <l1> <l2> ...${NC} Remove multiple (single restart)"
52435370
echo -e " ${GREEN}mtproxymax secret rotate <label>${NC} Replace key, keep label"
52445371
echo -e " ${GREEN}mtproxymax secret enable <label>${NC} Re-enable a disabled secret"
52455372
echo -e " ${GREEN}mtproxymax secret disable <label>${NC} Temporarily disable access"

0 commit comments

Comments
 (0)