Files
auth-portal/docs/integrate-cfdm.md
DenozordecandCursor 57e34ff5e9
Build and Push Auth Portal Docker Image / build-and-push (push) Successful in 1m46s
Build and Push Auth Portal Docker Image / create-release (push) Skipped
feat(admin): ingest аудита из apps и users 1:1 с Sheet журнала
Добавлен POST /api/v1/ingest/audit, фильтры source_app/user_id, last_login_at; таблица пользователей по solution-users-1 с журналом в Sheet.

Co-authored-by: Cursor <[email protected]>
2026-07-21 13:24:28 +07:00

124 lines
4.8 KiB
Markdown
Raw Permalink Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
# Интеграция 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
```bash
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`:
```env
VITE_CFDM_APP_URL=http://localhost:5174
```
Bootstrap: `[email protected]` / `admin`. В админке выдайте app **cfdm** и permissions `cfdm:*`.
### 2. cloudflare-domain-manager
```bash
cd cloudflare-domain-manager
pnpm install
```
Корень / API:
```env
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`:
```env
VITE_AUTH_ENABLED=true
VITE_AUTH_PORTAL_URL=http://localhost:5175
```
Порт Vite web — см. `apps/web/vite.config.ts` (часто `5174`). Добавьте origin в `RETURN_TO_ALLOWLIST` портала.
```bash
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`](./integrate-audit-ingest.md) (`source_app: cfdm`).
## UI аккаунта
SidebarFooter → **NavUser** ([app-shell-1](https://reui.io/preview/base/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` |