Files
auth-portal/docs/integrate-vps-tracker.md
T
Denozordec bac95bdb2e
Build and Push Auth Portal Docker Image / build-and-push (push) Successful in 5m26s
Build and Push Auth Portal Docker Image / create-release (push) Skipped
First Commit
2026-07-18 13:27:37 +07:00

107 lines
3.6 KiB
Markdown
Raw 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 ↔ VPS Tracker
Единый вход: пользователь логинится на auth-portal, получает JWT, переходит в VPS Tracker с токеном в URL fragment. VPS API проверяет JWT и права `vps:*`.
## Архитектура
```
Browser → VPS UI (нет token)
→ redirect AUTH_PORTAL_URL/?return_to=http://localhost:5173/auth/callback
→ login
→ redirect return_to#access_token=…
→ VPS /auth/callback сохраняет token
→ API Authorization: Bearer …
```
Общий секрет: `JWT_SECRET` / `AUTH_JWT_SECRET` (HS256). Issuer: `ISSUER` / `AUTH_ISSUER`.
## Локальный запуск
### 1. auth-portal
```bash
cd auth-portal
pnpm install
cp .env.example .env
# JWT_SECRET=dev-secret-change-me
# RETURN_TO_ALLOWLIST=.shnt.top,localhost,http://localhost:5173
pnpm --filter @authportal/api dev # :8080
pnpm --filter web dev # :5175
```
В `apps/web/.env.local`:
```env
VITE_VPS_APP_URL=http://localhost:5173
```
Bootstrap: `[email protected]` / `admin`. В админке выдайте app **vps** и нужные permissions.
### 2. vps-tracker
```bash
cd vps-tracker
pnpm install
```
Корень / API env (или shell):
```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
```
```bash
pnpm --filter @cfdm/api dev
pnpm --filter web dev # :5173
```
Откройте http://localhost:5173 → редирект на portal → после логина обратно в VPS.
## Permissions ↔ API / UI
Иерархия: `admin``write``read` в рамках одной секции.
| Permission | API | UI |
|------------|-----|-----|
| `vps:dashboard:read` | `GET /api/dashboard/*` | `/dashboard` |
| `vps:vps:read` | `GET /api/vps`, projects, reports-related reads | `/vps`, `/tariffs`, `/projects`, аналитика |
| `vps:vps:write` | POST/PUT/PATCH/DELETE `/api/vps`, projects | create/edit/delete VPS |
| `vps:accounts:read` | GET providers, provider-accounts | `/providers`, `/accounts` |
| `vps:accounts:write` | мутации providers/accounts | формы аккаунтов |
| `vps:payments:read` | GET payments, balance-ledger | `/payments`, `/balance` |
| `vps:payments:write` | мутации payments / ledger | формы платежей |
| `vps:sync:write` | POST `/api/sync/*`, GET sync status | `/sync-journal`, кнопка sync |
| `vps:settings:admin` | `/api/settings`, backup, audit, migrate | `/settings`, `/audit` |
Без app `vps` в JWT `apps`**403** на весь `/api/*` (кроме health и CFDM integration).
`AUTH_REQUIRED=false` — auth выключен (удобно для локальной разработки без portal).
## Troubleshooting
| Симптом | Причина |
|---------|---------|
| 401 на API | Нет/битый Bearer; разные `JWT_SECRET` |
| 403 «нет доступа к приложению» | В portal не выдан app `vps` |
| 403 на write | Только `*:read` в permissions |
| Loop на login | `return_to` не в `RETURN_TO_ALLOWLIST` |
| CORS | Portal и VPS на разных origin — fragment handoff не требует CORS для token |
## Production
- Один `JWT_SECRET` в secret store обоих сервисов
- `ISSUER=https://auth.shnt.top`
- `RETURN_TO_ALLOWLIST=.shnt.top,https://vps.shnt.top`
- `AUTH_REQUIRED=true`, `VITE_AUTH_ENABLED=true`
- `VITE_VPS_APP_URL=https://vps.shnt.top` (portal)