# 2026-09-20 — Вход через WebView + Telegram Login Widget ## Запрос Реализовать нативный вход: открыть кабинет в WebView и забрать JWT через JS-канал. Бэкенд не менять. ## Почему не «просто открыть страницу» Telegram Login Widget в обычном браузере работает через iframe + `data-onauth`. В Android/iOS WebView этот путь ломается: - popup (`window.open` на `oauth.telegram.org`) не возвращает `opener`; - iframe режется third-party cookies и User-Agent с маркером `; wv`; - callback `onTelegramAuth` просто не вызывается. Поэтому в WebView виджет переключается на **redirect-режим** (`data-auth-url`), а Flutter забирает уже готовый JWT, который кабинет и так кладёт в `localStorage.ppm_session_jwt`. API (`POST /api/auth/telegram`) не трогали. ## Поток 1. Экран входа на iOS/Android показывает «Войти через Telegram». 2. Открывается fullscreen WebView на `{cabinet}/login`. 3. Кабинет видит канал `window.PpmAuth` → ставит виджету `data-auth-url=/login`. 4. Пользователь логинится в Telegram; редирект приходит на `/login?id&hash&…`. 5. `telegramPayloadFromQuery` собирает payload, кабинет зовёт тот же `loginWithTelegram` / `POST /api/auth/telegram`. 6. `setSession` пишет JWT в `localStorage` и зовёт `PpmAuth.postMessage`. 7. Flutter парсит сообщение, закрывает WebView, проверяет токен через `GET /api/me`, кладёт сессию в `SharedPreferences`. Запасные пути, если кабинет ещё не задеплоен с мостом: - JS в WebView хукает `localStorage.setItem('ppm_session_jwt')` и поллит ключ; - на Windows/web WebView нет — форма «вставить токен»; - «Демо-режим» по-прежнему без сети. ## Что изменилось ### Web (не API) - `web/src/auth/telegramRedirect.ts` — разбор query и `postTokenToNativeApp`. - `TelegramLoginButton` — `data-auth-url` только если есть `window.PpmAuth`. - `LoginPage` — автологин, если в URL уже лежит telegram-payload. - `setSession` — после записи токена шлёт его в канал. ### Mobile - `TelegramLoginScreen` (`webview_flutter`): канал `PpmAuth`, Chrome UA без `; wv`, third-party cookies на Android, `tg://` уходит во внешнее приложение, кнопка «назад» после oauth.telegram.org. - `resolveCabinetLoginUri` всегда открывает `/login`. - `INTERNET` в main `AndroidManifest` (раньше был только в debug). - iOS: `LSApplicationQueriesSchemes` для `tg` / `telegram`. - `PPM_WEB_URL` по умолчанию = `PPM_API_BASE_URL` (один origin за nginx). ## Тесты - `resolveApiBaseUrl` / `resolveCabinetLoginUri` / парсер канала. - виджет: инжектированный launcher отдаёт JWT → `GET /api/me` → signed in. - 32 теста приложения, 102 в Widgetbook, `flutter analyze` чистый. ## Запуск против живого кабинета ```powershell cd mobile .\run.ps1 -Device windows # на Windows будет форма токена # на телефоне: .\run.ps1 -ApiBaseUrl https://<домен-кабинета> ``` Нужен публичный HTTPS и BotFather `/setdomain` на этот домен — как для веба.