@azure/msal-browser
Version:
Microsoft Authentication Library for js
248 lines (245 loc) • 14.5 kB
JavaScript
/*! @azure/msal-browser v5.7.0 2026-04-16 */
'use strict';
import { CustomAuthApiError } from '../../core/error/CustomAuthApiError.mjs';
import { UNSUPPORTED_CHALLENGE_TYPE, ATTRIBUTES_REQUIRED, CREDENTIAL_REQUIRED, INVALID_RESPONSE_BODY, CONTINUATION_TOKEN_MISSING } from '../../core/network_client/custom_auth_api/types/ApiErrorCodes.mjs';
import { UnexpectedError } from '../../core/error/UnexpectedError.mjs';
import { CustomAuthInteractionClientBase } from '../../core/interaction_client/CustomAuthInteractionClientBase.mjs';
import { SIGN_UP_START, SIGN_UP_WITH_PASSWORD_START, SIGN_UP_SUBMIT_CODE, SIGN_UP_SUBMIT_PASSWORD, SIGN_UP_SUBMIT_ATTRIBUTES, SIGN_UP_RESEND_CODE } from '../../core/telemetry/PublicApiId.mjs';
import { ChallengeType, DefaultCustomAuthApiCodeResendIntervalInSec, DefaultCustomAuthApiCodeLength } from '../../CustomAuthConstants.mjs';
import { SIGN_UP_CODE_REQUIRED_RESULT_TYPE, SIGN_UP_PASSWORD_REQUIRED_RESULT_TYPE, SIGN_UP_ATTRIBUTES_REQUIRED_RESULT_TYPE, createSignUpCodeRequiredResult, createSignUpPasswordRequiredResult, createSignUpCompletedResult, createSignUpAttributesRequiredResult } from './result/SignUpActionResult.mjs';
import { initializeServerTelemetryManager } from '../../../interaction_client/BaseInteractionClient.mjs';
/*
* Copyright (c) Microsoft Corporation. All rights reserved.
* Licensed under the MIT License.
*/
class SignUpClient extends CustomAuthInteractionClientBase {
/**
* Starts the sign up flow.
* @param parameters The parameters for the sign up start action.
* @returns The result of the sign up start action.
*/
async start(parameters) {
const correlationId = parameters.correlationId || this.correlationId;
const apiId = !parameters.password
? SIGN_UP_START
: SIGN_UP_WITH_PASSWORD_START;
const telemetryManager = initializeServerTelemetryManager(apiId, this.config.auth.clientId, correlationId, this.browserStorage, this.logger);
const startRequest = {
username: parameters.username,
password: parameters.password,
attributes: parameters.attributes,
challenge_type: this.getChallengeTypes(parameters.challengeType),
telemetryManager,
correlationId: correlationId,
};
this.logger.verbose("1ufort", correlationId);
const startResponse = await this.customAuthApiClient.signUpApi.start(startRequest);
this.logger.verbose("1mzh8i", startResponse.correlation_id || correlationId);
const challengeRequest = {
continuation_token: startResponse.continuation_token ?? "",
challenge_type: this.getChallengeTypes(parameters.challengeType),
telemetryManager,
correlationId: startResponse.correlation_id || correlationId,
};
return this.performChallengeRequest(challengeRequest);
}
/**
* Submits the code for the sign up flow.
* @param parameters The parameters for the sign up submit code action.
* @returns The result of the sign up submit code action.
*/
async submitCode(parameters) {
const correlationId = parameters.correlationId || this.correlationId;
const apiId = SIGN_UP_SUBMIT_CODE;
const telemetryManager = initializeServerTelemetryManager(apiId, this.config.auth.clientId, correlationId, this.browserStorage, this.logger);
const requestSubmitCode = {
continuation_token: parameters.continuationToken,
oob: parameters.code,
telemetryManager,
correlationId: correlationId,
};
const result = await this.performContinueRequest("SignUpClient.submitCode", parameters, telemetryManager, () => this.customAuthApiClient.signUpApi.continueWithCode(requestSubmitCode), correlationId);
if (result.type === SIGN_UP_CODE_REQUIRED_RESULT_TYPE) {
throw new CustomAuthApiError(UNSUPPORTED_CHALLENGE_TYPE, "The challenge type 'oob' is invalid after submtting code for sign up.", result.correlationId || correlationId);
}
return result;
}
/**
* Submits the password for the sign up flow.
* @param parameters The parameters for the sign up submit password action.
* @returns The result of the sign up submit password action.
*/
async submitPassword(parameters) {
const correlationId = parameters.correlationId || this.correlationId;
const apiId = SIGN_UP_SUBMIT_PASSWORD;
const telemetryManager = initializeServerTelemetryManager(apiId, this.config.auth.clientId, correlationId, this.browserStorage, this.logger);
const requestSubmitPwd = {
continuation_token: parameters.continuationToken,
password: parameters.password,
telemetryManager,
correlationId: correlationId,
};
const result = await this.performContinueRequest("SignUpClient.submitPassword", parameters, telemetryManager, () => this.customAuthApiClient.signUpApi.continueWithPassword(requestSubmitPwd), correlationId);
if (result.type === SIGN_UP_PASSWORD_REQUIRED_RESULT_TYPE) {
throw new CustomAuthApiError(UNSUPPORTED_CHALLENGE_TYPE, "The challenge type 'password' is invalid after submtting password for sign up.", result.correlationId || correlationId);
}
return result;
}
/**
* Submits the attributes for the sign up flow.
* @param parameters The parameters for the sign up submit attributes action.
* @returns The result of the sign up submit attributes action.
*/
async submitAttributes(parameters) {
const correlationId = parameters.correlationId || this.correlationId;
const apiId = SIGN_UP_SUBMIT_ATTRIBUTES;
const telemetryManager = initializeServerTelemetryManager(apiId, this.config.auth.clientId, correlationId, this.browserStorage, this.logger);
const reqWithAttr = {
continuation_token: parameters.continuationToken,
attributes: parameters.attributes,
telemetryManager,
correlationId: correlationId,
};
const result = await this.performContinueRequest("SignUpClient.submitAttributes", parameters, telemetryManager, () => this.customAuthApiClient.signUpApi.continueWithAttributes(reqWithAttr), correlationId);
if (result.type === SIGN_UP_ATTRIBUTES_REQUIRED_RESULT_TYPE) {
throw new CustomAuthApiError(ATTRIBUTES_REQUIRED, "User attributes required", result.correlationId || correlationId, [], "", result.requiredAttributes, result.continuationToken);
}
return result;
}
/**
* Resends the code for the sign up flow.
* @param parameters The parameters for the sign up resend code action.
* @returns The result of the sign up resend code action.
*/
async resendCode(parameters) {
const correlationId = parameters.correlationId || this.correlationId;
const apiId = SIGN_UP_RESEND_CODE;
const telemetryManager = initializeServerTelemetryManager(apiId, this.config.auth.clientId, correlationId, this.browserStorage, this.logger);
const challengeRequest = {
continuation_token: parameters.continuationToken ?? "",
challenge_type: this.getChallengeTypes(parameters.challengeType),
telemetryManager,
correlationId: correlationId,
};
const result = await this.performChallengeRequest(challengeRequest);
if (result.type === SIGN_UP_PASSWORD_REQUIRED_RESULT_TYPE) {
throw new CustomAuthApiError(UNSUPPORTED_CHALLENGE_TYPE, "The challenge type 'password' is invalid after resending code for sign up.", result.correlationId || correlationId);
}
return result;
}
async performChallengeRequest(request) {
this.logger.verbose("0wfw94", request.correlationId);
const challengeResponse = await this.customAuthApiClient.signUpApi.requestChallenge(request);
this.logger.verbose("1izuav", challengeResponse.correlation_id || request.correlationId);
if (challengeResponse.challenge_type === ChallengeType.OOB) {
// Code is required
this.logger.verbose("0ucygy", challengeResponse.correlation_id || request.correlationId);
return createSignUpCodeRequiredResult({
correlationId: challengeResponse.correlation_id || request.correlationId,
continuationToken: challengeResponse.continuation_token ?? "",
challengeChannel: challengeResponse.challenge_channel ?? "",
challengeTargetLabel: challengeResponse.challenge_target_label ?? "",
codeLength: challengeResponse.code_length ??
DefaultCustomAuthApiCodeLength,
interval: challengeResponse.interval ??
DefaultCustomAuthApiCodeResendIntervalInSec,
bindingMethod: challengeResponse.binding_method ?? "",
});
}
if (challengeResponse.challenge_type === ChallengeType.PASSWORD) {
// Password is required
this.logger.verbose("11vq5l", challengeResponse.correlation_id || request.correlationId);
return createSignUpPasswordRequiredResult({
correlationId: challengeResponse.correlation_id || request.correlationId,
continuationToken: challengeResponse.continuation_token ?? "",
});
}
this.logger.error("0wg2fe", challengeResponse.correlation_id || request.correlationId);
throw new CustomAuthApiError(UNSUPPORTED_CHALLENGE_TYPE, `Unsupported challenge type '${challengeResponse.challenge_type}'.`, challengeResponse.correlation_id || request.correlationId);
}
async performContinueRequest(callerName, requestParams, telemetryManager, responseGetter, requestCorrelationId) {
this.logger.verbose("0sw5ym", requestCorrelationId);
try {
const response = await responseGetter();
this.logger.verbose("0ib062", response.correlation_id || requestCorrelationId);
return createSignUpCompletedResult({
correlationId: response.correlation_id || requestCorrelationId,
continuationToken: response.continuation_token ?? "",
});
}
catch (error) {
if (error instanceof CustomAuthApiError) {
return this.handleContinueResponseError(error, error.correlationId || requestCorrelationId, requestParams, telemetryManager);
}
else {
this.logger.errorPii("03rje8", requestCorrelationId);
throw new UnexpectedError(error, requestCorrelationId);
}
}
}
async handleContinueResponseError(responseError, correlationId, requestParams, telemetryManager) {
if (responseError.error ===
CREDENTIAL_REQUIRED &&
!!responseError.errorCodes &&
responseError.errorCodes.includes(55103)) {
// Credential is required
this.logger.verbose("164mmt", correlationId);
const continuationToken = this.readContinuationTokenFromResponeError(responseError, correlationId);
// Call the challenge endpoint to ensure the password challenge type is supported.
const challengeRequest = {
continuation_token: continuationToken,
challenge_type: this.getChallengeTypes(requestParams.challengeType),
telemetryManager,
correlationId,
};
const challengeResult = await this.performChallengeRequest(challengeRequest);
if (challengeResult.type === SIGN_UP_PASSWORD_REQUIRED_RESULT_TYPE) {
return createSignUpPasswordRequiredResult({
correlationId: challengeResult.correlationId || correlationId,
continuationToken: challengeResult.continuationToken,
});
}
if (challengeResult.type === SIGN_UP_CODE_REQUIRED_RESULT_TYPE) {
return createSignUpCodeRequiredResult({
correlationId: challengeResult.correlationId || correlationId,
continuationToken: challengeResult.continuationToken,
challengeChannel: challengeResult.challengeChannel,
challengeTargetLabel: challengeResult.challengeTargetLabel,
codeLength: challengeResult.codeLength,
interval: challengeResult.interval,
bindingMethod: challengeResult.bindingMethod,
});
}
throw new CustomAuthApiError(UNSUPPORTED_CHALLENGE_TYPE, "The challenge type is not supported.", correlationId);
}
if (this.isAttributesRequiredError(responseError, correlationId)) {
// Attributes are required
this.logger.verbose("13zvmd", correlationId);
const continuationToken = this.readContinuationTokenFromResponeError(responseError, correlationId);
return createSignUpAttributesRequiredResult({
correlationId: correlationId,
continuationToken: continuationToken,
requiredAttributes: responseError.attributes ?? [],
});
}
throw responseError;
}
isAttributesRequiredError(responseError, correlationId) {
if (responseError.error === ATTRIBUTES_REQUIRED) {
if (!responseError.attributes ||
responseError.attributes.length === 0) {
throw new CustomAuthApiError(INVALID_RESPONSE_BODY, "Attributes are required but required_attributes field is missing in the response body.", correlationId);
}
return true;
}
return false;
}
readContinuationTokenFromResponeError(responseError, correlationId) {
if (!responseError.continuationToken) {
throw new CustomAuthApiError(CONTINUATION_TOKEN_MISSING, "Continuation token is missing in the response body", correlationId);
}
return responseError.continuationToken;
}
}
export { SignUpClient };
//# sourceMappingURL=SignUpClient.mjs.map