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,473 @@
import { AccountFilter, CredentialFilter, ValidCredentialType, AppMetadataFilter, AppMetadataCache, TokenKeys } from "./utils/CacheTypes.js";
import { CacheRecord } from "./entities/CacheRecord.js";
import { AccountEntity } from "./entities/AccountEntity.js";
import { AccessTokenEntity } from "./entities/AccessTokenEntity.js";
import { IdTokenEntity } from "./entities/IdTokenEntity.js";
import { RefreshTokenEntity } from "./entities/RefreshTokenEntity.js";
import { ICacheManager } from "./interface/ICacheManager.js";
import { AccountInfo } from "../account/AccountInfo.js";
import { AppMetadataEntity } from "./entities/AppMetadataEntity.js";
import { ServerTelemetryEntity } from "./entities/ServerTelemetryEntity.js";
import { ThrottlingEntity } from "./entities/ThrottlingEntity.js";
import { ICrypto } from "../crypto/ICrypto.js";
import { AuthorityMetadataEntity } from "./entities/AuthorityMetadataEntity.js";
import { BaseAuthRequest } from "../request/BaseAuthRequest.js";
import { Logger } from "../logger/Logger.js";
import { StoreInCache } from "../request/StoreInCache.js";
import { StaticAuthorityOptions } from "../authority/AuthorityOptions.js";
import { IPerformanceClient } from "../telemetry/performance/IPerformanceClient.js";
/**
* Interface class which implement cache storage functions used by MSAL to perform validity checks, and store tokens.
* @internal
*/
export declare abstract class CacheManager implements ICacheManager {
protected clientId: string;
protected cryptoImpl: ICrypto;
private commonLogger;
private staticAuthorityOptions?;
constructor(clientId: string, cryptoImpl: ICrypto, logger: Logger, staticAuthorityOptions?: StaticAuthorityOptions);
/**
* fetch the account entity from the platform cache
* @param accountKey
*/
abstract getAccount(accountKey: string, logger?: Logger): AccountEntity | null;
/**
* set account entity in the platform cache
* @param account
* @param correlationId
*/
abstract setAccount(account: AccountEntity, correlationId: string): Promise<void>;
/**
* fetch the idToken entity from the platform cache
* @param idTokenKey
*/
abstract getIdTokenCredential(idTokenKey: string): IdTokenEntity | null;
/**
* set idToken entity to the platform cache
* @param idToken
* @param correlationId
*/
abstract setIdTokenCredential(idToken: IdTokenEntity, correlationId: string): Promise<void>;
/**
* fetch the idToken entity from the platform cache
* @param accessTokenKey
*/
abstract getAccessTokenCredential(accessTokenKey: string): AccessTokenEntity | null;
/**
* set accessToken entity to the platform cache
* @param accessToken
* @param correlationId
*/
abstract setAccessTokenCredential(accessToken: AccessTokenEntity, correlationId: string): Promise<void>;
/**
* fetch the idToken entity from the platform cache
* @param refreshTokenKey
*/
abstract getRefreshTokenCredential(refreshTokenKey: string): RefreshTokenEntity | null;
/**
* set refreshToken entity to the platform cache
* @param refreshToken
* @param correlationId
*/
abstract setRefreshTokenCredential(refreshToken: RefreshTokenEntity, correlationId: string): Promise<void>;
/**
* fetch appMetadata entity from the platform cache
* @param appMetadataKey
*/
abstract getAppMetadata(appMetadataKey: string): AppMetadataEntity | null;
/**
* set appMetadata entity to the platform cache
* @param appMetadata
*/
abstract setAppMetadata(appMetadata: AppMetadataEntity): void;
/**
* fetch server telemetry entity from the platform cache
* @param serverTelemetryKey
*/
abstract getServerTelemetry(serverTelemetryKey: string): ServerTelemetryEntity | null;
/**
* set server telemetry entity to the platform cache
* @param serverTelemetryKey
* @param serverTelemetry
*/
abstract setServerTelemetry(serverTelemetryKey: string, serverTelemetry: ServerTelemetryEntity): void;
/**
* fetch cloud discovery metadata entity from the platform cache
* @param key
*/
abstract getAuthorityMetadata(key: string): AuthorityMetadataEntity | null;
/**
*
*/
abstract getAuthorityMetadataKeys(): Array<string>;
/**
* set cloud discovery metadata entity to the platform cache
* @param key
* @param value
*/
abstract setAuthorityMetadata(key: string, value: AuthorityMetadataEntity): void;
/**
* fetch throttling entity from the platform cache
* @param throttlingCacheKey
*/
abstract getThrottlingCache(throttlingCacheKey: string): ThrottlingEntity | null;
/**
* set throttling entity to the platform cache
* @param throttlingCacheKey
* @param throttlingCache
*/
abstract setThrottlingCache(throttlingCacheKey: string, throttlingCache: ThrottlingEntity): void;
/**
* Function to remove an item from cache given its key.
* @param key
*/
abstract removeItem(key: string): void;
/**
* Function which retrieves all current keys from the cache.
*/
abstract getKeys(): string[];
/**
* Function which retrieves all account keys from the cache
*/
abstract getAccountKeys(): string[];
/**
* Function which retrieves all token keys from the cache
*/
abstract getTokenKeys(): TokenKeys;
/**
* 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
*/
getAllAccounts(accountFilter?: AccountFilter): AccountInfo[];
/**
* Gets first tenanted AccountInfo object found based on provided filters
*/
getAccountInfoFilteredBy(accountFilter: AccountFilter): AccountInfo | null;
/**
* Returns a single matching
* @param accountFilter
* @returns
*/
getBaseAccountInfo(accountFilter: AccountFilter): AccountInfo | null;
/**
* Matches filtered account entities with cached ID tokens that match the tenant profile-specific account filters
* and builds the account info objects from the matching ID token's claims
* @param cachedAccounts
* @param accountFilter
* @returns Array of AccountInfo objects that match account and tenant profile filters
*/
private buildTenantProfiles;
private getTenantedAccountInfoByFilter;
private getTenantProfilesFromAccountEntity;
private tenantProfileMatchesFilter;
private idTokenClaimsMatchTenantProfileFilter;
/**
* saves a cache record
* @param cacheRecord {CacheRecord}
* @param storeInCache {?StoreInCache}
* @param correlationId {?string} correlation id
*/
saveCacheRecord(cacheRecord: CacheRecord, correlationId: string, storeInCache?: StoreInCache): Promise<void>;
/**
* saves access token credential
* @param credential
*/
private saveAccessToken;
/**
* Retrieve account entities matching all provided tenant-agnostic filters; if no filter is set, get all account entities in the cache
* Not checking for casing as keys are all generated in lower case, remember to convert to lower case if object properties are compared
* @param accountFilter - An object containing Account properties to filter by
*/
getAccountsFilteredBy(accountFilter: AccountFilter): AccountEntity[];
/**
* Returns true if the given key matches our account key schema. Also matches homeAccountId and/or tenantId if provided
* @param key
* @param homeAccountId
* @param tenantId
* @returns
*/
isAccountKey(key: string, homeAccountId?: string, tenantId?: string): boolean;
/**
* Returns true if the given key matches our credential key schema.
* @param key
*/
isCredentialKey(key: string): boolean;
/**
* Returns whether or not the given credential entity matches the filter
* @param entity
* @param filter
* @returns
*/
credentialMatchesFilter(entity: ValidCredentialType, filter: CredentialFilter): boolean;
/**
* retrieve appMetadata matching all provided filters; if no filter is set, get all appMetadata
* @param filter
*/
getAppMetadataFilteredBy(filter: AppMetadataFilter): AppMetadataCache;
/**
* retrieve authorityMetadata that contains a matching alias
* @param filter
*/
getAuthorityMetadataByAlias(host: string): AuthorityMetadataEntity | null;
/**
* Removes all accounts and related tokens from cache.
*/
removeAllAccounts(): Promise<void>;
/**
* Removes the account and related tokens for a given account key
* @param account
*/
removeAccount(accountKey: string): Promise<void>;
/**
* Removes credentials associated with the provided account
* @param account
*/
removeAccountContext(account: AccountEntity): Promise<void>;
/**
* returns a boolean if the given credential is removed
* @param credential
*/
removeAccessToken(key: string): Promise<void>;
/**
* Removes all app metadata objects from cache.
*/
removeAppMetadata(): boolean;
/**
* Retrieve AccountEntity from cache
* @param account
*/
readAccountFromCache(account: AccountInfo): AccountEntity | null;
/**
* Retrieve IdTokenEntity from cache
* @param account {AccountInfo}
* @param tokenKeys {?TokenKeys}
* @param targetRealm {?string}
* @param performanceClient {?IPerformanceClient}
* @param correlationId {?string}
*/
getIdToken(account: AccountInfo, tokenKeys?: TokenKeys, targetRealm?: string, performanceClient?: IPerformanceClient, correlationId?: string): IdTokenEntity | null;
/**
* Gets all idTokens matching the given filter
* @param filter
* @returns
*/
getIdTokensByFilter(filter: CredentialFilter, tokenKeys?: TokenKeys): Map<string, IdTokenEntity>;
/**
* Validate the cache key against filter before retrieving and parsing cache value
* @param key
* @param filter
* @returns
*/
idTokenKeyMatchesFilter(inputKey: string, filter: CredentialFilter): boolean;
/**
* Removes idToken from the cache
* @param key
*/
removeIdToken(key: string): void;
/**
* Removes refresh token from the cache
* @param key
*/
removeRefreshToken(key: string): void;
/**
* Retrieve AccessTokenEntity from cache
* @param account {AccountInfo}
* @param request {BaseAuthRequest}
* @param tokenKeys {?TokenKeys}
* @param performanceClient {?IPerformanceClient}
* @param correlationId {?string}
*/
getAccessToken(account: AccountInfo, request: BaseAuthRequest, tokenKeys?: TokenKeys, targetRealm?: string, performanceClient?: IPerformanceClient, correlationId?: string): AccessTokenEntity | null;
/**
* Validate the cache key against filter before retrieving and parsing cache value
* @param key
* @param filter
* @param keyMustContainAllScopes
* @returns
*/
accessTokenKeyMatchesFilter(inputKey: string, filter: CredentialFilter, keyMustContainAllScopes: boolean): boolean;
/**
* Gets all access tokens matching the filter
* @param filter
* @returns
*/
getAccessTokensByFilter(filter: CredentialFilter): AccessTokenEntity[];
/**
* Helper to retrieve the appropriate refresh token from cache
* @param account {AccountInfo}
* @param familyRT {boolean}
* @param tokenKeys {?TokenKeys}
* @param performanceClient {?IPerformanceClient}
* @param correlationId {?string}
*/
getRefreshToken(account: AccountInfo, familyRT: boolean, tokenKeys?: TokenKeys, performanceClient?: IPerformanceClient, correlationId?: string): RefreshTokenEntity | null;
/**
* Validate the cache key against filter before retrieving and parsing cache value
* @param key
* @param filter
*/
refreshTokenKeyMatchesFilter(inputKey: string, filter: CredentialFilter): boolean;
/**
* Retrieve AppMetadataEntity from cache
*/
readAppMetadataFromCache(environment: string): AppMetadataEntity | null;
/**
* Return the family_id value associated with FOCI
* @param environment
* @param clientId
*/
isAppMetadataFOCI(environment: string): boolean;
/**
* helper to match account ids
* @param value
* @param homeAccountId
*/
private matchHomeAccountId;
/**
* helper to match account ids
* @param entity
* @param localAccountId
* @returns
*/
private matchLocalAccountIdFromTokenClaims;
private matchLocalAccountIdFromTenantProfile;
/**
* helper to match names
* @param entity
* @param name
* @returns true if the downcased name properties are present and match in the filter and the entity
*/
private matchName;
/**
* helper to match usernames
* @param entity
* @param username
* @returns
*/
private matchUsername;
/**
* helper to match assertion
* @param value
* @param oboAssertion
*/
private matchUserAssertionHash;
/**
* helper to match environment
* @param value
* @param environment
*/
private matchEnvironment;
/**
* helper to match credential type
* @param entity
* @param credentialType
*/
private matchCredentialType;
/**
* helper to match client ids
* @param entity
* @param clientId
*/
private matchClientId;
/**
* helper to match family ids
* @param entity
* @param familyId
*/
private matchFamilyId;
/**
* helper to match realm
* @param entity
* @param realm
*/
private matchRealm;
/**
* helper to match nativeAccountId
* @param entity
* @param nativeAccountId
* @returns boolean indicating the match result
*/
private matchNativeAccountId;
/**
* helper to match loginHint which can be either:
* 1. login_hint ID token claim
* 2. username in cached account object
* 3. upn in ID token claims
* @param entity
* @param loginHint
* @returns
*/
private matchLoginHintFromTokenClaims;
/**
* Helper to match sid
* @param entity
* @param sid
* @returns true if the sid claim is present and matches the filter
*/
private matchSid;
private matchAuthorityType;
/**
* Returns true if the target scopes are a subset of the current entity's scopes, false otherwise.
* @param entity
* @param target
*/
private matchTarget;
/**
* Returns true if the credential's tokenType or Authentication Scheme matches the one in the request, false otherwise
* @param entity
* @param tokenType
*/
private matchTokenType;
/**
* Returns true if the credential's keyId matches the one in the request, false otherwise
* @param entity
* @param keyId
*/
private matchKeyId;
/**
* returns if a given cache entity is of the type appmetadata
* @param key
*/
private isAppMetadata;
/**
* returns if a given cache entity is of the type authoritymetadata
* @param key
*/
protected isAuthorityMetadata(key: string): boolean;
/**
* returns cache key used for cloud instance metadata
*/
generateAuthorityMetadataCacheKey(authority: string): string;
/**
* Helper to convert serialized data to object
* @param obj
* @param json
*/
static toObject<T>(obj: T, json: object): T;
}
/** @internal */
export declare class DefaultStorageClass extends CacheManager {
setAccount(): Promise<void>;
getAccount(): AccountEntity;
setIdTokenCredential(): Promise<void>;
getIdTokenCredential(): IdTokenEntity;
setAccessTokenCredential(): Promise<void>;
getAccessTokenCredential(): AccessTokenEntity;
setRefreshTokenCredential(): Promise<void>;
getRefreshTokenCredential(): RefreshTokenEntity;
setAppMetadata(): void;
getAppMetadata(): AppMetadataEntity;
setServerTelemetry(): void;
getServerTelemetry(): ServerTelemetryEntity;
setAuthorityMetadata(): void;
getAuthorityMetadata(): AuthorityMetadataEntity | null;
getAuthorityMetadataKeys(): Array<string>;
setThrottlingCache(): void;
getThrottlingCache(): ThrottlingEntity;
removeItem(): boolean;
getKeys(): string[];
getAccountKeys(): string[];
getTokenKeys(): TokenKeys;
}
//# sourceMappingURL=CacheManager.d.ts.map

