/*! @azure/msal-browser v2.30.0 2022-10-10 */
'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
