refactor: change logout and refresh token to use useQuery (#2999)

✨ (headerComponent/index.tsx): Add functionality to handle user logout in the header component
🔧 (api.tsx): Add useLogout and useRefreshAccessToken functions to handle user logout and access token refresh
🔧 (use-post-logout.ts): Implement useLogout function to handle user logout functionality
🔧 (use-post-refresh-access.ts): Implement useRefreshAccessToken function to handle access token refresh
🔧 (authStore.ts): Remove unnecessary imports and update the authStore functionality for user logout and access token management.

Co-authored-by: anovazzi1 <otavio2204@gmail.com>
This commit is contained in:
Cristhian Zanforlin Lousa 2024-07-29 19:16:26 -03:00 • committed by GitHub
commit 9903b4408f
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
6 changed files with 43 additions and 27 deletions

View file

@ -11,6 +11,7 @@ import {
} from "../../constants/constants"; } from "../../constants/constants";
import { AuthContext } from "../../contexts/authContext"; import { AuthContext } from "../../contexts/authContext";
import { useLogout } from "@/controllers/API/queries/auth";
import useAuthStore from "@/stores/authStore"; import useAuthStore from "@/stores/authStore";
import useAlertStore from "../../stores/alertStore"; import useAlertStore from "../../stores/alertStore";
import { useDarkStore } from "../../stores/darkStore"; import { useDarkStore } from "../../stores/darkStore";
@ -35,10 +36,13 @@ export default function Header(): JSX.Element {
const notificationCenter = useAlertStore((state) => state.notificationCenter); const notificationCenter = useAlertStore((state) => state.notificationCenter);
const location = useLocation(); const location = useLocation();
const { logout, userData } = useContext(AuthContext); const { userData } = useContext(AuthContext);
const isAdmin = useAuthStore((state) => state.isAdmin); const isAdmin = useAuthStore((state) => state.isAdmin);
const autoLogin = useAuthStore((state) => state.autoLogin); const autoLogin = useAuthStore((state) => state.autoLogin);
const { mutate: mutationLogout } = useLogout();
const logout = useAuthStore((state) => state.logout);
const navigate = useNavigate(); const navigate = useNavigate();
const removeFlow = useFlowsManagerStore((store) => store.removeFlow); const removeFlow = useFlowsManagerStore((store) => store.removeFlow);
const hasStore = useStoreStore((state) => state.hasStore); const hasStore = useStoreStore((state) => state.hasStore);
@ -83,6 +87,17 @@ export default function Header(): JSX.Element {
LOCATIONS_TO_RETURN.some((path) => location.pathname.includes(path)) && LOCATIONS_TO_RETURN.some((path) => location.pathname.includes(path)) &&
visitedFlowPathBefore(); visitedFlowPathBefore();
const handleLogout = () => {
mutationLogout(undefined, {
onSuccess: () => {
logout();
},
onError: (error) => {
console.error(error);
},
});
};
return ( return (
<div className="header-arrangement"> <div className="header-arrangement">
<div className="header-start-display lg:w-[407px]"> <div className="header-start-display lg:w-[407px]">
@ -275,9 +290,7 @@ export default function Header(): JSX.Element {
<DropdownMenuSeparator /> <DropdownMenuSeparator />
<DropdownMenuItem <DropdownMenuItem
className="cursor-pointer gap-2" className="cursor-pointer gap-2"
onClick={() => { onClick={handleLogout}
logout();
}}
> >
<ForwardedIconComponent name="LogOut" className="w-4" /> <ForwardedIconComponent name="LogOut" className="w-4" />
Log Out Log Out

View file

@ -1,18 +1,15 @@
import { import { LANGFLOW_ACCESS_TOKEN } from "@/constants/constants";
LANGFLOW_ACCESS_TOKEN,
LANGFLOW_AUTO_LOGIN_OPTION,
} from "@/constants/constants";
import useAuthStore from "@/stores/authStore"; import useAuthStore from "@/stores/authStore";
import useFlowsManagerStore from "@/stores/flowsManagerStore"; import useFlowsManagerStore from "@/stores/flowsManagerStore";
import axios, { AxiosError, AxiosInstance, AxiosRequestConfig } from "axios"; import axios, { AxiosError, AxiosInstance, AxiosRequestConfig } from "axios";
import { useContext, useEffect } from "react"; import { useContext, useEffect } from "react";
import { Cookies } from "react-cookie"; import { Cookies } from "react-cookie";
import { renewAccessToken } from ".";
import { BuildStatus } from "../../constants/enums"; import { BuildStatus } from "../../constants/enums";
import { AuthContext } from "../../contexts/authContext"; import { AuthContext } from "../../contexts/authContext";
import useAlertStore from "../../stores/alertStore"; import useAlertStore from "../../stores/alertStore";
import useFlowStore from "../../stores/flowStore"; import useFlowStore from "../../stores/flowStore";
import { checkDuplicateRequestAndStoreRequest } from "./helpers/check-duplicate-requests"; import { checkDuplicateRequestAndStoreRequest } from "./helpers/check-duplicate-requests";
import { useLogout, useRefreshAccessToken } from "./queries/auth";
// Create a new Axios instance // Create a new Axios instance
const api: AxiosInstance = axios.create({ const api: AxiosInstance = axios.create({
@ -22,10 +19,12 @@ const api: AxiosInstance = axios.create({
function ApiInterceptor() { function ApiInterceptor() {
const autoLogin = useAuthStore((state) => state.autoLogin); const autoLogin = useAuthStore((state) => state.autoLogin);
const setErrorData = useAlertStore((state) => state.setErrorData); const setErrorData = useAlertStore((state) => state.setErrorData);
let { accessToken, logout, authenticationErrorCount } = let { accessToken, authenticationErrorCount } = useContext(AuthContext);
useContext(AuthContext);
const cookies = new Cookies(); const cookies = new Cookies();
const setSaveLoading = useFlowsManagerStore((state) => state.setSaveLoading); const setSaveLoading = useFlowsManagerStore((state) => state.setSaveLoading);
const { mutate: mutationLogout } = useLogout();
const { mutate: mutationRenewAccessToken } = useRefreshAccessToken();
const logout = useAuthStore((state) => state.logout);
useEffect(() => { useEffect(() => {
const interceptor = api.interceptors.response.use( const interceptor = api.interceptors.response.use(
@ -127,7 +126,14 @@ function ApiInterceptor() {
if (authenticationErrorCount > 3) { if (authenticationErrorCount > 3) {
authenticationErrorCount = 0; authenticationErrorCount = 0;
logout(); mutationLogout(undefined, {
onSuccess: () => {
logout();
},
onError: (error) => {
console.error(error);
},
});
return false; return false;
} }
@ -137,10 +143,17 @@ function ApiInterceptor() {
async function tryToRenewAccessToken(error: AxiosError) { async function tryToRenewAccessToken(error: AxiosError) {
try { try {
if (window.location.pathname.includes("/login")) return; if (window.location.pathname.includes("/login")) return;
await renewAccessToken(); mutationRenewAccessToken({});
} catch (error) { } catch (error) {
clearBuildVerticesState(error); clearBuildVerticesState(error);
logout(); mutationLogout(undefined, {
onSuccess: () => {
logout();
},
onError: (error) => {
console.error(error);
},
});
return Promise.reject("Authentication error"); return Promise.reject("Authentication error");
} }
} }

View file

@ -2,9 +2,9 @@ export * from "./use-delete-users";
export * from "./use-get-autologin"; export * from "./use-get-autologin";
export * from "./use-get-user"; export * from "./use-get-user";
export * from "./use-get-users-page"; export * from "./use-get-users-page";
export * from "./use-patch-logout";
export * from "./use-patch-reset-password"; export * from "./use-patch-reset-password";
export * from "./use-patch-update-user"; export * from "./use-patch-update-user";
export * from "./use-post-add-user"; export * from "./use-post-add-user";
export * from "./use-post-login-user"; export * from "./use-post-login-user";
export * from "./use-post-logout";
export * from "./use-post-refresh-access"; export * from "./use-post-refresh-access";

View file

@ -22,7 +22,7 @@ export const useLogout: useMutationFunctionType<undefined, void> = (
if (autoLogin) { if (autoLogin) {
return {}; return {};
} }
const res = await api.patch(`${getURL("LOGOUT")}`); const res = await api.post(`${getURL("LOGOUT")}`);
return res.data; return res.data;
} }

View file

@ -15,7 +15,7 @@ export const useRefreshAccessToken: useMutationFunctionType<undefined, any> = (
} }
const mutation: UseMutationResult = mutate( const mutation: UseMutationResult = mutate(
["useRefrshAccessToken"], ["useRefreshAccessToken"],
refreshAccess, refreshAccess,
options, options,
); );

View file

@ -2,19 +2,9 @@
import { LANGFLOW_ACCESS_TOKEN } from "@/constants/constants"; import { LANGFLOW_ACCESS_TOKEN } from "@/constants/constants";
import useFlowsManagerStore from "@/stores/flowsManagerStore"; import useFlowsManagerStore from "@/stores/flowsManagerStore";
import { AuthStoreType } from "@/types/zustand/auth"; import { AuthStoreType } from "@/types/zustand/auth";
import { useNavigate } from "react-router-dom";
import Cookies from "universal-cookie"; import Cookies from "universal-cookie";
import { create } from "zustand"; import { create } from "zustand";
import {
getGlobalVariables,
getLoggedUser,
requestLogout,
} from "../controllers/API";
import useAlertStore from "../stores/alertStore";
import { useFolderStore } from "../stores/foldersStore"; import { useFolderStore } from "../stores/foldersStore";
import { useGlobalVariablesStore } from "../stores/globalVariablesStore/globalVariables";
import { useStoreStore } from "../stores/storeStore";
import { Users } from "../types/api";
const cookies = new Cookies(); const cookies = new Cookies();