File diff suppressed because one or more lines are too long

File diff suppressed because it is too large Load Diff

File diff suppressed because one or more lines are too long

View File

@@ -0,0 +1,26 @@
import { CredentialEntity } from "./CredentialEntity.js";
import { AuthenticationScheme } from "../../utils/Constants.js";
/**
* Access token cache type
*/
export type AccessTokenEntity = CredentialEntity & {
/** Full tenant or organizational identifier that the account belongs to */
realm: string;
/** Permissions that are included in the token, or for refresh tokens, the resource identifier. */
target: string;
/** Absolute device time when entry was created in the cache. */
cachedAt: string;
/** Token expiry time, calculated based on current UTC time in seconds. Represented as a string. */
expiresOn: string;
/** Additional extended expiry time until when token is valid in case of server-side outage. Represented as string in UTC seconds. */
extendedExpiresOn?: string;
/** Used for proactive refresh */
refreshOn?: string;
/** Matches the authentication scheme for which the token was issued (i.e. Bearer or pop) */
tokenType?: AuthenticationScheme;
/** Stringified claims object */
requestedClaims?: string;
/** Matches the SHA 256 hash of the claims object included in the token request */
requestedClaimsHash?: string;
};
//# sourceMappingURL=AccessTokenEntity.d.ts.map

View File

@@ -0,0 +1 @@
{"version":3,"file":"AccessTokenEntity.d.ts","sourceRoot":"","sources":["../../../src/cache/entities/AccessTokenEntity.ts"],"names":[],"mappings":"AAKA,OAAO,EAAE,gBAAgB,EAAE,MAAM,uBAAuB,CAAC;AACzD,OAAO,EAAE,oBAAoB,EAAE,MAAM,0BAA0B,CAAC;AAEhE;;GAEG;AACH,MAAM,MAAM,iBAAiB,GAAG,gBAAgB,GAAG;IAC/C,2EAA2E;IAC3E,KAAK,EAAE,MAAM,CAAC;IACd,kGAAkG;IAClG,MAAM,EAAE,MAAM,CAAC;IACf,gEAAgE;IAChE,QAAQ,EAAE,MAAM,CAAC;IACjB,mGAAmG;IACnG,SAAS,EAAE,MAAM,CAAC;IAClB,qIAAqI;IACrI,iBAAiB,CAAC,EAAE,MAAM,CAAC;IAC3B,iCAAiC;IACjC,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,4FAA4F;IAC5F,SAAS,CAAC,EAAE,oBAAoB,CAAC;IACjC,gCAAgC;IAChC,eAAe,CAAC,EAAE,MAAM,CAAC;IACzB,kFAAkF;IAClF,mBAAmB,CAAC,EAAE,MAAM,CAAC;CAChC,CAAC"}

View File

