# Authentication Error Handling

## Overview

This document explains the improved authentication error handling mechanism that was implemented to prevent unnecessary logouts when non-authentication errors occur.

## Problem Statement

Previously, the application would log out users on **any** error with status codes 401 or 407, regardless of the actual cause. This was too aggressive and caused users to be logged out in scenarios that didn't warrant it, such as:

- **Authorization failures** (403 Forbidden) - User is authenticated but lacks permission
- **Temporary network issues** - Transient errors that could be retried
- **API validation errors** - Business logic errors unrelated to authentication
- **Resource-specific permission errors** - User can access other resources

## Solution

A new error classification system was implemented that analyzes errors to determine if they represent genuine authentication failures vs. other types of errors.

### Key Components

#### 1. Backend: `server/utils/authErrorHelper.ts`

Provides error classification logic for server-side code.

**Key Functions:**
- `classifyAuthError(error)` - Analyzes an error and returns classification
- `shouldLogoutOnError(error)` - Returns boolean indicating if logout is needed

**Error Types:**
- `token_expired` - Token has expired (logout required)
- `token_invalid` - Token is invalid or malformed (logout required)
- `authorization` - User authenticated but lacks permission (NO logout)
- `other` - Non-authentication error (NO logout)
- `none` - Not an auth-related error (NO logout)

#### 2. Backend: `server/utils/forceLogoutHelper.ts` (Refactored)

Updated to use the new classification logic instead of blindly logging out on 401/407.

**Changes:**
- Now calls `classifyAuthError()` before deciding to logout
- Returns boolean indicating if logout was performed
- Includes better error handling and logging
- Only logs out on true authentication failures

#### 3. Frontend: `composables/useAuthError.ts`

Provides the same error classification logic for Vue components.

**Usage Example:**

```vue
<script setup>
const { handleAuthError, classifyAuthError } = useAuthError()

// In your error handler
try {
  const data = await $fetch('/api/some-endpoint')
} catch (error) {
  // Option 1: Automatically handle the error
  const wasLoggedOut = await handleAuthError(error.data)
  if (!wasLoggedOut) {
    // Show error to user, they're still logged in
    alert.value.message = error.data?.message
  }

  // Option 2: Just check if logout should happen
  const classification = classifyAuthError(error.data)
  if (classification.shouldLogout) {
    // Handle logout
  } else {
    // Handle other error types
    console.log('Error type:', classification.errorType)
    console.log('Reason:', classification.reason)
  }
}
</script>
```

### Error Classification Logic

The system examines both the HTTP status code and the error message to classify errors:

#### Status Code Analysis

| Status | Default Action | Reasoning |
|--------|---------------|-----------|
| 401    | Logout        | Unauthorized - typically means invalid/expired token |
| 403    | No Logout     | Forbidden - user is authenticated but lacks permission |
| 407    | Logout        | Proxy authentication required |
| Others | No Logout     | Not authentication-related |

#### Message Analysis

The system also examines error messages for specific indicators:

**Token Expired Indicators** (→ Logout):
- "token expired"
- "jwt expired"
- "session expired"
- "authentication expired"

**Token Invalid Indicators** (→ Logout):
- "invalid token"
- "invalid credentials"
- "authentication failed"
- "token not found"
- "missing token"

**Authorization Indicators** (→ No Logout):
- "forbidden"
- "access denied"
- "insufficient permissions"
- "not authorized"
- "permission denied"

## Migration Guide

### For Backend API Endpoints

The existing server endpoints already use `forceLogoutHelper`, so they will automatically benefit from the improved logic. No changes needed.

### For Frontend Vue Pages

**Before:**
```vue
<script setup>
const forcingLogout = async () => {
  await $fetch('/api/idempiere-auth/logout', {
    method: 'POST',
    headers: useRequestHeaders(['cookie'])
  })
  await navigateTo('/signin')
}

onBeforeMount(() => {
  if(Number(countries.value?.status || 200) === 401) {
    forcingLogout()
  }
})
```

**After:**
```vue
<script setup>
const { handleAuthError } = useAuthError()

onBeforeMount(async () => {
  if (countries.value?.status) {
    await handleAuthError(countries.value)
  }
})
```

Or for more control:
```vue
<script setup>
const { shouldLogoutOnError, performLogout } = useAuthError()

onBeforeMount(async () => {
  if (shouldLogoutOnError(countries.value)) {
    await performLogout()
  } else {
    // Show error message to user but keep them logged in
    showError(countries.value?.message)
  }
})
```

## Benefits

1. **Better User Experience** - Users aren't logged out unnecessarily
2. **Clearer Error Messages** - Users understand why they can't access something
3. **Easier Debugging** - Classification logging helps identify issues
4. **Security Best Practice** - Follows principle of least surprise
5. **Maintainability** - Centralized logic easier to update

## Testing Recommendations

Test these scenarios to ensure proper behavior:

1. **Expired Token** - Should logout ✓
2. **Invalid Token** - Should logout ✓
3. **Permission Denied (403)** - Should NOT logout ✓
4. **Resource Not Found (404)** - Should NOT logout ✓
5. **Validation Error (400)** - Should NOT logout ✓
6. **Server Error (500)** - Should NOT logout ✓
7. **Network Error** - Should NOT logout ✓

## Development Mode Logging

In development mode, the classification logic logs detailed information:

```
[forceLogoutHelper] Error classification: {
  status: 403,
  errorType: 'authorization',
  shouldLogout: false,
  reason: 'Access forbidden - likely a permissions issue, not authentication'
}
```

This helps debug issues and tune the classification logic if needed.

## Future Improvements

Potential enhancements:

1. **Configurable Retry Logic** - Auto-retry on transient errors
2. **Error Recovery Strategies** - Different handling per error type
3. **Metrics/Analytics** - Track error types and frequencies
4. **Custom Error Messages** - User-friendly messages per error type
5. **Token Refresh Strategy** - Attempt refresh before logout for expired tokens
