Files
auth-portal/docs/integrate-cdnmanager.md
DenozordecandCursor 0f1f89776b
quality / commitlint (push) Skipped
quality / changes (push) Successful in 5s
quality / docker-check (push) Skipped
quality / web (push) Successful in 57s
quality / api (push) Failing after 30s
CD / quality (push) Failing after 1m36s
CD / publish (push) Skipped
feat(cdn): integrate CDN Manager into the application
- Updated environment configurations to include CDN Manager in the RETURN_TO_ALLOWLIST.
- Enhanced target app resolution to recognize CDN-related hosts.
- Added CDN Manager to the application switcher and updated relevant documentation.
- Included tests to verify the correct mapping of CDN hosts.

Co-authored-by: Cursor <[email protected]>
2026-09-04 14:11:34 +07:00

142 lines
5.2 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 ↔ CDN Manager
Единый вход: пользователь логинится на auth-portal, получает JWT, переходит в CDNManager с токеном в URL fragment. CDNManager API проверяет JWT и права `cdn:*`.
## Архитектура
```
Browser → CDNManager UI (нет token)
→ redirect AUTH_PORTAL_URL/?return_to=…/auth/callback
→ login
→ redirect return_to#access_token=…
→ CDNManager /auth/callback сохраняет token (cdnmanager_token)
→ API Authorization: Bearer …
```
Общий секрет: `JWT_SECRET` / `AUTH_JWT_SECRET` (HS256). Issuer: `ISSUER` / `AUTH_ISSUER`.
App id в портале: **`cdn`** (каталог 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:5176
pnpm --filter @authportal/api dev # :8080
pnpm --filter web dev # :5175
```
В `apps/web/.env.local` (опционально для App Switcher / SSO open):
```env
VITE_CDN_APP_URL=http://localhost:5176
```
Bootstrap: `[email protected]` / `admin`. В админке выдайте app **cdn** и permissions `cdn:*`.
### 2. CDNManager
```bash
cd CDNManager
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
CLOUDFLARE_API_TOKEN=
```
`apps/web/.env.local`:
```env
VITE_AUTH_ENABLED=true
VITE_AUTH_PORTAL_URL=http://localhost:5175
```
Порт Vite web — `5176` (`apps/web/vite.config.ts`). Добавьте origin в `RETURN_TO_ALLOWLIST` портала.
```bash
pnpm --filter @cdnmanager/api dev
pnpm --filter web dev
```
Откройте CDNManager → редирект на portal → после логина NavUser показывает имя/email.
## Permissions ↔ API / UI
Иерархия: `admin``write``read` в рамках одной секции.
| Permission | API | UI |
|------------|-----|-----|
| `cdn:dashboard:read` | GET `/api/v1/dashboard/*`, `/topology` | `/` |
| `cdn:nodes:read` | GET `/api/v1/nodes*`, `/locations` | `/nodes` |
| `cdn:nodes:write` | POST/PATCH/DELETE nodes | create/edit нод |
| `cdn:aliases:read` | GET `/api/v1/aliases*` | `/aliases` |
| `cdn:aliases:write` | POST/PATCH aliases, retarget | create / Retarget |
| `cdn:zones:read` | GET `/api/v1/zones*` | `/zones` |
| `cdn:zones:write` | POST/PATCH zones, BIND export | создать зону |
| `cdn:sync:write` | POST `…/sync`, `…/apply` | Sync / Apply |
| `cdn:topology:read` | GET `/api/v1/topology` | `/topology` |
| `cdn:settings:admin` | GET/PATCH `/api/v1/settings` | `/settings/*` |
Без app `cdn` в 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). CDNManager chrome (`AppSwitcher` / `AppsMenu`) читает его через `ensureAuthConfig().portalUrl`.
Редактор только на портале: **Админка → Ссылки приложений** (`/admin/apps`). В CDNManager Settings → Интеграции — read-only ссылка на портал.
`CURRENT_APP_ID = cdn`. Если в JWT есть `apps[]` — в меню только пересечение с каталогом.
## Audit ingest
Dual-write локального журнала в portal: [`integrate-audit-ingest.md`](./integrate-audit-ingest.md) (`source_app: cdn`).
## UI аккаунта
SidebarFooter → **NavUser**: Настройки, Тема, Выйти → `AUTH_PORTAL_URL/logout`.
## Logout (SSO)
Очистить `cdnmanager_token` → редирект на **`/logout`** портала (не на `/?return_to=…` — иначе portal сразу выдаст новый SSO-токен).
## Production (Docker)
Рекомендуется Traefik-стек в репозитории CDNManager: `docs/deploy-traefik.md`
(`deploy/docker-compose.traefik.yml` + `deploy/env.traefik.example`).
Ключевые env контейнера:
```env
AUTH_REQUIRED=true
AUTH_JWT_SECRET=<тот же JWT_SECRET портала>
AUTH_ISSUER=https://auth.shnt.top
AUTH_PORTAL_URL=https://auth.shnt.top
AUTH_AUDIT_INGEST_SECRET=<AUDIT_INGEST_SECRET портала>
CLOUDFLARE_API_TOKEN=<Zone DNS Edit + Zone Read>
```
В portal: `RETURN_TO_ALLOWLIST` включает `https://cdn.shnt.top` (или ваш origin).
## Troubleshooting
| Симптом | Причина |
|---------|---------|
| SSO loop / «Сессия не принята» | разный `JWT_SECRET` или `ISSUER` у portal и CDNManager |
| 403 «Нет доступа к приложению» | у пользователя нет app `cdn` в portal |
| 403 «Недостаточно прав» | нет нужного `cdn:…` permission |
| return_to rejected | origin CDNManager не в `RETURN_TO_ALLOWLIST` |
| «Выйти» сразу возвращает в CDNManager | клиент должен открывать `/logout`, не login с `return_to` |