Update login.py to include request parameter in refresh_token endpoint

This commit is contained in:
anovazzi1 2024-01-08 15:35:10 -03:00
commit a7427ef20b
11 changed files with 91 additions and 79 deletions

View file

@ -1,4 +1,4 @@
from fastapi import Response, APIRouter, Depends, HTTPException, status from fastapi import Request, Response, APIRouter, Depends, HTTPException, status
from fastapi.security import OAuth2PasswordRequestForm from fastapi.security import OAuth2PasswordRequestForm
from sqlmodel import Session from sqlmodel import Session
@ -59,7 +59,8 @@ async def auto_login(db: Session = Depends(get_session), settings_service=Depend
@router.post("/refresh") @router.post("/refresh")
async def refresh_token(response: Response, token: str): async def refresh_token(request: Request, response: Response):
token = request.cookies.get("refresh_token_lf")
if token: if token:
tokens = create_refresh_token(token) tokens = create_refresh_token(token)
response.set_cookie("refresh_token_lf", tokens["refresh_token"], httponly=True, secure=True, samesite="strict") response.set_cookie("refresh_token_lf", tokens["refresh_token"], httponly=True, secure=True, samesite="strict")

View file

@ -284,7 +284,7 @@
{ "name": "Accept-Language", "value": "en-US,en;q=0.9" }, { "name": "Accept-Language", "value": "en-US,en;q=0.9" },
{ "name": "Authorization", "value": "Bearer eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJzdWIiOiJkMjUzYmZiYS02MzY4LTQ0ZGMtODVmNy0wZDZkYTllNDU5NjgiLCJleHAiOjE3MzM4NTY4OTh9.5MFFb0JCck3ITSKXbxhwO9yAscnXcwXNTV70ZYBRB20" }, { "name": "Authorization", "value": "Bearer eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJzdWIiOiJkMjUzYmZiYS02MzY4LTQ0ZGMtODVmNy0wZDZkYTllNDU5NjgiLCJleHAiOjE3MzM4NTY4OTh9.5MFFb0JCck3ITSKXbxhwO9yAscnXcwXNTV70ZYBRB20" },
{ "name": "Connection", "value": "keep-alive" }, { "name": "Connection", "value": "keep-alive" },
{ "name": "Cookie", "value": "access_tkn_lflw=eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJzdWIiOiJkMjUzYmZiYS02MzY4LTQ0ZGMtODVmNy0wZDZkYTllNDU5NjgiLCJleHAiOjE3MzM4NTY4OTh9.5MFFb0JCck3ITSKXbxhwO9yAscnXcwXNTV70ZYBRB20; refresh_tkn_lflw=auto" }, { "name": "Cookie", "value": "access_token_lf=eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJzdWIiOiJkMjUzYmZiYS02MzY4LTQ0ZGMtODVmNy0wZDZkYTllNDU5NjgiLCJleHAiOjE3MzM4NTY4OTh9.5MFFb0JCck3ITSKXbxhwO9yAscnXcwXNTV70ZYBRB20; refresh_tkn_lflw=auto" },
{ "name": "Host", "value": "localhost:3000" }, { "name": "Host", "value": "localhost:3000" },
{ "name": "Referer", "value": "http://localhost:3000/flows" }, { "name": "Referer", "value": "http://localhost:3000/flows" },
{ "name": "Sec-Fetch-Dest", "value": "empty" }, { "name": "Sec-Fetch-Dest", "value": "empty" },
@ -338,7 +338,7 @@
{ "name": "Accept-Language", "value": "en-US,en;q=0.9" }, { "name": "Accept-Language", "value": "en-US,en;q=0.9" },
{ "name": "Authorization", "value": "Bearer eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJzdWIiOiJkMjUzYmZiYS02MzY4LTQ0ZGMtODVmNy0wZDZkYTllNDU5NjgiLCJleHAiOjE3MzM4NTY4OTh9.5MFFb0JCck3ITSKXbxhwO9yAscnXcwXNTV70ZYBRB20" }, { "name": "Authorization", "value": "Bearer eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJzdWIiOiJkMjUzYmZiYS02MzY4LTQ0ZGMtODVmNy0wZDZkYTllNDU5NjgiLCJleHAiOjE3MzM4NTY4OTh9.5MFFb0JCck3ITSKXbxhwO9yAscnXcwXNTV70ZYBRB20" },
{ "name": "Connection", "value": "keep-alive" }, { "name": "Connection", "value": "keep-alive" },
{ "name": "Cookie", "value": "access_tkn_lflw=eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJzdWIiOiJkMjUzYmZiYS02MzY4LTQ0ZGMtODVmNy0wZDZkYTllNDU5NjgiLCJleHAiOjE3MzM4NTY4OTh9.5MFFb0JCck3ITSKXbxhwO9yAscnXcwXNTV70ZYBRB20; refresh_tkn_lflw=auto" }, { "name": "Cookie", "value": "access_token_lf=eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJzdWIiOiJkMjUzYmZiYS02MzY4LTQ0ZGMtODVmNy0wZDZkYTllNDU5NjgiLCJleHAiOjE3MzM4NTY4OTh9.5MFFb0JCck3ITSKXbxhwO9yAscnXcwXNTV70ZYBRB20; refresh_tkn_lflw=auto" },
{ "name": "Host", "value": "localhost:3000" }, { "name": "Host", "value": "localhost:3000" },
{ "name": "Referer", "value": "http://localhost:3000/flows" }, { "name": "Referer", "value": "http://localhost:3000/flows" },
{ "name": "Sec-Fetch-Dest", "value": "empty" }, { "name": "Sec-Fetch-Dest", "value": "empty" },
@ -392,7 +392,7 @@
{ "name": "Accept-Language", "value": "en-US,en;q=0.9" }, { "name": "Accept-Language", "value": "en-US,en;q=0.9" },
{ "name": "Authorization", "value": "Bearer eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJzdWIiOiJkMjUzYmZiYS02MzY4LTQ0ZGMtODVmNy0wZDZkYTllNDU5NjgiLCJleHAiOjE3MzM4NTY4OTh9.5MFFb0JCck3ITSKXbxhwO9yAscnXcwXNTV70ZYBRB20" }, { "name": "Authorization", "value": "Bearer eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJzdWIiOiJkMjUzYmZiYS02MzY4LTQ0ZGMtODVmNy0wZDZkYTllNDU5NjgiLCJleHAiOjE3MzM4NTY4OTh9.5MFFb0JCck3ITSKXbxhwO9yAscnXcwXNTV70ZYBRB20" },
{ "name": "Connection", "value": "keep-alive" }, { "name": "Connection", "value": "keep-alive" },
{ "name": "Cookie", "value": "access_tkn_lflw=eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJzdWIiOiJkMjUzYmZiYS02MzY4LTQ0ZGMtODVmNy0wZDZkYTllNDU5NjgiLCJleHAiOjE3MzM4NTY4OTh9.5MFFb0JCck3ITSKXbxhwO9yAscnXcwXNTV70ZYBRB20; refresh_tkn_lflw=auto" }, { "name": "Cookie", "value": "access_token_lf=eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJzdWIiOiJkMjUzYmZiYS02MzY4LTQ0ZGMtODVmNy0wZDZkYTllNDU5NjgiLCJleHAiOjE3MzM4NTY4OTh9.5MFFb0JCck3ITSKXbxhwO9yAscnXcwXNTV70ZYBRB20; refresh_tkn_lflw=auto" },
{ "name": "Host", "value": "localhost:3000" }, { "name": "Host", "value": "localhost:3000" },
{ "name": "Referer", "value": "http://localhost:3000/flows" }, { "name": "Referer", "value": "http://localhost:3000/flows" },
{ "name": "Sec-Fetch-Dest", "value": "empty" }, { "name": "Sec-Fetch-Dest", "value": "empty" },
@ -446,7 +446,7 @@
{ "name": "Accept-Language", "value": "en-US,en;q=0.9" }, { "name": "Accept-Language", "value": "en-US,en;q=0.9" },
{ "name": "Authorization", "value": "Bearer eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJzdWIiOiJkMjUzYmZiYS02MzY4LTQ0ZGMtODVmNy0wZDZkYTllNDU5NjgiLCJleHAiOjE3MzM4NTY4OTh9.5MFFb0JCck3ITSKXbxhwO9yAscnXcwXNTV70ZYBRB20" }, { "name": "Authorization", "value": "Bearer eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJzdWIiOiJkMjUzYmZiYS02MzY4LTQ0ZGMtODVmNy0wZDZkYTllNDU5NjgiLCJleHAiOjE3MzM4NTY4OTh9.5MFFb0JCck3ITSKXbxhwO9yAscnXcwXNTV70ZYBRB20" },
{ "name": "Connection", "value": "keep-alive" }, { "name": "Connection", "value": "keep-alive" },
{ "name": "Cookie", "value": "access_tkn_lflw=eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJzdWIiOiJkMjUzYmZiYS02MzY4LTQ0ZGMtODVmNy0wZDZkYTllNDU5NjgiLCJleHAiOjE3MzM4NTY4OTh9.5MFFb0JCck3ITSKXbxhwO9yAscnXcwXNTV70ZYBRB20; refresh_tkn_lflw=auto" }, { "name": "Cookie", "value": "access_token_lf=eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJzdWIiOiJkMjUzYmZiYS02MzY4LTQ0ZGMtODVmNy0wZDZkYTllNDU5NjgiLCJleHAiOjE3MzM4NTY4OTh9.5MFFb0JCck3ITSKXbxhwO9yAscnXcwXNTV70ZYBRB20; refresh_tkn_lflw=auto" },
{ "name": "Host", "value": "localhost:3000" }, { "name": "Host", "value": "localhost:3000" },
{ "name": "Referer", "value": "http://localhost:3000/flow/2920dde2-5c24-4fe0-9c06-ef86b5a16a99" }, { "name": "Referer", "value": "http://localhost:3000/flow/2920dde2-5c24-4fe0-9c06-ef86b5a16a99" },
{ "name": "Sec-Fetch-Dest", "value": "empty" }, { "name": "Sec-Fetch-Dest", "value": "empty" },
@ -500,7 +500,7 @@
{ "name": "Accept-Language", "value": "en-US,en;q=0.9" }, { "name": "Accept-Language", "value": "en-US,en;q=0.9" },
{ "name": "Authorization", "value": "Bearer eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJzdWIiOiJkMjUzYmZiYS02MzY4LTQ0ZGMtODVmNy0wZDZkYTllNDU5NjgiLCJleHAiOjE3MzM4NTY4OTh9.5MFFb0JCck3ITSKXbxhwO9yAscnXcwXNTV70ZYBRB20" }, { "name": "Authorization", "value": "Bearer eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJzdWIiOiJkMjUzYmZiYS02MzY4LTQ0ZGMtODVmNy0wZDZkYTllNDU5NjgiLCJleHAiOjE3MzM4NTY4OTh9.5MFFb0JCck3ITSKXbxhwO9yAscnXcwXNTV70ZYBRB20" },
{ "name": "Connection", "value": "keep-alive" }, { "name": "Connection", "value": "keep-alive" },
{ "name": "Cookie", "value": "access_tkn_lflw=eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJzdWIiOiJkMjUzYmZiYS02MzY4LTQ0ZGMtODVmNy0wZDZkYTllNDU5NjgiLCJleHAiOjE3MzM4NTY4OTh9.5MFFb0JCck3ITSKXbxhwO9yAscnXcwXNTV70ZYBRB20; refresh_tkn_lflw=auto" }, { "name": "Cookie", "value": "access_token_lf=eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJzdWIiOiJkMjUzYmZiYS02MzY4LTQ0ZGMtODVmNy0wZDZkYTllNDU5NjgiLCJleHAiOjE3MzM4NTY4OTh9.5MFFb0JCck3ITSKXbxhwO9yAscnXcwXNTV70ZYBRB20; refresh_tkn_lflw=auto" },
{ "name": "Host", "value": "localhost:3000" }, { "name": "Host", "value": "localhost:3000" },
{ "name": "Referer", "value": "http://localhost:3000/flow/2920dde2-5c24-4fe0-9c06-ef86b5a16a99" }, { "name": "Referer", "value": "http://localhost:3000/flow/2920dde2-5c24-4fe0-9c06-ef86b5a16a99" },
{ "name": "Sec-Fetch-Dest", "value": "empty" }, { "name": "Sec-Fetch-Dest", "value": "empty" },
@ -554,7 +554,7 @@
{ "name": "Accept-Language", "value": "en-US,en;q=0.9" }, { "name": "Accept-Language", "value": "en-US,en;q=0.9" },
{ "name": "Authorization", "value": "Bearer eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJzdWIiOiJkMjUzYmZiYS02MzY4LTQ0ZGMtODVmNy0wZDZkYTllNDU5NjgiLCJleHAiOjE3MzM4NTY4OTh9.5MFFb0JCck3ITSKXbxhwO9yAscnXcwXNTV70ZYBRB20" }, { "name": "Authorization", "value": "Bearer eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJzdWIiOiJkMjUzYmZiYS02MzY4LTQ0ZGMtODVmNy0wZDZkYTllNDU5NjgiLCJleHAiOjE3MzM4NTY4OTh9.5MFFb0JCck3ITSKXbxhwO9yAscnXcwXNTV70ZYBRB20" },
{ "name": "Connection", "value": "keep-alive" }, { "name": "Connection", "value": "keep-alive" },
{ "name": "Cookie", "value": "access_tkn_lflw=eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJzdWIiOiJkMjUzYmZiYS02MzY4LTQ0ZGMtODVmNy0wZDZkYTllNDU5NjgiLCJleHAiOjE3MzM4NTY4OTh9.5MFFb0JCck3ITSKXbxhwO9yAscnXcwXNTV70ZYBRB20; refresh_tkn_lflw=auto" }, { "name": "Cookie", "value": "access_token_lf=eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJzdWIiOiJkMjUzYmZiYS02MzY4LTQ0ZGMtODVmNy0wZDZkYTllNDU5NjgiLCJleHAiOjE3MzM4NTY4OTh9.5MFFb0JCck3ITSKXbxhwO9yAscnXcwXNTV70ZYBRB20; refresh_tkn_lflw=auto" },
{ "name": "Host", "value": "localhost:3000" }, { "name": "Host", "value": "localhost:3000" },
{ "name": "Referer", "value": "http://localhost:3000/flow/2920dde2-5c24-4fe0-9c06-ef86b5a16a99" }, { "name": "Referer", "value": "http://localhost:3000/flow/2920dde2-5c24-4fe0-9c06-ef86b5a16a99" },
{ "name": "Sec-Fetch-Dest", "value": "empty" }, { "name": "Sec-Fetch-Dest", "value": "empty" },

View file

@ -1,19 +1,15 @@
import { useContext, useEffect } from "react"; import { useContext } from "react";
import { Navigate } from "react-router-dom"; import { Navigate } from "react-router-dom";
import { AuthContext } from "../../contexts/authContext"; import { AuthContext } from "../../contexts/authContext";
export const ProtectedAdminRoute = ({ children }) => { export const ProtectedAdminRoute = ({ children }) => {
const { const { isAdmin, isAuthenticated, logout, userData, autoLogin } =
isAdmin, useContext(AuthContext);
isAuthenticated,
logout,
userData,
autoLogin,
} = useContext(AuthContext);
if (!isAuthenticated) { if (!isAuthenticated) {
logout(); logout().then(() => {
return <Navigate to="/login" replace />; return <Navigate to="/login" replace />;
});
} }
if ((userData && !isAdmin) || autoLogin) { if ((userData && !isAdmin) || autoLogin) {

View file

@ -3,11 +3,11 @@ import { Navigate } from "react-router-dom";
import { AuthContext } from "../../contexts/authContext"; import { AuthContext } from "../../contexts/authContext";
export const ProtectedRoute = ({ children }) => { export const ProtectedRoute = ({ children }) => {
const { isAuthenticated, logout} = const { isAuthenticated, logout } = useContext(AuthContext);
useContext(AuthContext);
if (!isAuthenticated) { if (!isAuthenticated) {
logout(); logout().then(() => {
return <Navigate to="/login" replace />; return <Navigate to="/login" replace />;
});
} }
return children; return children;

View file

@ -166,7 +166,10 @@ export default function Header(): JSX.Element {
<button <button
className={ className={
"h-7 w-7 rounded-full focus-visible:outline-0 " + "h-7 w-7 rounded-full focus-visible:outline-0 " +
(userData?.profile_image ?? gradients[parseInt(userData?.id ?? "", 30) % gradients.length]) (userData?.profile_image ??
gradients[
parseInt(userData?.id ?? "", 30) % gradients.length
])
} }
/> />
</DropdownMenuTrigger> </DropdownMenuTrigger>
@ -190,8 +193,9 @@ export default function Header(): JSX.Element {
<DropdownMenuItem <DropdownMenuItem
className="cursor-pointer" className="cursor-pointer"
onClick={() => { onClick={() => {
logout(); logout().then(() => {
navigate("/login"); navigate("/login");
});
}} }}
> >
Sign Out Sign Out

View file

@ -1,6 +1,10 @@
import { createContext, useEffect, useState } from "react"; import { createContext, useEffect, useState } from "react";
import Cookies from "universal-cookie"; import Cookies from "universal-cookie";
import { autoLogin as autoLoginApi, getLoggedUser } from "../controllers/API"; import {
autoLogin as autoLoginApi,
getLoggedUser,
requestLogout,
} from "../controllers/API";
import useAlertStore from "../stores/alertStore"; import useAlertStore from "../stores/alertStore";
import { Users } from "../types/api"; import { Users } from "../types/api";
import { AuthContextType } from "../types/contexts/auth"; import { AuthContextType } from "../types/contexts/auth";
@ -10,9 +14,8 @@ const initialValue: AuthContextType = {
setIsAdmin: () => false, setIsAdmin: () => false,
isAuthenticated: false, isAuthenticated: false,
accessToken: null, accessToken: null,
refreshToken: null,
login: () => {}, login: () => {},
logout: () => {}, logout: () => new Promise(() => {}),
userData: null, userData: null,
setUserData: () => {}, setUserData: () => {},
authenticationErrorCount: 0, authenticationErrorCount: 0,
@ -28,13 +31,10 @@ export const AuthContext = createContext<AuthContextType>(initialValue);
export function AuthProvider({ children }): React.ReactElement { export function AuthProvider({ children }): React.ReactElement {
const cookies = new Cookies(); const cookies = new Cookies();
const [accessToken, setAccessToken] = useState<string | null>( const [accessToken, setAccessToken] = useState<string | null>(
cookies.get("access_tkn_lflw") cookies.get("access_token_lf") ?? null
);
const [refreshToken, setRefreshToken] = useState<string | null>(
cookies.get("refresh_tkn_lflw")
); );
const [isAuthenticated, setIsAuthenticated] = useState<boolean>( const [isAuthenticated, setIsAuthenticated] = useState<boolean>(
!!cookies.get("refresh_tkn_lflw") && !!cookies.get("access_tkn_lflw") !!cookies.get("access_token_lf")
); );
const [isAdmin, setIsAdmin] = useState<boolean>(false); const [isAdmin, setIsAdmin] = useState<boolean>(false);
const [userData, setUserData] = useState<Users | null>(null); const [userData, setUserData] = useState<Users | null>(null);
@ -45,7 +45,7 @@ export function AuthProvider({ children }): React.ReactElement {
); );
useEffect(() => { useEffect(() => {
const storedAccessToken = cookies.get("access_tkn_lflw"); const storedAccessToken = cookies.get("access_token_lf");
if (storedAccessToken) { if (storedAccessToken) {
setAccessToken(storedAccessToken); setAccessToken(storedAccessToken);
} }
@ -65,7 +65,7 @@ export function AuthProvider({ children }): React.ReactElement {
.then((user) => { .then((user) => {
if (user && user["access_token"]) { if (user && user["access_token"]) {
user["refresh_token"] = "auto"; user["refresh_token"] = "auto";
login(user["access_token"], user["refresh_token"]); login(user["access_token"]);
setUserData(user); setUserData(user);
setAutoLogin(true); setAutoLogin(true);
setLoading(false); setLoading(false);
@ -95,25 +95,26 @@ export function AuthProvider({ children }): React.ReactElement {
}); });
} }
function login(newAccessToken: string, refreshToken: string) { function login(newAccessToken: string) {
cookies.set("access_tkn_lflw", newAccessToken, { path: "/" });
cookies.set("refresh_tkn_lflw", refreshToken, { path: "/" });
setAccessToken(newAccessToken); setAccessToken(newAccessToken);
setRefreshToken(refreshToken);
setIsAuthenticated(true); setIsAuthenticated(true);
setTimeout(() => {getUser();}, 500) setTimeout(() => {
getUser();
}, 500);
} }
function logout() { async function logout() {
cookies.remove("access_tkn_lflw", { path: "/" }); try {
cookies.remove("refresh_tkn_lflw", { path: "/" }); await requestLogout();
cookies.remove("apikey_tkn_lflw", { path: "/" }); cookies.remove("apikey_tkn_lflw", { path: "/" });
setIsAdmin(false); setIsAdmin(false);
setUserData(null); setUserData(null);
setAccessToken(null); setAccessToken(null);
setRefreshToken(null);
setIsAuthenticated(false); setIsAuthenticated(false);
} catch (error) {
console.error(error);
throw error;
}
} }
function storeApiKey(apikey: string) { function storeApiKey(apikey: string) {
@ -129,7 +130,6 @@ export function AuthProvider({ children }): React.ReactElement {
setIsAdmin, setIsAdmin,
isAuthenticated, isAuthenticated,
accessToken, accessToken,
refreshToken,
login, login,
logout, logout,
setUserData, setUserData,

View file

@ -13,7 +13,7 @@ const api: AxiosInstance = axios.create({
function ApiInterceptor() { function ApiInterceptor() {
const setErrorData = useAlertStore((state) => state.setErrorData); const setErrorData = useAlertStore((state) => state.setErrorData);
let { accessToken, login, logout, authenticationErrorCount } = let { accessToken, login, logout, authenticationErrorCount, autoLogin } =
useContext(AuthContext); useContext(AuthContext);
const navigate = useNavigate(); const navigate = useNavigate();
const cookies = new Cookies(); const cookies = new Cookies();
@ -23,44 +23,48 @@ function ApiInterceptor() {
(response) => response, (response) => response,
async (error: AxiosError) => { async (error: AxiosError) => {
if (error.response?.status === 401) { if (error.response?.status === 401) {
const refreshToken = cookies.get("refresh_tkn_lflw"); const accessToken = cookies.get("access_token_lf");
if (refreshToken && refreshToken !== "auto") { if (accessToken && !autoLogin) {
authenticationErrorCount = authenticationErrorCount + 1; authenticationErrorCount = authenticationErrorCount + 1;
if (authenticationErrorCount > 3) { if (authenticationErrorCount > 3) {
authenticationErrorCount = 0; authenticationErrorCount = 0;
logout(); logout().then(() => {
navigate("/login"); navigate("/login");
});
} }
try { try {
const res = await renewAccessToken(refreshToken); const res = await renewAccessToken();
if (res?.data?.access_token && res?.data?.refresh_token) { if (res?.data?.access_token && res?.data?.refresh_token) {
login(res?.data?.access_token, res?.data?.refresh_token); login(res?.data?.access_token);
} }
if (error?.config?.headers) { if (error?.config?.headers) {
delete error.config.headers["Authorization"]; delete error.config.headers["Authorization"];
error.config.headers["Authorization"] = `Bearer ${cookies.get( error.config.headers["Authorization"] = `Bearer ${cookies.get(
"access_tkn_lflw" "access_token_lf"
)}`; )}`;
const response = await axios.request(error.config); const response = await axios.request(error.config);
return response; return response;
} }
} catch (error) { } catch (error) {
if (axios.isAxiosError(error) && error.response?.status === 401) { if (axios.isAxiosError(error) && error.response?.status === 401) {
logout(); logout().then(() => {
navigate("/login"); navigate("/login");
});
} else { } else {
console.error(error); console.error(error);
logout(); logout().then(() => {
navigate("/login"); navigate("/login");
});
} }
} }
} }
if (!refreshToken && error?.config?.url?.includes("login")) { if (!accessToken && error?.config?.url?.includes("login")) {
return Promise.reject(error); return Promise.reject(error);
} else { } else {
logout(); logout().then(() => {
navigate("/login"); navigate("/login");
});
} }
} else { } else {
// if (URL_EXCLUDED_FROM_ERROR_RETRIES.includes(error.config?.url)) { // if (URL_EXCLUDED_FROM_ERROR_RETRIES.includes(error.config?.url)) {

View file

@ -411,11 +411,9 @@ export async function autoLogin() {
} }
} }
export async function renewAccessToken(token: string) { export async function renewAccessToken() {
try { try {
if (token) { return await api.post(`${BASE_URL_API}refresh`);
return await api.post(`${BASE_URL_API}refresh?token=${token}`);
}
} catch (error) { } catch (error) {
throw error; throw error;
} }
@ -842,3 +840,13 @@ export async function updateFlowStore(
throw error; throw error;
} }
} }
export async function requestLogout() {
try {
const response = await api.post(`${BASE_URL_API}logout`);
return response.data;
} catch (error) {
console.error(error);
throw error;
}
}

View file

@ -4,7 +4,7 @@ import { Button } from "../../../components/ui/button";
import { Input } from "../../../components/ui/input"; import { Input } from "../../../components/ui/input";
import { CONTROL_LOGIN_STATE } from "../../../constants/constants"; import { CONTROL_LOGIN_STATE } from "../../../constants/constants";
import { AuthContext } from "../../../contexts/authContext"; import { AuthContext } from "../../../contexts/authContext";
import { getLoggedUser, onLogin } from "../../../controllers/API"; import { onLogin } from "../../../controllers/API";
import useAlertStore from "../../../stores/alertStore"; import useAlertStore from "../../../stores/alertStore";
import { LoginType } from "../../../types/api"; import { LoginType } from "../../../types/api";
import { import {
@ -34,7 +34,7 @@ export default function LoginAdminPage() {
}; };
onLogin(user) onLogin(user)
.then((user) => { .then((user) => {
login(user.access_token, user.refresh_token); login(user.access_token);
navigate("/admin/"); navigate("/admin/");
}) })
.catch((error) => { .catch((error) => {

View file

@ -6,7 +6,7 @@ import { Button } from "../../components/ui/button";
import { Input } from "../../components/ui/input"; import { Input } from "../../components/ui/input";
import { CONTROL_LOGIN_STATE } from "../../constants/constants"; import { CONTROL_LOGIN_STATE } from "../../constants/constants";
import { AuthContext } from "../../contexts/authContext"; import { AuthContext } from "../../contexts/authContext";
import { getLoggedUser, onLogin } from "../../controllers/API"; import { onLogin } from "../../controllers/API";
import useAlertStore from "../../stores/alertStore"; import useAlertStore from "../../stores/alertStore";
import { LoginType } from "../../types/api"; import { LoginType } from "../../types/api";
import { import {
@ -37,7 +37,7 @@ export default function LoginPage(): JSX.Element {
}; };
onLogin(user) onLogin(user)
.then((user) => { .then((user) => {
login(user.access_token, user.refresh_token); login(user.access_token);
navigate("/"); navigate("/");
}) })
.catch((error) => { .catch((error) => {

View file

@ -5,9 +5,8 @@ export type AuthContextType = {
setIsAdmin: (isAdmin: boolean) => void; setIsAdmin: (isAdmin: boolean) => void;
isAuthenticated: boolean; isAuthenticated: boolean;
accessToken: string | null; accessToken: string | null;
refreshToken: string | null; login: (accessToken: string) => void;
login: (accessToken: string, refreshToken: string) => void; logout: () => Promise<void>;
logout: () => void;
userData: Users | null; userData: Users | null;
setUserData: (userData: Users | null) => void; setUserData: (userData: Users | null) => void;
authenticationErrorCount: number; authenticationErrorCount: number;