Skip to content

Commit

Permalink
Merge pull request #1082 from frontegg/FR-14220-step-up-hoc
Browse files Browse the repository at this point in the history
FR-14220 - Added SteppedUpContent HOC
  • Loading branch information
doregg authored Dec 31, 2023
2 parents 0ff9f28 + 7a63805 commit 58eecd8
Show file tree
Hide file tree
Showing 4 changed files with 58 additions and 2 deletions.
1 change: 1 addition & 0 deletions packages/react/rollup.config.js
Original file line number Diff line number Diff line change
Expand Up @@ -53,6 +53,7 @@ const isExternal = (id) => {
id !== './FronteggProvider' &&
id !== './AlwaysRenderInProvider' &&
id !== './AuthorizedContent' &&
id !== './SteppedUpContent' &&
id !== './sdkVersion' &&
id !== './routerProxy' &&
id !== './queryKeeper' &&
Expand Down
4 changes: 2 additions & 2 deletions packages/react/src/FronteggProvider.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@ import { FronteggStoreProvider } from '@frontegg/react-hooks';
import { BrowserRouter, useHistory, UseHistory } from './routerProxy';
import { ContextHolder, RedirectOptions, FronteggFrameworks } from '@frontegg/rest-api';
import { AppHolder } from '@frontegg/js/AppHolder';
import { isAuthRoute, AuthPageRoutes } from '@frontegg/redux-store';
import { isAuthRoute, AuthPageRoutes, defaultFronteggRoutes } from '@frontegg/redux-store';
import sdkVersion from './sdkVersion';
import ReactPkg from 'react/package.json';
import { AlwaysRenderInProvider, HistoryObject } from './AlwaysRenderInProvider';
Expand All @@ -32,7 +32,7 @@ export const ConnectorHistory: FC<Omit<ConnectorProps, 'history'>> = (props) =>
* @returns true when should bypass react router
*/
function isBypassReactRoute(path: string, routes?: Partial<AuthPageRoutes>) {
const stepUpUrl = routes?.stepUpUrl;
const stepUpUrl = routes?.stepUpUrl || defaultFronteggRoutes.stepUpUrl;
return stepUpUrl && path.startsWith(stepUpUrl);
}

Expand Down
54 changes: 54 additions & 0 deletions packages/react/src/SteppedUpContent.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,54 @@
import React, { ReactNode, useEffect, useRef } from 'react';

import { useStepUp, useIsSteppedUp, useIsAuthenticated } from '@frontegg/react-hooks';

export interface SteppedUpProps {
maxAge?: number;
preventSteppingUp?: boolean;
render?: (isSteppedUp: boolean) => React.ReactNode | null;
children?: ReactNode;
}

/**
* Stepped up content component that shows the wrapped content only when the user is stepped up
* The component triggers the step up flow if the user is not stepped up
* @param props.maxAge maximum time in second that the login is valid
* @param props.preventSteppingUp true when the step up flow should not be triggered automatically when the user is not stepped up, default to false
* @param props.render render function to be called when user is stepped up
* @param props.children to be shown when user is stepped up (only if render not provided)
*
* Pay attention, when shouldTriggerStepUp is true, two instances of SteppedUpContent can be rendered in the same page on the same render cycle.
*/
export const SteppedUpContent: React.FC<SteppedUpProps> = (props) => {
const isAuthenticated = useIsAuthenticated();
if (!isAuthenticated) return null;

return <SteppedUpContentInternal {...props} />;
};

const SteppedUpContentInternal: React.FC<SteppedUpProps> = ({ maxAge, preventSteppingUp, render, children }) => {
const isSteppedUp = useIsSteppedUp({ maxAge });
const stepUp = useStepUp();
const isStepUpCalled = useRef(false);

useEffect(() => {
if (isSteppedUp) {
isStepUpCalled.current = false;
return;
}

if (isStepUpCalled.current) return;

if (!preventSteppingUp) {
stepUp({ maxAge });
}

isStepUpCalled.current = true;
}, [isSteppedUp, maxAge, preventSteppingUp, stepUp]);

if (typeof render === 'function') {
return <>{render(isSteppedUp)}</>;
}

return isSteppedUp ? <>{children}</> : null;
};
1 change: 1 addition & 0 deletions packages/react/src/index.ts
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
export * from './FronteggProvider';
export * from './AuthorizedContent';
export * from './CheckoutDialog';
export * from './SteppedUpContent';

export { AdminPortal, CheckoutDialog, HostedLogin } from '@frontegg/js';
export * from '@frontegg/react-hooks';
Expand Down

0 comments on commit 58eecd8

Please sign in to comment.