diff --git a/src/gist.js b/src/gist.js index e38dc45..56c720f 100644 --- a/src/gist.js +++ b/src/gist.js @@ -1,5 +1,6 @@ import EventEmitter from "./utilities/event-emitter"; import { log } from "./utilities/log"; +import { clearExpiredFromLocalStore } from "./utilities/local-storage"; import { startQueueListener, checkMessageQueue, stopSSEListener } from "./managers/queue-manager"; import { setUserToken, clearUserToken, useGuestSession } from "./managers/user-manager"; import { showMessage, embedMessage, hideMessage, removePersistentMessage, fetchMessageByInstanceId, logBroadcastDismissedLocally } from "./managers/message-manager"; @@ -23,6 +24,7 @@ export default class { this.currentRoute = null; this.isDocumentVisible = true; this.config.isPreviewSession = setupPreview(); + clearExpiredFromLocalStore(); log(`Setup complete on ${this.config.env} environment.`); diff --git a/src/utilities/local-storage.js b/src/utilities/local-storage.js index 6f44622..9aa4d83 100644 --- a/src/utilities/local-storage.js +++ b/src/utilities/local-storage.js @@ -1,3 +1,5 @@ +import { log } from "./log"; + const maxExpiryDays = 365; const isPersistingSessionLocalStoreName = "gist.web.isPersistingSession"; @@ -21,32 +23,20 @@ export function setKeyToLocalStore(key, value, ttl = null) { } export function getKeyFromLocalStore(key) { - const itemStr = getStorage().getItem(key); - if (!itemStr) return null; - - const item = JSON.parse(itemStr); - const now = new Date(); - const expiryTime = new Date(item.expiry); - - // Retroactive bugfix: remove old cache entries with long expiry times - const isBroadcastOrUserKey = (key.startsWith("gist.web.message.broadcasts") && !key.endsWith("shouldShow") && !key.endsWith("numberOfTimesShown")) || (key.startsWith("gist.web.message.user") && !key.endsWith("seen")); - const sixtyMinutesFromNow = new Date(now.getTime() + 61 * 60 * 1000); - if (isBroadcastOrUserKey && expiryTime.getTime() > sixtyMinutesFromNow.getTime()) { - clearKeyFromLocalStore(key); - return null; - } - - if (now.getTime() > expiryTime.getTime()) { - clearKeyFromLocalStore(key); - return null; - } - return item.value; + return checkKeyForExpiry(key); } export function clearKeyFromLocalStore(key) { getStorage().removeItem(key); } +export function clearExpiredFromLocalStore() { + const storage = getStorage(); + for (let i = storage.length - 1; i >= 0; i--) { + checkKeyForExpiry(storage.key(i)); + } +} + export function isSessionBeingPersisted() { const currentValue = sessionStorage.getItem(isPersistingSessionLocalStoreName); if (currentValue === null) { @@ -59,4 +49,38 @@ export function isSessionBeingPersisted() { // Helper function to select the correct storage based on the session flag function getStorage() { return isSessionBeingPersisted() ? localStorage : sessionStorage; +} + +function checkKeyForExpiry(key) { + if (!key) return null; + + try { + const itemStr = getStorage().getItem(key); + if (!itemStr) return null; + + const item = JSON.parse(itemStr); + if (!item.expiry) return item.value; + + const now = new Date(); + const expiryTime = new Date(item.expiry); + + // remove old cache entries with long expiry times + const isBroadcastOrUserKey = (key.startsWith("gist.web.message.broadcasts") && !key.endsWith("shouldShow") && !key.endsWith("numberOfTimesShown")) || (key.startsWith("gist.web.message.user") && !key.endsWith("seen")); + const sixtyMinutesFromNow = new Date(now.getTime() + 61 * 60 * 1000); + if (isBroadcastOrUserKey && expiryTime.getTime() > sixtyMinutesFromNow.getTime()) { + clearKeyFromLocalStore(key); + return null; + } + + if (now.getTime() > expiryTime.getTime()) { + clearKeyFromLocalStore(key); + return null; + } + + return item.value; + } catch (e) { + log(`Error checking key ${key} for expiry: ${e}`); + } + + return null; } \ No newline at end of file