Commit iniziale

This commit is contained in:
Paolo A
2025-02-18 22:59:07 +00:00
commit 4bbf35cefb
6879 changed files with 623784 additions and 0 deletions

View File

@@ -0,0 +1,49 @@
import { AccountInfo, AccountFilter, Logger } from "@azure/msal-common/browser";
import { BrowserCacheManager } from "./BrowserCacheManager.js";
/**
* Returns all the accounts in the cache that match the optional filter. If no filter is provided, all accounts are returned.
* @param accountFilter - (Optional) filter to narrow down the accounts returned
* @returns Array of AccountInfo objects in cache
*/
export declare function getAllAccounts(logger: Logger, browserStorage: BrowserCacheManager, isInBrowser: boolean, accountFilter?: AccountFilter): AccountInfo[];
/**
* Returns the first account found in the cache that matches the account filter passed in.
* @param accountFilter
* @returns The first account found in the cache matching the provided filter or null if no account could be found.
*/
export declare function getAccount(accountFilter: AccountFilter, logger: Logger, browserStorage: BrowserCacheManager): AccountInfo | null;
/**
* Returns the signed in account matching username.
* (the account object is created at the time of successful login)
* or null when no matching account is found.
* This API is provided for convenience but getAccountById should be used for best reliability
* @param username
* @returns The account object stored in MSAL
*/
export declare function getAccountByUsername(username: string, logger: Logger, browserStorage: BrowserCacheManager): AccountInfo | null;
/**
* Returns the signed in account matching homeAccountId.
* (the account object is created at the time of successful login)
* or null when no matching account is found
* @param homeAccountId
* @returns The account object stored in MSAL
*/
export declare function getAccountByHomeId(homeAccountId: string, logger: Logger, browserStorage: BrowserCacheManager): AccountInfo | null;
/**
* Returns the signed in account matching localAccountId.
* (the account object is created at the time of successful login)
* or null when no matching account is found
* @param localAccountId
* @returns The account object stored in MSAL
*/
export declare function getAccountByLocalId(localAccountId: string, logger: Logger, browserStorage: BrowserCacheManager): AccountInfo | null;
/**
* Sets the account to use as the active account. If no account is passed to the acquireToken APIs, then MSAL will use this active account.
* @param account
*/
export declare function setActiveAccount(account: AccountInfo | null, browserStorage: BrowserCacheManager): void;
/**
* Gets the currently active account
*/
export declare function getActiveAccount(browserStorage: BrowserCacheManager): AccountInfo | null;
//# sourceMappingURL=AccountManager.d.ts.map

View File

@@ -0,0 +1 @@
{"version":3,"file":"AccountManager.d.ts","sourceRoot":"","sources":["../../src/cache/AccountManager.ts"],"names":[],"mappings":"AAKA,OAAO,EAAE,WAAW,EAAE,aAAa,EAAE,MAAM,EAAE,MAAM,4BAA4B,CAAC;AAChF,OAAO,EAAE,mBAAmB,EAAE,MAAM,0BAA0B,CAAC;AAE/D;;;;GAIG;AACH,wBAAgB,cAAc,CAC1B,MAAM,EAAE,MAAM,EACd,cAAc,EAAE,mBAAmB,EACnC,WAAW,EAAE,OAAO,EACpB,aAAa,CAAC,EAAE,aAAa,GAC9B,WAAW,EAAE,CAGf;AAED;;;;GAIG;AACH,wBAAgB,UAAU,CACtB,aAAa,EAAE,aAAa,EAC5B,MAAM,EAAE,MAAM,EACd,cAAc,EAAE,mBAAmB,GACpC,WAAW,GAAG,IAAI,CAmBpB;AAED;;;;;;;GAOG;AACH,wBAAgB,oBAAoB,CAChC,QAAQ,EAAE,MAAM,EAChB,MAAM,EAAE,MAAM,EACd,cAAc,EAAE,mBAAmB,GACpC,WAAW,GAAG,IAAI,CAwBpB;AAED;;;;;;GAMG;AACH,wBAAgB,kBAAkB,CAC9B,aAAa,EAAE,MAAM,EACrB,MAAM,EAAE,MAAM,EACd,cAAc,EAAE,mBAAmB,GACpC,WAAW,GAAG,IAAI,CAwBpB;AAED;;;;;;GAMG;AACH,wBAAgB,mBAAmB,CAC/B,cAAc,EAAE,MAAM,EACtB,MAAM,EAAE,MAAM,EACd,cAAc,EAAE,mBAAmB,GACpC,WAAW,GAAG,IAAI,CAwBpB;AAED;;;GAGG;AACH,wBAAgB,gBAAgB,CAC5B,OAAO,EAAE,WAAW,GAAG,IAAI,EAC3B,cAAc,EAAE,mBAAmB,GACpC,IAAI,CAEN;AAED;;GAEG;AACH,wBAAgB,gBAAgB,CAC5B,cAAc,EAAE,mBAAmB,GACpC,WAAW,GAAG,IAAI,CAEpB"}

View File

@@ -0,0 +1,131 @@
/*! @azure/msal-browser v4.2.1 2025-02-11 */
'use strict';
/*
* Copyright (c) Microsoft Corporation. All rights reserved.
* Licensed under the MIT License.
*/
/**
* Returns all the accounts in the cache that match the optional filter. If no filter is provided, all accounts are returned.
* @param accountFilter - (Optional) filter to narrow down the accounts returned
* @returns Array of AccountInfo objects in cache
*/
function getAllAccounts(logger, browserStorage, isInBrowser, accountFilter) {
logger.verbose("getAllAccounts called");
return isInBrowser ? browserStorage.getAllAccounts(accountFilter) : [];
}
/**
* Returns the first account found in the cache that matches the account filter passed in.
* @param accountFilter
* @returns The first account found in the cache matching the provided filter or null if no account could be found.
*/
function getAccount(accountFilter, logger, browserStorage) {
logger.trace("getAccount called");
if (Object.keys(accountFilter).length === 0) {
logger.warning("getAccount: No accountFilter provided");
return null;
}
const account = browserStorage.getAccountInfoFilteredBy(accountFilter);
if (account) {
logger.verbose("getAccount: Account matching provided filter found, returning");
return account;
}
else {
logger.verbose("getAccount: No matching account found, returning null");
return null;
}
}
/**
* Returns the signed in account matching username.
* (the account object is created at the time of successful login)
* or null when no matching account is found.
* This API is provided for convenience but getAccountById should be used for best reliability
* @param username
* @returns The account object stored in MSAL
*/
function getAccountByUsername(username, logger, browserStorage) {
logger.trace("getAccountByUsername called");
if (!username) {
logger.warning("getAccountByUsername: No username provided");
return null;
}
const account = browserStorage.getAccountInfoFilteredBy({
username,
});
if (account) {
logger.verbose("getAccountByUsername: Account matching username found, returning");
logger.verbosePii(`getAccountByUsername: Returning signed-in accounts matching username: ${username}`);
return account;
}
else {
logger.verbose("getAccountByUsername: No matching account found, returning null");
return null;
}
}
/**
* Returns the signed in account matching homeAccountId.
* (the account object is created at the time of successful login)
* or null when no matching account is found
* @param homeAccountId
* @returns The account object stored in MSAL
*/
function getAccountByHomeId(homeAccountId, logger, browserStorage) {
logger.trace("getAccountByHomeId called");
if (!homeAccountId) {
logger.warning("getAccountByHomeId: No homeAccountId provided");
return null;
}
const account = browserStorage.getAccountInfoFilteredBy({
homeAccountId,
});
if (account) {
logger.verbose("getAccountByHomeId: Account matching homeAccountId found, returning");
logger.verbosePii(`getAccountByHomeId: Returning signed-in accounts matching homeAccountId: ${homeAccountId}`);
return account;
}
else {
logger.verbose("getAccountByHomeId: No matching account found, returning null");
return null;
}
}
/**
* Returns the signed in account matching localAccountId.
* (the account object is created at the time of successful login)
* or null when no matching account is found
* @param localAccountId
* @returns The account object stored in MSAL
*/
function getAccountByLocalId(localAccountId, logger, browserStorage) {
logger.trace("getAccountByLocalId called");
if (!localAccountId) {
logger.warning("getAccountByLocalId: No localAccountId provided");
return null;
}
const account = browserStorage.getAccountInfoFilteredBy({
localAccountId,
});
if (account) {
logger.verbose("getAccountByLocalId: Account matching localAccountId found, returning");
logger.verbosePii(`getAccountByLocalId: Returning signed-in accounts matching localAccountId: ${localAccountId}`);
return account;
}
else {
logger.verbose("getAccountByLocalId: No matching account found, returning null");
return null;
}
}
/**
* Sets the account to use as the active account. If no account is passed to the acquireToken APIs, then MSAL will use this active account.
* @param account
*/
function setActiveAccount(account, browserStorage) {
browserStorage.setActiveAccount(account);
}
/**
* Gets the currently active account
*/
function getActiveAccount(browserStorage) {
return browserStorage.getActiveAccount();
}
export { getAccount, getAccountByHomeId, getAccountByLocalId, getAccountByUsername, getActiveAccount, getAllAccounts, setActiveAccount };
//# sourceMappingURL=AccountManager.mjs.map

View File

@@ -0,0 +1 @@
{"version":3,"file":"AccountManager.mjs","sources":["../../src/cache/AccountManager.ts"],"sourcesContent":[null],"names":[],"mappings":"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"}

View File

@@ -0,0 +1,51 @@
import { Logger } from "@azure/msal-common/browser";
import { IAsyncStorage } from "./IAsyncStorage.js";
/**
* This class allows MSAL to store artifacts asynchronously using the DatabaseStorage IndexedDB wrapper,
* backed up with the more volatile MemoryStorage object for cases in which IndexedDB may be unavailable.
*/
export declare class AsyncMemoryStorage<T> implements IAsyncStorage<T> {
private inMemoryCache;
private indexedDBCache;
private logger;
constructor(logger: Logger);
private handleDatabaseAccessError;
/**
* Get the item matching the given key. Tries in-memory cache first, then in the asynchronous
* storage object if item isn't found in-memory.
* @param key
*/
getItem(key: string): Promise<T | null>;
/**
* Sets the item in the in-memory cache and then tries to set it in the asynchronous
* storage object with the given key.
* @param key
* @param value
*/
setItem(key: string, value: T): Promise<void>;
/**
* Removes the item matching the key from the in-memory cache, then tries to remove it from the asynchronous storage object.
* @param key
*/
removeItem(key: string): Promise<void>;
/**
* Get all the keys from the in-memory cache as an iterable array of strings. If no keys are found, query the keys in the
* asynchronous storage object.
*/
getKeys(): Promise<string[]>;
/**
* Returns true or false if the given key is present in the cache.
* @param key
*/
containsKey(key: string): Promise<boolean>;
/**
* Clears in-memory Map
*/
clearInMemory(): void;
/**
* Tries to delete the IndexedDB database
* @returns
*/
clearPersistent(): Promise<boolean>;
}
//# sourceMappingURL=AsyncMemoryStorage.d.ts.map

View File

@@ -0,0 +1 @@
{"version":3,"file":"AsyncMemoryStorage.d.ts","sourceRoot":"","sources":["../../src/cache/AsyncMemoryStorage.ts"],"names":[],"mappings":"AAKA,OAAO,EAAE,MAAM,EAAE,MAAM,4BAA4B,CAAC;AAMpD,OAAO,EAAE,aAAa,EAAE,MAAM,oBAAoB,CAAC;AAGnD;;;GAGG;AACH,qBAAa,kBAAkB,CAAC,CAAC,CAAE,YAAW,aAAa,CAAC,CAAC,CAAC;IAC1D,OAAO,CAAC,aAAa,CAAmB;IACxC,OAAO,CAAC,cAAc,CAAqB;IAC3C,OAAO,CAAC,MAAM,CAAS;gBAEX,MAAM,EAAE,MAAM;IAM1B,OAAO,CAAC,yBAAyB;IAYjC;;;;OAIG;IACG,OAAO,CAAC,GAAG,EAAE,MAAM,GAAG,OAAO,CAAC,CAAC,GAAG,IAAI,CAAC;IAe7C;;;;;OAKG;IACG,OAAO,CAAC,GAAG,EAAE,MAAM,EAAE,KAAK,EAAE,CAAC,GAAG,OAAO,CAAC,IAAI,CAAC;IASnD;;;OAGG;IACG,UAAU,CAAC,GAAG,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC;IAS5C;;;OAGG;IACG,OAAO,IAAI,OAAO,CAAC,MAAM,EAAE,CAAC;IAelC;;;OAGG;IACG,WAAW,CAAC,GAAG,EAAE,MAAM,GAAG,OAAO,CAAC,OAAO,CAAC;IAehD;;OAEG;IACH,aAAa,IAAI,IAAI;IAOrB;;;OAGG;IACG,eAAe,IAAI,OAAO,CAAC,OAAO,CAAC;CAc5C"}

View File

@@ -0,0 +1,141 @@
/*! @azure/msal-browser v4.2.1 2025-02-11 */
'use strict';
import { BrowserAuthError } from '../error/BrowserAuthError.mjs';
import { DatabaseStorage } from './DatabaseStorage.mjs';
import { MemoryStorage } from './MemoryStorage.mjs';
import { databaseUnavailable } from '../error/BrowserAuthErrorCodes.mjs';
/*
* Copyright (c) Microsoft Corporation. All rights reserved.
* Licensed under the MIT License.
*/
/**
* This class allows MSAL to store artifacts asynchronously using the DatabaseStorage IndexedDB wrapper,
* backed up with the more volatile MemoryStorage object for cases in which IndexedDB may be unavailable.
*/
class AsyncMemoryStorage {
constructor(logger) {
this.inMemoryCache = new MemoryStorage();
this.indexedDBCache = new DatabaseStorage();
this.logger = logger;
}
handleDatabaseAccessError(error) {
if (error instanceof BrowserAuthError &&
error.errorCode === databaseUnavailable) {
this.logger.error("Could not access persistent storage. This may be caused by browser privacy features which block persistent storage in third-party contexts.");
}
else {
throw error;
}
}
/**
* Get the item matching the given key. Tries in-memory cache first, then in the asynchronous
* storage object if item isn't found in-memory.
* @param key
*/
async getItem(key) {
const item = this.inMemoryCache.getItem(key);
if (!item) {
try {
this.logger.verbose("Queried item not found in in-memory cache, now querying persistent storage.");
return await this.indexedDBCache.getItem(key);
}
catch (e) {
this.handleDatabaseAccessError(e);
}
}
return item;
}
/**
* Sets the item in the in-memory cache and then tries to set it in the asynchronous
* storage object with the given key.
* @param key
* @param value
*/
async setItem(key, value) {
this.inMemoryCache.setItem(key, value);
try {
await this.indexedDBCache.setItem(key, value);
}
catch (e) {
this.handleDatabaseAccessError(e);
}
}
/**
* Removes the item matching the key from the in-memory cache, then tries to remove it from the asynchronous storage object.
* @param key
*/
async removeItem(key) {
this.inMemoryCache.removeItem(key);
try {
await this.indexedDBCache.removeItem(key);
}
catch (e) {
this.handleDatabaseAccessError(e);
}
}
/**
* Get all the keys from the in-memory cache as an iterable array of strings. If no keys are found, query the keys in the
* asynchronous storage object.
*/
async getKeys() {
const cacheKeys = this.inMemoryCache.getKeys();
if (cacheKeys.length === 0) {
try {
this.logger.verbose("In-memory cache is empty, now querying persistent storage.");
return await this.indexedDBCache.getKeys();
}
catch (e) {
this.handleDatabaseAccessError(e);
}
}
return cacheKeys;
}
/**
* Returns true or false if the given key is present in the cache.
* @param key
*/
async containsKey(key) {
const containsKey = this.inMemoryCache.containsKey(key);
if (!containsKey) {
try {
this.logger.verbose("Key not found in in-memory cache, now querying persistent storage.");
return await this.indexedDBCache.containsKey(key);
}
catch (e) {
this.handleDatabaseAccessError(e);
}
}
return containsKey;
}
/**
* Clears in-memory Map
*/
clearInMemory() {
// InMemory cache is a Map instance, clear is straightforward
this.logger.verbose(`Deleting in-memory keystore`);
this.inMemoryCache.clear();
this.logger.verbose(`In-memory keystore deleted`);
}
/**
* Tries to delete the IndexedDB database
* @returns
*/
async clearPersistent() {
try {
this.logger.verbose("Deleting persistent keystore");
const dbDeleted = await this.indexedDBCache.deleteDatabase();
if (dbDeleted) {
this.logger.verbose("Persistent keystore deleted");
}
return dbDeleted;
}
catch (e) {
this.handleDatabaseAccessError(e);
return false;
}
}
}
export { AsyncMemoryStorage };
//# sourceMappingURL=AsyncMemoryStorage.mjs.map