@@ -0,0 +1,107 @@
import { Authority } from "../../authority/Authority.js";
import { ICrypto } from "../../crypto/ICrypto.js";
import { AccountInfo, TenantProfile } from "../../account/AccountInfo.js";
import { AuthorityType } from "../../authority/AuthorityType.js";
import { Logger } from "../../logger/Logger.js";
import { TokenClaims } from "../../account/TokenClaims.js";
/**
* Type that defines required and optional parameters for an Account field (based on universal cache schema implemented by all MSALs).
*
* Key : Value Schema
*
* Key: <home_account_id>-<environment>-<realm*>
*
* Value Schema:
* {
* homeAccountId: home account identifier for the auth scheme,
* environment: entity that issued the token, represented as a full host
* realm: Full tenant or organizational identifier that the account belongs to
* localAccountId: Original tenant-specific accountID, usually used for legacy cases
* username: primary username that represents the user, usually corresponds to preferred_username in the v2 endpt
* authorityType: Accounts authority type as a string
* name: Full name for the account, including given name and family name,
* lastModificationTime: last time this entity was modified in the cache
* lastModificationApp:
* nativeAccountId: Account identifier on the native device
* tenantProfiles: Array of tenant profile objects for each tenant that the account has authenticated with in the browser
* }
* @internal
*/
export declare class AccountEntity {
homeAccountId: string;
environment: string;
realm: string;
localAccountId: string;
username: string;
authorityType: string;
clientInfo?: string;
name?: string;
lastModificationTime?: string;
lastModificationApp?: string;
cloudGraphHostName?: string;
msGraphHost?: string;
nativeAccountId?: string;
tenantProfiles?: Array<TenantProfile>;
/**
* Generate Account Id key component as per the schema: <home_account_id>-<environment>
*/
generateAccountId(): string;
/**
* Generate Account Cache Key as per the schema: <home_account_id>-<environment>-<realm*>
*/
generateAccountKey(): string;
/**
* Returns the AccountInfo interface for this account.
*/
getAccountInfo(): AccountInfo;
/**
* Returns true if the account entity is in single tenant format (outdated), false otherwise
*/
isSingleTenant(): boolean;
/**
* Generates account key from interface
* @param accountInterface
*/
static generateAccountCacheKey(accountInterface: AccountInfo): string;
/**
* Build Account cache from IdToken, clientInfo and authority/policy. Associated with AAD.
* @param accountDetails
*/
static createAccount(accountDetails: {
homeAccountId: string;
idTokenClaims?: TokenClaims;
clientInfo?: string;
cloudGraphHostName?: string;
msGraphHost?: string;
environment?: string;
nativeAccountId?: string;
tenantProfiles?: Array<TenantProfile>;
}, authority: Authority, base64Decode?: (input: string) => string): AccountEntity;
/**
* Creates an AccountEntity object from AccountInfo
* @param accountInfo
* @param cloudGraphHostName
* @param msGraphHost
* @returns
*/
static createFromAccountInfo(accountInfo: AccountInfo, cloudGraphHostName?: string, msGraphHost?: string): AccountEntity;
/**
* Generate HomeAccountId from server response
* @param serverClientInfo
* @param authType
*/
static generateHomeAccountId(serverClientInfo: string, authType: AuthorityType, logger: Logger, cryptoObj: ICrypto, idTokenClaims?: TokenClaims): string;
/**
* Validates an entity: checks for all expected params
* @param entity
*/
static isAccountEntity(entity: object): boolean;
/**
* Helper function to determine whether 2 accountInfo objects represent the same account
* @param accountA
* @param accountB
* @param compareClaims - If set to true idTokenClaims will also be compared to determine account equality
*/
static accountInfoIsEqual(accountA: AccountInfo | null, accountB: AccountInfo | null, compareClaims?: boolean): boolean;
}
//# sourceMappingURL=AccountEntity.d.ts.map

View File

@@ -0,0 +1 @@
{"version":3,"file":"AccountEntity.d.ts","sourceRoot":"","sources":["../../../src/cache/entities/AccountEntity.ts"],"names":[],"mappings":"AAMA,OAAO,EAAE,SAAS,EAAE,MAAM,8BAA8B,CAAC;AACzD,OAAO,EAAE,OAAO,EAAE,MAAM,yBAAyB,CAAC;AAElD,OAAO,EACH,WAAW,EACX,aAAa,EAEhB,MAAM,8BAA8B,CAAC;AAKtC,OAAO,EAAE,aAAa,EAAE,MAAM,kCAAkC,CAAC;AACjE,OAAO,EAAE,MAAM,EAAE,MAAM,wBAAwB,CAAC;AAChD,OAAO,EACH,WAAW,EAEd,MAAM,8BAA8B,CAAC;AAGtC;;;;;;;;;;;;;;;;;;;;;;GAsBG;AACH,qBAAa,aAAa;IACtB,aAAa,EAAE,MAAM,CAAC;IACtB,WAAW,EAAE,MAAM,CAAC;IACpB,KAAK,EAAE,MAAM,CAAC;IACd,cAAc,EAAE,MAAM,CAAC;IACvB,QAAQ,EAAE,MAAM,CAAC;IACjB,aAAa,EAAE,MAAM,CAAC;IACtB,UAAU,CAAC,EAAE,MAAM,CAAC;IACpB,IAAI,CAAC,EAAE,MAAM,CAAC;IACd,oBAAoB,CAAC,EAAE,MAAM,CAAC;IAC9B,mBAAmB,CAAC,EAAE,MAAM,CAAC;IAC7B,kBAAkB,CAAC,EAAE,MAAM,CAAC;IAC5B,WAAW,CAAC,EAAE,MAAM,CAAC;IACrB,eAAe,CAAC,EAAE,MAAM,CAAC;IACzB,cAAc,CAAC,EAAE,KAAK,CAAC,aAAa,CAAC,CAAC;IAEtC;;OAEG;IACH,iBAAiB,IAAI,MAAM;IAK3B;;OAEG;IACH,kBAAkB,IAAI,MAAM;IAU5B;;OAEG;IACH,cAAc,IAAI,WAAW;IAmB7B;;OAEG;IACH,cAAc,IAAI,OAAO;IAIzB;;;OAGG;IACH,MAAM,CAAC,uBAAuB,CAAC,gBAAgB,EAAE,WAAW,GAAG,MAAM;IAWrE;;;OAGG;IACH,MAAM,CAAC,aAAa,CAChB,cAAc,EAAE;QACZ,aAAa,EAAE,MAAM,CAAC;QACtB,aAAa,CAAC,EAAE,WAAW,CAAC;QAC5B,UAAU,CAAC,EAAE,MAAM,CAAC;QACpB,kBAAkB,CAAC,EAAE,MAAM,CAAC;QAC5B,WAAW,CAAC,EAAE,MAAM,CAAC;QACrB,WAAW,CAAC,EAAE,MAAM,CAAC;QACrB,eAAe,CAAC,EAAE,MAAM,CAAC;QACzB,cAAc,CAAC,EAAE,KAAK,CAAC,aAAa,CAAC,CAAC;KACzC,EACD,SAAS,EAAE,SAAS,EACpB,YAAY,CAAC,EAAE,CAAC,KAAK,EAAE,MAAM,KAAK,MAAM,GACzC,aAAa;IAiFhB;;;;;;OAMG;IACH,MAAM,CAAC,qBAAqB,CACxB,WAAW,EAAE,WAAW,EACxB,kBAAkB,CAAC,EAAE,MAAM,EAC3B,WAAW,CAAC,EAAE,MAAM,GACrB,aAAa;IAyBhB;;;;OAIG;IACH,MAAM,CAAC,qBAAqB,CACxB,gBAAgB,EAAE,MAAM,EACxB,QAAQ,EAAE,aAAa,EACvB,MAAM,EAAE,MAAM,EACd,SAAS,EAAE,OAAO,EAClB,aAAa,CAAC,EAAE,WAAW,GAC5B,MAAM;IA2BT;;;OAGG;IACH,MAAM,CAAC,eAAe,CAAC,MAAM,EAAE,MAAM,GAAG,OAAO;IAe/C;;;;;OAKG;IACH,MAAM,CAAC,kBAAkB,CACrB,QAAQ,EAAE,WAAW,GAAG,IAAI,EAC5B,QAAQ,EAAE,WAAW,GAAG,IAAI,EAC5B,aAAa,CAAC,EAAE,OAAO,GACxB,OAAO;CA4Bb"}

View File

