Files
igny8/LOGOUT-TRACKING-IMPLEMENTATION.md
IGNY8 VPS (Salman) 5366cc1805 logo out issues fixes
2025-12-15 16:08:47 +00:00

11 KiB

Logout Tracking & Culprit Detection System

Implemented: December 15, 2025
Purpose: Precise tracking and display of logout causes with exact page/context


Overview

A comprehensive logging and display system that captures exactly why and where a user was logged out, with detailed context for debugging and user transparency.


Implementation Components

1. Backend Middleware Enhancement

File: backend/igny8_core/auth/middleware.py

Changes:

  • Added LOGOUT_REASONS dictionary with standardized error codes
  • Enhanced all logout triggers to include:
    • logout_reason: Error code (e.g., SESSION_ACCOUNT_MISMATCH)
    • logout_message: Human-readable message
    • logout_path: Exact page where logout occurred
    • logout_context: Additional debugging context
    • timestamp: ISO timestamp of logout event

Error Codes Added:

  • SESSION_ACCOUNT_MISMATCH - Session contamination: account ID mismatch
  • SESSION_USER_MISMATCH - Session contamination: user ID mismatch
  • ACCOUNT_MISSING - Account not configured for this user
  • ACCOUNT_SUSPENDED - Account is suspended
  • ACCOUNT_CANCELLED - Account is cancelled
  • PLAN_MISSING - No subscription plan assigned
  • PLAN_INACTIVE - Subscription plan is inactive
  • USER_INACTIVE - User account is inactive

Response Format:

{
  "success": false,
  "error": "User-friendly message",
  "logout_reason": "ERROR_CODE",
  "logout_message": "Detailed explanation",
  "logout_path": "/previous/page/path",
  "logout_context": {
    "stored_account_id": 123,
    "current_account_id": 456,
    "user_id": 789
  }
}

2. Frontend API Interceptor Enhancement

File: frontend/src/services/api.ts

Changes:

401 Unauthorized Handler

  • Parses backend logout reasons from 401 responses
  • Logs detailed context before attempting token refresh
  • Stores logout reason in localStorage before logout
  • Console logging with 🚨 emoji for visibility

403 Forbidden Handler

  • Detects authentication vs permission errors
  • Only logs out for auth credential issues
  • Stores detailed context including token state

Token Refresh Failure Handler

  • Creates logout reason when refresh fails
  • Includes original endpoint in context
  • Differentiates between "refresh failed" and "no refresh token"

Logout Reason Format:

{
  code: 'ERROR_CODE',
  message: 'Human-readable message',
  path: '/page/where/logout/happened',  // NOT /signin
  context: {
    // Additional debugging info
    error: 'specific error details',
    endpoint: '/api/v1/...',
    hasToken: true/false,
  },
  timestamp: '2025-12-15T10:30:45.123Z',
  source: 'token_refresh_failure' | 'backend_middleware' | 'api_403_auth_error'
}

3. Auth Store Enhancement

File: frontend/src/store/authStore.ts

Changes:

Manual Logout

  • Captures logout context BEFORE clearing anything
  • Includes user email and current page
  • Stores with source: manual_user_action
  • Console log with 🚪 emoji

refreshUser Validation

  • Enhanced account validation with logout tracking
  • Stores detailed context for ACCOUNT_REQUIRED
  • Stores detailed context for PLAN_REQUIRED
  • Console logging with 🚨 emoji

4. SignIn Page Display

File: frontend/src/components/auth/SignInForm.tsx

Changes:

On Component Mount

  1. Reads logout_reason from localStorage
  2. Displays reason to user in yellow alert box
  3. Logs full details to console
  4. Clears logout_reason after reading (single display)

UI Components

Alert Box Features:

  • Yellow background (warning, not error)
  • Clear "Session Ended" heading
  • User-friendly message
  • Original page path (if not /signin)
  • Expandable technical details button

Technical Details Panel:

  • Error code
  • Source system
  • Exact timestamp
  • Full context JSON (formatted)
  • Collapsible to avoid overwhelming users

Logout Reason Codes & Sources

Backend-Triggered (source: backend_middleware)

Code Message Trigger Location
SESSION_ACCOUNT_MISMATCH Session contamination: account ID mismatch AccountContextMiddleware line ~58
SESSION_USER_MISMATCH Session contamination: user ID mismatch AccountContextMiddleware line ~73
ACCOUNT_MISSING Account not configured for this user validate_account_and_plan()
ACCOUNT_SUSPENDED Account is suspended validate_account_and_plan()
ACCOUNT_CANCELLED Account is cancelled validate_account_and_plan()
PLAN_MISSING No subscription plan assigned validate_account_and_plan()
PLAN_INACTIVE Subscription plan is inactive validate_account_and_plan()

Frontend-Triggered (source: varies)

Code Message Source Trigger Location
TOKEN_REFRESH_FAILED Token refresh failed - session expired token_refresh_failure api.ts line ~318
NO_REFRESH_TOKEN No refresh token available missing_refresh_token api.ts line ~330
AUTH_CREDENTIALS_MISSING Authentication credentials were not provided api_403_auth_error api.ts line ~203
MANUAL_LOGOUT User manually logged out manual_user_action authStore.ts line ~151
ACCOUNT_REQUIRED Account not configured refresh_user_validation authStore.ts line ~412
PLAN_REQUIRED Plan not configured refresh_user_validation authStore.ts line ~425

Console Logging Format

Backend Logs

