Files
autoreg-skills-max/skills/ai-provider-autoreg/references/neuroflash-zitadel-jwt-login.md

46 lines
4.2 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.

# neuroflash.com — Zitadel OIDC + /api/v1/login/jwt (HTTP-only registration)
Live 2026-10-07: customer создан полным HTTP-флоу без браузера (customer id в ответе login/jwt, `firstLogin:true`).
## Стек
- IdP: Zitadel на `https://id.neuroflash.com` (discovery: `/.well-known/openid-configuration`)
- Публичный app client_id `304685938091620422`, redirect `https://app.neuroflash.com/login/callback`
- scope: `openid email profile offline_access urn:zitadel:iam:org:projects:roles urn:zitadel:iam:org:project:id:304489704877737470:aud`
- Почта: Voidash `voidash.bond` проходит (API — см. attio-референс)
## Флоу (чистый HTTP, один cookiejar, редиректы вручную)
1. `GET /oauth/v2/authorize?client_id=…&response_type=code&redirect_uri=…&scope=…&state=…&nonce=…` → 302 на `/ui/login/register?authRequestID=<id>`
2. GET register-страницы с authRequestID → распарсить hidden `gorilla.csrf.Token`
3. POST `/ui/login/register`: `authRequestID`, `gorilla.csrf.Token`, `firstname`, `lastname`, `email`, `register-password`, `register-password-confirmation`, `register-term-confirmation=on`, `register-term-confirmation-privacy=on`
4. 6-значный код из письма → POST `/ui/login/user/init?authRequestID=<id>` (token+code)
5. POST `/ui/login/login` (authRequestID+csrf) → GET `/oauth/v2/authorize/callback?id=<authRequestID>` → 302 на `https://app.neuroflash.com/login/callback?code=…&state=…`
6. **Обмен (ключевой шаг, найден в chunk `0apql_5~16mez.js`, ф-я `loginToBackend`):**
```
POST https://app.neuroflash.com/api/v1/login/jwt
Authorization: Bearer <zitad…ken>
body: {"campaign_url":null,"preferred_pricing_id":null,"preferred_pricing_plan_id":null}
→ 200 {"firstLogin":true,"customer":{"id":<int>,"email":…},"workspaceId":…}
```
Этот POST создаёт customer-запись. Frontend дальше хранит customerId в cookie/store.
7. Все последующие API-вызовы: `Authorization: Bearer <zitad…ken>` + `x-customer-id: <customer.id>`
- без `x-customer-id` → 403 `"this is neither a valid service account nor a valid customer account"`
- **customer.id ≠ JWT sub** (backend int ~1.8M vs Zitadel snowflake ~3.9e17) — брать только из ответа login/jwt
- заголовок `x-access-token` вместо Bearer → 401 (workspace-service требует именно `Authorization: Bearer`)
## API-сервисы (база `https://app.neuroflash.com/api/`)
- `/workspace-service/v1/workspaces` — у свежего customer 0 воркспейсов (онбординг не пройден)
- `/ds-prototypes/model_selection/models`, `/ds-prototypes/content_generation/chat/completions` (OpenAI-форма)
- pricing-plan-service существует, но `GET /v1/pricing-plans` → 404 UNKNOWN_PATH (пути не разведаны)
- BFF-угадывание `/api/auth/*`, `/api/customer/*` = только UNKNOWN_PATH/404-шум — не тратить IP-квоту, читать чанки (pitfall 49)
## Легальный API-доступ (путь nf-gateway)
Service Account: Settings → Workspace → API Access → Create Service Account → client_credentials на `https://id.neuroflash.com/oauth/v2/token` (scope `openid`) + заголовок `x-workspace-id` (авто-детект: `GET /workspace-service/v1/workspaces`). Референс-шлюз: `github.com/aa27259/nf-gateway` (stdlib-only). Асимметрия model-id: каталог `claude-sonnet-5.5`, ответ генерации `anthropic/claude-sonnet-5.5` — шлюз режет префикс в обе стороны. Tool calling нативный (бэкенд = OpenRouter-proxy форма).
## Граница скоупа (важно)
Триал-фарм через сгенерированные IBAN (randomiban.dev) в Stripe SEPA Direct Debit = платёжное мошенничество — ОТКАЗ. Рекон регистрации выше легитимен; НЕ расширять его в схему fake-IBAN/триал-ротации/DE-VPN-обхода гео для платных триалов.