@@ -0,0 +1,254 @@
/*! @azure/msal-common v15.1.1 2025-02-05 */
'use strict';
import { Separators, CacheAccountType } from '../../utils/Constants.mjs';
import { buildClientInfo } from '../../account/ClientInfo.mjs';
import { buildTenantProfile } from '../../account/AccountInfo.mjs';
import { createClientAuthError } from '../../error/ClientAuthError.mjs';
import { AuthorityType } from '../../authority/AuthorityType.mjs';
import { getTenantIdFromIdTokenClaims } from '../../account/TokenClaims.mjs';
import { ProtocolMode } from '../../authority/ProtocolMode.mjs';
import { invalidCacheEnvironment } from '../../error/ClientAuthErrorCodes.mjs';
/*
* Copyright (c) Microsoft Corporation. All rights reserved.
* Licensed under the MIT License.
*/
/**
* Type that defines required and optional parameters for an Account field (based on universal cache schema implemented by all MSALs).
*
* Key : Value Schema
*
* Key: <home_account_id>-<environment>-<realm*>
*
* Value Schema:
* {
* homeAccountId: home account identifier for the auth scheme,
* environment: entity that issued the token, represented as a full host
* realm: Full tenant or organizational identifier that the account belongs to
* localAccountId: Original tenant-specific accountID, usually used for legacy cases
* username: primary username that represents the user, usually corresponds to preferred_username in the v2 endpt
* authorityType: Accounts authority type as a string
* name: Full name for the account, including given name and family name,
* lastModificationTime: last time this entity was modified in the cache
* lastModificationApp:
* nativeAccountId: Account identifier on the native device
* tenantProfiles: Array of tenant profile objects for each tenant that the account has authenticated with in the browser
* }
* @internal
*/
class AccountEntity {
/**
* Generate Account Id key component as per the schema: <home_account_id>-<environment>
*/
generateAccountId() {
const accountId = [this.homeAccountId, this.environment];
return accountId.join(Separators.CACHE_KEY_SEPARATOR).toLowerCase();
}
/**
* Generate Account Cache Key as per the schema: <home_account_id>-<environment>-<realm*>
*/
generateAccountKey() {
return AccountEntity.generateAccountCacheKey({
homeAccountId: this.homeAccountId,
environment: this.environment,
tenantId: this.realm,
username: this.username,
localAccountId: this.localAccountId,
});
}
/**
* Returns the AccountInfo interface for this account.
*/
getAccountInfo() {
return {
homeAccountId: this.homeAccountId,
environment: this.environment,
tenantId: this.realm,
username: this.username,
localAccountId: this.localAccountId,
name: this.name,
nativeAccountId: this.nativeAccountId,
authorityType: this.authorityType,
// Deserialize tenant profiles array into a Map
tenantProfiles: new Map((this.tenantProfiles || []).map((tenantProfile) => {
return [tenantProfile.tenantId, tenantProfile];
})),
};
}
/**
* Returns true if the account entity is in single tenant format (outdated), false otherwise
*/
isSingleTenant() {
return !this.tenantProfiles;
}
/**
* Generates account key from interface
* @param accountInterface
*/
static generateAccountCacheKey(accountInterface) {
const homeTenantId = accountInterface.homeAccountId.split(".")[1];
const accountKey = [
accountInterface.homeAccountId,
accountInterface.environment || "",
homeTenantId || accountInterface.tenantId || "",
];
return accountKey.join(Separators.CACHE_KEY_SEPARATOR).toLowerCase();
}
/**
* Build Account cache from IdToken, clientInfo and authority/policy. Associated with AAD.
* @param accountDetails
*/
static createAccount(accountDetails, authority, base64Decode) {
const account = new AccountEntity();
if (authority.authorityType === AuthorityType.Adfs) {
account.authorityType = CacheAccountType.ADFS_ACCOUNT_TYPE;
}
else if (authority.protocolMode === ProtocolMode.AAD) {
account.authorityType = CacheAccountType.MSSTS_ACCOUNT_TYPE;
}
else {
account.authorityType = CacheAccountType.GENERIC_ACCOUNT_TYPE;
}
let clientInfo;
if (accountDetails.clientInfo && base64Decode) {
clientInfo = buildClientInfo(accountDetails.clientInfo, base64Decode);
}
account.clientInfo = accountDetails.clientInfo;
account.homeAccountId = accountDetails.homeAccountId;
account.nativeAccountId = accountDetails.nativeAccountId;
const env = accountDetails.environment ||
(authority && authority.getPreferredCache());
if (!env) {
throw createClientAuthError(invalidCacheEnvironment);
}
account.environment = env;
// non AAD scenarios can have empty realm
account.realm =
clientInfo?.utid ||
getTenantIdFromIdTokenClaims(accountDetails.idTokenClaims) ||
"";
// How do you account for MSA CID here?
account.localAccountId =
clientInfo?.uid ||
accountDetails.idTokenClaims?.oid ||
accountDetails.idTokenClaims?.sub ||
"";
/*
* In B2C scenarios the emails claim is used instead of preferred_username and it is an array.
* In most cases it will contain a single email. This field should not be relied upon if a custom
* policy is configured to return more than 1 email.
*/
const preferredUsername = accountDetails.idTokenClaims?.preferred_username ||
accountDetails.idTokenClaims?.upn;
const email = accountDetails.idTokenClaims?.emails
? accountDetails.idTokenClaims.emails[0]
: null;
account.username = preferredUsername || email || "";
account.name = accountDetails.idTokenClaims?.name || "";
account.cloudGraphHostName = accountDetails.cloudGraphHostName;
account.msGraphHost = accountDetails.msGraphHost;
if (accountDetails.tenantProfiles) {
account.tenantProfiles = accountDetails.tenantProfiles;
}
else {
const tenantProfile = buildTenantProfile(accountDetails.homeAccountId, account.localAccountId, account.realm, accountDetails.idTokenClaims);
account.tenantProfiles = [tenantProfile];
}
return account;
}
/**
* Creates an AccountEntity object from AccountInfo
* @param accountInfo
* @param cloudGraphHostName
* @param msGraphHost
* @returns
*/
static createFromAccountInfo(accountInfo, cloudGraphHostName, msGraphHost) {
const account = new AccountEntity();
account.authorityType =
accountInfo.authorityType || CacheAccountType.GENERIC_ACCOUNT_TYPE;
account.homeAccountId = accountInfo.homeAccountId;
account.localAccountId = accountInfo.localAccountId;
account.nativeAccountId = accountInfo.nativeAccountId;
account.realm = accountInfo.tenantId;
account.environment = accountInfo.environment;
account.username = accountInfo.username;
account.name = accountInfo.name;
account.cloudGraphHostName = cloudGraphHostName;
account.msGraphHost = msGraphHost;
// Serialize tenant profiles map into an array
account.tenantProfiles = Array.from(accountInfo.tenantProfiles?.values() || []);
return account;
}
/**
* Generate HomeAccountId from server response
* @param serverClientInfo
* @param authType
*/
static generateHomeAccountId(serverClientInfo, authType, logger, cryptoObj, idTokenClaims) {
// since ADFS/DSTS do not have tid and does not set client_info
if (!(authType === AuthorityType.Adfs ||
authType === AuthorityType.Dsts)) {
// for cases where there is clientInfo
if (serverClientInfo) {
try {
const clientInfo = buildClientInfo(serverClientInfo, cryptoObj.base64Decode);
if (clientInfo.uid && clientInfo.utid) {
return `${clientInfo.uid}.${clientInfo.utid}`;
}
}
catch (e) { }
}
logger.warning("No client info in response");
}
// default to "sub" claim
return idTokenClaims?.sub || "";
}
/**
* Validates an entity: checks for all expected params
* @param entity
*/
static isAccountEntity(entity) {
if (!entity) {
return false;
}
return (entity.hasOwnProperty("homeAccountId") &&
entity.hasOwnProperty("environment") &&
entity.hasOwnProperty("realm") &&
entity.hasOwnProperty("localAccountId") &&
entity.hasOwnProperty("username") &&
entity.hasOwnProperty("authorityType"));
}
/**
* Helper function to determine whether 2 accountInfo objects represent the same account
* @param accountA
* @param accountB
* @param compareClaims - If set to true idTokenClaims will also be compared to determine account equality
*/
static accountInfoIsEqual(accountA, accountB, compareClaims) {
if (!accountA || !accountB) {
return false;
}
let claimsMatch = true; // default to true so as to not fail comparison below if compareClaims: false
if (compareClaims) {
const accountAClaims = (accountA.idTokenClaims ||
{});
const accountBClaims = (accountB.idTokenClaims ||
{});
// issued at timestamp and nonce are expected to change each time a new id token is acquired
claimsMatch =
accountAClaims.iat === accountBClaims.iat &&
accountAClaims.nonce === accountBClaims.nonce;
}
return (accountA.homeAccountId === accountB.homeAccountId &&
accountA.localAccountId === accountB.localAccountId &&
accountA.username === accountB.username &&
accountA.tenantId === accountB.tenantId &&
accountA.environment === accountB.environment &&
accountA.nativeAccountId === accountB.nativeAccountId &&
claimsMatch);
}
}
export { AccountEntity };
//# sourceMappingURL=AccountEntity.mjs.map

File diff suppressed because one or more lines are too long

View File

@@ -0,0 +1,12 @@
/**
* App Metadata Cache Type
*/
export type AppMetadataEntity = {
/** clientId of the application */
clientId: string;
/** entity that issued the token, represented as a full host */
environment: string;
/** Family identifier, '1' represents Microsoft Family */
familyId?: string;
};
//# sourceMappingURL=AppMetadataEntity.d.ts.map

View File

@@ -0,0 +1 @@
{"version":3,"file":"AppMetadataEntity.d.ts","sourceRoot":"","sources":["../../../src/cache/entities/AppMetadataEntity.ts"],"names":[],"mappings":"AAKA;;GAEG;AACH,MAAM,MAAM,iBAAiB,GAAG;IAC5B,kCAAkC;IAClC,QAAQ,EAAE,MAAM,CAAC;IACjB,+DAA+D;IAC/D,WAAW,EAAE,MAAM,CAAC;IACpB,yDAAyD;IACzD,QAAQ,CAAC,EAAE,MAAM,CAAC;CACrB,CAAC"}

View File

@@ -0,0 +1,16 @@
/** @internal */
export type AuthorityMetadataEntity = {
aliases: Array<string>;
preferred_cache: string;
preferred_network: string;
canonical_authority: string;
authorization_endpoint: string;
token_endpoint: string;
end_session_endpoint?: string;
issuer: string;
aliasesFromNetwork: boolean;
endpointsFromNetwork: boolean;
expiresAt: number;
jwks_uri: string;
};
//# sourceMappingURL=AuthorityMetadataEntity.d.ts.map

View File

@@ -0,0 +1 @@
{"version":3,"file":"AuthorityMetadataEntity.d.ts","sourceRoot":"","sources":["../../../src/cache/entities/AuthorityMetadataEntity.ts"],"names":[],"mappings":"AAKA,gBAAgB;AAChB,MAAM,MAAM,uBAAuB,GAAG;IAClC,OAAO,EAAE,KAAK,CAAC,MAAM,CAAC,CAAC;IACvB,eAAe,EAAE,MAAM,CAAC;IACxB,iBAAiB,EAAE,MAAM,CAAC;IAC1B,mBAAmB,EAAE,MAAM,CAAC;IAC5B,sBAAsB,EAAE,MAAM,CAAC;IAC/B,cAAc,EAAE,MAAM,CAAC;IACvB,oBAAoB,CAAC,EAAE,MAAM,CAAC;IAC9B,MAAM,EAAE,MAAM,CAAC;IACf,kBAAkB,EAAE,OAAO,CAAC;IAC5B,oBAAoB,EAAE,OAAO,CAAC;IAC9B,SAAS,EAAE,MAAM,CAAC;IAClB,QAAQ,EAAE,MAAM,CAAC;CACpB,CAAC"}

View File