View File

@@ -0,0 +1 @@
{"version":3,"file":"AsyncMemoryStorage.mjs","sources":["../../src/cache/AsyncMemoryStorage.ts"],"sourcesContent":[null],"names":["BrowserAuthErrorCodes.databaseUnavailable"],"mappings":"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"}

View File

@@ -0,0 +1,312 @@
import { CommonAuthorizationCodeRequest, ICrypto, AccountEntity, IdTokenEntity, AccessTokenEntity, RefreshTokenEntity, AppMetadataEntity, CacheManager, ServerTelemetryEntity, ThrottlingEntity, Logger, AuthorityMetadataEntity, AccountInfo, TokenKeys, CredentialType, CacheRecord, IPerformanceClient, StaticAuthorityOptions, StoreInCache } from "@azure/msal-common/browser";
import { CacheOptions } from "../config/Configuration.js";
import { InteractionType } from "../utils/BrowserConstants.js";
import { MemoryStorage } from "./MemoryStorage.js";
import { IWindowStorage } from "./IWindowStorage.js";
import { NativeTokenRequest } from "../broker/nativeBroker/NativeRequest.js";
import { AuthenticationResult } from "../response/AuthenticationResult.js";
import { SilentRequest } from "../request/SilentRequest.js";
import { SsoSilentRequest } from "../request/SsoSilentRequest.js";
import { RedirectRequest } from "../request/RedirectRequest.js";
import { PopupRequest } from "../request/PopupRequest.js";
import { CookieStorage } from "./CookieStorage.js";
import { EventHandler } from "../event/EventHandler.js";
/**
* This class implements the cache storage interface for MSAL through browser local or session storage.
* Cookies are only used if storeAuthStateInCookie is true, and are only used for
* parameters such as state and nonce, generally.
*/
export declare class BrowserCacheManager extends CacheManager {
protected cacheConfig: Required<CacheOptions>;
protected browserStorage: IWindowStorage<string>;
protected internalStorage: MemoryStorage<string>;
protected temporaryCacheStorage: IWindowStorage<string>;
protected cookieStorage: CookieStorage;
protected logger: Logger;
protected performanceClient: IPerformanceClient;
private eventHandler;
constructor(clientId: string, cacheConfig: Required<CacheOptions>, cryptoImpl: ICrypto, logger: Logger, performanceClient: IPerformanceClient, eventHandler: EventHandler, staticAuthorityOptions?: StaticAuthorityOptions);
initialize(correlationId: string): Promise<void>;
/**
* Parses passed value as JSON object, JSON.parse() will throw an error.
* @param input
*/
protected validateAndParseJson(jsonValue: string): object | null;
/**
* Reads account from cache, deserializes it into an account entity and returns it.
* If account is not found from the key, returns null and removes key from map.
* @param accountKey
* @returns
*/
getAccount(accountKey: string): AccountEntity | null;
/**
* set account entity in the platform cache
* @param account
*/
setAccount(account: AccountEntity, correlationId: string): Promise<void>;
/**
* Returns the array of account keys currently cached
* @returns
*/
getAccountKeys(): Array<string>;
/**
* Add a new account to the key map
* @param key
*/
addAccountKeyToMap(key: string): boolean;
/**
* Remove an account from the key map
* @param key
*/
removeAccountKeyFromMap(key: string): void;
/**
* Extends inherited removeAccount function to include removal of the account key from the map
* @param key
*/
removeAccount(key: string): Promise<void>;
/**
* Removes credentials associated with the provided account
* @param account
*/
removeAccountContext(account: AccountEntity): Promise<void>;
/**
* Removes given idToken from the cache and from the key map
* @param key
*/
removeIdToken(key: string): void;
/**
* Removes given accessToken from the cache and from the key map
* @param key
*/
removeAccessToken(key: string): Promise<void>;
/**
* Removes given refreshToken from the cache and from the key map
* @param key
*/
removeRefreshToken(key: string): void;
/**
* Gets the keys for the cached tokens associated with this clientId
* @returns
*/
getTokenKeys(): TokenKeys;
/**
* Adds the given key to the token key map
* @param key
* @param type
*/
addTokenKey(key: string, type: CredentialType): void;
/**
* Removes the given key from the token key map
* @param key
* @param type
*/
removeTokenKey(key: string, type: CredentialType): void;
/**
* generates idToken entity from a string
* @param idTokenKey
*/
getIdTokenCredential(idTokenKey: string): IdTokenEntity | null;
/**
* set IdToken credential to the platform cache
* @param idToken
*/
setIdTokenCredential(idToken: IdTokenEntity, correlationId: string): Promise<void>;
/**
* generates accessToken entity from a string
* @param key
*/
getAccessTokenCredential(accessTokenKey: string): AccessTokenEntity | null;
/**
* set accessToken credential to the platform cache
* @param accessToken
*/
setAccessTokenCredential(accessToken: AccessTokenEntity, correlationId: string): Promise<void>;
/**
* generates refreshToken entity from a string
* @param refreshTokenKey
*/
getRefreshTokenCredential(refreshTokenKey: string): RefreshTokenEntity | null;
/**
* set refreshToken credential to the platform cache
* @param refreshToken
*/
setRefreshTokenCredential(refreshToken: RefreshTokenEntity, correlationId: string): Promise<void>;
/**
* fetch appMetadata entity from the platform cache
* @param appMetadataKey
*/
getAppMetadata(appMetadataKey: string): AppMetadataEntity | null;
/**
* set appMetadata entity to the platform cache
* @param appMetadata
*/
setAppMetadata(appMetadata: AppMetadataEntity): void;
/**
* fetch server telemetry entity from the platform cache
* @param serverTelemetryKey
*/
getServerTelemetry(serverTelemetryKey: string): ServerTelemetryEntity | null;
/**
* set server telemetry entity to the platform cache
* @param serverTelemetryKey
* @param serverTelemetry
*/
setServerTelemetry(serverTelemetryKey: string, serverTelemetry: ServerTelemetryEntity): void;
/**
*
*/
getAuthorityMetadata(key: string): AuthorityMetadataEntity | null;
/**
*
*/
getAuthorityMetadataKeys(): Array<string>;
/**
* Sets wrapper metadata in memory
* @param wrapperSKU
* @param wrapperVersion
*/
setWrapperMetadata(wrapperSKU: string, wrapperVersion: string): void;
/**
* Returns wrapper metadata from in-memory storage
*/
getWrapperMetadata(): [string, string];
/**
*
* @param entity
*/
setAuthorityMetadata(key: string, entity: AuthorityMetadataEntity): void;
/**
* Gets the active account
*/
getActiveAccount(): AccountInfo | null;
/**
* Sets the active account's localAccountId in cache
* @param account
*/
setActiveAccount(account: AccountInfo | null): void;
/**
* fetch throttling entity from the platform cache
* @param throttlingCacheKey
*/
getThrottlingCache(throttlingCacheKey: string): ThrottlingEntity | null;
/**
* set throttling entity to the platform cache
* @param throttlingCacheKey
* @param throttlingCache
*/
setThrottlingCache(throttlingCacheKey: string, throttlingCache: ThrottlingEntity): void;
/**
* Gets cache item with given key.
* Will retrieve from cookies if storeAuthStateInCookie is set to true.
* @param key
*/
getTemporaryCache(cacheKey: string, generateKey?: boolean): string | null;
/**
* Sets the cache item with the key and value given.
* Stores in cookie if storeAuthStateInCookie is set to true.
* This can cause cookie overflow if used incorrectly.
* @param key
* @param value
*/
setTemporaryCache(cacheKey: string, value: string, generateKey?: boolean): void;
/**
* Removes the cache item with the given key.
* @param key
*/
removeItem(key: string): void;
/**
* Removes the temporary cache item with the given key.
* Will also clear the cookie item if storeAuthStateInCookie is set to true.
* @param key
*/
removeTemporaryItem(key: string): void;
/**
* Gets all keys in window.
*/
getKeys(): string[];
/**
* Clears all cache entries created by MSAL.
*/
clear(): Promise<void>;
/**
* Clears all access tokes that have claims prior to saving the current one
* @param performanceClient {IPerformanceClient}
* @param correlationId {string} correlation id
* @returns
*/
clearTokensAndKeysWithClaims(performanceClient: IPerformanceClient, correlationId: string): Promise<void>;
/**
* Prepend msal.<client-id> to each key; Skip for any JSON object as Key (defined schemas do not need the key appended: AccessToken Keys or the upcoming schema)
* @param key
* @param addInstanceId
*/
generateCacheKey(key: string): string;
/**
* Create authorityKey to cache authority
* @param state
*/
generateAuthorityKey(stateString: string): string;
/**
* Create Nonce key to cache nonce
* @param state
*/
generateNonceKey(stateString: string): string;
/**
* Creates full cache key for the request state
* @param stateString State string for the request
*/
generateStateKey(stateString: string): string;
/**
* Gets the cached authority based on the cached state. Returns empty if no cached state found.
*/
getCachedAuthority(cachedState: string): string | null;
/**
* Updates account, authority, and state in cache
* @param serverAuthenticationRequest
* @param account
*/
updateCacheEntries(state: string, nonce: string, authorityInstance: string, loginHint: string, account: AccountInfo | null): void;
/**
* Reset all temporary cache items
* @param state
*/
resetRequestCache(state: string): void;
/**
* Removes temporary cache for the provided state
* @param stateString
*/
cleanRequestByState(stateString: string): void;
/**
* Looks in temporary cache for any state values with the provided interactionType and removes all temporary cache items for that state
* Used in scenarios where temp cache needs to be cleaned but state is not known, such as clicking browser back button.
* @param interactionType
*/
cleanRequestByInteractionType(interactionType: InteractionType): void;
cacheCodeRequest(authCodeRequest: CommonAuthorizationCodeRequest): void;
/**
* Gets the token exchange parameters from the cache. Throws an error if nothing is found.
*/
getCachedRequest(state: string): CommonAuthorizationCodeRequest;
/**
* Gets cached native request for redirect flows
*/
getCachedNativeRequest(): NativeTokenRequest | null;
isInteractionInProgress(matchClientId?: boolean): boolean;
getInteractionInProgress(): string | null;
setInteractionInProgress(inProgress: boolean): void;
/**
* Builds credential entities from AuthenticationResult object and saves the resulting credentials to the cache
* @param result
* @param request
*/
hydrateCache(result: AuthenticationResult, request: SilentRequest | SsoSilentRequest | RedirectRequest | PopupRequest): Promise<void>;
/**
* saves a cache record
* @param cacheRecord {CacheRecord}
* @param storeInCache {?StoreInCache}
* @param correlationId {?string} correlation id
*/
saveCacheRecord(cacheRecord: CacheRecord, correlationId: string, storeInCache?: StoreInCache): Promise<void>;
}
export declare const DEFAULT_BROWSER_CACHE_MANAGER: (clientId: string, logger: Logger, performanceClient: IPerformanceClient, eventHandler: EventHandler) => BrowserCacheManager;
//# sourceMappingURL=BrowserCacheManager.d.ts.map

File diff suppressed because one or more lines are too long

View File

