Добавлен POST /api/v1/ingest/audit, фильтры source_app/user_id, last_login_at; таблица пользователей по solution-users-1 с журналом в Sheet. Co-authored-by: Cursor <[email protected]>
4.8 KiB
Интеграция auth-portal ↔ Cloudflare Domain Manager (CFDM)
Единый вход: пользователь логинится на auth-portal, получает JWT, переходит в CFDM с токеном в URL fragment. CFDM API проверяет JWT и права cfdm:*.
Архитектура
Browser → CFDM UI (нет token)
→ redirect AUTH_PORTAL_URL/?return_to=…/auth/callback
→ login
→ redirect return_to#access_token=…
→ CFDM /auth/callback сохраняет token (cfdm_token)
→ API Authorization: Bearer …
Общий секрет: JWT_SECRET / AUTH_JWT_SECRET (HS256). Issuer: ISSUER / AUTH_ISSUER.
App id в портале: cfdm (уже в каталоге permissions).
Локальный запуск
1. auth-portal
cd auth-portal
pnpm install
# JWT_SECRET=dev-secret-change-me
# RETURN_TO_ALLOWLIST=.shnt.top,localhost,http://localhost:5173,http://localhost:5174
pnpm --filter @authportal/api dev # :8080
pnpm --filter web dev # :5175
В apps/web/.env.local:
VITE_CFDM_APP_URL=http://localhost:5174
Bootstrap: [email protected] / admin. В админке выдайте app cfdm и permissions cfdm:*.
2. cloudflare-domain-manager
cd cloudflare-domain-manager
pnpm install
Корень / API:
AUTH_REQUIRED=true
AUTH_JWT_SECRET=dev-secret-change-me
AUTH_ISSUER=https://auth.shnt.top
AUTH_PORTAL_URL=http://localhost:5175
apps/web/.env.local:
VITE_AUTH_ENABLED=true
VITE_AUTH_PORTAL_URL=http://localhost:5175
Порт Vite web — см. apps/web/vite.config.ts (часто 5174). Добавьте origin в RETURN_TO_ALLOWLIST портала.
pnpm --filter api dev
pnpm --filter web dev
Откройте CFDM → редирект на portal → после логина NavUser показывает имя/email.
Permissions ↔ API / UI
Иерархия: admin ⊃ write ⊃ read в рамках одной секции.
| Permission | API | UI |
|---|---|---|
cfdm:domains:read |
GET /api/v1/domains*, monitors |
/, /domains |
cfdm:domains:write |
мутации domains, sync | create/edit/sync |
cfdm:dns:read |
GET dns, subdomains | DNS на карточке домена |
cfdm:dns:write |
мутации dns/subdomains | формы DNS |
cfdm:certificates:read |
GET certificates | /certificates |
cfdm:certificates:write |
мутации certificates | действия сертификатов |
cfdm:groups:read |
GET groups, service-groups | /groups |
cfdm:groups:write |
мутации groups | формы групп |
cfdm:services:read |
GET services, bindings | /services |
cfdm:services:write |
мутации services | формы сервисов |
cfdm:settings:admin |
settings, notifications, health-check | /settings/* |
Без app cfdm в JWT apps → 403 на защищённые /api/v1/*.
AUTH_REQUIRED=false — локальный login (ADMIN_*) для тестов/dev без portal; UI /login.
App Switcher
Публичный конфиг: GET {AUTH_PORTAL_URL}/api/v1/app-switcher (CORS open). CFDM chrome (AppSwitcher / AppsMenu) читает его через ensureAuthConfig().portalUrl; offline fallback — hardcoded defaults с ids cfdm | vps | bgp.
Редактор только на портале: Админка → Ссылки приложений (/admin/apps). В CFDM Settings → Integrations — read-only ссылка на портал.
CURRENT_APP_ID = cfdm. Если в JWT есть apps[] — в меню только пересечение с каталогом.
Audit ingest
Dual-write локального журнала в portal: integrate-audit-ingest.md (source_app: cfdm).
UI аккаунта
SidebarFooter → NavUser (app-shell-1): Настройки, Тема, Выйти → AUTH_PORTAL_URL/logout.
Logout (SSO)
Очистить cfdm_token → редирект на /logout портала (не на /?return_to=… — иначе portal сразу выдаст новый SSO-токен).
Troubleshooting
| Симптом | Причина |
|---|---|
| SSO loop / «Сессия не принята» | разный JWT_SECRET или ISSUER у portal и CFDM |
| 403 «Нет доступа к приложению» | у пользователя нет app cfdm в portal |
| 403 «Недостаточно прав» | нет нужного cfdm:… permission |
| return_to rejected | origin CFDM не в RETURN_TO_ALLOWLIST |
| «Выйти» сразу возвращает в CFDM | клиент должен открывать /logout, не login с return_to |