# All files / src/hooks useAuth.ts

0% Statements 0/49
0% Branches 0/14
0% Functions 0/7
0% Lines 0/49

Press n or j to go to the next uncovered block, b, p or k for the previous block.

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37
    38
    39
    40
    41
    42
    43
    44
    45
    46
    47
    48
    49
    50
    51
    52
    53
    54
    55
    56
    57
    58
    59
    60
    61
    62
    63
    64
    65
    66
    67
    68
    69
    70
    71
    72
    73
    74
    75
    76
    77
    78
    79
    80
    81
    82
    83
    84
    85
    86
    87
    88
    89
    90
    91
    92
    93
    94
    95
    96
    97
    98
    99
    100
    101
    102
    103
    104
    105
    106
    107
    108
    109
    110
    111
    112
    113
    114
    115
    116
    117
    118
    119
    120
    121
    122
    123
    124
    125
    126
    127

     // Authentication hook

    'use client';

    import { useState, useEffect, useCallback } from 'react';
    import { authService } from '@/services';
    import { authCleanup } from '@/utils/authCleanup';
    import { User, LoginRequest, UserRole } from '@/types';
    import { normalizeRole } from '@/utils/auth';

    interface UseAuthReturn {
      user: User | null;
      isAuthenticated: boolean;
      isLoading: boolean;
      login: (credentials: LoginRequest) => Promise<{ success: boolean; error?: string }>;
      logout: () => Promise<void>;
      hasRole: (role: UserRole) => boolean;
      hasAnyRole: (roles: UserRole[]) => boolean;
    }

    export function useAuth(): UseAuthReturn {
      const [user, setUser] = useState<User | null>(null);
      const [isLoading, setIsLoading] = useState(true);

      const isAuthenticated = !!user;

      // Initialize auth state
      useEffect(() => {
        const initAuth = () => {
          try {
            const storedUser = authService.getStoredUser();
            const hasToken = authService.isAuthenticated();

            if (storedUser && hasToken) {
              // Normalize stored user role and ensure defaults
              const roleNormalized = normalizeRole((storedUser as any).role as any);
              const userWithDefaults: User = {
                ...(storedUser as any),
                role: roleNormalized,
                active: (storedUser as any).active ?? true,
                created_at: (storedUser as any).created_at ?? new Date().toISOString()};
              setUser(userWithDefaults);
            }
          } catch (err) {
            console.error('Error initializing auth:', err);
            // Clear potentially corrupted data
            authService.clearStoredUser();
          } finally {
            setIsLoading(false);
          }
        };

        initAuth();
      }, []);

      const login = useCallback(async (credentials: LoginRequest) => {
        setIsLoading(true);

        try {
          const result = await authService.login(credentials);

          if (result.success) {
            const { token, user: userData } = result.data;

            // Store auth data
            authService.setAuthToken(token);
            authService.setStoredUser(userData);

            // Convert UserInfo to User format
            const userWithDefaults: User = {
              ...userData,
              active: true,
              created_at: new Date().toISOString()};
            setUser(userWithDefaults);

            return { success: true };
          } else {
            return {
              success: false,
              error: result.error.details || 'Login failed'
            };
          }
        } catch {
          return {
            success: false,
            error: 'An unexpected error occurred during login'
          };
        } finally {
          setIsLoading(false);
        }
      }, []);

      const logout = useCallback(async () => {
        setIsLoading(true);

        try {
          // Call logout API (will clear token regardless of response)
          await authService.logout();
        } catch (err) {
          console.error('Logout API error:', err);
        } finally {
          // Always clear local state
          authService.clearStoredUser();
          authCleanup.clearAllAuthData();
          setUser(null);
          setIsLoading(false);
        }
      }, []);

      const hasRole = useCallback((role: UserRole): boolean => {
        return user?.role === role;
      }, [user]);

      const hasAnyRole = useCallback((roles: UserRole[]): boolean => {
        return user ? roles.includes(user.role) : false;
      }, [user]);

      return {
        user,
        isAuthenticated,
        isLoading,
        login,
        logout,
        hasRole,
        hasAnyRole};
    }