Add extracted source directory and README navigation

This commit is contained in:
Shawn Bot
2026-03-31 14:56:06 +00:00
parent 6252bb6eb5
commit 91e01d755b
4757 changed files with 984951 additions and 0 deletions

View File

@@ -0,0 +1,5 @@
// Copyright (c) Microsoft Corporation.
// Licensed under the MIT License.
import * as msalCommon from "@azure/msal-node";
export { msalCommon };
//# sourceMappingURL=msal.js.map

View File

@@ -0,0 +1,469 @@
// Copyright (c) Microsoft Corporation.
// Licensed under the MIT License.
import * as msal from "@azure/msal-node";
import { credentialLogger, formatSuccess } from "../../util/logging.js";
import { msalPlugins } from "./msalPlugins.js";
import { defaultLoggerCallback, ensureValidMsalToken, getAuthority, getAuthorityHost, getKnownAuthorities, getMSALLogLevel, handleMsalError, msalToPublic, publicToMsal, } from "../utils.js";
import { AuthenticationRequiredError } from "../../errors.js";
import { IdentityClient } from "../../client/identityClient.js";
import { calculateRegionalAuthority } from "../../regionalAuthority.js";
import { getLogLevel } from "@azure/logger";
import { resolveTenantId } from "../../util/tenantIdUtils.js";
/**
* The default logger used if no logger was passed in by the credential.
*/
const msalLogger = credentialLogger("MsalClient");
/**
* Generates the configuration for MSAL (Microsoft Authentication Library).
*
* @param clientId - The client ID of the application.
* @param tenantId - The tenant ID of the Azure Active Directory.
* @param msalClientOptions - Optional. Additional options for creating the MSAL client.
* @returns The MSAL configuration object.
*/
export function generateMsalConfiguration(clientId, tenantId, msalClientOptions = {}) {
var _a, _b, _c;
const resolvedTenant = resolveTenantId((_a = msalClientOptions.logger) !== null && _a !== void 0 ? _a : msalLogger, tenantId, clientId);
// TODO: move and reuse getIdentityClientAuthorityHost
const authority = getAuthority(resolvedTenant, getAuthorityHost(msalClientOptions));
const httpClient = new IdentityClient(Object.assign(Object.assign({}, msalClientOptions.tokenCredentialOptions), { authorityHost: authority, loggingOptions: msalClientOptions.loggingOptions }));
const msalConfig = {
auth: {
clientId,
authority,
knownAuthorities: getKnownAuthorities(resolvedTenant, authority, msalClientOptions.disableInstanceDiscovery),
},
system: {
networkClient: httpClient,
loggerOptions: {
loggerCallback: defaultLoggerCallback((_b = msalClientOptions.logger) !== null && _b !== void 0 ? _b : msalLogger),
logLevel: getMSALLogLevel(getLogLevel()),
piiLoggingEnabled: (_c = msalClientOptions.loggingOptions) === null || _c === void 0 ? void 0 : _c.enableUnsafeSupportLogging,
},
},
};
return msalConfig;
}
/**
* Creates an instance of the MSAL (Microsoft Authentication Library) client.
*
* @param clientId - The client ID of the application.
* @param tenantId - The tenant ID of the Azure Active Directory.
* @param createMsalClientOptions - Optional. Additional options for creating the MSAL client.
* @returns An instance of the MSAL client.
*
* @public
*/
export function createMsalClient(clientId, tenantId, createMsalClientOptions = {}) {
var _a;
const state = {
msalConfig: generateMsalConfiguration(clientId, tenantId, createMsalClientOptions),
cachedAccount: createMsalClientOptions.authenticationRecord
? publicToMsal(createMsalClientOptions.authenticationRecord)
: null,
pluginConfiguration: msalPlugins.generatePluginConfiguration(createMsalClientOptions),
logger: (_a = createMsalClientOptions.logger) !== null && _a !== void 0 ? _a : msalLogger,
};
const publicApps = new Map();
async function getPublicApp(options = {}) {
const appKey = options.enableCae ? "CAE" : "default";
let publicClientApp = publicApps.get(appKey);
if (publicClientApp) {
state.logger.getToken.info("Existing PublicClientApplication found in cache, returning it.");
return publicClientApp;
}
// Initialize a new app and cache it
state.logger.getToken.info(`Creating new PublicClientApplication with CAE ${options.enableCae ? "enabled" : "disabled"}.`);
const cachePlugin = options.enableCae
? state.pluginConfiguration.cache.cachePluginCae
: state.pluginConfiguration.cache.cachePlugin;
state.msalConfig.auth.clientCapabilities = options.enableCae ? ["cp1"] : undefined;
publicClientApp = new msal.PublicClientApplication(Object.assign(Object.assign({}, state.msalConfig), { broker: { nativeBrokerPlugin: state.pluginConfiguration.broker.nativeBrokerPlugin }, cache: { cachePlugin: await cachePlugin } }));
publicApps.set(appKey, publicClientApp);
return publicClientApp;
}
const confidentialApps = new Map();
async function getConfidentialApp(options = {}) {
const appKey = options.enableCae ? "CAE" : "default";
let confidentialClientApp = confidentialApps.get(appKey);
if (confidentialClientApp) {
state.logger.getToken.info("Existing ConfidentialClientApplication found in cache, returning it.");
return confidentialClientApp;
}
// Initialize a new app and cache it
state.logger.getToken.info(`Creating new ConfidentialClientApplication with CAE ${options.enableCae ? "enabled" : "disabled"}.`);
const cachePlugin = options.enableCae
? state.pluginConfiguration.cache.cachePluginCae
: state.pluginConfiguration.cache.cachePlugin;
state.msalConfig.auth.clientCapabilities = options.enableCae ? ["cp1"] : undefined;
confidentialClientApp = new msal.ConfidentialClientApplication(Object.assign(Object.assign({}, state.msalConfig), { broker: { nativeBrokerPlugin: state.pluginConfiguration.broker.nativeBrokerPlugin }, cache: { cachePlugin: await cachePlugin } }));
confidentialApps.set(appKey, confidentialClientApp);
return confidentialClientApp;
}
async function getTokenSilent(app, scopes, options = {}) {
if (state.cachedAccount === null) {
state.logger.getToken.info("No cached account found in local state.");
throw new AuthenticationRequiredError({ scopes });
}
// Keep track and reuse the claims we received across challenges
if (options.claims) {
state.cachedClaims = options.claims;
}
const silentRequest = {
account: state.cachedAccount,
scopes,
claims: state.cachedClaims,
};
if (state.pluginConfiguration.broker.isEnabled) {
silentRequest.tokenQueryParameters || (silentRequest.tokenQueryParameters = {});
if (state.pluginConfiguration.broker.enableMsaPassthrough) {
silentRequest.tokenQueryParameters["msal_request_type"] = "consumer_passthrough";
}
}
if (options.proofOfPossessionOptions) {
silentRequest.shrNonce = options.proofOfPossessionOptions.nonce;
silentRequest.authenticationScheme = "pop";
silentRequest.resourceRequestMethod = options.proofOfPossessionOptions.resourceRequestMethod;
silentRequest.resourceRequestUri = options.proofOfPossessionOptions.resourceRequestUrl;
}
state.logger.getToken.info("Attempting to acquire token silently");
try {
return await app.acquireTokenSilent(silentRequest);
}
catch (err) {
throw handleMsalError(scopes, err, options);
}
}
/**
* Builds an authority URL for the given request. The authority may be different than the one used when creating the MSAL client
* if the user is creating cross-tenant requests
*/
function calculateRequestAuthority(options) {
if (options === null || options === void 0 ? void 0 : options.tenantId) {
return getAuthority(options.tenantId, getAuthorityHost(createMsalClientOptions));
}
return state.msalConfig.auth.authority;
}
/**
* Performs silent authentication using MSAL to acquire an access token.
* If silent authentication fails, falls back to interactive authentication.
*
* @param msalApp - The MSAL application instance.
* @param scopes - The scopes for which to acquire the access token.
* @param options - The options for acquiring the access token.
* @param onAuthenticationRequired - A callback function to handle interactive authentication when silent authentication fails.
* @returns A promise that resolves to an AccessToken object containing the access token and its expiration timestamp.
*/
async function withSilentAuthentication(msalApp, scopes, options, onAuthenticationRequired) {
var _a, _b;
let response = null;
try {
response = await getTokenSilent(msalApp, scopes, options);
}
catch (e) {
if (e.name !== "AuthenticationRequiredError") {
throw e;
}
if (options.disableAutomaticAuthentication) {
throw new AuthenticationRequiredError({
scopes,
getTokenOptions: options,
message: "Automatic authentication has been disabled. You may call the authentication() method.",
});
}
}
// Silent authentication failed
if (response === null) {
try {
response = await onAuthenticationRequired();
}
catch (err) {
throw handleMsalError(scopes, err, options);
}
}
// At this point we should have a token, process it
ensureValidMsalToken(scopes, response, options);
state.cachedAccount = (_a = response === null || response === void 0 ? void 0 : response.account) !== null && _a !== void 0 ? _a : null;
state.logger.getToken.info(formatSuccess(scopes));
return {
token: response.accessToken,
expiresOnTimestamp: response.expiresOn.getTime(),
refreshAfterTimestamp: (_b = response.refreshOn) === null || _b === void 0 ? void 0 : _b.getTime(),
tokenType: response.tokenType,
};
}
async function getTokenByClientSecret(scopes, clientSecret, options = {}) {
var _a;
state.logger.getToken.info(`Attempting to acquire token using client secret`);
state.msalConfig.auth.clientSecret = clientSecret;
const msalApp = await getConfidentialApp(options);
try {
const response = await msalApp.acquireTokenByClientCredential({
scopes,
authority: calculateRequestAuthority(options),
azureRegion: calculateRegionalAuthority(),
claims: options === null || options === void 0 ? void 0 : options.claims,
});
ensureValidMsalToken(scopes, response, options);
state.logger.getToken.info(formatSuccess(scopes));
return {
token: response.accessToken,
expiresOnTimestamp: response.expiresOn.getTime(),
refreshAfterTimestamp: (_a = response.refreshOn) === null || _a === void 0 ? void 0 : _a.getTime(),
tokenType: response.tokenType,
};
}
catch (err) {
throw handleMsalError(scopes, err, options);
}
}
async function getTokenByClientAssertion(scopes, clientAssertion, options = {}) {
var _a;
state.logger.getToken.info(`Attempting to acquire token using client assertion`);
state.msalConfig.auth.clientAssertion = clientAssertion;
const msalApp = await getConfidentialApp(options);
try {
const response = await msalApp.acquireTokenByClientCredential({
scopes,
authority: calculateRequestAuthority(options),
azureRegion: calculateRegionalAuthority(),
claims: options === null || options === void 0 ? void 0 : options.claims,
clientAssertion,
});
ensureValidMsalToken(scopes, response, options);
state.logger.getToken.info(formatSuccess(scopes));
return {
token: response.accessToken,
expiresOnTimestamp: response.expiresOn.getTime(),
refreshAfterTimestamp: (_a = response.refreshOn) === null || _a === void 0 ? void 0 : _a.getTime(),
tokenType: response.tokenType,
};
}
catch (err) {
throw handleMsalError(scopes, err, options);
}
}
async function getTokenByClientCertificate(scopes, certificate, options = {}) {
var _a;
state.logger.getToken.info(`Attempting to acquire token using client certificate`);
state.msalConfig.auth.clientCertificate = certificate;
const msalApp = await getConfidentialApp(options);
try {
const response = await msalApp.acquireTokenByClientCredential({
scopes,
authority: calculateRequestAuthority(options),
azureRegion: calculateRegionalAuthority(),
claims: options === null || options === void 0 ? void 0 : options.claims,
});
ensureValidMsalToken(scopes, response, options);
state.logger.getToken.info(formatSuccess(scopes));
return {
token: response.accessToken,
expiresOnTimestamp: response.expiresOn.getTime(),
refreshAfterTimestamp: (_a = response.refreshOn) === null || _a === void 0 ? void 0 : _a.getTime(),
tokenType: response.tokenType,
};
}
catch (err) {
throw handleMsalError(scopes, err, options);
}
}
async function getTokenByDeviceCode(scopes, deviceCodeCallback, options = {}) {
state.logger.getToken.info(`Attempting to acquire token using device code`);
const msalApp = await getPublicApp(options);
return withSilentAuthentication(msalApp, scopes, options, () => {
var _a, _b;
const requestOptions = {
scopes,
cancel: (_b = (_a = options === null || options === void 0 ? void 0 : options.abortSignal) === null || _a === void 0 ? void 0 : _a.aborted) !== null && _b !== void 0 ? _b : false,
deviceCodeCallback,
authority: calculateRequestAuthority(options),
claims: options === null || options === void 0 ? void 0 : options.claims,
};
const deviceCodeRequest = msalApp.acquireTokenByDeviceCode(requestOptions);
if (options.abortSignal) {
options.abortSignal.addEventListener("abort", () => {
requestOptions.cancel = true;
});
}
return deviceCodeRequest;
});
}
async function getTokenByUsernamePassword(scopes, username, password, options = {}) {
state.logger.getToken.info(`Attempting to acquire token using username and password`);
const msalApp = await getPublicApp(options);
return withSilentAuthentication(msalApp, scopes, options, () => {
const requestOptions = {
scopes,
username,
password,
authority: calculateRequestAuthority(options),
claims: options === null || options === void 0 ? void 0 : options.claims,
};
return msalApp.acquireTokenByUsernamePassword(requestOptions);
});
}
function getActiveAccount() {
if (!state.cachedAccount) {
return undefined;
}
return msalToPublic(clientId, state.cachedAccount);
}
async function getTokenByAuthorizationCode(scopes, redirectUri, authorizationCode, clientSecret, options = {}) {
state.logger.getToken.info(`Attempting to acquire token using authorization code`);
let msalApp;
if (clientSecret) {
// If a client secret is provided, we need to use a confidential client application
// See https://learn.microsoft.com/entra/identity-platform/v2-oauth2-auth-code-flow#request-an-access-token-with-a-client_secret
state.msalConfig.auth.clientSecret = clientSecret;
msalApp = await getConfidentialApp(options);
}
else {
msalApp = await getPublicApp(options);
}
return withSilentAuthentication(msalApp, scopes, options, () => {
return msalApp.acquireTokenByCode({
scopes,
redirectUri,
code: authorizationCode,
authority: calculateRequestAuthority(options),
claims: options === null || options === void 0 ? void 0 : options.claims,
});
});
}
async function getTokenOnBehalfOf(scopes, userAssertionToken, clientCredentials, options = {}) {
var _a;
msalLogger.getToken.info(`Attempting to acquire token on behalf of another user`);
if (typeof clientCredentials === "string") {
// Client secret
msalLogger.getToken.info(`Using client secret for on behalf of flow`);
state.msalConfig.auth.clientSecret = clientCredentials;
}
else if (typeof clientCredentials === "function") {
// Client Assertion
msalLogger.getToken.info(`Using client assertion callback for on behalf of flow`);
state.msalConfig.auth.clientAssertion = clientCredentials;
}
else {
// Client certificate
msalLogger.getToken.info(`Using client certificate for on behalf of flow`);
state.msalConfig.auth.clientCertificate = clientCredentials;
}
const msalApp = await getConfidentialApp(options);
try {
const response = await msalApp.acquireTokenOnBehalfOf({
scopes,
authority: calculateRequestAuthority(options),
claims: options.claims,
oboAssertion: userAssertionToken,
});
ensureValidMsalToken(scopes, response, options);
msalLogger.getToken.info(formatSuccess(scopes));
return {
token: response.accessToken,
expiresOnTimestamp: response.expiresOn.getTime(),
refreshAfterTimestamp: (_a = response.refreshOn) === null || _a === void 0 ? void 0 : _a.getTime(),
tokenType: response.tokenType,
};
}
catch (err) {
throw handleMsalError(scopes, err, options);
}
}
async function getTokenByInteractiveRequest(scopes, options = {}) {
msalLogger.getToken.info(`Attempting to acquire token interactively`);
const app = await getPublicApp(options);
/**
* A helper function that supports brokered authentication through the MSAL's public application.
*
* When options.useDefaultBrokerAccount is true, the method will attempt to authenticate using the default broker account.
* If the default broker account is not available, the method will fall back to interactive authentication.
*/
async function getBrokeredToken(useDefaultBrokerAccount) {
var _a;
msalLogger.verbose("Authentication will resume through the broker");
const interactiveRequest = createBaseInteractiveRequest();
if (state.pluginConfiguration.broker.parentWindowHandle) {
interactiveRequest.windowHandle = Buffer.from(state.pluginConfiguration.broker.parentWindowHandle);
}
else {
// this is a bug, as the pluginConfiguration handler should validate this case.
msalLogger.warning("Parent window handle is not specified for the broker. This may cause unexpected behavior. Please provide the parentWindowHandle.");
}
if (state.pluginConfiguration.broker.enableMsaPassthrough) {
((_a = interactiveRequest.tokenQueryParameters) !== null && _a !== void 0 ? _a : (interactiveRequest.tokenQueryParameters = {}))["msal_request_type"] =
"consumer_passthrough";
}
if (useDefaultBrokerAccount) {
interactiveRequest.prompt = "none";
msalLogger.verbose("Attempting broker authentication using the default broker account");
}
else {
msalLogger.verbose("Attempting broker authentication without the default broker account");
}
if (options.proofOfPossessionOptions) {
interactiveRequest.shrNonce = options.proofOfPossessionOptions.nonce;
interactiveRequest.authenticationScheme = "pop";
interactiveRequest.resourceRequestMethod =
options.proofOfPossessionOptions.resourceRequestMethod;
interactiveRequest.resourceRequestUri = options.proofOfPossessionOptions.resourceRequestUrl;
}
try {
return await app.acquireTokenInteractive(interactiveRequest);
}
catch (e) {
msalLogger.verbose(`Failed to authenticate through the broker: ${e.message}`);
// If we tried to use the default broker account and failed, fall back to interactive authentication
if (useDefaultBrokerAccount) {
return getBrokeredToken(/* useDefaultBrokerAccount: */ false);
}
else {
throw e;
}
}
}
function createBaseInteractiveRequest() {
var _a, _b;
return {
openBrowser: async (url) => {
const open = await import("open");
await open.default(url, { wait: true, newInstance: true });
},
scopes,
authority: calculateRequestAuthority(options),
claims: options === null || options === void 0 ? void 0 : options.claims,
loginHint: options === null || options === void 0 ? void 0 : options.loginHint,
errorTemplate: (_a = options === null || options === void 0 ? void 0 : options.browserCustomizationOptions) === null || _a === void 0 ? void 0 : _a.errorMessage,
successTemplate: (_b = options === null || options === void 0 ? void 0 : options.browserCustomizationOptions) === null || _b === void 0 ? void 0 : _b.successMessage,
prompt: (options === null || options === void 0 ? void 0 : options.loginHint) ? "login" : "select_account",
};
}
return withSilentAuthentication(app, scopes, options, async () => {
var _a;
const interactiveRequest = createBaseInteractiveRequest();
if (state.pluginConfiguration.broker.isEnabled) {
return getBrokeredToken((_a = state.pluginConfiguration.broker.useDefaultBrokerAccount) !== null && _a !== void 0 ? _a : false);
}
if (options.proofOfPossessionOptions) {
interactiveRequest.shrNonce = options.proofOfPossessionOptions.nonce;
interactiveRequest.authenticationScheme = "pop";
interactiveRequest.resourceRequestMethod =
options.proofOfPossessionOptions.resourceRequestMethod;
interactiveRequest.resourceRequestUri = options.proofOfPossessionOptions.resourceRequestUrl;
}
return app.acquireTokenInteractive(interactiveRequest);
});
}
return {
getActiveAccount,
getTokenByClientSecret,
getTokenByClientAssertion,
getTokenByClientCertificate,
getTokenByDeviceCode,
getTokenByUsernamePassword,
getTokenByAuthorizationCode,
getTokenOnBehalfOf,
getTokenByInteractiveRequest,
};
}
//# sourceMappingURL=msalClient.js.map