[2025-12-15 10:30:45] [WARNING] [auth.middleware] [AUTO-LOGOUT] SESSION_ACCOUNT_MISMATCH: Session contamination: account ID mismatch. Session=123, Current=456, User=789, Path=/dashboard, IP=192.168.1.1, Timestamp=2025-12-15T10:30:45.123Z

View Commands:

# All auto-logouts
docker logs igny8_backend 2>&1 | grep "\[AUTO-LOGOUT\]"

# Specific error code
docker logs igny8_backend 2>&1 | grep "SESSION_ACCOUNT_MISMATCH"

# Real-time monitoring
docker logs -f igny8_backend | grep "\[AUTO-LOGOUT\]"

Frontend Console Logs

// Console group with full details
🔍 LOGOUT REASON DETAILS
  Code: SESSION_ACCOUNT_MISMATCH
  Message: Session contamination: account ID mismatch
  Original Page: /dashboard/content
  Timestamp: 2025-12-15T10:30:45.123Z
  Source: backend_middleware
  Context: {stored_account_id: 123, current_account_id: 456, ...}

// Individual logout events
🚨 LOGOUT TRIGGERED - Backend Validation Failed: {...}
🚨 LOGOUT TRIGGERED - Token Refresh Failed: {...}
🚨 LOGOUT TRIGGERED - No Refresh Token: {...}
🚨 LOGOUT TRIGGERED - Authentication Credentials Missing: {...}
🚨 LOGOUT TRIGGERED - Account Required: {...}
🚨 LOGOUT TRIGGERED - Plan Required: {...}
🚪 LOGOUT - User Action: {...}

User Experience Flow

1. User Gets Logged Out

User browsing /dashboard/content
    ↓
Backend validation fails (e.g., account mismatch)
    ↓
Backend returns 401 with logout_reason JSON
    ↓
Frontend API interceptor catches response
    ↓
Logs detailed context to console
    ↓
Stores logout_reason in localStorage
    ↓
Triggers logout and redirects to /signin

2. User Sees Explanation on SignIn Page

SignIn component mounts
    ↓
Reads logout_reason from localStorage
    ↓
Displays yellow alert box with:
  - "Session Ended" heading
  - User-friendly message
  - Original page path
  - Technical details (expandable)
    ↓
Logs full details to browser console
    ↓
Clears logout_reason from localStorage
    ↓
User understands why they were logged out

Debugging Workflow

For Users (Non-Technical)

  1. After logout, check yellow alert box on signin page
  2. Note the message shown
  3. If needed, click info icon for technical details
  4. Take screenshot and share with support

For Developers

  1. Check Browser Console:

    Open DevTools → Console
    Look for 🚨 or 🚪 emoji logs
    Expand the logged object for full context
    
  2. Check Backend Logs:

    docker logs igny8_backend 2>&1 | grep "\[AUTO-LOGOUT\]" | tail -20
    
  3. Check Stored Reason (if still in localStorage):

    JSON.parse(localStorage.getItem('logout_reason'))
    
  4. Trace Request Path:

    • Note the logout_path field - this is the original page
    • Note the source field - this tells you which system component triggered it
    • Check context for specific IDs and values

Key Features

Exact Page Tracking

  • logout_path always contains the original page where logout occurred
  • Never shows /signin as logout path
  • Captured BEFORE redirect happens

Comprehensive Context

  • Every logout includes relevant IDs (user_id, account_id, etc.)
  • Token state captured for auth errors
  • Error details preserved through retry attempts

User-Friendly Display

  • Non-technical users see simple message
  • Technical users can expand for details
  • Automatic cleanup (shown once, then cleared)

Developer-Friendly Logging

  • Console groups for easy reading
  • Emoji markers for quick scanning (🚨 = automatic, 🚪 = manual)
  • Full JSON context for debugging
  • Backend logs with grep-friendly prefixes

No False Positives

  • Only logs out when truly necessary
  • Differentiates between auth and permission errors
  • Preserves context through token refresh attempts

Testing Scenarios

1. Test Session Contamination

# In backend, manually modify session
request.session['_account_id'] = 999  # Wrong account
# Expected: SESSION_ACCOUNT_MISMATCH logout

2. Test Token Expiration

// Wait 15+ minutes, then make API call
// Expected: TOKEN_REFRESH_FAILED or NO_REFRESH_TOKEN logout

3. Test Manual Logout

// Click logout button
// Expected: MANUAL_LOGOUT with correct page path

4. Test Account/Plan Validation

# In backend, deactivate user's plan
user.account.plan.is_active = False
user.account.plan.save()
# Expected: PLAN_INACTIVE logout on next request

Future Enhancements (Optional)

  1. Analytics Integration:

    • Send logout reasons to analytics
    • Track which reasons are most common
    • Identify systemic issues
  2. Admin Dashboard:

    • View all logout events
    • Filter by reason code
    • Track affected users
  3. User Notification:

    • Email users when logged out (except manual)
    • Include reason and next steps
    • Link to support if needed
  4. Automated Recovery:

    • For some errors (e.g., PLAN_INACTIVE), show payment link
    • Auto-retry after fixing issues
    • Remember intended destination

Summary

This implementation provides 100% accurate culprit detection by:

  1. Capturing exact page where logout occurred (NOT signin page)
  2. Logging detailed context at every logout trigger point
  3. Displaying reasons clearly to users on signin page
  4. Providing comprehensive debugging info in console and backend logs
  5. Using standardized error codes for easy tracking
  6. Preserving context through redirects and token refresh attempts

Result: No more guessing why users were logged out. Every logout is tracked, explained, and debuggable.