From 64c76e0b1f4fccf1c0ed93269a0307212be9d661 Mon Sep 17 00:00:00 2001 From: Guillaume Chervet Date: Tue, 23 Apr 2024 03:28:06 +0200 Subject: [PATCH] feature(oidc):preload user (release) (#1352) * feature(oidc):preload user (alpha) * fix (alpha) * fix (alpha) --- examples/react-oidc-demo/src/Profile.tsx | 2 ++ examples/react-oidc-demo/src/configurations.ts | 1 + packages/oidc-client/src/keepSession.ts | 6 ++++++ packages/oidc-client/src/login.ts | 3 +++ packages/oidc-client/src/oidc.ts | 1 + packages/oidc-client/src/oidcClient.ts | 6 +++++- packages/oidc-client/src/types.ts | 1 + packages/react-oidc/src/User.ts | 17 ++++++++++++----- 8 files changed, 31 insertions(+), 6 deletions(-) diff --git a/examples/react-oidc-demo/src/Profile.tsx b/examples/react-oidc-demo/src/Profile.tsx index 4a510d6bd..1a767f3a5 100644 --- a/examples/react-oidc-demo/src/Profile.tsx +++ b/examples/react-oidc-demo/src/Profile.tsx @@ -8,6 +8,8 @@ interface OidcUserRoleInfo extends OidcUserInfo{ const DisplayUserInfo = () => { const { oidcUser, oidcUserLoadingState, reloadOidcUser } = useOidcUser(); + console.log('oidcUser', oidcUser); + console.log('oidcUserLoadingState', oidcUserLoadingState); switch (oidcUserLoadingState) { case OidcUserStatus.Loading: return

User Information are loading

; diff --git a/examples/react-oidc-demo/src/configurations.ts b/examples/react-oidc-demo/src/configurations.ts index eb1a58728..16efca83f 100644 --- a/examples/react-oidc-demo/src/configurations.ts +++ b/examples/react-oidc-demo/src/configurations.ts @@ -18,6 +18,7 @@ export const configurationIdentityServer = { token_renew_mode: TokenRenewMode.access_token_invalid, token_automatic_renew_mode: TokenAutomaticRenewMode.AutomaticOnlyWhenFetchExecuted, demonstrating_proof_of_possession: false, + preload_user_info: true }; export const configurationIdentityServer1 = { diff --git a/packages/oidc-client/src/keepSession.ts b/packages/oidc-client/src/keepSession.ts index 881f03320..e863229cd 100644 --- a/packages/oidc-client/src/keepSession.ts +++ b/packages/oidc-client/src/keepSession.ts @@ -28,6 +28,9 @@ export const tryKeepSessionAsync = async (oidc: Oidc) =>{ const sessionState = await serviceWorker.getSessionStateAsync(); // @ts-ignore await oidc.startCheckSessionAsync(oidcServerConfiguration.check_session_iframe, configuration.client_id, sessionState); + if(configuration.preload_user_info){ + await oidc.userInfoAsync(); + } oidc.publishEvent(eventNames.tryKeepExistingSessionAsync_end, { success: true, message: 'tokens inside ServiceWorker are valid', @@ -55,6 +58,9 @@ export const tryKeepSessionAsync = async (oidc: Oidc) =>{ const sessionState = await session.getSessionStateAsync(); // @ts-ignore await oidc.startCheckSessionAsync(oidcServerConfiguration.check_session_iframe, configuration.client_id, sessionState); + if(configuration.preload_user_info){ + await oidc.userInfoAsync(); + } oidc.publishEvent(eventNames.tryKeepExistingSessionAsync_end, { success: true, message: 'tokens inside storage are valid', diff --git a/packages/oidc-client/src/login.ts b/packages/oidc-client/src/login.ts index 95547c304..4614eebb3 100644 --- a/packages/oidc-client/src/login.ts +++ b/packages/oidc-client/src/login.ts @@ -207,6 +207,9 @@ export const loginCallbackAsync = (oidc:Oidc) => async (isSilentSignin = false) } await oidc.startCheckSessionAsync(oidcServerConfiguration.checkSessionIframe, clientId, sessionState, isSilentSignin); + if(configuration.preload_user_info){ + await oidc.userInfoAsync(); + } oidc.publishEvent(eventNames.loginCallbackAsync_end, {}); return { tokens: formattedTokens, diff --git a/packages/oidc-client/src/oidc.ts b/packages/oidc-client/src/oidc.ts index 0398a05f7..36f42bc37 100644 --- a/packages/oidc-client/src/oidc.ts +++ b/packages/oidc-client/src/oidc.ts @@ -121,6 +121,7 @@ export class Oidc { service_worker_update_require_callback, service_worker_activate: configuration.service_worker_activate ?? activateServiceWorker, demonstrating_proof_of_possession_configuration: configuration.demonstrating_proof_of_possession_configuration ?? defaultDemonstratingProofOfPossessionConfiguration, + preload_user_info: configuration.preload_user_info ?? false, }; this.getFetch = getFetch ?? getFetchDefault; diff --git a/packages/oidc-client/src/oidcClient.ts b/packages/oidc-client/src/oidcClient.ts index 7a799e17a..59a293dbe 100644 --- a/packages/oidc-client/src/oidcClient.ts +++ b/packages/oidc-client/src/oidcClient.ts @@ -80,7 +80,11 @@ export class OidcClient { } async userInfoAsync(noCache = false, demonstrating_proof_of_possession:boolean=false):Promise { - return this._oidc.userInfoAsync(noCache); + return this._oidc.userInfoAsync(noCache, demonstrating_proof_of_possession); + } + + userInfo():T { + return this._oidc.userInfo; } } diff --git a/packages/oidc-client/src/types.ts b/packages/oidc-client/src/types.ts index a816c4a31..a2dd29267 100644 --- a/packages/oidc-client/src/types.ts +++ b/packages/oidc-client/src/types.ts @@ -40,6 +40,7 @@ export type OidcConfiguration = { logout_tokens_to_invalidate?:Array; demonstrating_proof_of_possession?:boolean; demonstrating_proof_of_possession_configuration?: DemonstratingProofOfPossessionConfiguration; + preload_user_info?:boolean; }; export interface DemonstratingProofOfPossessionConfiguration { diff --git a/packages/react-oidc/src/User.ts b/packages/react-oidc/src/User.ts index a1212fbf0..53490a08b 100644 --- a/packages/react-oidc/src/User.ts +++ b/packages/react-oidc/src/User.ts @@ -14,16 +14,22 @@ export type OidcUser = { } export const useOidcUser = (configurationName = 'default', demonstrating_proof_of_possession=false) => { - const [oidcUser, setOidcUser] = useState>({ user: null, status: OidcUserStatus.Unauthenticated }); - const [oidcUserId, setOidcUserId] = useState(''); + const oidc = OidcClient.get(configurationName); + const user = oidc.userInfo(); + const [oidcUser, setOidcUser] = useState>({ user: user, status: user ? OidcUserStatus.Loaded : OidcUserStatus.Unauthenticated }); + const [oidcUserId, setOidcUserId] = useState(user ? 1 : 0); + const [oidcPreviousUserId, setPreviousOidcUserId] = useState(user ? 1 : 0); useEffect(() => { const oidc = OidcClient.get(configurationName); let isMounted = true; if (oidc && oidc.tokens) { + const isCache = oidcUserId === oidcPreviousUserId; + if(isCache && oidc.userInfo()) { + return; + } setOidcUser({ ...oidcUser, status: OidcUserStatus.Loading }); - const isNoCache = oidcUserId !== ''; - oidc.userInfoAsync(isNoCache, demonstrating_proof_of_possession) + oidc.userInfoAsync(!isCache, demonstrating_proof_of_possession) .then((info) => { if (isMounted) { // @ts-ignore @@ -31,6 +37,7 @@ export const useOidcUser = (configuration } }) .catch(() => setOidcUser({ ...oidcUser, status: OidcUserStatus.LoadingError })); + setPreviousOidcUserId(oidcUserId); } else { setOidcUser({ user: null, status: OidcUserStatus.Unauthenticated }); } @@ -48,7 +55,7 @@ export const useOidcUser = (configuration }, [oidcUserId]); const reloadOidcUser = () => { - setOidcUserId(oidcUserId + ' '); + setOidcUserId(oidcUserId+1); }; return { oidcUser: oidcUser.user, oidcUserLoadingState: oidcUser.status, reloadOidcUser };