@azure/msal-browser
Version:
Microsoft Authentication Library for js
158 lines (155 loc) • 8.99 kB
JavaScript
/*! @azure/msal-browser v5.7.0 2026-04-16 */
'use strict';
import { CustomAuthApiError } from '../../core/error/CustomAuthApiError.mjs';
import { CustomAuthInteractionClientBase } from '../../core/interaction_client/CustomAuthInteractionClientBase.mjs';
import { UNSUPPORTED_CHALLENGE_TYPE, PASSWORD_CHANGE_FAILED, PASSWORD_RESET_TIMEOUT } from '../../core/network_client/custom_auth_api/types/ApiErrorCodes.mjs';
import { PASSWORD_RESET_START, PASSWORD_RESET_SUBMIT_CODE, PASSWORD_RESET_RESEND_CODE, PASSWORD_RESET_SUBMIT_PASSWORD } from '../../core/telemetry/PublicApiId.mjs';
import { ChallengeType, DefaultCustomAuthApiCodeLength, PasswordResetPollingTimeoutInMs, ResetPasswordPollStatus } from '../../CustomAuthConstants.mjs';
import { ensureArgumentIsNotEmptyString } from '../../core/utils/ArgumentValidator.mjs';
import { initializeServerTelemetryManager } from '../../../interaction_client/BaseInteractionClient.mjs';
/*
* Copyright (c) Microsoft Corporation. All rights reserved.
* Licensed under the MIT License.
*/
class ResetPasswordClient extends CustomAuthInteractionClientBase {
/**
* Starts the password reset flow.
* @param parameters The parameters for starting the password reset flow.
* @returns The result of password reset start operation.
*/
async start(parameters) {
const correlationId = parameters.correlationId || this.correlationId;
const apiId = PASSWORD_RESET_START;
const telemetryManager = initializeServerTelemetryManager(apiId, this.config.auth.clientId, correlationId, this.browserStorage, this.logger);
const startRequest = {
challenge_type: this.getChallengeTypes(parameters.challengeType),
username: parameters.username,
correlationId: correlationId,
telemetryManager: telemetryManager,
};
this.logger.verbose("13zstj", correlationId);
const startResponse = await this.customAuthApiClient.resetPasswordApi.start(startRequest);
this.logger.verbose("0wsodm", correlationId);
const challengeRequest = {
continuation_token: startResponse.continuation_token ?? "",
challenge_type: this.getChallengeTypes(parameters.challengeType),
correlationId: startResponse.correlation_id || correlationId,
telemetryManager: telemetryManager,
};
return this.performChallengeRequest(challengeRequest);
}
/**
* Submits the code for password reset.
* @param parameters The parameters for submitting the code for password reset.
* @returns The result of submitting the code for password reset.
*/
async submitCode(parameters) {
const correlationId = parameters.correlationId || this.correlationId;
ensureArgumentIsNotEmptyString("parameters.code", parameters.code, correlationId);
const apiId = PASSWORD_RESET_SUBMIT_CODE;
const telemetryManager = initializeServerTelemetryManager(apiId, this.config.auth.clientId, correlationId, this.browserStorage, this.logger);
const continueRequest = {
continuation_token: parameters.continuationToken,
oob: parameters.code,
correlationId: correlationId,
telemetryManager: telemetryManager,
};
this.logger.verbose("0rnsi3", correlationId);
const response = await this.customAuthApiClient.resetPasswordApi.continueWithCode(continueRequest);
this.logger.verbose("1w9r8y", response.correlation_id);
return {
correlationId: response.correlation_id || correlationId,
continuationToken: response.continuation_token ?? "",
};
}
/**
* Resends the another one-time passcode if the previous one hasn't been verified
* @param parameters The parameters for resending the code for password reset.
* @returns The result of resending the code for password reset.
*/
async resendCode(parameters) {
const correlationId = parameters.correlationId || this.correlationId;
const apiId = PASSWORD_RESET_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),
correlationId: correlationId,
telemetryManager: telemetryManager,
};
return this.performChallengeRequest(challengeRequest);
}
/**
* Submits the new password for password reset.
* @param parameters The parameters for submitting the new password for password reset.
* @returns The result of submitting the new password for password reset.
*/
async submitNewPassword(parameters) {
const correlationId = parameters.correlationId || this.correlationId;
ensureArgumentIsNotEmptyString("parameters.newPassword", parameters.newPassword, correlationId);
const apiId = PASSWORD_RESET_SUBMIT_PASSWORD;
const telemetryManager = initializeServerTelemetryManager(apiId, this.config.auth.clientId, correlationId, this.browserStorage, this.logger);
const submitRequest = {
continuation_token: parameters.continuationToken,
new_password: parameters.newPassword,
correlationId: correlationId,
telemetryManager: telemetryManager,
};
this.logger.verbose("060415", correlationId);
const submitResponse = await this.customAuthApiClient.resetPasswordApi.submitNewPassword(submitRequest);
this.logger.verbose("0vmsxm", submitResponse.correlation_id || correlationId);
return this.performPollCompletionRequest(submitResponse.continuation_token ?? "", submitResponse.poll_interval, submitResponse.correlation_id || correlationId, telemetryManager);
}
async performChallengeRequest(request) {
const correlationId = request.correlationId;
this.logger.verbose("0sjpbp", correlationId);
const response = await this.customAuthApiClient.resetPasswordApi.requestChallenge(request);
this.logger.verbose("1l48o7", response.correlation_id || correlationId);
if (response.challenge_type === ChallengeType.OOB) {
// Code is required
this.logger.verbose("1oz986", response.correlation_id || correlationId);
return {
correlationId: response.correlation_id || correlationId,
continuationToken: response.continuation_token ?? "",
challengeChannel: response.challenge_channel ?? "",
challengeTargetLabel: response.challenge_target_label ?? "",
codeLength: response.code_length ?? DefaultCustomAuthApiCodeLength,
bindingMethod: response.binding_method ?? "",
};
}
this.logger.error("0emdih", response.correlation_id || correlationId);
throw new CustomAuthApiError(UNSUPPORTED_CHALLENGE_TYPE, `Unsupported challenge type '${response.challenge_type}'.`, response.correlation_id || correlationId);
}
async performPollCompletionRequest(continuationToken, pollInterval, correlationId, telemetryManager) {
const startTime = performance.now();
while (performance.now() - startTime <
PasswordResetPollingTimeoutInMs) {
const pollRequest = {
continuation_token: continuationToken,
correlationId: correlationId,
telemetryManager: telemetryManager,
};
this.logger.verbose("1hadzp", correlationId);
const pollResponse = await this.customAuthApiClient.resetPasswordApi.pollCompletion(pollRequest);
this.logger.verbose("0cghal", correlationId);
if (pollResponse.status === ResetPasswordPollStatus.SUCCEEDED) {
return {
correlationId: pollResponse.correlation_id,
continuationToken: pollResponse.continuation_token ?? "",
};
}
else if (pollResponse.status === ResetPasswordPollStatus.FAILED) {
throw new CustomAuthApiError(PASSWORD_CHANGE_FAILED, "Password is failed to be reset.", pollResponse.correlation_id);
}
this.logger.verbose("0ykdlr", correlationId);
await this.delay(pollInterval * 1000);
}
this.logger.error("0v2tkb", correlationId);
throw new CustomAuthApiError(PASSWORD_RESET_TIMEOUT, "Password reset flow has timed out.", correlationId);
}
async delay(ms) {
return new Promise((resolve) => setTimeout(resolve, ms));
}
}
export { ResetPasswordClient };
//# sourceMappingURL=ResetPasswordClient.mjs.map