@@ -0,0 +1,991 @@
/*! @azure/msal-browser v4.2.1 2025-02-11 */
'use strict';
import { CacheManager, AccountEntity, invokeAsync, PerformanceEvents, CredentialType, createClientAuthError, ClientAuthErrorCodes, CacheHelpers, Constants, PersistentCacheKeys, StringUtils, ProtocolUtils, CacheError, DEFAULT_CRYPTO_IMPLEMENTATION, CcsCredentialType } from '@azure/msal-common/browser';
import { createBrowserAuthError } from '../error/BrowserAuthError.mjs';
import { BrowserCacheLocation, StaticCacheKeys, InMemoryCacheKeys, TemporaryCacheKeys } from '../utils/BrowserConstants.mjs';
import { LocalStorage } from './LocalStorage.mjs';
import { SessionStorage } from './SessionStorage.mjs';
import { MemoryStorage } from './MemoryStorage.mjs';
import { extractBrowserRequestState } from '../utils/BrowserProtocolUtils.mjs';
import { base64Decode } from '../encode/Base64Decode.mjs';
import { base64Encode } from '../encode/Base64Encode.mjs';
import { CookieStorage } from './CookieStorage.mjs';
import { getAccountKeys, getTokenKeys } from './CacheHelpers.mjs';
import { EventType } from '../event/EventType.mjs';
import { noTokenRequestCacheError, unableToParseTokenRequestCacheError, noCachedAuthorityError, interactionInProgress } from '../error/BrowserAuthErrorCodes.mjs';
/*
* Copyright (c) Microsoft Corporation. All rights reserved.
* Licensed under the MIT License.
*/
/**
* This class implements the cache storage interface for MSAL through browser local or session storage.
* Cookies are only used if storeAuthStateInCookie is true, and are only used for
* parameters such as state and nonce, generally.
*/
class BrowserCacheManager extends CacheManager {
constructor(clientId, cacheConfig, cryptoImpl, logger, performanceClient, eventHandler, staticAuthorityOptions) {
super(clientId, cryptoImpl, logger, staticAuthorityOptions);
this.cacheConfig = cacheConfig;
this.logger = logger;
this.internalStorage = new MemoryStorage();
this.browserStorage = getStorageImplementation(clientId, cacheConfig.cacheLocation, logger, performanceClient);
this.temporaryCacheStorage = getStorageImplementation(clientId, cacheConfig.temporaryCacheLocation, logger, performanceClient);
this.cookieStorage = new CookieStorage();
this.performanceClient = performanceClient;
this.eventHandler = eventHandler;
}
async initialize(correlationId) {
await this.browserStorage.initialize(correlationId);
}
/**
* Parses passed value as JSON object, JSON.parse() will throw an error.
* @param input
*/
validateAndParseJson(jsonValue) {
try {
const parsedJson = JSON.parse(jsonValue);
/**
* There are edge cases in which JSON.parse will successfully parse a non-valid JSON object
* (e.g. JSON.parse will parse an escaped string into an unescaped string), so adding a type check
* of the parsed value is necessary in order to be certain that the string represents a valid JSON object.
*
*/
return parsedJson && typeof parsedJson === "object"
? parsedJson
: null;
}
catch (error) {
return null;
}
}
/**
* Reads account from cache, deserializes it into an account entity and returns it.
* If account is not found from the key, returns null and removes key from map.
* @param accountKey
* @returns
*/
getAccount(accountKey) {
this.logger.trace("BrowserCacheManager.getAccount called");
const serializedAccount = this.browserStorage.getUserData(accountKey);
if (!serializedAccount) {
this.removeAccountKeyFromMap(accountKey);
return null;
}
const parsedAccount = this.validateAndParseJson(serializedAccount);
if (!parsedAccount || !AccountEntity.isAccountEntity(parsedAccount)) {
this.removeAccountKeyFromMap(accountKey);
return null;
}
return CacheManager.toObject(new AccountEntity(), parsedAccount);
}
/**
* set account entity in the platform cache
* @param account
*/
async setAccount(account, correlationId) {
this.logger.trace("BrowserCacheManager.setAccount called");
const key = account.generateAccountKey();
await invokeAsync(this.browserStorage.setUserData.bind(this.browserStorage), PerformanceEvents.SetUserData, this.logger, this.performanceClient)(key, JSON.stringify(account), correlationId);
const wasAdded = this.addAccountKeyToMap(key);
/**
* @deprecated - Remove this in next major version in favor of more consistent LOGIN event
*/
if (this.cacheConfig.cacheLocation ===
BrowserCacheLocation.LocalStorage &&
wasAdded) {
this.eventHandler.emitEvent(EventType.ACCOUNT_ADDED, undefined, account.getAccountInfo());
}
}
/**
* Returns the array of account keys currently cached
* @returns
*/
getAccountKeys() {
return getAccountKeys(this.browserStorage);
}
/**
* Add a new account to the key map
* @param key
*/
addAccountKeyToMap(key) {
this.logger.trace("BrowserCacheManager.addAccountKeyToMap called");
this.logger.tracePii(`BrowserCacheManager.addAccountKeyToMap called with key: ${key}`);
const accountKeys = this.getAccountKeys();
if (accountKeys.indexOf(key) === -1) {
// Only add key if it does not already exist in the map
accountKeys.push(key);
this.browserStorage.setItem(StaticCacheKeys.ACCOUNT_KEYS, JSON.stringify(accountKeys));
this.logger.verbose("BrowserCacheManager.addAccountKeyToMap account key added");
return true;
}
else {
this.logger.verbose("BrowserCacheManager.addAccountKeyToMap account key already exists in map");
return false;
}
}
/**
* Remove an account from the key map
* @param key
*/
removeAccountKeyFromMap(key) {
this.logger.trace("BrowserCacheManager.removeAccountKeyFromMap called");
this.logger.tracePii(`BrowserCacheManager.removeAccountKeyFromMap called with key: ${key}`);
const accountKeys = this.getAccountKeys();
const removalIndex = accountKeys.indexOf(key);
if (removalIndex > -1) {
accountKeys.splice(removalIndex, 1);
this.browserStorage.setItem(StaticCacheKeys.ACCOUNT_KEYS, JSON.stringify(accountKeys));
this.logger.trace("BrowserCacheManager.removeAccountKeyFromMap account key removed");
}
else {
this.logger.trace("BrowserCacheManager.removeAccountKeyFromMap key not found in existing map");
}
}
/**
* Extends inherited removeAccount function to include removal of the account key from the map
* @param key
*/
async removeAccount(key) {
void super.removeAccount(key);
this.removeAccountKeyFromMap(key);
}
/**
* Removes credentials associated with the provided account
* @param account
*/
async removeAccountContext(account) {
await super.removeAccountContext(account);
/**
* @deprecated - Remove this in next major version in favor of more consistent LOGOUT event
*/
if (this.cacheConfig.cacheLocation === BrowserCacheLocation.LocalStorage) {
this.eventHandler.emitEvent(EventType.ACCOUNT_REMOVED, undefined, account.getAccountInfo());
}
}
/**
* Removes given idToken from the cache and from the key map
* @param key
*/
removeIdToken(key) {
super.removeIdToken(key);
this.removeTokenKey(key, CredentialType.ID_TOKEN);
}
/**
* Removes given accessToken from the cache and from the key map
* @param key
*/
async removeAccessToken(key) {
void super.removeAccessToken(key);
this.removeTokenKey(key, CredentialType.ACCESS_TOKEN);
}
/**
* Removes given refreshToken from the cache and from the key map
* @param key
*/
removeRefreshToken(key) {
super.removeRefreshToken(key);
this.removeTokenKey(key, CredentialType.REFRESH_TOKEN);
}
/**
* Gets the keys for the cached tokens associated with this clientId
* @returns
*/
getTokenKeys() {
return getTokenKeys(this.clientId, this.browserStorage);
}
/**
* Adds the given key to the token key map
* @param key
* @param type
*/
addTokenKey(key, type) {
this.logger.trace("BrowserCacheManager addTokenKey called");
const tokenKeys = this.getTokenKeys();
switch (type) {
case CredentialType.ID_TOKEN:
if (tokenKeys.idToken.indexOf(key) === -1) {
this.logger.info("BrowserCacheManager: addTokenKey - idToken added to map");
tokenKeys.idToken.push(key);
}
break;
case CredentialType.ACCESS_TOKEN:
if (tokenKeys.accessToken.indexOf(key) === -1) {
this.logger.info("BrowserCacheManager: addTokenKey - accessToken added to map");
tokenKeys.accessToken.push(key);
}
break;
case CredentialType.REFRESH_TOKEN:
if (tokenKeys.refreshToken.indexOf(key) === -1) {
this.logger.info("BrowserCacheManager: addTokenKey - refreshToken added to map");
tokenKeys.refreshToken.push(key);
}
break;
default:
this.logger.error(`BrowserCacheManager:addTokenKey - CredentialType provided invalid. CredentialType: ${type}`);
throw createClientAuthError(ClientAuthErrorCodes.unexpectedCredentialType);
}
this.browserStorage.setItem(`${StaticCacheKeys.TOKEN_KEYS}.${this.clientId}`, JSON.stringify(tokenKeys));
}
/**
* Removes the given key from the token key map
* @param key
* @param type
*/
removeTokenKey(key, type) {
this.logger.trace("BrowserCacheManager removeTokenKey called");
const tokenKeys = this.getTokenKeys();
switch (type) {
case CredentialType.ID_TOKEN:
this.logger.infoPii(`BrowserCacheManager: removeTokenKey - attempting to remove idToken with key: ${key} from map`);
const idRemoval = tokenKeys.idToken.indexOf(key);
if (idRemoval > -1) {
this.logger.info("BrowserCacheManager: removeTokenKey - idToken removed from map");
tokenKeys.idToken.splice(idRemoval, 1);
}
else {
this.logger.info("BrowserCacheManager: removeTokenKey - idToken does not exist in map. Either it was previously removed or it was never added.");
}
break;
case CredentialType.ACCESS_TOKEN:
this.logger.infoPii(`BrowserCacheManager: removeTokenKey - attempting to remove accessToken with key: ${key} from map`);
const accessRemoval = tokenKeys.accessToken.indexOf(key);
if (accessRemoval > -1) {
this.logger.info("BrowserCacheManager: removeTokenKey - accessToken removed from map");
tokenKeys.accessToken.splice(accessRemoval, 1);
}
else {
this.logger.info("BrowserCacheManager: removeTokenKey - accessToken does not exist in map. Either it was previously removed or it was never added.");
}
break;
case CredentialType.REFRESH_TOKEN:
this.logger.infoPii(`BrowserCacheManager: removeTokenKey - attempting to remove refreshToken with key: ${key} from map`);
const refreshRemoval = tokenKeys.refreshToken.indexOf(key);
if (refreshRemoval > -1) {
this.logger.info("BrowserCacheManager: removeTokenKey - refreshToken removed from map");
tokenKeys.refreshToken.splice(refreshRemoval, 1);
}
else {
this.logger.info("BrowserCacheManager: removeTokenKey - refreshToken does not exist in map. Either it was previously removed or it was never added.");
}
break;
default:
this.logger.error(`BrowserCacheManager:removeTokenKey - CredentialType provided invalid. CredentialType: ${type}`);
throw createClientAuthError(ClientAuthErrorCodes.unexpectedCredentialType);
}
this.browserStorage.setItem(`${StaticCacheKeys.TOKEN_KEYS}.${this.clientId}`, JSON.stringify(tokenKeys));
}
/**
* generates idToken entity from a string
* @param idTokenKey
*/
getIdTokenCredential(idTokenKey) {
const value = this.browserStorage.getUserData(idTokenKey);
if (!value) {
this.logger.trace("BrowserCacheManager.getIdTokenCredential: called, no cache hit");
this.removeTokenKey(idTokenKey, CredentialType.ID_TOKEN);
return null;
}
const parsedIdToken = this.validateAndParseJson(value);
if (!parsedIdToken || !CacheHelpers.isIdTokenEntity(parsedIdToken)) {
this.logger.trace("BrowserCacheManager.getIdTokenCredential: called, no cache hit");
this.removeTokenKey(idTokenKey, CredentialType.ID_TOKEN);
return null;
}
this.logger.trace("BrowserCacheManager.getIdTokenCredential: cache hit");
return parsedIdToken;
}
/**
* set IdToken credential to the platform cache
* @param idToken
*/
async setIdTokenCredential(idToken, correlationId) {
this.logger.trace("BrowserCacheManager.setIdTokenCredential called");
const idTokenKey = CacheHelpers.generateCredentialKey(idToken);
await invokeAsync(this.browserStorage.setUserData.bind(this.browserStorage), PerformanceEvents.SetUserData, this.logger, this.performanceClient)(idTokenKey, JSON.stringify(idToken), correlationId);
this.addTokenKey(idTokenKey, CredentialType.ID_TOKEN);
}
/**
* generates accessToken entity from a string
* @param key
*/
getAccessTokenCredential(accessTokenKey) {
const value = this.browserStorage.getUserData(accessTokenKey);
if (!value) {
this.logger.trace("BrowserCacheManager.getAccessTokenCredential: called, no cache hit");
this.removeTokenKey(accessTokenKey, CredentialType.ACCESS_TOKEN);
return null;
}
const parsedAccessToken = this.validateAndParseJson(value);
if (!parsedAccessToken ||
!CacheHelpers.isAccessTokenEntity(parsedAccessToken)) {
this.logger.trace("BrowserCacheManager.getAccessTokenCredential: called, no cache hit");
this.removeTokenKey(accessTokenKey, CredentialType.ACCESS_TOKEN);
return null;
}
this.logger.trace("BrowserCacheManager.getAccessTokenCredential: cache hit");
return parsedAccessToken;
}
/**
* set accessToken credential to the platform cache
* @param accessToken
*/
async setAccessTokenCredential(accessToken, correlationId) {
this.logger.trace("BrowserCacheManager.setAccessTokenCredential called");
const accessTokenKey = CacheHelpers.generateCredentialKey(accessToken);
await invokeAsync(this.browserStorage.setUserData.bind(this.browserStorage), PerformanceEvents.SetUserData, this.logger, this.performanceClient)(accessTokenKey, JSON.stringify(accessToken), correlationId);
this.addTokenKey(accessTokenKey, CredentialType.ACCESS_TOKEN);
}
/**
* generates refreshToken entity from a string
* @param refreshTokenKey
*/
getRefreshTokenCredential(refreshTokenKey) {
const value = this.browserStorage.getUserData(refreshTokenKey);
if (!value) {
this.logger.trace("BrowserCacheManager.getRefreshTokenCredential: called, no cache hit");
this.removeTokenKey(refreshTokenKey, CredentialType.REFRESH_TOKEN);
return null;
}
const parsedRefreshToken = this.validateAndParseJson(value);
if (!parsedRefreshToken ||
!CacheHelpers.isRefreshTokenEntity(parsedRefreshToken)) {
this.logger.trace("BrowserCacheManager.getRefreshTokenCredential: called, no cache hit");
this.removeTokenKey(refreshTokenKey, CredentialType.REFRESH_TOKEN);
return null;
}
this.logger.trace("BrowserCacheManager.getRefreshTokenCredential: cache hit");
return parsedRefreshToken;
}
/**
* set refreshToken credential to the platform cache
* @param refreshToken
*/
async setRefreshTokenCredential(refreshToken, correlationId) {
this.logger.trace("BrowserCacheManager.setRefreshTokenCredential called");
const refreshTokenKey = CacheHelpers.generateCredentialKey(refreshToken);
await invokeAsync(this.browserStorage.setUserData.bind(this.browserStorage), PerformanceEvents.SetUserData, this.logger, this.performanceClient)(refreshTokenKey, JSON.stringify(refreshToken), correlationId);
this.addTokenKey(refreshTokenKey, CredentialType.REFRESH_TOKEN);
}
/**
* fetch appMetadata entity from the platform cache
* @param appMetadataKey
*/
getAppMetadata(appMetadataKey) {
const value = this.browserStorage.getItem(appMetadataKey);
if (!value) {
this.logger.trace("BrowserCacheManager.getAppMetadata: called, no cache hit");
return null;
}
const parsedMetadata = this.validateAndParseJson(value);
if (!parsedMetadata ||
!CacheHelpers.isAppMetadataEntity(appMetadataKey, parsedMetadata)) {
this.logger.trace("BrowserCacheManager.getAppMetadata: called, no cache hit");
return null;
}
this.logger.trace("BrowserCacheManager.getAppMetadata: cache hit");
return parsedMetadata;
}
/**
* set appMetadata entity to the platform cache
* @param appMetadata
*/
setAppMetadata(appMetadata) {
this.logger.trace("BrowserCacheManager.setAppMetadata called");
const appMetadataKey = CacheHelpers.generateAppMetadataKey(appMetadata);
this.browserStorage.setItem(appMetadataKey, JSON.stringify(appMetadata));
}
/**
* fetch server telemetry entity from the platform cache
* @param serverTelemetryKey
*/
getServerTelemetry(serverTelemetryKey) {
const value = this.browserStorage.getItem(serverTelemetryKey);
if (!value) {
this.logger.trace("BrowserCacheManager.getServerTelemetry: called, no cache hit");
return null;
}
const parsedEntity = this.validateAndParseJson(value);
if (!parsedEntity ||
!CacheHelpers.isServerTelemetryEntity(serverTelemetryKey, parsedEntity)) {
this.logger.trace("BrowserCacheManager.getServerTelemetry: called, no cache hit");
return null;
}
this.logger.trace("BrowserCacheManager.getServerTelemetry: cache hit");
return parsedEntity;
}
/**
* set server telemetry entity to the platform cache
* @param serverTelemetryKey
* @param serverTelemetry
*/
setServerTelemetry(serverTelemetryKey, serverTelemetry) {
this.logger.trace("BrowserCacheManager.setServerTelemetry called");
this.browserStorage.setItem(serverTelemetryKey, JSON.stringify(serverTelemetry));
}
/**
*
*/
getAuthorityMetadata(key) {
const value = this.internalStorage.getItem(key);
if (!value) {
this.logger.trace("BrowserCacheManager.getAuthorityMetadata: called, no cache hit");
return null;
}
const parsedMetadata = this.validateAndParseJson(value);
if (parsedMetadata &&
CacheHelpers.isAuthorityMetadataEntity(key, parsedMetadata)) {
this.logger.trace("BrowserCacheManager.getAuthorityMetadata: cache hit");
return parsedMetadata;
}
return null;
}
/**
*
*/
getAuthorityMetadataKeys() {
const allKeys = this.internalStorage.getKeys();
return allKeys.filter((key) => {
return this.isAuthorityMetadata(key);
});
}
/**
* Sets wrapper metadata in memory
* @param wrapperSKU
* @param wrapperVersion
*/
setWrapperMetadata(wrapperSKU, wrapperVersion) {
this.internalStorage.setItem(InMemoryCacheKeys.WRAPPER_SKU, wrapperSKU);
this.internalStorage.setItem(InMemoryCacheKeys.WRAPPER_VER, wrapperVersion);
}
/**
* Returns wrapper metadata from in-memory storage
*/
getWrapperMetadata() {
const sku = this.internalStorage.getItem(InMemoryCacheKeys.WRAPPER_SKU) ||
Constants.EMPTY_STRING;
const version = this.internalStorage.getItem(InMemoryCacheKeys.WRAPPER_VER) ||
Constants.EMPTY_STRING;
return [sku, version];
}
/**
*
* @param entity
*/
setAuthorityMetadata(key, entity) {
this.logger.trace("BrowserCacheManager.setAuthorityMetadata called");
this.internalStorage.setItem(key, JSON.stringify(entity));
}
/**
* Gets the active account
*/
getActiveAccount() {
const activeAccountKeyFilters = this.generateCacheKey(PersistentCacheKeys.ACTIVE_ACCOUNT_FILTERS);
const activeAccountValueFilters = this.browserStorage.getItem(activeAccountKeyFilters);
if (!activeAccountValueFilters) {
this.logger.trace("BrowserCacheManager.getActiveAccount: No active account filters found");
return null;
}
const activeAccountValueObj = this.validateAndParseJson(activeAccountValueFilters);
if (activeAccountValueObj) {
this.logger.trace("BrowserCacheManager.getActiveAccount: Active account filters schema found");
return this.getAccountInfoFilteredBy({
homeAccountId: activeAccountValueObj.homeAccountId,
localAccountId: activeAccountValueObj.localAccountId,
tenantId: activeAccountValueObj.tenantId,
});
}
this.logger.trace("BrowserCacheManager.getActiveAccount: No active account found");
return null;
}
/**
* Sets the active account's localAccountId in cache
* @param account
*/
setActiveAccount(account) {
const activeAccountKey = this.generateCacheKey(PersistentCacheKeys.ACTIVE_ACCOUNT_FILTERS);
if (account) {
this.logger.verbose("setActiveAccount: Active account set");
const activeAccountValue = {
homeAccountId: account.homeAccountId,
localAccountId: account.localAccountId,
tenantId: account.tenantId,
};
this.browserStorage.setItem(activeAccountKey, JSON.stringify(activeAccountValue));
}
else {
this.logger.verbose("setActiveAccount: No account passed, active account not set");
this.browserStorage.removeItem(activeAccountKey);
}
this.eventHandler.emitEvent(EventType.ACTIVE_ACCOUNT_CHANGED);
}
/**
* fetch throttling entity from the platform cache
* @param throttlingCacheKey
*/
getThrottlingCache(throttlingCacheKey) {
const value = this.browserStorage.getItem(throttlingCacheKey);
if (!value) {
this.logger.trace("BrowserCacheManager.getThrottlingCache: called, no cache hit");
return null;
}
const parsedThrottlingCache = this.validateAndParseJson(value);
if (!parsedThrottlingCache ||
!CacheHelpers.isThrottlingEntity(throttlingCacheKey, parsedThrottlingCache)) {
this.logger.trace("BrowserCacheManager.getThrottlingCache: called, no cache hit");
return null;
}
this.logger.trace("BrowserCacheManager.getThrottlingCache: cache hit");
return parsedThrottlingCache;
}
/**
* set throttling entity to the platform cache
* @param throttlingCacheKey
* @param throttlingCache
*/
setThrottlingCache(throttlingCacheKey, throttlingCache) {
this.logger.trace("BrowserCacheManager.setThrottlingCache called");
this.browserStorage.setItem(throttlingCacheKey, JSON.stringify(throttlingCache));
}
/**
* Gets cache item with given key.
* Will retrieve from cookies if storeAuthStateInCookie is set to true.
* @param key
*/
getTemporaryCache(cacheKey, generateKey) {
const key = generateKey ? this.generateCacheKey(cacheKey) : cacheKey;
if (this.cacheConfig.storeAuthStateInCookie) {
const itemCookie = this.cookieStorage.getItem(key);
if (itemCookie) {
this.logger.trace("BrowserCacheManager.getTemporaryCache: storeAuthStateInCookies set to true, retrieving from cookies");
return itemCookie;
}
}
const value = this.temporaryCacheStorage.getItem(key);
if (!value) {
// If temp cache item not found in session/memory, check local storage for items set by old versions
if (this.cacheConfig.cacheLocation ===
BrowserCacheLocation.LocalStorage) {
const item = this.browserStorage.getItem(key);
if (item) {
this.logger.trace("BrowserCacheManager.getTemporaryCache: Temporary cache item found in local storage");
return item;
}
}
this.logger.trace("BrowserCacheManager.getTemporaryCache: No cache item found in local storage");
return null;
}
this.logger.trace("BrowserCacheManager.getTemporaryCache: Temporary cache item returned");
return value;
}
/**
* Sets the cache item with the key and value given.
* Stores in cookie if storeAuthStateInCookie is set to true.
* This can cause cookie overflow if used incorrectly.
* @param key
* @param value
*/
setTemporaryCache(cacheKey, value, generateKey) {
const key = generateKey ? this.generateCacheKey(cacheKey) : cacheKey;
this.temporaryCacheStorage.setItem(key, value);
if (this.cacheConfig.storeAuthStateInCookie) {
this.logger.trace("BrowserCacheManager.setTemporaryCache: storeAuthStateInCookie set to true, setting item cookie");
this.cookieStorage.setItem(key, value, undefined, this.cacheConfig.secureCookies);
}
}
/**
* Removes the cache item with the given key.
* @param key
*/
removeItem(key) {
this.browserStorage.removeItem(key);
}
/**
* Removes the temporary cache item with the given key.
* Will also clear the cookie item if storeAuthStateInCookie is set to true.
* @param key
*/
removeTemporaryItem(key) {
this.temporaryCacheStorage.removeItem(key);
if (this.cacheConfig.storeAuthStateInCookie) {
this.logger.trace("BrowserCacheManager.removeItem: storeAuthStateInCookie is true, clearing item cookie");
this.cookieStorage.removeItem(key);
}
}
/**
* Gets all keys in window.
*/
getKeys() {
return this.browserStorage.getKeys();
}
/**
* Clears all cache entries created by MSAL.
*/
async clear() {
// Removes all accounts and their credentials
await this.removeAllAccounts();
this.removeAppMetadata();
// Remove temp storage first to make sure any cookies are cleared
this.temporaryCacheStorage.getKeys().forEach((cacheKey) => {
if (cacheKey.indexOf(Constants.CACHE_PREFIX) !== -1 ||
cacheKey.indexOf(this.clientId) !== -1) {
this.removeTemporaryItem(cacheKey);
}
});
// Removes all remaining MSAL cache items
this.browserStorage.getKeys().forEach((cacheKey) => {
if (cacheKey.indexOf(Constants.CACHE_PREFIX) !== -1 ||
cacheKey.indexOf(this.clientId) !== -1) {
this.browserStorage.removeItem(cacheKey);
}
});
this.internalStorage.clear();
}
/**
* Clears all access tokes that have claims prior to saving the current one
* @param performanceClient {IPerformanceClient}
* @param correlationId {string} correlation id
* @returns
*/
async clearTokensAndKeysWithClaims(performanceClient, correlationId) {
performanceClient.addQueueMeasurement(PerformanceEvents.ClearTokensAndKeysWithClaims, correlationId);
const tokenKeys = this.getTokenKeys();
const removedAccessTokens = [];
tokenKeys.accessToken.forEach((key) => {
// if the access token has claims in its key, remove the token key and the token
const credential = this.getAccessTokenCredential(key);
if (credential?.requestedClaimsHash &&
key.includes(credential.requestedClaimsHash.toLowerCase())) {
removedAccessTokens.push(this.removeAccessToken(key));
}
});
await Promise.all(removedAccessTokens);
// warn if any access tokens are removed
if (removedAccessTokens.length > 0) {
this.logger.warning(`${removedAccessTokens.length} access tokens with claims in the cache keys have been removed from the cache.`);
}
}
/**
* Prepend msal.<client-id> to each key; Skip for any JSON object as Key (defined schemas do not need the key appended: AccessToken Keys or the upcoming schema)
* @param key
* @param addInstanceId
*/
generateCacheKey(key) {
const generatedKey = this.validateAndParseJson(key);
if (!generatedKey) {
if (StringUtils.startsWith(key, Constants.CACHE_PREFIX)) {
return key;
}
return `${Constants.CACHE_PREFIX}.${this.clientId}.${key}`;
}
return JSON.stringify(key);
}
/**
* Create authorityKey to cache authority
* @param state
*/
generateAuthorityKey(stateString) {
const { libraryState: { id: stateId }, } = ProtocolUtils.parseRequestState(this.cryptoImpl, stateString);
return this.generateCacheKey(`${TemporaryCacheKeys.AUTHORITY}.${stateId}`);
}
/**
* Create Nonce key to cache nonce
* @param state
*/
generateNonceKey(stateString) {
const { libraryState: { id: stateId }, } = ProtocolUtils.parseRequestState(this.cryptoImpl, stateString);
return this.generateCacheKey(`${TemporaryCacheKeys.NONCE_IDTOKEN}.${stateId}`);
}
/**
* Creates full cache key for the request state
* @param stateString State string for the request
*/
generateStateKey(stateString) {
// Use the library state id to key temp storage for uniqueness for multiple concurrent requests
const { libraryState: { id: stateId }, } = ProtocolUtils.parseRequestState(this.cryptoImpl, stateString);
return this.generateCacheKey(`${TemporaryCacheKeys.REQUEST_STATE}.${stateId}`);
}
/**
* Gets the cached authority based on the cached state. Returns empty if no cached state found.
*/
getCachedAuthority(cachedState) {
const stateCacheKey = this.generateStateKey(cachedState);
const state = this.getTemporaryCache(stateCacheKey);
if (!state) {
return null;
}
const authorityCacheKey = this.generateAuthorityKey(state);
return this.getTemporaryCache(authorityCacheKey);
}
/**
* Updates account, authority, and state in cache
* @param serverAuthenticationRequest
* @param account
*/
updateCacheEntries(state, nonce, authorityInstance, loginHint, account) {
this.logger.trace("BrowserCacheManager.updateCacheEntries called");
// Cache the request state
const stateCacheKey = this.generateStateKey(state);
this.setTemporaryCache(stateCacheKey, state, false);
// Cache the nonce
const nonceCacheKey = this.generateNonceKey(state);
this.setTemporaryCache(nonceCacheKey, nonce, false);
// Cache authorityKey
const authorityCacheKey = this.generateAuthorityKey(state);
this.setTemporaryCache(authorityCacheKey, authorityInstance, false);
if (account) {
const ccsCredential = {
credential: account.homeAccountId,
type: CcsCredentialType.HOME_ACCOUNT_ID,
};
this.setTemporaryCache(TemporaryCacheKeys.CCS_CREDENTIAL, JSON.stringify(ccsCredential), true);
}
else if (loginHint) {
const ccsCredential = {
credential: loginHint,
type: CcsCredentialType.UPN,
};
this.setTemporaryCache(TemporaryCacheKeys.CCS_CREDENTIAL, JSON.stringify(ccsCredential), true);
}
}
/**
* Reset all temporary cache items
* @param state
*/
resetRequestCache(state) {
this.logger.trace("BrowserCacheManager.resetRequestCache called");
// check state and remove associated cache items
if (state) {
this.temporaryCacheStorage.getKeys().forEach((key) => {
if (key.indexOf(state) !== -1) {
this.removeTemporaryItem(key);
}
});
// delete generic interactive request parameters
this.removeTemporaryItem(this.generateStateKey(state));
this.removeTemporaryItem(this.generateNonceKey(state));
this.removeTemporaryItem(this.generateAuthorityKey(state));
}
this.removeTemporaryItem(this.generateCacheKey(TemporaryCacheKeys.REQUEST_PARAMS));
this.removeTemporaryItem(this.generateCacheKey(TemporaryCacheKeys.ORIGIN_URI));
this.removeTemporaryItem(this.generateCacheKey(TemporaryCacheKeys.URL_HASH));
this.removeTemporaryItem(this.generateCacheKey(TemporaryCacheKeys.CORRELATION_ID));
this.removeTemporaryItem(this.generateCacheKey(TemporaryCacheKeys.CCS_CREDENTIAL));
this.removeTemporaryItem(this.generateCacheKey(TemporaryCacheKeys.NATIVE_REQUEST));
this.setInteractionInProgress(false);
}
/**
* Removes temporary cache for the provided state
* @param stateString
*/
cleanRequestByState(stateString) {
this.logger.trace("BrowserCacheManager.cleanRequestByState called");
// Interaction is completed - remove interaction status.
if (stateString) {
const stateKey = this.generateStateKey(stateString);
const cachedState = this.temporaryCacheStorage.getItem(stateKey);
this.logger.infoPii(`BrowserCacheManager.cleanRequestByState: Removing temporary cache items for state: ${cachedState}`);
this.resetRequestCache(cachedState || Constants.EMPTY_STRING);
}
}
/**
* Looks in temporary cache for any state values with the provided interactionType and removes all temporary cache items for that state
* Used in scenarios where temp cache needs to be cleaned but state is not known, such as clicking browser back button.
* @param interactionType
*/
cleanRequestByInteractionType(interactionType) {
this.logger.trace("BrowserCacheManager.cleanRequestByInteractionType called");
// Loop through all keys to find state key
this.temporaryCacheStorage.getKeys().forEach((key) => {
// If this key is not the state key, move on
if (key.indexOf(TemporaryCacheKeys.REQUEST_STATE) === -1) {
return;
}
// Retrieve state value, return if not a valid value
const stateValue = this.temporaryCacheStorage.getItem(key);
if (!stateValue) {
return;
}
// Extract state and ensure it matches given InteractionType, then clean request cache
const parsedState = extractBrowserRequestState(this.cryptoImpl, stateValue);
if (parsedState &&
parsedState.interactionType === interactionType) {
this.logger.infoPii(`BrowserCacheManager.cleanRequestByInteractionType: Removing temporary cache items for state: ${stateValue}`);
this.resetRequestCache(stateValue);
}
});
this.setInteractionInProgress(false);
}
cacheCodeRequest(authCodeRequest) {
this.logger.trace("BrowserCacheManager.cacheCodeRequest called");
const encodedValue = base64Encode(JSON.stringify(authCodeRequest));
this.setTemporaryCache(TemporaryCacheKeys.REQUEST_PARAMS, encodedValue, true);
}
/**
* Gets the token exchange parameters from the cache. Throws an error if nothing is found.
*/
getCachedRequest(state) {
this.logger.trace("BrowserCacheManager.getCachedRequest called");
// Get token request from cache and parse as TokenExchangeParameters.
const encodedTokenRequest = this.getTemporaryCache(TemporaryCacheKeys.REQUEST_PARAMS, true);
if (!encodedTokenRequest) {
throw createBrowserAuthError(noTokenRequestCacheError);
}
let parsedRequest;
try {
parsedRequest = JSON.parse(base64Decode(encodedTokenRequest));
}
catch (e) {
this.logger.errorPii(`Attempted to parse: ${encodedTokenRequest}`);
this.logger.error(`Parsing cached token request threw with error: ${e}`);
throw createBrowserAuthError(unableToParseTokenRequestCacheError);
}
this.removeTemporaryItem(this.generateCacheKey(TemporaryCacheKeys.REQUEST_PARAMS));
// Get cached authority and use if no authority is cached with request.
if (!parsedRequest.authority) {
const authorityCacheKey = this.generateAuthorityKey(state);
const cachedAuthority = this.getTemporaryCache(authorityCacheKey);
if (!cachedAuthority) {
throw createBrowserAuthError(noCachedAuthorityError);
}
parsedRequest.authority = cachedAuthority;
}
return parsedRequest;
}
/**
* Gets cached native request for redirect flows
*/
getCachedNativeRequest() {
this.logger.trace("BrowserCacheManager.getCachedNativeRequest called");
const cachedRequest = this.getTemporaryCache(TemporaryCacheKeys.NATIVE_REQUEST, true);
if (!cachedRequest) {
this.logger.trace("BrowserCacheManager.getCachedNativeRequest: No cached native request found");
return null;
}
const parsedRequest = this.validateAndParseJson(cachedRequest);
if (!parsedRequest) {
this.logger.error("BrowserCacheManager.getCachedNativeRequest: Unable to parse native request");
return null;
}
return parsedRequest;
}
isInteractionInProgress(matchClientId) {
const clientId = this.getInteractionInProgress();
if (matchClientId) {
return clientId === this.clientId;
}
else {
return !!clientId;
}
}
getInteractionInProgress() {
const key = `${Constants.CACHE_PREFIX}.${TemporaryCacheKeys.INTERACTION_STATUS_KEY}`;
return this.getTemporaryCache(key, false);
}
setInteractionInProgress(inProgress) {
// Ensure we don't overwrite interaction in progress for a different clientId
const key = `${Constants.CACHE_PREFIX}.${TemporaryCacheKeys.INTERACTION_STATUS_KEY}`;
if (inProgress) {
if (this.getInteractionInProgress()) {
throw createBrowserAuthError(interactionInProgress);
}
else {
// No interaction is in progress
this.setTemporaryCache(key, this.clientId, false);
}
}
else if (!inProgress &&
this.getInteractionInProgress() === this.clientId) {
this.removeTemporaryItem(key);
}
}
/**
* Builds credential entities from AuthenticationResult object and saves the resulting credentials to the cache
* @param result
* @param request
*/
async hydrateCache(result, request) {
const idTokenEntity = CacheHelpers.createIdTokenEntity(result.account?.homeAccountId, result.account?.environment, result.idToken, this.clientId, result.tenantId);
let claimsHash;
if (request.claims) {
claimsHash = await this.cryptoImpl.hashString(request.claims);
}
/**
* meta data for cache stores time in seconds from epoch
* AuthenticationResult returns expiresOn and extExpiresOn in milliseconds (as a Date object which is in ms)
* We need to map these for the cache when building tokens from AuthenticationResult
*
* The next MSAL VFuture should map these both to same value if possible
*/
const accessTokenEntity = CacheHelpers.createAccessTokenEntity(result.account?.homeAccountId, result.account.environment, result.accessToken, this.clientId, result.tenantId, result.scopes.join(" "), result.expiresOn ? result.expiresOn.getTime() / 1000 : 0, result.extExpiresOn ? result.extExpiresOn.getTime() / 1000 : 0, base64Decode, undefined, // refreshOn
result.tokenType, undefined, // userAssertionHash
request.sshKid, request.claims, claimsHash);
const cacheRecord = {
idToken: idTokenEntity,
accessToken: accessTokenEntity,
};
return this.saveCacheRecord(cacheRecord, result.correlationId);
}
/**
* saves a cache record
* @param cacheRecord {CacheRecord}
* @param storeInCache {?StoreInCache}
* @param correlationId {?string} correlation id
*/
async saveCacheRecord(cacheRecord, correlationId, storeInCache) {
try {
await super.saveCacheRecord(cacheRecord, correlationId, storeInCache);
}
catch (e) {
if (e instanceof CacheError &&
this.performanceClient &&
correlationId) {
try {
const tokenKeys = this.getTokenKeys();
this.performanceClient.addFields({
cacheRtCount: tokenKeys.refreshToken.length,
cacheIdCount: tokenKeys.idToken.length,
cacheAtCount: tokenKeys.accessToken.length,
}, correlationId);
}
catch (e) { }
}
throw e;
}
}
}
/**
* Returns a window storage class implementing the IWindowStorage interface that corresponds to the configured cacheLocation.
* @param cacheLocation
*/
function getStorageImplementation(clientId, cacheLocation, logger, performanceClient) {
try {
switch (cacheLocation) {
case BrowserCacheLocation.LocalStorage:
return new LocalStorage(clientId, logger, performanceClient);
case BrowserCacheLocation.SessionStorage:
return new SessionStorage();
case BrowserCacheLocation.MemoryStorage:
default:
break;
}
}
catch (e) {
logger.error(e);
}
return new MemoryStorage();
}
const DEFAULT_BROWSER_CACHE_MANAGER = (clientId, logger, performanceClient, eventHandler) => {
const cacheOptions = {
cacheLocation: BrowserCacheLocation.MemoryStorage,
temporaryCacheLocation: BrowserCacheLocation.MemoryStorage,
storeAuthStateInCookie: false,
secureCookies: false,
cacheMigrationEnabled: false,
claimsBasedCachingEnabled: false,
};
return new BrowserCacheManager(clientId, cacheOptions, DEFAULT_CRYPTO_IMPLEMENTATION, logger, performanceClient, eventHandler);
};
export { BrowserCacheManager, DEFAULT_BROWSER_CACHE_MANAGER };
//# sourceMappingURL=BrowserCacheManager.mjs.map

