fix(mera/b2c): публичный лэндинг больше не показывает «Не удалось проверить доступ» #2910
No reviewers
Labels
No labels
Fable 5 ревью
GG-форсайт
admin
analytics
auth
automation
bug
business
chore
ci
compliance
data
data-moat
docs
duplicate
dx
enhancement
feedback/max
generative
needs-discussion
needs-human
observability
pause-bots
performance
priority/p0
priority/p1
priority/p2
priority/p3
scope/backend
scope/db
scope/devops
scope/frontend
scope/qa
scrapers
security
site-finder
stage/1
stage/2
status/blocked
status/done
status/needs-analysis
status/needs-fix
status/qa
status/ready
status/review
status/wip
tech-debt
tradein
ux
week ревью 1
wontfix
ИРД
вторичка
No milestone
No project
No assignees
1 participant
Notifications
Due date
No due date set.
Dependencies
No dependencies set.
Reference: lekss361/gendesign#2910
Loading…
Add table
Reference in a new issue
No description provided.
Delete branch "fix/mera-public-host-bypass"
Deleting a branch is permanent. Although the deleted branch may continue to exist for a short time before it actually gets removed, it CANNOT be undone in most cases. Continue?
Продовый баг, замеченный владельцем: внизу
meraocenka.ruпосетителю показывался экран проверки доступа из закрытого контура.Замер на живой странице:
Причина
Caddy на коротком домене переписывает путь внутренне (
rewrite, неredir): посетитель остаётся наmeraocenka.ru/, а Next получает/trade-in/mera-public. Поэтому на сервереusePathname()даёт/mera-publicи bypass срабатывает, а после гидратации клиент видит/— путь из адресной строки — и bypass молча отваливается. МонтируетсяGuardedRoute, летитGET /me, а на этом хосте Caddy намеренно не проксирует/trade-in/api/*→ 404 →NoAccessScreen. Отсюда и «внизу страницы»: ошибка появлялась после загрузки контента.Второй запрос (
support/anon/unread) — следствие того же: не сработал bypass, смонтировался закрытый контур со своим виджетом чата.В шапке
RouteGuardпрямо стояло допущение:Оно сломалось ровно в тот момент, когда домен появился. Заменено разбором факта, чтобы следующий читатель не унаследовал ту же ошибку.
Правка
Четыре коротких адреса публичного домена (
/,/oferta,/refund,/privacy) добавлены в bypass — точным совпадением, отдельной веткой.Префиксную проверку для
/применять нельзя:"/v2/admin".startsWith("/")истинно, то есть один такой элемент в списке сделал бы публичным всё приложение. Это главный риск правки, поэтому он закрыт тестом, а не комментарием.Адреса существуют только на публичном домене: на
gendsgn.ruих ловит catch-all 404, а/отдаёт server-side redirect на/v2изnext.config— приложение по этому пути не рендерится вовсе, bypass ему не достаётся.Проверено
Тест пинит оба инварианта: короткие адреса публичны И закрытый контур (
/v2,/admin/*,/history,/scrapers/*,/login) — нет. Мутация «точное совпадение → префиксное»:Плюс
vitest33 passed (7 файлов),tsc --noEmit, isolation guard 31 файл.Отдельно, не баг
Кнопка «Узнать цену» ничего не открывает намеренно:
PUBLIC_ESTIMATE_ENABLED = false, анонимный расчёт закрыт RBAC (#2895). Форма при этом не молчит — показывает блок «Расчёт по адресу мы ещё не открыли для всех». Вероятно, он терялся на фоне экрана ошибки; проверю на проде после выкатки.На meraocenka.ru посетитель видел внизу страницы экран проверки доступа из закрытого контура. Замер на проде: три вызова GET /trade-in/api/v1/me → 404 плюс подтянутый следом клиент чата поддержки. Причина. Caddy на коротком домене переписывает путь ВНУТРЕННЕ (rewrite, не redir): посетитель остаётся на meraocenka.ru/, а Next получает /trade-in/mera-public. Поэтому SSR видит /mera-public и bypass срабатывает, а после гидратации usePathname() возвращает «/» — путь из адресной строки — и bypass отваливается. Монтируется GuardedRoute, летит запрос к /me, а на этом хосте Caddy намеренно не проксирует /trade-in/api/* → 404 → NoAccessScreen. В шапке RouteGuard прямо стояло допущение «домен/rewrite настраиваются отдельным PR — на поведение гварда это не влияет, он смотрит на путь». Оно сломалось ровно в тот момент, когда домен появился; заменено разбором факта. Правка: четыре коротких адреса публичного домена (/, /oferta, /refund, /privacy) добавлены в bypass ТОЧНЫМ совпадением, отдельной веткой. Префиксную проверку для «/» применять нельзя — startsWith("/") истинно для любого пути, то есть один такой элемент сделал бы публичным всё приложение. Эти адреса существуют только на публичном домене: на gendsgn.ru их ловит catch-all 404, а «/» отдаёт server-side redirect на /v2 из next.config, то есть приложение по этому пути не рендерится вовсе. Тест на оба инварианта: короткие адреса публичны И закрытый контур (/v2, /admin/*, /history, /scrapers/*, /login) — нет. Мутация «точное совпадение → префиксное» роняет два теста из четырёх, проверено прогоном. Проверено: vitest 33 passed (7 файлов), tsc --noEmit, isolation guard 31 файл.