diff --git a/backend/users/views.py b/backend/users/views.py index a6f5a17..99fe2f8 100644 --- a/backend/users/views.py +++ b/backend/users/views.py @@ -66,7 +66,7 @@ class TokenGenerateView(TokenObtainPairView): class RefreshTokenView(TokenRefreshView): - permission_classes = (permissions.IsAuthenticated,) + permission_classes = (permissions.AllowAny,) def post(self, request, *args, **kwargs): refresh_token = request.COOKIES.get(settings.SIMPLE_JWT["AUTH_COOKIE"]) diff --git a/frontend/src/api/apiClient.ts b/frontend/src/api/apiClient.ts index e0e03e1..d0bb24a 100644 --- a/frontend/src/api/apiClient.ts +++ b/frontend/src/api/apiClient.ts @@ -1,10 +1,30 @@ import axios from "axios"; -const apiClient = axios.create({ +const authApiClient = axios.create({ baseURL: `${import.meta.env.VITE_API_URL}/api/auth/`, + withCredentials: true, headers: { "Content-Type": "application/json", }, }); -export default apiClient; +authApiClient.interceptors.response.use( + (response) => response, + async (error) => { + if (error.response.status === 401) { + // token expired, refresh it + try { + const response = await authApiClient.post("refresh/"); + if (response.status === 200) { + // refresh successful, retry the request + return authApiClient(error.config); + } + } catch (error) { + return Promise.reject(error); + } + } + return Promise.reject(error); + }, +); + +export default authApiClient; diff --git a/frontend/src/pages/Activate.tsx b/frontend/src/pages/Activate.tsx index 22bffec..2bef3e2 100644 --- a/frontend/src/pages/Activate.tsx +++ b/frontend/src/pages/Activate.tsx @@ -1,7 +1,7 @@ import { CheckCircleIcon, XCircleIcon } from "@phosphor-icons/react"; import { useEffect, useRef, useState } from "react"; import { useNavigate, useParams } from "react-router-dom"; -import apiClient from "../api/apiClient"; +import authApiClient from "../api/apiClient"; import Logo from "../components/Logo"; export default function Activate() { @@ -20,7 +20,7 @@ export default function Activate() { const activateAccount = async () => { try { - await apiClient.get(`/activate/${uidb64}/${token}/`); + await authApiClient.get(`/activate/${uidb64}/${token}/`); setStatus("success"); } catch (err) { console.error("Activation error:", err); diff --git a/frontend/src/pages/Register.tsx b/frontend/src/pages/Register.tsx index 05f0264..871647a 100644 --- a/frontend/src/pages/Register.tsx +++ b/frontend/src/pages/Register.tsx @@ -5,7 +5,7 @@ import { useState } from "react"; import { useForm } from "react-hook-form"; import { useNavigate } from "react-router-dom"; import { z } from "zod"; -import apiClient from "../api/apiClient"; +import authApiClient from "../api/apiClient"; import Logo from "../components/Logo"; import FormField from "../components/ui/FormField"; @@ -41,7 +41,7 @@ export default function Register() { setIsLoading(true); setApiError(null); try { - await apiClient.post("/register/", { + await authApiClient.post("/register/", { full_name: data.full_name, email: data.email, password: data.password,