File diff suppressed because one or more lines are too long

View File

@@ -0,0 +1,16 @@
import { TokenKeys } from "@azure/msal-common/browser";
import { IWindowStorage } from "./IWindowStorage.js";
/**
* Returns a list of cache keys for all known accounts
* @param storage
* @returns
*/
export declare function getAccountKeys(storage: IWindowStorage<string>): Array<string>;
/**
* Returns a list of cache keys for all known tokens
* @param clientId
* @param storage
* @returns
*/
export declare function getTokenKeys(clientId: string, storage: IWindowStorage<string>): TokenKeys;
//# sourceMappingURL=CacheHelpers.d.ts.map

View File

@@ -0,0 +1 @@
{"version":3,"file":"CacheHelpers.d.ts","sourceRoot":"","sources":["../../src/cache/CacheHelpers.ts"],"names":[],"mappings":"AAKA,OAAO,EAAE,SAAS,EAAE,MAAM,4BAA4B,CAAC;AAEvD,OAAO,EAAE,cAAc,EAAE,MAAM,qBAAqB,CAAC;AAErD;;;;GAIG;AACH,wBAAgB,cAAc,CAAC,OAAO,EAAE,cAAc,CAAC,MAAM,CAAC,GAAG,KAAK,CAAC,MAAM,CAAC,CAO7E;AAED;;;;;GAKG;AACH,wBAAgB,YAAY,CACxB,QAAQ,EAAE,MAAM,EAChB,OAAO,EAAE,cAAc,CAAC,MAAM,CAAC,GAChC,SAAS,CAmBX"}

