# Интеграция auth-portal ↔ MikrotikManager

App id: **`mm`**. Зеркало на стороне портала: [`auth-portal/docs/integrate-mikrotikmanager.md`](https://git.shx.one/denozord/auth-portal/src/branch/main/docs/integrate-mikrotikmanager.md).

## Flow

```
Browser → MikrotikManager UI (нет token)
       → redirect AUTH_PORTAL_URL/?return_to=…/auth/callback
       → login
       → redirect return_to#access_token=…
       → /auth/callback сохраняет token (localStorage: mmapp_token)
       → API Authorization: Bearer <JWT>
```

## Permissions

| Permission | UI / API |
|------------|----------|
| `mm:dashboard:read` | `/dashboard`, sidebar-counts |
| `mm:servers:read` / `write` | `/servers` |
| `mm:filters:read` / `write` | filters / GRE |
| `mm:bgp:read` / `write` | BGP |
| `mm:uptime:read` / `write` | `/uptime` |
| `mm:traffic:read` / `write` | `/traffic` |
| `mm:alerts:read` / `write` | `/alerts` |
| `mm:backups:read` / `write` | `/backups` |
| `mm:certificates:read` / `write` | certificates |
| `mm:network:read` / `write` | network / OSPF |
| `mm:settings:admin` | `/settings`, system DB, scheduler |

## Env

```env
# backend
AUTH_REQUIRED=true
AUTH_JWT_SECRET=<тот же JWT_SECRET портала>
AUTH_ISSUER=https://auth.shnt.top
AUTH_PORTAL_URL=https://auth.shnt.top
CORS_ORIGIN=https://mm.shnt.top
```

```env
# frontend build (Docker)
NEXT_PUBLIC_AUTH_PORTAL_URL=https://auth.shnt.top
```

UI читает `GET /api/auth/config` (через Next rewrite) для `required` / `portal_url`.

В portal Admin → Apps выдайте app `mm` и нужные `mm:*`. URL в App Switcher: `https://mm.shnt.top`.

## Checklist

1. Общий `JWT_SECRET` / `AUTH_JWT_SECRET` и одинаковый `AUTH_ISSUER`
2. Origin MM в `RETURN_TO_ALLOWLIST` портала
3. Пользователю выдан app `mm`
4. `AUTH_REQUIRED=true` на backend
5. Logout → `{AUTH_PORTAL_URL}/logout`

Prod: [`deploy/docker-compose.cdn-mm.yml`](../deploy/docker-compose.cdn-mm.yml) или standalone Traefik compose.
