diff --git a/src/pages/authentication/ResetPasswordPage.jsx b/src/pages/authentication/ResetPasswordPage.jsx index d68694a7..21b03df0 100644 --- a/src/pages/authentication/ResetPasswordPage.jsx +++ b/src/pages/authentication/ResetPasswordPage.jsx @@ -67,9 +67,13 @@ const ResetPasswordPage = () => { navigate("/auth/login", { replace: true }); // setLoading(false); } catch (error) { - showToast("Link is expries or Invalid ", "error"); - setTokenExpired(true); + debugger; setLoading(false); + if (error?.response?.status === 400) { + showToast("Please check valid Credentials", "error"); + } else { + setTokenExpired(true); + } } }; @@ -77,7 +81,10 @@ const ResetPasswordPage = () => { return (

Invalid Link 🔒

-

This link appears to be invalid or expired. Please use the 'Forgot Password' feature to set your new password.

+

+ This link appears to be invalid or expired. Please use the 'Forgot + Password' feature to set your new password. +

Go to Forgot Password @@ -142,7 +149,6 @@ const ResetPasswordPage = () => { borderTopLeftRadius: 0, borderBottomLeftRadius: 0, borderLeft: 0, - }} > {hidepass ? ( @@ -185,7 +191,6 @@ const ResetPasswordPage = () => { borderTopLeftRadius: 0, borderBottomLeftRadius: 0, borderLeft: 0, - }} > {hidepass1 ? ( diff --git a/src/repositories/AuthRepository.jsx b/src/repositories/AuthRepository.jsx index 503c07bc..4df8c89d 100644 --- a/src/repositories/AuthRepository.jsx +++ b/src/repositories/AuthRepository.jsx @@ -1,18 +1,20 @@ import { api } from "../utils/axiosClient"; const AuthRepository = { - login: (data) => api.post("/api/auth/login", data), - refreshToken: (data) => api.post("/api/auth/refresh-token", data), + // Public routes (no auth token required) + login: (data) => api.postPublic("/api/auth/login", data), + refreshToken: (data) => api.postPublic("/api/auth/refresh-token", data), + forgotPassword: (data) => api.postPublic("/api/auth/forgot-password", data), + resetPassword: (data) => api.postPublic("/api/auth/reset-password", data), + sendOTP: (data) => api.postPublic("/api/auth/send-otp", data), + verifyOTP: (data) => api.postPublic("/api/auth/login-otp", data), + register: (data) => api.postPublic("/api/auth/register", data), + sendMail: (data) => api.postPublic("/api/auth/sendmail", data), + // Protected routes (require auth token) logout: (data) => api.post("/api/auth/logout", data), - profile: () => api.get(`/api/user/profile`), - register: (data) => api.post("api/auth/register", data), - resetPassword: (data) => api.post("/api/auth/reset-password", data), - forgotPassword: (data) => api.post("/api/auth/forgot-password", data), - sendMail: (data) => api.post("/api/auth/sendmail", data), - changepassword: ( data ) => api.post( "/api/auth/change-password", data ), - sendOTP: ( data ) => api.post( 'api/auth/send-otp', data ), - verifyOTP:(data)=>api.post("api/auth/login-otp",data) + profile: () => api.get("/api/user/profile"), + changepassword: (data) => api.post("/api/auth/change-password", data), }; export default AuthRepository; diff --git a/src/utils/axiosClient.jsx b/src/utils/axiosClient.jsx index e2766d4c..20ff68ba 100644 --- a/src/utils/axiosClient.jsx +++ b/src/utils/axiosClient.jsx @@ -5,18 +5,22 @@ import showToast from "../services/toastService"; const base_Url = process.env.VITE_BASE_URL; // const base_Url = "https://api.marcoaiot.com"; export const axiosClient = axios.create({ - baseURL: base_Url, // Your Web API URL - withCredentials: false, // Required if the API uses cookies + baseURL: base_Url, + withCredentials: false, headers: { - "Content-Type": "application/json", // Specify the content type + "Content-Type": "application/json", }, }); + +// Auto retry failed requests (e.g., network issues) axiosRetry(axiosClient, { retries: 3 }); -// Request interceptor to add Bearer token +// Request Interceptor — Add Bearer token if required axiosClient.interceptors.request.use( async (config) => { - if (config.authRequired) { + const requiresAuth = config.authRequired !== false; // default to true + + if (requiresAuth) { const token = localStorage.getItem("jwtToken"); if (token) { config.headers["Authorization"] = `Bearer ${token}`; @@ -25,25 +29,24 @@ axiosClient.interceptors.request.use( config._retry = false; } } + return config; }, (error) => Promise.reject(error) ); -// // Response interceptor to handle responses globally (optional) -// Add an interceptor to handle expired tokens +// 🔄 Response Interceptor — Handle 401, refresh token, etc. axiosClient.interceptors.response.use( (response) => response, - async (error) => { const originalRequest = error.config; - // Prevent infinite loop - if (!originalRequest || originalRequest._retry) { + // Skip retry for public requests or already retried ones + if (!originalRequest || originalRequest._retry || originalRequest.authRequired === false) { return Promise.reject(error); } - // Only show one toast per request + // Avoid showing multiple toasts if (!originalRequest._toastShown) { originalRequest._toastShown = true; @@ -59,7 +62,6 @@ axiosClient.interceptors.response.use( 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"); @@ -70,7 +72,7 @@ axiosClient.interceptors.response.use( } try { - // Refresh token + // Refresh token call const res = await axiosClient.post("/api/Auth/refresh-token", { token: localStorage.getItem("jwtToken"), refreshToken, @@ -78,15 +80,13 @@ axiosClient.interceptors.response.use( const { token, refreshToken: newRefreshToken } = res.data.data; - // Save new tokens + // Save updated tokens localStorage.setItem("jwtToken", token); localStorage.setItem("refreshToken", newRefreshToken); - // Set Authorization header + // Retry original request with new token 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 + return axiosClient(originalRequest); } catch (refreshError) { redirectToLogin(); return Promise.reject(refreshError); @@ -96,11 +96,12 @@ axiosClient.interceptors.response.use( showToast("An unknown error occurred.", "error"); } } + return Promise.reject(error); } ); -// Generic API Call +// Generic API function const apiRequest = async (method, url, data = {}, config = {}) => { try { const response = await axiosClient({ @@ -116,15 +117,16 @@ const apiRequest = async (method, url, data = {}, config = {}) => { } }; +// Exported API wrapper export const api = { - // For public routes like login, set authRequired: false + // Public routes (no token required) postPublic: (url, data = {}, customHeaders = {}) => apiRequest("post", url, data, { headers: { ...customHeaders }, authRequired: false, }), - // For protected routes, authRequired defaults to true + // Authenticated routes get: (url, params = {}, customHeaders = {}) => apiRequest("get", url, params, { headers: { ...customHeaders }, @@ -149,7 +151,8 @@ export const api = { authRequired: true, }), }; -//export default axiosClient; + +// Redirect helper function redirectToLogin() { window.location.href = "/auth/login"; -} +} \ No newline at end of file