Skip to content
This repository was archived by the owner on Sep 11, 2024. It is now read-only.

Commit 162355f

Browse files
committed
Clear local storage settings handler cache on logout
1 parent 36fd9cb commit 162355f

File tree

2 files changed

+36
-22
lines changed

2 files changed

+36
-22
lines changed

src/Lifecycle.ts

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -61,6 +61,7 @@ import { setSentryUser } from "./sentry";
6161
import SdkConfig from "./SdkConfig";
6262
import { DialogOpener } from "./utils/DialogOpener";
6363
import { Action } from "./dispatcher/actions";
64+
import AbstractLocalStorageSettingsHandler from "./settings/handlers/AbstractLocalStorageSettingsHandler";
6465

6566
const HOMESERVER_URL_KEY = "mx_hs_url";
6667
const ID_SERVER_URL_KEY = "mx_is_url";
@@ -878,6 +879,7 @@ async function clearStorage(opts?: { deleteEverything?: boolean }): Promise<void
878879
const registrationTime = window.localStorage.getItem("mx_registration_time");
879880

880881
window.localStorage.clear();
882+
AbstractLocalStorageSettingsHandler.clear();
881883

882884
try {
883885
await StorageManager.idbDelete("account", "mx_access_token");

src/settings/handlers/AbstractLocalStorageSettingsHandler.ts

Lines changed: 34 additions & 22 deletions
Original file line numberDiff line numberDiff line change
@@ -21,64 +21,76 @@ import SettingsHandler from "./SettingsHandler";
2121
* by caching the values and listening for localStorage updates from other tabs.
2222
*/
2323
export default abstract class AbstractLocalStorageSettingsHandler extends SettingsHandler {
24-
private itemCache = new Map<string, any>();
25-
private objectCache = new Map<string, object>();
24+
// Shared cache between all subclass instances
25+
private static itemCache = new Map<string, any>();
26+
private static objectCache = new Map<string, object>();
27+
private static storageListenerBound = false;
28+
29+
private static onStorageEvent = (e: StorageEvent) => {
30+
if (e.key === null) {
31+
AbstractLocalStorageSettingsHandler.clear();
32+
} else {
33+
AbstractLocalStorageSettingsHandler.itemCache.delete(e.key);
34+
AbstractLocalStorageSettingsHandler.objectCache.delete(e.key);
35+
}
36+
};
37+
38+
// Expose the clear event for Lifecycle to call, the storage listener only fires for changes from other tabs
39+
public static clear() {
40+
AbstractLocalStorageSettingsHandler.itemCache.clear();
41+
AbstractLocalStorageSettingsHandler.objectCache.clear();
42+
}
2643

2744
protected constructor() {
2845
super();
2946

30-
// Listen for storage changes from other tabs to bust the cache
31-
window.addEventListener("storage", (e: StorageEvent) => {
32-
if (e.key === null) {
33-
this.itemCache.clear();
34-
this.objectCache.clear();
35-
} else {
36-
this.itemCache.delete(e.key);
37-
this.objectCache.delete(e.key);
38-
}
39-
});
47+
if (!AbstractLocalStorageSettingsHandler.storageListenerBound) {
48+
AbstractLocalStorageSettingsHandler.storageListenerBound = true;
49+
// Listen for storage changes from other tabs to bust the cache
50+
window.addEventListener("storage", AbstractLocalStorageSettingsHandler.onStorageEvent);
51+
}
4052
}
4153

4254
protected getItem(key: string): any {
43-
if (!this.itemCache.has(key)) {
55+
if (!AbstractLocalStorageSettingsHandler.itemCache.has(key)) {
4456
const value = localStorage.getItem(key);
45-
this.itemCache.set(key, value);
57+
AbstractLocalStorageSettingsHandler.itemCache.set(key, value);
4658
return value;
4759
}
4860

49-
return this.itemCache.get(key);
61+
return AbstractLocalStorageSettingsHandler.itemCache.get(key);
5062
}
5163

5264
protected getObject<T extends object>(key: string): T | null {
53-
if (!this.objectCache.has(key)) {
65+
if (!AbstractLocalStorageSettingsHandler.objectCache.has(key)) {
5466
try {
5567
const value = JSON.parse(localStorage.getItem(key));
56-
this.objectCache.set(key, value);
68+
AbstractLocalStorageSettingsHandler.objectCache.set(key, value);
5769
return value;
5870
} catch (err) {
5971
console.error("Failed to parse localStorage object", err);
6072
return null;
6173
}
6274
}
6375

64-
return this.objectCache.get(key) as T;
76+
return AbstractLocalStorageSettingsHandler.objectCache.get(key) as T;
6577
}
6678

6779
protected setItem(key: string, value: any): void {
68-
this.itemCache.set(key, value);
80+
AbstractLocalStorageSettingsHandler.itemCache.set(key, value);
6981
localStorage.setItem(key, value);
7082
}
7183

7284
protected setObject(key: string, value: object): void {
73-
this.objectCache.set(key, value);
85+
AbstractLocalStorageSettingsHandler.objectCache.set(key, value);
7486
localStorage.setItem(key, JSON.stringify(value));
7587
}
7688

7789
// handles both items and objects
7890
protected removeItem(key: string): void {
7991
localStorage.removeItem(key);
80-
this.itemCache.delete(key);
81-
this.objectCache.delete(key);
92+
AbstractLocalStorageSettingsHandler.itemCache.delete(key);
93+
AbstractLocalStorageSettingsHandler.objectCache.delete(key);
8294
}
8395

8496
public isSupported(): boolean {

0 commit comments

Comments
 (0)