> ## Documentation Index
> Fetch the complete documentation index at: https://docs.easygoal.com.br/llms.txt
> Use this file to discover all available pages before exploring further.

# Fluxo OAuth

> Como o SSO autentica usuários e distribui o eg_session para apps do ecossistema.

<Note>
  **Dois cenários de integração:**

  1. **Apps internos (app-front, subdomínios `.easygoal.com.br`)** — recebem `?eg_session=<token>` no redirect e salvam o cookie localmente via `handleAuthCallback`.

  2. **Apps externos (outros domínios)** — recebem `?eg_token=<token>` temporário e trocam por `eg_session` via `POST /auth/verify` server-side.
</Note>

## Fluxo Completo

```
[App] redireciona para SSO /auth/login?redirect_to=<callback_url>
    ↓
SSO: formulário de login / OAuth (Supabase PKCE)
    ↓
SSO /auth/callback:
  - Troca code → sessão Supabase
  - Cria/valida perfil em users_company
  - Assina eg_session JWT (SSO_JWT_SECRET, 30 dias)
  - Seta cookie eg_session em .easygoal.com.br
  ↓
  [cross-domain autorizado?]
  ├── SIM → adiciona ?eg_session=<token> ao redirect_to
  └── NÃO → redirect_to sem token (usa cookie de domínio)
    ↓
SSO /auth/welcome (splash 4s) → redireciona para redirect_to
    ↓
[App /auth/callback]:
  - ?eg_session= presente → salva no cookie local (app interno)
  - ?eg_token= presente → POST /auth/verify → obtém eg_session → salva cookie
  - Nenhum → redireciona para SSO login
```

## Implementar o Callback no App

Use `handleAuthCallback` do package `@easygoal/packages/auth`:

```ts theme={null}
// src/app/auth/callback/route.ts
import { createCallbackRoute } from '@easygoal/packages/auth/server';

export const GET = createCallbackRoute({
  ssoUrl: process.env.NEXT_PUBLIC_SSO_URL,
  appUrl: process.env.NEXT_PUBLIC_APP_URL,
  apiKey: process.env.EG_API_KEY, // apenas para apps externos
});
```

O handler trata automaticamente os dois cenários (`eg_session` e `eg_token`).

## Ler a Sessão no App

```tsx theme={null}
// layout.tsx
import { EgSessionProvider } from '@easygoal/packages/auth/client';

export default function RootLayout({ children }) {
  return <EgSessionProvider>{children}</EgSessionProvider>;
}
```

```tsx theme={null}
// qualquer componente
import { useEgSession } from '@easygoal/packages/auth/client';

const { user, isReady } = useEgSession();
// user: { id, email, name, avatarUrl, isProducer, companyName, rankName, planSlug }
```

O `EgSessionProvider` lê internamente via `GET /api/auth/session` (que lê o cookie `eg_session` server-side).

## Complete Profile — NDA Beta

Após o primeiro login OAuth, usuários sem CPF/CNPJ são redirecionados para `/complete-profile`.

Para **usuários beta**, a tela inclui aceite do NDA:

<Steps>
  <Step title="Dados básicos">
    Nome completo, CPF/CNPJ e outros campos obrigatórios.
  </Step>

  <Step title="Aceite do NDA (apenas betas)">
    Exibido somente se o usuário tem registro em `beta_users`. Timestamp, IP e user agent capturados no servidor e gravados em `beta_users`.
  </Step>

  <Step title="Redirecionamento">
    Após salvar: vincula compras guest ao usuário → redireciona para o `redirect_to` original.
  </Step>
</Steps>

O claim `is_beta` é definido como `true` no `eg_session` após o aceite.

## Logout

```ts theme={null}
// POST /auth/signout (no SSO)
// Limpa o cookie eg_session no domínio .easygoal.com.br

// No app, redirecionar para:
const signoutUrl = `${SSO_URL}/auth/signout?redirect_to=${encodeURIComponent(APP_URL)}`;
```
