244 lines
8.4 KiB
Plaintext
244 lines
8.4 KiB
Plaintext
Да, я бы убирал подписки полностью. В текущем состоянии это не недоделанная мелочь, а мёртвый функциональный слой, который создаёт ложное ожидание у оператора и путает 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.
|