@@ -41,6 +41,7 @@ import { isAccessTokenExpiredOrExpiring } from './utils/token';
4141import LoginPopupOverlay from './overlay/loginPopupOverlay' ;
4242import { LocalForageAsyncStorage } from './storage/LocalForageAsyncStorage' ;
4343
44+ const LOGIN_POPUP_CLOSED_POLLING_DURATION = 500 ;
4445const formUrlEncodedHeaders = {
4546 'Content-Type' : 'application/x-www-form-urlencoded' ,
4647} ;
@@ -498,14 +499,43 @@ export class Auth {
498499 const signinPopup = async ( ) => {
499500 const extraQueryParams = this . buildExtraQueryParams ( directLoginOptionsToUse , imPassportTraceId ) ;
500501
501- return this . userManager . signinPopup ( {
502+ const userPromise = this . userManager . signinPopup ( {
502503 extraQueryParams,
503504 popupWindowFeatures : {
504505 width : 410 ,
505506 height : 450 ,
506507 } ,
507508 popupWindowTarget,
509+ // Enable oidc-client-ts native popup close detection (works for initial screen)
510+ popupAbortOnClose : true ,
508511 } ) ;
512+
513+ // Additional polling workaround to detect popup closure during navigation
514+ // (e.g., when user navigates to third-party login, passwordless, or captcha screens)
515+ // This complements oidc-client-ts native detection which only checks once at start
516+ const popupRef = window . open ( '' , popupWindowTarget ) ;
517+ if ( popupRef ) {
518+ // Create a promise that rejects when popup is closed
519+ const popupClosedPromise = new Promise < never > ( ( _ , reject ) => {
520+ const timer = setInterval ( ( ) => {
521+ if ( popupRef . closed ) {
522+ clearInterval ( timer ) ;
523+ reject ( new Error ( 'Popup closed by user' ) ) ;
524+ }
525+ } , LOGIN_POPUP_CLOSED_POLLING_DURATION ) ;
526+
527+ // Clean up timer when the user promise resolves/rejects
528+ userPromise . finally ( ( ) => {
529+ clearInterval ( timer ) ;
530+ popupRef . close ( ) ;
531+ } ) ;
532+ } ) ;
533+
534+ // Race between user authentication and popup being closed
535+ return Promise . race ( [ userPromise , popupClosedPromise ] ) ;
536+ }
537+
538+ return userPromise ;
509539 } ;
510540
511541 return new Promise ( ( resolve , reject ) => {
0 commit comments