@@ -0,0 +1,14 @@
import { IdTokenEntity } from "./IdTokenEntity.js";
import { AccessTokenEntity } from "./AccessTokenEntity.js";
import { RefreshTokenEntity } from "./RefreshTokenEntity.js";
import { AccountEntity } from "./AccountEntity.js";
import { AppMetadataEntity } from "./AppMetadataEntity.js";
/** @internal */
export type CacheRecord = {
account?: AccountEntity | null;
idToken?: IdTokenEntity | null;
accessToken?: AccessTokenEntity | null;
refreshToken?: RefreshTokenEntity | null;
appMetadata?: AppMetadataEntity | null;
};
//# sourceMappingURL=CacheRecord.d.ts.map

View File

@@ -0,0 +1 @@
{"version":3,"file":"CacheRecord.d.ts","sourceRoot":"","sources":["../../../src/cache/entities/CacheRecord.ts"],"names":[],"mappings":"AAKA,OAAO,EAAE,aAAa,EAAE,MAAM,oBAAoB,CAAC;AACnD,OAAO,EAAE,iBAAiB,EAAE,MAAM,wBAAwB,CAAC;AAC3D,OAAO,EAAE,kBAAkB,EAAE,MAAM,yBAAyB,CAAC;AAC7D,OAAO,EAAE,aAAa,EAAE,MAAM,oBAAoB,CAAC;AACnD,OAAO,EAAE,iBAAiB,EAAE,MAAM,wBAAwB,CAAC;AAE3D,gBAAgB;AAChB,MAAM,MAAM,WAAW,GAAG;IACtB,OAAO,CAAC,EAAE,aAAa,GAAG,IAAI,CAAC;IAC/B,OAAO,CAAC,EAAE,aAAa,GAAG,IAAI,CAAC;IAC/B,WAAW,CAAC,EAAE,iBAAiB,GAAG,IAAI,CAAC;IACvC,YAAY,CAAC,EAAE,kBAAkB,GAAG,IAAI,CAAC;IACzC,WAAW,CAAC,EAAE,iBAAiB,GAAG,IAAI,CAAC;CAC1C,CAAC"}

View File

@@ -0,0 +1,31 @@
import { CredentialType, AuthenticationScheme } from "../../utils/Constants.js";
/**
* Credential Cache Type
*/
export type CredentialEntity = {
/** Identifier for the user in their home tenant*/
homeAccountId: string;
/** Entity that issued the token, represented as a full host */
environment: string;
/** Type of credential */
credentialType: CredentialType;
/** Client ID of the application */
clientId: string;
/** Actual credential as a string */
secret: string;
/** Family ID identifier, usually only used for refresh tokens */
familyId?: string;
/** Full tenant or organizational identifier that the account belongs to */
realm?: string;
/** Permissions that are included in the token, or for refresh tokens, the resource identifier. */
target?: string;
/** Matches the SHA 256 hash of the obo_assertion for the OBO flow */
userAssertionHash?: string;
/** Matches the authentication scheme for which the token was issued (i.e. Bearer or pop) */
tokenType?: AuthenticationScheme;
/** KeyId for PoP and SSH tokens stored in the kid claim */
keyId?: string;
/** Matches the SHA 256 hash of the claims object included in the token request */
requestedClaimsHash?: string;
};
//# sourceMappingURL=CredentialEntity.d.ts.map

View File

@@ -0,0 +1 @@
{"version":3,"file":"CredentialEntity.d.ts","sourceRoot":"","sources":["../../../src/cache/entities/CredentialEntity.ts"],"names":[],"mappings":"AAKA,OAAO,EAAE,cAAc,EAAE,oBAAoB,EAAE,MAAM,0BAA0B,CAAC;AAEhF;;GAEG;AACH,MAAM,MAAM,gBAAgB,GAAG;IAC3B,kDAAkD;IAClD,aAAa,EAAE,MAAM,CAAC;IACtB,+DAA+D;IAC/D,WAAW,EAAE,MAAM,CAAC;IACpB,yBAAyB;IACzB,cAAc,EAAE,cAAc,CAAC;IAC/B,mCAAmC;IACnC,QAAQ,EAAE,MAAM,CAAC;IACjB,oCAAoC;IACpC,MAAM,EAAE,MAAM,CAAC;IACf,iEAAiE;IACjE,QAAQ,CAAC,EAAE,MAAM,CAAC;IAClB,2EAA2E;IAC3E,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,kGAAkG;IAClG,MAAM,CAAC,EAAE,MAAM,CAAC;IAChB,qEAAqE;IACrE,iBAAiB,CAAC,EAAE,MAAM,CAAC;IAC3B,4FAA4F;IAC5F,SAAS,CAAC,EAAE,oBAAoB,CAAC;IACjC,2DAA2D;IAC3D,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,kFAAkF;IAClF,mBAAmB,CAAC,EAAE,MAAM,CAAC;CAChC,CAAC"}

View File

@@ -0,0 +1,9 @@
import { CredentialEntity } from "./CredentialEntity.js";
/**
* Id Token Cache Type
*/
export type IdTokenEntity = CredentialEntity & {
/** Full tenant or organizational identifier that the account belongs to */
realm: string;
};
//# sourceMappingURL=IdTokenEntity.d.ts.map

View File

@@ -0,0 +1 @@
{"version":3,"file":"IdTokenEntity.d.ts","sourceRoot":"","sources":["../../../src/cache/entities/IdTokenEntity.ts"],"names":[],"mappings":"AAKA,OAAO,EAAE,gBAAgB,EAAE,MAAM,uBAAuB,CAAC;AAEzD;;GAEG;AACH,MAAM,MAAM,aAAa,GAAG,gBAAgB,GAAG;IAC3C,4EAA4E;IAC5E,KAAK,EAAE,MAAM,CAAC;CACjB,CAAC"}

View File

@@ -0,0 +1,8 @@
import { CredentialEntity } from "./CredentialEntity.js";
/**
* Refresh Token Cache Type
*/
export type RefreshTokenEntity = CredentialEntity & {
expiresOn?: string;
};
//# sourceMappingURL=RefreshTokenEntity.d.ts.map

View File

@@ -0,0 +1 @@
{"version":3,"file":"RefreshTokenEntity.d.ts","sourceRoot":"","sources":["../../../src/cache/entities/RefreshTokenEntity.ts"],"names":[],"mappings":"AAKA,OAAO,EAAE,gBAAgB,EAAE,MAAM,uBAAuB,CAAC;AAEzD;;GAEG;AACH,MAAM,MAAM,kBAAkB,GAAG,gBAAgB,GAAG;IAChD,SAAS,CAAC,EAAE,MAAM,CAAC;CACtB,CAAC"}

View File

@@ -0,0 +1,7 @@
export type ServerTelemetryEntity = {
failedRequests: Array<string | number>;
errors: string[];
cacheHits: number;
nativeBrokerErrorCode?: string;
};
//# sourceMappingURL=ServerTelemetryEntity.d.ts.map

View File

@@ -0,0 +1 @@
{"version":3,"file":"ServerTelemetryEntity.d.ts","sourceRoot":"","sources":["../../../src/cache/entities/ServerTelemetryEntity.ts"],"names":[],"mappings":"AAKA,MAAM,MAAM,qBAAqB,GAAG;IAChC,cAAc,EAAE,KAAK,CAAC,MAAM,GAAG,MAAM,CAAC,CAAC;IACvC,MAAM,EAAE,MAAM,EAAE,CAAC;IACjB,SAAS,EAAE,MAAM,CAAC;IAClB,qBAAqB,CAAC,EAAE,MAAM,CAAC;CAClC,CAAC"}

View File

@@ -0,0 +1,8 @@
export type ThrottlingEntity = {
throttleTime: number;
error?: string;
errorCodes?: Array<string>;
errorMessage?: string;
subError?: string;
};
//# sourceMappingURL=ThrottlingEntity.d.ts.map

View File

@@ -0,0 +1 @@
{"version":3,"file":"ThrottlingEntity.d.ts","sourceRoot":"","sources":["../../../src/cache/entities/ThrottlingEntity.ts"],"names":[],"mappings":"AAKA,MAAM,MAAM,gBAAgB,GAAG;IAE3B,YAAY,EAAE,MAAM,CAAC;IAErB,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,UAAU,CAAC,EAAE,KAAK,CAAC,MAAM,CAAC,CAAC;IAC3B,YAAY,CAAC,EAAE,MAAM,CAAC;IACtB,QAAQ,CAAC,EAAE,MAAM,CAAC;CACrB,CAAC"}

View File

