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