Skip to content
Open
Show file tree
Hide file tree
Changes from 3 commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
22 changes: 17 additions & 5 deletions src/components/floweditor/FlowEditor.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,6 @@ import { DialogBox } from 'components/UI/DialogBox/DialogBox';
import { setErrorMessage, setNotification } from 'common/notification';
import { PUBLISH_FLOW, RESET_FLOW_COUNT } from 'graphql/mutations/Flow';
import { EXPORT_FLOW, GET_FLOW_DETAILS, GET_FREE_FLOW } from 'graphql/queries/Flow';
import { setAuthHeaders } from 'services/AuthService';
import { Loading } from 'components/UI/Layout/Loading/Loading';
import Track from 'services/TrackService';
import { exportFlowMethod } from 'common/utils';
Expand Down Expand Up @@ -237,7 +236,6 @@ export const FlowEditor = () => {

useEffect(() => {
if (flowId) {
const { fetch, xmlSend, xmlOpen } = setAuthHeaders();
const files = loadfiles(() => {
getFreeFlow({ variables: { id: flowId } });
});
Expand All @@ -263,14 +261,28 @@ export const FlowEditor = () => {
clearTimeout(timeoutId);
}
window.removeEventListener('focus', onfocus);
XMLHttpRequest.prototype.send = xmlSend;
XMLHttpRequest.prototype.open = xmlOpen;
window.fetch = fetch;
};
}
return () => {};
}, [flowId]);

useEffect(() => {
if (flowId) {
// health check to ensure the session is active
const pollFlowConnection = () => {
getFreeFlow({ variables: { id: flowId } });
Copy link
Contributor

@kurund kurund Oct 13, 2025

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Not sure about using getFreeFlow for polling here again? Maybe we can just add polling to the initial query and remove manual polling. Let's discuss.

};

// setting the polling interval to 15 minutes
const POLLING_INTERVAL = 15 * 60 * 1000;
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This should be moved to constants.ts

const pollingInterval = setInterval(pollFlowConnection, POLLING_INTERVAL);

return () => {
clearInterval(pollingInterval);
};
}
}, [flowId, getFreeFlow]);

const handlePublishFlow = () => {
publishFlow({ variables: { uuid: params.uuid } });
};
Expand Down
107 changes: 5 additions & 102 deletions src/services/AuthService.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -78,12 +78,14 @@ export const checkAuthStatusService = () => {
authStatus = false;
} else {
const tokenExpiryTime = new Date(tokenExpiryTimeFromSession);
// compare the session token with the current time
if (tokenExpiryTime > new Date()) {
// Create a buffer time of 1 minute before actual expiry
const bufferTime = new Date(tokenExpiryTime.getTime() - 60000);

if (bufferTime > new Date()) {
// token is still valid return true
authStatus = true;
} else {
// this means token has expired and let's return false
// this means token will expire in 1 minute or less, let's return false to trigger renewal
authStatus = false;
}
}
Expand Down Expand Up @@ -190,105 +192,6 @@ export const getOrganizationServices = (service: ServiceType) => {
return services[service];
};

export const setAuthHeaders = () => {
// add authorization header in all calls
let renewTokenCalled = false;
let renewCallInProgress = false;

const { fetch } = window;
window.fetch = (...args) =>
(async (parameters) => {
const parametersCopy = parameters;
if (checkAuthStatusService()) {
if (parametersCopy[1]) {
parametersCopy[1].headers = {
...parametersCopy[1].headers,
authorization: getAuthSession('access_token'),
};
}
// @ts-ignore
const result = await fetch(...parametersCopy);
return result;
}
renewTokenCalled = true;
const authToken = await renewAuthToken();
if (authToken.data) {
// update localstore
setAuthSession(authToken.data.data);
renewTokenCalled = false;
}
if (parametersCopy[1]) {
parametersCopy[1].headers = {
...parametersCopy[1].headers,
authorization: getAuthSession('access_token'),
};
}
// @ts-ignore
const result = await fetch(...parametersCopy);
return result;
})(args);

const xmlSend = XMLHttpRequest.prototype.send;
const xmlOpen = XMLHttpRequest.prototype.open;

((open) => {
// @ts-ignore
XMLHttpRequest.prototype.open = function authOpen(
method: string,
url: string | URL,
async: boolean,
username?: string | null,
password?: string | null
) {
if (url.toString().endsWith('renew')) {
// @ts-ignore
this.renewGlificCall = true;
}
open.call(this, method, url, async, username, password);
};
})(XMLHttpRequest.prototype.open);

((send) => {
XMLHttpRequest.prototype.send = async function authCheck(body) {
this.addEventListener('loadend', () => {
// @ts-ignore
if (this.renewGlificCall) {
renewCallInProgress = false;
} else if (this.status === 401) {
window.location.href = '/logout/user';
}
});

// @ts-ignore
if (this.renewGlificCall && !renewCallInProgress) {
renewCallInProgress = true;
send.call(this, body);
}
// @ts-ignore
else if (this.renewGlificCall) {
this.abort();
}
// @ts-ignore
else if (checkAuthStatusService()) {
this.setRequestHeader('authorization', getAuthSession('access_token'));
send.call(this, body);
} else if (!renewTokenCalled) {
renewTokenCalled = true;
const authToken = await renewAuthToken();
if (authToken.data) {
// update localstore
setAuthSession(authToken.data.data);
renewTokenCalled = false;
}
this.setRequestHeader('authorization', getAuthSession('access_token'));
send.call(this, body);
}
};
})(XMLHttpRequest.prototype.send);

return { xmlSend, fetch, xmlOpen };
};

export const checkOrgStatus = (status: any) => {
if (status === 'suspended') {
setErrorMessage(
Expand Down
Loading