44 * License, v. 2.0. If a copy of the MPL was not distributed with this
55 * file, You can obtain one at http://mozilla.org/MPL/2.0/.
66 */
7- import { Log , User , UserManager } from 'oidc-client' ;
8- import { jwtDecode } from 'jwt-decode' ;
97import { Dispatch } from 'react' ;
108import { NavigateFunction } from 'react-router-dom' ;
9+ import { jwtDecode } from 'jwt-decode' ;
10+ import { Log , User , UserManager } from 'oidc-client' ;
11+ import UserManagerMock from './UserManagerMock' ;
1112import {
1213 resetAuthenticationRouterError ,
1314 setLoggedUser ,
@@ -17,7 +18,6 @@ import {
1718 setUnauthorizedUserInfo ,
1819 setUserValidationError ,
1920} from '../redux/actions' ;
20- import UserManagerMock from './UserManagerMock' ;
2121
2222type UserValidationFunc = ( user : User ) => Promise < boolean > ;
2323type IdpSettingsGetter = ( ) => Promise < IdpSettings > ;
@@ -46,8 +46,6 @@ const hackAuthorityKey = 'oidc.hack.authority';
4646const oidcHackReloadedKey = 'gridsuite-oidc-hack-reloaded' ;
4747const pathKey = 'powsybl-gridsuite-current-path' ;
4848
49- const accessTokenExpiringNotificationTime = 60 ; // seconds
50-
5149function isIssuerError ( error : Error ) {
5250 return error . message . includes ( 'Invalid issuer in token' ) ;
5351}
@@ -94,7 +92,6 @@ function handleSigninSilent(
9492 dispatch : Dispatch < unknown > ,
9593 userManager : UserManager
9694) {
97- // eslint-disable-next-line consistent-return
9895 userManager . getUser ( ) . then ( ( user ) => {
9996 if ( user == null || getIdTokenExpiresIn ( user ) < 0 ) {
10097 return userManager . signinSilent ( ) . catch ( ( error : Error ) => {
@@ -105,6 +102,7 @@ function handleSigninSilent(
105102 }
106103 } ) ;
107104 }
105+ return Promise . resolve ( ) ;
108106 } ) ;
109107}
110108
@@ -140,6 +138,45 @@ function computeMinExpiresIn(
140138 return newExpiresIn ;
141139}
142140
141+ export function login ( location : Location , userManagerInstance : UserManager ) {
142+ sessionStorage . setItem ( pathKey , location . pathname + location . search ) ;
143+ return userManagerInstance
144+ . signinRedirect ( )
145+ . then ( ( ) => console . debug ( 'login' ) ) ;
146+ }
147+
148+ export function logout (
149+ dispatch : Dispatch < unknown > ,
150+ userManagerInstance : UserManager
151+ ) {
152+ sessionStorage . removeItem ( hackAuthorityKey ) ; // To remove when hack is removed
153+ sessionStorage . removeItem ( oidcHackReloadedKey ) ;
154+ return userManagerInstance . getUser ( ) . then ( ( user ) => {
155+ if ( user ) {
156+ // We don't need to check if token is valid at this point
157+ return userManagerInstance
158+ . signoutRedirect ( {
159+ extraQueryParams : {
160+ TargetResource :
161+ userManagerInstance . settings
162+ . post_logout_redirect_uri ,
163+ } ,
164+ } )
165+ . then ( ( ) => {
166+ console . debug ( 'logged out, window is closing...' ) ;
167+ } )
168+ . catch ( ( e ) => {
169+ console . log ( 'Error during logout :' , e ) ;
170+ // An error occured, window may not be closed, reset the user state
171+ dispatch ( setLoggedUser ( null ) ) ;
172+ dispatch ( setLogoutError ( user ?. profile ?. name , { error : e } ) ) ;
173+ } ) ;
174+ }
175+ console . log ( 'Error nobody to logout ' ) ;
176+ return Promise . resolve ( ) ;
177+ } ) ;
178+ }
179+
143180export function dispatchUser (
144181 dispatch : Dispatch < unknown > ,
145182 userManagerInstance : CustomUserManager ,
@@ -154,12 +191,11 @@ export function dispatchUser(
154191 console . debug (
155192 'User token is expired and will not be dispatched'
156193 ) ;
157- return ;
194+ return Promise . resolve ( ) ;
158195 }
159196 // without validateUser defined, valid user by default
160197 const validateUserPromise =
161- ( validateUser && validateUser ( user ) ) || Promise . resolve ( true ) ;
162- // eslint-disable-next-line consistent-return
198+ validateUser ?.( user ) || Promise . resolve ( true ) ;
163199 return validateUserPromise
164200 . then ( ( valid ) => {
165201 if ( ! valid ) {
@@ -196,9 +232,60 @@ export function dispatchUser(
196232 } ) ;
197233 }
198234 console . debug ( 'You are not logged in.' ) ;
235+ return Promise . resolve ( ) ;
199236 } ) ;
200237}
201238
239+ export function getPreLoginPath ( ) {
240+ return sessionStorage . getItem ( pathKey ) ;
241+ }
242+
243+ function navigateToPreLoginPath ( navigate : NavigateFunction ) {
244+ const previousPath = getPreLoginPath ( ) ;
245+ if ( previousPath !== null ) {
246+ navigate ( previousPath ) ;
247+ }
248+ }
249+
250+ export function handleSigninCallback (
251+ dispatch : Dispatch < unknown > ,
252+ navigate : NavigateFunction ,
253+ userManagerInstance : UserManager
254+ ) {
255+ let reloadAfterNavigate = false ;
256+ userManagerInstance
257+ . signinRedirectCallback ( )
258+ . catch ( ( e ) => {
259+ if ( isIssuerError ( e ) ) {
260+ extractIssuerToSessionStorage ( e ) ;
261+ // After navigate, location will be out of a redirection route (sign-in-silent or sign-in-callback) so reloading the page will attempt a silent signin
262+ // It will reload the user manager based on hacked authority at initialization with the new authority
263+ // We do this because on Azure we only get to know the issuer of the user in the idtoken and so signingredirectcallback will always fail
264+ // We could restart the whole login process from signin redirect with the correct issuer, but instead we just rely on the silent login after the reload which will work
265+ reloadAfterNavigate = true ;
266+ } else {
267+ throw e ;
268+ }
269+ } )
270+ . then ( ( ) => {
271+ dispatch ( setSignInCallbackError ( null ) ) ;
272+ navigateToPreLoginPath ( navigate ) ;
273+ if ( reloadAfterNavigate ) {
274+ reload ( ) ;
275+ }
276+ } )
277+ . catch ( ( e ) => {
278+ dispatch ( setSignInCallbackError ( e ) ) ;
279+ console . error ( e ) ;
280+ } ) ;
281+ }
282+
283+ export function handleSilentRenewCallback ( userManagerInstance : UserManager ) {
284+ userManagerInstance . signinSilentCallback ( ) ;
285+ }
286+
287+ const accessTokenExpiringNotificationTime = 60 ; // seconds
288+
202289function handleUser (
203290 dispatch : Dispatch < unknown > ,
204291 userManager : CustomUserManager ,
@@ -232,8 +319,8 @@ function handleUser(
232319 dispatch ( setShowAuthenticationRouterLogin ( true ) ) ;
233320 // logout during token expiration, show login without errors
234321 dispatch ( resetAuthenticationRouterError ( ) ) ;
235- // eslint-disable-next-line consistent-return
236- return dispatch ( setLoggedUser ( null ) ) ;
322+ dispatch ( setLoggedUser ( null ) ) ;
323+ return ;
237324 }
238325 if ( userManager . idpSettings ?. maxExpiresIn ) {
239326 if (
@@ -291,9 +378,7 @@ export async function initializeAuthenticationDev(
291378 validateUser : UserValidationFunc ,
292379 isSigninCallback : boolean
293380) {
294- const userManager : UserManager = new UserManagerMock (
295- { }
296- ) as unknown as UserManager ;
381+ const userManager : UserManager = new UserManagerMock ( { } ) ;
297382 if ( ! isSilentRenew ) {
298383 handleUser ( dispatch , userManager , validateUser ) ;
299384 if ( ! isSigninCallback ) {
@@ -341,90 +426,3 @@ export async function initializeAuthenticationProd(
341426 throw error ;
342427 }
343428}
344-
345- export function login ( location : Location , userManagerInstance : UserManager ) {
346- sessionStorage . setItem ( pathKey , location . pathname + location . search ) ;
347- return userManagerInstance
348- . signinRedirect ( )
349- . then ( ( ) => console . debug ( 'login' ) ) ;
350- }
351-
352- export function logout (
353- dispatch : Dispatch < unknown > ,
354- userManagerInstance : UserManager
355- ) {
356- sessionStorage . removeItem ( hackAuthorityKey ) ; // To remove when hack is removed
357- sessionStorage . removeItem ( oidcHackReloadedKey ) ;
358- // eslint-disable-next-line consistent-return
359- return userManagerInstance . getUser ( ) . then ( ( user ) => {
360- if ( user ) {
361- // We don't need to check if token is valid at this point
362- return userManagerInstance
363- . signoutRedirect ( {
364- extraQueryParams : {
365- TargetResource :
366- userManagerInstance . settings
367- . post_logout_redirect_uri ,
368- } ,
369- } )
370- . then ( ( ) => {
371- console . debug ( 'logged out, window is closing...' ) ;
372- } )
373- . catch ( ( e ) => {
374- console . log ( 'Error during logout :' , e ) ;
375- // An error occured, window may not be closed, reset the user state
376- dispatch ( setLoggedUser ( null ) ) ;
377- dispatch ( setLogoutError ( user ?. profile ?. name , { error : e } ) ) ;
378- } ) ;
379- }
380- console . log ( 'Error nobody to logout ' ) ;
381- } ) ;
382- }
383-
384- export function getPreLoginPath ( ) {
385- return sessionStorage . getItem ( pathKey ) ;
386- }
387-
388- function navigateToPreLoginPath ( navigate : NavigateFunction ) {
389- const previousPath = getPreLoginPath ( ) ;
390- if ( previousPath !== null ) {
391- navigate ( previousPath ) ;
392- }
393- }
394-
395- export function handleSigninCallback (
396- dispatch : Dispatch < unknown > ,
397- navigate : NavigateFunction ,
398- userManagerInstance : UserManager
399- ) {
400- let reloadAfterNavigate = false ;
401- userManagerInstance
402- . signinRedirectCallback ( )
403- . catch ( ( e ) => {
404- if ( isIssuerError ( e ) ) {
405- extractIssuerToSessionStorage ( e ) ;
406- // After navigate, location will be out of a redirection route (sign-in-silent or sign-in-callback) so reloading the page will attempt a silent signin
407- // It will reload the user manager based on hacked authority at initialization with the new authority
408- // We do this because on Azure we only get to know the issuer of the user in the idtoken and so signingredirectcallback will always fail
409- // We could restart the whole login process from signin redirect with the correct issuer, but instead we just rely on the silent login after the reload which will work
410- reloadAfterNavigate = true ;
411- } else {
412- throw e ;
413- }
414- } )
415- . then ( ( ) => {
416- dispatch ( setSignInCallbackError ( null ) ) ;
417- navigateToPreLoginPath ( navigate ) ;
418- if ( reloadAfterNavigate ) {
419- reload ( ) ;
420- }
421- } )
422- . catch ( ( e ) => {
423- dispatch ( setSignInCallbackError ( e ) ) ;
424- console . error ( e ) ;
425- } ) ;
426- }
427-
428- export function handleSilentRenewCallback ( userManagerInstance : UserManager ) {
429- userManagerInstance . signinSilentCallback ( ) ;
430- }
0 commit comments