View File

@@ -0,0 +1,87 @@
// Copyright (c) Microsoft Corporation.
// Licensed under the MIT License.
import { CACHE_CAE_SUFFIX, CACHE_NON_CAE_SUFFIX, DEFAULT_TOKEN_CACHE_NAME, } from "../../constants.js";
/**
* The current persistence provider, undefined by default.
* @internal
*/
export let persistenceProvider = undefined;
/**
* An object that allows setting the persistence provider.
* @internal
*/
export const msalNodeFlowCacheControl = {
setPersistence(pluginProvider) {
persistenceProvider = pluginProvider;
},
};
/**
* The current native broker provider, undefined by default.
* @internal
*/
export let nativeBrokerInfo = undefined;
export function hasNativeBroker() {
return nativeBrokerInfo !== undefined;
}
/**
* An object that allows setting the native broker provider.
* @internal
*/
export const msalNodeFlowNativeBrokerControl = {
setNativeBroker(broker) {
nativeBrokerInfo = {
broker,
};
},
};
/**
* Configures plugins, validating that required plugins are available and enabled.
*
* Does not create the plugins themselves, but rather returns the configuration that will be used to create them.
*
* @param options - options for creating the MSAL client
* @returns plugin configuration
*/
function generatePluginConfiguration(options) {
var _a, _b, _c, _d, _e, _f, _g;
const config = {
cache: {},
broker: {
isEnabled: (_b = (_a = options.brokerOptions) === null || _a === void 0 ? void 0 : _a.enabled) !== null && _b !== void 0 ? _b : false,
enableMsaPassthrough: (_d = (_c = options.brokerOptions) === null || _c === void 0 ? void 0 : _c.legacyEnableMsaPassthrough) !== null && _d !== void 0 ? _d : false,
parentWindowHandle: (_e = options.brokerOptions) === null || _e === void 0 ? void 0 : _e.parentWindowHandle,
},
};
if ((_f = options.tokenCachePersistenceOptions) === null || _f === void 0 ? void 0 : _f.enabled) {
if (persistenceProvider === undefined) {
throw new Error([
"Persistent token caching was requested, but no persistence provider was configured.",
"You must install the identity-cache-persistence plugin package (`npm install --save @azure/identity-cache-persistence`)",
"and enable it by importing `useIdentityPlugin` from `@azure/identity` and calling",
"`useIdentityPlugin(cachePersistencePlugin)` before using `tokenCachePersistenceOptions`.",
].join(" "));
}
const cacheBaseName = options.tokenCachePersistenceOptions.name || DEFAULT_TOKEN_CACHE_NAME;
config.cache.cachePlugin = persistenceProvider(Object.assign({ name: `${cacheBaseName}.${CACHE_NON_CAE_SUFFIX}` }, options.tokenCachePersistenceOptions));
config.cache.cachePluginCae = persistenceProvider(Object.assign({ name: `${cacheBaseName}.${CACHE_CAE_SUFFIX}` }, options.tokenCachePersistenceOptions));
}
if ((_g = options.brokerOptions) === null || _g === void 0 ? void 0 : _g.enabled) {
if (nativeBrokerInfo === undefined) {
throw new Error([
"Broker for WAM was requested to be enabled, but no native broker was configured.",
"You must install the identity-broker plugin package (`npm install --save @azure/identity-broker`)",
"and enable it by importing `useIdentityPlugin` from `@azure/identity` and calling",
"`useIdentityPlugin(createNativeBrokerPlugin())` before using `enableBroker`.",
].join(" "));
}
config.broker.nativeBrokerPlugin = nativeBrokerInfo.broker;
}
return config;
}
/**
* Wraps generatePluginConfiguration as a writeable property for test stubbing purposes.
*/
export const msalPlugins = {
generatePluginConfiguration,
};
//# sourceMappingURL=msalPlugins.js.map

