@azure/msal-common
Version:
Microsoft Authentication Library for js
168 lines (165 loc) • 8.09 kB
JavaScript
/*! @azure/msal-common v15.12.0 2025-08-19 */
'use strict';
import { buildClientConfiguration } from '../config/ClientConfiguration.mjs';
import { Logger } from '../logger/Logger.mjs';
import { Constants, HeaderNames } from '../utils/Constants.mjs';
import { name, version } from '../packageMetadata.mjs';
import { CcsCredentialType } from '../account/CcsCredential.mjs';
import { buildClientInfoFromHomeAccountId } from '../account/ClientInfo.mjs';
import { addBrokerParameters, addExtraQueryParameters, addCorrelationId, instrumentBrokerParams } from '../request/RequestParameterBuilder.mjs';
import { mapToQueryString } from '../utils/UrlUtils.mjs';
import { createDiscoveredInstance } from '../authority/AuthorityFactory.mjs';
import { PerformanceEvents } from '../telemetry/performance/PerformanceEvent.mjs';
import { ThrottlingUtils } from '../network/ThrottlingUtils.mjs';
import { AuthError } from '../error/AuthError.mjs';
import { createClientAuthError } from '../error/ClientAuthError.mjs';
import { NetworkError } from '../error/NetworkError.mjs';
import { invokeAsync } from '../utils/FunctionWrappers.mjs';
import { networkError } from '../error/ClientAuthErrorCodes.mjs';
/*
* Copyright (c) Microsoft Corporation. All rights reserved.
* Licensed under the MIT License.
*/
/**
* Base application class which will construct requests to send to and handle responses from the Microsoft STS using the authorization code flow.
* @internal
*/
class BaseClient {
constructor(configuration, performanceClient) {
// Set the configuration
this.config = buildClientConfiguration(configuration);
// Initialize the logger
this.logger = new Logger(this.config.loggerOptions, name, version);
// Initialize crypto
this.cryptoUtils = this.config.cryptoInterface;
// Initialize storage interface
this.cacheManager = this.config.storageInterface;
// Set the network interface
this.networkClient = this.config.networkInterface;
// Set TelemetryManager
this.serverTelemetryManager = this.config.serverTelemetryManager;
// set Authority
this.authority = this.config.authOptions.authority;
// set performance telemetry client
this.performanceClient = performanceClient;
}
/**
* Creates default headers for requests to token endpoint
*/
createTokenRequestHeaders(ccsCred) {
const headers = {};
headers[HeaderNames.CONTENT_TYPE] = Constants.URL_FORM_CONTENT_TYPE;
if (!this.config.systemOptions.preventCorsPreflight && ccsCred) {
switch (ccsCred.type) {
case CcsCredentialType.HOME_ACCOUNT_ID:
try {
const clientInfo = buildClientInfoFromHomeAccountId(ccsCred.credential);
headers[HeaderNames.CCS_HEADER] = `Oid:${clientInfo.uid}@${clientInfo.utid}`;
}
catch (e) {
this.logger.verbose("Could not parse home account ID for CCS Header: " +
e);
}
break;
case CcsCredentialType.UPN:
headers[HeaderNames.CCS_HEADER] = `UPN: ${ccsCred.credential}`;
break;
}
}
return headers;
}
/**
* Http post to token endpoint
* @param tokenEndpoint
* @param queryString
* @param headers
* @param thumbprint
*/
async executePostToTokenEndpoint(tokenEndpoint, queryString, headers, thumbprint, correlationId, queuedEvent) {
if (queuedEvent) {
this.performanceClient?.addQueueMeasurement(queuedEvent, correlationId);
}
const response = await this.sendPostRequest(thumbprint, tokenEndpoint, { body: queryString, headers: headers }, correlationId);
if (this.config.serverTelemetryManager &&
response.status < 500 &&
response.status !== 429) {
// Telemetry data successfully logged by server, clear Telemetry cache
this.config.serverTelemetryManager.clearTelemetryCache();
}
return response;
}
/**
* Wraps sendPostRequestAsync with necessary preflight and postflight logic
* @param thumbprint - Request thumbprint for throttling
* @param tokenEndpoint - Endpoint to make the POST to
* @param options - Body and Headers to include on the POST request
* @param correlationId - CorrelationId for telemetry
*/
async sendPostRequest(thumbprint, tokenEndpoint, options, correlationId) {
ThrottlingUtils.preProcess(this.cacheManager, thumbprint, correlationId);
let response;
try {
response = await invokeAsync((this.networkClient.sendPostRequestAsync.bind(this.networkClient)), PerformanceEvents.NetworkClientSendPostRequestAsync, this.logger, this.performanceClient, correlationId)(tokenEndpoint, options);
const responseHeaders = response.headers || {};
this.performanceClient?.addFields({
refreshTokenSize: response.body.refresh_token?.length || 0,
httpVerToken: responseHeaders[HeaderNames.X_MS_HTTP_VERSION] || "",
requestId: responseHeaders[HeaderNames.X_MS_REQUEST_ID] || "",
}, correlationId);
}
catch (e) {
if (e instanceof NetworkError) {
const responseHeaders = e.responseHeaders;
if (responseHeaders) {
this.performanceClient?.addFields({
httpVerToken: responseHeaders[HeaderNames.X_MS_HTTP_VERSION] || "",
requestId: responseHeaders[HeaderNames.X_MS_REQUEST_ID] ||
"",
contentTypeHeader: responseHeaders[HeaderNames.CONTENT_TYPE] ||
undefined,
contentLengthHeader: responseHeaders[HeaderNames.CONTENT_LENGTH] ||
undefined,
httpStatus: e.httpStatus,
}, correlationId);
}
throw e.error;
}
if (e instanceof AuthError) {
throw e;
}
else {
throw createClientAuthError(networkError);
}
}
ThrottlingUtils.postProcess(this.cacheManager, thumbprint, response, correlationId);
return response;
}
/**
* Updates the authority object of the client. Endpoint discovery must be completed.
* @param updatedAuthority
*/
async updateAuthority(cloudInstanceHostname, correlationId) {
this.performanceClient?.addQueueMeasurement(PerformanceEvents.UpdateTokenEndpointAuthority, correlationId);
const cloudInstanceAuthorityUri = `https://${cloudInstanceHostname}/${this.authority.tenant}/`;
const cloudInstanceAuthority = await createDiscoveredInstance(cloudInstanceAuthorityUri, this.networkClient, this.cacheManager, this.authority.options, this.logger, correlationId, this.performanceClient);
this.authority = cloudInstanceAuthority;
}
/**
* Creates query string for the /token request
* @param request
*/
createTokenQueryParameters(request) {
const parameters = new Map();
if (request.embeddedClientId) {
addBrokerParameters(parameters, this.config.authOptions.clientId, this.config.authOptions.redirectUri);
}
if (request.tokenQueryParameters) {
addExtraQueryParameters(parameters, request.tokenQueryParameters);
}
addCorrelationId(parameters, request.correlationId);
instrumentBrokerParams(parameters, request.correlationId, this.performanceClient);
return mapToQueryString(parameters);
}
}
export { BaseClient };
//# sourceMappingURL=BaseClient.mjs.map