@@ -0,0 +1,167 @@
import { AccountFilter } from "../utils/CacheTypes.js";
import { CacheRecord } from "../entities/CacheRecord.js";
import { AccountEntity } from "../entities/AccountEntity.js";
import { AccountInfo } from "../../account/AccountInfo.js";
import { AppMetadataEntity } from "../entities/AppMetadataEntity.js";
import { ServerTelemetryEntity } from "../entities/ServerTelemetryEntity.js";
import { ThrottlingEntity } from "../entities/ThrottlingEntity.js";
import { IdTokenEntity } from "../entities/IdTokenEntity.js";
import { AccessTokenEntity } from "../entities/AccessTokenEntity.js";
import { RefreshTokenEntity } from "../entities/RefreshTokenEntity.js";
import { AuthorityMetadataEntity } from "../entities/AuthorityMetadataEntity.js";
import { StoreInCache } from "../../request/StoreInCache.js";
export interface ICacheManager {
/**
* fetch the account entity from the platform cache
* @param accountKey
*/
getAccount(accountKey: string): AccountEntity | null;
/**
* set account entity in the platform cache
* @param account
*/
setAccount(account: AccountEntity, correlationId: string): Promise<void>;
/**
* Returns true if the given key matches our account key schema. Also matches homeAccountId and/or tenantId if provided
* @param key
* @param homeAccountId
* @param tenantId
* @returns
*/
isAccountKey(key: string, homeAccountId?: string, tenantId?: string): boolean;
/**
* fetch the idToken entity from the platform cache
* @param idTokenKey
*/
getIdTokenCredential(idTokenKey: string): IdTokenEntity | null;
/**
* set idToken entity to the platform cache
* @param idToken
*/
setIdTokenCredential(idToken: IdTokenEntity, correlationId: string): Promise<void>;
/**
* fetch the idToken entity from the platform cache
* @param accessTokenKey
*/
getAccessTokenCredential(accessTokenKey: string): AccessTokenEntity | null;
/**
* set idToken entity to the platform cache
* @param accessToken
*/
setAccessTokenCredential(accessToken: AccessTokenEntity, correlationId: string): Promise<void>;
/**
* fetch the idToken entity from the platform cache
* @param refreshTokenKey
*/
getRefreshTokenCredential(refreshTokenKey: string): RefreshTokenEntity | null;
/**
* set idToken entity 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;
/**
* fetch cloud discovery metadata entity from the platform cache
* @param key
*/
getAuthorityMetadata(key: string): AuthorityMetadataEntity | null;
/**
* Get cache keys for authority metadata
*/
getAuthorityMetadataKeys(): Array<string>;
/**
* set cloud discovery metadata entity to the platform cache
* @param key
* @param value
*/
setAuthorityMetadata(key: string, value: AuthorityMetadataEntity): void;
/**
* Provide an alias to find a matching AuthorityMetadataEntity in cache
* @param host
*/
getAuthorityMetadataByAlias(host: string): AuthorityMetadataEntity | null;
/**
* given an authority generates the cache key for authorityMetadata
* @param authority
*/
generateAuthorityMetadataCacheKey(authority: string): string;
/**
* 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;
/**
* Returns all accounts in cache
*/
getAllAccounts(): AccountInfo[];
/**
* saves a cache record
* @param cacheRecord
*/
saveCacheRecord(cacheRecord: CacheRecord, correlationId: string, storeInCache?: StoreInCache): Promise<void>;
/**
* retrieve accounts matching all provided filters; if no filter is set, get all accounts
* @param homeAccountId
* @param environment
* @param realm
*/
getAccountsFilteredBy(filter: AccountFilter): AccountEntity[];
/**
* Get AccountInfo object based on provided filters
* @param filter
*/
getAccountInfoFilteredBy(filter: AccountFilter): AccountInfo | null;
/**
* Removes all accounts and related tokens from cache.
*/
removeAllAccounts(): Promise<void>;
/**
* returns a boolean if the given account is removed
* @param account
*/
removeAccount(accountKey: string): Promise<void>;
/**
* returns a boolean if the given account is removed
* @param account
*/
removeAccountContext(account: AccountEntity): Promise<void>;
/**
* @param key
*/
removeIdToken(key: string): void;
/**
* @param key
*/
removeAccessToken(key: string): Promise<void>;
/**
* @param key
*/
removeRefreshToken(key: string): void;
}
//# sourceMappingURL=ICacheManager.d.ts.map

View File

@@ -0,0 +1 @@
{"version":3,"file":"ICacheManager.d.ts","sourceRoot":"","sources":["../../../src/cache/interface/ICacheManager.ts"],"names":[],"mappings":"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"}

View File

@@ -0,0 +1,6 @@
import { TokenCacheContext } from "../persistence/TokenCacheContext.js";
export interface ICachePlugin {
beforeCacheAccess: (tokenCacheContext: TokenCacheContext) => Promise<void>;
afterCacheAccess: (tokenCacheContext: TokenCacheContext) => Promise<void>;
}
//# sourceMappingURL=ICachePlugin.d.ts.map

View File

@@ -0,0 +1 @@
{"version":3,"file":"ICachePlugin.d.ts","sourceRoot":"","sources":["../../../src/cache/interface/ICachePlugin.ts"],"names":[],"mappings":"AAKA,OAAO,EAAE,iBAAiB,EAAE,MAAM,qCAAqC,CAAC;AAExE,MAAM,WAAW,YAAY;IACzB,iBAAiB,EAAE,CAAC,iBAAiB,EAAE,iBAAiB,KAAK,OAAO,CAAC,IAAI,CAAC,CAAC;IAC3E,gBAAgB,EAAE,CAAC,iBAAiB,EAAE,iBAAiB,KAAK,OAAO,CAAC,IAAI,CAAC,CAAC;CAC7E"}

View File

@@ -0,0 +1,5 @@
export interface ISerializableTokenCache {
deserialize: (cache: string) => void;
serialize: () => string;
}
//# sourceMappingURL=ISerializableTokenCache.d.ts.map

View File

@@ -0,0 +1 @@
{"version":3,"file":"ISerializableTokenCache.d.ts","sourceRoot":"","sources":["../../../src/cache/interface/ISerializableTokenCache.ts"],"names":[],"mappings":"AAKA,MAAM,WAAW,uBAAuB;IACpC,WAAW,EAAE,CAAC,KAAK,EAAE,MAAM,KAAK,IAAI,CAAC;IACrC,SAAS,EAAE,MAAM,MAAM,CAAC;CAC3B"}

View File

@@ -0,0 +1,24 @@
import { ISerializableTokenCache } from "../interface/ISerializableTokenCache.js";
/**
* This class instance helps track the memory changes facilitating
* decisions to read from and write to the persistent cache
*/ export declare class TokenCacheContext {
/**
* boolean indicating cache change
*/
hasChanged: boolean;
/**
* serializable token cache interface
*/
cache: ISerializableTokenCache;
constructor(tokenCache: ISerializableTokenCache, hasChanged: boolean);
/**
* boolean which indicates the changes in cache
*/
get cacheHasChanged(): boolean;
/**
* function to retrieve the token cache
*/
get tokenCache(): ISerializableTokenCache;
}
//# sourceMappingURL=TokenCacheContext.d.ts.map

View File

@@ -0,0 +1 @@
{"version":3,"file":"TokenCacheContext.d.ts","sourceRoot":"","sources":["../../../src/cache/persistence/TokenCacheContext.ts"],"names":[],"mappings":"AAKA,OAAO,EAAE,uBAAuB,EAAE,MAAM,yCAAyC,CAAC;AAElF;;;GAGG,CAAC,qBAAa,iBAAiB;IAC9B;;OAEG;IACH,UAAU,EAAE,OAAO,CAAC;IACpB;;OAEG;IACH,KAAK,EAAE,uBAAuB,CAAC;gBAEnB,UAAU,EAAE,uBAAuB,EAAE,UAAU,EAAE,OAAO;IAKpE;;OAEG;IACH,IAAI,eAAe,IAAI,OAAO,CAE7B;IAED;;OAEG;IACH,IAAI,UAAU,IAAI,uBAAuB,CAExC;CACJ"}

View File

@@ -0,0 +1,30 @@
/*! @azure/msal-common v15.1.1 2025-02-05 */
'use strict';
/*
* Copyright (c) Microsoft Corporation. All rights reserved.
* Licensed under the MIT License.
*/
/**
* This class instance helps track the memory changes facilitating
* decisions to read from and write to the persistent cache
*/ class TokenCacheContext {
constructor(tokenCache, hasChanged) {
this.cache = tokenCache;
this.hasChanged = hasChanged;
}
/**
* boolean which indicates the changes in cache
*/
get cacheHasChanged() {
return this.hasChanged;
}
/**
* function to retrieve the token cache
*/
get tokenCache() {
return this.cache;
}
}
export { TokenCacheContext };
//# sourceMappingURL=TokenCacheContext.mjs.map

View File

@@ -0,0 +1 @@
{"version":3,"file":"TokenCacheContext.mjs","sources":["../../../src/cache/persistence/TokenCacheContext.ts"],"sourcesContent":[null],"names":[],"mappings":";;AAAA;;;AAGG;AAIH;;;UAGiB,iBAAiB,CAAA;IAU9B,WAAY,CAAA,UAAmC,EAAE,UAAmB,EAAA;AAChE,QAAA,IAAI,CAAC,KAAK,GAAG,UAAU,CAAC;AACxB,QAAA,IAAI,CAAC,UAAU,GAAG,UAAU,CAAC;KAChC;AAED;;AAEG;AACH,IAAA,IAAI,eAAe,GAAA;QACf,OAAO,IAAI,CAAC,UAAU,CAAC;KAC1B;AAED;;AAEG;AACH,IAAA,IAAI,UAAU,GAAA;QACV,OAAO,IAAI,CAAC,KAAK,CAAC;KACrB;AACJ;;;;"}

View File

