fix(auth): восстанавливать раздел и фильтры после входа Portal

This commit is contained in:
Denozordec committed 2026-10-13 16:09:27 +07:00
1 parent 199910eceb
commit 46de87e213
15 files changed
+275 -17

No files matched your search

+20 -2
View File
@@ -1,6 +1,6 @@
# UX/UI: протокол внешней приёмки 12.5
Актуальное продолжение 2026-10-13: блок198 — actual expired JWT401, reissue role changes, logout boundary и live expired recovery ПК/телефон приняты. Первый внешний return_to и browser logout passed; остальные два return_to ограничены подтверждённым429 Portal. Runtime ux-peak196. Следующий199 — сохранить исходный раздел/параметры после SSO;12.5 открыта.
Актуальное продолжение 2026-10-13: завершён199 — SSO сохраняет исходный разрешённый раздел/query; unit/typecheck/ESLint,12 E2E и2 live expired recovery passed. Frontend ux-portal199/backend ux-peak196, Portal1.3.1. Оставшиеся return_to199 приняты после коррекции тестового URL. Следующий200 — crash/lock-loss traffic collector; диагностическая граница цельного Telegram197 сохраняется.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,7 +696,7 @@ flowchart LR
## 12.5.77 — основной блок IPsec (2026-10-09)
Актуальное продолжение 2026-10-13: блок198 — actual expired JWT401, reissue role changes, logout boundary и live expired recovery ПК/телефон приняты. Первый внешний return_to и browser logout passed; остальные два return_to ограничены подтверждённым429 Portal. Runtime ux-peak196. Следующий199 — сохранить исходный раздел/параметры после SSO;12.5 открыта.
Актуальное продолжение 2026-10-13: завершён199 — SSO сохраняет исходный разрешённый раздел/query; unit/typecheck/ESLint,12 E2E и2 live expired recovery passed. Frontend ux-portal199/backend ux-peak196, Portal1.3.1. Оставшиеся return_to199 приняты после коррекции тестового URL. Следующий200 — crash/lock-loss traffic collector; диагностическая граница цельного Telegram197 сохраняется.12.5 открыта.
Подробный объём, протоколы, схема и ограничения: [12.5.77 в журнале](ux-ui-progress.md).
@@ -2414,3 +2414,21 @@ Live UI1440/320 с настоящим expired JWT: MM очистил mmapp_token
Протоколы: [actual lifecycle API](ux-ui/acceptance/portal198-lifecycle-2026-10-13.json), [live UI и границы429](ux-ui/acceptance/portal198-live-ui-2026-10-13.json).
Следующий199: восстановить исходный same-origin раздел и query после SSO с проверкой permissions и запретом внешних/auth callback redirect. Затем профильные E2E/deploy и два оставшихся Portal return_to.12.5 открыта.
## 12.5.199 — восстановление раздела и параметров после SSO (2026-10-13)
Из198 подтверждено: expired session на /servers попадала после login в /dashboard. redirectToPortalLogin теперь добавляет исходный pathname+query в next callback URL. AuthCallbackPage после valid claims выбирает permittedAuthReturnPath и проверяет существующее permissionForPath/can; недопустимый путь или недостаточные права используют firstAllowedPath. При повторном handoff next сохраняется. JWT fragment не включается в сохранённый путь.
Новый pure helper отклоняет внешние/protocol-relative URL, backslash/control/space, слишком длинный путь, auth/api/access-denied loop, нормализованный dot traversal вauth и percent-encoded pathname. Query, включая percent-encoded filter values, сохраняется; hash удаляется. Консервативное ограничение касается pathname: приложение использует обычные фиксированные пути/ID; percent-encoded pathname не восстанавливается, выбирается fallback. Это не расширение существующей карты permissions и не замена backend RBAC.
Unit unsafe/normalization/query/permissions passed, frontend TypeScript и scoped ESLint passed.12 unique E2E/24971ms/0unexpected:10 query/denied/external/auth-loop/handoff cases1440/320 и2 runtime Portal links. Это fixtures, не реальные подписи Portal. Отдельно production frontend ux-portal199 собран и развёрнут,527 source files совпали перед build. Backend ux-peak196/Portal1.3.1/AUTH_REQUIRED=true сохранены.2 live UI с настоящим naturally expired JWT и login Portal1440/320 восстановили /servers?server=42&tab=details, fragment удалён, errors/overflow нет. CHR/native config и backend не менялись, новых Telegram sends нет.
Оставшиеся return_to198 проверены адресно: http://localhost:3001/auth/callback и http://localhost.evil.invalid:3000/auth/callback не вызывают external navigation, Portal остаётся /admin. Browser logout очищает storage. Предыдущий lookalike URL в драйвере был синтаксически ошибочным (порт3000.evil.invalid), поэтому login form отсутствовала; это исправлено в тесте. Подтверждённый429198 сохраняется в историческом протоколе, но не объявляется причиной этого отдельного malformed-URL сбоя. Повторные full cycles прекращены; реальные endpoints не mock. Доверенные allowlist origins сохранены.
Протоколы: [E2E12](ux-ui/acceptance/portal199-e2e-2026-10-13.json), [deployment](ux-ui/acceptance/portal199-deployment-2026-10-13.json), [actual expired recovery2](ux-ui/acceptance/portal199-live-ui-2026-10-13.json), [remaining return_to](ux-ui/acceptance/portal199-return-to-2026-10-13.json).
| Референс | Схема |
| --- | --- |
| [ReUI App Shell12](https://reui.io/preview/base/app-shell-12?ref=mcp) | Раздел + фильтры → expired session → Portal → callback с проверкой прав → тот же раздел + фильтры |
Следующий200: owned PostgreSQL/child-process crash и advisory-lock loss traffic collector. Цельный непрерывный Telegram live197 остаётся отдельно с исходным failed evidence; успешные chunk tests не отменяют его. Logout не отозвал offlineJWT доexp, publicIPv6/clientOS/independentWAN/scale остаются внешними ограничениями.12.5 открыта.
+3 -3
View File
@@ -1,12 +1,12 @@
# План реализации UX/UI по пятичасовым окнам
Актуальное продолжение 2026-10-13: блок198 — actual expired JWT401, reissue role changes, logout boundary и live expired recovery ПК/телефон приняты. Первый внешний return_to и browser logout passed; остальные два return_to ограничены подтверждённым429 Portal. Runtime ux-peak196. Следующий199 — сохранить исходный раздел/параметры после SSO;12.5 открыта.
Актуальное продолжение 2026-10-13: завершён199 — SSO сохраняет исходный разрешённый раздел/query; unit/typecheck/ESLint,12 E2E и2 live expired recovery passed. Frontend ux-portal199/backend ux-peak196, Portal1.3.1. Оставшиеся return_to199 приняты после коррекции тестового URL. Следующий200 — crash/lock-loss traffic collector; диагностическая граница цельного Telegram197 сохраняется.12.5 открыта.
Общий план проекта MikrotikManager. Основан на согласованном плане из задачи; точка продолжения обновлена 2026-10-13. Источник фактического прогресса, проверок и ограничений — [журнал реализации](ux-ui-progress.md). Этот документ задаёт объём и критерии завершения, журнал фиксирует результат.
## Актуальная точка продолжения — 2026-10-13
Актуальное продолжение 2026-10-13: блок198 — actual expired JWT401, reissue role changes, logout boundary и live expired recovery ПК/телефон приняты. Первый внешний return_to и browser logout passed; остальные два return_to ограничены подтверждённым429 Portal. Runtime ux-peak196. Следующий199 — сохранить исходный раздел/параметры после SSO;12.5 открыта.
Актуальное продолжение 2026-10-13: завершён199 — SSO сохраняет исходный разрешённый раздел/query; unit/typecheck/ESLint,12 E2E и2 live expired recovery passed. Frontend ux-portal199/backend ux-peak196, Portal1.3.1. Оставшиеся return_to199 приняты после коррекции тестового URL. Следующий200 — crash/lock-loss traffic collector; диагностическая граница цельного Telegram197 сохраняется.12.5 открыта.
Этапы0–11 завершены в локальных границах журнала. История выполненных внешних блоков и доказательства сохранены в [журнале](ux-ui-stage-12.md) и [протоколе](ux-ui-external-acceptance.md). Реальная Telegram доставка, Portal SSO, multi-instance и оставшиеся профильные сетевые ограничения открыты.
@@ -371,6 +371,6 @@ flowchart LR
## 12.5.77 — основной блок IPsec (2026-10-09)
Актуальное продолжение 2026-10-13: блок198 — actual expired JWT401, reissue role changes, logout boundary и live expired recovery ПК/телефон приняты. Первый внешний return_to и browser logout passed; остальные два return_to ограничены подтверждённым429 Portal. Runtime ux-peak196. Следующий199 — сохранить исходный раздел/параметры после SSO;12.5 открыта.
Актуальное продолжение 2026-10-13: завершён199 — SSO сохраняет исходный разрешённый раздел/query; unit/typecheck/ESLint,12 E2E и2 live expired recovery passed. Frontend ux-portal199/backend ux-peak196, Portal1.3.1. Оставшиеся return_to199 приняты после коррекции тестового URL. Следующий200 — crash/lock-loss traffic collector; диагностическая граница цельного Telegram197 сохраняется.12.5 открыта.
Подробный объём, протоколы, схема и ограничения: [12.5.77 в журнале](ux-ui-progress.md).
+19 -1
View File
@@ -1,6 +1,6 @@
# UX/UI: журнал реализации
Актуальное продолжение 2026-10-13: блок198 — actual expired JWT401, reissue role changes, logout boundary и live expired recovery ПК/телефон приняты. Первый внешний return_to и browser logout passed; остальные два return_to ограничены подтверждённым429 Portal. Runtime ux-peak196. Следующий199 — сохранить исходный раздел/параметры после SSO;12.5 открыта.
Актуальное продолжение 2026-10-13: завершён199 — SSO сохраняет исходный разрешённый раздел/query; unit/typecheck/ESLint,12 E2E и2 live expired recovery passed. Frontend ux-portal199/backend ux-peak196, Portal1.3.1. Оставшиеся return_to199 приняты после коррекции тестового URL. Следующий200 — crash/lock-loss traffic collector; диагностическая граница цельного Telegram197 сохраняется.12.5 открыта.
Общий план: [UX/UI по этапам и пятичасовым окнам](ux-ui-plan.md). План задаёт объём, этот журнал фиксирует выполненные блоки и ограничения. Записи расположены от новых к старым; подробная история этапа12 также сохранена в [ux-ui-stage-12.md](ux-ui-stage-12.md).
@@ -38,6 +38,24 @@
| 11Б | Оповещения, сбор данных, интеграции, релизы и настройки | Завершён в границах локальной приёмки 2026-10-03; ограничения и evidence в11Б.7 |
| 12 | Итоговая доступность, адаптивность, производительность и регрессия | Локальная приёмка завершена в границах12.3.83; внешняя12.5 в работе, выполненные блоки1–196 и ограничения ниже. Runtime backend/frontend ux-peak196. |
## 12.5.199 — восстановление раздела и параметров после SSO (2026-10-13)
Из198 подтверждено: expired session на /servers попадала после login в /dashboard. redirectToPortalLogin теперь добавляет исходный pathname+query в next callback URL. AuthCallbackPage после valid claims выбирает permittedAuthReturnPath и проверяет существующее permissionForPath/can; недопустимый путь или недостаточные права используют firstAllowedPath. При повторном handoff next сохраняется. JWT fragment не включается в сохранённый путь.
Новый pure helper отклоняет внешние/protocol-relative URL, backslash/control/space, слишком длинный путь, auth/api/access-denied loop, нормализованный dot traversal вauth и percent-encoded pathname. Query, включая percent-encoded filter values, сохраняется; hash удаляется. Консервативное ограничение касается pathname: приложение использует обычные фиксированные пути/ID; percent-encoded pathname не восстанавливается, выбирается fallback. Это не расширение существующей карты permissions и не замена backend RBAC.
Unit unsafe/normalization/query/permissions passed, frontend TypeScript и scoped ESLint passed.12 unique E2E/24971ms/0unexpected:10 query/denied/external/auth-loop/handoff cases1440/320 и2 runtime Portal links. Это fixtures, не реальные подписи Portal. Отдельно production frontend ux-portal199 собран и развёрнут,527 source files совпали перед build. Backend ux-peak196/Portal1.3.1/AUTH_REQUIRED=true сохранены.2 live UI с настоящим naturally expired JWT и login Portal1440/320 восстановили /servers?server=42&tab=details, fragment удалён, errors/overflow нет. CHR/native config и backend не менялись, новых Telegram sends нет.
Оставшиеся return_to198 проверены адресно: http://localhost:3001/auth/callback и http://localhost.evil.invalid:3000/auth/callback не вызывают external navigation, Portal остаётся /admin. Browser logout очищает storage. Предыдущий lookalike URL в драйвере был синтаксически ошибочным (порт3000.evil.invalid), поэтому login form отсутствовала; это исправлено в тесте. Подтверждённый429198 сохраняется в историческом протоколе, но не объявляется причиной этого отдельного malformed-URL сбоя. Повторные full cycles прекращены; реальные endpoints не mock. Доверенные allowlist origins сохранены.
Протоколы: [E2E12](ux-ui/acceptance/portal199-e2e-2026-10-13.json), [deployment](ux-ui/acceptance/portal199-deployment-2026-10-13.json), [actual expired recovery2](ux-ui/acceptance/portal199-live-ui-2026-10-13.json), [remaining return_to](ux-ui/acceptance/portal199-return-to-2026-10-13.json).
| Референс | Схема |
| --- | --- |
| [ReUI App Shell12](https://reui.io/preview/base/app-shell-12?ref=mcp) | Раздел + фильтры → expired session → Portal → callback с проверкой прав → тот же раздел + фильтры |
Следующий200: owned PostgreSQL/child-process crash и advisory-lock loss traffic collector. Цельный непрерывный Telegram live197 остаётся отдельно с исходным failed evidence; успешные chunk tests не отменяют его. Logout не отозвал offlineJWT доexp, publicIPv6/clientOS/independentWAN/scale остаются внешними ограничениями.12.5 открыта.
## 12.5.198 — срок действия Portal JWT, права и выход (2026-10-13)
Использован настоящий JWT, выданный Portal в195 и естественно истёкший к проверке: MM GET servers401, Portal me401 и reissue401. Токен не редактировался и TTL не менялся. На собственном временном reader через документированный PUT /api/v1/admin/users/:id/access удалён доступmm: прежний JWT по-прежнему200 доexp, reissue200 выдаёт текущие claims и новый MM JWT403. Возвращённый доступ и новый reissue восстановили200. Первый неверно адресованный PATCH в диагностическом драйвере был исправлен на PUT/access; изменение source продукта не требовалось. User fixture удалён204.
+21 -3
View File
@@ -1,8 +1,8 @@
# Оставшаяся внешняя приёмка — 2026-10-13
Актуальное продолжение 2026-10-13: блок198 — actual expired JWT401, reissue role changes, logout boundary и live expired recovery ПК/телефон приняты. Первый внешний return_to и browser logout passed; остальные два return_to ограничены подтверждённым429 Portal. Runtime ux-peak196. Следующий199 — сохранить исходный раздел/параметры после SSO;12.5 открыта.
Актуальное продолжение 2026-10-13: завершён199 — SSO сохраняет исходный разрешённый раздел/query; unit/typecheck/ESLint,12 E2E и2 live expired recovery passed. Frontend ux-portal199/backend ux-peak196, Portal1.3.1. Оставшиеся return_to199 приняты после коррекции тестового URL. Следующий200 — crash/lock-loss traffic collector; диагностическая граница цельного Telegram197 сохраняется.12.5 открыта.
Это актуальная матрица после 12.5.198. Исторические записи сохраняют версии и ограничения на момент выполнения; поздние проверки ниже уточняют их. Этап 12.5 открыт. Успех в двух CHR и одном backend не означает приёмку всех конфигураций, интеграций или полной регрессии.
Это актуальная матрица после 12.5.199. Исторические записи сохраняют версии и ограничения на момент выполнения; поздние проверки ниже уточняют их. Этап 12.5 открыт. Успех в двух CHR и одном backend не означает приёмку всех конфигураций, интеграций или полной регрессии.
Стенд: Debian13/Compose, PostgreSQL18.6, два CHR RouterOS7.24.5. Backend/frontend `ux-peak196`; 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. **199 — SSO context:** сохранить исходный разрешённый раздел/query после login, запретить внешние/auth callback redirect. Затем scoped deploy и два return_to, ограниченные429 в198.
1. **200 — crash/lock-loss collector:** собственная ограниченная БД и процессы, без остановки production PG или native CHR. Telegram197 whole-live failure остаётся отдельной диагностической границей.
2. **Профильный контроль:** для новых изменений выполнять затронутые SQL/API/UI проверки. Общая регрессия192 выполнена; не повторять её без изменений общей основы или нового основания.
3. **Внешние зависимости:** Portal issuer/login/revoke, Telegram bot/chat/разрешённое сообщение, клиентские ОС, независимые WAN/public IPv6 и scale/multi-instance — отдельные группы по таблице выше. Ограничения текущего стенда не превращать в обещание приёмки всех конфигураций.
@@ -1330,3 +1330,21 @@ Live UI1440/320 с настоящим expired JWT: MM очистил mmapp_token
Протоколы: [actual lifecycle API](ux-ui/acceptance/portal198-lifecycle-2026-10-13.json), [live UI и границы429](ux-ui/acceptance/portal198-live-ui-2026-10-13.json).
Следующий199: восстановить исходный same-origin раздел и query после SSO с проверкой permissions и запретом внешних/auth callback redirect. Затем профильные E2E/deploy и два оставшихся Portal return_to.12.5 открыта.
## 12.5.199 — восстановление раздела и параметров после SSO (2026-10-13)
Из198 подтверждено: expired session на /servers попадала после login в /dashboard. redirectToPortalLogin теперь добавляет исходный pathname+query в next callback URL. AuthCallbackPage после valid claims выбирает permittedAuthReturnPath и проверяет существующее permissionForPath/can; недопустимый путь или недостаточные права используют firstAllowedPath. При повторном handoff next сохраняется. JWT fragment не включается в сохранённый путь.
Новый pure helper отклоняет внешние/protocol-relative URL, backslash/control/space, слишком длинный путь, auth/api/access-denied loop, нормализованный dot traversal вauth и percent-encoded pathname. Query, включая percent-encoded filter values, сохраняется; hash удаляется. Консервативное ограничение касается pathname: приложение использует обычные фиксированные пути/ID; percent-encoded pathname не восстанавливается, выбирается fallback. Это не расширение существующей карты permissions и не замена backend RBAC.
Unit unsafe/normalization/query/permissions passed, frontend TypeScript и scoped ESLint passed.12 unique E2E/24971ms/0unexpected:10 query/denied/external/auth-loop/handoff cases1440/320 и2 runtime Portal links. Это fixtures, не реальные подписи Portal. Отдельно production frontend ux-portal199 собран и развёрнут,527 source files совпали перед build. Backend ux-peak196/Portal1.3.1/AUTH_REQUIRED=true сохранены.2 live UI с настоящим naturally expired JWT и login Portal1440/320 восстановили /servers?server=42&tab=details, fragment удалён, errors/overflow нет. CHR/native config и backend не менялись, новых Telegram sends нет.
Оставшиеся return_to198 проверены адресно: http://localhost:3001/auth/callback и http://localhost.evil.invalid:3000/auth/callback не вызывают external navigation, Portal остаётся /admin. Browser logout очищает storage. Предыдущий lookalike URL в драйвере был синтаксически ошибочным (порт3000.evil.invalid), поэтому login form отсутствовала; это исправлено в тесте. Подтверждённый429198 сохраняется в историческом протоколе, но не объявляется причиной этого отдельного malformed-URL сбоя. Повторные full cycles прекращены; реальные endpoints не mock. Доверенные allowlist origins сохранены.
Протоколы: [E2E12](ux-ui/acceptance/portal199-e2e-2026-10-13.json), [deployment](ux-ui/acceptance/portal199-deployment-2026-10-13.json), [actual expired recovery2](ux-ui/acceptance/portal199-live-ui-2026-10-13.json), [remaining return_to](ux-ui/acceptance/portal199-return-to-2026-10-13.json).
| Референс | Схема |
| --- | --- |
| [ReUI App Shell12](https://reui.io/preview/base/app-shell-12?ref=mcp) | Раздел + фильтры → expired session → Portal → callback с проверкой прав → тот же раздел + фильтры |
Следующий200: owned PostgreSQL/child-process crash и advisory-lock loss traffic collector. Цельный непрерывный Telegram live197 остаётся отдельно с исходным failed evidence; успешные chunk tests не отменяют его. Logout не отозвал offlineJWT доexp, publicIPv6/clientOS/independentWAN/scale остаются внешними ограничениями.12.5 открыта.
+19 -1
View File
@@ -1,6 +1,6 @@
# Этап 12: итоговая приёмка UX/UI
Актуальное продолжение 2026-10-13: блок198 — actual expired JWT401, reissue role changes, logout boundary и live expired recovery ПК/телефон приняты. Первый внешний return_to и browser logout passed; остальные два return_to ограничены подтверждённым429 Portal. Runtime ux-peak196. Следующий199 — сохранить исходный раздел/параметры после SSO;12.5 открыта.
Актуальное продолжение 2026-10-13: завершён199 — SSO сохраняет исходный разрешённый раздел/query; unit/typecheck/ESLint,12 E2E и2 live expired recovery passed. Frontend ux-portal199/backend ux-peak196, Portal1.3.1. Оставшиеся return_to199 приняты после коррекции тестового URL. Следующий200 — crash/lock-loss traffic collector; диагностическая граница цельного Telegram197 сохраняется.12.5 открыта.
План: [ux-ui-plan.md](ux-ui-plan.md). Фактические результаты: [ux-ui-progress.md](ux-ui-progress.md). Подготовлен после сводных проверок 11Б; завершение каждого блока требует локального коммита без push.
@@ -3719,3 +3719,21 @@ Live UI1440/320 с настоящим expired JWT: MM очистил mmapp_token
Протоколы: [actual lifecycle API](ux-ui/acceptance/portal198-lifecycle-2026-10-13.json), [live UI и границы429](ux-ui/acceptance/portal198-live-ui-2026-10-13.json).
Следующий199: восстановить исходный same-origin раздел и query после SSO с проверкой permissions и запретом внешних/auth callback redirect. Затем профильные E2E/deploy и два оставшихся Portal return_to.12.5 открыта.
## 12.5.199 — восстановление раздела и параметров после SSO (2026-10-13)
Из198 подтверждено: expired session на /servers попадала после login в /dashboard. redirectToPortalLogin теперь добавляет исходный pathname+query в next callback URL. AuthCallbackPage после valid claims выбирает permittedAuthReturnPath и проверяет существующее permissionForPath/can; недопустимый путь или недостаточные права используют firstAllowedPath. При повторном handoff next сохраняется. JWT fragment не включается в сохранённый путь.
Новый pure helper отклоняет внешние/protocol-relative URL, backslash/control/space, слишком длинный путь, auth/api/access-denied loop, нормализованный dot traversal вauth и percent-encoded pathname. Query, включая percent-encoded filter values, сохраняется; hash удаляется. Консервативное ограничение касается pathname: приложение использует обычные фиксированные пути/ID; percent-encoded pathname не восстанавливается, выбирается fallback. Это не расширение существующей карты permissions и не замена backend RBAC.
Unit unsafe/normalization/query/permissions passed, frontend TypeScript и scoped ESLint passed.12 unique E2E/24971ms/0unexpected:10 query/denied/external/auth-loop/handoff cases1440/320 и2 runtime Portal links. Это fixtures, не реальные подписи Portal. Отдельно production frontend ux-portal199 собран и развёрнут,527 source files совпали перед build. Backend ux-peak196/Portal1.3.1/AUTH_REQUIRED=true сохранены.2 live UI с настоящим naturally expired JWT и login Portal1440/320 восстановили /servers?server=42&tab=details, fragment удалён, errors/overflow нет. CHR/native config и backend не менялись, новых Telegram sends нет.
Оставшиеся return_to198 проверены адресно: http://localhost:3001/auth/callback и http://localhost.evil.invalid:3000/auth/callback не вызывают external navigation, Portal остаётся /admin. Browser logout очищает storage. Предыдущий lookalike URL в драйвере был синтаксически ошибочным (порт3000.evil.invalid), поэтому login form отсутствовала; это исправлено в тесте. Подтверждённый429198 сохраняется в историческом протоколе, но не объявляется причиной этого отдельного malformed-URL сбоя. Повторные full cycles прекращены; реальные endpoints не mock. Доверенные allowlist origins сохранены.
Протоколы: [E2E12](ux-ui/acceptance/portal199-e2e-2026-10-13.json), [deployment](ux-ui/acceptance/portal199-deployment-2026-10-13.json), [actual expired recovery2](ux-ui/acceptance/portal199-live-ui-2026-10-13.json), [remaining return_to](ux-ui/acceptance/portal199-return-to-2026-10-13.json).
| Референс | Схема |
| --- | --- |
| [ReUI App Shell12](https://reui.io/preview/base/app-shell-12?ref=mcp) | Раздел + фильтры → expired session → Portal → callback с проверкой прав → тот же раздел + фильтры |
Следующий200: owned PostgreSQL/child-process crash и advisory-lock loss traffic collector. Цельный непрерывный Telegram live197 остаётся отдельно с исходным failed evidence; успешные chunk tests не отменяют его. Logout не отозвал offlineJWT доexp, publicIPv6/clientOS/independentWAN/scale остаются внешними ограничениями.12.5 открыта.
+20 -2
View File
@@ -1,6 +1,6 @@
# Тестовый сервер UX/UI — 2026-10-10
Актуальное продолжение 2026-10-13: блок198 — actual expired JWT401, reissue role changes, logout boundary и live expired recovery ПК/телефон приняты. Первый внешний return_to и browser logout passed; остальные два return_to ограничены подтверждённым429 Portal. Runtime ux-peak196. Следующий199 — сохранить исходный раздел/параметры после SSO;12.5 открыта.
Актуальное продолжение 2026-10-13: завершён199 — SSO сохраняет исходный разрешённый раздел/query; unit/typecheck/ESLint,12 E2E и2 live expired recovery passed. Frontend ux-portal199/backend ux-peak196, Portal1.3.1. Оставшиеся return_to199 приняты после коррекции тестового URL. Следующий200 — crash/lock-loss traffic collector; диагностическая граница цельного Telegram197 сохраняется.12.5 открыта.
| Параметр | Проверенное состояние |
| --- | --- |
@@ -708,7 +708,7 @@ flowchart LR
## 12.5.77 — основной блок IPsec (2026-10-09)
Актуальное продолжение 2026-10-13: блок198 — actual expired JWT401, reissue role changes, logout boundary и live expired recovery ПК/телефон приняты. Первый внешний return_to и browser logout passed; остальные два return_to ограничены подтверждённым429 Portal. Runtime ux-peak196. Следующий199 — сохранить исходный раздел/параметры после SSO;12.5 открыта.
Актуальное продолжение 2026-10-13: завершён199 — SSO сохраняет исходный разрешённый раздел/query; unit/typecheck/ESLint,12 E2E и2 live expired recovery passed. Frontend ux-portal199/backend ux-peak196, Portal1.3.1. Оставшиеся return_to199 приняты после коррекции тестового URL. Следующий200 — crash/lock-loss traffic collector; диагностическая граница цельного Telegram197 сохраняется.12.5 открыта.
Подробный объём, протоколы, схема и ограничения: [12.5.77 в журнале](ux-ui-progress.md).
@@ -2145,3 +2145,21 @@ Live UI1440/320 с настоящим expired JWT: MM очистил mmapp_token
Протоколы: [actual lifecycle API](ux-ui/acceptance/portal198-lifecycle-2026-10-13.json), [live UI и границы429](ux-ui/acceptance/portal198-live-ui-2026-10-13.json).
Следующий199: восстановить исходный same-origin раздел и query после SSO с проверкой permissions и запретом внешних/auth callback redirect. Затем профильные E2E/deploy и два оставшихся Portal return_to.12.5 открыта.
## 12.5.199 — восстановление раздела и параметров после SSO (2026-10-13)
Из198 подтверждено: expired session на /servers попадала после login в /dashboard. redirectToPortalLogin теперь добавляет исходный pathname+query в next callback URL. AuthCallbackPage после valid claims выбирает permittedAuthReturnPath и проверяет существующее permissionForPath/can; недопустимый путь или недостаточные права используют firstAllowedPath. При повторном handoff next сохраняется. JWT fragment не включается в сохранённый путь.
Новый pure helper отклоняет внешние/protocol-relative URL, backslash/control/space, слишком длинный путь, auth/api/access-denied loop, нормализованный dot traversal вauth и percent-encoded pathname. Query, включая percent-encoded filter values, сохраняется; hash удаляется. Консервативное ограничение касается pathname: приложение использует обычные фиксированные пути/ID; percent-encoded pathname не восстанавливается, выбирается fallback. Это не расширение существующей карты permissions и не замена backend RBAC.
Unit unsafe/normalization/query/permissions passed, frontend TypeScript и scoped ESLint passed.12 unique E2E/24971ms/0unexpected:10 query/denied/external/auth-loop/handoff cases1440/320 и2 runtime Portal links. Это fixtures, не реальные подписи Portal. Отдельно production frontend ux-portal199 собран и развёрнут,527 source files совпали перед build. Backend ux-peak196/Portal1.3.1/AUTH_REQUIRED=true сохранены.2 live UI с настоящим naturally expired JWT и login Portal1440/320 восстановили /servers?server=42&tab=details, fragment удалён, errors/overflow нет. CHR/native config и backend не менялись, новых Telegram sends нет.
Оставшиеся return_to198 проверены адресно: http://localhost:3001/auth/callback и http://localhost.evil.invalid:3000/auth/callback не вызывают external navigation, Portal остаётся /admin. Browser logout очищает storage. Предыдущий lookalike URL в драйвере был синтаксически ошибочным (порт3000.evil.invalid), поэтому login form отсутствовала; это исправлено в тесте. Подтверждённый429198 сохраняется в историческом протоколе, но не объявляется причиной этого отдельного malformed-URL сбоя. Повторные full cycles прекращены; реальные endpoints не mock. Доверенные allowlist origins сохранены.
Протоколы: [E2E12](ux-ui/acceptance/portal199-e2e-2026-10-13.json), [deployment](ux-ui/acceptance/portal199-deployment-2026-10-13.json), [actual expired recovery2](ux-ui/acceptance/portal199-live-ui-2026-10-13.json), [remaining return_to](ux-ui/acceptance/portal199-return-to-2026-10-13.json).
| Референс | Схема |
| --- | --- |
| [ReUI App Shell12](https://reui.io/preview/base/app-shell-12?ref=mcp) | Раздел + фильтры → expired session → Portal → callback с проверкой прав → тот же раздел + фильтры |
Следующий200: owned PostgreSQL/child-process crash и advisory-lock loss traffic collector. Цельный непрерывный Telegram live197 остаётся отдельно с исходным failed evidence; успешные chunk tests не отменяют его. Logout не отозвал offlineJWT доexp, publicIPv6/clientOS/independentWAN/scale остаются внешними ограничениями.12.5 открыта.
@@ -0,0 +1,14 @@
{
"date": "2026-10-13",
"block": "12.5.199",
"sourceFilesMatched": 527,
"sourceHashAlgorithm": "sha256 raw bytes before Docker build",
"productionBuildPassed": true,
"frontendImage": "mmapp-test/frontend:ux-portal199",
"frontendImageId": "sha256:d3041db1ab0443211bc65bbe819438b9c9647763421fb7fe0dddae786c943cbe4",
"backendImage": "mmapp-test/backend:ux-peak196",
"rollbackFrontendTag": "ux-peak196",
"portalVersion": "1.3.1",
"authRequired": true,
"scope": "Only frontend image tag changed; actual expired session SSO UI tested separately"
}
@@ -0,0 +1,14 @@
{
"date": "2026-10-13",
"block": "12.5.199",
"stats": {
"startTime": "2026-10-13T09:01:20.154Z",
"duration": 24970.957000000002,
"expected": 12,
"skipped": 0,
"unexpected": 0,
"flaky": 0
},
"errors": [],
"scope": "10 callback/query/permissions/unsafe target/handoff fixtures + 2 runtime link fixtures; not real Portal"
}
@@ -0,0 +1,36 @@
{
"date": "2026-10-13",
"block": "12.5.199",
"cases": [
{
"name": "expired token recovery",
"width": 1440,
"expiredMmTokenCleared": true,
"portalLogin": true,
"recoveredActualSso": true,
"landingPath": "/servers",
"originalPathRestored": true,
"noFragment": true,
"noOverflow": true,
"pageErrors": 0,
"restoredSearch": "?server=42&tab=details"
},
{
"name": "expired token recovery",
"width": 320,
"expiredMmTokenCleared": true,
"portalLogin": true,
"recoveredActualSso": true,
"landingPath": "/servers",
"originalPathRestored": true,
"noFragment": true,
"noOverflow": true,
"pageErrors": 0,
"restoredSearch": "?server=42&tab=details"
}
],
"realRuntime": true,
"apiMocks": false,
"blockedUnexpectedNavigationForSafety": true,
"serverWrites": 0
}
@@ -0,0 +1,32 @@
{
"date": "2026-10-13",
"block": "12.5.199",
"cases": [
{
"name": "disallowed return_to",
"target": "http://localhost:3001/auth/callback",
"externalNavigationAttempts": 0,
"portalStayed": true,
"apiMocks": false
},
{
"name": "disallowed return_to",
"target": "http://localhost.evil.invalid:3000/auth/callback",
"externalNavigationAttempts": 0,
"portalStayed": true,
"apiMocks": false
},
{
"name": "Portal browser logout",
"loginVisible": true,
"tokenStorageCleared": true
}
],
"realRuntime": true,
"apiMocks": false,
"blockedUnexpectedNavigationForSafety": true,
"serverWrites": 0,
"remaining": [],
"complete": true,
"limitation": "Previous lookalike target used an invalid port and could not render login; corrected syntactically valid hostname tested separately."
}