/*! @azure/msal-browser v3.6.0 2023-12-01 */
'use strict';
import { RequestParameterBuilder, StringUtils, AuthenticationScheme, createClientAuthError, ClientAuthErrorCodes, AuthToken, AuthError, InteractionRequiredAuthError, ServerError, ClientAuthError } from '@azure/msal-common';
import { isBridgeError } from '../BridgeError.mjs';
import { BridgeStatusCode } from '../BridgeStatusCode.mjs';

/*
 * Copyright (c) Microsoft Corporation. All rights reserved.
 * Licensed under the MIT License.
 */
class NestedAppAuthAdapter {
    constructor(clientId, clientCapabilities, crypto, logger) {
        this.clientId = clientId;
        this.clientCapabilities = clientCapabilities;
        this.crypto = crypto;
        this.logger = logger;
    }
    toNaaTokenRequest(request) {
        let extraParams;
        if (request.extraQueryParameters === undefined) {
            extraParams = new Map();
        }
        else {
            extraParams = new Map(Object.entries(request.extraQueryParameters));
        }
        const requestBuilder = new RequestParameterBuilder();
        const claims = requestBuilder.addClientCapabilitiesToClaims(request.claims, this.clientCapabilities);
        const tokenRequest = {
            userObjectId: request.account?.homeAccountId,
            clientId: this.clientId,
            authority: request.authority,
            scope: request.scopes.join(" "),
            correlationId: request.correlationId !== undefined
                ? request.correlationId
                : this.crypto.createNewGuid(),
            nonce: request.nonce,
            claims: !StringUtils.isEmptyObj(claims) ? claims : undefined,
            state: request.state,
            authenticationScheme: request.authenticationScheme || AuthenticationScheme.BEARER,
            extraParameters: extraParams,
        };
        return tokenRequest;
    }
    fromNaaTokenResponse(request, response, reqTimestamp) {
        if (!response.id_token || !response.access_token) {
            throw createClientAuthError(ClientAuthErrorCodes.nullOrEmptyToken);
        }
        const expiresOn = new Date((reqTimestamp + (response.expires_in || 0)) * 1000);
        const idTokenClaims = AuthToken.extractTokenClaims(response.id_token, this.crypto.base64Decode);
        const account = this.fromNaaAccountInfo(response.account, idTokenClaims);
        const authenticationResult = {
            authority: response.authority || account.environment,
            uniqueId: account.localAccountId,
            tenantId: account.tenantId,
            scopes: response.scope.split(" "),
            account,
            idToken: response.id_token !== undefined ? response.id_token : "",
            idTokenClaims,
            accessToken: response.access_token,
            fromCache: true,
            expiresOn: expiresOn,
            tokenType: request.authenticationScheme || AuthenticationScheme.BEARER,
            correlationId: request.correlationId,
            extExpiresOn: expiresOn,
            state: request.state,
        };
        return authenticationResult;
    }
    /*
     *  export type AccountInfo = {
     *     homeAccountId: string;
     *     environment: string;
     *     tenantId: string;
     *     username: string;
     *     localAccountId: string;
     *     name?: string;
     *     idToken?: string;
     *     idTokenClaims?: TokenClaims & {
     *         [key: string]:
     *             | string
     *             | number
     *             | string[]
     *             | object
     *             | undefined
     *             | unknown;
     *     };
     *     nativeAccountId?: string;
     *     authorityType?: string;
     * };
     */
    fromNaaAccountInfo(fromAccount, idTokenClaims) {
        const effectiveIdTokenClaims = idTokenClaims || fromAccount.idTokenClaims;
        const localAccountId = fromAccount.localAccountId ||
            effectiveIdTokenClaims?.oid ||
            effectiveIdTokenClaims?.sub ||
            "";
        const tenantId = fromAccount.tenantId || effectiveIdTokenClaims?.tid || "";
        const homeAccountId = fromAccount.homeAccountId || `${localAccountId}.${tenantId}`;
        const username = fromAccount.username ||
            effectiveIdTokenClaims?.preferred_username ||
            "";
        const name = fromAccount.name || effectiveIdTokenClaims?.name;
        const account = {
            homeAccountId,
            environment: fromAccount.environment,
            tenantId,
            username,
            localAccountId,
            name,
            idToken: fromAccount.idToken,
            idTokenClaims: effectiveIdTokenClaims,
        };
        return account;
    }
    /**
     *
     * @param error BridgeError
     * @returns AuthError, ClientAuthError, ClientConfigurationError, ServerError, InteractionRequiredError
     */
    fromBridgeError(error) {
        if (isBridgeError(error)) {
            switch (error.status) {
                case BridgeStatusCode.USER_CANCEL:
                    return new ClientAuthError(ClientAuthErrorCodes.userCanceled);
                case BridgeStatusCode.NO_NETWORK:
                    return new ClientAuthError(ClientAuthErrorCodes.noNetworkConnectivity);
                case BridgeStatusCode.ACCOUNT_UNAVAILABLE:
                    return new ClientAuthError(ClientAuthErrorCodes.noAccountFound);
                case BridgeStatusCode.DISABLED:
                    return new ClientAuthError(ClientAuthErrorCodes.nestedAppAuthBridgeDisabled);
                case BridgeStatusCode.NESTED_APP_AUTH_UNAVAILABLE:
                    return new ClientAuthError(error.code ||
                        ClientAuthErrorCodes.nestedAppAuthBridgeDisabled, error.description);
                case BridgeStatusCode.TRANSIENT_ERROR:
                case BridgeStatusCode.PERSISTENT_ERROR:
                    return new ServerError(error.code, error.description);
                case BridgeStatusCode.USER_INTERACTION_REQUIRED:
                    return new InteractionRequiredAuthError(error.code, error.description);
                default:
                    return new AuthError(error.code, error.description);
            }
        }
        else {
            return new AuthError("unknown_error", "An unknown error occurred");
        }
    }
}

export { NestedAppAuthAdapter };
//# sourceMappingURL=NestedAppAuthAdapter.mjs.map
