🐛 fix(authContext.tsx): initialize accessToken and refreshToken with values from cookies to maintain user session

 feat(authContext.tsx): add support for process.env.PORT environment variable to be able to run app on a configurable port
🐛 fix(tabsContext.tsx): import missing AuthContext and use getAuthentication function to conditionally fetch data
🐛 fix(typesContext.tsx): import missing AuthContext and use getAuthentication function to conditionally fetch data
🐛 fix(api.tsx): add check to not refresh token if refreshToken is "auto"
This commit is contained in:
Cristhian Zanforlin Lousa 2023-08-25 19:08:38 -03:00
commit 89d69af7f8
4 changed files with 61 additions and 58 deletions

View file

@ -24,13 +24,13 @@ const initialValue: AuthContextType = {
export const AuthContext = createContext<AuthContextType>(initialValue);
export function AuthProvider({ children }): React.ReactElement {
const [accessToken, setAccessToken] = useState<string | null>(null);
const [refreshToken, setRefreshToken] = useState<string | null>(null);
const cookies = new Cookies();
const [accessToken, setAccessToken] = useState<string | null>(cookies.get("access_token"));
const [refreshToken, setRefreshToken] = useState<string | null>(cookies.get("refresh_token"));
const [isAuthenticated, setIsAuthenticated] = useState<boolean>(false);
const [isAdmin, setIsAdmin] = useState<boolean>(false);
const [userData, setUserData] = useState<Users | null>(null);
const [autoLogin, setAutoLogin] = useState<boolean>(false);
const cookies = new Cookies();
useEffect(() => {
const storedAccessToken = cookies.get("access_token");

View file

@ -1,3 +1,4 @@
import { AxiosError } from "axios";
import _ from "lodash";
import {
ReactNode,
@ -21,7 +22,7 @@ import {
import { APIClassType, APITemplateType } from "../types/api";
import { tweakType } from "../types/components";
import { FlowType, NodeDataType, NodeType } from "../types/flow";
import { TabsContextType, TabsState, errorsVarType } from "../types/tabs";
import { TabsContextType, TabsState } from "../types/tabs";
import {
addVersionToDuplicates,
updateIds,
@ -29,8 +30,8 @@ import {
} from "../utils/reactflowUtils";
import { getRandomDescription, getRandomName } from "../utils/utils";
import { alertContext } from "./alertContext";
import { AuthContext } from "./authContext";
import { typesContext } from "./typesContext";
import { AxiosError } from "axios";
const uid = new ShortUniqueId({ length: 5 });
@ -69,7 +70,9 @@ export const TabsContext = createContext<TabsContextType>(
);
export function TabsProvider({ children }: { children: ReactNode }) {
const { setErrorData, setNoticeData, setSuccessData } = useContext(alertContext);
const { setErrorData, setNoticeData, setSuccessData } =
useContext(alertContext);
const { getAuthentication } = useContext(AuthContext);
const [tabId, setTabId] = useState("");
@ -113,7 +116,6 @@ export function TabsProvider({ children }: { children: ReactNode }) {
}
function refreshFlows() {
setTimeout(() => {
getTabsDataFromDB().then((DbData) => {
if (DbData && Object.keys(templates).length > 0) {
try {
@ -124,20 +126,22 @@ export function TabsProvider({ children }: { children: ReactNode }) {
}
}
});
}, 2000);
}
useEffect(() => {
// get data from db
//get tabs locally saved
// let tabsData = getLocalStorageTabsData();
refreshFlows();
}, [templates]);
if (getAuthentication() === true) {
// get data from db
//get tabs locally saved
// let tabsData = getLocalStorageTabsData();
refreshFlows();
}
}, [templates, getAuthentication()]);
function getTabsDataFromDB() {
//get tabs from db
return readFlowsFromDatabase();
}
function processDBData(DbData: FlowType[]) {
DbData.forEach((flow: FlowType) => {
try {
@ -605,7 +609,10 @@ export function TabsProvider({ children }: { children: ReactNode }) {
});
}
} catch (err) {
setErrorData({title: "Error while saving changes",list:[(err as AxiosError).message]});
setErrorData({
title: "Error while saving changes",
list: [(err as AxiosError).message],
});
}
}

View file

@ -10,6 +10,7 @@ import { getAll, getHealth } from "../controllers/API";
import { APIKindType } from "../types/api";
import { typesContextType } from "../types/typesContext";
import { alertContext } from "./alertContext";
import { AuthContext } from "./authContext";
//context to share types adn functions from nodes to flow
@ -37,60 +38,55 @@ export function TypesProvider({ children }: { children: ReactNode }) {
const [data, setData] = useState({});
const [fetchError, setFetchError] = useState(false);
const { setLoading } = useContext(alertContext);
const { getAuthentication } = useContext(AuthContext);
useEffect(() => {
if (getAuthentication() === true) {
getTypes();
}
}, [getAuthentication()]);
setTimeout(() => {
async function getTypes(): Promise<void> {
// We will keep a flag to handle the case where the component is unmounted before the API call resolves.
let isMounted = true;
async function getTypes(): Promise<void> {
try {
const result = await getAll();
// Make sure to only update the state if the component is still mounted.
if (isMounted && result?.status === 200) {
setLoading(false);
setData(result.data);
setTemplates(
Object.keys(result.data).reduce((acc, curr) => {
try {
const result = await getAll();
// Make sure to only update the state if the component is still mounted.
if (isMounted && result?.status === 200) {
setLoading(false);
setData(result.data);
setTemplates(
Object.keys(result.data).reduce((acc, curr) => {
Object.keys(result.data[curr]).forEach((c: keyof APIKindType) => {
acc[c] = result.data[curr][c];
});
return acc;
}, {})
);
// Set the types by reducing over the keys of the result data and updating the accumulator.
setTypes(
// Reverse the keys so the tool world does not overlap
Object.keys(result.data)
.reverse()
.reduce((acc, curr) => {
Object.keys(result.data[curr]).forEach((c: keyof APIKindType) => {
acc[c] = result.data[curr][c];
acc[c] = curr;
// Add the base classes to the accumulator as well.
result.data[curr][c].base_classes?.forEach((b) => {
acc[b] = curr;
});
});
return acc;
}, {})
);
// Set the types by reducing over the keys of the result data and updating the accumulator.
setTypes(
// Reverse the keys so the tool world does not overlap
Object.keys(result.data)
.reverse()
.reduce((acc, curr) => {
Object.keys(result.data[curr]).forEach(
(c: keyof APIKindType) => {
acc[c] = curr;
// Add the base classes to the accumulator as well.
result.data[curr][c].base_classes?.forEach((b) => {
acc[b] = curr;
});
}
);
return acc;
}, {})
);
}
} catch (error) {
console.error("An error has occurred while fetching types.");
await getHealth().catch((e) => {
setFetchError(true);
});
);
}
} catch (error) {
console.error("An error has occurred while fetching types.");
await getHealth().catch((e) => {
setFetchError(true);
});
}
getTypes();
}, 2000);
}, []);
}
function deleteNode(idx: string) {
reactFlowInstance!.setNodes(

View file

@ -24,7 +24,7 @@ function ApiInterceptor() {
async (error: AxiosError) => {
if (error.response?.status === 401) {
const refreshToken = cookies.get("refresh_token");
if (refreshToken) {
if (refreshToken && refreshToken !== "auto") {
authenticationErrorCount = authenticationErrorCount + 1;
if (authenticationErrorCount > 3) {
authenticationErrorCount = 0;