View File

@@ -0,0 +1,238 @@
// Copyright (c) Microsoft Corporation.
// Licensed under the MIT License.
import { AuthenticationRequiredError, CredentialUnavailableError } from "../errors.js";
import { credentialLogger, formatError } from "../util/logging.js";
import { DefaultAuthority, DefaultAuthorityHost, DefaultTenantId } from "../constants.js";
import { randomUUID as coreRandomUUID, isNode, isNodeLike } from "@azure/core-util";
import { AbortError } from "@azure/abort-controller";
import { msalCommon } from "./msal.js";
/**
* @internal
*/
const logger = credentialLogger("IdentityUtils");
/**
* Latest AuthenticationRecord version
* @internal
*/
const LatestAuthenticationRecordVersion = "1.0";
/**
* Ensures the validity of the MSAL token
* @internal
*/
export function ensureValidMsalToken(scopes, msalToken, getTokenOptions) {
const error = (message) => {
logger.getToken.info(message);
return new AuthenticationRequiredError({
scopes: Array.isArray(scopes) ? scopes : [scopes],
getTokenOptions,
message,
});
};
if (!msalToken) {
throw error("No response");
}
if (!msalToken.expiresOn) {
throw error(`Response had no "expiresOn" property.`);
}
if (!msalToken.accessToken) {
throw error(`Response had no "accessToken" property.`);
}
}
/**
* Returns the authority host from either the options bag or the AZURE_AUTHORITY_HOST environment variable.
*
* Defaults to {@link DefaultAuthorityHost}.
* @internal
*/
export function getAuthorityHost(options) {
let authorityHost = options === null || options === void 0 ? void 0 : options.authorityHost;
if (!authorityHost && isNodeLike) {
authorityHost = process.env.AZURE_AUTHORITY_HOST;
}
return authorityHost !== null && authorityHost !== void 0 ? authorityHost : DefaultAuthorityHost;
}
/**
* Generates a valid authority by combining a host with a tenantId.
* @internal
*/
export function getAuthority(tenantId, host) {
if (!host) {
host = DefaultAuthorityHost;
}
if (new RegExp(`${tenantId}/?$`).test(host)) {
return host;
}
if (host.endsWith("/")) {
return host + tenantId;
}
else {
return `${host}/${tenantId}`;
}
}
/**
* Generates the known authorities.
* If the Tenant Id is `adfs`, the authority can't be validated since the format won't match the expected one.
* For that reason, we have to force MSAL to disable validating the authority
* by sending it within the known authorities in the MSAL configuration.
* @internal
*/
export function getKnownAuthorities(tenantId, authorityHost, disableInstanceDiscovery) {
if ((tenantId === "adfs" && authorityHost) || disableInstanceDiscovery) {
return [authorityHost];
}
return [];
}
/**
* Generates a logger that can be passed to the MSAL clients.
* @param credLogger - The logger of the credential.
* @internal
*/
export const defaultLoggerCallback = (credLogger, platform = isNode ? "Node" : "Browser") => (level, message, containsPii) => {
if (containsPii) {
return;
}
switch (level) {
case msalCommon.LogLevel.Error:
credLogger.info(`MSAL ${platform} V2 error: ${message}`);
return;
case msalCommon.LogLevel.Info:
credLogger.info(`MSAL ${platform} V2 info message: ${message}`);
return;
case msalCommon.LogLevel.Verbose:
credLogger.info(`MSAL ${platform} V2 verbose message: ${message}`);
return;
case msalCommon.LogLevel.Warning:
credLogger.info(`MSAL ${platform} V2 warning: ${message}`);
return;
}
};
/**
* @internal
*/
export function getMSALLogLevel(logLevel) {
switch (logLevel) {
case "error":
return msalCommon.LogLevel.Error;
case "info":
return msalCommon.LogLevel.Info;
case "verbose":
return msalCommon.LogLevel.Verbose;
case "warning":
return msalCommon.LogLevel.Warning;
default:
// default msal logging level should be Info
return msalCommon.LogLevel.Info;
}
}
/**
* Wraps core-util's randomUUID in order to allow for mocking in tests.
* This prepares the library for the upcoming core-util update to ESM.
*
* @internal
* @returns A string containing a random UUID
*/
export function randomUUID() {
return coreRandomUUID();
}
/**
* Handles MSAL errors.
*/
export function handleMsalError(scopes, error, getTokenOptions) {
if (error.name === "AuthError" ||
error.name === "ClientAuthError" ||
error.name === "BrowserAuthError") {
const msalError = error;
switch (msalError.errorCode) {
case "endpoints_resolution_error":
logger.info(formatError(scopes, error.message));
return new CredentialUnavailableError(error.message);
case "device_code_polling_cancelled":
return new AbortError("The authentication has been aborted by the caller.");
case "consent_required":
case "interaction_required":
case "login_required":
logger.info(formatError(scopes, `Authentication returned errorCode ${msalError.errorCode}`));
break;
default:
logger.info(formatError(scopes, `Failed to acquire token: ${error.message}`));
break;
}
}
if (error.name === "ClientConfigurationError" ||
error.name === "BrowserConfigurationAuthError" ||
error.name === "AbortError" ||
error.name === "AuthenticationError") {
return error;
}
if (error.name === "NativeAuthError") {
logger.info(formatError(scopes, `Error from the native broker: ${error.message} with status code: ${error.statusCode}`));
return error;
}
return new AuthenticationRequiredError({ scopes, getTokenOptions, message: error.message });
}
// transformations
export function publicToMsal(account) {
return {
localAccountId: account.homeAccountId,
environment: account.authority,
username: account.username,
homeAccountId: account.homeAccountId,
tenantId: account.tenantId,
};
}
export function msalToPublic(clientId, account) {
var _a;
const record = {
authority: (_a = account.environment) !== null && _a !== void 0 ? _a : DefaultAuthority,
homeAccountId: account.homeAccountId,
tenantId: account.tenantId || DefaultTenantId,
username: account.username,
clientId,
version: LatestAuthenticationRecordVersion,
};
return record;
}
/**
* Serializes an `AuthenticationRecord` into a string.
*
* The output of a serialized authentication record will contain the following properties:
*
* - "authority"
* - "homeAccountId"
* - "clientId"
* - "tenantId"
* - "username"
* - "version"
*
* To later convert this string to a serialized `AuthenticationRecord`, please use the exported function `deserializeAuthenticationRecord()`.
*/
export function serializeAuthenticationRecord(record) {
return JSON.stringify(record);
}
/**
* Deserializes a previously serialized authentication record from a string into an object.
*
* The input string must contain the following properties:
*
* - "authority"
* - "homeAccountId"
* - "clientId"
* - "tenantId"
* - "username"
* - "version"
*
* If the version we receive is unsupported, an error will be thrown.
*
* At the moment, the only available version is: "1.0", which is always set when the authentication record is serialized.
*
* @param serializedRecord - Authentication record previously serialized into string.
* @returns AuthenticationRecord.
*/
export function deserializeAuthenticationRecord(serializedRecord) {
const parsed = JSON.parse(serializedRecord);
if (parsed.version && parsed.version !== LatestAuthenticationRecordVersion) {
throw Error("Unsupported AuthenticationRecord version");
}
return parsed;
}
//# sourceMappingURL=utils.js.map