fix(admin): различать достижимость Traffic Stats API и соответствие профилю
Признак на странице конфигурации отвечал только на вопрос «достучится ли админка», поэтому 0.0.0.0 показывался как норма — хотя внутренний control plane при нём опубликован на всех интерфейсах, а оркестратор такой конфигурации не создаёт. Состояний теперь четыре: канон профиля, wildcard, не-канонический loopback и недостижимый адрес. Backend не тронут: он по-прежнему отвечает только на вопрос достижимости — превращать лишнюю публикацию в отказ обслуживания значило бы отключить всех пиров. Исправлено ложное утверждение в его комментарии: пустой хост `:36712` в Go означает все интерфейсы, а не loopback. Удалены мёртвые фразы common.wait/enableSuccess/disableSuccess — остатки операций запуска, остановки и смены версии Hysteria, которых у панели нет.
This commit is contained in:
@@ -543,7 +543,37 @@ describe("страница конфигурации Hysteria", () => {
|
||||
const source = configPage();
|
||||
|
||||
expect(source).toContain("hysteria.trafficStatsMissing");
|
||||
expect(source).toContain("trafficStatsIsLoopback");
|
||||
expect(source).toContain("trafficStatsListenState");
|
||||
});
|
||||
|
||||
// Достижимость и соответствие профилю — РАЗНЫЕ вопросы.
|
||||
//
|
||||
// Первая версия отвечала только на первый: `0.0.0.0` считался нормой, потому
|
||||
// что через wildcard админка достучится. Но wildcard — не loopback:
|
||||
// внутренний control plane при нём опубликован на всех интерфейсах, и при
|
||||
// `HY2XS_FIREWALL_MODE=external|off` его не прикрывает ничто. Оркестратор
|
||||
// такой конфигурации не создаёт, значит она появилась правкой руками — и
|
||||
// диагностический экран обязан это назвать.
|
||||
test("адрес Traffic Stats API различает достижимость и профиль", () => {
|
||||
const source = vueCodeOf(configPage());
|
||||
|
||||
// Канон профиля ровно один, и он назван литералом.
|
||||
expect(source).toContain('"127.0.0.1"');
|
||||
// Пустой хост — тот же wildcard, что и 0.0.0.0: в Go `:36712` означает все
|
||||
// интерфейсы, а не loopback.
|
||||
expect(source).toMatch(/host === "" \|\| host === "0\.0\.0\.0"/);
|
||||
|
||||
for (const state of ["canonical", "wildcard", "nonCanonicalLoopback", "unreachable"]) {
|
||||
expect(source).toContain(state);
|
||||
}
|
||||
|
||||
// Три разные новости — три разные фразы, и ни одна не потеряна в словарях.
|
||||
for (const dictionary of [ru, en] as const) {
|
||||
const hysteria = (dictionary as any).hysteria ?? {};
|
||||
expect(typeof hysteria.trafficStatsUnreachable).toBe("string");
|
||||
expect(typeof hysteria.trafficStatsWildcard).toBe("string");
|
||||
expect(typeof hysteria.trafficStatsNonCanonical).toBe("string");
|
||||
}
|
||||
});
|
||||
|
||||
// Read-only экран не имеет права быть щедрее санитизированной выгрузки того
|
||||
|
||||
Reference in New Issue
Block a user