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

4.2 KiB
Raw Blame History

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-обхода гео для платных триалов.