fix: IndexedDB cache broken on page reload - root cause of mobile login failure (refs #190)
All checks were successful
Deploy to Staging / Build Images (pull_request) Successful in 3m25s
Deploy to Staging / Deploy to Staging (pull_request) Successful in 51s
Deploy to Staging / Verify Staging (pull_request) Successful in 8s
Deploy to Staging / Notify Staging Ready (pull_request) Successful in 7s
Deploy to Staging / Notify Staging Failure (pull_request) Has been skipped
All checks were successful
Deploy to Staging / Build Images (pull_request) Successful in 3m25s
Deploy to Staging / Deploy to Staging (pull_request) Successful in 51s
Deploy to Staging / Verify Staging (pull_request) Successful in 8s
Deploy to Staging / Notify Staging Ready (pull_request) Successful in 7s
Deploy to Staging / Notify Staging Failure (pull_request) Has been skipped
loadCacheFromDB used store.getAll() which returns raw values, not key-value pairs. The item.key check always failed, so memoryCache was empty after every page reload. Auth0 SDK state stored before redirect was lost on mobile Safari (no bfcache). Also fixed set()/remove() to await IDB persistence so Auth0 state is fully written before loginWithRedirect() navigates away. Added 10s timeout on callback loading state as safety net. Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
This commit is contained in:
@@ -71,25 +71,27 @@ class IndexedDBStorage implements StorageAdapter, Auth0Cache {
|
||||
return new Promise((resolve) => {
|
||||
const transaction = this.db!.transaction([this.storeName], 'readonly');
|
||||
const store = transaction.objectStore(this.storeName);
|
||||
const request = store.getAll();
|
||||
const request = store.openCursor();
|
||||
this.memoryCache.clear();
|
||||
|
||||
request.onsuccess = () => {
|
||||
const results = request.result;
|
||||
this.memoryCache.clear();
|
||||
|
||||
for (const item of results) {
|
||||
if (item.key && typeof item.value === 'string') {
|
||||
this.memoryCache.set(item.key, item.value);
|
||||
const cursor = request.result;
|
||||
if (cursor) {
|
||||
const key = cursor.key as string;
|
||||
const value = cursor.value;
|
||||
if (typeof key === 'string' && typeof value === 'string') {
|
||||
this.memoryCache.set(key, value);
|
||||
}
|
||||
cursor.continue();
|
||||
} else {
|
||||
console.log(`[IndexedDB] Loaded ${this.memoryCache.size} items into cache`);
|
||||
resolve();
|
||||
}
|
||||
|
||||
console.log(`[IndexedDB] Loaded ${this.memoryCache.size} items into cache`);
|
||||
resolve();
|
||||
};
|
||||
|
||||
request.onerror = () => {
|
||||
console.warn('[IndexedDB] Failed to load cache from DB:', request.error);
|
||||
resolve(); // Don't fail initialization
|
||||
resolve();
|
||||
};
|
||||
});
|
||||
}
|
||||
@@ -199,12 +201,15 @@ class IndexedDBStorage implements StorageAdapter, Auth0Cache {
|
||||
|
||||
async set(key: string, value: any): Promise<void> {
|
||||
await this.initPromise;
|
||||
this.setItem(key, JSON.stringify(value));
|
||||
const stringValue = JSON.stringify(value);
|
||||
this.memoryCache.set(key, stringValue);
|
||||
await this.persistToDB(key, stringValue);
|
||||
}
|
||||
|
||||
async remove(key: string): Promise<void> {
|
||||
await this.initPromise;
|
||||
this.removeItem(key);
|
||||
this.memoryCache.delete(key);
|
||||
await this.persistToDB(key, null);
|
||||
}
|
||||
|
||||
// Additional methods for enhanced functionality
|
||||
|
||||
Reference in New Issue
Block a user