From 82e5ca40cce25399269d8ed2bb841d867d53afdf Mon Sep 17 00:00:00 2001 From: Crimson Date: Thu, 3 Sep 2026 23:07:19 +0500 Subject: [PATCH] =?UTF-8?q?fix(build):=20=D0=B3=D0=B5=D0=B9=D1=82=20ACME?= =?UTF-8?q?=20=D0=BE=D0=BF=D0=B8=D1=81=D1=8B=D0=B2=D0=B0=D0=BB=20=D1=81?= =?UTF-8?q?=D0=BD=D1=8F=D1=82=D1=83=D1=8E=20=D0=B0=D1=80=D1=85=D0=B8=D1=82?= =?UTF-8?q?=D0=B5=D0=BA=D1=82=D1=83=D1=80=D1=83=20=D0=BF=D0=B0=D0=BD=D0=B5?= =?UTF-8?q?=D0=BB=D0=B8?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Приёмка требовала, чтобы страница Hysteria содержала жёсткий список ACME DNS-провайдеров (cloudflare … vultr) и не содержала удалённого upstream namedotcom. Это имело смысл, пока панель ПРЕДЛАГАЛА выбор провайдера: список в UI был вторым экземпляром upstream-реестра и мог от него отстать — ровно так namedotcom и пришлось выпиливать вручную. После перевода страницы в read-only диагностику реестра нет и быть не должно: имя провайдера читается из фактического конфига и показывается как есть, поэтому новый upstream-провайдер отображается без правок панели. Возврат списка ради прохождения grep-а создал бы фиктивный реестр, существующий только для гейта. Гейт проверяет действующий контракт: провайдер приходит строкой и рисуется как значение, параметры DNS отдаются только именами, селектора на странице нет. Проверено положительно и на трёх нарушениях (провайдер перестал показываться, на странице появился селектор, тип стал перечислением) — гейт падает на каждом. Контрактный тест панели дополнен обратной проверкой: ни одно из восьми имён провайдеров не должно встречаться в исходнике страницы. Та же формулировка поправлена в матрице приёмки. Дополнительно прогнаны целиком все восемь функций приёмки, которым не нужен распакованный пакет: других устаревших утверждений нет. --- CHANGELOG.md | 17 +++++++++ docs/testing/11-2-builder-layer.md | 9 +++++ docs/testing/11-5-negative-and-matrix.md | 2 +- tools/build/lib/acceptance.sh | 44 +++++++++++++++++++----- tools/test/frontend-contract.test.ts | 36 +++++++++++++++++++ 5 files changed, 98 insertions(+), 10 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index ac3ddc7..6f95c08 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -364,6 +364,23 @@ Hysteria-интеграции с официальной документацие тестом с настоящими сокетами, а гейт приёмки запрещает возврат `IsLoopback()` и требует негативного случая в тестах. +### Исправлено — устаревшие утверждения приёмки + +- **Гейт «frontend ACME registry matches current upstream» описывал снятую + архитектуру.** Он требовал, чтобы страница Hysteria содержала жёсткий список + ACME DNS-провайдеров (`cloudflare` … `vultr`) и не содержала удалённого + upstream `namedotcom`. Это имело смысл, пока панель ПРЕДЛАГАЛА выбор + провайдера: список в UI был вторым экземпляром upstream-реестра и мог от него + отстать. После перевода страницы в read-only диагностику реестра нет и быть не + должно — имя провайдера читается из фактического конфига и показывается как + есть, поэтому новый upstream-провайдер отображается без правок панели. + Возврат списка ради прохождения grep'а создал бы фиктивный реестр, + существующий только для гейта, поэтому исправлен гейт: он проверяет + действующий контракт (провайдер приходит строкой и рисуется как значение, + параметры DNS — только именами, селектора на странице нет). То же утверждение + поправлено в матрице приёмки, а контрактный тест панели теперь требует + ОТСУТСТВИЯ всех восьми имён провайдеров в исходнике страницы. + ### Исправлено — зависимости frontend - **`browserslist@4.21.11` содержал high-advisory** (уязвимы `<= 4.28.6`) и diff --git a/docs/testing/11-2-builder-layer.md b/docs/testing/11-2-builder-layer.md index 44c97a1..5e6d481 100644 --- a/docs/testing/11-2-builder-layer.md +++ b/docs/testing/11-2-builder-layer.md @@ -726,6 +726,15 @@ credentials получает новую идентичность сессий». адрес auth-URL, имена параметров ACME DNS); - отсутствующий файл конфига — отказ, а не пустой профиль. +`tools/test/frontend-contract.test.ts` закрепляет ту же границу со стороны +панели: имя ACME DNS-провайдера показывается как фактическое значение профиля +(`text(profile.acme.dnsProvider)`), тип поля — обычная строка, а собственного +списка провайдеров в панели нет. Проверка перечисляет их поимённо +(`cloudflare`, `duckdns`, …, `namedotcom`) и требует, чтобы **ни один** не +встречался в исходнике страницы: реестр в UI был бы вторым экземпляром +upstream-списка, который умеет от него отстать — ровно так `namedotcom` +пришлось выпиливать вручную после его удаления в Hysteria 2.11.0. + `apps/service/hysteria2_export_test.go` дополнен якорями YAML: секрет за `&anchor`/`*alias` вырезается и по ссылке, и в самом объявлении; URL с учётными данными за якорем — тоже; ссылка на составной узел редактируется целиком; diff --git a/docs/testing/11-5-negative-and-matrix.md b/docs/testing/11-5-negative-and-matrix.md index db1ddd7..1cfb547 100644 --- a/docs/testing/11-5-negative-and-matrix.md +++ b/docs/testing/11-5-negative-and-matrix.md @@ -119,7 +119,7 @@ 28. экспорт не уничтожает современные и неизвестные upstream-поля 29. экспорт не содержит секретов 30. frontend отображает Gecko -31. `namedotcom` удалён, актуальные ACME-провайдеры отражены +31. панель показывает фактическое имя ACME DNS-провайдера из конфига и **не содержит** собственного списка провайдеров: страница Hysteria — read-only диагностика, выбирать провайдера она не предлагает, поэтому новый upstream-провайдер отображается без правок панели 32. документация нигде не утверждает, что Salamander — фиксированный инвариант 33. документация не фиксирует конкретный номер версии как «текущую версию», а объясняет latest-stable build policy 34. форма создания пира содержит примеры значений и пояснения для полей «Пир», «Комментарий» и «Секрет» diff --git a/tools/build/lib/acceptance.sh b/tools/build/lib/acceptance.sh index 0ac7e68..4a6d870 100644 --- a/tools/build/lib/acceptance.sh +++ b/tools/build/lib/acceptance.sh @@ -205,15 +205,41 @@ run_fix20_acceptance_subset() { grep -q 'GetRawHysteria2Config' apps/service/hysteria2_export.go \ || fail "acceptance: export must read the raw YAML instead of the typed model" - log_step "Acceptance: frontend ACME registry matches current upstream" - # Ищем именно предлагаемое значение, а не упоминание в комментарии. - ! grep -q '"namedotcom"' apps/frontend/src/views/hysteria/list/index.vue \ - || fail "acceptance: namedotcom was removed upstream in Hysteria 2.11.0 and must not be offered" - local provider - for provider in cloudflare duckdns gandi godaddy namecheap njalla porkbun vultr; do - grep -q "\"${provider}\"" apps/frontend/src/views/hysteria/list/index.vue \ - || fail "acceptance: ACME DNS provider ${provider} is missing from the UI registry" - done + log_step "Acceptance: frontend ACME diagnostics preserve upstream provider names" + # Этот гейт проверял НЕ ТО, и его предмет исчез вместе с прежней страницей. + # + # Раньше он требовал, чтобы `apps/frontend/src/views/hysteria/list/index.vue` + # содержал жёстко заданный список ACME DNS-провайдеров + # + # cloudflare duckdns gandi godaddy namecheap njalla porkbun vultr + # + # и не содержал `namedotcom`, удалённый upstream в Hysteria 2.11.0. Это имело + # смысл ровно до тех пор, пока панель ПРЕДЛАГАЛА оператору выбор провайдера: + # список в UI был вторым экземпляром upstream-реестра и мог от него отстать. + # + # Панель больше ничего не предлагает: конфигом владеет оркестратор, маршрутов + # записи в API нет, а страница Hysteria стала read-only диагностикой. Имя + # провайдера читается из фактического конфига и показывается как есть, поэтому + # реестра в UI нет и быть не должно — новый upstream-провайдер отображается + # без единой правки панели. + # + # Возврат старого списка ради прохождения этого grep'а создал бы фиктивный + # реестр, существующий только для гейта. Поэтому проверяется действующий + # контракт: провайдер приходит из профиля строкой и рисуется как значение. + local hysteria_page="apps/frontend/src/views/hysteria/list/index.vue" + local hysteria_types="apps/frontend/src/api/config/types.ts" + + code_has "$hysteria_page" -F -- 'text(profile.acme.dnsProvider)' \ + || fail "acceptance: the panel must render the ACME DNS provider reported by the backend" + code_has "$hysteria_types" -E -- 'dnsProvider:[[:space:]]*string[[:space:]]*\|[[:space:]]*null' \ + || fail "acceptance: the ACME profile must carry the provider name as a generic string" + # Значения параметров DNS-провайдера — ключ от DNS-зоны, и read-only экрану + # они не нужны: показываются только имена. + code_has "$hysteria_types" -F -- 'dnsConfigKeys: string[]' \ + || fail "acceptance: the ACME DNS parameters must be exposed as key names only" + # Селектор провайдера означал бы возврат к «панель владеет конфигом». + ! code_has "$hysteria_page" -F -- ' { } }); + // Имя ACME DNS-провайдера показывается как ФАКТИЧЕСКОЕ значение профиля. + // + // Прежняя страница несла жёсткий список провайдеров, то есть второй экземпляр + // upstream-реестра, который мог от него отстать: `namedotcom` пришлось + // выпиливать вручную после удаления в Hysteria 2.11.0. Панель больше ничего + // не предлагает — конфигом владеет оркестратор, — поэтому реестра в UI нет и + // быть не должно: новый upstream-провайдер отображается без правок панели. + test("ACME DNS provider показывается как фактическое значение профиля", () => { + const source = vueCodeOf(configPage()); + const types = codeOf(configTypes()); + + expect(source).toContain("profile.acme.dnsProvider"); + expect(source).toContain("text(profile.acme.dnsProvider)"); + expect(types).toContain("dnsProvider: string | null"); + + // Реестр провайдеров в панели не возвращается ни под каким видом. + for (const provider of [ + "cloudflare", + "duckdns", + "gandi", + "godaddy", + "namecheap", + "njalla", + "porkbun", + "vultr", + "namedotcom", + ]) { + expect(source).not.toContain(`"${provider}"`); + } + + // Значения параметров DNS — ключ от DNS-зоны: read-only экран получает + // только их имена. + expect(types).toContain("dnsConfigKeys: string[]"); + expect(types).not.toMatch(/dnsConfig:\s*(Record|\{)/); + }); + // Компоненты генерического редактора удалены вместе со страницей: пока они // существуют, «универсальный редактор Hysteria» отрастает заново. test("компоненты генерического редактора удалены", () => {