Explorar el Código

refactor login para passwordless

Gustavo Zanatta hace 1 mes
padre
commit
f800478eee
Se han modificado 4 ficheros con 64 adiciones y 15 borrados
  1. 3 2
      src/boot/axios.js
  2. 26 3
      src/composables/useAuth.js
  3. 32 0
      src/composables/useAuthStorage.js
  4. 3 10
      src/pages/LoginPage.vue

+ 3 - 2
src/boot/axios.js

@@ -2,6 +2,7 @@ import { defineBoot } from "#q-app/wrappers";
 import { Cookies, Notify } from "quasar";
 import axios from "axios";
 import { useRouter } from "vue-router";
+import { useAuth } from "src/composables/useAuth";
 import { userStore } from "src/stores/user";
 
 const api = axios.create({
@@ -75,7 +76,7 @@ const errorInterceptor = async (error, router) => {
 
   isRefreshing = true;
   try {
-    const response = await api.post("/refresh");
+    const response = await useAuth().refresh();
     const newAccessToken = response.data.payload.access_token;
     user_store.accessToken = newAccessToken;
     originalRequest.headers["Authorization"] = `Bearer ${newAccessToken}`;
@@ -83,7 +84,7 @@ const errorInterceptor = async (error, router) => {
     return api(originalRequest);
   } catch (err) {
     processQueue(err, null);
-    user_store.resetUser();
+    await useAuth().clearAuthData();
     router.push("/login");
     return Promise.reject(err);
   } finally {

+ 26 - 3
src/composables/useAuth.js

@@ -1,12 +1,22 @@
 import api from "src/api";
 import { permissionStore } from "src/stores/permission";
 import { userStore } from "src/stores/user";
+import { useAuthStorage } from "src/composables/useAuthStorage";
 
 export const useAuth = () => {
+  const { setRefreshToken, getRefreshToken, clearRefreshToken } = useAuthStorage();
+
+  const clearAuthData = async () => {
+    userStore().resetUser();
+    permissionStore().resetScopes();
+    await clearRefreshToken();
+  };
+
   const setAuthDataFromPayload = async (tokens) => {
-    const { access_token, user } = tokens;
+    const { access_token, refresh_token, user } = tokens;
     userStore().user = user;
     userStore().accessToken = access_token;
+    await setRefreshToken(refresh_token);
     await permissionStore().fetchScopes();
   };
 
@@ -30,26 +40,39 @@ export const useAuth = () => {
     try {
       const response = await api.post("/logout");
       if (response.status === 200) {
-        userStore().resetUser();
+        await clearAuthData();
       }
     } catch (error) {
       console.error(error);
+      await clearAuthData();
     }
   };
 
   const refresh = async () => {
     try {
-      const response = await api.post("/refresh");
+      const refreshToken = await getRefreshToken();
+
+      if (!refreshToken) {
+        return Promise.reject(new Error("No refresh token available"));
+      }
+
+      const response = await api.post("/refresh", {
+        refresh_token: refreshToken,
+      });
+
       if (response.status === 200) {
         await setAuthDataFromPayload(response.data.payload);
       }
       return response;
     } catch (error) {
+      await clearAuthData();
       return Promise.reject(error);
     }
   };
 
   return {
+    setAuthDataFromPayload,
+    clearAuthData,
     login,
     logout,
     refresh,

+ 32 - 0
src/composables/useAuthStorage.js

@@ -0,0 +1,32 @@
+import { Preferences } from '@capacitor/preferences';
+
+const REFRESH_TOKEN_KEY = 'auth_refresh_token';
+
+export const useAuthStorage = () => {
+  const setRefreshToken = async (token) => {
+    if (!token) {
+      await Preferences.remove({ key: REFRESH_TOKEN_KEY });
+      return;
+    }
+
+    await Preferences.set({
+      key: REFRESH_TOKEN_KEY,
+      value: token,
+    });
+  };
+
+  const getRefreshToken = async () => {
+    const { value } = await Preferences.get({ key: REFRESH_TOKEN_KEY });
+    return value;
+  };
+
+  const clearRefreshToken = async () => {
+    await Preferences.remove({ key: REFRESH_TOKEN_KEY });
+  };
+
+  return {
+    setRefreshToken,
+    getRefreshToken,
+    clearRefreshToken,
+  };
+};

+ 3 - 10
src/pages/LoginPage.vue

@@ -77,9 +77,8 @@
 <script setup>
 import { ref } from 'vue';
 import { createUserAndProvider, sendCode, validateCode } from 'src/api/user';
+import { useAuth } from 'src/composables/useAuth';
 import { useRouter } from 'vue-router';
-import { userStore } from 'src/stores/user';
-import { permissionStore } from 'src/stores/permission';
 
 import BackgroundLogin from 'src/assets/background-login.svg';
 import FotoDiarista from 'src/assets/foto_diarista_login.svg';
@@ -92,6 +91,7 @@ import LoginStepThreePanel from 'src/components/login/LoginStepThreePanel.vue';
 import LoginStepFourPanel from 'src/components/login/LoginStepFourPanel.vue';
 
 const router = useRouter();
+const { setAuthDataFromPayload } = useAuth();
 
 const email = ref('');
 const phone = ref('');
@@ -135,13 +135,6 @@ const validateCodeInput = async () => {
   }
 };
 
-const setUserAndPermissions = async (response) => {
-  const { user, access_token } = response;
-  userStore().user = user;
-  userStore().accessToken = access_token;
-  await permissionStore().fetchScopes();
-};
-
 const registerUserAndProvider = async () => {
   const payload = {
     ...stepThreeForm.value,
@@ -153,7 +146,7 @@ const registerUserAndProvider = async () => {
 
   const response = await createUserAndProvider(payload);
   if (response.status === 200) {
-    await setUserAndPermissions(response.data.payload);
+    await setAuthDataFromPayload(response.data.payload);
     router.push({ name: 'DashboardPage' });
   } else {
     console.error('Failed to create user and provider');