- 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 <cursoragent@cursor.com>
5.2 KiB
Интеграция 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
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):
VITE_CDN_APP_URL=http://localhost:5176
Bootstrap: admin@shnt.top / admin. В админке выдайте app cdn и permissions cdn:*.
2. CDNManager
cd CDNManager
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
CLOUDFLARE_API_TOKEN=
apps/web/.env.local:
VITE_AUTH_ENABLED=true
VITE_AUTH_PORTAL_URL=http://localhost:5175
Порт Vite web — 5176 (apps/web/vite.config.ts). Добавьте origin в RETURN_TO_ALLOWLIST портала.
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 (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 контейнера:
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 |