Полная зачистка legacy + закрытие fix24.1/fix24.2 + обновление логотипа

This commit is contained in:
2026-05-08 23:16:25 +05:00
parent de4a65a959
commit 1bca73814e
85 changed files with 4119 additions and 1911 deletions
+243
View File
@@ -0,0 +1,243 @@
Да, я бы убирал подписки полностью. В текущем состоянии это не недоделанная мелочь, а мёртвый функциональный слой, который создаёт ложное ожидание у оператора и путает UX.
По текущему коду видно следующее: ordinary Node URL / Node QR строятся отдельно и полезны; subscription-кнопки в UI есть, но backend endpoint `Hysteria2SubscribeUrl` фактически возвращает ошибку `subscription delivery is out of scope in HY2XS baseline`. При этом в service ещё лежит старая логика генерации подписок для Clash/Shadowrocket/v2rayN, но она не подключена нормальным публичным delivery route. То есть это уже рудимент: фронт показывает кнопки, backend говорит “не поддерживается”, а пользователи всё равно подключаются через обычный URI/QR.
Я бы добавил в общий план отдельный пункт.
---
## 27. Удалить subscription layer как неподдерживаемый рудимент
### Решение
Оставить только:
```text
Node URL
Node QR Code
Copy URI
Rotate Secret
```
Удалить:
```text
Subscribe
Subscribe QR Code
Subscription URL
Clash subscription extension
Shadowrocket/V2rayN subscription delivery
/hysteria2/hysteria2SubscribeUrl
```
То есть один peer — один обычный Hysteria2 URI/QR. Этого достаточно для текущей панели, особенно если цель — упрощённая, зрелая 3x-ui-like админка, а не subscription gateway.
---
## 28. Почему лучше удалить, а не чинить сейчас
Подписка — это отдельный продуктовый слой, а не просто “ещё один QR”.
Чтобы она была production-grade, нужны:
```text
публичный endpoint доставки подписки;
форматы под разные клиенты;
нормальная авторизация или signed token;
TTL / revoke / rotate;
rate limit;
логирование выдачи;
обработка client type;
совместимость Clash/Shadowrocket/v2rayN;
безопасное сокрытие peer secret;
корректные HTTP headers;
контроль доступа после disable/expire peer;
тесты на каждый формат клиента.
```
Сейчас этого нет. Более того, подписочный URL по старой логике строится вокруг `conPass`, то есть секрет peer’а становится частью URL. Это хуже обычного QR, потому что URL может попасть в browser history, reverse-proxy logs, access logs, Referer, скриншоты и т.д.
Обычный Node QR тоже содержит секрет, но он показывается авторизованному админу в панели для конкретного peer’а. Подписка же предполагает публичную доставку конфигурации по ссылке. Это другой threat model.
Поэтому чинить подписки сейчас — не “доделать кнопку”, а открывать отдельный блок безопасности и совместимости. Для текущего scope это лишнее.
---
## 29. Что удалить на backend
Удалить или пометить deprecated с последующим удалением:
```go
controller.Hysteria2SubscribeUrl
controller.Hysteria2Subscribe
service.Hysteria2SubscribeUrl
service.Hysteria2Subscribe
dto.Hysteria2SubscribeUrlDto
vo.Hysteria2SubscribeVo
```
Из router убрать:
```go
hysteria2.GET("/hysteria2SubscribeUrl", controller.Hysteria2SubscribeUrl)
```
Если будешь делать новую REST-модель после разделения `admin_user` / `peer`, оставить только:
```text
GET /hui/peers/:id/client-uri
GET /hui/peers/:id/client-qr
```
Или один endpoint:
```text
GET /hui/peers/:id/client-config
```
Response:
```json
{
"uri": "hysteria2://...",
"qrCode": "base64..."
}
```
Важно: этот endpoint должен работать только под admin JWT. Никакой публичной выдачи по `conPass`.
---
## 30. Что удалить на frontend
Из `src/views/account/list/index.vue` убрать:
```text
Subscribe
```
Из будущего peer drawer убрать:
```text
Subscribe
Subscribe QR
```
Из бывшего `src/views/info/account/index.vue` это всё всё равно исчезнет вместе с самой страницей `Account Info`.
Из `src/api/hysteria2/index.ts` убрать:
```ts
hysteria2SubscribeUrlApi
```
Из `src/api/hysteria2/types.ts` убрать:
```ts
Hysteria2SubscribeUrlDto
Hysteria2SubscribeVo
```
Из i18n убрать или оставить deprecated на один релиз:
```text
common.subscribe
common.subscribeQrCode
config.clashExtension
```
Если `CLASH_EXTENSION` используется только для подписки, убрать его из UI настроек. В базе можно не удалять сразу, чтобы не ломать существующие SQLite-файлы. Лучше сделать миграцию так:
```text
релиз N: поле скрыто, backend не использует;
релиз N+1: config key удаляется или игнорируется окончательно.
```
---
## 31. Что оставить вместо подписки
В peer list / peer drawer оставить понятные действия:
```text
Copy URI
Show QR
Rotate Secret
Edit
Reset Traffic
Kick
Disable
Delete
```
В detail drawer можно сделать блок:
```text
Connection
URI: hysteria2://...
[Copy]
[Show QR]
[Rotate secret]
```
И короткий warning:
```text
Rotating secret invalidates existing client configs.
```
Этого достаточно. Оператор создаёт peer, копирует URI или QR, отдаёт клиенту. Без псевдоподписок.
---
## 32. Если когда-нибудь возвращать подписки
Возвращать их стоит только как отдельную feature, не как восстановление старого кода.
Нормальная модель:
```text
subscription_token
id
peer_id
token_digest
expires_at
revoked_at
created_at
last_used_at
```
Публичный endpoint:
```text
GET /sub/:token
```
Token должен быть random, revocable, не равен peer secret. В URL нельзя класть `conPass`.
Формат:
```text
GET /sub/:token?target=clash
GET /sub/:token?target=shadowrocket
GET /sub/:token?target=v2rayn
```
Но я бы сейчас этого не делал. Это увеличит scope, а ценность низкая, если обычные URI/QR уже закрывают основной сценарий.
---
## 33. Acceptance criteria для удаления подписок
```text
В UI нигде нет Subscribe / Subscribe QR.
В peer list нет действий, ведущих к subscription endpoint.
В API клиента нет hysteria2SubscribeUrlApi.
Backend router не регистрирует /hysteria2/hysteria2SubscribeUrl.
Service-код генерации подписок удалён или явно deprecated и недоступен.
Обычный Node URL и Node QR продолжают работать.
Админ не получает Node URL/QR для себя, только для peer’ов.
В настройках нет Clash subscription extension, если подписки отключены.
```
Итог: да, подписку лучше удалить. Не скрыть кнопку CSS’ом, не оставить endpoint с `Fail`, а именно вырезать из публичного UI/API. Это упростит продукт, уберёт ложные кнопки и снизит риск утечки peer secret через URL.