7b664f9078
Коммит 4 закрыл утечку currentPageId на анонимном /availability, но эквивалентная (и более широкая) дыра оставалась на POST /aliases/set (reassign): при занятом алиасе и confirmReassign=false 409 отдавал currentPageId И currentPageTitle ЦЕЛЕВОЙ страницы, а контроллер гейтил только validateCanEdit на ИСХОДНОЙ странице. Любой участник с одной редактируемой+расшаренной страницей мог перебирать имена алиасов и мапить их на (id, title) чужих страниц без права просмотра — тот же класс перечисления, плюс ещё и заголовок. Фикс: setAlias теперь гейтит раскрытие. currentPageId НЕ отдаётся никогда (клиент им не пользуется, это перечислимая идентичность). currentPageTitle — только если validateCanView(целевая, user) проходит; иначе голый «занят» (клиент и так показывает generic confirm-модалку без заголовка — UX не ломается). Гейт живёт в сервисе, где строится раскрытие (PageAccessService — @Global, без цикла); контроллер прокидывает user. Поправлен неточный коммент checkAvailability. Тесты: viewer → 409 с title, БЕЗ id; не-viewer → 409 без title и без id. Mutation-verify: вернул утечку (id + безусловный title) → оба теста краснеют. Контроллер-спек и int-spec обновлены под новую сигнатуру; tsc чист. Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>