mirror of
https://github.com/open-metadata/OpenMetadata.git
synced 2025-10-16 11:18:33 +00:00
fix(ui): silent-callback redirect issue fix (#7297)
* fix(ui): silent-callback redirect issue fix * address comments
This commit is contained in:
parent
422f59d9e6
commit
1a9a67b087
@ -17,7 +17,6 @@ import { MsalProvider } from '@azure/msal-react';
|
|||||||
import { LoginCallback } from '@okta/okta-react';
|
import { LoginCallback } from '@okta/okta-react';
|
||||||
import { AxiosError } from 'axios';
|
import { AxiosError } from 'axios';
|
||||||
import { CookieStorage } from 'cookie-storage';
|
import { CookieStorage } from 'cookie-storage';
|
||||||
import jwtDecode, { JwtPayload } from 'jwt-decode';
|
|
||||||
import { isEmpty, isNil } from 'lodash';
|
import { isEmpty, isNil } from 'lodash';
|
||||||
import { observer } from 'mobx-react';
|
import { observer } from 'mobx-react';
|
||||||
import React, {
|
import React, {
|
||||||
@ -51,6 +50,7 @@ import { AuthTypes } from '../../enums/signin.enum';
|
|||||||
import { User } from '../../generated/entity/teams/user';
|
import { User } from '../../generated/entity/teams/user';
|
||||||
import jsonData from '../../jsons/en';
|
import jsonData from '../../jsons/en';
|
||||||
import {
|
import {
|
||||||
|
extractDetailsFromToken,
|
||||||
getAuthConfig,
|
getAuthConfig,
|
||||||
getNameFromEmail,
|
getNameFromEmail,
|
||||||
getUrlPathnameExpiry,
|
getUrlPathnameExpiry,
|
||||||
@ -109,10 +109,11 @@ export const AuthProvider = ({
|
|||||||
authenticatorRef.current?.invokeLogin();
|
authenticatorRef.current?.invokeLogin();
|
||||||
};
|
};
|
||||||
|
|
||||||
const onLogoutHandler = () => {
|
const onLogoutHandler = useCallback(() => {
|
||||||
|
clearTimeout(timeoutId);
|
||||||
authenticatorRef.current?.invokeLogout();
|
authenticatorRef.current?.invokeLogout();
|
||||||
setLoading(false);
|
setLoading(false);
|
||||||
};
|
}, [timeoutId]);
|
||||||
|
|
||||||
const onRenewIdTokenHandler = () => {
|
const onRenewIdTokenHandler = () => {
|
||||||
return authenticatorRef.current?.renewIdToken();
|
return authenticatorRef.current?.renewIdToken();
|
||||||
@ -292,31 +293,21 @@ export const AuthProvider = ({
|
|||||||
* This method will be call upon successful signIn
|
* This method will be call upon successful signIn
|
||||||
*/
|
*/
|
||||||
const startTokenExpiryTimer = () => {
|
const startTokenExpiryTimer = () => {
|
||||||
const token: string | void = localStorage.getItem(oidcTokenKey) || '';
|
// Extract expiry
|
||||||
// If token is not present do nothing
|
const { exp, isExpired, diff, timeoutExpiry } = extractDetailsFromToken();
|
||||||
if (token) {
|
|
||||||
try {
|
|
||||||
// Extract expiry
|
|
||||||
const { exp } = jwtDecode<JwtPayload>(token);
|
|
||||||
if (exp && exp * 1000 > Date.now()) {
|
|
||||||
// Check if token isn't expired yet
|
|
||||||
const diff = exp * 1000 - Date.now(); /* Convert to MS */
|
|
||||||
|
|
||||||
// Have 50s buffer before start trying for silent signIn
|
if (!isExpired && exp && diff && timeoutExpiry) {
|
||||||
// If token is about to expire then start silentSignIn
|
// Have 2m buffer before start trying for silent signIn
|
||||||
// else just set timer to try for silentSignIn before token expires
|
// If token is about to expire then start silentSignIn
|
||||||
if (diff > 50000) {
|
// else just set timer to try for silentSignIn before token expires
|
||||||
const timerId = setTimeout(() => {
|
if (diff > 120000) {
|
||||||
trySilentSignIn();
|
clearTimeout(timeoutId);
|
||||||
}, diff);
|
const timerId = setTimeout(() => {
|
||||||
setTimeoutId(Number(timerId));
|
trySilentSignIn();
|
||||||
} else {
|
}, timeoutExpiry);
|
||||||
trySilentSignIn();
|
setTimeoutId(Number(timerId));
|
||||||
}
|
} else {
|
||||||
}
|
trySilentSignIn();
|
||||||
} catch (error) {
|
|
||||||
// eslint-disable-next-line no-console
|
|
||||||
console.error('Error parsing id token.', error);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
@ -21,7 +21,8 @@ export const useAuth = (pathname = '') => {
|
|||||||
const isAuthenticatedRoute =
|
const isAuthenticatedRoute =
|
||||||
pathname !== ROUTES.SIGNUP &&
|
pathname !== ROUTES.SIGNUP &&
|
||||||
pathname !== ROUTES.SIGNIN &&
|
pathname !== ROUTES.SIGNIN &&
|
||||||
pathname !== ROUTES.CALLBACK;
|
pathname !== ROUTES.CALLBACK &&
|
||||||
|
pathname !== ROUTES.SILENT_CALLBACK;
|
||||||
const isTourRoute = pathname === ROUTES.TOUR;
|
const isTourRoute = pathname === ROUTES.TOUR;
|
||||||
|
|
||||||
return {
|
return {
|
||||||
|
@ -18,15 +18,19 @@ import {
|
|||||||
PopupRequest,
|
PopupRequest,
|
||||||
PublicClientApplication,
|
PublicClientApplication,
|
||||||
} from '@azure/msal-browser';
|
} from '@azure/msal-browser';
|
||||||
|
import jwtDecode, { JwtPayload } from 'jwt-decode';
|
||||||
import { isNil } from 'lodash';
|
import { isNil } from 'lodash';
|
||||||
import { WebStorageStateStore } from 'oidc-client';
|
import { WebStorageStateStore } from 'oidc-client';
|
||||||
import { ROUTES } from '../constants/constants';
|
import { oidcTokenKey, ROUTES } from '../constants/constants';
|
||||||
import { validEmailRegEx } from '../constants/regex.constants';
|
import { validEmailRegEx } from '../constants/regex.constants';
|
||||||
import { AuthTypes } from '../enums/signin.enum';
|
import { AuthTypes } from '../enums/signin.enum';
|
||||||
import { isDev } from './EnvironmentUtils';
|
import { isDev } from './EnvironmentUtils';
|
||||||
|
|
||||||
export let msalInstance: IPublicClientApplication;
|
export let msalInstance: IPublicClientApplication;
|
||||||
|
|
||||||
|
const DATE_NOW = Date.now();
|
||||||
|
const EXPIRY_THRESHOLD_MILLES = 2 * 60 * 100;
|
||||||
|
|
||||||
export const getOidcExpiry = () => {
|
export const getOidcExpiry = () => {
|
||||||
return new Date(Date.now() + 60 * 60 * 24 * 1000);
|
return new Date(Date.now() + 60 * 60 * 24 * 1000);
|
||||||
};
|
};
|
||||||
@ -184,7 +188,8 @@ export const isProtectedRoute = (pathname: string) => {
|
|||||||
return (
|
return (
|
||||||
pathname !== ROUTES.SIGNUP &&
|
pathname !== ROUTES.SIGNUP &&
|
||||||
pathname !== ROUTES.SIGNIN &&
|
pathname !== ROUTES.SIGNIN &&
|
||||||
pathname !== ROUTES.CALLBACK
|
pathname !== ROUTES.CALLBACK &&
|
||||||
|
pathname !== ROUTES.SILENT_CALLBACK
|
||||||
);
|
);
|
||||||
};
|
};
|
||||||
|
|
||||||
@ -195,3 +200,38 @@ export const isTourRoute = (pathname: string) => {
|
|||||||
export const getUrlPathnameExpiry = () => {
|
export const getUrlPathnameExpiry = () => {
|
||||||
return new Date(Date.now() + 60 * 60 * 1000);
|
return new Date(Date.now() + 60 * 60 * 1000);
|
||||||
};
|
};
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @exp expiry of token
|
||||||
|
* @isExpired wether token is already expired or not
|
||||||
|
* @diff Difference between token expiry & current time in ms
|
||||||
|
* @timeoutExpiry time in ms for try to silent sign-in
|
||||||
|
* @returns exp, isExpired, diff, timeoutExpiry
|
||||||
|
*/
|
||||||
|
export const extractDetailsFromToken = () => {
|
||||||
|
const token = localStorage.getItem(oidcTokenKey) || '';
|
||||||
|
|
||||||
|
try {
|
||||||
|
const { exp } = jwtDecode<JwtPayload>(token);
|
||||||
|
|
||||||
|
const diff = exp && exp * 1000 - DATE_NOW;
|
||||||
|
const timeoutExpiry = diff && diff - EXPIRY_THRESHOLD_MILLES;
|
||||||
|
|
||||||
|
return {
|
||||||
|
exp,
|
||||||
|
isExpired: exp && DATE_NOW >= exp * 1000,
|
||||||
|
diff,
|
||||||
|
timeoutExpiry,
|
||||||
|
};
|
||||||
|
} catch (error) {
|
||||||
|
// eslint-disable-next-line no-console
|
||||||
|
console.error('Error parsing id token.', error);
|
||||||
|
}
|
||||||
|
|
||||||
|
return {
|
||||||
|
exp: 0,
|
||||||
|
isExpired: true,
|
||||||
|
diff: 0,
|
||||||
|
timeoutExpiry: 0,
|
||||||
|
};
|
||||||
|
};
|
||||||
|
Loading…
x
Reference in New Issue
Block a user