UNPKG

@azure/identity

Version:

Provides credential implementations for Azure SDK libraries that can authenticate with Microsoft Entra ID

252 lines • 8.79 kB
"use strict"; // Copyright (c) Microsoft Corporation. // Licensed under the MIT License. Object.defineProperty(exports, "__esModule", { value: true }); exports.defaultLoggerCallback = void 0; exports.ensureValidMsalToken = ensureValidMsalToken; exports.getAuthorityHost = getAuthorityHost; exports.getAuthority = getAuthority; exports.getKnownAuthorities = getKnownAuthorities; exports.getMSALLogLevel = getMSALLogLevel; exports.randomUUID = randomUUID; exports.handleMsalError = handleMsalError; exports.publicToMsal = publicToMsal; exports.msalToPublic = msalToPublic; exports.serializeAuthenticationRecord = serializeAuthenticationRecord; exports.deserializeAuthenticationRecord = deserializeAuthenticationRecord; const errors_js_1 = require("../errors.js"); const logging_js_1 = require("../util/logging.js"); const constants_js_1 = require("../constants.js"); const core_util_1 = require("@azure/core-util"); const abort_controller_1 = require("@azure/abort-controller"); const msal_js_1 = require("./msal.js"); /** * @internal */ const logger = (0, logging_js_1.credentialLogger)("IdentityUtils"); /** * Latest AuthenticationRecord version * @internal */ const LatestAuthenticationRecordVersion = "1.0"; /** * Ensures the validity of the MSAL token * @internal */ function ensureValidMsalToken(scopes, msalToken, getTokenOptions) { const error = (message) => { logger.getToken.info(message); return new errors_js_1.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 */ function getAuthorityHost(options) { let authorityHost = options?.authorityHost; if (!authorityHost && core_util_1.isNodeLike) { authorityHost = process.env.AZURE_AUTHORITY_HOST; } return authorityHost ?? constants_js_1.DefaultAuthorityHost; } /** * Generates a valid authority by combining a host with a tenantId. * @internal */ function getAuthority(tenantId, host) { if (!host) { host = constants_js_1.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 */ 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 */ const defaultLoggerCallback = (credLogger, platform = core_util_1.isNode ? "Node" : "Browser") => (level, message, containsPii) => { if (containsPii) { return; } switch (level) { case msal_js_1.msalCommon.LogLevel.Error: credLogger.info(`MSAL ${platform} V2 error: ${message}`); return; case msal_js_1.msalCommon.LogLevel.Info: credLogger.info(`MSAL ${platform} V2 info message: ${message}`); return; case msal_js_1.msalCommon.LogLevel.Verbose: credLogger.info(`MSAL ${platform} V2 verbose message: ${message}`); return; case msal_js_1.msalCommon.LogLevel.Warning: credLogger.info(`MSAL ${platform} V2 warning: ${message}`); return; } }; exports.defaultLoggerCallback = defaultLoggerCallback; /** * @internal */ function getMSALLogLevel(logLevel) { switch (logLevel) { case "error": return msal_js_1.msalCommon.LogLevel.Error; case "info": return msal_js_1.msalCommon.LogLevel.Info; case "verbose": return msal_js_1.msalCommon.LogLevel.Verbose; case "warning": return msal_js_1.msalCommon.LogLevel.Warning; default: // default msal logging level should be Info return msal_js_1.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 */ function randomUUID() { return (0, core_util_1.randomUUID)(); } /** * Handles MSAL errors. */ 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((0, logging_js_1.formatError)(scopes, error.message)); return new errors_js_1.CredentialUnavailableError(error.message); case "device_code_polling_cancelled": return new abort_controller_1.AbortError("The authentication has been aborted by the caller."); case "consent_required": case "interaction_required": case "login_required": logger.info((0, logging_js_1.formatError)(scopes, `Authentication returned errorCode ${msalError.errorCode}`)); break; default: logger.info((0, logging_js_1.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((0, logging_js_1.formatError)(scopes, `Error from the native broker: ${error.message} with status code: ${error.statusCode}`)); return error; } return new errors_js_1.AuthenticationRequiredError({ scopes, getTokenOptions, message: error.message }); } // transformations function publicToMsal(account) { return { localAccountId: account.homeAccountId, environment: account.authority, username: account.username, homeAccountId: account.homeAccountId, tenantId: account.tenantId, }; } function msalToPublic(clientId, account) { const record = { authority: account.environment ?? constants_js_1.DefaultAuthority, homeAccountId: account.homeAccountId, tenantId: account.tenantId || constants_js_1.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()`. */ 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. */ 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