oidc-spa
Version:
Openidconnect client for Single Page Applications
141 lines • 5.22 kB
JavaScript
import { assert, typeGuard, id } from "../vendor/frontend/tsafe";
function parseSessionStorageItem(sessionStorageItemValue) {
let json;
try {
json = JSON.parse(sessionStorageItemValue);
}
catch {
return undefined;
}
if (!typeGuard(json, json instanceof Object &&
"__brand" in json &&
json.__brand === id("SessionStorageItem_Parsed-v1"))) {
return undefined;
}
return json;
}
const SESSION_STORAGE_PREFIX = "ephemeral:";
function createStoreInSessionStorageAndScheduleRemovalInMemoryItem(params) {
const { key, value, remainingTtlMs } = params;
const sessionStorageKey = `${SESSION_STORAGE_PREFIX}${key}`;
const removeFromSessionStorage = () => {
inMemoryItem.removeFromSessionStorage = undefined;
clearTimeout(timer);
sessionStorage.removeItem(sessionStorageKey);
};
const timer = setTimeout(() => removeFromSessionStorage(), remainingTtlMs);
const inMemoryItem = {
key,
value,
removeFromSessionStorage
};
sessionStorage.removeItem(sessionStorageKey);
sessionStorage.setItem(sessionStorageKey, JSON.stringify(id({
__brand: "SessionStorageItem_Parsed-v1",
value,
expiresAtTime: Date.now() + remainingTtlMs
})));
return inMemoryItem;
}
export function createEphemeralSessionStorage(params) {
const { sessionStorageTtlMs } = params;
const inMemoryItems = [];
for (let i = 0; i < sessionStorage.length; i++) {
const sessionStorageKey = sessionStorage.key(i);
assert(sessionStorageKey !== null, "470498");
if (!sessionStorageKey.startsWith(SESSION_STORAGE_PREFIX)) {
continue;
}
const sessionStorageItem = sessionStorage.getItem(sessionStorageKey);
assert(sessionStorageItem !== null, "846771");
const sessionStorageItem_parsed = parseSessionStorageItem(sessionStorageItem);
if (sessionStorageItem_parsed === undefined) {
continue;
}
const remainingTtlMs = sessionStorageItem_parsed.expiresAtTime - Date.now();
sessionStorage.removeItem(sessionStorageKey);
if (remainingTtlMs <= 0) {
continue;
}
inMemoryItems.push({
key: sessionStorageKey.slice(SESSION_STORAGE_PREFIX.length),
value: sessionStorageItem_parsed.value,
removeFromSessionStorage: undefined
});
}
let isPersistenceEnabled = false;
const storage = {
persistCurrentStateAndSubsequentChanges: () => {
isPersistenceEnabled = true;
for (let i = 0; i < storage.length; i++) {
const key = storage.key(i);
assert(key !== null, "803385");
const value = storage.getItem(key);
assert(value !== null, "777098");
storage.setItem(key, value);
}
},
get length() {
return inMemoryItems.length;
},
key: index => {
const inMemoryItem = inMemoryItems[index];
if (inMemoryItem === undefined) {
return null;
}
return inMemoryItem.key;
},
removeItem: key => {
const inMemoryItem = inMemoryItems.find(item => item.key === key);
if (inMemoryItem === undefined) {
return;
}
inMemoryItem.removeFromSessionStorage?.();
const index = inMemoryItems.indexOf(inMemoryItem);
inMemoryItems.splice(index, 1);
},
clear: () => {
for (let i = 0; i < storage.length; i++) {
const key = storage.key(i);
assert(key !== null, "290875");
storage.removeItem(key);
}
},
getItem: key => {
const inMemoryItem = inMemoryItems.find(item => item.key === key);
if (inMemoryItem === undefined) {
return null;
}
return inMemoryItem.value;
},
setItem: (key, value) => {
let existingInMemoryItemIndex = undefined;
{
const inMemoryItem = inMemoryItems.find(item => item.key === key);
if (inMemoryItem !== undefined) {
inMemoryItem.removeFromSessionStorage?.();
existingInMemoryItemIndex = inMemoryItems.indexOf(inMemoryItem);
}
}
const inMemoryItem_new = isPersistenceEnabled
? createStoreInSessionStorageAndScheduleRemovalInMemoryItem({
key,
value,
remainingTtlMs: sessionStorageTtlMs
})
: id({
key,
value,
removeFromSessionStorage: undefined
});
if (existingInMemoryItemIndex !== undefined) {
inMemoryItems[existingInMemoryItemIndex] = inMemoryItem_new;
}
else {
inMemoryItems.push(inMemoryItem_new);
}
}
};
return storage;
}
//# sourceMappingURL=EphemeralSessionStorage.js.map