View File

@@ -0,0 +1,46 @@
/*! @azure/msal-browser v4.2.1 2025-02-11 */
'use strict';
import { StaticCacheKeys } from '../utils/BrowserConstants.mjs';
/*
* Copyright (c) Microsoft Corporation. All rights reserved.
* Licensed under the MIT License.
*/
/**
* Returns a list of cache keys for all known accounts
* @param storage
* @returns
*/
function getAccountKeys(storage) {
const accountKeys = storage.getItem(StaticCacheKeys.ACCOUNT_KEYS);
if (accountKeys) {
return JSON.parse(accountKeys);
}
return [];
}
/**
* Returns a list of cache keys for all known tokens
* @param clientId
* @param storage
* @returns
*/
function getTokenKeys(clientId, storage) {
const item = storage.getItem(`${StaticCacheKeys.TOKEN_KEYS}.${clientId}`);
if (item) {
const tokenKeys = JSON.parse(item);
if (tokenKeys &&
tokenKeys.hasOwnProperty("idToken") &&
tokenKeys.hasOwnProperty("accessToken") &&
tokenKeys.hasOwnProperty("refreshToken")) {
return tokenKeys;
}
}
return {
idToken: [],
accessToken: [],
refreshToken: [],
};
}
export { getAccountKeys, getTokenKeys };
//# sourceMappingURL=CacheHelpers.mjs.map

View File

@@ -0,0 +1 @@
{"version":3,"file":"CacheHelpers.mjs","sources":["../../src/cache/CacheHelpers.ts"],"sourcesContent":[null],"names":[],"mappings":";;;;AAAA;;;AAGG;AAMH;;;;AAIG;AACG,SAAU,cAAc,CAAC,OAA+B,EAAA;IAC1D,MAAM,WAAW,GAAG,OAAO,CAAC,OAAO,CAAC,eAAe,CAAC,YAAY,CAAC,CAAC;AAClE,IAAA,IAAI,WAAW,EAAE;AACb,QAAA,OAAO,IAAI,CAAC,KAAK,CAAC,WAAW,CAAC,CAAC;AAClC,KAAA;AAED,IAAA,OAAO,EAAE,CAAC;AACd,CAAC;AAED;;;;;AAKG;AACa,SAAA,YAAY,CACxB,QAAgB,EAChB,OAA+B,EAAA;AAE/B,IAAA,MAAM,IAAI,GAAG,OAAO,CAAC,OAAO,CAAC,CAAA,EAAG,eAAe,CAAC,UAAU,CAAA,CAAA,EAAI,QAAQ,CAAA,CAAE,CAAC,CAAC;AAC1E,IAAA,IAAI,IAAI,EAAE;QACN,MAAM,SAAS,GAAG,IAAI,CAAC,KAAK,CAAC,IAAI,CAAC,CAAC;AACnC,QAAA,IACI,SAAS;AACT,YAAA,SAAS,CAAC,cAAc,CAAC,SAAS,CAAC;AACnC,YAAA,SAAS,CAAC,cAAc,CAAC,aAAa,CAAC;AACvC,YAAA,SAAS,CAAC,cAAc,CAAC,cAAc,CAAC,EAC1C;AACE,YAAA,OAAO,SAAsB,CAAC;AACjC,SAAA;AACJ,KAAA;IAED,OAAO;AACH,QAAA,OAAO,EAAE,EAAE;AACX,QAAA,WAAW,EAAE,EAAE;AACf,QAAA,YAAY,EAAE,EAAE;KACnB,CAAC;AACN;;;;"}

View File

@@ -0,0 +1,22 @@
import { IWindowStorage } from "./IWindowStorage.js";
export declare const SameSiteOptions: {
readonly Lax: "Lax";
readonly None: "None";
};
export type SameSiteOptions = (typeof SameSiteOptions)[keyof typeof SameSiteOptions];
export declare class CookieStorage implements IWindowStorage<string> {
initialize(): Promise<void>;
getItem(key: string): string | null;
getUserData(): string | null;
setItem(key: string, value: string, cookieLifeDays?: number, secure?: boolean, sameSite?: SameSiteOptions): void;
setUserData(): Promise<void>;
removeItem(key: string): void;
getKeys(): string[];
containsKey(key: string): boolean;
}
/**
* Get cookie expiration time
* @param cookieLifeDays
*/
export declare function getCookieExpirationTime(cookieLifeDays: number): string;
//# sourceMappingURL=CookieStorage.d.ts.map

View File

@@ -0,0 +1 @@
{"version":3,"file":"CookieStorage.d.ts","sourceRoot":"","sources":["../../src/cache/CookieStorage.ts"],"names":[],"mappings":"AASA,OAAO,EAAE,cAAc,EAAE,MAAM,qBAAqB,CAAC;AAKrD,eAAO,MAAM,eAAe;;;CAGlB,CAAC;AACX,MAAM,MAAM,eAAe,GACvB,CAAC,OAAO,eAAe,CAAC,CAAC,MAAM,OAAO,eAAe,CAAC,CAAC;AAE3D,qBAAa,aAAc,YAAW,cAAc,CAAC,MAAM,CAAC;IACxD,UAAU,IAAI,OAAO,CAAC,IAAI,CAAC;IAI3B,OAAO,CAAC,GAAG,EAAE,MAAM,GAAG,MAAM,GAAG,IAAI;IAenC,WAAW,IAAI,MAAM,GAAG,IAAI;IAI5B,OAAO,CACH,GAAG,EAAE,MAAM,EACX,KAAK,EAAE,MAAM,EACb,cAAc,CAAC,EAAE,MAAM,EACvB,MAAM,GAAE,OAAc,EACtB,QAAQ,GAAE,eAAqC,GAChD,IAAI;IAkBD,WAAW,IAAI,OAAO,CAAC,IAAI,CAAC;IAMlC,UAAU,CAAC,GAAG,EAAE,MAAM,GAAG,IAAI;IAK7B,OAAO,IAAI,MAAM,EAAE;IAWnB,WAAW,CAAC,GAAG,EAAE,MAAM,GAAG,OAAO;CAGpC;AAED;;;GAGG;AACH,wBAAgB,uBAAuB,CAAC,cAAc,EAAE,MAAM,GAAG,MAAM,CAMtE"}

View File

@@ -0,0 +1,78 @@
/*! @azure/msal-browser v4.2.1 2025-02-11 */
'use strict';
import { createClientAuthError, ClientAuthErrorCodes } from '@azure/msal-common/browser';
/*
* Copyright (c) Microsoft Corporation. All rights reserved.
* Licensed under the MIT License.
*/
// Cookie life calculation (hours * minutes * seconds * ms)
const COOKIE_LIFE_MULTIPLIER = 24 * 60 * 60 * 1000;
const SameSiteOptions = {
Lax: "Lax",
None: "None",
};
class CookieStorage {
initialize() {
return Promise.resolve();
}
getItem(key) {
const name = `${encodeURIComponent(key)}`;
const cookieList = document.cookie.split(";");
for (let i = 0; i < cookieList.length; i++) {
const cookie = cookieList[i];
const [key, ...rest] = decodeURIComponent(cookie).trim().split("=");
const value = rest.join("=");
if (key === name) {
return value;
}
}
return "";
}
getUserData() {
throw createClientAuthError(ClientAuthErrorCodes.methodNotImplemented);
}
setItem(key, value, cookieLifeDays, secure = true, sameSite = SameSiteOptions.Lax) {
let cookieStr = `${encodeURIComponent(key)}=${encodeURIComponent(value)};path=/;SameSite=${sameSite};`;
if (cookieLifeDays) {
const expireTime = getCookieExpirationTime(cookieLifeDays);
cookieStr += `expires=${expireTime};`;
}
if (secure || sameSite === SameSiteOptions.None) {
// SameSite None requires Secure flag
cookieStr += "Secure;";
}
document.cookie = cookieStr;
}
async setUserData() {
return Promise.reject(createClientAuthError(ClientAuthErrorCodes.methodNotImplemented));
}
removeItem(key) {
// Setting expiration to -1 removes it
this.setItem(key, "", -1);
}
getKeys() {
const cookieList = document.cookie.split(";");
const keys = [];
cookieList.forEach((cookie) => {
const cookieParts = decodeURIComponent(cookie).trim().split("=");
keys.push(cookieParts[0]);
});
return keys;
}
containsKey(key) {
return this.getKeys().includes(key);
}
}
/**
* Get cookie expiration time
* @param cookieLifeDays
*/
function getCookieExpirationTime(cookieLifeDays) {
const today = new Date();
const expr = new Date(today.getTime() + cookieLifeDays * COOKIE_LIFE_MULTIPLIER);
return expr.toUTCString();
}
export { CookieStorage, SameSiteOptions, getCookieExpirationTime };
//# sourceMappingURL=CookieStorage.mjs.map

View File

@@ -0,0 +1 @@
{"version":3,"file":"CookieStorage.mjs","sources":["../../src/cache/CookieStorage.ts"],"sourcesContent":[null],"names":[],"mappings":"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"}

View File

@@ -0,0 +1,57 @@
import { IAsyncStorage } from "./IAsyncStorage.js";
/**
* Storage wrapper for IndexedDB storage in browsers: https://developer.mozilla.org/en-US/docs/Web/API/IndexedDB_API
*/
export declare class DatabaseStorage<T> implements IAsyncStorage<T> {
private db;
private dbName;
private tableName;
private version;
private dbOpen;
constructor();
/**
* Opens IndexedDB instance.
*/
open(): Promise<void>;
/**
* Closes the connection to IndexedDB database when all pending transactions
* complete.
*/
closeConnection(): void;
/**
* Opens database if it's not already open
*/
private validateDbIsOpen;
/**
* Retrieves item from IndexedDB instance.
* @param key
*/
getItem(key: string): Promise<T | null>;
/**
* Adds item to IndexedDB under given key
* @param key
* @param payload
*/
setItem(key: string, payload: T): Promise<void>;
/**
* Removes item from IndexedDB under given key
* @param key
*/
removeItem(key: string): Promise<void>;
/**
* Get all the keys from the storage object as an iterable array of strings.
*/
getKeys(): Promise<string[]>;
/**
*
* Checks whether there is an object under the search key in the object store
*/
containsKey(key: string): Promise<boolean>;
/**
* Deletes the MSAL database. The database is deleted rather than cleared to make it possible
* for client applications to downgrade to a previous MSAL version without worrying about forward compatibility issues
* with IndexedDB database versions.
*/
deleteDatabase(): Promise<boolean>;
}
//# sourceMappingURL=DatabaseStorage.d.ts.map

View File

@@ -0,0 +1 @@
{"version":3,"file":"DatabaseStorage.d.ts","sourceRoot":"","sources":["../../src/cache/DatabaseStorage.ts"],"names":[],"mappings":"AAcA,OAAO,EAAE,aAAa,EAAE,MAAM,oBAAoB,CAAC;AAcnD;;GAEG;AACH,qBAAa,eAAe,CAAC,CAAC,CAAE,YAAW,aAAa,CAAC,CAAC,CAAC;IACvD,OAAO,CAAC,EAAE,CAA0B;IACpC,OAAO,CAAC,MAAM,CAAS;IACvB,OAAO,CAAC,SAAS,CAAS;IAC1B,OAAO,CAAC,OAAO,CAAS;IACxB,OAAO,CAAC,MAAM,CAAU;;IASxB;;OAEG;IACG,IAAI,IAAI,OAAO,CAAC,IAAI,CAAC;IA0B3B;;;OAGG;IACH,eAAe,IAAI,IAAI;IAQvB;;OAEG;YACW,gBAAgB;IAM9B;;;OAGG;IACG,OAAO,CAAC,GAAG,EAAE,MAAM,GAAG,OAAO,CAAC,CAAC,GAAG,IAAI,CAAC;IA+B7C;;;;OAIG;IACG,OAAO,CAAC,GAAG,EAAE,MAAM,EAAE,OAAO,EAAE,CAAC,GAAG,OAAO,CAAC,IAAI,CAAC;IAgCrD;;;OAGG;IACG,UAAU,CAAC,GAAG,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC;IA8B5C;;OAEG;IACG,OAAO,IAAI,OAAO,CAAC,MAAM,EAAE,CAAC;IA+BlC;;;OAGG;IACG,WAAW,CAAC,GAAG,EAAE,MAAM,GAAG,OAAO,CAAC,OAAO,CAAC;IAgChD;;;;OAIG;IACG,cAAc,IAAI,OAAO,CAAC,OAAO,CAAC;CAwB3C"}

View File

