mirror of
https://github.com/element-hq/element-web
synced 2024-11-27 03:36:07 +03:00
Clear local storage settings handler cache on logout (#8454)
This commit is contained in:
parent
3a245a0cbe
commit
633229ca26
2 changed files with 36 additions and 22 deletions
|
@ -61,6 +61,7 @@ import { setSentryUser } from "./sentry";
|
||||||
import SdkConfig from "./SdkConfig";
|
import SdkConfig from "./SdkConfig";
|
||||||
import { DialogOpener } from "./utils/DialogOpener";
|
import { DialogOpener } from "./utils/DialogOpener";
|
||||||
import { Action } from "./dispatcher/actions";
|
import { Action } from "./dispatcher/actions";
|
||||||
|
import AbstractLocalStorageSettingsHandler from "./settings/handlers/AbstractLocalStorageSettingsHandler";
|
||||||
|
|
||||||
const HOMESERVER_URL_KEY = "mx_hs_url";
|
const HOMESERVER_URL_KEY = "mx_hs_url";
|
||||||
const ID_SERVER_URL_KEY = "mx_is_url";
|
const ID_SERVER_URL_KEY = "mx_is_url";
|
||||||
|
@ -878,6 +879,7 @@ async function clearStorage(opts?: { deleteEverything?: boolean }): Promise<void
|
||||||
const registrationTime = window.localStorage.getItem("mx_registration_time");
|
const registrationTime = window.localStorage.getItem("mx_registration_time");
|
||||||
|
|
||||||
window.localStorage.clear();
|
window.localStorage.clear();
|
||||||
|
AbstractLocalStorageSettingsHandler.clear();
|
||||||
|
|
||||||
try {
|
try {
|
||||||
await StorageManager.idbDelete("account", "mx_access_token");
|
await StorageManager.idbDelete("account", "mx_access_token");
|
||||||
|
|
|
@ -21,39 +21,51 @@ import SettingsHandler from "./SettingsHandler";
|
||||||
* by caching the values and listening for localStorage updates from other tabs.
|
* by caching the values and listening for localStorage updates from other tabs.
|
||||||
*/
|
*/
|
||||||
export default abstract class AbstractLocalStorageSettingsHandler extends SettingsHandler {
|
export default abstract class AbstractLocalStorageSettingsHandler extends SettingsHandler {
|
||||||
private itemCache = new Map<string, any>();
|
// Shared cache between all subclass instances
|
||||||
private objectCache = new Map<string, object>();
|
private static itemCache = new Map<string, any>();
|
||||||
|
private static objectCache = new Map<string, object>();
|
||||||
|
private static storageListenerBound = false;
|
||||||
|
|
||||||
|
private static onStorageEvent = (e: StorageEvent) => {
|
||||||
|
if (e.key === null) {
|
||||||
|
AbstractLocalStorageSettingsHandler.clear();
|
||||||
|
} else {
|
||||||
|
AbstractLocalStorageSettingsHandler.itemCache.delete(e.key);
|
||||||
|
AbstractLocalStorageSettingsHandler.objectCache.delete(e.key);
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
// Expose the clear event for Lifecycle to call, the storage listener only fires for changes from other tabs
|
||||||
|
public static clear() {
|
||||||
|
AbstractLocalStorageSettingsHandler.itemCache.clear();
|
||||||
|
AbstractLocalStorageSettingsHandler.objectCache.clear();
|
||||||
|
}
|
||||||
|
|
||||||
protected constructor() {
|
protected constructor() {
|
||||||
super();
|
super();
|
||||||
|
|
||||||
// Listen for storage changes from other tabs to bust the cache
|
if (!AbstractLocalStorageSettingsHandler.storageListenerBound) {
|
||||||
window.addEventListener("storage", (e: StorageEvent) => {
|
AbstractLocalStorageSettingsHandler.storageListenerBound = true;
|
||||||
if (e.key === null) {
|
// Listen for storage changes from other tabs to bust the cache
|
||||||
this.itemCache.clear();
|
window.addEventListener("storage", AbstractLocalStorageSettingsHandler.onStorageEvent);
|
||||||
this.objectCache.clear();
|
}
|
||||||
} else {
|
|
||||||
this.itemCache.delete(e.key);
|
|
||||||
this.objectCache.delete(e.key);
|
|
||||||
}
|
|
||||||
});
|
|
||||||
}
|
}
|
||||||
|
|
||||||
protected getItem(key: string): any {
|
protected getItem(key: string): any {
|
||||||
if (!this.itemCache.has(key)) {
|
if (!AbstractLocalStorageSettingsHandler.itemCache.has(key)) {
|
||||||
const value = localStorage.getItem(key);
|
const value = localStorage.getItem(key);
|
||||||
this.itemCache.set(key, value);
|
AbstractLocalStorageSettingsHandler.itemCache.set(key, value);
|
||||||
return value;
|
return value;
|
||||||
}
|
}
|
||||||
|
|
||||||
return this.itemCache.get(key);
|
return AbstractLocalStorageSettingsHandler.itemCache.get(key);
|
||||||
}
|
}
|
||||||
|
|
||||||
protected getObject<T extends object>(key: string): T | null {
|
protected getObject<T extends object>(key: string): T | null {
|
||||||
if (!this.objectCache.has(key)) {
|
if (!AbstractLocalStorageSettingsHandler.objectCache.has(key)) {
|
||||||
try {
|
try {
|
||||||
const value = JSON.parse(localStorage.getItem(key));
|
const value = JSON.parse(localStorage.getItem(key));
|
||||||
this.objectCache.set(key, value);
|
AbstractLocalStorageSettingsHandler.objectCache.set(key, value);
|
||||||
return value;
|
return value;
|
||||||
} catch (err) {
|
} catch (err) {
|
||||||
console.error("Failed to parse localStorage object", err);
|
console.error("Failed to parse localStorage object", err);
|
||||||
|
@ -61,24 +73,24 @@ export default abstract class AbstractLocalStorageSettingsHandler extends Settin
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
return this.objectCache.get(key) as T;
|
return AbstractLocalStorageSettingsHandler.objectCache.get(key) as T;
|
||||||
}
|
}
|
||||||
|
|
||||||
protected setItem(key: string, value: any): void {
|
protected setItem(key: string, value: any): void {
|
||||||
this.itemCache.set(key, value);
|
AbstractLocalStorageSettingsHandler.itemCache.set(key, value);
|
||||||
localStorage.setItem(key, value);
|
localStorage.setItem(key, value);
|
||||||
}
|
}
|
||||||
|
|
||||||
protected setObject(key: string, value: object): void {
|
protected setObject(key: string, value: object): void {
|
||||||
this.objectCache.set(key, value);
|
AbstractLocalStorageSettingsHandler.objectCache.set(key, value);
|
||||||
localStorage.setItem(key, JSON.stringify(value));
|
localStorage.setItem(key, JSON.stringify(value));
|
||||||
}
|
}
|
||||||
|
|
||||||
// handles both items and objects
|
// handles both items and objects
|
||||||
protected removeItem(key: string): void {
|
protected removeItem(key: string): void {
|
||||||
localStorage.removeItem(key);
|
localStorage.removeItem(key);
|
||||||
this.itemCache.delete(key);
|
AbstractLocalStorageSettingsHandler.itemCache.delete(key);
|
||||||
this.objectCache.delete(key);
|
AbstractLocalStorageSettingsHandler.objectCache.delete(key);
|
||||||
}
|
}
|
||||||
|
|
||||||
public isSupported(): boolean {
|
public isSupported(): boolean {
|
||||||
|
|
Loading…
Reference in a new issue