import axios from 'axios'; import { Alert } from 'react-native'; import * as SecureStore from 'expo-secure-store'; import { forgetPasswordFormData } from '../types/signup'; import { CustomerData } from '../types/signUpFormData'; import * as FileSystem from 'expo-file-system'; class AuthenticationService { private apiUrl: string; constructor() { this.apiUrl = process.env.EXPO_PUBLIC_API_URL; if (!this.apiUrl) { throw new Error('API URL is not defined in environment variables'); } } async emailLogin(username: string, password: string, isBinding?: boolean) { try { console.log('username in emailLogin auth service', username); console.log('password in emailLogin auth service', password); console.log('isBinding in emailLogin auth service', isBinding); const response = await axios.post( `${this.apiUrl}/public/client/customer/sign-in`, { email: username, password: password, isBinding: isBinding }, { headers: { 'Content-Type': 'application/json', Accept: 'application/json' } } ); if (response.status === 201) { const token = response.data.accessToken; await SecureStore.setItemAsync('accessToken', token); console.log('AccessToken', token); console.log('Login successful!'); return true; } else { console.error('Login failed:', response.status); return false; } } catch (error) { if (axios.isAxiosError(error)) { console.error('Login error:', error.response?.data?.message || error.message); } else { console.error('An unexpected error occurred:', error); } return false; } } async phoneLogin(username: string | null | undefined, password: string, isBinding?: boolean) { try { const response = await axios.post( // `${this.apiUrl}/public/client/customer/sign-in`, // `${this.apiUrl}/public/client/customer/sign-in`, `${this.apiUrl}/public/client/customer/phone/sign-in`, { phone: username, password: password, isBinding: isBinding }, { headers: { 'Content-Type': 'application/json', Accept: '*/*' } } ); if (response.status === 201) { const token = response.data.accessToken; await SecureStore.setItemAsync('accessToken', token); return 'login successful'; } else { return response.data.message; } } catch (error) { if (axios.isAxiosError(error)) { console.error('Login error:', error.response?.data?.message || error.message); return error.response?.data?.message || error.message; } else { console.error('An unexpected error occurred:', error); return 'An unexpected error occurred: ' + error; } } } async logout() { await SecureStore.deleteItemAsync('accessToken'); console.log('log out successfully, accessToken deleted'); } //BELOW CODES RELATE TO "SIGN UP" //BELOW CODES RELATE TO "SIGN UP" async sendOtpToSignUpEmail(email: string) { try { const response = await axios.post( `${this.apiUrl}/public/client/customer/otp`, { email: email }, { headers: { 'Content-Type': 'application/json', Accept: 'application/json' } } ); if (response.status === 200 || response.status === 201) { return true; } else { console.error('Failed to send OTP:', response.status); return false; } } catch (error) { if (axios.isAxiosError(error)) { console.error('Error sending OTP:', error.response?.data?.message || error.message); } else { console.error('An unexpected error occurred while sending OTP:', error); } return false; } } async uploadUberImage(imageUri: string, customFileName: string) { try { const fileInfo = await FileSystem.getInfoAsync(imageUri); if (!fileInfo.exists) { throw new Error('File does not exist'); } const fileExtension = imageUri.split('.').pop().toLowerCase(); const allowedExtensions = ['jpg', 'jpeg', 'png']; if (!allowedExtensions.includes(fileExtension)) { throw new Error('只接受jpg,jpeg,png格式的圖片'); } const formData = new FormData(); const fileName = customFileName || imageUri.split('/').pop(); formData.append('file', { uri: imageUri, name: fileName, type: `image/${fileExtension}` } as any); const accessToken = await SecureStore.getItemAsync('accessToken'); const response = await axios.post(`${this.apiUrl}/clients/customer/image?type=uber`, formData, { headers: { accept: '*/*', 'Content-Type': 'multipart/form-data', Authorization: `Bearer ${accessToken}` } }); console.log('Upload response:', response.data); return response.data; } catch (error) { console.error('Error uploading image:', error); throw error; } } async verifySignUpOtp( email: string, code: string, setScreen: React.Dispatch>, setError: React.Dispatch> ) { try { const response = await axios.put( `${this.apiUrl}/public/client/customer/otp`, { email, code }, { headers: { 'Content-Type': 'application/json', Accept: 'application/json' } } ); if (response.status === 200) { console.log('OTP verified successfully'); setScreen((currentScreenNumber: number) => currentScreenNumber + 1); return true; } else { console.error('OTP verification failed:', response.status); setError('OTP驗證碼錯誤'); return false; } } catch (error) { if (axios.isAxiosError(error)) { console.error('Error verifying OTP:', error.response?.data?.message || error.message); setError('發生意外錯誤,請確保您輸入的電子郵件正確,並再次確認您的OTP驗證碼是否正確。'); } else { console.error('An unexpected error occurred while verifying OTP:', error); setError('發生意外錯誤,請稍後再試'); } return false; } } async signUp(data: CustomerData) { try { const response = await axios.post(`${this.apiUrl}/public/client/customer`, data, { headers: { 'Content-Type': 'application/json', Accept: 'application/json' } }); if (response.status === 200 || response.status === 201) { return true; } else { console.error('Signup failed:', response.status); return false; } } catch (error) { if (axios.isAxiosError(error)) { console.error('Error signing up:', error.response?.data?.message || error.message); } else { console.error('An unexpected error occurred while signing up:', error); } return false; } } //BELOW CODES RELATE TO "FORGET PASSWORD" //BELOW CODES RELATE TO "FORGET PASSWORD" async sendForgetPasswordOtp(email: string) { try { const response = await axios.post( `${this.apiUrl}/public/client/customer/pw/otp`, { email }, { headers: { 'Content-Type': 'application/json', Accept: 'application/json' } } ); if (response.status === 200 || response.status === 201) { console.log('Forget password OTP sent successfully'); return true; } else { console.error('Failed to send forget password OTP:', response.status); return false; } } catch (error) { if (axios.isAxiosError(error)) { console.error('Error sending forget password OTP:', error.response?.data?.message || error.message); } else { console.error('An unexpected error occurred while sending forget password OTP:', error); } return false; } } async getVersion() { try { const response = await axios.get(`${this.apiUrl}/public/client/app/version`); return response.data.data; } catch (error) { console.error('Error getting version:', error); return null; } } async verifyingOtpForgetPassword( email: string, otp: string, setForgetPasswordFormData: React.Dispatch>, setData: React.Dispatch> ) { try { const res = await axios.put(`${this.apiUrl}/public/client/customer/pw/otp`, { email: email, code: otp }); const data = res.data; setData(data.msg); console.log(data.msg); setForgetPasswordFormData((prevFormData) => ({ ...prevFormData, otpAuthCompleted: true })); return true; } catch (error) { console.error('Error', error); return false; } } async changePassword(confirmedNewPassword: string, data: string) { try { const res = await axios.put( `${this.apiUrl}/clients/customer/pw/forget`, { newPassword: confirmedNewPassword }, { headers: { Authorization: `Bearer ${data}` } } ); return true; } catch (error) { if (axios.isAxiosError(error)) { console.error('Error changing password:', error.response?.data?.message || error.message); } else { console.error('An unexpected error occurred:', error); } } } //BELOW CODES RELATE TO "changing account info (such as gender, name)" //BELOW CODES RELATE TO "changing account info (such as gender, name)" async changeName(name: string | null, token: string | null): Promise { try { const res = await axios.put( `${this.apiUrl}/clients/customer`, { nickname: name }, { headers: { Authorization: `Bearer ${token}` } } ); console.log('Change Name Successfully!'); return true; } catch (error) { if (axios.isAxiosError(error)) { console.error('Error changing name:', error.response?.data?.message); } else { console.error('An unexpected error occurred:', error); } return false; } } async changeNotifySessionID(notifySessionID: string | null): Promise { try { const res = await axios.put( `${this.apiUrl}/clients/customer`, { notify_session_id: notifySessionID }, { headers: { Authorization: `Bearer ${await SecureStore.getItemAsync('accessToken')}` } } ); if (res.data.status == 200) { console.log('Change notifySessionID Successfully!'); return true; } else { console.log('Change notifySessionID Failed!'); return false; } } catch (error) { if (axios.isAxiosError(error)) { console.error('Error changing name:', error.response?.data?.message); } else { console.error('An unexpected error occurred:', error); } return false; } } async changePhone(phone: string | null, token: string | null): Promise { try { const convertPhoneStringToNumber = Number(phone); const res = await axios.put( `${this.apiUrl}/clients/customer`, { phone: convertPhoneStringToNumber }, { headers: { Authorization: `Bearer ${token}` } } ); return true; } catch (error) { if (axios.isAxiosError(error)) { console.error('Error changing phone:', error.response?.data?.message); } else { console.error('An unexpected error occurred:', error); } return false; } } async changeGender(gender: string | null, token: string | null): Promise { try { const res = await axios.put( `${this.apiUrl}/clients/customer`, { gender: gender }, { headers: { Authorization: `Bearer ${token}` } } ); console.log('Change gender Successfully!'); return true; } catch (error) { if (axios.isAxiosError(error)) { console.error('Error changing gender:', error.response?.data?.message); } else { console.error('An unexpected error occurred:', error); } return false; } } async getUserInfo() { try { const response = await axios.get(`${this.apiUrl}/clients/customer`, { headers: { Authorization: `Bearer ${await SecureStore.getItemAsync('accessToken')}` } }); if (response.status === 200 || response.status === 201) { return response; } else { console.log('invalid response'); } } catch (error) { console.log(error); } } async deleteAccount(): Promise { try { const accessToken = await SecureStore.getItemAsync('accessToken'); const response = await axios.delete(`${this.apiUrl}/clients/customer`, { headers: { Authorization: `Bearer ${accessToken}` } }); if (response.status === 200 || response.status === 201) { console.log('Account deleted successfully'); return true; } else { console.error('Failed to delete account:', response.status); return false; } } catch (error) { if (axios.isAxiosError(error)) { console.error('Error deleting account:', error.response?.data?.message || error.message); } else { console.error('An unexpected error occurred while deleting account:', error); } return false; } } async checkPhoneSame(phoneNumber: string) { try { console.log('being checkPhoneSame'); const response = await axios.post( `${this.apiUrl}/clients/customer/binding/sms`, { phone: phoneNumber, type: 3 }, { headers: { Authorization: `Bearer ${await SecureStore.getItemAsync('accessToken')}` } } ); const token = await SecureStore.getItemAsync('accessToken'); console.log('accessToken', token); console.log('checkPhoneSame response', response.data); return response.data; } catch (error) { console.log(error); } } async confirmBindingPhone(phoneNumber: string, otp: string, notify_session_id: string) { try { const response = await axios.put( `${this.apiUrl}/public/client/customer/phone/otp`, { phone: phoneNumber, code: otp, notify_session_id: notify_session_id, type: 3 }, { headers: { 'Content-Type': 'application/json', Accept: 'application/json' } } ); console.log('confirmBindingPhone response', response.data); return response.data; } catch (error) { console.log(error); } } async verifyPhoneOtp(phoneNumber: string, otp: string, notify_session_id: string) { try { const response = await axios.put( `${this.apiUrl}/public/client/customer/phone/otp`, { phone: phoneNumber, code: otp, notify_session_id: notify_session_id }, { headers: { 'Content-Type': 'application/json', Accept: '*/*' } } ); console.log('verifyPhoneOtp response:', response.data); return response.data; } catch (error) { if (axios.isAxiosError(error)) { console.error('Error verifying phone OTP:', error.response?.data || error.message); throw error; } else { console.error('Unexpected error:', error); throw new Error('Failed to verify phone OTP'); } } } async sendOtpToSignUpPhone(phone: string) { try { const response = await axios.post(`${this.apiUrl}/public/client/customer/phone/sms`, { phone: phone, type: 1 }); if (response.status === 200 || response.status === 201) { console.log('OTP sent successfully -- from api sendOtpToSignUpPhone, response:', response); return true; } else { console.error('Failed to send OTP -- from api sendOtpToSignUpPhone.. response:', response); return false; } } catch (error) { console.log(error); } } } export const authenticationService = new AuthenticationService();