| |
| import AsyncStorage from '@react-native-async-storage/async-storage'; |
|
|
| class AuthService { |
| constructor() { |
| |
| try { |
| const { API_BASE_URL } = require('./config'); |
| this.baseURL = API_BASE_URL; |
| } catch (e) { |
| this.baseURL = 'http://192.168.1.8:5000'; |
| } |
| this.isRefreshing = false; |
| this.failedQueue = []; |
| } |
|
|
| |
| processQueue(error, token = null) { |
| this.failedQueue.forEach(prom => { |
| if (error) { |
| prom.reject(error); |
| } else { |
| prom.resolve(token); |
| } |
| }); |
| this.failedQueue = []; |
| } |
|
|
| |
| async getAccessToken() { |
| try { |
| |
| const authToken = await AsyncStorage.getItem('authToken'); |
| if (authToken) { |
| |
| return authToken; |
| } |
|
|
| |
| const token = await AsyncStorage.getItem('accessToken'); |
| if (token) { |
| |
| return token; |
| } |
|
|
| console.log('⚠️ AuthService: No token found'); |
| return null; |
| } catch (error) { |
| console.error('Error getting access token:', error); |
| return null; |
| } |
| } |
|
|
| |
| async getRefreshToken() { |
| try { |
| return await AsyncStorage.getItem('refreshToken'); |
| } catch (error) { |
| console.error('Error getting refresh token:', error); |
| return null; |
| } |
| } |
|
|
| |
| async saveTokens(accessToken, refreshToken) { |
| try { |
| await AsyncStorage.setItem('accessToken', accessToken); |
| await AsyncStorage.setItem('refreshToken', refreshToken); |
| console.log('✅ Tokens saved to AsyncStorage'); |
| } catch (error) { |
| console.error('❌ Error saving tokens:', error); |
| } |
| } |
|
|
| |
| async refreshAccessToken() { |
| |
| |
| console.log('⚠️ Token refresh not supported in new backend. Forcing logout.'); |
| await this.clearTokens(); |
| throw new Error('Session expired. Please login again.'); |
| } |
|
|
| |
| async authenticatedFetch(url, options = {}) { |
| let accessToken = await this.getAccessToken(); |
|
|
| if (!accessToken) { |
| throw new Error('No access token available. Please login.'); |
| } |
|
|
| |
| const headers = { |
| ...options.headers, |
| 'Authorization': `Bearer ${accessToken}`, |
| }; |
|
|
| let response = await fetch(url, { ...options, headers }); |
|
|
| |
| if (response.status === 401) { |
| if (!this.isRefreshing) { |
| this.isRefreshing = true; |
| try { |
| accessToken = await this.refreshAccessToken(); |
| this.isRefreshing = false; |
| this.processQueue(null, accessToken); |
| } catch (error) { |
| this.isRefreshing = false; |
| this.processQueue(error, null); |
| throw error; |
| } |
| } |
|
|
| |
| return new Promise((resolve, reject) => { |
| this.failedQueue.push({ resolve, reject }); |
| }).then(token => { |
| headers['Authorization'] = `Bearer ${token}`; |
| return fetch(url, { ...options, headers }); |
| }); |
| } |
|
|
| return response; |
| } |
|
|
| |
| async clearTokens() { |
| try { |
| await AsyncStorage.removeItem('accessToken'); |
| await AsyncStorage.removeItem('refreshToken'); |
| await AsyncStorage.removeItem('token'); |
| await AsyncStorage.removeItem('authToken'); |
| console.log('✅ Tokens cleared'); |
| } catch (error) { |
| console.error('❌ Error clearing tokens:', error); |
| } |
| } |
|
|
| |
| async authenticateUser(email, password) { |
| try { |
| console.log('🔐 Authenticating user with backend:', email); |
|
|
| const response = await fetch(`${this.baseURL}/api/auth/login`, { |
| method: 'POST', |
| headers: { |
| 'Content-Type': 'application/json', |
| }, |
| body: JSON.stringify({ email, password }), |
| }); |
|
|
| const data = await response.json(); |
|
|
| if (response.ok && data.success) { |
| console.log('✅ Authentication successful for:', email); |
|
|
| |
| await this.saveTokens(data.accessToken, data.refreshToken); |
|
|
| |
| await AsyncStorage.setItem('userData', JSON.stringify(data.user)); |
|
|
| return { |
| success: true, |
| user: data.user, |
| accessToken: data.accessToken, |
| refreshToken: data.refreshToken |
| }; |
| } else { |
| console.log('❌ Authentication failed:', data.error); |
| return { |
| success: false, |
| error: data.error || 'Authentication failed' |
| }; |
| } |
| } catch (error) { |
| console.error('❌ Authentication error:', error); |
| return { |
| success: false, |
| error: error.message |
| }; |
| } |
| } |
|
|
| |
| async registerUser(userData, userType) { |
| try { |
| console.log('📝 Registering user with backend:', userData.email, 'Type:', userType); |
|
|
| const registerData = { |
| name: userData.name, |
| email: userData.email, |
| password: userData.password, |
| role: userType === 'central_authority' ? 'authority' : 'trainer' |
| }; |
|
|
| const response = await fetch(`${this.baseURL}/api/auth/register`, { |
| method: 'POST', |
| headers: { |
| 'Content-Type': 'application/json', |
| }, |
| body: JSON.stringify(registerData), |
| }); |
|
|
| const data = await response.json(); |
|
|
| if (response.ok && data.success) { |
| console.log('✅ Registration successful for:', userData.email); |
|
|
| |
| await this.saveTokens(data.accessToken, data.refreshToken); |
|
|
| |
| await AsyncStorage.setItem('userData', JSON.stringify(data.user)); |
|
|
| return { |
| success: true, |
| user: data.user, |
| message: 'Registration successful! You can now login.' |
| }; |
| } else { |
| console.log('❌ Registration failed:', data.error); |
| return { |
| success: false, |
| error: data.error || 'Registration failed' |
| }; |
| } |
| } catch (error) { |
| console.error('❌ Registration error:', error); |
| return { |
| success: false, |
| error: error.message |
| }; |
| } |
| } |
|
|
| |
| async getUserProfile(userId, token) { |
| try { |
| |
| await this.delay(1000); |
|
|
| |
| return { |
| success: true, |
| user: { |
| id: userId, |
| name: 'Demo User', |
| email: 'demo@ndma.gov.in', |
| type: 'general', |
| verified: true, |
| lastLogin: new Date().toISOString() |
| } |
| }; |
| } catch (error) { |
| return { |
| success: false, |
| error: error.message |
| }; |
| } |
| } |
|
|
| |
| async updateUserProfile(userId, updateData, token) { |
| try { |
| await this.delay(1500); |
|
|
| console.log('Updating user profile:', userId, updateData); |
|
|
| return { |
| success: true, |
| message: 'Profile updated successfully' |
| }; |
| } catch (error) { |
| return { |
| success: false, |
| error: error.message |
| }; |
| } |
| } |
|
|
| |
| async resetPassword(email) { |
| try { |
| await this.delay(2000); |
|
|
| console.log('Password reset requested for:', email); |
|
|
| return { |
| success: true, |
| message: 'Password reset instructions sent to your email' |
| }; |
| } catch (error) { |
| return { |
| success: false, |
| error: error.message |
| }; |
| } |
| } |
|
|
| |
| async logout() { |
| try { |
| await this.clearTokens(); |
| await AsyncStorage.removeItem('userData'); |
| await AsyncStorage.removeItem('user'); |
| await AsyncStorage.removeItem('@ndma_session_user'); |
| console.log('✅ User logged out and storage cleared'); |
| return { |
| success: true, |
| message: 'Logged out successfully' |
| }; |
| } catch (error) { |
| return { |
| success: false, |
| error: error.message |
| }; |
| } |
| } |
|
|
| |
| async getCurrentUser() { |
| try { |
| let userDataString = await AsyncStorage.getItem('userData'); |
| if (!userDataString) { |
| userDataString = await AsyncStorage.getItem('user'); |
| } |
|
|
| if (userDataString) { |
| const userData = JSON.parse(userDataString); |
| console.log('✅ Retrieved current user:', userData.email || userData.phone); |
| return userData; |
| } |
| console.log('❌ No user data found in storage'); |
| return null; |
| } catch (error) { |
| console.error('❌ Error getting current user:', error); |
| throw error; |
| } |
| } |
|
|
| |
| async updateProfile(updateData) { |
| try { |
| let userDataString = await AsyncStorage.getItem('userData'); |
| let key = 'userData'; |
|
|
| if (!userDataString) { |
| userDataString = await AsyncStorage.getItem('user'); |
| key = 'user'; |
| } |
|
|
| if (userDataString) { |
| const userData = JSON.parse(userDataString); |
| const updatedUser = { ...userData, ...updateData }; |
| await AsyncStorage.setItem(key, JSON.stringify(updatedUser)); |
| console.log('✅ Profile updated successfully'); |
| return updatedUser; |
| } |
| throw new Error('No user data found'); |
| } catch (error) { |
| console.error('❌ Error updating profile:', error); |
| throw error; |
| } |
| } |
|
|
| |
| async uploadProfilePicture(imageUri) { |
| try { |
| |
| console.log('📸 Uploading profile picture:', imageUri); |
| await this.delay(1500); |
|
|
| |
| return imageUri; |
| } catch (error) { |
| console.error('❌ Error uploading profile picture:', error); |
| throw error; |
| } |
| } |
|
|
| |
| delay(ms) { |
| return new Promise(resolve => setTimeout(resolve, ms)); |
| } |
|
|
| |
|
|
| |
| validateEmail(email) { |
| const emailRegex = /^[^\s@]+@[^\s@]+\.[^\s@]+$/; |
| return emailRegex.test(email); |
| } |
|
|
| |
| validatePassword(password) { |
| if (password.length < 6) { |
| return { valid: false, message: 'Password must be at least 6 characters long' }; |
| } |
| return { valid: true }; |
| } |
|
|
| |
| getTestCredentials() { |
| return { |
| email: 'test@example.com', |
| password: 'password123', |
| description: 'Test account for development' |
| }; |
| } |
| } |
|
|
| |
| const authService = new AuthService(); |
|
|
| |
| export default authService; |
| export { authService }; |