@@ -0,0 +1,209 @@
/*! @azure/msal-browser v4.2.1 2025-02-11 */
'use strict';
import { createBrowserAuthError } from '../error/BrowserAuthError.mjs';
import { DB_NAME, DB_VERSION, DB_TABLE_NAME } from '../utils/BrowserConstants.mjs';
import { databaseUnavailable, databaseNotOpen } from '../error/BrowserAuthErrorCodes.mjs';
/*
* Copyright (c) Microsoft Corporation. All rights reserved.
* Licensed under the MIT License.
*/
/**
* Storage wrapper for IndexedDB storage in browsers: https://developer.mozilla.org/en-US/docs/Web/API/IndexedDB_API
*/
class DatabaseStorage {
constructor() {
this.dbName = DB_NAME;
this.version = DB_VERSION;
this.tableName = DB_TABLE_NAME;
this.dbOpen = false;
}
/**
* Opens IndexedDB instance.
*/
async open() {
return new Promise((resolve, reject) => {
const openDB = window.indexedDB.open(this.dbName, this.version);
openDB.addEventListener("upgradeneeded", (e) => {
const event = e;
event.target.result.createObjectStore(this.tableName);
});
openDB.addEventListener("success", (e) => {
const event = e;
this.db = event.target.result;
this.dbOpen = true;
resolve();
});
openDB.addEventListener("error", () => reject(createBrowserAuthError(databaseUnavailable)));
});
}
/**
* Closes the connection to IndexedDB database when all pending transactions
* complete.
*/
closeConnection() {
const db = this.db;
if (db && this.dbOpen) {
db.close();
this.dbOpen = false;
}
}
/**
* Opens database if it's not already open
*/
async validateDbIsOpen() {
if (!this.dbOpen) {
return this.open();
}
}
/**
* Retrieves item from IndexedDB instance.
* @param key
*/
async getItem(key) {
await this.validateDbIsOpen();
return new Promise((resolve, reject) => {
// TODO: Add timeouts?
if (!this.db) {
return reject(createBrowserAuthError(databaseNotOpen));
}
const transaction = this.db.transaction([this.tableName], "readonly");
const objectStore = transaction.objectStore(this.tableName);
const dbGet = objectStore.get(key);
dbGet.addEventListener("success", (e) => {
const event = e;
this.closeConnection();
resolve(event.target.result);
});
dbGet.addEventListener("error", (e) => {
this.closeConnection();
reject(e);
});
});
}
/**
* Adds item to IndexedDB under given key
* @param key
* @param payload
*/
async setItem(key, payload) {
await this.validateDbIsOpen();
return new Promise((resolve, reject) => {
// TODO: Add timeouts?
if (!this.db) {
return reject(createBrowserAuthError(databaseNotOpen));
}
const transaction = this.db.transaction([this.tableName], "readwrite");
const objectStore = transaction.objectStore(this.tableName);
const dbPut = objectStore.put(payload, key);
dbPut.addEventListener("success", () => {
this.closeConnection();
resolve();
});
dbPut.addEventListener("error", (e) => {
this.closeConnection();
reject(e);
});
});
}
/**
* Removes item from IndexedDB under given key
* @param key
*/
async removeItem(key) {
await this.validateDbIsOpen();
return new Promise((resolve, reject) => {
if (!this.db) {
return reject(createBrowserAuthError(databaseNotOpen));
}
const transaction = this.db.transaction([this.tableName], "readwrite");
const objectStore = transaction.objectStore(this.tableName);
const dbDelete = objectStore.delete(key);
dbDelete.addEventListener("success", () => {
this.closeConnection();
resolve();
});
dbDelete.addEventListener("error", (e) => {
this.closeConnection();
reject(e);
});
});
}
/**
* Get all the keys from the storage object as an iterable array of strings.
*/
async getKeys() {
await this.validateDbIsOpen();
return new Promise((resolve, reject) => {
if (!this.db) {
return reject(createBrowserAuthError(databaseNotOpen));
}
const transaction = this.db.transaction([this.tableName], "readonly");
const objectStore = transaction.objectStore(this.tableName);
const dbGetKeys = objectStore.getAllKeys();
dbGetKeys.addEventListener("success", (e) => {
const event = e;
this.closeConnection();
resolve(event.target.result);
});
dbGetKeys.addEventListener("error", (e) => {
this.closeConnection();
reject(e);
});
});
}
/**
*
* Checks whether there is an object under the search key in the object store
*/
async containsKey(key) {
await this.validateDbIsOpen();
return new Promise((resolve, reject) => {
if (!this.db) {
return reject(createBrowserAuthError(databaseNotOpen));
}
const transaction = this.db.transaction([this.tableName], "readonly");
const objectStore = transaction.objectStore(this.tableName);
const dbContainsKey = objectStore.count(key);
dbContainsKey.addEventListener("success", (e) => {
const event = e;
this.closeConnection();
resolve(event.target.result === 1);
});
dbContainsKey.addEventListener("error", (e) => {
this.closeConnection();
reject(e);
});
});
}
/**
* Deletes the MSAL database. The database is deleted rather than cleared to make it possible
* for client applications to downgrade to a previous MSAL version without worrying about forward compatibility issues
* with IndexedDB database versions.
*/
async deleteDatabase() {
// Check if database being deleted exists
if (this.db && this.dbOpen) {
this.closeConnection();
}
return new Promise((resolve, reject) => {
const deleteDbRequest = window.indexedDB.deleteDatabase(DB_NAME);
const id = setTimeout(() => reject(false), 200); // Reject if events aren't raised within 200ms
deleteDbRequest.addEventListener("success", () => {
clearTimeout(id);
return resolve(true);
});
deleteDbRequest.addEventListener("blocked", () => {
clearTimeout(id);
return resolve(true);
});
deleteDbRequest.addEventListener("error", () => {
clearTimeout(id);
return reject(false);
});
});
}
}
export { DatabaseStorage };
//# sourceMappingURL=DatabaseStorage.mjs.map

File diff suppressed because one or more lines are too long

View File

@@ -0,0 +1,28 @@
export interface IAsyncStorage<T> {
/**
* Get the item from the asynchronous storage object matching the given key.
* @param key
*/
getItem(key: string): Promise<T | null>;
/**
* Sets the item in the asynchronous storage object with the given key.
* @param key
* @param value
*/
setItem(key: string, value: T): Promise<void>;
/**
* Removes the item in the asynchronous storage object matching the given key.
* @param key
*/
removeItem(key: string): Promise<void>;
/**
* Get all the keys from the asynchronous storage object as an iterable array of strings.
*/
getKeys(): Promise<string[]>;
/**
* Returns true or false if the given key is present in the cache.
* @param key
*/
containsKey(key: string): Promise<boolean>;
}
//# sourceMappingURL=IAsyncStorage.d.ts.map

View File

@@ -0,0 +1 @@
{"version":3,"file":"IAsyncStorage.d.ts","sourceRoot":"","sources":["../../src/cache/IAsyncStorage.ts"],"names":[],"mappings":"AAKA,MAAM,WAAW,aAAa,CAAC,CAAC;IAC5B;;;OAGG;IACH,OAAO,CAAC,GAAG,EAAE,MAAM,GAAG,OAAO,CAAC,CAAC,GAAG,IAAI,CAAC,CAAC;IAExC;;;;OAIG;IACH,OAAO,CAAC,GAAG,EAAE,MAAM,EAAE,KAAK,EAAE,CAAC,GAAG,OAAO,CAAC,IAAI,CAAC,CAAC;IAE9C;;;OAGG;IACH,UAAU,CAAC,GAAG,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC,CAAC;IAEvC;;OAEG;IACH,OAAO,IAAI,OAAO,CAAC,MAAM,EAAE,CAAC,CAAC;IAE7B;;;OAGG;IACH,WAAW,CAAC,GAAG,EAAE,MAAM,GAAG,OAAO,CAAC,OAAO,CAAC,CAAC;CAC9C"}

View File

@@ -0,0 +1,12 @@
import { ExternalTokenResponse } from "@azure/msal-common/browser";
import { SilentRequest } from "../request/SilentRequest.js";
import { LoadTokenOptions } from "./TokenCache.js";
import { AuthenticationResult } from "../response/AuthenticationResult.js";
export interface ITokenCache {
/**
* API to side-load tokens to MSAL cache
* @returns `AuthenticationResult` for the response that was loaded.
*/
loadExternalTokens(request: SilentRequest, response: ExternalTokenResponse, options: LoadTokenOptions): Promise<AuthenticationResult>;
}
//# sourceMappingURL=ITokenCache.d.ts.map

View File

@@ -0,0 +1 @@
{"version":3,"file":"ITokenCache.d.ts","sourceRoot":"","sources":["../../src/cache/ITokenCache.ts"],"names":[],"mappings":"AAKA,OAAO,EAAE,qBAAqB,EAAE,MAAM,4BAA4B,CAAC;AACnE,OAAO,EAAE,aAAa,EAAE,MAAM,6BAA6B,CAAC;AAC5D,OAAO,EAAE,gBAAgB,EAAE,MAAM,iBAAiB,CAAC;AACnD,OAAO,EAAE,oBAAoB,EAAE,MAAM,qCAAqC,CAAC;AAE3E,MAAM,WAAW,WAAW;IACxB;;;OAGG;IACH,kBAAkB,CACd,OAAO,EAAE,aAAa,EACtB,QAAQ,EAAE,qBAAqB,EAC/B,OAAO,EAAE,gBAAgB,GAC1B,OAAO,CAAC,oBAAoB,CAAC,CAAC;CACpC"}

View File

@@ -0,0 +1,40 @@
export interface IWindowStorage<T> {
/**
* Async initializer
*/
initialize(correlationId: string): Promise<void>;
/**
* Get the item from the window storage object matching the given key.
* @param key
*/
getItem(key: string): T | null;
/**
* Getter for sensitive data that may contain PII.
*/
getUserData(key: string): T | null;
/**
* Sets the item in the window storage object with the given key.
* @param key
* @param value
*/
setItem(key: string, value: T): void;
/**
* Setter for sensitive data that may contain PII.
*/
setUserData(key: string, value: T, correlationId: string): Promise<void>;
/**
* Removes the item in the window storage object matching the given key.
* @param key
*/
removeItem(key: string): void;
/**
* Get all the keys from the window storage object as an iterable array of strings.
*/
getKeys(): string[];
/**
* Returns true or false if the given key is present in the cache.
* @param key
*/
containsKey(key: string): boolean;
}
//# sourceMappingURL=IWindowStorage.d.ts.map

View File

@@ -0,0 +1 @@
{"version":3,"file":"IWindowStorage.d.ts","sourceRoot":"","sources":["../../src/cache/IWindowStorage.ts"],"names":[],"mappings":"AAKA,MAAM,WAAW,cAAc,CAAC,CAAC;IAC7B;;OAEG;IACH,UAAU,CAAC,aAAa,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC,CAAC;IACjD;;;OAGG;IACH,OAAO,CAAC,GAAG,EAAE,MAAM,GAAG,CAAC,GAAG,IAAI,CAAC;IAE/B;;OAEG;IACH,WAAW,CAAC,GAAG,EAAE,MAAM,GAAG,CAAC,GAAG,IAAI,CAAC;IAEnC;;;;OAIG;IACH,OAAO,CAAC,GAAG,EAAE,MAAM,EAAE,KAAK,EAAE,CAAC,GAAG,IAAI,CAAC;IAErC;;OAEG;IACH,WAAW,CAAC,GAAG,EAAE,MAAM,EAAE,KAAK,EAAE,CAAC,EAAE,aAAa,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC,CAAC;IAEzE;;;OAGG;IACH,UAAU,CAAC,GAAG,EAAE,MAAM,GAAG,IAAI,CAAC;IAE9B;;OAEG;IACH,OAAO,IAAI,MAAM,EAAE,CAAC;IAEpB;;;OAGG;IACH,WAAW,CAAC,GAAG,EAAE,MAAM,GAAG,OAAO,CAAC;CACrC"}

View File

@@ -0,0 +1,49 @@
import { IPerformanceClient, Logger } from "@azure/msal-common/browser";
import { IWindowStorage } from "./IWindowStorage.js";
export declare class LocalStorage implements IWindowStorage<string> {
private clientId;
private initialized;
private memoryStorage;
private performanceClient;
private logger;
private encryptionCookie?;
private broadcast;
constructor(clientId: string, logger: Logger, performanceClient: IPerformanceClient);
initialize(correlationId: string): Promise<void>;
getItem(key: string): string | null;
getUserData(key: string): string | null;
setItem(key: string, value: string): void;
setUserData(key: string, value: string, correlationId: string): Promise<void>;
removeItem(key: string): void;
getKeys(): string[];
containsKey(key: string): boolean;
/**
* Removes all known MSAL keys from the cache
*/
clear(): void;
/**
* Helper to decrypt all known MSAL keys in localStorage and save them to inMemory storage
* @returns
*/
private importExistingCache;
/**
* Helper to decrypt and save cache entries
* @param key
* @returns
*/
private getItemFromEncryptedCache;
/**
* Helper to decrypt and save an array of cache keys
* @param arr
* @returns Array of keys successfully imported
*/
private importArray;
/**
* Gets encryption context for a given cache entry. This is clientId for app specific entries, empty string for shared entries
* @param key
* @returns
*/
private getContext;
private updateCache;
}
//# sourceMappingURL=LocalStorage.d.ts.map

View File

@@ -0,0 +1 @@
{"version":3,"file":"LocalStorage.d.ts","sourceRoot":"","sources":["../../src/cache/LocalStorage.ts"],"names":[],"mappings":"AAKA,OAAO,EAGH,kBAAkB,EAGlB,MAAM,EAET,MAAM,4BAA4B,CAAC;AAmBpC,OAAO,EAAE,cAAc,EAAE,MAAM,qBAAqB,CAAC;AAmBrD,qBAAa,YAAa,YAAW,cAAc,CAAC,MAAM,CAAC;IACvD,OAAO,CAAC,QAAQ,CAAS;IACzB,OAAO,CAAC,WAAW,CAAU;IAC7B,OAAO,CAAC,aAAa,CAAwB;IAC7C,OAAO,CAAC,iBAAiB,CAAqB;IAC9C,OAAO,CAAC,MAAM,CAAS;IACvB,OAAO,CAAC,gBAAgB,CAAC,CAAmB;IAC5C,OAAO,CAAC,SAAS,CAAmB;gBAGhC,QAAQ,EAAE,MAAM,EAChB,MAAM,EAAE,MAAM,EACd,iBAAiB,EAAE,kBAAkB;IAenC,UAAU,CAAC,aAAa,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC;IAoFtD,OAAO,CAAC,GAAG,EAAE,MAAM,GAAG,MAAM,GAAG,IAAI;IAInC,WAAW,CAAC,GAAG,EAAE,MAAM,GAAG,MAAM,GAAG,IAAI;IASvC,OAAO,CAAC,GAAG,EAAE,MAAM,EAAE,KAAK,EAAE,MAAM,GAAG,IAAI;IAInC,WAAW,CACb,GAAG,EAAE,MAAM,EACX,KAAK,EAAE,MAAM,EACb,aAAa,EAAE,MAAM,GACtB,OAAO,CAAC,IAAI,CAAC;IA+BhB,UAAU,CAAC,GAAG,EAAE,MAAM,GAAG,IAAI;IAY7B,OAAO,IAAI,MAAM,EAAE;IAInB,WAAW,CAAC,GAAG,EAAE,MAAM,GAAG,OAAO;IAIjC;;OAEG;IACH,KAAK,IAAI,IAAI;IAsBb;;;OAGG;YACW,mBAAmB;IA8BjC;;;;OAIG;YACW,yBAAyB;IAqDvC;;;;OAIG;YACW,WAAW;IA0BzB;;;;OAIG;IACH,OAAO,CAAC,UAAU;IASlB,OAAO,CAAC,WAAW;CAkCtB"}

View File

