@@ -195,6 +195,8 @@ export class HankoAuth extends LitElement {
195195 private _lastSessionId : string | null = null ;
196196 private _hanko : any = null ;
197197 private _isPrimary = false ; // Is this the primary instance?
198+ private _sessionCheckFailures = 0 ;
199+ private _sessionCheckBackoffTimer : ReturnType < typeof setTimeout > | null = null ;
198200 private _hankoObserver : MutationObserver | null = null ;
199201
200202 // Hanko signup headline text across all supported languages (used for subtitle injection)
@@ -368,6 +370,8 @@ export class HankoAuth extends LitElement {
368370 private _handleVisibilityChange = ( ) => {
369371 // Only primary instance should handle visibility changes to prevent race conditions
370372 if ( ! this . _isPrimary ) return ;
373+ // Don't re-check if a backoff retry is already scheduled
374+ if ( this . _sessionCheckBackoffTimer ) return ;
371375
372376 if ( ! document . hidden && ! this . showProfile && ! this . user ) {
373377 // Page became visible, we're in header mode, and no user is logged in
@@ -380,6 +384,8 @@ export class HankoAuth extends LitElement {
380384 private _handleWindowFocus = ( ) => {
381385 // Only primary instance should handle window focus to prevent race conditions
382386 if ( ! this . _isPrimary ) return ;
387+ // Don't re-check if a backoff retry is already scheduled
388+ if ( this . _sessionCheckBackoffTimer ) return ;
383389
384390 if ( ! this . showProfile && ! this . user ) {
385391 // Window focused, we're in header mode, and no user is logged in
@@ -549,6 +555,16 @@ export class HankoAuth extends LitElement {
549555 }
550556 }
551557
558+ private _scheduleSessionRetry ( ) {
559+ if ( this . _sessionCheckBackoffTimer ) return ; // already scheduled
560+ const delay = Math . min ( 1000 * 2 ** this . _sessionCheckFailures , 60000 ) ;
561+ this . log ( `Session check failed, retrying in ${ delay / 1000 } s (attempt ${ this . _sessionCheckFailures } )` ) ;
562+ this . _sessionCheckBackoffTimer = setTimeout ( ( ) => {
563+ this . _sessionCheckBackoffTimer = null ;
564+ this . checkSession ( ) ;
565+ } , delay ) ;
566+ }
567+
552568 private async checkSession ( ) {
553569 this . log ( "Checking for existing Hanko session..." ) ;
554570
@@ -592,6 +608,7 @@ export class HankoAuth extends LitElement {
592608 return ;
593609 }
594610
611+ this . _sessionCheckFailures = 0 ; // reset backoff on success
595612 this . log ( "Valid Hanko session found via cookie" ) ;
596613 this . log ( "Session data:" , sessionData ) ;
597614
@@ -710,12 +727,16 @@ export class HankoAuth extends LitElement {
710727 this . log ( "No valid session cookie found - user needs to login" ) ;
711728 }
712729 } catch ( validateError ) {
730+ this . _sessionCheckFailures ++ ;
713731 this . log ( "Session validation failed:" , validateError ) ;
714- this . log ( "No valid session - user needs to login" ) ;
732+ this . _scheduleSessionRetry ( ) ;
733+ return ;
715734 }
716735 } catch ( error ) {
736+ this . _sessionCheckFailures ++ ;
717737 this . log ( "Session check error:" , error ) ;
718- this . log ( "No existing session - user needs to login" ) ;
738+ this . _scheduleSessionRetry ( ) ;
739+ return ;
719740 } finally {
720741 // Broadcast state changes to other instances
721742 if ( this . _isPrimary ) {
0 commit comments