import { useCallback } from 'react'; import { usePersSDK } from '../providers/PersSDKProvider'; import type { RawUserData } from '@explorins/pers-sdk/core'; import { AccountOwnerType } from '@explorins/pers-sdk/core'; import type { UserDTO, SessionAuthContextResponseDTO } from '@explorins/pers-sdk'; // Re-export RawUserData for convenience export type { RawUserData }; /** * React hook for authentication operations in the PERS SDK * * Provides methods for user login, logout, token management, and authentication state. * Automatically manages authentication state and user data synchronization. * * @returns Authentication hook with methods and state * * @example * ```typescript * function LoginComponent() { * const { login, logout, isAuthenticated, user } = useAuth(); * * const handleLogin = async (token: string) => { * try { * await login(token, 'user'); * console.log('Login successful'); * } catch (error) { * console.error('Login failed:', error); * } * }; * * return ( *
* {isAuthenticated ? ( *
*

Welcome, {user?.name}

* *
* ) : ( * * )} *
* ); * } * ``` */ export const useAuth = () => { const { sdk, authProvider, isInitialized, isAuthenticated, user, refreshUserData } = usePersSDK(); /** * Authenticates a user with a JWT token * * @param jwtToken - The JWT token to authenticate with * @param userType - The type of user (AccountOwnerType), defaults to USER * @returns Promise resolving to session auth context with user data * @throws Error if SDK is not initialized or authentication fails * * @example * ```typescript * const { login } = useAuth(); * const result = await login(jwtToken, AccountOwnerType.USER); * console.log('Logged in user:', result.user); * ``` */ const login = useCallback(async (jwtToken: string, userType: AccountOwnerType = AccountOwnerType.USER): Promise => { if (!sdk || !authProvider) { throw new Error('SDK not initialized. Call initialize() first.'); } try { // Set token in auth provider await authProvider.setAccessToken(jwtToken); // Perform login - emits login_success event which Provider handles const result = await sdk.auth.loginWithToken(jwtToken, userType); return result; } catch (error) { console.error('Login failed:', error); throw error; } }, [sdk, authProvider]); /** * Logs in a user using raw user data (direct authentication bypass) * * @param rawUserData - Raw user data for direct authentication * @throws Error if SDK is not initialized or authentication fails * * @example * ```typescript * const { loginWithRawData } = useAuth(); * await loginWithRawData({ userId: '123', email: 'user@example.com' }); * ``` */ const loginWithRawData = useCallback(async (rawUserData: RawUserData): Promise => { if (!sdk || !authProvider) { throw new Error('SDK not initialized. Call initialize() first.'); } try { // Use the raw data login - emits login_success event which Provider handles const result = await sdk.auth.loginWithRawData(rawUserData); // Set token from result if (result.accessToken) { await authProvider.setAccessToken(result.accessToken); } } catch (error) { console.error('Raw data login failed:', error); throw error; } }, [sdk, authProvider]); /** * Logs out the current user and clears authentication state * * @throws Error if logout process fails * * @example * ```typescript * const { logout } = useAuth(); * await logout(); * console.log('User logged out'); * ``` */ const logout = useCallback(async (): Promise => { if (!sdk) { throw new Error('SDK not initialized. Call initialize() first.'); } try { // clearAuth emits logout_success event which Provider handles await sdk.auth.clearAuth(); } catch (error) { console.error('Logout failed:', error); throw error; } }, [sdk]); /** * Retrieves the current authenticated user data * * @returns Promise resolving to current user data * @throws Error if SDK is not initialized * * @example * ```typescript * const { getCurrentUser } = useAuth(); * const user = await getCurrentUser(); * console.log('Current user:', user.email); * ``` */ const getCurrentUser = useCallback(async (): Promise => { if (!sdk) { throw new Error('SDK not initialized. Call initialize() first.'); } return sdk.auth.getCurrentUser(); }, [sdk]); /** * Checks if the current session is authenticated * * @returns Promise resolving to authentication status * * @example * ```typescript * const { checkIsAuthenticated } = useAuth(); * const isAuth = await checkIsAuthenticated(); * console.log('Is authenticated:', isAuth); * ``` */ const checkIsAuthenticated = useCallback(async (): Promise => { if (!sdk) { return false; } return sdk.auth.isAuthenticated(); }, [sdk]); /** * Refreshes authentication tokens * * @param refreshToken - Optional refresh token to use * @returns Promise resolving to new session auth response * @throws Error if SDK is not initialized * * @example * ```typescript * const { refreshTokens } = useAuth(); * const tokens = await refreshTokens(); * console.log('Tokens refreshed:', tokens); * ``` */ const refreshTokens = useCallback(async (refreshToken?: string) => { if (!sdk) { throw new Error('SDK not initialized. Call initialize() first.'); } return sdk.auth.refreshTokens(refreshToken); }, [sdk]); /** * Clears all authentication data and resets auth state * * @throws Error if SDK is not initialized * * @example * ```typescript * const { clearAuth } = useAuth(); * await clearAuth(); * console.log('Auth data cleared'); * ``` */ const clearAuth = useCallback(async (): Promise => { if (!sdk) { throw new Error('SDK not initialized. Call initialize() first.'); } // clearAuth emits logout_success event which Provider handles await sdk.auth.clearAuth(); }, [sdk]); /** * Checks if the current authentication is valid (non-expired) * * @returns Boolean indicating if auth is valid * * @example * ```typescript * const { hasValidAuth } = useAuth(); * const isValid = hasValidAuth(); * console.log('Auth is valid:', isValid); * ``` */ const hasValidAuth = useCallback(async (): Promise => { if (!sdk) { return false; } return await sdk.auth.hasValidAuth(); }, [sdk]); return { // State isInitialized, isAuthenticated, user, // Methods login, loginWithRawData, logout, refreshUserData, getCurrentUser, checkIsAuthenticated, refreshTokens, clearAuth, hasValidAuth, }; }; export type AuthHook = ReturnType;