403Webshell
Server IP : 65.108.144.40  /  Your IP : 216.73.217.165
Web Server : Apache/2.4.52 (Ubuntu)
System : Linux ubuntu-8gb-hel1-1 5.15.0-173-generic #183-Ubuntu SMP Fri Mar 6 13:29:34 UTC 2026 x86_64
User : dev ( 1000)
PHP Version : 8.2.30
Disable Function : NONE
MySQL : OFF  |  cURL : ON  |  WGET : ON  |  Perl : ON  |  Python : ON  |  Sudo : ON  |  Pkexec : ON
Directory :  /var/www/html/project-slim/

Upload File :
current_dir [ Writeable ] document_root [ Writeable ]

 

Command :


[ Back ]     

Current File : /var/www/html/project-slim//AUTHENTICATION_FLOW.md
# Authentication Flow Documentation

## Overview

This document outlines the complete authentication flow for the Slim Framework 4 API, detailing how data is processed through each step from initial request to final response.

## Table of Contents

1. [System Architecture](#system-architecture)
2. [Authentication Endpoints](#authentication-endpoints)
3. [Registration Flow](#registration-flow)
4. [Login Flow](#login-flow)
5. [Token Management](#token-management)
6. [Middleware Protection](#middleware-protection)
7. [Password Management](#password-management)
8. [Data Flow Diagrams](#data-flow-diagrams)
9. [Error Handling](#error-handling)
10. [Security Features](#security-features)

## System Architecture

### Core Components

```
┌─────────────────┐    ┌─────────────────┐    ┌─────────────────┐
│   Client App    │───▶│  Slim Router    │───▶│ AuthController  │
└─────────────────┘    └─────────────────┘    └─────────────────┘
                                                       │
                                                       ▼
┌─────────────────┐    ┌─────────────────┐    ┌─────────────────┐
│  JWT Response   │◀───│   AuthService   │───▶│  AuthValidator  │
└─────────────────┘    └─────────────────┘    └─────────────────┘
                               │                       │
                               ▼                       ▼
                    ┌─────────────────┐    ┌─────────────────┐
                    │ UserRepository  │    │ BaseValidator   │
                    └─────────────────┘    └─────────────────┘
                               │
                               ▼
                    ┌─────────────────┐
                    │    Database     │
                    └─────────────────┘
```

### File Structure

```
app/
├── Controllers/
│   └── AuthController.php       # HTTP request handling and response
├── Services/
│   └── AuthService.php         # Business logic and JWT management
├── Validators/
│   ├── BaseValidator.php       # Core validation framework
│   └── AuthValidator.php       # Authentication-specific validation
├── Middleware/
│   └── AuthMiddleware.php      # JWT token verification
├── Routes/Groups/
│   └── AuthGroup.php          # Authentication route definitions
└── Exceptions/
    └── ValidationException.php # Custom validation exception handling
```

## Authentication Endpoints

### Public Endpoints (No Authentication Required)

| Method | Endpoint | Purpose |
|--------|----------|---------|
| POST | `/auth/login` | User authentication |
| POST | `/auth/register` | User registration |
| POST | `/auth/refresh` | Token refresh |
| POST | `/auth/forgot-password` | Password reset request |
| POST | `/auth/reset-password` | Password reset with token |
| GET | `/auth/verify-email/{token}` | Email verification |
| POST | `/auth/resend-verification` | Resend verification email |

### Protected Endpoints (Authentication Required)

| Method | Endpoint | Purpose |
|--------|----------|---------|
| POST | `/auth/logout` | User logout |
| POST | `/auth/change-password` | Password change |
| GET | `/auth/check` | Authentication status |
| POST | `/auth/2fa/setup` | Two-factor authentication setup |
| POST | `/auth/2fa/verify` | Two-factor authentication verification |
| POST | `/auth/2fa/disable` | Disable two-factor authentication |
| GET | `/auth/sessions` | Get active sessions |
| DELETE | `/auth/sessions/all` | Revoke all sessions |
| DELETE | `/auth/sessions/{id}` | Revoke specific session |
| GET | `/auth/profile` | Get user profile |
| PUT | `/auth/profile` | Update user profile |

## Registration Flow

### Step-by-Step Process

#### 1. HTTP Request Reception
```
POST /auth/register
Content-Type: application/json

{
  "first_name": "John",
  "last_name": "Doe",
  "email": "john.doe@example.com",
  "password": "SecurePass123!",
  "phone": "+1234567890",
  "company_id": 1
}
```

#### 2. Route Processing
- **File**: `app/Routes/Groups/AuthGroup.php`
- **Action**: Router matches `/auth/register` to `AuthController::register`
- **Method**: POST request routed to controller

#### 3. Controller Layer (`AuthController::register`)
```php
public function register(Request $request, Response $response): Response
{
    try {
        // Extract request data
        $data = $request->getParsedBody();
        
        // Call service layer
        $user = $this->authService->register($data);
        
        // Return success response
        return $this->successResponse($response, $user, 'Registration successful', 201);
    } catch (\Exception $e) {
        return $this->handleException($response, $e);
    }
}
```

#### 4. Service Layer (`AuthService::register`)
```php
public function register(array $data): array
{
    // 1. Validate input data
    $this->authValidator->validateRegister($data);
    
    // 2. Check for existing email
    $existingUser = $this->userRepo->findByEmail($data['email']);
    if ($existingUser) {
        throw new ValidationException("Email already exists", 
            ['email' => 'This email is already registered']);
    }
    
    // 3. Hash password
    $data['password'] = $this->hashPassword($data['password']);
    
    // 4. Create user record
    $user = $this->userRepo->create($data);
    
    // 5. Generate verification token
    $verificationToken = $this->generateVerificationToken($user);
    
    return [
        'user' => $user->toArray(),
        'message' => 'User registered successfully. Please verify your email.',
        'verification_token' => $verificationToken
    ];
}
```

#### 5. Validation Layer (`AuthValidator::validateRegister`)

**Comprehensive Validation Rules:**

```php
public function validateRegister(array $data): void
{
    $this->data = $data;
    $this->clearErrors();

    // Name validation
    $this->required('first_name', 'First name is required')
         ->minLength('first_name', 2, 'First name must be at least 2 characters')
         ->maxLength('first_name', 50, 'First name must not exceed 50 characters')
         ->regex('first_name', '/^[a-zA-Z\s\-\'\.]+$/', 'Invalid characters in first name');

    $this->required('last_name', 'Last name is required')
         ->minLength('last_name', 2, 'Last name must be at least 2 characters')
         ->maxLength('last_name', 50, 'Last name must not exceed 50 characters')
         ->regex('last_name', '/^[a-zA-Z\s\-\'\.]+$/', 'Invalid characters in last name');

    // Email validation
    $this->required('email', 'Email address is required')
         ->email('email', 'Please enter a valid email address')
         ->maxLength('email', 255, 'Email address too long');

    // Strong password validation
    $this->required('password', 'Password is required')
         ->strongPassword('password');

    // Optional phone validation
    if (isset($data['phone']) && !empty($data['phone'])) {
        $this->phone('phone', 'Please enter a valid phone number');
    }

    // Company ID validation
    if (isset($data['company_id'])) {
        $this->integer('company_id', 'Company ID must be a valid integer')
             ->min('company_id', 1, 'Company ID must be positive');
    }

    $this->throwIfErrors('Registration validation failed');
}
```

**Strong Password Requirements:**
- Minimum 8 characters
- At least one uppercase letter
- At least one lowercase letter
- At least one number
- At least one special character (!@#$%^&*()_+-=[]{}|;:,.<>?)

#### 6. Repository Layer
- **Action**: User data inserted into database
- **Validation**: Database constraints applied
- **Result**: User entity returned with auto-generated ID

#### 7. Response Generation
```json
{
  "status": "success",
  "message": "Registration successful",
  "data": {
    "user": {
      "id": 123,
      "first_name": "John",
      "last_name": "Doe",
      "email": "john.doe@example.com",
      "phone": "+1234567890",
      "company_id": 1,
      "created_at": "2025-09-15T10:30:00Z",
      "updated_at": "2025-09-15T10:30:00Z"
    },
    "message": "User registered successfully. Please verify your email.",
    "verification_token": "eyJ0eXAiOiJKV1QiLCJhbGciOiJIUzI1NiJ9..."
  }
}
```

## Login Flow

### Step-by-Step Process

#### 1. HTTP Request Reception
```
POST /auth/login
Content-Type: application/json

{
  "email": "john.doe@example.com",
  "password": "SecurePass123!"
}
```

#### 2. Route Processing
- **File**: `app/Routes/Groups/AuthGroup.php`
- **Action**: Router matches `/auth/login` to `AuthController::login`

#### 3. Controller Layer (`AuthController::login`)
```php
public function login(Request $request, Response $response): Response
{
    try {
        $data = $request->getParsedBody();
        
        // Basic validation
        if (!isset($data['email']) || !isset($data['password'])) {
            return $this->validationErrorResponse($response, [
                'email' => 'Email is required',
                'password' => 'Password is required'
            ]);
        }

        // Process login
        $result = $this->authService->login($data['email'], $data['password']);

        if (!$result) {
            return $this->unauthorizedResponse($response, 'Invalid credentials');
        }

        return $this->successResponse($response, $result, 'Login successful');
    } catch (\Exception $e) {
        return $this->handleException($response, $e);
    }
}
```

#### 4. Service Layer (`AuthService::login`)
```php
public function login(string $email, string $password): array
{
    // 1. Validate login data
    $this->authValidator->validateLogin(['email' => $email, 'password' => $password]);
    
    // 2. Find user by email
    $user = $this->userRepo->findByEmail($email);
    
    // 3. Verify credentials
    if (!$user || !$this->verifyPassword($password, $user->password_hash)) {
        throw new UnauthorizedException("Invalid credentials");
    }
    
    // 4. Check account status
    if (!$user->isActive()) {
        throw new UnauthorizedException("Account is not active");
    }
    
    // 5. Generate JWT tokens
    $tokens = $this->generateTokens($user);
    
    return [
        'access_token' => $tokens['access_token'],
        'refresh_token' => $tokens['refresh_token'],
        'token_type' => 'Bearer',
        'expires_in' => $this->jwtConfig['expiry'],
        'user' => $user->toArray()
    ];
}
```

#### 5. Password Verification Process
```php
private function verifyPassword(string $password, string $hash): bool
{
    return password_verify($password, $hash);
}
```

#### 6. JWT Token Generation
```php
private function generateTokens($user): array
{
    $now = time();
    $expiry = $now + $this->jwtConfig['expiry'];
    
    // Access token payload
    $accessPayload = [
        'iss' => $this->jwtConfig['issuer'],
        'sub' => $user->id,
        'iat' => $now,
        'exp' => $expiry,
        'type' => 'access',
        'user_id' => $user->id,
        'email' => $user->email,
        'role' => $user->role
    ];
    
    // Refresh token payload (longer expiry)
    $refreshPayload = [
        'iss' => $this->jwtConfig['issuer'],
        'sub' => $user->id,
        'iat' => $now,
        'exp' => $now + ($this->jwtConfig['expiry'] * 7), // 7x longer
        'type' => 'refresh',
        'user_id' => $user->id
    ];
    
    return [
        'access_token' => JWT::encode($accessPayload, $this->jwtConfig['secret'], $this->jwtConfig['algorithm']),
        'refresh_token' => JWT::encode($refreshPayload, $this->jwtConfig['secret'], $this->jwtConfig['algorithm'])
    ];
}
```

#### 7. Successful Login Response
```json
{
  "status": "success",
  "message": "Login successful",
  "data": {
    "access_token": "eyJ0eXAiOiJKV1QiLCJhbGciOiJIUzI1NiJ9...",
    "refresh_token": "eyJ0eXAiOiJKV1QiLCJhbGciOiJIUzI1NiJ9...",
    "token_type": "Bearer",
    "expires_in": 3600,
    "user": {
      "id": 123,
      "first_name": "John",
      "last_name": "Doe",
      "email": "john.doe@example.com",
      "role": "user",
      "is_active": true
    }
  }
}
```

## Token Management

### Access Token Structure
```json
{
  "iss": "your-app.com",
  "sub": "123",
  "iat": 1694776800,
  "exp": 1694780400,
  "type": "access",
  "user_id": 123,
  "email": "john.doe@example.com",
  "role": "user"
}
```

### Refresh Token Structure
```json
{
  "iss": "your-app.com",
  "sub": "123",
  "iat": 1694776800,
  "exp": 1695381600,
  "type": "refresh",
  "user_id": 123
}
```

### Token Refresh Flow

#### 1. Refresh Request
```
POST /auth/refresh
Content-Type: application/json

{
  "refresh_token": "eyJ0eXAiOiJKV1QiLCJhbGciOiJIUzI1NiJ9..."
}
```

#### 2. Token Validation and Refresh
```php
public function refreshToken(string $refreshToken): array
{
    try {
        // Decode and validate refresh token
        $decoded = JWT::decode($refreshToken, new Key($this->jwtConfig['secret'], $this->jwtConfig['algorithm']));
        
        // Verify token type
        if ($decoded->type !== 'refresh') {
            throw new UnauthorizedException("Invalid refresh token");
        }
        
        // Verify user still exists and is active
        $user = $this->userRepo->findById($decoded->user_id);
        if (!$user || !$user->isActive()) {
            throw new UnauthorizedException("User not found or inactive");
        }
        
        // Generate new token pair
        $tokens = $this->generateTokens($user);
        
        return [
            'access_token' => $tokens['access_token'],
            'refresh_token' => $tokens['refresh_token'],
            'token_type' => 'Bearer',
            'expires_in' => $this->jwtConfig['expiry']
        ];
    } catch (\Exception $e) {
        throw new UnauthorizedException("Invalid refresh token");
    }
}
```

## Middleware Protection

### AuthMiddleware Flow

#### 1. Request Interception
```php
public function __invoke(Request $request, RequestHandler $handler): Response
{
    // Extract Authorization header
    $authHeader = $request->getHeaderLine('Authorization');
    
    if (empty($authHeader)) {
        return $this->unauthorizedResponse('Authorization header required');
    }
    
    // Validate Bearer format
    if (!preg_match('/Bearer\s+(.*)$/i', $authHeader, $matches)) {
        return $this->unauthorizedResponse('Invalid authorization header format');
    }
    
    $token = $matches[1];
    
    try {
        // Decode JWT token
        $decoded = JWT::decode($token, new Key($this->jwtConfig['secret'], $this->jwtConfig['algorithm']));
        
        // Verify token type
        if ($decoded->type !== 'access') {
            throw new \Exception('Invalid token type');
        }
        
        // Add user info to request attributes
        $request = $request->withAttribute('user_id', $decoded->user_id);
        $request = $request->withAttribute('user_email', $decoded->email);
        $request = $request->withAttribute('user_role', $decoded->role);
        
        // Continue to next middleware/controller
        return $handler->handle($request);
        
    } catch (\Exception $e) {
        return $this->unauthorizedResponse('Invalid or expired token');
    }
}
```

#### 2. Protected Endpoint Access
```php
// In protected controller methods
public function getProfile(Request $request, Response $response): Response
{
    // Get user ID from middleware
    $userId = $request->getAttribute('user_id');
    
    // Fetch user data
    $user = $this->userService->getUserById($userId);
    
    return $this->successResponse($response, $user);
}
```

## Password Management

### Forgot Password Flow

#### 1. Request Reset
```
POST /auth/forgot-password
Content-Type: application/json

{
  "email": "john.doe@example.com"
}
```

#### 2. Generate Reset Token
```php
public function forgotPassword(string $email): array
{
    $user = $this->userRepo->findByEmail($email);
    
    if (!$user) {
        // Return success even if user not found (security)
        return ['message' => 'If the email exists, a reset link has been sent'];
    }
    
    // Generate secure reset token
    $resetToken = $this->generatePasswordResetToken($user);
    
    // Store token with expiry (typically 1 hour)
    $this->storePasswordResetToken($user->id, $resetToken);
    
    // Send email (in real implementation)
    // $this->emailService->sendPasswordResetEmail($user, $resetToken);
    
    return [
        'message' => 'Password reset instructions sent to your email',
        'reset_token' => $resetToken // Remove in production
    ];
}
```

#### 3. Reset Password
```
POST /auth/reset-password
Content-Type: application/json

{
  "token": "secure_reset_token_here",
  "password": "NewSecurePass123!",
  "password_confirmation": "NewSecurePass123!"
}
```

```php
public function resetPassword(array $data): array
{
    // Validate reset data
    $this->authValidator->validatePasswordReset($data);
    
    // Verify reset token
    $userId = $this->verifyPasswordResetToken($data['token']);
    if (!$userId) {
        throw new ValidationException("Invalid or expired reset token");
    }
    
    // Hash new password
    $hashedPassword = $this->hashPassword($data['password']);
    
    // Update user password
    $this->userRepo->updatePassword($userId, $hashedPassword);
    
    // Invalidate reset token
    $this->invalidatePasswordResetToken($data['token']);
    
    return ['message' => 'Password reset successfully'];
}
```

## Data Flow Diagrams

### Registration Data Flow
```
┌─────────────┐    ┌─────────────┐    ┌─────────────┐
│   Client    │───▶│   Router    │───▶│ Controller  │
│             │    │             │    │             │
│ POST /auth/ │    │ Match Route │    │ Extract     │
│ register    │    │             │    │ Request     │
└─────────────┘    └─────────────┘    └─────────────┘
                                             │
                                             ▼
┌─────────────┐    ┌─────────────┐    ┌─────────────┐
│  Database   │◀───│ Repository  │◀───│   Service   │
│             │    │             │    │             │
│ INSERT user │    │ Create User │    │ Business    │
│             │    │             │    │ Logic       │
└─────────────┘    └─────────────┘    └─────────────┘
                                             ▲
                                             │
                           ┌─────────────────┴─────────────┐
                           │                               │
                           ▼                               ▼
                    ┌─────────────┐                ┌─────────────┐
                    │  Validator  │                │ Hash/Token  │
                    │             │                │ Generation  │
                    │ Validate    │                │             │
                    │ Input       │                │             │
                    └─────────────┘                └─────────────┘
```

### Login Data Flow
```
┌─────────────┐    ┌─────────────┐    ┌─────────────┐
│   Client    │───▶│   Router    │───▶│ Controller  │
│             │    │             │    │             │
│ POST /auth/ │    │ Match Route │    │ Extract     │
│ login       │    │             │    │ Credentials │
└─────────────┘    └─────────────┘    └─────────────┘
                                             │
                                             ▼
┌─────────────┐    ┌─────────────┐    ┌─────────────┐
│ JWT Token   │◀───│   Service   │───▶│  Validator  │
│ Response    │    │             │    │             │
│             │    │ Verify      │    │ Validate    │
│             │    │ Password    │    │ Input       │
└─────────────┘    └─────────────┘    └─────────────┘
                           │                   ▲
                           ▼                   │
                    ┌─────────────┐    ┌─────────────┐
                    │ Repository  │───▶│  Database   │
                    │             │    │             │
                    │ Find User   │    │ SELECT user │
                    │ by Email    │    │ by email    │
                    └─────────────┘    └─────────────┘
```

### Protected Route Access Flow
```
┌─────────────┐    ┌─────────────┐    ┌─────────────┐
│   Client    │───▶│   Router    │───▶│ Middleware  │
│             │    │             │    │             │
│ GET /auth/  │    │ Match Route │    │ Extract &   │
│ profile     │    │             │    │ Verify JWT  │
│             │    │             │    │ Token       │
└─────────────┘    └─────────────┘    └─────────────┘
                                             │
                                    ┌────────┴────────┐
                                    │ Valid Token?    │
                                    └────────┬────────┘
                                       Yes   │   No
                              ┌──────────────┼───────────────┐
                              ▼              ▼               ▼
                    ┌─────────────┐    ┌─────────────┐ ┌─────────────┐
                    │ Controller  │    │ 401 Error   │ │ Return      │
                    │             │    │ Response    │ │ Unauthorized│
                    │ Process     │    │             │ │             │
                    │ Request     │    │             │ │             │
                    └─────────────┘    └─────────────┘ └─────────────┘
```

## Error Handling

### Validation Errors
```json
{
  "status": "error",
  "message": "Validation failed",
  "errors": {
    "email": ["Please enter a valid email address"],
    "password": ["Password must be at least 8 characters long", "Password must contain at least one uppercase letter"]
  }
}
```

### Authentication Errors
```json
{
  "status": "error",
  "message": "Invalid credentials",
  "code": 401
}
```

### Authorization Errors
```json
{
  "status": "error",
  "message": "Access denied. Insufficient permissions",
  "code": 403
}
```

### Token Errors
```json
{
  "status": "error",
  "message": "Invalid or expired token",
  "code": 401
}
```

## Security Features

### Password Security
- **Hashing**: bcrypt with automatic salt generation
- **Strength Requirements**: Enforced through validation
- **Password History**: Prevent reuse of recent passwords (future enhancement)

### JWT Security
- **Algorithm**: HMAC SHA-256 (HS256)
- **Secret Key**: Environment-specific secret
- **Token Expiry**: Short-lived access tokens (1 hour)
- **Refresh Tokens**: Longer-lived for token renewal (7 days)

### Request Security
- **Rate Limiting**: Prevent brute force attacks (future enhancement)
- **CORS**: Configured for specific origins
- **HTTPS**: Enforced in production
- **Input Sanitization**: Comprehensive validation

### Session Security
- **Token Blacklisting**: Logout invalidates tokens (future enhancement)
- **Session Management**: Track and manage active sessions
- **Concurrent Sessions**: Limit simultaneous logins (configurable)

## Configuration

### Environment Variables
```env
# JWT Configuration
JWT_SECRET=your_super_secure_secret_key_here
JWT_ISSUER=your-app.com
JWT_EXPIRY=3600

# Database Configuration
DB_HOST=localhost
DB_NAME=your_database
DB_USER=your_username
DB_PASS=your_password

# Email Configuration (for verification/reset)
SMTP_HOST=smtp.gmail.com
SMTP_PORT=587
SMTP_USER=your_email@gmail.com
SMTP_PASS=your_password
```

### Security Headers
```php
// Add to middleware or global configuration
$response = $response
    ->withHeader('X-Content-Type-Options', 'nosniff')
    ->withHeader('X-Frame-Options', 'DENY')
    ->withHeader('X-XSS-Protection', '1; mode=block')
    ->withHeader('Strict-Transport-Security', 'max-age=31536000; includeSubDomains');
```

This documentation provides a comprehensive overview of the authentication system architecture, data flow, and security implementation. The system follows industry best practices for secure authentication and authorization in modern web applications.

Youez - 2016 - github.com/yon3zu
LinuXploit