# Customer Authentication Flow with Access Tokens and Refresh Tokens

## Overview

This implementation provides a secure authentication flow for customers using Laravel Passport with access tokens and refresh tokens.

## Token Configuration

- **Access Token Expiry**: 20 minutes
- **Refresh Token Expiry**: 3 days
- **Token Type**: Laravel Passport Personal Access Tokens

## API Endpoints

### 1. Login
**POST** `/api/customer/login`

**Request Body:**
```json
{
    "email": "customer@example.com",
    "password": "password123"
}
```

**Response:**
```json
{
    "status": true,
    "access_token": "eyJ0eXAiOiJKV1QiLCJhbGciOiJSUzI1NiJ9...",
    "data": {
        "id": 1,
        "profileName": "John Doe",
        "type": "customer",
        "email": "customer@example.com",
        "role": "customer",
        "priceType": "",
        "group_name": "",
        "contact_id": "CUST001",
        "contact_type": "individual",
        "is_approved": true,
        "is_active": true,
        "balance": "0.00"
    }
}
```

**Cookies Set:**
- `refresh_token`: Valid for 3 days, used for token refresh

### 2. Refresh Token
**POST** `/api/customer/refresh-token`

**Request:** No body required, uses refresh token from cookie

**Response:**
```json
{
    "status": true,
    "access_token": "eyJ0eXAiOiJKV1QiLCJhbGciOiJSUzI1NiJ9...",
    "message": "Token refreshed successfully"
}
```

### 3. Logout
**GET** `/api/customer/logout`

**Headers:** `Authorization: Bearer {access_token}`

**Response:**
```json
{
    "status": true,
    "message": "Successfully logged out"
}
```

## How to Use

### Frontend Implementation

1. **Login Flow:**
   ```javascript
   const response = await fetch('/api/customer/login', {
       method: 'POST',
       headers: {
           'Content-Type': 'application/json',
       },
       body: JSON.stringify({
           email: 'customer@example.com',
           password: 'password123'
       })
   });
   
   const data = await response.json();
   if (data.status) {
       // Store access token
       localStorage.setItem('access_token', data.access_token);
       // Refresh token is automatically stored in cookies
   }
   ```

2. **API Requests:**
   ```javascript
   const makeApiRequest = async (url, options = {}) => {
       const accessToken = localStorage.getItem('access_token');
       
       const response = await fetch(url, {
           ...options,
           headers: {
               'Authorization': `Bearer ${accessToken}`,
               'Content-Type': 'application/json',
               ...options.headers
           }
       });
       
       if (response.status === 401) {
           // Token expired, try to refresh
           await refreshToken();
           // Retry the request
           return makeApiRequest(url, options);
       }
       
       return response;
   };
   ```

3. **Token Refresh:**
   ```javascript
   const refreshToken = async () => {
       const response = await fetch('/api/customer/refresh-token', {
           method: 'POST',
           credentials: 'include' // Important for cookies
       });
       
       const data = await response.json();
       if (data.status) {
           localStorage.setItem('access_token', data.access_token);
           return true;
       }
       
       // Refresh failed, redirect to login
       localStorage.removeItem('access_token');
       window.location.href = '/login';
       return false;
   };
   ```

4. **Logout:**
   ```javascript
   const logout = async () => {
       const accessToken = localStorage.getItem('access_token');
       
       await fetch('/api/customer/logout', {
           method: 'GET',
           headers: {
               'Authorization': `Bearer ${accessToken}`
           },
           credentials: 'include'
       });
       
       localStorage.removeItem('access_token');
       window.location.href = '/login';
   };
   ```

## Security Features

1. **Automatic Token Expiry**: Access tokens expire after 20 minutes
2. **Refresh Token Rotation**: Each refresh generates a new refresh token
3. **Token Revocation**: Old tokens are revoked when new ones are issued
4. **Secure Cookies**: Refresh tokens are stored in HTTP-only cookies
5. **Cross-Origin Support**: Configured for cross-origin requests

## Error Handling

### Common Error Responses

1. **Invalid Credentials:**
   ```json
   {
       "status": false,
       "message": "Invalid credentials"
   }
   ```

2. **Token Expired:**
   ```json
   {
       "status": false,
       "message": "Invalid or expired refresh token"
   }
   ```

3. **Account Not Approved:**
   ```json
   {
       "status": false,
       "message": "Not Approved!"
   }
   ```

4. **Account Deactivated:**
   ```json
   {
       "status": false,
       "message": "This account is deactivated"
   }
   ```

## Configuration

The token expiry times are configured in `app/Providers/AuthServiceProvider.php`:

```php
// Configure access token expiry for customers (20 minutes)
Passport::tokensExpireIn(Carbon::now()->addMinutes(20));

// Configure refresh token expiry for customers (3 days)
Passport::refreshTokensExpireIn(Carbon::now()->addDays(3));
```

## Database Tables

The implementation uses the following Passport tables:
- `oauth_access_tokens`: Stores access tokens
- `oauth_refresh_tokens`: Stores refresh tokens

## Notes

- Refresh tokens are automatically included in cookies by the server
- Access tokens must be included in the `Authorization` header for API requests
- The system automatically handles token refresh when access tokens expire
- All tokens are properly revoked on logout 