# API v2 OfficeGest - Guia de Autenticação

**Documentação completa da autenticação API v2 para desenvolvedores**

## 📋 Guias Disponíveis

- **[Helpers Guide](helpers-guide.md)** - Funções auxiliares PHP para facilitar o uso
- Este README - Conceitos básicos e endpoints
- Exemplos práticos para diferentes cenários

## 🚀 Introdução Rápida

A API v2 usa autenticação baseada em tokens (similar ao Laravel Sanctum) com:

- **API Tokens**: Integrações externas
- **SPA Tokens**: Aplicações internas com cookies
- **Abilities/Scopes**: Controle granular de permissões

## ⚙️ Configuração Básica

### Endpoints Principais
```
POST /api/v2/auth/login    - Fazer login
DELETE /api/v2/auth/logout - Fazer logout (requer auth)
```

### Headers Padrão
```http
Content-Type: application/json
Accept: application/json
Authorization: Bearer {token} # Após login
```

## 🎯 Cenários de Uso

### 1. **React/SPA Injetado** (Mais Comum)

Use helpers PHP para inicialização automática:

```php
<!-- Em qualquer view/template -->
<?= renderCookieAuthScript() ?>

<div id="react-app"></div>
<script>
    // window.OfficeGestAPI já disponível
    ReactDOM.render(<MyApp />, document.getElementById('react-app'));
</script>
```

No React:
```jsx
function useApiV2() {
    const api = useCallback(async (endpoint, options = {}) => {
        return fetch(`/api/v2${endpoint}`, {
            credentials: 'include', // Cookie automático
            headers: {
                'Accept': 'application/json',
                'Content-Type': 'application/json',
                'X-Requested-With': 'XMLHttpRequest'
            },
            ...options
        }).then(res => res.json());
    }, []);
    
    return { api };
}
```

### 2. **JavaScript Puro/jQuery**

```javascript
// Setup global
window.OfficeGestAPI = {
    baseURL: '/api/v2',
    defaultHeaders: {
        'Content-Type': 'application/json',
        'Accept': 'application/json',
        'X-Requested-With': 'XMLHttpRequest'
    }
};

// Função universal
async function apiCall(endpoint, options = {}) {
    return fetch(`/api/v2${endpoint}`, {
        credentials: 'include',
        headers: window.OfficeGestAPI.defaultHeaders,
        ...options
    }).then(res => res.json());
}

// Uso
apiCall('/tickets').then(data => console.log(data));
```

### 3. **API Externa/Mobile**

```javascript
// Login primeiro
const loginResponse = await fetch('/api/v2/auth/login', {
    method: 'POST',
    headers: { 'Content-Type': 'application/json' },
    body: JSON.stringify({ username: 'user', password: 'pass' })
});

const { data } = await loginResponse.json();
const token = data.access_token;

// Chamadas com token
const response = await fetch('/api/v2/some-endpoint', {
    headers: {
        'Authorization': `Bearer ${token}`,
        'Accept': 'application/json'
    }
});
```

### 4. **PHP/Backend**

```php
// Usar helpers
$token = loginForSpa('username', 'password');
if ($token) {
    echo "Token: " . $token->getPlainTextToken();
}

// Verificações
if (authCheck()) {
    $user = authUser();
    echo "Logado como: " . $user['nome'];
}

// Criar tokens API
$apiToken = createApiToken(123, 'integration');
```

## 🔐 Endpoints Detalhados

### Login
```http
POST /api/v2/auth/login
Content-Type: application/json

{
    "username": "usuario",
    "password": "senha"
}
```

**Resposta:**
```json
{
    "data": {
        "access_token": "1|token_string...",
        "user": {
            "id": 123,
            "nome": "João Silva",
            "email": "joao@empresa.com"
        }
    }
}
```

### Logout
```http
DELETE /api/v2/auth/logout
Authorization: Bearer {token}
```

**Resposta:**
```json
{
    "message": "Logged out successfully"
}
```

## 🚨 Tratamento de Erros

### Códigos Comuns
- **401**: Token inválido/expirado
- **422**: Dados de login inválidos
- **429**: Rate limit excedido

### Exemplo de Tratamento
```javascript
async function safeApiCall(endpoint, options = {}) {
    try {
        const response = await fetch(`/api/v2${endpoint}`, {
            credentials: 'include',
            headers: { 'Accept': 'application/json' },
            ...options
        });
        
        if (response.status === 401) {
            // Token expirado - recarregar página ou redirecionar
            window.location.reload();
            return;
        }
        
        return await response.json();
    } catch (error) {
        console.error('API Error:', error);
        throw error;
    }
}
```

## 🛠️ Helpers PHP Principais

Para facilitar o uso, utilize os helpers disponíveis:

```php
// Verificações rápidas
authCheck()                    // Usuário logado?
authUser()                     // Dados do usuário
authCan('permission')          // Tem permissão?

// Scripts automáticos (resolve F5 spam)
renderCookieAuthScript()       // SPA com cookies (recomendado)
renderAuthScript(true, true)   // Com token reutilizado

// Gestão de tokens
spaToken()                     // Token SPA (reutiliza existente)
createApiToken(123, 'api')     // Token API
cleanupUserTokens(123, 5)      // Manter só 5 tokens
```

Veja o **[Helpers Guide](helpers-guide.md)** para documentação completa com exemplos.

## 🎯 Melhores Práticas

### Para Aplicações Internas
1. Use `renderCookieAuthScript()` - evita tokens desnecessários
2. `credentials: 'include'` em todas as chamadas
3. Trate 401 como reload da página

### Para APIs Externas  
1. Armazene tokens de forma segura
2. Implemente refresh automático
3. Use abilities específicas, não `['*']`

### Para Desenvolvimento
1. Use `guardDebug()` para debugging
2. Configure rate limits apropriados
3. Execute `pruneTokens()` periodicamente

## 🔧 Configuração Avançada

Configurações em `/Modules/Common/Config/guard.php`:

```php
'spa' => [
    'expires_in' => 60 * 24,        // 24 horas
    'cookie_name' => 'guard_token',
    'cookie_secure' => true,
],
'security' => [
    'max_tokens_per_user' => 50,
    'prune_expired' => true,
]
```

## 📞 Suporte e Debug

```php
// Ver estado atual
$debug = guardDebug();
print_r($debug);

// Configurações
$config = guardConfig('spa.expires_in');
```

---

**Esta documentação cobre os casos de uso mais comuns. Para exemplos específicos e funções avançadas, consulte o [Helpers Guide](helpers-guide.md).**