---
name: kodoceh-auth-multiidentity
description: "Требование и план: вход в продукты КодоЦех БЕЗ Telegram (РКН блочит TG) + перенос данных — multi-identity аккаунт, начинаем с Автероа"
metadata: 
  node_type: memory
  type: project
  originSessionId: b11e39bd-4f6f-47c9-ba7b-680ccf041a5b
---

**Требование (юзер 2026-06-25):** пользователи продуктов КодоЦех должны входить и пользоваться **без Telegram** (РКН периодически блочит TG). Если уже завели через TG — должна быть возможность **перенести баланс/данные** на новый способ входа.

**Решение (одобрено):** модель **multi-identity** (как уже реализовано в zemlya-web): ядро `account` + привязанные `identity` (provider: telegram/email/yandex/mailru/vk, provider_uid, email). Перенос данных = **линковка** нового способа входа к ТОМУ ЖЕ account (данные не переезжают, аккаунт получает доп. метод).

**Способы входа (выбраны юзером, юр-чисто в РФ — см. [[tbr-auth-406fz]]):** Email magic-link (база) + **Яндекс ID** + Mail.ru/VK. ❌ Google/Apple OAuth. Telegram остаётся ОДНИМ из способов.

**Порядок (выбрано): начать с Автероа** (нет тенантов/ролей → проще), обкатать, потом перенести на Гаечкина (там `Tenant.owner_tg_id` → `account_id`, миграция БД) и ВакХантер.

**Предусловия (внешние, держать в голове):**
1. **Magic-link** → нужен SMTP (ящик Яндекс/Mail + app-пароль). До него — механизм собран и проверен через «dev-outbox» (ссылка пишется в файл `data/outbox/` + лог), реальная доставка включается env `AVTERO_SMTP_*`.
2. **OAuth Яндекс/Mail/VK** → нужны (а) зарегистрированные приложения (client_id/secret — действие юзера) и (б) **стабильный публичный HTTPS redirect URI** = домен+VPS-edge (всё ещё pending) или временно Tailscale Funnel. До этого OAuth = только каркас, не проверяем.

**ПОЧТА (решено 2026-06-25, «как у zemlya»):** magic-link Автероа шлётся через ТОТ ЖЕ Postfix, что zemlya — SSH-туннель на mini `127.0.0.1:2525` → VPS-Postfix (DKIM/SPF для zbrcheck.ru уже настроены). `app/mailer.py` переписан под loopback-plain (как `zemlya-web/backend/app/services/mailer.py`). Env в `local.avtero.plist`: `AVTERO_SMTP_HOST=127.0.0.1 PORT=2525 USE_TLS=0 FROM=noreply@zbrcheck.ru FROM_NAME="Автеро · КодоЦех"` + `AVTERO_PUBLIC_BASE=https://avtero.codoceh.ru/api/pk` `AVTERO_APP_URL=https://avtero.codoceh.ru/app`. **Реальная отправка проверена** (письмо на cebers227@gmail.com, лог «sent via 127.0.0.1:2525»). ⇒ **Для codoceh.ru почтовые DNS НЕ нужны** (письма с аутентифицированного zbrcheck.ru-отправителя); reg.ru = только A-записи сайтов. Минус: from = @zbrcheck.ru (не codoceh.ru) — брендинг можно поправить позже своим Postfix на codoceh-VPS.

**СТАТУС (2026-06-25):** Во ВСЕХ 3 продуктах вход = Telegram + email magic-link + **OAuth-каркас Яндекс/Mail** (env-gated, кнопки только при ключах). Автеро — настоящая multi-identity (`account/identity`), OAuth=новая identity. Гаечкин/ВакХантер завязаны на tg_id/user_id → OAuth трактуем как «верифицированный email» через sidecar (email→tg_id/user_id; под сессией линкуем, иначе вход-если-привязан, иначе notlinked) — см. [[D18]] в Decisions. State HMAC-подписан (`*_session.hmac_sign`). Endpoints `/api/.../auth/{providers,oauth/{p}/start,oauth/{p}/callback}`.

**OAuth — что осталось юзеру:** прислать client_id/secret, выставить env `<PRODUCT>_OAUTH_<YANDEX|MAILRU>_CLIENT_ID/_SECRET` (PRODUCT = AVTERO/GAECHKIN/VAKHUNTER), зарегистрировать redirect_uri `https://<product>.codoceh.ru/api/<pk|gk|vh>/auth/oauth/<yandex|mailru>/callback`. Коммиты: avtero `5316dd1`, Gaechkin `d8207b7`, VakHunter `dd8f11d`, kodoceh-web `7abbba6`/`136ffab`.

**Web-push «как приложение» (2026-06-25, ГОТОВ, отдельно от OAuth):** VAPID самогенерируемый (работает сразу, нужен только `pywebpush`). Кнопка `@cbr/ui EnablePush` во всех 3, SW push/notificationclick, `/api/.../push/{vapid,subscribe,test}`, подписки в БД, send с прунингом 404/410. Send-путь прогнан реально. **Авто-триггеры (событие→пуш) НЕ подключены** (инвазивно к live + доставку не проверить headless) — сначала юзер на девайсе жмёт «Включить уведомления»+тест. Коммиты avtero `2b9c13d`, Gaechkin `069ee74`, VakHunter `42cafbc`, kodoceh-web `e891aa6`. Hero-мотивы (шестерни/радар/VIN-скан) — `59c0513`.

**Автеро тех.детали:** бэкенд `~/Services/avtero` (FastAPI :8201, SQLite `data/app.db`). Сейчас identity = только `pk_session` cookie (tg_id+name), таблицы юзеров нет, allowlist в боте. План: добавить таблицы `account`/`identity`/`magic_link` (идемпотентно в `app/db.py`), `app/accounts.py` (get_or_create/link), `app/emailauth.py`+`app/mailer.py`, расширить сессию полем `account_id` (обратно совместимо — старые cookie без него резолвятся по tg_id). Бота Автероа НЕ трогаем (account создаётся на стороне API при poll→make_session). Связь: [[kodoceh-web-overview]], [[zemlya-web-oauth-plan]], [[tbr-auth-406fz]].
