authService.tsx 17 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470
  1. import axios, {isAxiosError} from 'axios';
  2. import { Alert } from 'react-native';
  3. import * as SecureStore from 'expo-secure-store';
  4. import { forgetPasswordFormData } from '../types/signup';
  5. import { CustomerData } from '../types/signUpFormData';
  6. import * as FileSystem from 'expo-file-system';
  7. import {apiClient} from './requets'
  8. class AuthenticationService {
  9. async emailLogin(username: string, password: string, isBinding?: boolean) {
  10. try {
  11. const response = await apiClient.instance.post('/public/client/customer/sign-in',
  12. {
  13. email: username,
  14. password: password,
  15. isBinding: isBinding,
  16. },
  17. {
  18. customConfig: {needAuth: true}
  19. },
  20. );
  21. if (response.status === 201) {
  22. const token = response.data.accessToken;
  23. await SecureStore.setItemAsync('accessToken', token);
  24. console.log('AccessToken', token);
  25. return true;
  26. } else {
  27. console.error('Login failed:', response.status);
  28. return false;
  29. }
  30. } catch (error) {
  31. if (isAxiosError(error)) {
  32. console.error('Login error:', error.response?.data?.message || error.message);
  33. } else {
  34. console.error('An unexpected error occurred:', error);
  35. }
  36. return false;
  37. }
  38. }
  39. async phoneLogin(username: string | null | undefined, password: string, isBinding?: boolean) {
  40. try {
  41. const response = await apiClient.instance.post(
  42. `/public/client/customer/phone/sign-in`,
  43. {
  44. phone: username,
  45. password: password,
  46. isBinding: isBinding,
  47. },
  48. {
  49. customConfig: {needAuth: true}
  50. }
  51. );
  52. if (response.status === 201) {
  53. const token = response.data.accessToken;
  54. await SecureStore.setItemAsync('accessToken', token);
  55. return 'login successful';
  56. } else {
  57. return response.data.message;
  58. }
  59. } catch (error) {
  60. if (axios.isAxiosError(error)) {
  61. console.error('Login error:', error.response?.data?.message || error.message);
  62. return error.response?.data?.message || error.message;
  63. } else {
  64. console.error('An unexpected error occurred:', error);
  65. return 'An unexpected error occurred: ' + error;
  66. }
  67. }
  68. }
  69. async logout() {
  70. await SecureStore.deleteItemAsync('accessToken');
  71. console.log('log out successfully, accessToken deleted');
  72. }
  73. async sendOtpToSignUpEmail(email: string) {
  74. try {
  75. const response = await apiClient.instance.post(
  76. `/public/client/customer/otp`,
  77. { email: email },
  78. );
  79. if (response.status === 200 || response.status === 201) {
  80. return true;
  81. } else {
  82. console.error('Failed to send OTP:', response.status);
  83. return false;
  84. }
  85. } catch (error) {
  86. if (isAxiosError(error)) {
  87. console.error('Error sending OTP:', error.response?.data?.message || error.message);
  88. } else {
  89. console.error('An unexpected error occurred while sending OTP:', error);
  90. }
  91. return false;
  92. }
  93. }
  94. async uploadUberImage(imageUri: string, customFileName: string) {
  95. try {
  96. const fileInfo = await FileSystem.getInfoAsync(imageUri);
  97. if (!fileInfo.exists) {
  98. throw new Error('File does not exist');
  99. }
  100. const fileExtension = imageUri ? imageUri.split('.').pop()?.toLowerCase() : undefined;
  101. const allowedExtensions = ['jpg', 'jpeg', 'png'];
  102. if (fileExtension && !allowedExtensions.includes(fileExtension)) {
  103. throw new Error('只接受jpg,jpeg,png格式的圖片');
  104. }
  105. const formData = new FormData();
  106. const fileName = customFileName || imageUri.split('/').pop();
  107. formData.append('file', {
  108. uri: imageUri,
  109. name: fileName,
  110. type: `image/${fileExtension}`
  111. } as any);
  112. const response = await apiClient.instance.post(`/clients/customer/image?type=uber`, formData, {
  113. headers: {
  114. accept: '*/*',
  115. 'Content-Type': 'multipart/form-data',
  116. }
  117. });
  118. console.log('Upload response:', response.data);
  119. return response.data;
  120. } catch (error) {
  121. console.error('Error uploading image:', error);
  122. throw error;
  123. }
  124. }
  125. async verifySignUpOtp(
  126. email: string,
  127. code: string,
  128. setScreen: React.Dispatch<React.SetStateAction<number>>,
  129. setError: React.Dispatch<React.SetStateAction<string>>
  130. ) {
  131. try {
  132. const response = await apiClient.instance.put(
  133. `/public/client/customer/otp`,
  134. { email, code },
  135. );
  136. if (response.status === 200) {
  137. console.log('OTP verified successfully');
  138. setScreen((currentScreenNumber: number) => currentScreenNumber + 1);
  139. return true;
  140. } else {
  141. console.error('OTP verification failed:', response.status);
  142. setError('OTP驗證碼錯誤');
  143. return false;
  144. }
  145. } catch (error) {
  146. if (isAxiosError(error)) {
  147. console.error('Error verifying OTP:', error.response?.data?.message || error.message);
  148. setError('發生意外錯誤,請確保您輸入的電子郵件正確,並再次確認您的OTP驗證碼是否正確。');
  149. } else {
  150. console.error('An unexpected error occurred while verifying OTP:', error);
  151. setError('發生意外錯誤,請稍後再試');
  152. }
  153. return false;
  154. }
  155. }
  156. async signUp(data: CustomerData) {
  157. try {
  158. const response = await apiClient.instance.post(`/public/client/customer`, data);
  159. if (response.status === 200 || response.status === 201) {
  160. return true;
  161. } else {
  162. console.error('Signup failed:', response.status);
  163. return false;
  164. }
  165. } catch (error) {
  166. if (isAxiosError(error)) {
  167. console.error('Error signing up:', error.response?.data?.message || error.message);
  168. } else {
  169. console.error('An unexpected error occurred while signing up:', error);
  170. }
  171. return false;
  172. }
  173. }
  174. async sendForgetPasswordOtp(email: string) {
  175. try {
  176. const response = await apiClient.instance.post(
  177. `/public/client/customer/pw/otp`,
  178. { email },
  179. );
  180. if (response.status === 200 || response.status === 201) {
  181. console.log('Forget password OTP sent successfully');
  182. return true;
  183. } else {
  184. console.error('Failed to send forget password OTP:', response.status);
  185. return false;
  186. }
  187. } catch (error) {
  188. if (isAxiosError(error)) {
  189. console.error('Error sending forget password OTP:', error.response?.data?.message || error.message);
  190. } else {
  191. console.error('An unexpected error occurred while sending forget password OTP:', error);
  192. }
  193. return false;
  194. }
  195. }
  196. async getVersion() {
  197. try {
  198. const response = await apiClient.instance.get(`/public/client/app/version`);
  199. return response.data.data;
  200. } catch (error) {
  201. console.error('Error getting version:', error);
  202. return null;
  203. }
  204. }
  205. async verifyingOtpForgetPassword(
  206. email: string,
  207. otp: string,
  208. setForgetPasswordFormData: React.Dispatch<React.SetStateAction<forgetPasswordFormData>>,
  209. setData: React.Dispatch<React.SetStateAction<string>>
  210. ) {
  211. try {
  212. const res = await apiClient.instance.put(`/public/client/customer/pw/otp`, {
  213. email: email,
  214. code: otp
  215. });
  216. const data = res.data;
  217. setData(data.msg);
  218. console.log(data.msg);
  219. setForgetPasswordFormData((prevFormData) => ({
  220. ...prevFormData,
  221. otpAuthCompleted: true
  222. }));
  223. return true;
  224. } catch (error) {
  225. console.error('Error', error);
  226. return false;
  227. }
  228. }
  229. async changePassword(confirmedNewPassword: string, data: string) {
  230. try {
  231. const res = await apiClient.instance.put(
  232. `/clients/customer/pw/forget`,
  233. { newPassword: confirmedNewPassword },
  234. );
  235. return true;
  236. } catch (error) {
  237. if (isAxiosError(error)) {
  238. console.error('Error changing password:', error.response?.data?.message || error.message);
  239. } else {
  240. console.error('An unexpected error occurred:', error);
  241. }
  242. }
  243. }
  244. async changeEmail(email: string | null, token: string | null): Promise<boolean> {
  245. try {
  246. const res = await apiClient.instance.put(
  247. `/clients/customer`,
  248. { email: email },
  249. );
  250. console.log('Change Name Successfully!');
  251. return true;
  252. } catch (error) {
  253. if (isAxiosError(error)) {
  254. console.error('Error changing name:', error.response?.data?.message);
  255. } else {
  256. console.error('An unexpected error occurred:', error);
  257. }
  258. return false;
  259. }
  260. }
  261. //BELOW CODES RELATE TO "changing account info (such as gender, name)"
  262. async changeName(name: string | null, token: string | null): Promise<boolean> {
  263. try {
  264. const res = await apiClient.instance.put(
  265. `/clients/customer`,
  266. { nickname: name },
  267. );
  268. console.log('Change Name Successfully!');
  269. return true;
  270. } catch (error) {
  271. if (isAxiosError(error)) {
  272. console.error('Error changing name:', error.response?.data?.message);
  273. } else {
  274. console.error('An unexpected error occurred:', error);
  275. }
  276. return false;
  277. }
  278. }
  279. async changeNotifySessionID(notifySessionID: string | null): Promise<boolean> {
  280. try {
  281. const res = await apiClient.instance.put(
  282. `/clients/customer`,
  283. { notify_session_id: notifySessionID }
  284. );
  285. if (res.data.status == 200) {
  286. console.log('Change notifySessionID Successfully!');
  287. return true;
  288. } else {
  289. console.log('Change notifySessionID Failed!');
  290. return false;
  291. }
  292. } catch (error) {
  293. if (isAxiosError(error)) {
  294. console.error('Error changing name:', error.response?.data?.message);
  295. } else {
  296. console.error('An unexpected error occurred:', error);
  297. }
  298. return false;
  299. }
  300. }
  301. async changePhone(phone: string | null, token: string | null): Promise<boolean> {
  302. try {
  303. const convertPhoneStringToNumber = Number(phone);
  304. const res = await apiClient.instance.put(
  305. `/clients/customer`,
  306. { phone: convertPhoneStringToNumber },
  307. );
  308. return true;
  309. } catch (error) {
  310. if (isAxiosError(error)) {
  311. console.error('Error changing phone:', error.response?.data?.message);
  312. } else {
  313. console.error('An unexpected error occurred:', error);
  314. }
  315. return false;
  316. }
  317. }
  318. async changeGender(gender: string | null, token: string | null): Promise<boolean> {
  319. try {
  320. const res = await apiClient.instance.put(
  321. `/clients/customer`,
  322. { gender: gender },
  323. );
  324. console.log('Change gender Successfully!');
  325. return true;
  326. } catch (error) {
  327. if (isAxiosError(error)) {
  328. console.error('Error changing gender:', error.response?.data?.message);
  329. } else {
  330. console.error('An unexpected error occurred:', error);
  331. }
  332. return false;
  333. }
  334. }
  335. async getUserInfo() {
  336. try {
  337. const response = await apiClient.instance.get(`/clients/customer`);
  338. if (response.status === 200 || response.status === 201) {
  339. return response;
  340. } else {
  341. console.log('invalid response');
  342. }
  343. } catch (error) {
  344. console.log(error);
  345. }
  346. }
  347. async deleteAccount(): Promise<boolean> {
  348. try {
  349. const response = await apiClient.instance.delete(`/clients/customer`);
  350. if (response.status === 200 || response.status === 201) {
  351. console.log('Account deleted successfully');
  352. return true;
  353. } else {
  354. console.error('Failed to delete account:', response.status);
  355. return false;
  356. }
  357. } catch (error) {
  358. if (isAxiosError(error)) {
  359. console.error('Error deleting account:', error.response?.data?.message || error.message);
  360. } else {
  361. console.error('An unexpected error occurred while deleting account:', error);
  362. }
  363. return false;
  364. }
  365. }
  366. async checkPhoneSame(phoneNumber: string) {
  367. try {
  368. console.log('being checkPhoneSame');
  369. const response = await apiClient.instance.post(
  370. `/clients/customer/binding/sms`,
  371. {
  372. phone: phoneNumber,
  373. type: 3
  374. }
  375. );
  376. const token = await SecureStore.getItemAsync('accessToken');
  377. console.log('accessToken', token);
  378. console.log('checkPhoneSame response', response.data);
  379. return response.data;
  380. } catch (error) {
  381. console.log(error);
  382. }
  383. }
  384. async confirmBindingPhone(phoneNumber: string, otp: string, notify_session_id: string) {
  385. try {
  386. const response = await apiClient.instance.put(
  387. `/public/client/customer/phone/otp`,
  388. {
  389. phone: phoneNumber,
  390. code: otp,
  391. notify_session_id: notify_session_id,
  392. type: 3
  393. },
  394. );
  395. console.log('confirmBindingPhone response', response.data);
  396. return response.data;
  397. } catch (error) {
  398. console.log(error);
  399. }
  400. }
  401. async verifyPhoneOtp(phoneNumber: string, otp: string, notify_session_id: string) {
  402. try {
  403. const response = await apiClient.instance.put(
  404. `/public/client/customer/phone/otp`,
  405. {
  406. phone: phoneNumber,
  407. code: otp,
  408. notify_session_id: notify_session_id
  409. },
  410. );
  411. return response.data;
  412. } catch (error) {
  413. if (isAxiosError(error)) {
  414. console.error('Error verifying phone OTP:', error.response?.data || error.message);
  415. throw error;
  416. } else {
  417. console.error('Unexpected error:', error);
  418. throw new Error('Failed to verify phone OTP');
  419. }
  420. }
  421. }
  422. async sendOtpToSignUpPhone(phone: string) {
  423. try {
  424. const response = await apiClient.instance.post(`/public/client/customer/phone/sms`, {
  425. phone: phone,
  426. type: 1
  427. });
  428. if (response.status === 200 || response.status === 201) {
  429. return true;
  430. } else {
  431. return false;
  432. }
  433. } catch (error) {
  434. console.log(error);
  435. }
  436. }
  437. }
  438. export const authenticationService = new AuthenticationService();