417 lines
14 KiB
JavaScript
417 lines
14 KiB
JavaScript
/*! @azure/msal-node v2.5.1 2023-11-07 */
|
|
'use strict';
|
|
'use strict';
|
|
|
|
var msalCommon = require('@azure/msal-common');
|
|
var Deserializer = require('./serializer/Deserializer.cjs');
|
|
var Serializer = require('./serializer/Serializer.cjs');
|
|
|
|
/*
|
|
* Copyright (c) Microsoft Corporation. All rights reserved.
|
|
* Licensed under the MIT License.
|
|
*/
|
|
/**
|
|
* This class implements Storage for node, reading cache from user specified storage location or an extension library
|
|
* @public
|
|
*/
|
|
class NodeStorage extends msalCommon.CacheManager {
|
|
constructor(logger, clientId, cryptoImpl, staticAuthorityOptions) {
|
|
super(clientId, cryptoImpl, logger, staticAuthorityOptions);
|
|
this.cache = {};
|
|
this.changeEmitters = [];
|
|
this.logger = logger;
|
|
}
|
|
/**
|
|
* Queue up callbacks
|
|
* @param func - a callback function for cache change indication
|
|
*/
|
|
registerChangeEmitter(func) {
|
|
this.changeEmitters.push(func);
|
|
}
|
|
/**
|
|
* Invoke the callback when cache changes
|
|
*/
|
|
emitChange() {
|
|
this.changeEmitters.forEach((func) => func.call(null));
|
|
}
|
|
/**
|
|
* Converts cacheKVStore to InMemoryCache
|
|
* @param cache - key value store
|
|
*/
|
|
cacheToInMemoryCache(cache) {
|
|
const inMemoryCache = {
|
|
accounts: {},
|
|
idTokens: {},
|
|
accessTokens: {},
|
|
refreshTokens: {},
|
|
appMetadata: {},
|
|
};
|
|
for (const key in cache) {
|
|
const value = cache[key];
|
|
if (typeof value !== "object") {
|
|
continue;
|
|
}
|
|
if (value instanceof msalCommon.AccountEntity) {
|
|
inMemoryCache.accounts[key] = value;
|
|
}
|
|
else if (msalCommon.CacheHelpers.isIdTokenEntity(value)) {
|
|
inMemoryCache.idTokens[key] = value;
|
|
}
|
|
else if (msalCommon.CacheHelpers.isAccessTokenEntity(value)) {
|
|
inMemoryCache.accessTokens[key] = value;
|
|
}
|
|
else if (msalCommon.CacheHelpers.isRefreshTokenEntity(value)) {
|
|
inMemoryCache.refreshTokens[key] = value;
|
|
}
|
|
else if (value instanceof msalCommon.AppMetadataEntity) {
|
|
inMemoryCache.appMetadata[key] = value;
|
|
}
|
|
else {
|
|
continue;
|
|
}
|
|
}
|
|
return inMemoryCache;
|
|
}
|
|
/**
|
|
* converts inMemoryCache to CacheKVStore
|
|
* @param inMemoryCache - kvstore map for inmemory
|
|
*/
|
|
inMemoryCacheToCache(inMemoryCache) {
|
|
// convert in memory cache to a flat Key-Value map
|
|
let cache = this.getCache();
|
|
cache = {
|
|
...cache,
|
|
...inMemoryCache.accounts,
|
|
...inMemoryCache.idTokens,
|
|
...inMemoryCache.accessTokens,
|
|
...inMemoryCache.refreshTokens,
|
|
...inMemoryCache.appMetadata,
|
|
};
|
|
// convert in memory cache to a flat Key-Value map
|
|
return cache;
|
|
}
|
|
/**
|
|
* gets the current in memory cache for the client
|
|
*/
|
|
getInMemoryCache() {
|
|
this.logger.trace("Getting in-memory cache");
|
|
// convert the cache key value store to inMemoryCache
|
|
const inMemoryCache = this.cacheToInMemoryCache(this.getCache());
|
|
return inMemoryCache;
|
|
}
|
|
/**
|
|
* sets the current in memory cache for the client
|
|
* @param inMemoryCache - key value map in memory
|
|
*/
|
|
setInMemoryCache(inMemoryCache) {
|
|
this.logger.trace("Setting in-memory cache");
|
|
// convert and append the inMemoryCache to cacheKVStore
|
|
const cache = this.inMemoryCacheToCache(inMemoryCache);
|
|
this.setCache(cache);
|
|
this.emitChange();
|
|
}
|
|
/**
|
|
* get the current cache key-value store
|
|
*/
|
|
getCache() {
|
|
this.logger.trace("Getting cache key-value store");
|
|
return this.cache;
|
|
}
|
|
/**
|
|
* sets the current cache (key value store)
|
|
* @param cacheMap - key value map
|
|
*/
|
|
setCache(cache) {
|
|
this.logger.trace("Setting cache key value store");
|
|
this.cache = cache;
|
|
// mark change in cache
|
|
this.emitChange();
|
|
}
|
|
/**
|
|
* Gets cache item with given key.
|
|
* @param key - lookup key for the cache entry
|
|
*/
|
|
getItem(key) {
|
|
this.logger.tracePii(`Item key: ${key}`);
|
|
// read cache
|
|
const cache = this.getCache();
|
|
return cache[key];
|
|
}
|
|
/**
|
|
* Gets cache item with given key-value
|
|
* @param key - lookup key for the cache entry
|
|
* @param value - value of the cache entry
|
|
*/
|
|
setItem(key, value) {
|
|
this.logger.tracePii(`Item key: ${key}`);
|
|
// read cache
|
|
const cache = this.getCache();
|
|
cache[key] = value;
|
|
// write to cache
|
|
this.setCache(cache);
|
|
}
|
|
getAccountKeys() {
|
|
const inMemoryCache = this.getInMemoryCache();
|
|
const accountKeys = Object.keys(inMemoryCache.accounts);
|
|
return accountKeys;
|
|
}
|
|
getTokenKeys() {
|
|
const inMemoryCache = this.getInMemoryCache();
|
|
const tokenKeys = {
|
|
idToken: Object.keys(inMemoryCache.idTokens),
|
|
accessToken: Object.keys(inMemoryCache.accessTokens),
|
|
refreshToken: Object.keys(inMemoryCache.refreshTokens),
|
|
};
|
|
return tokenKeys;
|
|
}
|
|
/**
|
|
* fetch the account entity
|
|
* @param accountKey - lookup key to fetch cache type AccountEntity
|
|
*/
|
|
getAccount(accountKey) {
|
|
const account = this.getItem(accountKey);
|
|
if (msalCommon.AccountEntity.isAccountEntity(account)) {
|
|
return account;
|
|
}
|
|
return null;
|
|
}
|
|
/**
|
|
* set account entity
|
|
* @param account - cache value to be set of type AccountEntity
|
|
*/
|
|
setAccount(account) {
|
|
const accountKey = account.generateAccountKey();
|
|
this.setItem(accountKey, account);
|
|
}
|
|
/**
|
|
* fetch the idToken credential
|
|
* @param idTokenKey - lookup key to fetch cache type IdTokenEntity
|
|
*/
|
|
getIdTokenCredential(idTokenKey) {
|
|
const idToken = this.getItem(idTokenKey);
|
|
if (msalCommon.CacheHelpers.isIdTokenEntity(idToken)) {
|
|
return idToken;
|
|
}
|
|
return null;
|
|
}
|
|
/**
|
|
* set idToken credential
|
|
* @param idToken - cache value to be set of type IdTokenEntity
|
|
*/
|
|
setIdTokenCredential(idToken) {
|
|
const idTokenKey = msalCommon.CacheHelpers.generateCredentialKey(idToken);
|
|
this.setItem(idTokenKey, idToken);
|
|
}
|
|
/**
|
|
* fetch the accessToken credential
|
|
* @param accessTokenKey - lookup key to fetch cache type AccessTokenEntity
|
|
*/
|
|
getAccessTokenCredential(accessTokenKey) {
|
|
const accessToken = this.getItem(accessTokenKey);
|
|
if (msalCommon.CacheHelpers.isAccessTokenEntity(accessToken)) {
|
|
return accessToken;
|
|
}
|
|
return null;
|
|
}
|
|
/**
|
|
* set accessToken credential
|
|
* @param accessToken - cache value to be set of type AccessTokenEntity
|
|
*/
|
|
setAccessTokenCredential(accessToken) {
|
|
const accessTokenKey = msalCommon.CacheHelpers.generateCredentialKey(accessToken);
|
|
this.setItem(accessTokenKey, accessToken);
|
|
}
|
|
/**
|
|
* fetch the refreshToken credential
|
|
* @param refreshTokenKey - lookup key to fetch cache type RefreshTokenEntity
|
|
*/
|
|
getRefreshTokenCredential(refreshTokenKey) {
|
|
const refreshToken = this.getItem(refreshTokenKey);
|
|
if (msalCommon.CacheHelpers.isRefreshTokenEntity(refreshToken)) {
|
|
return refreshToken;
|
|
}
|
|
return null;
|
|
}
|
|
/**
|
|
* set refreshToken credential
|
|
* @param refreshToken - cache value to be set of type RefreshTokenEntity
|
|
*/
|
|
setRefreshTokenCredential(refreshToken) {
|
|
const refreshTokenKey = msalCommon.CacheHelpers.generateCredentialKey(refreshToken);
|
|
this.setItem(refreshTokenKey, refreshToken);
|
|
}
|
|
/**
|
|
* fetch appMetadata entity from the platform cache
|
|
* @param appMetadataKey - lookup key to fetch cache type AppMetadataEntity
|
|
*/
|
|
getAppMetadata(appMetadataKey) {
|
|
const appMetadata = this.getItem(appMetadataKey);
|
|
if (msalCommon.AppMetadataEntity.isAppMetadataEntity(appMetadataKey, appMetadata)) {
|
|
return appMetadata;
|
|
}
|
|
return null;
|
|
}
|
|
/**
|
|
* set appMetadata entity to the platform cache
|
|
* @param appMetadata - cache value to be set of type AppMetadataEntity
|
|
*/
|
|
setAppMetadata(appMetadata) {
|
|
const appMetadataKey = appMetadata.generateAppMetadataKey();
|
|
this.setItem(appMetadataKey, appMetadata);
|
|
}
|
|
/**
|
|
* fetch server telemetry entity from the platform cache
|
|
* @param serverTelemetrykey - lookup key to fetch cache type ServerTelemetryEntity
|
|
*/
|
|
getServerTelemetry(serverTelemetrykey) {
|
|
const serverTelemetryEntity = this.getItem(serverTelemetrykey);
|
|
if (serverTelemetryEntity &&
|
|
msalCommon.CacheHelpers.isServerTelemetryEntity(serverTelemetrykey, serverTelemetryEntity)) {
|
|
return serverTelemetryEntity;
|
|
}
|
|
return null;
|
|
}
|
|
/**
|
|
* set server telemetry entity to the platform cache
|
|
* @param serverTelemetryKey - lookup key to fetch cache type ServerTelemetryEntity
|
|
* @param serverTelemetry - cache value to be set of type ServerTelemetryEntity
|
|
*/
|
|
setServerTelemetry(serverTelemetryKey, serverTelemetry) {
|
|
this.setItem(serverTelemetryKey, serverTelemetry);
|
|
}
|
|
/**
|
|
* fetch authority metadata entity from the platform cache
|
|
* @param key - lookup key to fetch cache type AuthorityMetadataEntity
|
|
*/
|
|
getAuthorityMetadata(key) {
|
|
const authorityMetadataEntity = this.getItem(key);
|
|
if (authorityMetadataEntity &&
|
|
msalCommon.AuthorityMetadataEntity.isAuthorityMetadataEntity(key, authorityMetadataEntity)) {
|
|
return authorityMetadataEntity;
|
|
}
|
|
return null;
|
|
}
|
|
/**
|
|
* Get all authority metadata keys
|
|
*/
|
|
getAuthorityMetadataKeys() {
|
|
return this.getKeys().filter((key) => {
|
|
return this.isAuthorityMetadata(key);
|
|
});
|
|
}
|
|
/**
|
|
* set authority metadata entity to the platform cache
|
|
* @param key - lookup key to fetch cache type AuthorityMetadataEntity
|
|
* @param metadata - cache value to be set of type AuthorityMetadataEntity
|
|
*/
|
|
setAuthorityMetadata(key, metadata) {
|
|
this.setItem(key, metadata);
|
|
}
|
|
/**
|
|
* fetch throttling entity from the platform cache
|
|
* @param throttlingCacheKey - lookup key to fetch cache type ThrottlingEntity
|
|
*/
|
|
getThrottlingCache(throttlingCacheKey) {
|
|
const throttlingCache = this.getItem(throttlingCacheKey);
|
|
if (throttlingCache &&
|
|
msalCommon.ThrottlingEntity.isThrottlingEntity(throttlingCacheKey, throttlingCache)) {
|
|
return throttlingCache;
|
|
}
|
|
return null;
|
|
}
|
|
/**
|
|
* set throttling entity to the platform cache
|
|
* @param throttlingCacheKey - lookup key to fetch cache type ThrottlingEntity
|
|
* @param throttlingCache - cache value to be set of type ThrottlingEntity
|
|
*/
|
|
setThrottlingCache(throttlingCacheKey, throttlingCache) {
|
|
this.setItem(throttlingCacheKey, throttlingCache);
|
|
}
|
|
/**
|
|
* Removes the cache item from memory with the given key.
|
|
* @param key - lookup key to remove a cache entity
|
|
* @param inMemory - key value map of the cache
|
|
*/
|
|
removeItem(key) {
|
|
this.logger.tracePii(`Item key: ${key}`);
|
|
// read inMemoryCache
|
|
let result = false;
|
|
const cache = this.getCache();
|
|
if (!!cache[key]) {
|
|
delete cache[key];
|
|
result = true;
|
|
}
|
|
// write to the cache after removal
|
|
if (result) {
|
|
this.setCache(cache);
|
|
this.emitChange();
|
|
}
|
|
return result;
|
|
}
|
|
/**
|
|
* Checks whether key is in cache.
|
|
* @param key - look up key for a cache entity
|
|
*/
|
|
containsKey(key) {
|
|
return this.getKeys().includes(key);
|
|
}
|
|
/**
|
|
* Gets all keys in window.
|
|
*/
|
|
getKeys() {
|
|
this.logger.trace("Retrieving all cache keys");
|
|
// read cache
|
|
const cache = this.getCache();
|
|
return [...Object.keys(cache)];
|
|
}
|
|
/**
|
|
* Clears all cache entries created by MSAL (except tokens).
|
|
*/
|
|
async clear() {
|
|
this.logger.trace("Clearing cache entries created by MSAL");
|
|
// read inMemoryCache
|
|
const cacheKeys = this.getKeys();
|
|
// delete each element
|
|
cacheKeys.forEach((key) => {
|
|
this.removeItem(key);
|
|
});
|
|
this.emitChange();
|
|
}
|
|
/**
|
|
* Initialize in memory cache from an exisiting cache vault
|
|
* @param cache - blob formatted cache (JSON)
|
|
*/
|
|
static generateInMemoryCache(cache) {
|
|
return Deserializer.Deserializer.deserializeAllCache(Deserializer.Deserializer.deserializeJSONBlob(cache));
|
|
}
|
|
/**
|
|
* retrieves the final JSON
|
|
* @param inMemoryCache - itemised cache read from the JSON
|
|
*/
|
|
static generateJsonCache(inMemoryCache) {
|
|
return Serializer.Serializer.serializeAllCache(inMemoryCache);
|
|
}
|
|
/**
|
|
* Updates a credential's cache key if the current cache key is outdated
|
|
*/
|
|
updateCredentialCacheKey(currentCacheKey, credential) {
|
|
const updatedCacheKey = msalCommon.CacheHelpers.generateCredentialKey(credential);
|
|
if (currentCacheKey !== updatedCacheKey) {
|
|
const cacheItem = this.getItem(currentCacheKey);
|
|
if (cacheItem) {
|
|
this.removeItem(currentCacheKey);
|
|
this.setItem(updatedCacheKey, cacheItem);
|
|
this.logger.verbose(`Updated an outdated ${credential.credentialType} cache key`);
|
|
return updatedCacheKey;
|
|
}
|
|
else {
|
|
this.logger.error(`Attempted to update an outdated ${credential.credentialType} cache key but no item matching the outdated key was found in storage`);
|
|
}
|
|
}
|
|
return currentCacheKey;
|
|
}
|
|
}
|
|
|
|
exports.NodeStorage = NodeStorage;
|
|
//# sourceMappingURL=NodeStorage.cjs.map
|