@@ -0,0 +1,263 @@
/*! @azure/msal-browser v4.2.1 2025-02-11 */
'use strict';
import { invoke, PerformanceEvents, invokeAsync, Constants } from '@azure/msal-common/browser';
import { generateHKDF, createNewGuid, generateBaseKey, encrypt, decrypt } from '../crypto/BrowserCrypto.mjs';
import { base64DecToArr } from '../encode/Base64Decode.mjs';
import { urlEncodeArr } from '../encode/Base64Encode.mjs';
import { createBrowserAuthError } from '../error/BrowserAuthError.mjs';
import { createBrowserConfigurationAuthError } from '../error/BrowserConfigurationAuthError.mjs';
import { SameSiteOptions, CookieStorage } from './CookieStorage.mjs';
import { MemoryStorage } from './MemoryStorage.mjs';
import { getAccountKeys, getTokenKeys } from './CacheHelpers.mjs';
import { StaticCacheKeys } from '../utils/BrowserConstants.mjs';
import { storageNotSupported } from '../error/BrowserConfigurationAuthErrorCodes.mjs';
import { uninitializedPublicClientApplication } from '../error/BrowserAuthErrorCodes.mjs';
/*
* Copyright (c) Microsoft Corporation. All rights reserved.
* Licensed under the MIT License.
*/
const ENCRYPTION_KEY = "msal.cache.encryption";
const BROADCAST_CHANNEL_NAME = "msal.broadcast.cache";
class LocalStorage {
constructor(clientId, logger, performanceClient) {
if (!window.localStorage) {
throw createBrowserConfigurationAuthError(storageNotSupported);
}
this.memoryStorage = new MemoryStorage();
this.initialized = false;
this.clientId = clientId;
this.logger = logger;
this.performanceClient = performanceClient;
this.broadcast = new BroadcastChannel(BROADCAST_CHANNEL_NAME);
}
async initialize(correlationId) {
this.initialized = true;
const cookies = new CookieStorage();
const cookieString = cookies.getItem(ENCRYPTION_KEY);
let parsedCookie = { key: "", id: "" };
if (cookieString) {
try {
parsedCookie = JSON.parse(cookieString);
}
catch (e) { }
}
if (parsedCookie.key && parsedCookie.id) {
// Encryption key already exists, import
const baseKey = invoke(base64DecToArr, PerformanceEvents.Base64Decode, this.logger, this.performanceClient, correlationId)(parsedCookie.key);
this.encryptionCookie = {
id: parsedCookie.id,
key: await invokeAsync(generateHKDF, PerformanceEvents.GenerateHKDF, this.logger, this.performanceClient, correlationId)(baseKey),
};
await invokeAsync(this.importExistingCache.bind(this), PerformanceEvents.ImportExistingCache, this.logger, this.performanceClient, correlationId)(correlationId);
}
else {
// Encryption key doesn't exist or is invalid, generate a new one and clear existing cache
this.clear();
const id = createNewGuid();
const baseKey = await invokeAsync(generateBaseKey, PerformanceEvents.GenerateBaseKey, this.logger, this.performanceClient, correlationId)();
const keyStr = invoke(urlEncodeArr, PerformanceEvents.UrlEncodeArr, this.logger, this.performanceClient, correlationId)(new Uint8Array(baseKey));
this.encryptionCookie = {
id: id,
key: await invokeAsync(generateHKDF, PerformanceEvents.GenerateHKDF, this.logger, this.performanceClient, correlationId)(baseKey),
};
const cookieData = {
id: id,
key: keyStr,
};
cookies.setItem(ENCRYPTION_KEY, JSON.stringify(cookieData), 0, // Expiration - 0 means cookie will be cleared at the end of the browser session
true, // Secure flag
SameSiteOptions.None // SameSite must be None to support iframed apps
);
}
// Register listener for cache updates in other tabs
this.broadcast.addEventListener("message", this.updateCache.bind(this));
}
getItem(key) {
return window.localStorage.getItem(key);
}
getUserData(key) {
if (!this.initialized) {
throw createBrowserAuthError(uninitializedPublicClientApplication);
}
return this.memoryStorage.getItem(key);
}
setItem(key, value) {
window.localStorage.setItem(key, value);
}
async setUserData(key, value, correlationId) {
if (!this.initialized || !this.encryptionCookie) {
throw createBrowserAuthError(uninitializedPublicClientApplication);
}
const { data, nonce } = await invokeAsync(encrypt, PerformanceEvents.Encrypt, this.logger, this.performanceClient, correlationId)(this.encryptionCookie.key, value, this.getContext(key));
const encryptedData = {
id: this.encryptionCookie.id,
nonce: nonce,
data: data,
};
this.memoryStorage.setItem(key, value);
this.setItem(key, JSON.stringify(encryptedData));
// Notify other frames to update their in-memory cache
this.broadcast.postMessage({
key: key,
value: value,
context: this.getContext(key),
});
}
removeItem(key) {
if (this.memoryStorage.containsKey(key)) {
this.memoryStorage.removeItem(key);
this.broadcast.postMessage({
key: key,
value: null,
context: this.getContext(key),
});
}
window.localStorage.removeItem(key);
}
getKeys() {
return Object.keys(window.localStorage);
}
containsKey(key) {
return window.localStorage.hasOwnProperty(key);
}
/**
* Removes all known MSAL keys from the cache
*/
clear() {
// Removes all remaining MSAL cache items
this.memoryStorage.clear();
const accountKeys = getAccountKeys(this);
accountKeys.forEach((key) => this.removeItem(key));
const tokenKeys = getTokenKeys(this.clientId, this);
tokenKeys.idToken.forEach((key) => this.removeItem(key));
tokenKeys.accessToken.forEach((key) => this.removeItem(key));
tokenKeys.refreshToken.forEach((key) => this.removeItem(key));
// Clean up anything left
this.getKeys().forEach((cacheKey) => {
if (cacheKey.startsWith(Constants.CACHE_PREFIX) ||
cacheKey.indexOf(this.clientId) !== -1) {
this.removeItem(cacheKey);
}
});
}
/**
* Helper to decrypt all known MSAL keys in localStorage and save them to inMemory storage
* @returns
*/
async importExistingCache(correlationId) {
if (!this.encryptionCookie) {
return;
}
let accountKeys = getAccountKeys(this);
accountKeys = await this.importArray(accountKeys, correlationId);
// Write valid account keys back to map
this.setItem(StaticCacheKeys.ACCOUNT_KEYS, JSON.stringify(accountKeys));
const tokenKeys = getTokenKeys(this.clientId, this);
tokenKeys.idToken = await this.importArray(tokenKeys.idToken, correlationId);
tokenKeys.accessToken = await this.importArray(tokenKeys.accessToken, correlationId);
tokenKeys.refreshToken = await this.importArray(tokenKeys.refreshToken, correlationId);
// Write valid token keys back to map
this.setItem(`${StaticCacheKeys.TOKEN_KEYS}.${this.clientId}`, JSON.stringify(tokenKeys));
}
/**
* Helper to decrypt and save cache entries
* @param key
* @returns
*/
async getItemFromEncryptedCache(key, correlationId) {
if (!this.encryptionCookie) {
return null;
}
const rawCache = this.getItem(key);
if (!rawCache) {
return null;
}
let encObj;
try {
encObj = JSON.parse(rawCache);
}
catch (e) {
// Not a valid encrypted object, remove
return null;
}
if (!encObj.id || !encObj.nonce || !encObj.data) {
// Data is not encrypted, likely from old version of MSAL. It must be removed because we don't know how old it is.
this.performanceClient.incrementFields({ unencryptedCacheCount: 1 }, correlationId);
return null;
}
if (encObj.id !== this.encryptionCookie.id) {
// Data was encrypted with a different key. It must be removed because it is from a previous session.
this.performanceClient.incrementFields({ encryptedCacheExpiredCount: 1 }, correlationId);
return null;
}
return invokeAsync(decrypt, PerformanceEvents.Decrypt, this.logger, this.performanceClient, correlationId)(this.encryptionCookie.key, encObj.nonce, this.getContext(key), encObj.data);
}
/**
* Helper to decrypt and save an array of cache keys
* @param arr
* @returns Array of keys successfully imported
*/
async importArray(arr, correlationId) {
const importedArr = [];
const promiseArr = [];
arr.forEach((key) => {
const promise = this.getItemFromEncryptedCache(key, correlationId).then((value) => {
if (value) {
this.memoryStorage.setItem(key, value);
importedArr.push(key);
}
else {
// If value is empty, unencrypted or expired remove
this.removeItem(key);
}
});
promiseArr.push(promise);
});
await Promise.all(promiseArr);
return importedArr;
}
/**
* Gets encryption context for a given cache entry. This is clientId for app specific entries, empty string for shared entries
* @param key
* @returns
*/
getContext(key) {
let context = "";
if (key.includes(this.clientId)) {
context = this.clientId; // Used to bind encryption key to this appId
}
return context;
}
updateCache(event) {
this.logger.trace("Updating internal cache from broadcast event");
const perfMeasurement = this.performanceClient.startMeasurement(PerformanceEvents.LocalStorageUpdated);
perfMeasurement.add({ isBackground: true });
const { key, value, context } = event.data;
if (!key) {
this.logger.error("Broadcast event missing key");
perfMeasurement.end({ success: false, errorCode: "noKey" });
return;
}
if (context && context !== this.clientId) {
this.logger.trace(`Ignoring broadcast event from clientId: ${context}`);
perfMeasurement.end({
success: false,
errorCode: "contextMismatch",
});
return;
}
if (!value) {
this.memoryStorage.removeItem(key);
this.logger.verbose("Removed item from internal cache");
}
else {
this.memoryStorage.setItem(key, value);
this.logger.verbose("Updated item in internal cache");
}
perfMeasurement.end({ success: true });
}
}
export { LocalStorage };
//# sourceMappingURL=LocalStorage.mjs.map

File diff suppressed because one or more lines are too long

View File

@@ -0,0 +1,15 @@
import { IWindowStorage } from "./IWindowStorage.js";
export declare class MemoryStorage<T> implements IWindowStorage<T> {
private cache;
constructor();
initialize(): Promise<void>;
getItem(key: string): T | null;
getUserData(key: string): T | null;
setItem(key: string, value: T): void;
setUserData(key: string, value: T): Promise<void>;
removeItem(key: string): void;
getKeys(): string[];
containsKey(key: string): boolean;
clear(): void;
}
//# sourceMappingURL=MemoryStorage.d.ts.map

View File

@@ -0,0 +1 @@
{"version":3,"file":"MemoryStorage.d.ts","sourceRoot":"","sources":["../../src/cache/MemoryStorage.ts"],"names":[],"mappings":"AAKA,OAAO,EAAE,cAAc,EAAE,MAAM,qBAAqB,CAAC;AAErD,qBAAa,aAAa,CAAC,CAAC,CAAE,YAAW,cAAc,CAAC,CAAC,CAAC;IACtD,OAAO,CAAC,KAAK,CAAiB;;IAMxB,UAAU,IAAI,OAAO,CAAC,IAAI,CAAC;IAIjC,OAAO,CAAC,GAAG,EAAE,MAAM,GAAG,CAAC,GAAG,IAAI;IAI9B,WAAW,CAAC,GAAG,EAAE,MAAM,GAAG,CAAC,GAAG,IAAI;IAIlC,OAAO,CAAC,GAAG,EAAE,MAAM,EAAE,KAAK,EAAE,CAAC,GAAG,IAAI;IAI9B,WAAW,CAAC,GAAG,EAAE,MAAM,EAAE,KAAK,EAAE,CAAC,GAAG,OAAO,CAAC,IAAI,CAAC;IAIvD,UAAU,CAAC,GAAG,EAAE,MAAM,GAAG,IAAI;IAI7B,OAAO,IAAI,MAAM,EAAE;IAQnB,WAAW,CAAC,GAAG,EAAE,MAAM,GAAG,OAAO;IAIjC,KAAK,IAAI,IAAI;CAGhB"}

View File

@@ -0,0 +1,45 @@
/*! @azure/msal-browser v4.2.1 2025-02-11 */
'use strict';
/*
* Copyright (c) Microsoft Corporation. All rights reserved.
* Licensed under the MIT License.
*/
class MemoryStorage {
constructor() {
this.cache = new Map();
}
async initialize() {
// Memory storage does not require initialization
}
getItem(key) {
return this.cache.get(key) || null;
}
getUserData(key) {
return this.getItem(key);
}
setItem(key, value) {
this.cache.set(key, value);
}
async setUserData(key, value) {
this.setItem(key, value);
}
removeItem(key) {
this.cache.delete(key);
}
getKeys() {
const cacheKeys = [];
this.cache.forEach((value, key) => {
cacheKeys.push(key);
});
return cacheKeys;
}
containsKey(key) {
return this.cache.has(key);
}
clear() {
this.cache.clear();
}
}
export { MemoryStorage };
//# sourceMappingURL=MemoryStorage.mjs.map

View File

@@ -0,0 +1 @@
{"version":3,"file":"MemoryStorage.mjs","sources":["../../src/cache/MemoryStorage.ts"],"sourcesContent":[null],"names":[],"mappings":";;AAAA;;;AAGG;MAIU,aAAa,CAAA;AAGtB,IAAA,WAAA,GAAA;AACI,QAAA,IAAI,CAAC,KAAK,GAAG,IAAI,GAAG,EAAa,CAAC;KACrC;AAED,IAAA,MAAM,UAAU,GAAA;;KAEf;AAED,IAAA,OAAO,CAAC,GAAW,EAAA;QACf,OAAO,IAAI,CAAC,KAAK,CAAC,GAAG,CAAC,GAAG,CAAC,IAAI,IAAI,CAAC;KACtC;AAED,IAAA,WAAW,CAAC,GAAW,EAAA;AACnB,QAAA,OAAO,IAAI,CAAC,OAAO,CAAC,GAAG,CAAC,CAAC;KAC5B;IAED,OAAO,CAAC,GAAW,EAAE,KAAQ,EAAA;QACzB,IAAI,CAAC,KAAK,CAAC,GAAG,CAAC,GAAG,EAAE,KAAK,CAAC,CAAC;KAC9B;AAED,IAAA,MAAM,WAAW,CAAC,GAAW,EAAE,KAAQ,EAAA;AACnC,QAAA,IAAI,CAAC,OAAO,CAAC,GAAG,EAAE,KAAK,CAAC,CAAC;KAC5B;AAED,IAAA,UAAU,CAAC,GAAW,EAAA;AAClB,QAAA,IAAI,CAAC,KAAK,CAAC,MAAM,CAAC,GAAG,CAAC,CAAC;KAC1B;IAED,OAAO,GAAA;QACH,MAAM,SAAS,GAAa,EAAE,CAAC;QAC/B,IAAI,CAAC,KAAK,CAAC,OAAO,CAAC,CAAC,KAAQ,EAAE,GAAW,KAAI;AACzC,YAAA,SAAS,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC;AACxB,SAAC,CAAC,CAAC;AACH,QAAA,OAAO,SAAS,CAAC;KACpB;AAED,IAAA,WAAW,CAAC,GAAW,EAAA;QACnB,OAAO,IAAI,CAAC,KAAK,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC;KAC9B;IAED,KAAK,GAAA;AACD,QAAA,IAAI,CAAC,KAAK,CAAC,KAAK,EAAE,CAAC;KACtB;AACJ;;;;"}

View File

@@ -0,0 +1,13 @@
import { IWindowStorage } from "./IWindowStorage.js";
export declare class SessionStorage implements IWindowStorage<string> {
constructor();
initialize(): Promise<void>;
getItem(key: string): string | null;
getUserData(key: string): string | null;
setItem(key: string, value: string): void;
setUserData(key: string, value: string): Promise<void>;
removeItem(key: string): void;
getKeys(): string[];
containsKey(key: string): boolean;
}
//# sourceMappingURL=SessionStorage.d.ts.map

View File

@@ -0,0 +1 @@
{"version":3,"file":"SessionStorage.d.ts","sourceRoot":"","sources":["../../src/cache/SessionStorage.ts"],"names":[],"mappings":"AASA,OAAO,EAAE,cAAc,EAAE,MAAM,qBAAqB,CAAC;AAErD,qBAAa,cAAe,YAAW,cAAc,CAAC,MAAM,CAAC;;IASnD,UAAU,IAAI,OAAO,CAAC,IAAI,CAAC;IAIjC,OAAO,CAAC,GAAG,EAAE,MAAM,GAAG,MAAM,GAAG,IAAI;IAInC,WAAW,CAAC,GAAG,EAAE,MAAM,GAAG,MAAM,GAAG,IAAI;IAIvC,OAAO,CAAC,GAAG,EAAE,MAAM,EAAE,KAAK,EAAE,MAAM,GAAG,IAAI;IAInC,WAAW,CAAC,GAAG,EAAE,MAAM,EAAE,KAAK,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC;IAI5D,UAAU,CAAC,GAAG,EAAE,MAAM,GAAG,IAAI;IAI7B,OAAO,IAAI,MAAM,EAAE;IAInB,WAAW,CAAC,GAAG,EAAE,MAAM,GAAG,OAAO;CAGpC"}

View File

