fix: resolve auth callback failure from IndexedDB cache issues (refs #188)
All checks were successful
Deploy to Staging / Build Images (pull_request) Successful in 3m23s
Deploy to Staging / Deploy to Staging (pull_request) Successful in 52s
Deploy to Staging / Verify Staging (pull_request) Successful in 9s
Deploy to Staging / Notify Staging Ready (pull_request) Successful in 7s
Deploy to Staging / Notify Staging Failure (pull_request) Has been skipped

Add allKeys() to IndexedDBStorage to eliminate Auth0 CacheKeyManifest
fallback, revert set()/remove() to non-blocking persist, add auth error
display on callback route, remove leaky force-auth-check interceptor,
and migrate debug console calls to centralized logger.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
This commit is contained in:
Eric Gullickson
2026-02-15 09:06:40 -06:00
parent da59168d7b
commit b5b82db532
3 changed files with 58 additions and 102 deletions

View File

@@ -3,6 +3,8 @@
* @ai-context Replaces localStorage with IndexedDB for mobile browser compatibility
*/
import logger from '../../utils/logger';
interface StorageAdapter {
getItem(key: string): string | null;
setItem(key: string, value: string): void;
@@ -36,9 +38,9 @@ class IndexedDBStorage implements StorageAdapter, Auth0Cache {
this.db = await this.openDatabase();
await this.loadCacheFromDB();
this.isReady = true;
console.log('[IndexedDB] Storage initialized successfully');
logger.debug('IndexedDB storage initialized successfully');
} catch (error) {
console.error('[IndexedDB] Initialization failed, using memory only:', error);
logger.error('IndexedDB initialization failed, using memory only', { error: String(error) });
this.isReady = false;
}
}
@@ -48,7 +50,7 @@ class IndexedDBStorage implements StorageAdapter, Auth0Cache {
const request = indexedDB.open(this.dbName, this.dbVersion);
request.onerror = () => {
console.error(`IndexedDB open failed: ${request.error?.message}`);
logger.error(`IndexedDB open failed: ${request.error?.message}`);
resolve(null as any); // Fallback to memory-only mode
};
@@ -84,13 +86,13 @@ class IndexedDBStorage implements StorageAdapter, Auth0Cache {
}
cursor.continue();
} else {
console.log(`[IndexedDB] Loaded ${this.memoryCache.size} items into cache`);
logger.debug(`IndexedDB loaded ${this.memoryCache.size} items into cache`);
resolve();
}
};
request.onerror = () => {
console.warn('[IndexedDB] Failed to load cache from DB:', request.error);
logger.warn('IndexedDB failed to load cache from DB', { error: String(request.error) });
resolve();
};
});
@@ -107,14 +109,14 @@ class IndexedDBStorage implements StorageAdapter, Auth0Cache {
const request = store.delete(key);
request.onsuccess = () => resolve();
request.onerror = () => {
console.warn(`[IndexedDB] Failed to delete ${key}:`, request.error);
logger.warn(`IndexedDB failed to delete ${key}`, { error: String(request.error) });
resolve();
};
} else {
const request = store.put(value, key);
request.onsuccess = () => resolve();
request.onerror = () => {
console.warn(`[IndexedDB] Failed to persist ${key}:`, request.error);
logger.warn(`IndexedDB failed to persist ${key}`, { error: String(request.error) });
resolve();
};
}
@@ -132,7 +134,7 @@ class IndexedDBStorage implements StorageAdapter, Auth0Cache {
// Async persist to IndexedDB (non-blocking)
if (this.isReady) {
this.persistToDB(key, value).catch(error => {
console.warn(`[IndexedDB] Background persist failed for ${key}:`, error);
logger.warn(`IndexedDB background persist failed for ${key}`, { error: String(error) });
});
}
}
@@ -143,7 +145,7 @@ class IndexedDBStorage implements StorageAdapter, Auth0Cache {
// Async remove from IndexedDB (non-blocking)
if (this.isReady) {
this.persistToDB(key, null).catch(error => {
console.warn(`[IndexedDB] Background removal failed for ${key}:`, error);
logger.warn(`IndexedDB background removal failed for ${key}`, { error: String(error) });
});
}
}
@@ -193,6 +195,11 @@ class IndexedDBStorage implements StorageAdapter, Auth0Cache {
}
// Auth0 Cache interface implementation
// allKeys() eliminates Auth0 SDK's CacheKeyManifest fallback (auth0-spa-js line 2319)
allKeys(): string[] {
return Array.from(this.memoryCache.keys());
}
async get(key: string): Promise<any> {
await this.initPromise;
const value = this.getItem(key);
@@ -203,13 +210,19 @@ class IndexedDBStorage implements StorageAdapter, Auth0Cache {
await this.initPromise;
const stringValue = JSON.stringify(value);
this.memoryCache.set(key, stringValue);
await this.persistToDB(key, stringValue);
// Fire-and-forget: persist to IndexedDB for page reload survival
this.persistToDB(key, stringValue).catch(error => {
logger.warn(`IndexedDB background persist failed for ${key}`, { error: String(error) });
});
}
async remove(key: string): Promise<void> {
await this.initPromise;
this.memoryCache.delete(key);
await this.persistToDB(key, null);
// Fire-and-forget: remove from IndexedDB
this.persistToDB(key, null).catch(error => {
logger.warn(`IndexedDB background removal failed for ${key}`, { error: String(error) });
});
}
// Additional methods for enhanced functionality