Категория: ux · Приоритет: low · Размер: S · Ранг: 9/10
Что построить
Меню действий «…» в строке пользователя с пунктами «Сбросить ссылку подписки» (ротация subId → старая ссылка перестаёт работать) и «Копировать ссылку».
Паритет с конкурентами
Marzban/Marzneshin (revoke/rotate subscription), 3x-ui (per-user share + reset), Remnawave (user.revoked event), Hiddify (short-link revoke). Отзыв/ротация токена — стандартное действие.
Чего не хватает сейчас (код)
Токен подписки = усечённый HMAC(secret, subId) (token.Make в users_get/handler.go:77), то есть детерминирован от subId — отозвать утёкшую ссылку нельзя без смены subId, а смены subId нет. В строке только одна кнопка «Mihomo» (copy(u.sub.url), index.html:80), нет ротации и компактного меню действий.
Зачем
Оператор мгновенно гасит утёкшую ссылку, не пересоздавая пользователя, и удобно делится новой. Сегодня subgen не умеет инвалидировать подписку: HMAC от subId неизменен, subId не ротируется — утёкшая ссылка живёт вечно.
Предлагаемая реализация
Сервисный метод provisioning.RotateSubID: минтит новый subId (как при создании), ре-байндит клиента на всех панелях с тем же uuid, но новым subId (AddClient уже принимает subId), обновляет users.sub_id. Ручка user_rotate_sub (openapi → ogen), тонкий хендлер. Во Vue — dropdown-меню действий в строке (Bootstrap уже вендорён), пункты дергают POST и copy().
Затронутые файлы
internal/service/provisioning/service.go (RotateSubID), internal/repository/users/ (UpdateSubID)
openapi/user_rotate_sub.yaml (новый) + openapi.yaml, internal/handlers/user_rotate_sub/
internal/handlers/web/static/{app.js,index.html}
Продуктовый ресёрч: изучены аналоги (Marzban/Marzneshin, 3x-ui, Remnawave, Hiddify, sub-store + клиентские стандарты импорта). Паритет и subgen-gap код-обоснованы. Ранг = продуктовый приоритет.
Категория: ux · Приоритет: low · Размер: S · Ранг: 9/10
Что построить
Меню действий «…» в строке пользователя с пунктами «Сбросить ссылку подписки» (ротация subId → старая ссылка перестаёт работать) и «Копировать ссылку».
Паритет с конкурентами
Marzban/Marzneshin (revoke/rotate subscription), 3x-ui (per-user share + reset), Remnawave (
user.revokedevent), Hiddify (short-link revoke). Отзыв/ротация токена — стандартное действие.Чего не хватает сейчас (код)
Токен подписки = усечённый
HMAC(secret, subId)(token.Makeвusers_get/handler.go:77), то есть детерминирован от subId — отозвать утёкшую ссылку нельзя без смены subId, а смены subId нет. В строке только одна кнопка «Mihomo» (copy(u.sub.url),index.html:80), нет ротации и компактного меню действий.Зачем
Оператор мгновенно гасит утёкшую ссылку, не пересоздавая пользователя, и удобно делится новой. Сегодня subgen не умеет инвалидировать подписку: HMAC от subId неизменен, subId не ротируется — утёкшая ссылка живёт вечно.
Предлагаемая реализация
Сервисный метод
provisioning.RotateSubID: минтит новый subId (как при создании), ре-байндит клиента на всех панелях с тем же uuid, но новым subId (AddClientуже принимает subId), обновляетusers.sub_id. Ручкаuser_rotate_sub(openapi → ogen), тонкий хендлер. Во Vue — dropdown-меню действий в строке (Bootstrap уже вендорён), пункты дергают POST иcopy().Затронутые файлы
internal/service/provisioning/service.go(RotateSubID),internal/repository/users/(UpdateSubID)openapi/user_rotate_sub.yaml(новый) +openapi.yaml,internal/handlers/user_rotate_sub/internal/handlers/web/static/{app.js,index.html}Продуктовый ресёрч: изучены аналоги (Marzban/Marzneshin, 3x-ui, Remnawave, Hiddify, sub-store + клиентские стандарты импорта). Паритет и subgen-gap код-обоснованы. Ранг = продуктовый приоритет.