Skip to content

Commit 20e56cd

Browse files
committed
Add exponential backoff on session check failures
1 parent 81e7708 commit 20e56cd

1 file changed

Lines changed: 23 additions & 2 deletions

File tree

auth-libs/web-component/src/hanko-auth.ts

Lines changed: 23 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -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

Comments
 (0)