fix(network): скрыть GRE PSK и сохранить признак IPsec
This commit is contained in:
1 parent
a404da768d
commit
3f3f06f147
24 files changed
+1570
-23
No files matched your search
@@ -1,6 +1,6 @@
|
||||
# UX/UI: протокол внешней приёмки 12.5
|
||||
|
||||
Актуальное продолжение 2026-10-13:208 закрывает WireGuard private-key GET дляreader иread-only операции пятисетевыхразделов; baseline/fixed SQL11, WireGuard profile56,53 unique E2E,20 live UI и2 own native интерфейса passed/cleaned. Backend/frontend ux-native208, source470/527 иcompiled1044 matched. Следующий209 — секреты GRE вGET /gre/tunnels и/filters/gre-tunnels.12.5 открыта.
|
||||
Актуальное продолжение 2026-10-13: блок 209 завершён. GRE PSK скрыт от читателя; каталог Filters сохраняет признак настроенного IPsec без ключа. Пройдены 12 SQL/API-проверок, профиль live-maps, 4 E2E и 4 live UI-сценария. Два собственных отключённых GRE на CHR созданы и удалены. Backend/frontend: ux-gre209, 473/527 исходных файлов и 1048 compiled artifacts совпали. Следующий блок 210 — keepalive при создании GRE без явных параметров. Этап 12.5 открыт.
|
||||
|
||||
IPsec78: реальный PSK responder established, mode-config198.18.78.10 и online=true подтверждены API; точные собственные объекты удалены. Сертификатный/DN online, late failure и history restore остаются открытыми. [Отчёт](ux-ui/acceptance/ipsec-mode-config-2026-10-09.json), [журнал](ux-ui-progress.md).
|
||||
|
||||
@@ -696,8 +696,6 @@ flowchart LR
|
||||
|
||||
## 12.5.77 — основной блок IPsec (2026-10-09)
|
||||
|
||||
Актуальное продолжение 2026-10-13:208 закрывает WireGuard private-key GET дляreader иread-only операции пятисетевыхразделов; baseline/fixed SQL11, WireGuard profile56,53 unique E2E,20 live UI и2 own native интерфейса passed/cleaned. Backend/frontend ux-native208, source470/527 иcompiled1044 matched. Следующий209 — секреты GRE вGET /gre/tunnels и/filters/gre-tunnels.12.5 открыта.
|
||||
|
||||
Подробный объём, протоколы, схема и ограничения: [12.5.77 в журнале](ux-ui-progress.md).
|
||||
|
||||
## 12.5.86 — BFD/OSPF: раздельные наблюдения реакции и маршрута (2026-10-09)
|
||||
@@ -2524,3 +2522,20 @@ Backend/frontend ux-native208 развёрнуты;470/527 source files и1044 c
|
||||
Протоколы: [baseline](ux-ui/acceptance/wireguard208-baseline-result.json), [fixed SQL11](ux-ui/acceptance/wireguard208-fixed-result.json), [profile](ux-ui/acceptance/native208-profile-result.json), [E2E53](ux-ui/acceptance/native208-e2e-2026-10-13.json), [live UI20](ux-ui/acceptance/native208-live-ui-2026-10-13.json), [native privacy/cleanup2](ux-ui/acceptance/wireguard208-native-live-2026-10-13.json), [compiled](ux-ui/acceptance/compiled208-result.json), [deployment](ux-ui/acceptance/native208-deployment-2026-10-13.json).
|
||||
|
||||
Следующий209: GRE mapper содержит ipsecSecret иipsec.secret, проверить оба публичных GET иограничить выдачу секретов reader, сохранив crypto-state/public metadata иwriter editing.12.5 открыта.
|
||||
|
||||
## 12.5.209 — доступ к GRE PSK и достоверность каталога IPsec (2026-10-13)
|
||||
|
||||
В production baseline читатель получал PSK через GET /gre/tunnels. Каталог /filters/gre-tunnels ключ не раскрывал, но всегда возвращал ipsec:null, скрывая сам факт настройки IPsec. Основной GET теперь копирует публичный DTO и очищает secret при отсутствии mm:network:write/admin; алгоритмы и наличие объекта IPsec сохраняются. Internal snapshot и право редактирования для writer/admin не меняются. is_admin без permission не даёт доступ к ключу. Legacy AUTH_REQUIRED=false сохранён. Общий каталог Filters возвращает только признак IPsec и пустой secret для всех ролей.
|
||||
|
||||
Экспорт скрытого PSK явно помечен как шаблон, содержит <IPSEC_PSK> и указание заменить ключ перед применением. Пустой ipsec-secret не подставляется как готовая конфигурация. Установленные ReUI компоненты и тема не изменялись.
|
||||
|
||||
Проверки: baseline и исправленный production backend — по 12 уникальных SQL/API-кейсов на собственных ограниченных PostgreSQL DB/role, с синтетическим PSK и настоящим auth middleware. Snapshot сохраняет исходный PSK; native writes 0. Оба комплекта DB/role/container удалены. Локальный test:live-maps, frontend TypeScript, backend build и ESLint прошли. Четыре E2E: скрытый ключ/шаблон на 1440 и 320px, прежние изменение/очистка PSK writer. Полную регрессию 192 не повторяли.
|
||||
|
||||
Backend/frontend ux-gre209 развёрнуты; 473/527 source files и 1048 compiled artifacts совпали, backend healthy. Live: по одному собственному отключённому GRE с PSK на каждом CHR, реальные Portal admin/reader JWT; reader не получает ключ, admin сохраняет его, каталог обеих ролей показывает IPsec без ключа. Четыре UI-кейса reader/admin × 1440/320, без API mocks и без UI mutations. Оба интерфейса и временный Portal user удалены; отсутствие интерфейсов проверено. Пароли и исходные объекты не менялись. Это проверка privacy/configured state, не шифрованного data plane.
|
||||
|
||||
Первоначальная сборка имела неверную ссылку на базовый Docker image; исправлена до развёртывания. Финальный frontend собран с mock=false и live default. Два первых native create отказали: опущенный keepalive превращался в 0, который RouterOS отклоняет. Cleanup прошёл; проверка завершена с явным 10s,3. Ошибка значения по умолчанию остаётся отдельным пунктом 210. Повторные проверки не складываются в число уникальных кейсов.
|
||||
|
||||
Протоколы: [baseline](ux-ui/acceptance/gre209-baseline-result.json), [fixed SQL/API](ux-ui/acceptance/gre209-fixed-result.json), [профиль](ux-ui/acceptance/gre209-profile-2026-10-13.json), [E2E](ux-ui/acceptance/gre209-e2e-2026-10-13.json), [native/UI/cleanup](ux-ui/acceptance/gre209-native-live-2026-10-13.json), [source](ux-ui/acceptance/source209-result.json), [compiled](ux-ui/acceptance/compiled209-result.json), [deployment](ux-ui/acceptance/gre209-deployment-2026-10-13.json).
|
||||
|
||||
Следующий блок 210: исправить создание GRE с опущенным keepalive, проверить фактический RouterOS ответ и прежнее редактирование. Этап 12.5 открыт; внешние ограничения в актуальной матрице сохраняются.
|
||||
|
||||
+1
-5
@@ -1,13 +1,11 @@
|
||||
# План реализации UX/UI по пятичасовым окнам
|
||||
|
||||
Актуальное продолжение 2026-10-13:208 закрывает WireGuard private-key GET дляreader иread-only операции пятисетевыхразделов; baseline/fixed SQL11, WireGuard profile56,53 unique E2E,20 live UI и2 own native интерфейса passed/cleaned. Backend/frontend ux-native208, source470/527 иcompiled1044 matched. Следующий209 — секреты GRE вGET /gre/tunnels и/filters/gre-tunnels.12.5 открыта.
|
||||
Актуальное продолжение 2026-10-13: блок 209 завершён. GRE PSK скрыт от читателя; каталог Filters сохраняет признак настроенного IPsec без ключа. Пройдены 12 SQL/API-проверок, профиль live-maps, 4 E2E и 4 live UI-сценария. Два собственных отключённых GRE на CHR созданы и удалены. Backend/frontend: ux-gre209, 473/527 исходных файлов и 1048 compiled artifacts совпали. Следующий блок 210 — keepalive при создании GRE без явных параметров. Этап 12.5 открыт.
|
||||
|
||||
Общий план проекта MikrotikManager. Основан на согласованном плане из задачи; точка продолжения обновлена 2026-10-13. Источник фактического прогресса, проверок и ограничений — [журнал реализации](ux-ui-progress.md). Этот документ задаёт объём и критерии завершения, журнал фиксирует результат.
|
||||
|
||||
## Актуальная точка продолжения — 2026-10-13
|
||||
|
||||
Актуальное продолжение 2026-10-13:208 закрывает WireGuard private-key GET дляreader иread-only операции пятисетевыхразделов; baseline/fixed SQL11, WireGuard profile56,53 unique E2E,20 live UI и2 own native интерфейса passed/cleaned. Backend/frontend ux-native208, source470/527 иcompiled1044 matched. Следующий209 — секреты GRE вGET /gre/tunnels и/filters/gre-tunnels.12.5 открыта.
|
||||
|
||||
Этапы0–11 завершены в локальных границах журнала. История выполненных внешних блоков и доказательства сохранены в [журнале](ux-ui-stage-12.md) и [протоколе](ux-ui-external-acceptance.md). Реальная Telegram доставка, Portal SSO, multi-instance и оставшиеся профильные сетевые ограничения открыты.
|
||||
|
||||
По поручению2026-10-09 работать укрупнёнными разделами, последовательно на текущей модели: карта возможностей → исправления → профильные тесты → build/deploy → собственные реальные сценарии → cleanup → один локальный коммит без push. Проверять квоту после завершённого раздела; незавершённые проверки явно переносить в журнал.
|
||||
@@ -371,6 +369,4 @@ flowchart LR
|
||||
|
||||
## 12.5.77 — основной блок IPsec (2026-10-09)
|
||||
|
||||
Актуальное продолжение 2026-10-13:208 закрывает WireGuard private-key GET дляreader иread-only операции пятисетевыхразделов; baseline/fixed SQL11, WireGuard profile56,53 unique E2E,20 live UI и2 own native интерфейса passed/cleaned. Backend/frontend ux-native208, source470/527 иcompiled1044 matched. Следующий209 — секреты GRE вGET /gre/tunnels и/filters/gre-tunnels.12.5 открыта.
|
||||
|
||||
Подробный объём, протоколы, схема и ограничения: [12.5.77 в журнале](ux-ui-progress.md).
|
||||
+17
-1
@@ -1,6 +1,6 @@
|
||||
# UX/UI: журнал реализации
|
||||
|
||||
Актуальное продолжение 2026-10-13:208 закрывает WireGuard private-key GET дляreader иread-only операции пятисетевыхразделов; baseline/fixed SQL11, WireGuard profile56,53 unique E2E,20 live UI и2 own native интерфейса passed/cleaned. Backend/frontend ux-native208, source470/527 иcompiled1044 matched. Следующий209 — секреты GRE вGET /gre/tunnels и/filters/gre-tunnels.12.5 открыта.
|
||||
Актуальное продолжение 2026-10-13: блок 209 завершён. GRE PSK скрыт от читателя; каталог Filters сохраняет признак настроенного IPsec без ключа. Пройдены 12 SQL/API-проверок, профиль live-maps, 4 E2E и 4 live UI-сценария. Два собственных отключённых GRE на CHR созданы и удалены. Backend/frontend: ux-gre209, 473/527 исходных файлов и 1048 compiled artifacts совпали. Следующий блок 210 — keepalive при создании GRE без явных параметров. Этап 12.5 открыт.
|
||||
|
||||
Общий план: [UX/UI по этапам и пятичасовым окнам](ux-ui-plan.md). План задаёт объём, этот журнал фиксирует выполненные блоки и ограничения. Записи расположены от новых к старым; подробная история этапа12 также сохранена в [ux-ui-stage-12.md](ux-ui-stage-12.md).
|
||||
|
||||
@@ -38,6 +38,22 @@
|
||||
| 11Б | Оповещения, сбор данных, интеграции, релизы и настройки | Завершён в границах локальной приёмки 2026-10-03; ограничения и evidence в11Б.7 |
|
||||
| 12 | Итоговая доступность, адаптивность, производительность и регрессия | Локальная приёмка завершена в границах12.3.83; внешняя12.5 в работе, выполненные блоки1–196 и ограничения ниже. Runtime backend/frontend ux-peak196. |
|
||||
|
||||
## 12.5.209 — доступ к GRE PSK и достоверность каталога IPsec (2026-10-13)
|
||||
|
||||
В production baseline читатель получал PSK через GET /gre/tunnels. Каталог /filters/gre-tunnels ключ не раскрывал, но всегда возвращал ipsec:null, скрывая сам факт настройки IPsec. Основной GET теперь копирует публичный DTO и очищает secret при отсутствии mm:network:write/admin; алгоритмы и наличие объекта IPsec сохраняются. Internal snapshot и право редактирования для writer/admin не меняются. is_admin без permission не даёт доступ к ключу. Legacy AUTH_REQUIRED=false сохранён. Общий каталог Filters возвращает только признак IPsec и пустой secret для всех ролей.
|
||||
|
||||
Экспорт скрытого PSK явно помечен как шаблон, содержит <IPSEC_PSK> и указание заменить ключ перед применением. Пустой ipsec-secret не подставляется как готовая конфигурация. Установленные ReUI компоненты и тема не изменялись.
|
||||
|
||||
Проверки: baseline и исправленный production backend — по 12 уникальных SQL/API-кейсов на собственных ограниченных PostgreSQL DB/role, с синтетическим PSK и настоящим auth middleware. Snapshot сохраняет исходный PSK; native writes 0. Оба комплекта DB/role/container удалены. Локальный test:live-maps, frontend TypeScript, backend build и ESLint прошли. Четыре E2E: скрытый ключ/шаблон на 1440 и 320px, прежние изменение/очистка PSK writer. Полную регрессию 192 не повторяли.
|
||||
|
||||
Backend/frontend ux-gre209 развёрнуты; 473/527 source files и 1048 compiled artifacts совпали, backend healthy. Live: по одному собственному отключённому GRE с PSK на каждом CHR, реальные Portal admin/reader JWT; reader не получает ключ, admin сохраняет его, каталог обеих ролей показывает IPsec без ключа. Четыре UI-кейса reader/admin × 1440/320, без API mocks и без UI mutations. Оба интерфейса и временный Portal user удалены; отсутствие интерфейсов проверено. Пароли и исходные объекты не менялись. Это проверка privacy/configured state, не шифрованного data plane.
|
||||
|
||||
Первоначальная сборка имела неверную ссылку на базовый Docker image; исправлена до развёртывания. Финальный frontend собран с mock=false и live default. Два первых native create отказали: опущенный keepalive превращался в 0, который RouterOS отклоняет. Cleanup прошёл; проверка завершена с явным 10s,3. Ошибка значения по умолчанию остаётся отдельным пунктом 210. Повторные проверки не складываются в число уникальных кейсов.
|
||||
|
||||
Протоколы: [baseline](ux-ui/acceptance/gre209-baseline-result.json), [fixed SQL/API](ux-ui/acceptance/gre209-fixed-result.json), [профиль](ux-ui/acceptance/gre209-profile-2026-10-13.json), [E2E](ux-ui/acceptance/gre209-e2e-2026-10-13.json), [native/UI/cleanup](ux-ui/acceptance/gre209-native-live-2026-10-13.json), [source](ux-ui/acceptance/source209-result.json), [compiled](ux-ui/acceptance/compiled209-result.json), [deployment](ux-ui/acceptance/gre209-deployment-2026-10-13.json).
|
||||
|
||||
Следующий блок 210: исправить создание GRE с опущенным keepalive, проверить фактический RouterOS ответ и прежнее редактирование. Этап 12.5 открыт; внешние ограничения в актуальной матрице сохраняются.
|
||||
|
||||
## 12.5.208 — приватные ключи WireGuard и режим просмотра сетевых разделов (2026-10-13)
|
||||
|
||||
Старый production backend выдавал синтетический непустой приватный ключ reader при GET WireGuard с includePrivateKey=1/true. Baseline подтверждён actual compiled auth/mapper на собственной ограниченной PostgreSQL БД и локальном RouterOS HTTP fixture. Теперь явный запрос приватного ключа требует mm:network:write/admin, иначе403 до любых native requests. Обычный GET200 сохраняет public key и не содержит private key. is_admin без необходимого permission не заменяет право. Writer/admin сохраняют прежнее действие, legacy AUTH_REQUIRED=false не менялся.
|
||||
|
||||
@@ -1,10 +1,10 @@
|
||||
# Оставшаяся внешняя приёмка — 2026-10-13
|
||||
|
||||
Актуальное продолжение 2026-10-13:208 закрывает WireGuard private-key GET дляreader иread-only операции пятисетевыхразделов; baseline/fixed SQL11, WireGuard profile56,53 unique E2E,20 live UI и2 own native интерфейса passed/cleaned. Backend/frontend ux-native208, source470/527 иcompiled1044 matched. Следующий209 — секреты GRE вGET /gre/tunnels и/filters/gre-tunnels.12.5 открыта.
|
||||
Актуальное продолжение 2026-10-13: блок 209 завершён. GRE PSK скрыт от читателя; каталог Filters сохраняет признак настроенного IPsec без ключа. Пройдены 12 SQL/API-проверок, профиль live-maps, 4 E2E и 4 live UI-сценария. Два собственных отключённых GRE на CHR созданы и удалены. Backend/frontend: ux-gre209, 473/527 исходных файлов и 1048 compiled artifacts совпали. Следующий блок 210 — keepalive при создании GRE без явных параметров. Этап 12.5 открыт.
|
||||
|
||||
Это актуальная матрица после 12.5.208. Исторические записи сохраняют версии и ограничения на момент выполнения; поздние проверки ниже уточняют их. Этап 12.5 открыт. Успех в двух CHR и одном backend не означает приёмку всех конфигураций, интеграций или полной регрессии.
|
||||
Это актуальная матрица после 12.5.209. Исторические записи сохраняют версии и ограничения на момент выполнения; поздние проверки ниже уточняют их. Этап 12.5 открыт. Успех в двух CHR и одном backend не означает приёмку всех конфигураций, интеграций или полной регрессии.
|
||||
|
||||
Стенд: Debian13/Compose, PostgreSQL18.6, два CHR RouterOS7.24.5. Backend/frontend `ux-native208`; production lab с195 использует AUTH_REQUIRED=true и Portal1.3.1. Подписанные JWT/RBAC проверялись в изолированных процессах. Все собственные объекты112 удалены, исходные13 коллекций×2 (включая logging/certificates/files/routes) проверены; пароли не менялись.
|
||||
Стенд: Debian13/Compose, PostgreSQL18.6, два CHR RouterOS7.24.5. Backend/frontend `ux-gre209`; production lab с195 использует AUTH_REQUIRED=true и Portal1.3.1. Подписанные JWT/RBAC проверялись в изолированных процессах. Все собственные объекты112 удалены, исходные13 коллекций×2 (включая logging/certificates/files/routes) проверены; пароли не менялись.
|
||||
|
||||
| Раздел | Подтверждено | Осталось / условие завершения |
|
||||
| --- | --- | --- |
|
||||
@@ -26,7 +26,7 @@
|
||||
|
||||
## Следующая последовательность — 2026-10-13
|
||||
|
||||
1. **209 — GRE secret DTOs:** /gre/tunnels и/filters/gre-tunnels, синтетические ключи/own DB, роли исохранение crypto-state; не менятьnative config.
|
||||
1. **210 — GRE keepalive:** исправить значение по умолчанию создания, которое RouterOS отклоняет; проверить отсутствие неожиданных изменений при PATCH.
|
||||
2. **Профильный контроль:** для новых изменений выполнять затронутые SQL/API/UI проверки. Общая регрессия192 выполнена; не повторять её без изменений общей основы или нового основания.
|
||||
3. **Внешние зависимости:** Portal issuer/login/revoke, Telegram bot/chat/разрешённое сообщение, клиентские ОС, независимые WAN/public IPv6 и scale/multi-instance — отдельные группы по таблице выше. Ограничения текущего стенда не превращать в обещание приёмки всех конфигураций.
|
||||
|
||||
@@ -1440,3 +1440,20 @@ Backend/frontend ux-native208 развёрнуты;470/527 source files и1044 c
|
||||
Протоколы: [baseline](ux-ui/acceptance/wireguard208-baseline-result.json), [fixed SQL11](ux-ui/acceptance/wireguard208-fixed-result.json), [profile](ux-ui/acceptance/native208-profile-result.json), [E2E53](ux-ui/acceptance/native208-e2e-2026-10-13.json), [live UI20](ux-ui/acceptance/native208-live-ui-2026-10-13.json), [native privacy/cleanup2](ux-ui/acceptance/wireguard208-native-live-2026-10-13.json), [compiled](ux-ui/acceptance/compiled208-result.json), [deployment](ux-ui/acceptance/native208-deployment-2026-10-13.json).
|
||||
|
||||
Следующий209: GRE mapper содержит ipsecSecret иipsec.secret, проверить оба публичных GET иограничить выдачу секретов reader, сохранив crypto-state/public metadata иwriter editing.12.5 открыта.
|
||||
|
||||
## 12.5.209 — доступ к GRE PSK и достоверность каталога IPsec (2026-10-13)
|
||||
|
||||
В production baseline читатель получал PSK через GET /gre/tunnels. Каталог /filters/gre-tunnels ключ не раскрывал, но всегда возвращал ipsec:null, скрывая сам факт настройки IPsec. Основной GET теперь копирует публичный DTO и очищает secret при отсутствии mm:network:write/admin; алгоритмы и наличие объекта IPsec сохраняются. Internal snapshot и право редактирования для writer/admin не меняются. is_admin без permission не даёт доступ к ключу. Legacy AUTH_REQUIRED=false сохранён. Общий каталог Filters возвращает только признак IPsec и пустой secret для всех ролей.
|
||||
|
||||
Экспорт скрытого PSK явно помечен как шаблон, содержит <IPSEC_PSK> и указание заменить ключ перед применением. Пустой ipsec-secret не подставляется как готовая конфигурация. Установленные ReUI компоненты и тема не изменялись.
|
||||
|
||||
Проверки: baseline и исправленный production backend — по 12 уникальных SQL/API-кейсов на собственных ограниченных PostgreSQL DB/role, с синтетическим PSK и настоящим auth middleware. Snapshot сохраняет исходный PSK; native writes 0. Оба комплекта DB/role/container удалены. Локальный test:live-maps, frontend TypeScript, backend build и ESLint прошли. Четыре E2E: скрытый ключ/шаблон на 1440 и 320px, прежние изменение/очистка PSK writer. Полную регрессию 192 не повторяли.
|
||||
|
||||
Backend/frontend ux-gre209 развёрнуты; 473/527 source files и 1048 compiled artifacts совпали, backend healthy. Live: по одному собственному отключённому GRE с PSK на каждом CHR, реальные Portal admin/reader JWT; reader не получает ключ, admin сохраняет его, каталог обеих ролей показывает IPsec без ключа. Четыре UI-кейса reader/admin × 1440/320, без API mocks и без UI mutations. Оба интерфейса и временный Portal user удалены; отсутствие интерфейсов проверено. Пароли и исходные объекты не менялись. Это проверка privacy/configured state, не шифрованного data plane.
|
||||
|
||||
Первоначальная сборка имела неверную ссылку на базовый Docker image; исправлена до развёртывания. Финальный frontend собран с mock=false и live default. Два первых native create отказали: опущенный keepalive превращался в 0, который RouterOS отклоняет. Cleanup прошёл; проверка завершена с явным 10s,3. Ошибка значения по умолчанию остаётся отдельным пунктом 210. Повторные проверки не складываются в число уникальных кейсов.
|
||||
|
||||
Протоколы: [baseline](ux-ui/acceptance/gre209-baseline-result.json), [fixed SQL/API](ux-ui/acceptance/gre209-fixed-result.json), [профиль](ux-ui/acceptance/gre209-profile-2026-10-13.json), [E2E](ux-ui/acceptance/gre209-e2e-2026-10-13.json), [native/UI/cleanup](ux-ui/acceptance/gre209-native-live-2026-10-13.json), [source](ux-ui/acceptance/source209-result.json), [compiled](ux-ui/acceptance/compiled209-result.json), [deployment](ux-ui/acceptance/gre209-deployment-2026-10-13.json).
|
||||
|
||||
Следующий блок 210: исправить создание GRE с опущенным keepalive, проверить фактический RouterOS ответ и прежнее редактирование. Этап 12.5 открыт; внешние ограничения в актуальной матрице сохраняются.
|
||||
|
||||
+18
-1
@@ -1,6 +1,6 @@
|
||||
# Этап 12: итоговая приёмка UX/UI
|
||||
|
||||
Актуальное продолжение 2026-10-13:208 закрывает WireGuard private-key GET дляreader иread-only операции пятисетевыхразделов; baseline/fixed SQL11, WireGuard profile56,53 unique E2E,20 live UI и2 own native интерфейса passed/cleaned. Backend/frontend ux-native208, source470/527 иcompiled1044 matched. Следующий209 — секреты GRE вGET /gre/tunnels и/filters/gre-tunnels.12.5 открыта.
|
||||
Актуальное продолжение 2026-10-13: блок 209 завершён. GRE PSK скрыт от читателя; каталог Filters сохраняет признак настроенного IPsec без ключа. Пройдены 12 SQL/API-проверок, профиль live-maps, 4 E2E и 4 live UI-сценария. Два собственных отключённых GRE на CHR созданы и удалены. Backend/frontend: ux-gre209, 473/527 исходных файлов и 1048 compiled artifacts совпали. Следующий блок 210 — keepalive при создании GRE без явных параметров. Этап 12.5 открыт.
|
||||
|
||||
План: [ux-ui-plan.md](ux-ui-plan.md). Фактические результаты: [ux-ui-progress.md](ux-ui-progress.md). Подготовлен после сводных проверок 11Б; завершение каждого блока требует локального коммита без push.
|
||||
|
||||
@@ -3829,3 +3829,20 @@ Backend/frontend ux-native208 развёрнуты;470/527 source files и1044 c
|
||||
Протоколы: [baseline](ux-ui/acceptance/wireguard208-baseline-result.json), [fixed SQL11](ux-ui/acceptance/wireguard208-fixed-result.json), [profile](ux-ui/acceptance/native208-profile-result.json), [E2E53](ux-ui/acceptance/native208-e2e-2026-10-13.json), [live UI20](ux-ui/acceptance/native208-live-ui-2026-10-13.json), [native privacy/cleanup2](ux-ui/acceptance/wireguard208-native-live-2026-10-13.json), [compiled](ux-ui/acceptance/compiled208-result.json), [deployment](ux-ui/acceptance/native208-deployment-2026-10-13.json).
|
||||
|
||||
Следующий209: GRE mapper содержит ipsecSecret иipsec.secret, проверить оба публичных GET иограничить выдачу секретов reader, сохранив crypto-state/public metadata иwriter editing.12.5 открыта.
|
||||
|
||||
## 12.5.209 — доступ к GRE PSK и достоверность каталога IPsec (2026-10-13)
|
||||
|
||||
В production baseline читатель получал PSK через GET /gre/tunnels. Каталог /filters/gre-tunnels ключ не раскрывал, но всегда возвращал ipsec:null, скрывая сам факт настройки IPsec. Основной GET теперь копирует публичный DTO и очищает secret при отсутствии mm:network:write/admin; алгоритмы и наличие объекта IPsec сохраняются. Internal snapshot и право редактирования для writer/admin не меняются. is_admin без permission не даёт доступ к ключу. Legacy AUTH_REQUIRED=false сохранён. Общий каталог Filters возвращает только признак IPsec и пустой secret для всех ролей.
|
||||
|
||||
Экспорт скрытого PSK явно помечен как шаблон, содержит <IPSEC_PSK> и указание заменить ключ перед применением. Пустой ipsec-secret не подставляется как готовая конфигурация. Установленные ReUI компоненты и тема не изменялись.
|
||||
|
||||
Проверки: baseline и исправленный production backend — по 12 уникальных SQL/API-кейсов на собственных ограниченных PostgreSQL DB/role, с синтетическим PSK и настоящим auth middleware. Snapshot сохраняет исходный PSK; native writes 0. Оба комплекта DB/role/container удалены. Локальный test:live-maps, frontend TypeScript, backend build и ESLint прошли. Четыре E2E: скрытый ключ/шаблон на 1440 и 320px, прежние изменение/очистка PSK writer. Полную регрессию 192 не повторяли.
|
||||
|
||||
Backend/frontend ux-gre209 развёрнуты; 473/527 source files и 1048 compiled artifacts совпали, backend healthy. Live: по одному собственному отключённому GRE с PSK на каждом CHR, реальные Portal admin/reader JWT; reader не получает ключ, admin сохраняет его, каталог обеих ролей показывает IPsec без ключа. Четыре UI-кейса reader/admin × 1440/320, без API mocks и без UI mutations. Оба интерфейса и временный Portal user удалены; отсутствие интерфейсов проверено. Пароли и исходные объекты не менялись. Это проверка privacy/configured state, не шифрованного data plane.
|
||||
|
||||
Первоначальная сборка имела неверную ссылку на базовый Docker image; исправлена до развёртывания. Финальный frontend собран с mock=false и live default. Два первых native create отказали: опущенный keepalive превращался в 0, который RouterOS отклоняет. Cleanup прошёл; проверка завершена с явным 10s,3. Ошибка значения по умолчанию остаётся отдельным пунктом 210. Повторные проверки не складываются в число уникальных кейсов.
|
||||
|
||||
Протоколы: [baseline](ux-ui/acceptance/gre209-baseline-result.json), [fixed SQL/API](ux-ui/acceptance/gre209-fixed-result.json), [профиль](ux-ui/acceptance/gre209-profile-2026-10-13.json), [E2E](ux-ui/acceptance/gre209-e2e-2026-10-13.json), [native/UI/cleanup](ux-ui/acceptance/gre209-native-live-2026-10-13.json), [source](ux-ui/acceptance/source209-result.json), [compiled](ux-ui/acceptance/compiled209-result.json), [deployment](ux-ui/acceptance/gre209-deployment-2026-10-13.json).
|
||||
|
||||
Следующий блок 210: исправить создание GRE с опущенным keepalive, проверить фактический RouterOS ответ и прежнее редактирование. Этап 12.5 открыт; внешние ограничения в актуальной матрице сохраняются.
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
# Тестовый сервер UX/UI — 2026-10-10
|
||||
|
||||
Актуальное продолжение 2026-10-13:208 закрывает WireGuard private-key GET дляreader иread-only операции пятисетевыхразделов; baseline/fixed SQL11, WireGuard profile56,53 unique E2E,20 live UI и2 own native интерфейса passed/cleaned. Backend/frontend ux-native208, source470/527 иcompiled1044 matched. Следующий209 — секреты GRE вGET /gre/tunnels и/filters/gre-tunnels.12.5 открыта.
|
||||
Актуальное продолжение 2026-10-13: блок 209 завершён. GRE PSK скрыт от читателя; каталог Filters сохраняет признак настроенного IPsec без ключа. Пройдены 12 SQL/API-проверок, профиль live-maps, 4 E2E и 4 live UI-сценария. Два собственных отключённых GRE на CHR созданы и удалены. Backend/frontend: ux-gre209, 473/527 исходных файлов и 1048 compiled artifacts совпали. Следующий блок 210 — keepalive при создании GRE без явных параметров. Этап 12.5 открыт.
|
||||
|
||||
| Параметр | Проверенное состояние |
|
||||
| --- | --- |
|
||||
@@ -708,8 +708,6 @@ flowchart LR
|
||||
|
||||
## 12.5.77 — основной блок IPsec (2026-10-09)
|
||||
|
||||
Актуальное продолжение 2026-10-13:208 закрывает WireGuard private-key GET дляreader иread-only операции пятисетевыхразделов; baseline/fixed SQL11, WireGuard profile56,53 unique E2E,20 live UI и2 own native интерфейса passed/cleaned. Backend/frontend ux-native208, source470/527 иcompiled1044 matched. Следующий209 — секреты GRE вGET /gre/tunnels и/filters/gre-tunnels.12.5 открыта.
|
||||
|
||||
Подробный объём, протоколы, схема и ограничения: [12.5.77 в журнале](ux-ui-progress.md).
|
||||
|
||||
12.5.87 (2026-10-09): OSPF optimizer native/API и4 browser checks passed, собственные объекты очищены, baseline7 коллекций×2 сохранён. Подробности/runtime происхождение — в журнале.
|
||||
@@ -2255,3 +2253,20 @@ Backend/frontend ux-native208 развёрнуты;470/527 source files и1044 c
|
||||
Протоколы: [baseline](ux-ui/acceptance/wireguard208-baseline-result.json), [fixed SQL11](ux-ui/acceptance/wireguard208-fixed-result.json), [profile](ux-ui/acceptance/native208-profile-result.json), [E2E53](ux-ui/acceptance/native208-e2e-2026-10-13.json), [live UI20](ux-ui/acceptance/native208-live-ui-2026-10-13.json), [native privacy/cleanup2](ux-ui/acceptance/wireguard208-native-live-2026-10-13.json), [compiled](ux-ui/acceptance/compiled208-result.json), [deployment](ux-ui/acceptance/native208-deployment-2026-10-13.json).
|
||||
|
||||
Следующий209: GRE mapper содержит ipsecSecret иipsec.secret, проверить оба публичных GET иограничить выдачу секретов reader, сохранив crypto-state/public metadata иwriter editing.12.5 открыта.
|
||||
|
||||
## 12.5.209 — доступ к GRE PSK и достоверность каталога IPsec (2026-10-13)
|
||||
|
||||
В production baseline читатель получал PSK через GET /gre/tunnels. Каталог /filters/gre-tunnels ключ не раскрывал, но всегда возвращал ipsec:null, скрывая сам факт настройки IPsec. Основной GET теперь копирует публичный DTO и очищает secret при отсутствии mm:network:write/admin; алгоритмы и наличие объекта IPsec сохраняются. Internal snapshot и право редактирования для writer/admin не меняются. is_admin без permission не даёт доступ к ключу. Legacy AUTH_REQUIRED=false сохранён. Общий каталог Filters возвращает только признак IPsec и пустой secret для всех ролей.
|
||||
|
||||
Экспорт скрытого PSK явно помечен как шаблон, содержит <IPSEC_PSK> и указание заменить ключ перед применением. Пустой ipsec-secret не подставляется как готовая конфигурация. Установленные ReUI компоненты и тема не изменялись.
|
||||
|
||||
Проверки: baseline и исправленный production backend — по 12 уникальных SQL/API-кейсов на собственных ограниченных PostgreSQL DB/role, с синтетическим PSK и настоящим auth middleware. Snapshot сохраняет исходный PSK; native writes 0. Оба комплекта DB/role/container удалены. Локальный test:live-maps, frontend TypeScript, backend build и ESLint прошли. Четыре E2E: скрытый ключ/шаблон на 1440 и 320px, прежние изменение/очистка PSK writer. Полную регрессию 192 не повторяли.
|
||||
|
||||
Backend/frontend ux-gre209 развёрнуты; 473/527 source files и 1048 compiled artifacts совпали, backend healthy. Live: по одному собственному отключённому GRE с PSK на каждом CHR, реальные Portal admin/reader JWT; reader не получает ключ, admin сохраняет его, каталог обеих ролей показывает IPsec без ключа. Четыре UI-кейса reader/admin × 1440/320, без API mocks и без UI mutations. Оба интерфейса и временный Portal user удалены; отсутствие интерфейсов проверено. Пароли и исходные объекты не менялись. Это проверка privacy/configured state, не шифрованного data plane.
|
||||
|
||||
Первоначальная сборка имела неверную ссылку на базовый Docker image; исправлена до развёртывания. Финальный frontend собран с mock=false и live default. Два первых native create отказали: опущенный keepalive превращался в 0, который RouterOS отклоняет. Cleanup прошёл; проверка завершена с явным 10s,3. Ошибка значения по умолчанию остаётся отдельным пунктом 210. Повторные проверки не складываются в число уникальных кейсов.
|
||||
|
||||
Протоколы: [baseline](ux-ui/acceptance/gre209-baseline-result.json), [fixed SQL/API](ux-ui/acceptance/gre209-fixed-result.json), [профиль](ux-ui/acceptance/gre209-profile-2026-10-13.json), [E2E](ux-ui/acceptance/gre209-e2e-2026-10-13.json), [native/UI/cleanup](ux-ui/acceptance/gre209-native-live-2026-10-13.json), [source](ux-ui/acceptance/source209-result.json), [compiled](ux-ui/acceptance/compiled209-result.json), [deployment](ux-ui/acceptance/gre209-deployment-2026-10-13.json).
|
||||
|
||||
Следующий блок 210: исправить создание GRE с опущенным keepalive, проверить фактический RouterOS ответ и прежнее редактирование. Этап 12.5 открыт; внешние ограничения в актуальной матрице сохраняются.
|
||||
|
||||
File diff suppressed because it is too large.
Load diff
@@ -0,0 +1,103 @@
|
||||
{
|
||||
"date": "2026-10-13",
|
||||
"block": "12.5.209",
|
||||
"database": "mm_accept_166_1791897731540",
|
||||
"baseline": true,
|
||||
"cases": [
|
||||
{
|
||||
"role": "reader",
|
||||
"path": "/api/gre/tunnels",
|
||||
"status": 200,
|
||||
"pskExposed": true,
|
||||
"configuredStatePresent": true,
|
||||
"plainStateNull": true
|
||||
},
|
||||
{
|
||||
"role": "reader",
|
||||
"path": "/api/filters/gre-tunnels",
|
||||
"status": 200,
|
||||
"pskExposed": false,
|
||||
"configuredStatePresent": false,
|
||||
"plainStateNull": true
|
||||
},
|
||||
{
|
||||
"role": "filter-writer",
|
||||
"path": "/api/gre/tunnels",
|
||||
"status": 200,
|
||||
"pskExposed": true,
|
||||
"configuredStatePresent": true,
|
||||
"plainStateNull": true
|
||||
},
|
||||
{
|
||||
"role": "filter-writer",
|
||||
"path": "/api/filters/gre-tunnels",
|
||||
"status": 200,
|
||||
"pskExposed": false,
|
||||
"configuredStatePresent": false,
|
||||
"plainStateNull": true
|
||||
},
|
||||
{
|
||||
"role": "network-writer",
|
||||
"path": "/api/gre/tunnels",
|
||||
"status": 200,
|
||||
"pskExposed": true,
|
||||
"configuredStatePresent": true,
|
||||
"plainStateNull": true
|
||||
},
|
||||
{
|
||||
"role": "network-writer",
|
||||
"path": "/api/filters/gre-tunnels",
|
||||
"status": 200,
|
||||
"pskExposed": false,
|
||||
"configuredStatePresent": false,
|
||||
"plainStateNull": true
|
||||
},
|
||||
{
|
||||
"role": "network-admin",
|
||||
"path": "/api/gre/tunnels",
|
||||
"status": 200,
|
||||
"pskExposed": true,
|
||||
"configuredStatePresent": true,
|
||||
"plainStateNull": true
|
||||
},
|
||||
{
|
||||
"role": "network-admin",
|
||||
"path": "/api/filters/gre-tunnels",
|
||||
"status": 200,
|
||||
"pskExposed": false,
|
||||
"configuredStatePresent": false,
|
||||
"plainStateNull": true
|
||||
},
|
||||
{
|
||||
"role": "is-admin-only",
|
||||
"path": "/api/gre/tunnels",
|
||||
"status": 200,
|
||||
"pskExposed": true,
|
||||
"configuredStatePresent": true,
|
||||
"plainStateNull": true
|
||||
},
|
||||
{
|
||||
"role": "is-admin-only",
|
||||
"path": "/api/filters/gre-tunnels",
|
||||
"status": 200,
|
||||
"pskExposed": false,
|
||||
"configuredStatePresent": false,
|
||||
"plainStateNull": true
|
||||
},
|
||||
{
|
||||
"role": "unauthenticated",
|
||||
"path": "/api/gre/tunnels",
|
||||
"status": 401
|
||||
},
|
||||
{
|
||||
"role": "unauthenticated",
|
||||
"path": "/api/filters/gre-tunnels",
|
||||
"status": 401
|
||||
}
|
||||
],
|
||||
"scope": "Production compiled GRE/Filters GET and auth with own restricted PostgreSQL, local native HTTP fixture, synthetic nonempty PSK and isolated signed JWT",
|
||||
"passed": true,
|
||||
"internalSnapshotRetainsPsk": true,
|
||||
"nativeWrites": 0,
|
||||
"databaseAndRoleRemoved": true
|
||||
}
|
||||
@@ -0,0 +1,35 @@
|
||||
{
|
||||
"date": "2026-10-13",
|
||||
"block": "12.5.209",
|
||||
"runtime": "ux-gre209",
|
||||
"services": {
|
||||
"backend": {
|
||||
"image": "mmapp-test/backend:ux-gre209",
|
||||
"imageId": "sha256:5324663c72cc559354d09538aaed115bd3dc08f653d53e553223898c2ed06baf",
|
||||
"running": true,
|
||||
"health": "healthy"
|
||||
},
|
||||
"frontend": {
|
||||
"image": "mmapp-test/frontend:ux-gre209",
|
||||
"imageId": "sha256:30d7d3886c0b531bd8119337d156e80f7348f0dfe12e75db632ee59483310b28",
|
||||
"running": true,
|
||||
"health": null
|
||||
}
|
||||
},
|
||||
"rollbackTags": {
|
||||
"MMAPP_IMAGE_TAG": "ux-native208",
|
||||
"BACKEND_IMAGE_TAG": "ux-native208"
|
||||
},
|
||||
"chrPasswordsChanged": false,
|
||||
"source": [
|
||||
{
|
||||
"kind": "backend",
|
||||
"matched": 473
|
||||
},
|
||||
{
|
||||
"kind": "frontend",
|
||||
"matched": 527
|
||||
}
|
||||
],
|
||||
"compiledMatched": 1048
|
||||
}
|
||||
@@ -0,0 +1,15 @@
|
||||
{
|
||||
"date": "2026-10-13",
|
||||
"block": "12.5.209",
|
||||
"stats": {
|
||||
"startTime": "2026-10-13T13:29:15.534Z",
|
||||
"duration": 13684.177,
|
||||
"expected": 4,
|
||||
"skipped": 0,
|
||||
"unexpected": 0,
|
||||
"flaky": 0
|
||||
},
|
||||
"scope": "Masked GRE PSK export on 1440/320 and existing PSK edit/clear API fixtures",
|
||||
"apiMocked": true,
|
||||
"uniqueCases": 4
|
||||
}
|
||||
@@ -0,0 +1,103 @@
|
||||
{
|
||||
"date": "2026-10-13",
|
||||
"block": "12.5.209",
|
||||
"database": "mm_accept_166_1791898793107",
|
||||
"baseline": false,
|
||||
"cases": [
|
||||
{
|
||||
"role": "reader",
|
||||
"path": "/api/gre/tunnels",
|
||||
"status": 200,
|
||||
"pskExposed": false,
|
||||
"configuredStatePresent": true,
|
||||
"plainStateNull": true
|
||||
},
|
||||
{
|
||||
"role": "reader",
|
||||
"path": "/api/filters/gre-tunnels",
|
||||
"status": 200,
|
||||
"pskExposed": false,
|
||||
"configuredStatePresent": true,
|
||||
"plainStateNull": true
|
||||
},
|
||||
{
|
||||
"role": "filter-writer",
|
||||
"path": "/api/gre/tunnels",
|
||||
"status": 200,
|
||||
"pskExposed": false,
|
||||
"configuredStatePresent": true,
|
||||
"plainStateNull": true
|
||||
},
|
||||
{
|
||||
"role": "filter-writer",
|
||||
"path": "/api/filters/gre-tunnels",
|
||||
"status": 200,
|
||||
"pskExposed": false,
|
||||
"configuredStatePresent": true,
|
||||
"plainStateNull": true
|
||||
},
|
||||
{
|
||||
"role": "network-writer",
|
||||
"path": "/api/gre/tunnels",
|
||||
"status": 200,
|
||||
"pskExposed": true,
|
||||
"configuredStatePresent": true,
|
||||
"plainStateNull": true
|
||||
},
|
||||
{
|
||||
"role": "network-writer",
|
||||
"path": "/api/filters/gre-tunnels",
|
||||
"status": 200,
|
||||
"pskExposed": false,
|
||||
"configuredStatePresent": true,
|
||||
"plainStateNull": true
|
||||
},
|
||||
{
|
||||
"role": "network-admin",
|
||||
"path": "/api/gre/tunnels",
|
||||
"status": 200,
|
||||
"pskExposed": true,
|
||||
"configuredStatePresent": true,
|
||||
"plainStateNull": true
|
||||
},
|
||||
{
|
||||
"role": "network-admin",
|
||||
"path": "/api/filters/gre-tunnels",
|
||||
"status": 200,
|
||||
"pskExposed": false,
|
||||
"configuredStatePresent": true,
|
||||
"plainStateNull": true
|
||||
},
|
||||
{
|
||||
"role": "is-admin-only",
|
||||
"path": "/api/gre/tunnels",
|
||||
"status": 200,
|
||||
"pskExposed": false,
|
||||
"configuredStatePresent": true,
|
||||
"plainStateNull": true
|
||||
},
|
||||
{
|
||||
"role": "is-admin-only",
|
||||
"path": "/api/filters/gre-tunnels",
|
||||
"status": 200,
|
||||
"pskExposed": false,
|
||||
"configuredStatePresent": true,
|
||||
"plainStateNull": true
|
||||
},
|
||||
{
|
||||
"role": "unauthenticated",
|
||||
"path": "/api/gre/tunnels",
|
||||
"status": 401
|
||||
},
|
||||
{
|
||||
"role": "unauthenticated",
|
||||
"path": "/api/filters/gre-tunnels",
|
||||
"status": 401
|
||||
}
|
||||
],
|
||||
"scope": "Production compiled GRE/Filters GET and auth with own restricted PostgreSQL, local native HTTP fixture, synthetic nonempty PSK and isolated signed JWT",
|
||||
"passed": true,
|
||||
"internalSnapshotRetainsPsk": true,
|
||||
"nativeWrites": 0,
|
||||
"databaseAndRoleRemoved": true
|
||||
}
|
||||
@@ -0,0 +1,69 @@
|
||||
{
|
||||
"date": "2026-10-13",
|
||||
"block": "12.5.209",
|
||||
"runtime": "ux-gre209",
|
||||
"cases": [
|
||||
{
|
||||
"host": "194.226.121.150",
|
||||
"createdDisabled": true,
|
||||
"adminSecretRetained": true,
|
||||
"readerSecretRedacted": true,
|
||||
"catalogConfiguredStateRetained": true,
|
||||
"catalogKeyAbsent": true,
|
||||
"dataPlaneTest": false
|
||||
},
|
||||
{
|
||||
"host": "104.165.244.7",
|
||||
"createdDisabled": true,
|
||||
"adminSecretRetained": true,
|
||||
"readerSecretRedacted": true,
|
||||
"catalogConfiguredStateRetained": true,
|
||||
"catalogKeyAbsent": true,
|
||||
"dataPlaneTest": false
|
||||
}
|
||||
],
|
||||
"uiCases": [
|
||||
{
|
||||
"width": 1440,
|
||||
"role": "reader",
|
||||
"actualNativeData": true,
|
||||
"templateLabel": true,
|
||||
"keyMaterialPublished": false,
|
||||
"mutationRequests": 0,
|
||||
"pageErrors": 0
|
||||
},
|
||||
{
|
||||
"width": 1440,
|
||||
"role": "admin",
|
||||
"actualNativeData": true,
|
||||
"templateLabel": false,
|
||||
"keyMaterialPublished": false,
|
||||
"mutationRequests": 0,
|
||||
"pageErrors": 0
|
||||
},
|
||||
{
|
||||
"width": 320,
|
||||
"role": "reader",
|
||||
"actualNativeData": true,
|
||||
"templateLabel": true,
|
||||
"keyMaterialPublished": false,
|
||||
"mutationRequests": 0,
|
||||
"pageErrors": 0
|
||||
},
|
||||
{
|
||||
"width": 320,
|
||||
"role": "admin",
|
||||
"actualNativeData": true,
|
||||
"templateLabel": false,
|
||||
"keyMaterialPublished": false,
|
||||
"mutationRequests": 0,
|
||||
"pageErrors": 0
|
||||
}
|
||||
],
|
||||
"apiMocks": false,
|
||||
"realPortalJWT": true,
|
||||
"privateMaterialPublished": false,
|
||||
"cleanupCompleted": true,
|
||||
"scope": "Disabled owned native GRE interfaces and PSK read policy; no encryption/data-plane claim",
|
||||
"ownPortalUserRemoved": true
|
||||
}
|
||||
@@ -0,0 +1,11 @@
|
||||
{
|
||||
"date": "2026-10-13",
|
||||
"block": "12.5.209",
|
||||
"command": "npm --prefix backend run test:live-maps",
|
||||
"passed": true,
|
||||
"location": "local development dependencies",
|
||||
"externalNativeDevices": false,
|
||||
"frontendTypecheckPassed": true,
|
||||
"backendBuildPassed": true,
|
||||
"eslintErrors": 0
|
||||
}
|
||||
@@ -0,0 +1,14 @@
|
||||
{
|
||||
"date": "2026-10-13",
|
||||
"block": "12.5.209",
|
||||
"kinds": [
|
||||
{
|
||||
"kind": "backend",
|
||||
"matched": 473
|
||||
},
|
||||
{
|
||||
"kind": "frontend",
|
||||
"matched": 527
|
||||
}
|
||||
]
|
||||
}
|
||||
Reference in new issue
Block a user