Invalid OTP Redirects to Login Page Instead of Showing Error. #206

Closed
kartik.sharma wants to merge 1 commits from Kartik_Bug#494 into Issues_June_3W

View File

@ -32,18 +32,90 @@ axiosClient.interceptors.request.use(
// // Response interceptor to handle responses globally (optional) // // Response interceptor to handle responses globally (optional)
// Add an interceptor to handle expired tokens // Add an interceptor to handle expired tokens
// PAST CODE
// axiosClient.interceptors.response.use(
// (response) => response,
// async (error) => {
// const originalRequest = error.config;
// // Prevent infinite loop
// if (!originalRequest || originalRequest._retry) {
// return Promise.reject(error);
// }
// // Only show one toast per request
// if (!originalRequest._toastShown) {
// originalRequest._toastShown = true;
// if (error.code === "ERR_CONNECTION_REFUSED") {
// showToast("Unable to connect to the server. Please try again later.", "error");
// } else if (error.code === "ERR_NETWORK") {
// showToast("Network error. Please check your connection.", "error");
// redirectToLogin();
// } else if (error.code === "ECONNABORTED") {
// showToast("Request timed out. Please try again.", "error");
// } else if (error.response) {
// const status = error.response.status;
// const isRefreshRequest = error.config.url.includes("refresh-token");
// if (status === 401 && !isRefreshRequest) {
// // Mark as retried to avoid loops
// originalRequest._retry = true;
// const refreshToken = localStorage.getItem("refreshToken");
// if (!refreshToken || error.response.data?.errors === "Invalid or expired refresh token.") {
// redirectToLogin();
// return Promise.reject(error);
// }
// try {
// // Refresh token
// const res = await axiosClient.post("/api/Auth/refresh-token", {
// token: localStorage.getItem("jwtToken"),
// refreshToken,
// });
// const { token, refreshToken: newRefreshToken } = res.data.data;
// // Save new tokens
// localStorage.setItem("jwtToken", token);
// localStorage.setItem("refreshToken", newRefreshToken);
// // Set Authorization header
// originalRequest.headers["Authorization"] = `Bearer ${token}`;
// // Optional: Instead of retrying, you may choose to reload app or go to home
// return axiosClient(originalRequest); // <== only retry once
// } catch (refreshError) {
// redirectToLogin();
// return Promise.reject(refreshError);
// }
// }
// } else {
// showToast("An unknown error occurred.", "error");
// }
// }
// return Promise.reject(error);
// }
// );
// Generic API Call
axiosClient.interceptors.response.use( axiosClient.interceptors.response.use(
(response) => response, (response) => response,
async (error) => { async (error) => {
const originalRequest = error.config; const originalRequest = error.config;
//change here
// Prevent infinite loop if (!originalRequest || originalRequest._retry > 0) {
if (!originalRequest || originalRequest._retry) {
return Promise.reject(error); return Promise.reject(error);
} }
//add this line
originalRequest._retry = originalRequest._retry || 0;
// Only show one toast per request
if (!originalRequest._toastShown) { if (!originalRequest._toastShown) {
originalRequest._toastShown = true; originalRequest._toastShown = true;
@ -56,21 +128,27 @@ axiosClient.interceptors.response.use(
showToast("Request timed out. Please try again.", "error"); showToast("Request timed out. Please try again.", "error");
} else if (error.response) { } else if (error.response) {
const status = error.response.status; const status = error.response.status;
const isRefreshRequest = error.config.url.includes("refresh-token"); const isRefreshRequest = originalRequest.url.includes("refresh-token");
// const errorMessage = error.response?.data?.message || error.response?.data?.errors;
// add this line
if (isLoginAuthError && !isRefreshRequest) {
// showToast(errorMessage || "Authentication failed. Please check your credentials.", "error");
return Promise.reject(error);
}
if (status === 401 && !isRefreshRequest) { if (status === 401 && !isRefreshRequest) {
// Mark as retried to avoid loops originalRequest._retry++; // this add
originalRequest._retry = true;
const refreshToken = localStorage.getItem("refreshToken"); const refreshToken = localStorage.getItem("refreshToken");
if (!refreshToken || error.response.data?.errors === "Invalid or expired refresh token.") { if (!refreshToken || errorMessage === "Invalid or expired refresh token.") {
showToast("Your session has expired. Please log in again.", "error");
redirectToLogin(); redirectToLogin();
return Promise.reject(error); return Promise.reject(error);
} }
try { try {
// Refresh token
const res = await axiosClient.post("/api/Auth/refresh-token", { const res = await axiosClient.post("/api/Auth/refresh-token", {
token: localStorage.getItem("jwtToken"), token: localStorage.getItem("jwtToken"),
refreshToken, refreshToken,
@ -78,19 +156,20 @@ axiosClient.interceptors.response.use(
const { token, refreshToken: newRefreshToken } = res.data.data; const { token, refreshToken: newRefreshToken } = res.data.data;
// Save new tokens
localStorage.setItem("jwtToken", token); localStorage.setItem("jwtToken", token);
localStorage.setItem("refreshToken", newRefreshToken); localStorage.setItem("refreshToken", newRefreshToken);
// Set Authorization header
originalRequest.headers["Authorization"] = `Bearer ${token}`; originalRequest.headers["Authorization"] = `Bearer ${token}`;
// Optional: Instead of retrying, you may choose to reload app or go to home return axiosClient(originalRequest);
return axiosClient(originalRequest); // <== only retry once
} catch (refreshError) { } catch (refreshError) {
showToast("Failed to refresh session. Please log in again.", "error");
redirectToLogin(); redirectToLogin();
return Promise.reject(refreshError); return Promise.reject(refreshError);
} }
} else {
const defaultErrorMessage = `Error ${status}: ${error.response?.statusText || "Something went wrong."}`;
showToast(errorMessage || defaultErrorMessage, "error");
} }
} else { } else {
showToast("An unknown error occurred.", "error"); showToast("An unknown error occurred.", "error");
@ -100,7 +179,6 @@ axiosClient.interceptors.response.use(
} }
); );
// Generic API Call
const apiRequest = async (method, url, data = {}, config = {}) => { const apiRequest = async (method, url, data = {}, config = {}) => {
try { try {
const response = await axiosClient({ const response = await axiosClient({