41 lines
3.3 KiB
Markdown
41 lines
3.3 KiB
Markdown
---
|
||
добавлено: 2026-10-13
|
||
---
|
||
# Спецификация. Тестовая страница встраивания CRM
|
||
|
||
Агент: `crm-embed-test` (создаёт админ). Код в Gitea `gitea.tes.gd`, хостинг на нашем сервере (Coolify).
|
||
|
||
## Цель
|
||
|
||
Проверить задачу Олега в CRM «Передавати авторизацію CRM сайтам в iframe через postMessage» (`mv5mmtt7kdk16z`, проект Tvorymo shotam): страница, открытая в iframe из боковой панели CRM, узнаёт пользователя CRM.
|
||
|
||
## Адреса
|
||
|
||
- Страница: `https://test-crm.tes.gd` (HTTPS обязателен).
|
||
- CRM: `https://shotam.tvorymo.com` и `https://units.tvorymo.com` (с 2026-10-16; `test.units.tvorymo.com` больше не используется — 403). Та же база Supabase.
|
||
- Supabase: `https://yjxbkcqsquwbsyoonfkn.supabase.co`.
|
||
|
||
## Протокол (со стороны страницы)
|
||
|
||
1. После загрузки: `window.parent.postMessage({ type: "crm:ready", version: 1 }, "*")`.
|
||
2. Принимать `crm:auth` `{ access_token, expires_at, user: { id, email, name } }` только от разрешённых origin CRM (env `CRM_ORIGINS`, решение владельца 2026-10-16). Origin отправителя показывать на странице.
|
||
3. `access_token` отправить на сервер страницы; сервер проверяет его через `GET /auth/v1/user` (заголовки `apikey: <publishable key>`, `Authorization: Bearer <token>`) и сверяет `exp`, `aud = "authenticated"`.
|
||
4. Имя и email брать из ответа Supabase, не из `user` в сообщении (имя из `user_metadata`; если пусто, показать «имя не задано в Supabase» и email).
|
||
5. Кнопка «Обновить токен»: отправляет `{ type: "crm:refresh" }`, CRM отвечает новым `crm:auth`; страница показывает, что токен сменился (время `expires_at`, без самого токена).
|
||
6. Выход (`crm:logout`) не проверяем.
|
||
|
||
## Требования
|
||
|
||
- Заголовок `Content-Security-Policy: frame-ancestors <origin CRM>` (только разрешённые origin CRM), без `X-Frame-Options`.
|
||
- Токен не логировать ни в браузере, ни на сервере. Сессию держать в памяти.
|
||
- Publishable-ключ Supabase агент получает от Ланы и записывает в свой CLAUDE.md (ключ публичный по дизайну).
|
||
- Без открытого токена в ответе страницы: показываем только имя, email, id, origin, `expires_at`.
|
||
|
||
## Готово, когда
|
||
|
||
- Страница в iframe CRM показывает имя и email пользователя из Supabase.
|
||
- После «Обновить токен» приходит новый токен и страница это показывает.
|
||
- Без iframe (открыта напрямую) страница пишет «жду авторизацию от CRM».
|
||
|
||
Ссылку в боковую панель CRM добавляет владелец.
|