@@ -0,0 +1,43 @@
/*! @azure/msal-browser v4.2.1 2025-02-11 */
'use strict';
import { createBrowserConfigurationAuthError } from '../error/BrowserConfigurationAuthError.mjs';
import { storageNotSupported } from '../error/BrowserConfigurationAuthErrorCodes.mjs';
/*
* Copyright (c) Microsoft Corporation. All rights reserved.
* Licensed under the MIT License.
*/
class SessionStorage {
constructor() {
if (!window.sessionStorage) {
throw createBrowserConfigurationAuthError(storageNotSupported);
}
}
async initialize() {
// Session storage does not require initialization
}
getItem(key) {
return window.sessionStorage.getItem(key);
}
getUserData(key) {
return this.getItem(key);
}
setItem(key, value) {
window.sessionStorage.setItem(key, value);
}
async setUserData(key, value) {
this.setItem(key, value);
}
removeItem(key) {
window.sessionStorage.removeItem(key);
}
getKeys() {
return Object.keys(window.sessionStorage);
}
containsKey(key) {
return window.sessionStorage.hasOwnProperty(key);
}
}
export { SessionStorage };
//# sourceMappingURL=SessionStorage.mjs.map

View File

@@ -0,0 +1 @@
{"version":3,"file":"SessionStorage.mjs","sources":["../../src/cache/SessionStorage.ts"],"sourcesContent":[null],"names":["BrowserConfigurationAuthErrorCodes.storageNotSupported"],"mappings":";;;;;AAAA;;;AAGG;MAQU,cAAc,CAAA;AACvB,IAAA,WAAA,GAAA;AACI,QAAA,IAAI,CAAC,MAAM,CAAC,cAAc,EAAE;AACxB,YAAA,MAAM,mCAAmC,CACrCA,mBAAsD,CACzD,CAAC;AACL,SAAA;KACJ;AAED,IAAA,MAAM,UAAU,GAAA;;KAEf;AAED,IAAA,OAAO,CAAC,GAAW,EAAA;QACf,OAAO,MAAM,CAAC,cAAc,CAAC,OAAO,CAAC,GAAG,CAAC,CAAC;KAC7C;AAED,IAAA,WAAW,CAAC,GAAW,EAAA;AACnB,QAAA,OAAO,IAAI,CAAC,OAAO,CAAC,GAAG,CAAC,CAAC;KAC5B;IAED,OAAO,CAAC,GAAW,EAAE,KAAa,EAAA;QAC9B,MAAM,CAAC,cAAc,CAAC,OAAO,CAAC,GAAG,EAAE,KAAK,CAAC,CAAC;KAC7C;AAED,IAAA,MAAM,WAAW,CAAC,GAAW,EAAE,KAAa,EAAA;AACxC,QAAA,IAAI,CAAC,OAAO,CAAC,GAAG,EAAE,KAAK,CAAC,CAAC;KAC5B;AAED,IAAA,UAAU,CAAC,GAAW,EAAA;AAClB,QAAA,MAAM,CAAC,cAAc,CAAC,UAAU,CAAC,GAAG,CAAC,CAAC;KACzC;IAED,OAAO,GAAA;QACH,OAAO,MAAM,CAAC,IAAI,CAAC,MAAM,CAAC,cAAc,CAAC,CAAC;KAC7C;AAED,IAAA,WAAW,CAAC,GAAW,EAAA;QACnB,OAAO,MAAM,CAAC,cAAc,CAAC,cAAc,CAAC,GAAG,CAAC,CAAC;KACpD;AACJ;;;;"}

View File

@@ -0,0 +1,78 @@
import { ICrypto, Logger, ExternalTokenResponse } from "@azure/msal-common/browser";
import { BrowserConfiguration } from "../config/Configuration.js";
import { SilentRequest } from "../request/SilentRequest.js";
import { BrowserCacheManager } from "./BrowserCacheManager.js";
import { ITokenCache } from "./ITokenCache.js";
import { AuthenticationResult } from "../response/AuthenticationResult.js";
export type LoadTokenOptions = {
clientInfo?: string;
expiresOn?: number;
extendedExpiresOn?: number;
};
/**
* Token cache manager
*/
export declare class TokenCache implements ITokenCache {
isBrowserEnvironment: boolean;
protected config: BrowserConfiguration;
private storage;
private logger;
private cryptoObj;
constructor(configuration: BrowserConfiguration, storage: BrowserCacheManager, logger: Logger, cryptoObj: ICrypto);
/**
* API to load tokens to msal-browser cache.
* @param request
* @param response
* @param options
* @returns `AuthenticationResult` for the response that was loaded.
*/
loadExternalTokens(request: SilentRequest, response: ExternalTokenResponse, options: LoadTokenOptions): Promise<AuthenticationResult>;
/**
* Helper function to load account to msal-browser cache
* @param idToken
* @param environment
* @param clientInfo
* @param authorityType
* @param requestHomeAccountId
* @returns `AccountEntity`
*/
private loadAccount;
/**
* Helper function to load id tokens to msal-browser cache
* @param idToken
* @param homeAccountId
* @param environment
* @param tenantId
* @returns `IdTokenEntity`
*/
private loadIdToken;
/**
* Helper function to load access tokens to msal-browser cache
* @param request
* @param response
* @param homeAccountId
* @param environment
* @param tenantId
* @returns `AccessTokenEntity`
*/
private loadAccessToken;
/**
* Helper function to load refresh tokens to msal-browser cache
* @param request
* @param response
* @param homeAccountId
* @param environment
* @returns `RefreshTokenEntity`
*/
private loadRefreshToken;
/**
* Helper function to generate an `AuthenticationResult` for the result.
* @param request
* @param idTokenObj
* @param cacheRecord
* @param authority
* @returns `AuthenticationResult`
*/
private generateAuthenticationResult;
}
//# sourceMappingURL=TokenCache.d.ts.map

View File

@@ -0,0 +1 @@
{"version":3,"file":"TokenCache.d.ts","sourceRoot":"","sources":["../../src/cache/TokenCache.ts"],"names":[],"mappings":"AAKA,OAAO,EAEH,OAAO,EAEP,MAAM,EAIN,qBAAqB,EAQxB,MAAM,4BAA4B,CAAC;AACpC,OAAO,EAAE,oBAAoB,EAAE,MAAM,4BAA4B,CAAC;AAClE,OAAO,EAAE,aAAa,EAAE,MAAM,6BAA6B,CAAC;AAC5D,OAAO,EAAE,mBAAmB,EAAE,MAAM,0BAA0B,CAAC;AAC/D,OAAO,EAAE,WAAW,EAAE,MAAM,kBAAkB,CAAC;AAK/C,OAAO,EAAE,oBAAoB,EAAE,MAAM,qCAAqC,CAAC;AAI3E,MAAM,MAAM,gBAAgB,GAAG;IAC3B,UAAU,CAAC,EAAE,MAAM,CAAC;IACpB,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,iBAAiB,CAAC,EAAE,MAAM,CAAC;CAC9B,CAAC;AAEF;;GAEG;AACH,qBAAa,UAAW,YAAW,WAAW;IAEnC,oBAAoB,EAAE,OAAO,CAAC;IAErC,SAAS,CAAC,MAAM,EAAE,oBAAoB,CAAC;IAEvC,OAAO,CAAC,OAAO,CAAsB;IAErC,OAAO,CAAC,MAAM,CAAS;IAEvB,OAAO,CAAC,SAAS,CAAU;gBAGvB,aAAa,EAAE,oBAAoB,EACnC,OAAO,EAAE,mBAAmB,EAC5B,MAAM,EAAE,MAAM,EACd,SAAS,EAAE,OAAO;IAWtB;;;;;;OAMG;IACG,kBAAkB,CACpB,OAAO,EAAE,aAAa,EACtB,QAAQ,EAAE,qBAAqB,EAC/B,OAAO,EAAE,gBAAgB,GAC1B,OAAO,CAAC,oBAAoB,CAAC;IAkFhC;;;;;;;;OAQG;YACW,WAAW;IAoDzB;;;;;;;OAOG;YACW,WAAW;IAyBzB;;;;;;;;OAQG;YACW,eAAe;IA8D7B;;;;;;;OAOG;YACW,gBAAgB;IA+B9B;;;;;;;OAOG;IACH,OAAO,CAAC,4BAA4B;CAgDvC"}

View File

@@ -0,0 +1,207 @@
/*! @azure/msal-browser v4.2.1 2025-02-11 */
'use strict';
import { AuthToken, Authority, AccountEntity, buildAccountToCache, CacheHelpers, ScopeSet } from '@azure/msal-common/browser';
import { createBrowserAuthError } from '../error/BrowserAuthError.mjs';
import { base64Decode } from '../encode/Base64Decode.mjs';
import { createNewGuid } from '../crypto/BrowserCrypto.mjs';
import { nonBrowserEnvironment, unableToLoadToken } from '../error/BrowserAuthErrorCodes.mjs';
/*
* Copyright (c) Microsoft Corporation. All rights reserved.
* Licensed under the MIT License.
*/
/**
* Token cache manager
*/
class TokenCache {
constructor(configuration, storage, logger, cryptoObj) {
this.isBrowserEnvironment = typeof window !== "undefined";
this.config = configuration;
this.storage = storage;
this.logger = logger;
this.cryptoObj = cryptoObj;
}
// Move getAllAccounts here and cache utility APIs
/**
* API to load tokens to msal-browser cache.
* @param request
* @param response
* @param options
* @returns `AuthenticationResult` for the response that was loaded.
*/
async loadExternalTokens(request, response, options) {
if (!this.isBrowserEnvironment) {
throw createBrowserAuthError(nonBrowserEnvironment);
}
const correlationId = request.correlationId || createNewGuid();
const idTokenClaims = response.id_token
? AuthToken.extractTokenClaims(response.id_token, base64Decode)
: undefined;
const authorityOptions = {
protocolMode: this.config.auth.protocolMode,
knownAuthorities: this.config.auth.knownAuthorities,
cloudDiscoveryMetadata: this.config.auth.cloudDiscoveryMetadata,
authorityMetadata: this.config.auth.authorityMetadata,
skipAuthorityMetadataCache: this.config.auth.skipAuthorityMetadataCache,
};
const authority = request.authority
? new Authority(Authority.generateAuthority(request.authority, request.azureCloudOptions), this.config.system.networkClient, this.storage, authorityOptions, this.logger, request.correlationId || createNewGuid())
: undefined;
const cacheRecordAccount = await this.loadAccount(request, options.clientInfo || response.client_info || "", correlationId, idTokenClaims, authority);
const idToken = await this.loadIdToken(response, cacheRecordAccount.homeAccountId, cacheRecordAccount.environment, cacheRecordAccount.realm, correlationId);
const accessToken = await this.loadAccessToken(request, response, cacheRecordAccount.homeAccountId, cacheRecordAccount.environment, cacheRecordAccount.realm, options, correlationId);
const refreshToken = await this.loadRefreshToken(response, cacheRecordAccount.homeAccountId, cacheRecordAccount.environment, correlationId);
return this.generateAuthenticationResult(request, {
account: cacheRecordAccount,
idToken,
accessToken,
refreshToken,
}, idTokenClaims, authority);
}
/**
* Helper function to load account to msal-browser cache
* @param idToken
* @param environment
* @param clientInfo
* @param authorityType
* @param requestHomeAccountId
* @returns `AccountEntity`
*/
async loadAccount(request, clientInfo, correlationId, idTokenClaims, authority) {
this.logger.verbose("TokenCache - loading account");
if (request.account) {
const accountEntity = AccountEntity.createFromAccountInfo(request.account);
await this.storage.setAccount(accountEntity, correlationId);
return accountEntity;
}
else if (!authority || (!clientInfo && !idTokenClaims)) {
this.logger.error("TokenCache - if an account is not provided on the request, authority and either clientInfo or idToken must be provided instead.");
throw createBrowserAuthError(unableToLoadToken);
}
const homeAccountId = AccountEntity.generateHomeAccountId(clientInfo, authority.authorityType, this.logger, this.cryptoObj, idTokenClaims);
const claimsTenantId = idTokenClaims?.tid;
const cachedAccount = buildAccountToCache(this.storage, authority, homeAccountId, base64Decode, idTokenClaims, clientInfo, authority.hostnameAndPort, claimsTenantId, undefined, // authCodePayload
undefined, // nativeAccountId
this.logger);
await this.storage.setAccount(cachedAccount, correlationId);
return cachedAccount;
}
/**
* Helper function to load id tokens to msal-browser cache
* @param idToken
* @param homeAccountId
* @param environment
* @param tenantId
* @returns `IdTokenEntity`
*/
async loadIdToken(response, homeAccountId, environment, tenantId, correlationId) {
if (!response.id_token) {
this.logger.verbose("TokenCache - no id token found in response");
return null;
}
this.logger.verbose("TokenCache - loading id token");
const idTokenEntity = CacheHelpers.createIdTokenEntity(homeAccountId, environment, response.id_token, this.config.auth.clientId, tenantId);
await this.storage.setIdTokenCredential(idTokenEntity, correlationId);
return idTokenEntity;
}
/**
* Helper function to load access tokens to msal-browser cache
* @param request
* @param response
* @param homeAccountId
* @param environment
* @param tenantId
* @returns `AccessTokenEntity`
*/
async loadAccessToken(request, response, homeAccountId, environment, tenantId, options, correlationId) {
if (!response.access_token) {
this.logger.verbose("TokenCache - no access token found in response");
return null;
}
else if (!response.expires_in) {
this.logger.error("TokenCache - no expiration set on the access token. Cannot add it to the cache.");
return null;
}
else if (!response.scope &&
(!request.scopes || !request.scopes.length)) {
this.logger.error("TokenCache - scopes not specified in the request or response. Cannot add token to the cache.");
return null;
}
this.logger.verbose("TokenCache - loading access token");
const scopes = response.scope
? ScopeSet.fromString(response.scope)
: new ScopeSet(request.scopes);
const expiresOn = options.expiresOn ||
response.expires_in + new Date().getTime() / 1000;
const extendedExpiresOn = options.extendedExpiresOn ||
(response.ext_expires_in || response.expires_in) +
new Date().getTime() / 1000;
const accessTokenEntity = CacheHelpers.createAccessTokenEntity(homeAccountId, environment, response.access_token, this.config.auth.clientId, tenantId, scopes.printScopes(), expiresOn, extendedExpiresOn, base64Decode);
await this.storage.setAccessTokenCredential(accessTokenEntity, correlationId);
return accessTokenEntity;
}
/**
* Helper function to load refresh tokens to msal-browser cache
* @param request
* @param response
* @param homeAccountId
* @param environment
* @returns `RefreshTokenEntity`
*/
async loadRefreshToken(response, homeAccountId, environment, correlationId) {
if (!response.refresh_token) {
this.logger.verbose("TokenCache - no refresh token found in response");
return null;
}
this.logger.verbose("TokenCache - loading refresh token");
const refreshTokenEntity = CacheHelpers.createRefreshTokenEntity(homeAccountId, environment, response.refresh_token, this.config.auth.clientId, response.foci, undefined, // userAssertionHash
response.refresh_token_expires_in);
await this.storage.setRefreshTokenCredential(refreshTokenEntity, correlationId);
return refreshTokenEntity;
}
/**
* Helper function to generate an `AuthenticationResult` for the result.
* @param request
* @param idTokenObj
* @param cacheRecord
* @param authority
* @returns `AuthenticationResult`
*/
generateAuthenticationResult(request, cacheRecord, idTokenClaims, authority) {
let accessToken = "";
let responseScopes = [];
let expiresOn = null;
let extExpiresOn;
if (cacheRecord?.accessToken) {
accessToken = cacheRecord.accessToken.secret;
responseScopes = ScopeSet.fromString(cacheRecord.accessToken.target).asArray();
expiresOn = new Date(Number(cacheRecord.accessToken.expiresOn) * 1000);
extExpiresOn = new Date(Number(cacheRecord.accessToken.extendedExpiresOn) * 1000);
}
const accountEntity = cacheRecord.account;
return {
authority: authority ? authority.canonicalAuthority : "",
uniqueId: cacheRecord.account.localAccountId,
tenantId: cacheRecord.account.realm,
scopes: responseScopes,
account: accountEntity.getAccountInfo(),
idToken: cacheRecord.idToken?.secret || "",
idTokenClaims: idTokenClaims || {},
accessToken: accessToken,
fromCache: true,
expiresOn: expiresOn,
correlationId: request.correlationId || "",
requestId: "",
extExpiresOn: extExpiresOn,
familyId: cacheRecord.refreshToken?.familyId || "",
tokenType: cacheRecord?.accessToken?.tokenType || "",
state: request.state || "",
cloudGraphHostName: accountEntity.cloudGraphHostName || "",
msGraphHost: accountEntity.msGraphHost || "",
fromNativeBroker: false,
};
}
}
export { TokenCache };
//# sourceMappingURL=TokenCache.mjs.map

File diff suppressed because one or more lines are too long