useAuth.js 4.0 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171
  1. import api from "src/api";
  2. import { permissionStore } from "src/stores/permission";
  3. import { useAuthStorage } from "src/composables/useAuthStorage";
  4. import { APPROVAL_STATUS, useProviderApproval } from "src/composables/useProviderApproval";
  5. import { usePushNotifications } from "src/composables/usePushNotifications";
  6. import { userStore } from "src/stores/user";
  7. let refreshPromise = null;
  8. export const useAuth = () => {
  9. const { setRefreshToken, getRefreshToken, clearRefreshToken } = useAuthStorage();
  10. const clearAuthData = async () => {
  11. userStore().resetUser();
  12. permissionStore().resetScopes();
  13. await clearRefreshToken();
  14. };
  15. const setAuthDataFromPayload = async (tokens) => {
  16. const { access_token, refresh_token, user } = tokens;
  17. const store = userStore();
  18. store.setUser(user);
  19. store.accessToken = access_token;
  20. await setRefreshToken(refresh_token);
  21. // Fire-and-forget: o boot só consegue registrar o token quando o app abre
  22. // já autenticado. Quem acabou de se cadastrar ou de entrar registra aqui.
  23. registerPushDevice();
  24. if (String(user?.type).toUpperCase() === "PROVIDER" && !user?.provider) {
  25. await store.fetchUser();
  26. }
  27. if (useProviderApproval().isPendingProvider.value) {
  28. permissionStore().resetScopes();
  29. return;
  30. }
  31. await permissionStore().fetchScopes();
  32. };
  33. /**
  34. * Reconsulta o cadastro do prestador em análise e, se ele já tiver sido
  35. * aprovado, carrega os escopos para liberar o app sem exigir novo login.
  36. *
  37. * @return {Promise<boolean>} true quando o cadastro acabou de ser aprovado.
  38. */
  39. const refreshApprovalStatus = async () => {
  40. const { approvalStatus, isPendingProvider } = useProviderApproval();
  41. if (!isPendingProvider.value) {
  42. return false;
  43. }
  44. await userStore().fetchUser();
  45. if (approvalStatus.value !== APPROVAL_STATUS.ACCEPTED) {
  46. return false;
  47. }
  48. await permissionStore().fetchScopes();
  49. return true;
  50. };
  51. /**
  52. * Garante que o dispositivo esteja apto a receber push depois do login:
  53. * envia o token já capturado e (re)solicita o registro no FCM.
  54. */
  55. const registerPushDevice = async () => {
  56. const { isSupported, requestPermissionAndRegister, syncDeviceToken } =
  57. usePushNotifications();
  58. if (!isSupported()) {
  59. return;
  60. }
  61. try {
  62. await syncDeviceToken();
  63. await requestPermissionAndRegister();
  64. } catch (error) {
  65. console.error(error);
  66. }
  67. };
  68. //
  69. const login = async (email, password) => {
  70. try {
  71. const response = await api.post("/login", {
  72. email: email,
  73. password: password,
  74. });
  75. if (response.status === 200) {
  76. await setAuthDataFromPayload(response.data.payload);
  77. }
  78. return response;
  79. } catch (error) {
  80. return Promise.reject(error);
  81. }
  82. };
  83. const logout = async () => {
  84. try {
  85. // Precisa acontecer antes do /logout, enquanto o token ainda é válido.
  86. await usePushNotifications().unregisterDeviceToken();
  87. const response = await api.post("/logout");
  88. if (response.status === 200) {
  89. await clearAuthData();
  90. }
  91. } catch (error) {
  92. console.error(error);
  93. await clearAuthData();
  94. }
  95. };
  96. //
  97. const doRefresh = async () => {
  98. try {
  99. const refreshToken = await getRefreshToken();
  100. if (!refreshToken) {
  101. return Promise.reject(new Error("No refresh token available"));
  102. }
  103. const response = await api.post("/refresh-app", {
  104. refresh_token: refreshToken,
  105. });
  106. if (response.status === 200) {
  107. await setAuthDataFromPayload(response.data.payload);
  108. }
  109. return response;
  110. } catch (error) {
  111. await clearAuthData();
  112. return Promise.reject(error);
  113. }
  114. };
  115. const refresh = () => {
  116. if (!refreshPromise) {
  117. refreshPromise = doRefresh().finally(() => {
  118. refreshPromise = null;
  119. });
  120. }
  121. return refreshPromise;
  122. };
  123. return {
  124. clearAuthData,
  125. login,
  126. logout,
  127. refresh,
  128. refreshApprovalStatus,
  129. setAuthDataFromPayload,
  130. };
  131. };