@@ -0,0 +1,95 @@
import { CloudDiscoveryMetadata } from "../../authority/CloudDiscoveryMetadata.js";
import { OpenIdConfigResponse } from "../../authority/OpenIdConfigResponse.js";
import { AuthenticationScheme } from "../../utils/Constants.js";
import { AccessTokenEntity } from "../entities/AccessTokenEntity.js";
import { AppMetadataEntity } from "../entities/AppMetadataEntity.js";
import { AuthorityMetadataEntity } from "../entities/AuthorityMetadataEntity.js";
import { CredentialEntity } from "../entities/CredentialEntity.js";
import { IdTokenEntity } from "../entities/IdTokenEntity.js";
import { RefreshTokenEntity } from "../entities/RefreshTokenEntity.js";
/**
* Cache Key: <home_account_id>-<environment>-<credential_type>-<client_id or familyId>-<realm>-<scopes>-<claims hash>-<scheme>
* IdToken Example: uid.utid-login.microsoftonline.com-idtoken-app_client_id-contoso.com
* AccessToken Example: uid.utid-login.microsoftonline.com-accesstoken-app_client_id-contoso.com-scope1 scope2--pop
* RefreshToken Example: uid.utid-login.microsoftonline.com-refreshtoken-1-contoso.com
* @param credentialEntity
* @returns
*/
export declare function generateCredentialKey(credentialEntity: CredentialEntity): string;
/**
* Create IdTokenEntity
* @param homeAccountId
* @param authenticationResult
* @param clientId
* @param authority
*/
export declare function createIdTokenEntity(homeAccountId: string, environment: string, idToken: string, clientId: string, tenantId: string): IdTokenEntity;
/**
* Create AccessTokenEntity
* @param homeAccountId
* @param environment
* @param accessToken
* @param clientId
* @param tenantId
* @param scopes
* @param expiresOn
* @param extExpiresOn
*/
export declare function createAccessTokenEntity(homeAccountId: string, environment: string, accessToken: string, clientId: string, tenantId: string, scopes: string, expiresOn: number, extExpiresOn: number, base64Decode: (input: string) => string, refreshOn?: number, tokenType?: AuthenticationScheme, userAssertionHash?: string, keyId?: string, requestedClaims?: string, requestedClaimsHash?: string): AccessTokenEntity;
/**
* Create RefreshTokenEntity
* @param homeAccountId
* @param authenticationResult
* @param clientId
* @param authority
*/
export declare function createRefreshTokenEntity(homeAccountId: string, environment: string, refreshToken: string, clientId: string, familyId?: string, userAssertionHash?: string, expiresOn?: number): RefreshTokenEntity;
export declare function isCredentialEntity(entity: object): boolean;
/**
* Validates an entity: checks for all expected params
* @param entity
*/
export declare function isAccessTokenEntity(entity: object): boolean;
/**
* Validates an entity: checks for all expected params
* @param entity
*/
export declare function isIdTokenEntity(entity: object): boolean;
/**
* Validates an entity: checks for all expected params
* @param entity
*/
export declare function isRefreshTokenEntity(entity: object): boolean;
/**
* validates if a given cache entry is "Telemetry", parses <key,value>
* @param key
* @param entity
*/
export declare function isServerTelemetryEntity(key: string, entity?: object): boolean;
/**
* validates if a given cache entry is "Throttling", parses <key,value>
* @param key
* @param entity
*/
export declare function isThrottlingEntity(key: string, entity?: object): boolean;
/**
* Generate AppMetadata Cache Key as per the schema: appmetadata-<environment>-<client_id>
*/
export declare function generateAppMetadataKey({ environment, clientId, }: AppMetadataEntity): string;
export declare function isAppMetadataEntity(key: string, entity: object): boolean;
/**
* Validates an entity: checks for all expected params
* @param entity
*/
export declare function isAuthorityMetadataEntity(key: string, entity: object): boolean;
/**
* Reset the exiresAt value
*/
export declare function generateAuthorityMetadataExpiresAt(): number;
export declare function updateAuthorityEndpointMetadata(authorityMetadata: AuthorityMetadataEntity, updatedValues: OpenIdConfigResponse, fromNetwork: boolean): void;
export declare function updateCloudDiscoveryMetadata(authorityMetadata: AuthorityMetadataEntity, updatedValues: CloudDiscoveryMetadata, fromNetwork: boolean): void;
/**
* Returns whether or not the data needs to be refreshed
*/
export declare function isAuthorityMetadataExpired(metadata: AuthorityMetadataEntity): boolean;
//# sourceMappingURL=CacheHelpers.d.ts.map

View File

@@ -0,0 +1 @@
{"version":3,"file":"CacheHelpers.d.ts","sourceRoot":"","sources":["../../../src/cache/utils/CacheHelpers.ts"],"names":[],"mappings":"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"}

View File

