Update login.py to include request parameter in refresh_token endpoint
This commit is contained in:
parent
2f91fc0b8f
commit
a7427ef20b
11 changed files with 91 additions and 79 deletions
|
|
@ -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")
|
||||||
|
|
|
||||||
|
|
@ -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" },
|
||||||
|
|
|
||||||
|
|
@ -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) {
|
||||||
|
|
|
||||||
|
|
@ -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;
|
||||||
|
|
|
||||||
|
|
@ -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
|
||||||
|
|
|
||||||
|
|
@ -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,
|
||||||
|
|
|
||||||
|
|
@ -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)) {
|
||||||
|
|
|
||||||
|
|
@ -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;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
|
||||||
|
|
@ -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) => {
|
||||||
|
|
|
||||||
|
|
@ -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) => {
|
||||||
|
|
|
||||||
|
|
@ -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;
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue