fix: auto login and logout functionality (#3629)
* Made auto login not call refresh * Fixed mutation query * Removed navigation to login on logout function * Made refresh token set cookie for docker * Added return to login with custom navigate and added check for refreshing only if its authenticated * Minor refactor * Navigate after logout on get autologin * Removed unused console.log
This commit is contained in:
parent
3bef9aa633
commit
a71375c6f9
7 changed files with 49 additions and 61 deletions
|
|
@ -1,24 +1,16 @@
|
||||||
import {
|
import {
|
||||||
LANGFLOW_ACCESS_TOKEN_EXPIRE_SECONDS,
|
LANGFLOW_ACCESS_TOKEN_EXPIRE_SECONDS,
|
||||||
LANGFLOW_ACCESS_TOKEN_EXPIRE_SECONDS_ENV,
|
LANGFLOW_ACCESS_TOKEN_EXPIRE_SECONDS_ENV,
|
||||||
LANGFLOW_AUTO_LOGIN_OPTION,
|
|
||||||
} from "@/constants/constants";
|
} from "@/constants/constants";
|
||||||
import {
|
import { useRefreshAccessToken } from "@/controllers/API/queries/auth";
|
||||||
useLogout,
|
import { CustomNavigate } from "@/customization/components/custom-navigate";
|
||||||
useRefreshAccessToken,
|
|
||||||
} from "@/controllers/API/queries/auth";
|
|
||||||
import useAuthStore from "@/stores/authStore";
|
import useAuthStore from "@/stores/authStore";
|
||||||
import { useEffect } from "react";
|
import { useEffect } from "react";
|
||||||
import { Cookies } from "react-cookie";
|
|
||||||
|
|
||||||
export const ProtectedRoute = ({ children }) => {
|
export const ProtectedRoute = ({ children }) => {
|
||||||
const isAuthenticated = useAuthStore((state) => state.isAuthenticated);
|
const isAuthenticated = useAuthStore((state) => state.isAuthenticated);
|
||||||
const hasToken = !!localStorage.getItem(LANGFLOW_AUTO_LOGIN_OPTION);
|
|
||||||
|
|
||||||
const cookies = new Cookies();
|
|
||||||
const refreshToken = cookies.get("refresh_token");
|
|
||||||
const { mutate: mutateRefresh } = useRefreshAccessToken();
|
const { mutate: mutateRefresh } = useRefreshAccessToken();
|
||||||
const { mutate: mutationLogout } = useLogout();
|
const autoLogin = useAuthStore((state) => state.autoLogin);
|
||||||
|
|
||||||
useEffect(() => {
|
useEffect(() => {
|
||||||
const envRefreshTime = LANGFLOW_ACCESS_TOKEN_EXPIRE_SECONDS_ENV;
|
const envRefreshTime = LANGFLOW_ACCESS_TOKEN_EXPIRE_SECONDS_ENV;
|
||||||
|
|
@ -29,19 +21,17 @@ export const ProtectedRoute = ({ children }) => {
|
||||||
: envRefreshTime;
|
: envRefreshTime;
|
||||||
|
|
||||||
const intervalFunction = () => {
|
const intervalFunction = () => {
|
||||||
if (isAuthenticated) {
|
mutateRefresh();
|
||||||
mutateRefresh({ refresh_token: refreshToken });
|
|
||||||
}
|
|
||||||
};
|
};
|
||||||
|
|
||||||
const intervalId = setInterval(intervalFunction, accessTokenTimer * 1000);
|
if (!autoLogin && isAuthenticated) {
|
||||||
intervalFunction();
|
const intervalId = setInterval(intervalFunction, accessTokenTimer * 1000);
|
||||||
|
intervalFunction();
|
||||||
return () => clearInterval(intervalId);
|
return () => clearInterval(intervalId);
|
||||||
|
}
|
||||||
}, [isAuthenticated]);
|
}, [isAuthenticated]);
|
||||||
|
if (!isAuthenticated && !autoLogin) {
|
||||||
if (!isAuthenticated && hasToken) {
|
return <CustomNavigate to="/login" replace />;
|
||||||
mutationLogout();
|
|
||||||
} else {
|
} else {
|
||||||
return children;
|
return children;
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -145,21 +145,18 @@ function ApiInterceptor() {
|
||||||
error.config.headers[key] = value;
|
error.config.headers[key] = value;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
mutationRenewAccessToken(
|
mutationRenewAccessToken(undefined, {
|
||||||
{},
|
onSuccess: async () => {
|
||||||
{
|
authenticationErrorCount = 0;
|
||||||
onSuccess: async (data) => {
|
await remakeRequest(error);
|
||||||
authenticationErrorCount = 0;
|
authenticationErrorCount = 0;
|
||||||
await remakeRequest(error);
|
|
||||||
authenticationErrorCount = 0;
|
|
||||||
},
|
|
||||||
onError: (error) => {
|
|
||||||
console.error(error);
|
|
||||||
mutationLogout();
|
|
||||||
return Promise.reject("Authentication error");
|
|
||||||
},
|
|
||||||
},
|
},
|
||||||
);
|
onError: (error) => {
|
||||||
|
console.error(error);
|
||||||
|
mutationLogout();
|
||||||
|
return Promise.reject("Authentication error");
|
||||||
|
},
|
||||||
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
async function clearBuildVerticesState(error) {
|
async function clearBuildVerticesState(error) {
|
||||||
|
|
|
||||||
|
|
@ -1,4 +1,5 @@
|
||||||
import { AuthContext } from "@/contexts/authContext";
|
import { AuthContext } from "@/contexts/authContext";
|
||||||
|
import { useCustomNavigate } from "@/customization/hooks/use-custom-navigate";
|
||||||
import useAuthStore from "@/stores/authStore";
|
import useAuthStore from "@/stores/authStore";
|
||||||
import { AxiosError } from "axios";
|
import { AxiosError } from "axios";
|
||||||
import { useContext } from "react";
|
import { useContext } from "react";
|
||||||
|
|
@ -23,7 +24,8 @@ export const useGetAutoLogin: useQueryFunctionType<undefined, undefined> = (
|
||||||
const setAutoLogin = useAuthStore((state) => state.setAutoLogin);
|
const setAutoLogin = useAuthStore((state) => state.setAutoLogin);
|
||||||
const isAuthenticated = useAuthStore((state) => state.isAuthenticated);
|
const isAuthenticated = useAuthStore((state) => state.isAuthenticated);
|
||||||
const isLoginPage = location.pathname.includes("login");
|
const isLoginPage = location.pathname.includes("login");
|
||||||
const { mutate: mutationLogout } = useLogout();
|
const navigate = useCustomNavigate();
|
||||||
|
const { mutateAsync: mutationLogout } = useLogout();
|
||||||
|
|
||||||
async function getAutoLoginFn(): Promise<null> {
|
async function getAutoLoginFn(): Promise<null> {
|
||||||
try {
|
try {
|
||||||
|
|
@ -41,8 +43,8 @@ export const useGetAutoLogin: useQueryFunctionType<undefined, undefined> = (
|
||||||
setAutoLogin(false);
|
setAutoLogin(false);
|
||||||
if (!isLoginPage) {
|
if (!isLoginPage) {
|
||||||
if (!isAuthenticated) {
|
if (!isAuthenticated) {
|
||||||
mutationLogout();
|
await mutationLogout();
|
||||||
throw new Error("Unauthorized");
|
navigate("/login");
|
||||||
} else {
|
} else {
|
||||||
getUser();
|
getUser();
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -1,9 +1,5 @@
|
||||||
import { keepPreviousData, UseMutationResult } from "@tanstack/react-query";
|
import { UseMutationResult } from "@tanstack/react-query";
|
||||||
import {
|
import { useMutationFunctionType, Users } from "../../../../types/api";
|
||||||
useMutationFunctionType,
|
|
||||||
useQueryFunctionType,
|
|
||||||
Users,
|
|
||||||
} from "../../../../types/api";
|
|
||||||
import { api } from "../../api";
|
import { api } from "../../api";
|
||||||
import { getURL } from "../../helpers/constants";
|
import { getURL } from "../../helpers/constants";
|
||||||
import { UseRequestProcessor } from "../../services/request-processor";
|
import { UseRequestProcessor } from "../../services/request-processor";
|
||||||
|
|
@ -35,7 +31,7 @@ export const useGetUsers: useMutationFunctionType<any, getUsersQueryParams> = (
|
||||||
getUsersQueryParams,
|
getUsersQueryParams,
|
||||||
any,
|
any,
|
||||||
getUsersQueryParams
|
getUsersQueryParams
|
||||||
> = mutate(["useRefreshAccessToken"], getUsers, options);
|
> = mutate(["useGetUsers"], getUsers, options);
|
||||||
|
|
||||||
return mutation;
|
return mutation;
|
||||||
};
|
};
|
||||||
|
|
|
||||||
|
|
@ -1,7 +1,6 @@
|
||||||
import useAuthStore from "@/stores/authStore";
|
import useAuthStore from "@/stores/authStore";
|
||||||
import { useMutationFunctionType } from "@/types/api";
|
import { useMutationFunctionType } from "@/types/api";
|
||||||
|
|
||||||
import { useCustomNavigate } from "@/customization/hooks/use-custom-navigate";
|
|
||||||
import { api } from "../../api";
|
import { api } from "../../api";
|
||||||
import { getURL } from "../../helpers/constants";
|
import { getURL } from "../../helpers/constants";
|
||||||
import { UseRequestProcessor } from "../../services/request-processor";
|
import { UseRequestProcessor } from "../../services/request-processor";
|
||||||
|
|
@ -10,7 +9,6 @@ export const useLogout: useMutationFunctionType<undefined, void> = (
|
||||||
options?,
|
options?,
|
||||||
) => {
|
) => {
|
||||||
const { mutate } = UseRequestProcessor();
|
const { mutate } = UseRequestProcessor();
|
||||||
const navigate = useCustomNavigate();
|
|
||||||
const logout = useAuthStore((state) => state.logout);
|
const logout = useAuthStore((state) => state.logout);
|
||||||
|
|
||||||
async function logoutUser(): Promise<any> {
|
async function logoutUser(): Promise<any> {
|
||||||
|
|
@ -25,7 +23,6 @@ export const useLogout: useMutationFunctionType<undefined, void> = (
|
||||||
const mutation = mutate(["useLogout"], logoutUser, {
|
const mutation = mutate(["useLogout"], logoutUser, {
|
||||||
onSuccess: () => {
|
onSuccess: () => {
|
||||||
logout();
|
logout();
|
||||||
navigate("/login");
|
|
||||||
},
|
},
|
||||||
onError: (error) => {
|
onError: (error) => {
|
||||||
console.error(error);
|
console.error(error);
|
||||||
|
|
|
||||||
|
|
@ -1,24 +1,31 @@
|
||||||
import { LoginType, changeUser, useMutationFunctionType } from "@/types/api";
|
import { LANGFLOW_REFRESH_TOKEN } from "@/constants/constants";
|
||||||
import { UseMutationResult } from "@tanstack/react-query";
|
import { useMutationFunctionType } from "@/types/api";
|
||||||
|
import { Cookies } from "react-cookie";
|
||||||
import { api } from "../../api";
|
import { api } from "../../api";
|
||||||
import { getURL } from "../../helpers/constants";
|
import { getURL } from "../../helpers/constants";
|
||||||
import { UseRequestProcessor } from "../../services/request-processor";
|
import { UseRequestProcessor } from "../../services/request-processor";
|
||||||
|
interface IRefreshAccessToken {
|
||||||
|
access_token: string;
|
||||||
|
refresh_token: string;
|
||||||
|
token_type: string;
|
||||||
|
}
|
||||||
|
|
||||||
export const useRefreshAccessToken: useMutationFunctionType<undefined, any> = (
|
export const useRefreshAccessToken: useMutationFunctionType<
|
||||||
options?,
|
undefined,
|
||||||
) => {
|
undefined | void,
|
||||||
|
IRefreshAccessToken
|
||||||
|
> = (options?) => {
|
||||||
const { mutate } = UseRequestProcessor();
|
const { mutate } = UseRequestProcessor();
|
||||||
|
const cookies = new Cookies();
|
||||||
|
|
||||||
|
async function refreshAccess(): Promise<IRefreshAccessToken> {
|
||||||
|
const res = await api.post<IRefreshAccessToken>(`${getURL("REFRESH")}`);
|
||||||
|
cookies.set(LANGFLOW_REFRESH_TOKEN, res.data.refresh_token, { path: "/" });
|
||||||
|
|
||||||
async function refreshAccess(): Promise<any> {
|
|
||||||
const res = await api.post(`${getURL("REFRESH")}`);
|
|
||||||
return res.data;
|
return res.data;
|
||||||
}
|
}
|
||||||
|
|
||||||
const mutation: UseMutationResult = mutate(
|
const mutation = mutate(["useRefreshAccessToken"], refreshAccess, options);
|
||||||
["useRefreshAccessToken"],
|
|
||||||
refreshAccess,
|
|
||||||
options,
|
|
||||||
);
|
|
||||||
|
|
||||||
return mutation;
|
return mutation;
|
||||||
};
|
};
|
||||||
|
|
|
||||||
|
|
@ -42,7 +42,6 @@ export default function UserManagementModal({
|
||||||
}: inputHandlerEventType): void {
|
}: inputHandlerEventType): void {
|
||||||
setInputState((prev) => ({ ...prev, [name]: value }));
|
setInputState((prev) => ({ ...prev, [name]: value }));
|
||||||
}
|
}
|
||||||
console.log(data);
|
|
||||||
|
|
||||||
useEffect(() => {
|
useEffect(() => {
|
||||||
if (open) {
|
if (open) {
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue