Also use unload event to clean up session lock (#11800)

Signed-off-by: Manuel Huber <info@manuelhu.de>
Co-authored-by: Florian Duros <florianduros@element.io>
This commit is contained in:
Manuel Huber 2023-10-26 14:26:49 +02:00 committed by GitHub
parent 1881fb1ee4
commit 6423f226b4
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23

View file

@ -171,6 +171,27 @@ export async function getSessionLock(onNewInstance: () => Promise<void>): Promis
} }
} }
// handler for pagehide and unload events, used later
function onPagehideEvent(): void {
// only remove the ping if we still think we're the owner. Otherwise we could be removing someone else's claim!
if (lockServicer !== null) {
prefixedLogger.debug("page hide: clearing our claim");
window.clearInterval(lockServicer);
window.localStorage.removeItem(SESSION_LOCK_CONSTANTS.STORAGE_ITEM_PING);
window.localStorage.removeItem(SESSION_LOCK_CONSTANTS.STORAGE_ITEM_OWNER);
lockServicer = null;
}
// It's worth noting that, according to the spec, the page might come back to life again after a pagehide.
//
// In practice that's unlikely because Element is unlikely to qualify for the bfcache, but if it does,
// this is probably the best we can do: we certainly don't want to stop the user loading any new tabs because
// Element happens to be in a bfcache somewhere.
//
// So, we just hope that we aren't in the middle of any crypto operations, and rely on `onStorageEvent` kicking
// in soon enough after we resume to tell us if another tab woke up while we were asleep.
}
async function releaseLock(): Promise<void> { async function releaseLock(): Promise<void> {
// tell the app to shut down // tell the app to shut down
await onNewInstance(); await onNewInstance();
@ -239,23 +260,11 @@ export async function getSessionLock(onNewInstance: () => Promise<void>): Promis
window.addEventListener("storage", onStorageEvent); window.addEventListener("storage", onStorageEvent);
// also add a listener to clear our claims when our tab closes or navigates away // also add a listener to clear our claims when our tab closes or navigates away
window.addEventListener("pagehide", (event) => { window.addEventListener("pagehide", onPagehideEvent);
// only remove the ping if we still think we're the owner. Otherwise we could be removing someone else's claim!
if (lockServicer !== null) {
prefixedLogger.debug("page hide: clearing our claim");
window.localStorage.removeItem(SESSION_LOCK_CONSTANTS.STORAGE_ITEM_PING);
window.localStorage.removeItem(SESSION_LOCK_CONSTANTS.STORAGE_ITEM_OWNER);
}
// It's worth noting that, according to the spec, the page might come back to life again after a pagehide. // The pagehide event is called unreliably on Firefox, so additionally add an unload handler.
// // https://bugzilla.mozilla.org/show_bug.cgi?id=1854492
// In practice that's unlikely because Element is unlikely to qualify for the bfcache, but if it does, window.addEventListener("unload", onPagehideEvent);
// this is probably the best we can do: we certainly don't want to stop the user loading any new tabs because
// Element happens to be in a bfcache somewhere.
//
// So, we just hope that we aren't in the middle of any crypto operations, and rely on `onStorageEvent` kicking
// in soon enough after we resume to tell us if another tab woke up while we were asleep.
});
return true; return true;
} }