Vue Router 4.1.6 -> 4.6.4, Pinia 2.0.33 -> 2.3.1, @vueuse/core 9 -> 13.9.0,
vue-i18n 9.0.0 -> 9.14.5, echarts 5.6 -> 6.1.0, vue-echarts 7 -> 8.1.0.
Pinia 3, Vue Router 5 и Vite 8 сознательно не берутся: ни один из них не даёт
проекту ничего, кроме номера версии, а Vite 8 — это переезд на Rolldown.
vue-i18n и echarts обновлены не ради свежести: `pnpm audit --prod` на базовой
линии показывал 4 moderate, из них GHSA-x8qp-wqqm-57ph (vue-i18n, исправлено в
9.14.5) и GHSA-fgmj-fm8m-jvvx (echarts XSS, исправлено в 6.1.0). Теперь
`pnpm audit --prod` чист.
Четвёртая advisory — GHSA-5m5x-9j46-h678 в el-link — исправленной версии не
имеет, но в продукте недостижима: el-link не используется ни в одном
представлении. pnpm audit анализа достижимости не делает, в отличие от
govulncheck, поэтому это приходится проверять руками.
VueUse 13 сломал сборку: `[auto-import] identifier toRef already defined with
vue`. Причина — авто-импорт всего @vueuse/core, то есть пятисот с лишним имён,
среди которых реэкспорты toRef и toValue. Список сужен до двух функций, которые
действительно используются без явного импорта; src/types/auto-imports.d.ts
сократился с 526 строк до 124.
Заодно включена генерация .eslintrc-auto-import.json: файл подключён через
extends в .eslintrc.cjs, но не генерировался, то есть перечислял глобальные
имена, которых в авто-импорте давно нет. Устаревший список молча отключает
предупреждение eslint об обращении к несуществующему имени.
bundle: 2 604 924 против 2 404 202 на базовой линии (+8%).
typecheck: 0, eslint: 0, go build с встроенным dist: OK.
Экспорт в панели формировался через os.Create в /var/lib/hy2xs-admin/export,
и файл там оставался навсегда. При includeSecrets=true это означало
расшифрованные секреты пиров — фактические учётные данные доступа — в
открытом виде на диске, накапливающиеся с каждым нажатием кнопки. Выгрузки
формируются в памяти, каталога export/ больше нет.
Generic export/import таблицы config удалён целиком. Он исключал только сырой
Hysteria YAML, а в той же таблице лежат JWT_SECRET, PEER_SECRET_KEY,
PEER_SECRET_ENCRYPTION_KEY и HYSTERIA2_TRAFFIC_STATS_SECRET: кнопка Export
выгружала их открытым текстом, импорт позволял подменить. Для
PEER_SECRET_ENCRYPTION_KEY подмена ломает расшифровку секретов уже
существующих пиров. Production-сценария у этой пары не было.
Импорт пиров шёл мимо всей валидации, которую проходит обычное создание пира:
в базу попадало имя любой длины и с любыми символами, disabled с произвольным
числом, отрицательные счётчики. Файл применялся построчно, поэтому ошибка в
середине оставляла список наполовину изменённым, а импорт мог перезаписать
bootstrap-admin-peer, чей секрет продублирован в bootstrap-admin.secret.
Партия проверяется целиком до первой записи, неизвестные поля отклоняются.
Убран слой сетевых настроек панели: H_UI_WEB_PORT, H_UI_WEB_CONTEXT,
H_UI_CRT_PATH, H_UI_KEY_PATH и собственный TLS. Оркестратор передавал порт
аргументом, админка писала его в SQLite и тут же читала обратно, а UI
показывал поля disabled — второй источник истины, из которого ничего нельзя
было изменить. HUI_DATA/HUI_LOG заменены на HY2XS_DATA_DIR/HY2XS_LOG_DIR,
база переименована в hy2xs-admin.db, reference-схема — в schema.sql.
API namespace разделён по природе маршрутов: операторский API на /api,
machine-auth Hysteria на /internal/hysteria/auth. Путь machine-auth —
runtime-контракт, он уезжает в config.yaml и post-install.env, поэтому
объявлен одной константой на компонент.
Go-санитайзер экспорта вырезал секреты из URL только у ключей url/addr:
будущее upstream-поле с другим именем уносило учётные данные и access_token
целиком, а URL внутри списков не обрабатывались вовсе. Граница определяется
значением, а не именем ключа — как в TS-санитайзере оркестратора.
Заодно индикатор загрузки и цвета 401/404 переведены на брендовый токен:
NProgress приходил со своим #29d и был единственным элементом вне палитры.