/** * Authentication API endpoints * Handles user login, registration, and logout operations */ import { apiClient } from './client' import type { LoginRequest, RegisterRequest, AuthResponse, CurrentUserResponse, SendVerifyCodeRequest, SendVerifyCodeResponse, PublicSettings, TotpLoginResponse, TotpLogin2FARequest } from '@/types' /** * Login response type - can be either full auth or 2FA required */ export type LoginResponse = AuthResponse | TotpLoginResponse /** * Type guard to check if login response requires 2FA */ export function isTotp2FARequired(response: LoginResponse): response is TotpLoginResponse { return 'requires_2fa' in response && response.requires_2fa === true } /** * Store authentication token in localStorage */ export function setAuthToken(token: string): void { localStorage.setItem('auth_token', token) } /** * Get authentication token from localStorage */ export function getAuthToken(): string | null { return localStorage.getItem('auth_token') } /** * Clear authentication token from localStorage */ export function clearAuthToken(): void { localStorage.removeItem('auth_token') localStorage.removeItem('auth_user') } /** * User login * @param credentials - Email and password * @returns Authentication response with token and user data, or 2FA required response */ export async function login(credentials: LoginRequest): Promise { const { data } = await apiClient.post('/auth/login', credentials) // Only store token if 2FA is not required if (!isTotp2FARequired(data)) { setAuthToken(data.access_token) localStorage.setItem('auth_user', JSON.stringify(data.user)) } return data } /** * Complete login with 2FA code * @param request - Temp token and TOTP code * @returns Authentication response with token and user data */ export async function login2FA(request: TotpLogin2FARequest): Promise { const { data } = await apiClient.post('/auth/login/2fa', request) // Store token and user data setAuthToken(data.access_token) localStorage.setItem('auth_user', JSON.stringify(data.user)) return data } /** * User registration * @param userData - Registration data (username, email, password) * @returns Authentication response with token and user data */ export async function register(userData: RegisterRequest): Promise { const { data } = await apiClient.post('/auth/register', userData) // Store token and user data setAuthToken(data.access_token) localStorage.setItem('auth_user', JSON.stringify(data.user)) return data } /** * Get current authenticated user * @returns User profile data */ export async function getCurrentUser() { return apiClient.get('/auth/me') } /** * User logout * Clears authentication token and user data from localStorage */ export function logout(): void { clearAuthToken() // Optionally redirect to login page // window.location.href = '/login'; } /** * Check if user is authenticated * @returns True if user has valid token */ export function isAuthenticated(): boolean { return getAuthToken() !== null } /** * Get public settings (no auth required) * @returns Public settings including registration and Turnstile config */ export async function getPublicSettings(): Promise { const { data } = await apiClient.get('/settings/public') return data } /** * Send verification code to email * @param request - Email and optional Turnstile token * @returns Response with countdown seconds */ export async function sendVerifyCode( request: SendVerifyCodeRequest ): Promise { const { data } = await apiClient.post('/auth/send-verify-code', request) return data } /** * Validate promo code response */ export interface ValidatePromoCodeResponse { valid: boolean bonus_amount?: number error_code?: string message?: string } /** * Validate promo code (public endpoint, no auth required) * @param code - Promo code to validate * @returns Validation result with bonus amount if valid */ export async function validatePromoCode(code: string): Promise { const { data } = await apiClient.post('/auth/validate-promo-code', { code }) return data } /** * Forgot password request */ export interface ForgotPasswordRequest { email: string turnstile_token?: string } /** * Forgot password response */ export interface ForgotPasswordResponse { message: string } /** * Request password reset link * @param request - Email and optional Turnstile token * @returns Response with message */ export async function forgotPassword(request: ForgotPasswordRequest): Promise { const { data } = await apiClient.post('/auth/forgot-password', request) return data } /** * Reset password request */ export interface ResetPasswordRequest { email: string token: string new_password: string } /** * Reset password response */ export interface ResetPasswordResponse { message: string } /** * Reset password with token * @param request - Email, token, and new password * @returns Response with message */ export async function resetPassword(request: ResetPasswordRequest): Promise { const { data } = await apiClient.post('/auth/reset-password', request) return data } export const authAPI = { login, login2FA, isTotp2FARequired, register, getCurrentUser, logout, isAuthenticated, setAuthToken, getAuthToken, clearAuthToken, getPublicSettings, sendVerifyCode, validatePromoCode, forgotPassword, resetPassword } export default authAPI