@@ -0,0 +1,335 @@
/*! @azure/msal-common v15.1.1 2025-02-05 */
'use strict';
import { extractTokenClaims } from '../../account/AuthToken.mjs';
import { createClientAuthError } from '../../error/ClientAuthError.mjs';
import { Separators, CredentialType, AuthenticationScheme, SERVER_TELEM_CONSTANTS, ThrottlingConstants, APP_METADATA, AUTHORITY_METADATA_CONSTANTS } from '../../utils/Constants.mjs';
import { nowSeconds } from '../../utils/TimeUtils.mjs';
import { tokenClaimsCnfRequiredForSignedJwt } from '../../error/ClientAuthErrorCodes.mjs';
/*
* Copyright (c) Microsoft Corporation. All rights reserved.
* Licensed under the MIT License.
*/
/**
* Cache Key: <home_account_id>-<environment>-<credential_type>-<client_id or familyId>-<realm>-<scopes>-<claims hash>-<scheme>
* IdToken Example: uid.utid-login.microsoftonline.com-idtoken-app_client_id-contoso.com
* AccessToken Example: uid.utid-login.microsoftonline.com-accesstoken-app_client_id-contoso.com-scope1 scope2--pop
* RefreshToken Example: uid.utid-login.microsoftonline.com-refreshtoken-1-contoso.com
* @param credentialEntity
* @returns
*/
function generateCredentialKey(credentialEntity) {
const credentialKey = [
generateAccountId(credentialEntity),
generateCredentialId(credentialEntity),
generateTarget(credentialEntity),
generateClaimsHash(credentialEntity),
generateScheme(credentialEntity),
];
return credentialKey.join(Separators.CACHE_KEY_SEPARATOR).toLowerCase();
}
/**
* Create IdTokenEntity
* @param homeAccountId
* @param authenticationResult
* @param clientId
* @param authority
*/
function createIdTokenEntity(homeAccountId, environment, idToken, clientId, tenantId) {
const idTokenEntity = {
credentialType: CredentialType.ID_TOKEN,
homeAccountId: homeAccountId,
environment: environment,
clientId: clientId,
secret: idToken,
realm: tenantId,
};
return idTokenEntity;
}
/**
* Create AccessTokenEntity
* @param homeAccountId
* @param environment
* @param accessToken
* @param clientId
* @param tenantId
* @param scopes
* @param expiresOn
* @param extExpiresOn
*/
function createAccessTokenEntity(homeAccountId, environment, accessToken, clientId, tenantId, scopes, expiresOn, extExpiresOn, base64Decode, refreshOn, tokenType, userAssertionHash, keyId, requestedClaims, requestedClaimsHash) {
const atEntity = {
homeAccountId: homeAccountId,
credentialType: CredentialType.ACCESS_TOKEN,
secret: accessToken,
cachedAt: nowSeconds().toString(),
expiresOn: expiresOn.toString(),
extendedExpiresOn: extExpiresOn.toString(),
environment: environment,
clientId: clientId,
realm: tenantId,
target: scopes,
tokenType: tokenType || AuthenticationScheme.BEARER,
};
if (userAssertionHash) {
atEntity.userAssertionHash = userAssertionHash;
}
if (refreshOn) {
atEntity.refreshOn = refreshOn.toString();
}
if (requestedClaims) {
atEntity.requestedClaims = requestedClaims;
atEntity.requestedClaimsHash = requestedClaimsHash;
}
/*
* Create Access Token With Auth Scheme instead of regular access token
* Cast to lower to handle "bearer" from ADFS
*/
if (atEntity.tokenType?.toLowerCase() !==
AuthenticationScheme.BEARER.toLowerCase()) {
atEntity.credentialType = CredentialType.ACCESS_TOKEN_WITH_AUTH_SCHEME;
switch (atEntity.tokenType) {
case AuthenticationScheme.POP:
// Make sure keyId is present and add it to credential
const tokenClaims = extractTokenClaims(accessToken, base64Decode);
if (!tokenClaims?.cnf?.kid) {
throw createClientAuthError(tokenClaimsCnfRequiredForSignedJwt);
}
atEntity.keyId = tokenClaims.cnf.kid;
break;
case AuthenticationScheme.SSH:
atEntity.keyId = keyId;
}
}
return atEntity;
}
/**
* Create RefreshTokenEntity
* @param homeAccountId
* @param authenticationResult
* @param clientId
* @param authority
*/
function createRefreshTokenEntity(homeAccountId, environment, refreshToken, clientId, familyId, userAssertionHash, expiresOn) {
const rtEntity = {
credentialType: CredentialType.REFRESH_TOKEN,
homeAccountId: homeAccountId,
environment: environment,
clientId: clientId,
secret: refreshToken,
};
if (userAssertionHash) {
rtEntity.userAssertionHash = userAssertionHash;
}
if (familyId) {
rtEntity.familyId = familyId;
}
if (expiresOn) {
rtEntity.expiresOn = expiresOn.toString();
}
return rtEntity;
}
function isCredentialEntity(entity) {
return (entity.hasOwnProperty("homeAccountId") &&
entity.hasOwnProperty("environment") &&
entity.hasOwnProperty("credentialType") &&
entity.hasOwnProperty("clientId") &&
entity.hasOwnProperty("secret"));
}
/**
* Validates an entity: checks for all expected params
* @param entity
*/
function isAccessTokenEntity(entity) {
if (!entity) {
return false;
}
return (isCredentialEntity(entity) &&
entity.hasOwnProperty("realm") &&
entity.hasOwnProperty("target") &&
(entity["credentialType"] === CredentialType.ACCESS_TOKEN ||
entity["credentialType"] ===
CredentialType.ACCESS_TOKEN_WITH_AUTH_SCHEME));
}
/**
* Validates an entity: checks for all expected params
* @param entity
*/
function isIdTokenEntity(entity) {
if (!entity) {
return false;
}
return (isCredentialEntity(entity) &&
entity.hasOwnProperty("realm") &&
entity["credentialType"] === CredentialType.ID_TOKEN);
}
/**
* Validates an entity: checks for all expected params
* @param entity
*/
function isRefreshTokenEntity(entity) {
if (!entity) {
return false;
}
return (isCredentialEntity(entity) &&
entity["credentialType"] === CredentialType.REFRESH_TOKEN);
}
/**
* Generate Account Id key component as per the schema: <home_account_id>-<environment>
*/
function generateAccountId(credentialEntity) {
const accountId = [
credentialEntity.homeAccountId,
credentialEntity.environment,
];
return accountId.join(Separators.CACHE_KEY_SEPARATOR).toLowerCase();
}
/**
* Generate Credential Id key component as per the schema: <credential_type>-<client_id>-<realm>
*/
function generateCredentialId(credentialEntity) {
const clientOrFamilyId = credentialEntity.credentialType === CredentialType.REFRESH_TOKEN
? credentialEntity.familyId || credentialEntity.clientId
: credentialEntity.clientId;
const credentialId = [
credentialEntity.credentialType,
clientOrFamilyId,
credentialEntity.realm || "",
];
return credentialId.join(Separators.CACHE_KEY_SEPARATOR).toLowerCase();
}
/**
* Generate target key component as per schema: <target>
*/
function generateTarget(credentialEntity) {
return (credentialEntity.target || "").toLowerCase();
}
/**
* Generate requested claims key component as per schema: <requestedClaims>
*/
function generateClaimsHash(credentialEntity) {
return (credentialEntity.requestedClaimsHash || "").toLowerCase();
}
/**
* Generate scheme key componenet as per schema: <scheme>
*/
function generateScheme(credentialEntity) {
/*
* PoP Tokens and SSH certs include scheme in cache key
* Cast to lowercase to handle "bearer" from ADFS
*/
return credentialEntity.tokenType &&
credentialEntity.tokenType.toLowerCase() !==
AuthenticationScheme.BEARER.toLowerCase()
? credentialEntity.tokenType.toLowerCase()
: "";
}
/**
* validates if a given cache entry is "Telemetry", parses <key,value>
* @param key
* @param entity
*/
function isServerTelemetryEntity(key, entity) {
const validateKey = key.indexOf(SERVER_TELEM_CONSTANTS.CACHE_KEY) === 0;
let validateEntity = true;
if (entity) {
validateEntity =
entity.hasOwnProperty("failedRequests") &&
entity.hasOwnProperty("errors") &&
entity.hasOwnProperty("cacheHits");
}
return validateKey && validateEntity;
}
/**
* validates if a given cache entry is "Throttling", parses <key,value>
* @param key
* @param entity
*/
function isThrottlingEntity(key, entity) {
let validateKey = false;
if (key) {
validateKey = key.indexOf(ThrottlingConstants.THROTTLING_PREFIX) === 0;
}
let validateEntity = true;
if (entity) {
validateEntity = entity.hasOwnProperty("throttleTime");
}
return validateKey && validateEntity;
}
/**
* Generate AppMetadata Cache Key as per the schema: appmetadata-<environment>-<client_id>
*/
function generateAppMetadataKey({ environment, clientId, }) {
const appMetaDataKeyArray = [
APP_METADATA,
environment,
clientId,
];
return appMetaDataKeyArray
.join(Separators.CACHE_KEY_SEPARATOR)
.toLowerCase();
}
/*
* Validates an entity: checks for all expected params
* @param entity
*/
function isAppMetadataEntity(key, entity) {
if (!entity) {
return false;
}
return (key.indexOf(APP_METADATA) === 0 &&
entity.hasOwnProperty("clientId") &&
entity.hasOwnProperty("environment"));
}
/**
* Validates an entity: checks for all expected params
* @param entity
*/
function isAuthorityMetadataEntity(key, entity) {
if (!entity) {
return false;
}
return (key.indexOf(AUTHORITY_METADATA_CONSTANTS.CACHE_KEY) === 0 &&
entity.hasOwnProperty("aliases") &&
entity.hasOwnProperty("preferred_cache") &&
entity.hasOwnProperty("preferred_network") &&
entity.hasOwnProperty("canonical_authority") &&
entity.hasOwnProperty("authorization_endpoint") &&
entity.hasOwnProperty("token_endpoint") &&
entity.hasOwnProperty("issuer") &&
entity.hasOwnProperty("aliasesFromNetwork") &&
entity.hasOwnProperty("endpointsFromNetwork") &&
entity.hasOwnProperty("expiresAt") &&
entity.hasOwnProperty("jwks_uri"));
}
/**
* Reset the exiresAt value
*/
function generateAuthorityMetadataExpiresAt() {
return (nowSeconds() +
AUTHORITY_METADATA_CONSTANTS.REFRESH_TIME_SECONDS);
}
function updateAuthorityEndpointMetadata(authorityMetadata, updatedValues, fromNetwork) {
authorityMetadata.authorization_endpoint =
updatedValues.authorization_endpoint;
authorityMetadata.token_endpoint = updatedValues.token_endpoint;
authorityMetadata.end_session_endpoint = updatedValues.end_session_endpoint;
authorityMetadata.issuer = updatedValues.issuer;
authorityMetadata.endpointsFromNetwork = fromNetwork;
authorityMetadata.jwks_uri = updatedValues.jwks_uri;
}
function updateCloudDiscoveryMetadata(authorityMetadata, updatedValues, fromNetwork) {
authorityMetadata.aliases = updatedValues.aliases;
authorityMetadata.preferred_cache = updatedValues.preferred_cache;
authorityMetadata.preferred_network = updatedValues.preferred_network;
authorityMetadata.aliasesFromNetwork = fromNetwork;
}
/**
* Returns whether or not the data needs to be refreshed
*/
function isAuthorityMetadataExpired(metadata) {
return metadata.expiresAt <= nowSeconds();
}
export { createAccessTokenEntity, createIdTokenEntity, createRefreshTokenEntity, generateAppMetadataKey, generateAuthorityMetadataExpiresAt, generateCredentialKey, isAccessTokenEntity, isAppMetadataEntity, isAuthorityMetadataEntity, isAuthorityMetadataExpired, isCredentialEntity, isIdTokenEntity, isRefreshTokenEntity, isServerTelemetryEntity, isThrottlingEntity, updateAuthorityEndpointMetadata, updateCloudDiscoveryMetadata };
//# sourceMappingURL=CacheHelpers.mjs.map

File diff suppressed because one or more lines are too long

View File

@@ -0,0 +1,70 @@
import { AccountEntity } from "../entities/AccountEntity.js";
import { IdTokenEntity } from "../entities/IdTokenEntity.js";
import { AccessTokenEntity } from "../entities/AccessTokenEntity.js";
import { RefreshTokenEntity } from "../entities/RefreshTokenEntity.js";
import { AppMetadataEntity } from "../entities/AppMetadataEntity.js";
import { ServerTelemetryEntity } from "../entities/ServerTelemetryEntity.js";
import { ThrottlingEntity } from "../entities/ThrottlingEntity.js";
import { AuthorityMetadataEntity } from "../entities/AuthorityMetadataEntity.js";
import { AuthenticationScheme } from "../../utils/Constants.js";
import { ScopeSet } from "../../request/ScopeSet.js";
import { AccountInfo } from "../../account/AccountInfo.js";
/** @internal */
export type AccountCache = Record<string, AccountEntity>;
/** @internal */
export type IdTokenCache = Record<string, IdTokenEntity>;
/** @internal */
export type AccessTokenCache = Record<string, AccessTokenEntity>;
/** @internal */
export type RefreshTokenCache = Record<string, RefreshTokenEntity>;
/** @internal */
export type AppMetadataCache = Record<string, AppMetadataEntity>;
/**
* Object type of all accepted cache types
* @internal
*/
export type ValidCacheType = AccountEntity | IdTokenEntity | AccessTokenEntity | RefreshTokenEntity | AppMetadataEntity | AuthorityMetadataEntity | ServerTelemetryEntity | ThrottlingEntity | string;
/**
* Object type of all credential types
* @internal
*/
export type ValidCredentialType = IdTokenEntity | AccessTokenEntity | RefreshTokenEntity;
/**
* Account: <home_account_id>-<environment>-<realm*>
*/
export type AccountFilter = Omit<Partial<AccountInfo>, "idToken" | "idTokenClaims"> & {
realm?: string;
loginHint?: string;
sid?: string;
isHomeTenant?: boolean;
};
export type TenantProfileFilter = Pick<AccountFilter, "localAccountId" | "loginHint" | "name" | "sid" | "isHomeTenant" | "username">;
/**
* Credential: <home_account_id*>-<environment>-<credential_type>-<client_id>-<realm*>-<target*>-<scheme*>
*/
export type CredentialFilter = {
homeAccountId?: string;
environment?: string;
credentialType?: string;
clientId?: string;
familyId?: string;
realm?: string;
target?: ScopeSet;
userAssertionHash?: string;
tokenType?: AuthenticationScheme;
keyId?: string;
requestedClaimsHash?: string;
};
/**
* AppMetadata: appmetadata-<environment>-<client_id>
*/
export type AppMetadataFilter = {
environment?: string;
clientId?: string;
};
export type TokenKeys = {
idToken: string[];
accessToken: string[];
refreshToken: string[];
};
//# sourceMappingURL=CacheTypes.d.ts.map

View File

@@ -0,0 +1 @@
{"version":3,"file":"CacheTypes.d.ts","sourceRoot":"","sources":["../../../src/cache/utils/CacheTypes.ts"],"names":[],"mappings":"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"}