From 9bf9b456b865f03900a093b1094b2b9d747ad952 Mon Sep 17 00:00:00 2001
From: "Embruch, Gerd" <gerd.embruch@uni-hamburg.de>
Date: Wed, 3 Jul 2024 13:25:09 +0200
Subject: [PATCH] enables jwt refresh on every api call

---
 src/contexts/Auth/AuthState.jsx  | 21 +++++++++++++----
 src/pages/User/Login.jsx         |  4 ++--
 src/pages/User/ResetPassword.jsx |  2 +-
 src/pages/User/Signup.jsx        |  2 +-
 src/utils/AxiosConfig.js         | 39 ++++++++------------------------
 5 files changed, 30 insertions(+), 38 deletions(-)

diff --git a/src/contexts/Auth/AuthState.jsx b/src/contexts/Auth/AuthState.jsx
index fd36942..3fa34b5 100755
--- a/src/contexts/Auth/AuthState.jsx
+++ b/src/contexts/Auth/AuthState.jsx
@@ -26,11 +26,22 @@ function AuthState({ children }) {
 
   // ### LOGIN
   async function login(credentials) {
-    const result = await api.post(
-      '/users/login',
-      credentials,
-      { withCredentials: true }
-    );
+    let result = {};
+    try {
+      result = await api.post(
+        '/users/login',
+        credentials,
+        { withCredentials: true }
+      );
+    } catch (error) {
+      result = await api.post(
+        '/users/adminlogin',
+        credentials,
+        { withCredentials: true }
+      );
+      // try to match output with normal user
+      result.data.record = { ...result.data.admin, isAdmin: true };
+    }
     // set current user to login and merge accessToken into currentUser
     dispatchCurrentUser({ type: USER_ACTIONS.SET, payload: { ...result.data.record } });
     setAccessToken(result.data.token);
diff --git a/src/pages/User/Login.jsx b/src/pages/User/Login.jsx
index d8d73a6..0dbd5c0 100644
--- a/src/pages/User/Login.jsx
+++ b/src/pages/User/Login.jsx
@@ -34,7 +34,7 @@ function Login() {
   // ### PREPARE FORM
   const methods = useForm({
     resolver: zodResolver(schema),
-    mode: 'onBlur',
+    mode: 'onSubmit',
     defaultValues: {
       email: '',
       password: ''
@@ -106,7 +106,7 @@ function Login() {
 
       <div className="mt-4 flex justify-between">
         <Link to="/reset_password">Reset Password</Link>
-        <Link to="/signup">Create an account</Link>
+        <Link to="/signup">Create account</Link>
       </div>
     </>
   );
diff --git a/src/pages/User/ResetPassword.jsx b/src/pages/User/ResetPassword.jsx
index 1950c9c..29d0067 100644
--- a/src/pages/User/ResetPassword.jsx
+++ b/src/pages/User/ResetPassword.jsx
@@ -38,7 +38,7 @@ function ResetPasswordForm() {
   // ### PREPARE FORM
   const methods = useForm({
     resolver: zodResolver(schema),
-    mode: 'onBlur',
+    mode: 'onSubmit',
     defaultValues: {
       token: token,
     }
diff --git a/src/pages/User/Signup.jsx b/src/pages/User/Signup.jsx
index 9823a68..d3eb5da 100644
--- a/src/pages/User/Signup.jsx
+++ b/src/pages/User/Signup.jsx
@@ -43,7 +43,7 @@ function Signup() {
   // ### PREPARE FORM
   const methods = useForm({
     resolver: zodResolver(schema),
-    mode: 'onBlur',
+    mode: 'onSubmit',
     defaultValues: {
       name: '',
       username: '',
diff --git a/src/utils/AxiosConfig.js b/src/utils/AxiosConfig.js
index 7e9e6a7..a32332c 100755
--- a/src/utils/AxiosConfig.js
+++ b/src/utils/AxiosConfig.js
@@ -29,40 +29,21 @@ api.interceptors.request.use(
 // ### RESPONSE INTERCEPTOR 
 // refreshes accessToken if needed
 api.interceptors.response.use(
-  (res) => {
-    return res;
-  },
-  async (err) => {
-    // console.log('JWT error: ', err);
-    // save original request config
-    const originalConfig = err.config;
-    // if access denied and not a retry already
-    // BUG: Infinit loop because _retry isn't set at runtime
-    // console.log('originalConfig: ',originalConfig);
-    // console.log('originalConfig: ',JSON.stringify(originalConfig));
-    if (originalConfig && err?.response?.status === 403 && originalConfig._retry !== true) {
-      // patch config to remember it's a retry
-      originalConfig._retry = true;
-      console.log('trying to refresh the accessToken and rerun the request');
-      // console.log('retry', err.code, originalConfig._retry);
-      // refresh access token
-      try {
-        const result = await api.get(
+  async (res) => {
+    switch (res.config.url) {
+      case '/users/refreshjwt':
+      case '/users/logout':
+      case '/users/login':
+        return res;
+      default:
+        const refresh = await api.get(
           '/users/refreshjwt',
           {},
           { withCredentials: true }
         );
-        // TODO: don't store accessToken in localStorage, keep in memory only
-        localStorage.setItem("accessToken", JSON.stringify(result.data.accessToken));
-        // run retry
-        return api(originalConfig);
-
-      } catch (error) {
-        return Promise.reject(error);
-      }
+        localStorage.setItem("accessToken", JSON.stringify(refresh.data.token));
+        return res;
     }
-    return Promise.reject(err);
-
   }
 );
 
-- 
GitLab