UNPKG

@azure/msal-browser

Version:
296 lines (293 loc) 16.8 kB
/*! @azure/msal-browser v2.28.1 2022-08-01 */ 'use strict'; import { __extends, __awaiter, __generator, __assign } from '../_virtual/_tslib.js'; import { UrlString, Constants, AuthorizationCodeClient, PerformanceEvents, Authority, AuthorityFactory, ResponseMode, StringUtils, ProtocolUtils } from '@azure/msal-common'; import { BaseInteractionClient } from './BaseInteractionClient.js'; import { BrowserConstants } from '../utils/BrowserConstants.js'; import { version } from '../packageMetadata.js'; import { BrowserAuthError } from '../error/BrowserAuthError.js'; import { BrowserProtocolUtils } from '../utils/BrowserProtocolUtils.js'; import { BrowserUtils } from '../utils/BrowserUtils.js'; /* * Copyright (c) Microsoft Corporation. All rights reserved. * Licensed under the MIT License. */ /** * Defines the class structure and helper functions used by the "standard", non-brokered auth flows (popup, redirect, silent (RT), silent (iframe)) */ var StandardInteractionClient = /** @class */ (function (_super) { __extends(StandardInteractionClient, _super); function StandardInteractionClient() { return _super !== null && _super.apply(this, arguments) || this; } /** * Generates an auth code request tied to the url request. * @param request */ StandardInteractionClient.prototype.initializeAuthorizationCodeRequest = function (request) { return __awaiter(this, void 0, void 0, function () { var generatedPkceParams, authCodeRequest; return __generator(this, function (_a) { switch (_a.label) { case 0: this.logger.verbose("initializeAuthorizationRequest called", request.correlationId); return [4 /*yield*/, this.browserCrypto.generatePkceCodes()]; case 1: generatedPkceParams = _a.sent(); authCodeRequest = __assign(__assign({}, request), { redirectUri: request.redirectUri, code: Constants.EMPTY_STRING, codeVerifier: generatedPkceParams.verifier }); request.codeChallenge = generatedPkceParams.challenge; request.codeChallengeMethod = Constants.S256_CODE_CHALLENGE_METHOD; return [2 /*return*/, authCodeRequest]; } }); }); }; /** * Initializer for the logout request. * @param logoutRequest */ StandardInteractionClient.prototype.initializeLogoutRequest = function (logoutRequest) { this.logger.verbose("initializeLogoutRequest called", logoutRequest === null || logoutRequest === void 0 ? void 0 : logoutRequest.correlationId); var validLogoutRequest = __assign({ correlationId: this.correlationId || this.browserCrypto.createNewGuid() }, logoutRequest); /** * Set logout_hint to be login_hint from ID Token Claims if present * and logoutHint attribute wasn't manually set in logout request */ if (logoutRequest) { // If logoutHint isn't set and an account was passed in, try to extract logoutHint from ID Token Claims if (!logoutRequest.logoutHint) { if (logoutRequest.account) { var logoutHint = this.getLogoutHintFromIdTokenClaims(logoutRequest.account); if (logoutHint) { this.logger.verbose("Setting logoutHint to login_hint ID Token Claim value for the account provided"); validLogoutRequest.logoutHint = logoutHint; } } else { this.logger.verbose("logoutHint was not set and account was not passed into logout request, logoutHint will not be set"); } } else { this.logger.verbose("logoutHint has already been set in logoutRequest"); } } else { this.logger.verbose("logoutHint will not be set since no logout request was configured"); } /* * Only set redirect uri if logout request isn't provided or the set uri isn't null. * Otherwise, use passed uri, config, or current page. */ if (!logoutRequest || logoutRequest.postLogoutRedirectUri !== null) { if (logoutRequest && logoutRequest.postLogoutRedirectUri) { this.logger.verbose("Setting postLogoutRedirectUri to uri set on logout request", validLogoutRequest.correlationId); validLogoutRequest.postLogoutRedirectUri = UrlString.getAbsoluteUrl(logoutRequest.postLogoutRedirectUri, BrowserUtils.getCurrentUri()); } else if (this.config.auth.postLogoutRedirectUri === null) { this.logger.verbose("postLogoutRedirectUri configured as null and no uri set on request, not passing post logout redirect", validLogoutRequest.correlationId); } else if (this.config.auth.postLogoutRedirectUri) { this.logger.verbose("Setting postLogoutRedirectUri to configured uri", validLogoutRequest.correlationId); validLogoutRequest.postLogoutRedirectUri = UrlString.getAbsoluteUrl(this.config.auth.postLogoutRedirectUri, BrowserUtils.getCurrentUri()); } else { this.logger.verbose("Setting postLogoutRedirectUri to current page", validLogoutRequest.correlationId); validLogoutRequest.postLogoutRedirectUri = UrlString.getAbsoluteUrl(BrowserUtils.getCurrentUri(), BrowserUtils.getCurrentUri()); } } else { this.logger.verbose("postLogoutRedirectUri passed as null, not setting post logout redirect uri", validLogoutRequest.correlationId); } return validLogoutRequest; }; /** * Parses login_hint ID Token Claim out of AccountInfo object to be used as * logout_hint in end session request. * @param account */ StandardInteractionClient.prototype.getLogoutHintFromIdTokenClaims = function (account) { var idTokenClaims = account.idTokenClaims; if (idTokenClaims) { if (idTokenClaims.login_hint) { return idTokenClaims.login_hint; } else { this.logger.verbose("The ID Token Claims tied to the provided account do not contain a login_hint claim, logoutHint will not be added to logout request"); } } else { this.logger.verbose("The provided account does not contain ID Token Claims, logoutHint will not be added to logout request"); } return null; }; /** * Creates an Authorization Code Client with the given authority, or the default authority. * @param serverTelemetryManager * @param authorityUrl */ StandardInteractionClient.prototype.createAuthCodeClient = function (serverTelemetryManager, authorityUrl, requestAzureCloudOptions) { return __awaiter(this, void 0, void 0, function () { var clientConfig; return __generator(this, function (_a) { switch (_a.label) { case 0: return [4 /*yield*/, this.getClientConfiguration(serverTelemetryManager, authorityUrl, requestAzureCloudOptions)]; case 1: clientConfig = _a.sent(); return [2 /*return*/, new AuthorizationCodeClient(clientConfig)]; } }); }); }; /** * Creates a Client Configuration object with the given request authority, or the default authority. * @param serverTelemetryManager * @param requestAuthority * @param requestCorrelationId */ StandardInteractionClient.prototype.getClientConfiguration = function (serverTelemetryManager, requestAuthority, requestAzureCloudOptions) { return __awaiter(this, void 0, void 0, function () { var discoveredAuthority; return __generator(this, function (_a) { switch (_a.label) { case 0: this.logger.verbose("getClientConfiguration called", this.correlationId); return [4 /*yield*/, this.getDiscoveredAuthority(requestAuthority, requestAzureCloudOptions)]; case 1: discoveredAuthority = _a.sent(); return [2 /*return*/, { authOptions: { clientId: this.config.auth.clientId, authority: discoveredAuthority, clientCapabilities: this.config.auth.clientCapabilities }, systemOptions: { tokenRenewalOffsetSeconds: this.config.system.tokenRenewalOffsetSeconds, preventCorsPreflight: true }, loggerOptions: { loggerCallback: this.config.system.loggerOptions.loggerCallback, piiLoggingEnabled: this.config.system.loggerOptions.piiLoggingEnabled, logLevel: this.config.system.loggerOptions.logLevel, correlationId: this.correlationId }, cryptoInterface: this.browserCrypto, networkInterface: this.networkClient, storageInterface: this.browserStorage, serverTelemetryManager: serverTelemetryManager, libraryInfo: { sku: BrowserConstants.MSAL_SKU, version: version, cpu: Constants.EMPTY_STRING, os: Constants.EMPTY_STRING }, telemetry: this.config.telemetry }]; } }); }); }; /** * @param hash * @param interactionType */ StandardInteractionClient.prototype.validateAndExtractStateFromHash = function (serverParams, interactionType, requestCorrelationId) { this.logger.verbose("validateAndExtractStateFromHash called", requestCorrelationId); if (!serverParams.state) { throw BrowserAuthError.createHashDoesNotContainStateError(); } var platformStateObj = BrowserProtocolUtils.extractBrowserRequestState(this.browserCrypto, serverParams.state); if (!platformStateObj) { throw BrowserAuthError.createUnableToParseStateError(); } if (platformStateObj.interactionType !== interactionType) { throw BrowserAuthError.createStateInteractionTypeMismatchError(); } this.logger.verbose("Returning state from hash", requestCorrelationId); return serverParams.state; }; /** * Used to get a discovered version of the default authority. * @param requestAuthority * @param requestCorrelationId */ StandardInteractionClient.prototype.getDiscoveredAuthority = function (requestAuthority, requestAzureCloudOptions) { return __awaiter(this, void 0, void 0, function () { var getAuthorityMeasurement, authorityOptions, userAuthority, builtAuthority; return __generator(this, function (_a) { switch (_a.label) { case 0: this.logger.verbose("getDiscoveredAuthority called", this.correlationId); getAuthorityMeasurement = this.performanceClient.startMeasurement(PerformanceEvents.StandardInteractionClientGetDiscoveredAuthority, this.correlationId); authorityOptions = { protocolMode: this.config.auth.protocolMode, knownAuthorities: this.config.auth.knownAuthorities, cloudDiscoveryMetadata: this.config.auth.cloudDiscoveryMetadata, authorityMetadata: this.config.auth.authorityMetadata, skipAuthorityMetadataCache: this.config.auth.skipAuthorityMetadataCache }; userAuthority = requestAuthority ? requestAuthority : this.config.auth.authority; builtAuthority = Authority.generateAuthority(userAuthority, requestAzureCloudOptions || this.config.auth.azureCloudOptions); this.logger.verbose("Creating discovered authority with configured authority", this.correlationId); return [4 /*yield*/, AuthorityFactory.createDiscoveredInstance(builtAuthority, this.config.system.networkClient, this.browserStorage, authorityOptions) .then(function (result) { getAuthorityMeasurement.endMeasurement({ success: true }); return result; }) .catch(function (error) { getAuthorityMeasurement.endMeasurement({ errorCode: error.errorCode, subErrorCode: error.subError, success: false }); throw error; })]; case 1: return [2 /*return*/, _a.sent()]; } }); }); }; /** * Helper to initialize required request parameters for interactive APIs and ssoSilent() * @param request * @param interactionType */ StandardInteractionClient.prototype.initializeAuthorizationRequest = function (request, interactionType) { return __awaiter(this, void 0, void 0, function () { var redirectUri, browserState, state, validatedRequest, _a, account, legacyLoginHint; return __generator(this, function (_b) { switch (_b.label) { case 0: this.logger.verbose("initializeAuthorizationRequest called", this.correlationId); redirectUri = this.getRedirectUri(request.redirectUri); browserState = { interactionType: interactionType }; state = ProtocolUtils.setRequestState(this.browserCrypto, (request && request.state) || Constants.EMPTY_STRING, browserState); _a = [{}]; return [4 /*yield*/, this.initializeBaseRequest(request)]; case 1: validatedRequest = __assign.apply(void 0, [__assign.apply(void 0, _a.concat([_b.sent()])), { redirectUri: redirectUri, state: state, nonce: request.nonce || this.browserCrypto.createNewGuid(), responseMode: ResponseMode.FRAGMENT }]); account = request.account || this.browserStorage.getActiveAccount(); if (account) { this.logger.verbose("Setting validated request account", this.correlationId); this.logger.verbosePii("Setting validated request account: " + account.homeAccountId, this.correlationId); validatedRequest.account = account; } // Check for ADAL/MSAL v1 SSO if (StringUtils.isEmpty(validatedRequest.loginHint) && !account) { legacyLoginHint = this.browserStorage.getLegacyLoginHint(); if (legacyLoginHint) { validatedRequest.loginHint = legacyLoginHint; } } return [2 /*return*/, validatedRequest]; } }); }); }; return StandardInteractionClient; }(BaseInteractionClient)); export { StandardInteractionClient }; //# sourceMappingURL=StandardInteractionClient.js.map