Skip to content

Commit ffe81ab

Browse files
authored
[Native Auth] Update the logic for detecting phone blocked errors (#8087)
1 parent b08a46c commit ffe81ab

File tree

6 files changed

+41
-39
lines changed

6 files changed

+41
-39
lines changed
Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,7 @@
1+
{
2+
"type": "patch",
3+
"comment": "Update the logic for detecting phone blocked error #8087",
4+
"packageName": "@azure/msal-browser",
5+
"email": "[email protected]",
6+
"dependentChangeType": "patch"
7+
}

lib/msal-browser/src/custom_auth/core/auth_flow/AuthFlowErrorBase.ts

Lines changed: 3 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -153,11 +153,9 @@ export abstract class AuthFlowErrorBase {
153153
protected isVerificationContactBlockedError(): boolean {
154154
return (
155155
this.errorData instanceof CustomAuthApiError &&
156-
this.errorData.error === CustomAuthApiErrorCode.INVALID_REQUEST &&
157-
this.errorData.errorCodes?.includes(550024) === true &&
158-
this.errorData.errorDescription?.includes(
159-
"multi-factor authentication method is blocked"
160-
) === true
156+
this.errorData.error === CustomAuthApiErrorCode.ACCESS_DENIED &&
157+
this.errorData.subError ===
158+
CustomAuthApiSuberror.PROVIDER_BLOCKED_BY_REPUTATION
161159
);
162160
}
163161
}

lib/msal-browser/src/custom_auth/core/network_client/custom_auth_api/types/ApiErrorCodes.ts

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -24,3 +24,4 @@ export const PASSWORD_CHANGE_FAILED = "password_change_failed";
2424
export const PASSWORD_RESET_TIMEOUT = "password_reset_timeout";
2525
export const CLIENT_INFO_MISSING = "client_info_missing";
2626
export const EXPIRED_TOKEN = "expired_token";
27+
export const ACCESS_DENIED = "access_denied";

lib/msal-browser/src/custom_auth/core/network_client/custom_auth_api/types/ApiSuberrors.ts

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -14,3 +14,4 @@ export const ATTRIBUTE_VALIATION_FAILED = "attribute_validation_failed";
1414
export const NATIVEAUTHAPI_DISABLED = "nativeauthapi_disabled";
1515
export const REGISTRATION_REQUIRED = "registration_required";
1616
export const MFA_REQUIRED = "mfa_required";
17+
export const PROVIDER_BLOCKED_BY_REPUTATION = "provider_blocked_by_rep";

lib/msal-browser/test/custom_auth/core/auth_flow/jit/error_type/AuthMethodRegistrationError.spec.ts

Lines changed: 15 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -95,12 +95,13 @@ describe("JitError", () => {
9595
expect(error.isInvalidInput()).toBe(false);
9696
});
9797

98-
it("should return true for isVerificationContactBlocked when API error with error code 550024 and correct description", () => {
98+
it("should return true for isVerificationContactBlocked when ACCESS_DENIED with PROVIDER_BLOCKED_BY_REPUTATION subError", () => {
9999
const apiError = new CustomAuthApiError(
100-
CustomAuthApiErrorCode.INVALID_REQUEST,
101-
"multi-factor authentication method is blocked",
100+
CustomAuthApiErrorCode.ACCESS_DENIED,
101+
"Verification contact blocked by reputation system",
102102
"correlation-id",
103-
[550024]
103+
[],
104+
CustomAuthApiSuberror.PROVIDER_BLOCKED_BY_REPUTATION
104105
);
105106
const error = new AuthMethodRegistrationChallengeMethodError(
106107
apiError
@@ -109,12 +110,13 @@ describe("JitError", () => {
109110
expect(error.isVerificationContactBlocked()).toBe(true);
110111
});
111112

112-
it("should return false for isVerificationContactBlocked when API error with error code 550024 but wrong description", () => {
113+
it("should return false for isVerificationContactBlocked when ACCESS_DENIED but different subError", () => {
113114
const apiError = new CustomAuthApiError(
114-
CustomAuthApiErrorCode.INVALID_REQUEST,
115-
"Some other error description",
115+
CustomAuthApiErrorCode.ACCESS_DENIED,
116+
"Other access denied scenario",
116117
"correlation-id",
117-
[550024]
118+
[],
119+
CustomAuthApiSuberror.INVALID_OOB_VALUE
118120
);
119121
const error = new AuthMethodRegistrationChallengeMethodError(
120122
apiError
@@ -123,12 +125,13 @@ describe("JitError", () => {
123125
expect(error.isVerificationContactBlocked()).toBe(false);
124126
});
125127

126-
it("should return false for isVerificationContactBlocked when different error code", () => {
128+
it("should return false for isVerificationContactBlocked when subError matches but error != ACCESS_DENIED", () => {
127129
const apiError = new CustomAuthApiError(
128-
CustomAuthApiErrorCode.INVALID_GRANT,
129-
"multi-factor authentication method is blocked",
130+
CustomAuthApiErrorCode.INVALID_REQUEST,
131+
"Verification contact blocked by reputation system",
130132
"correlation-id",
131-
[901001]
133+
[],
134+
CustomAuthApiSuberror.PROVIDER_BLOCKED_BY_REPUTATION
132135
);
133136
const error = new AuthMethodRegistrationChallengeMethodError(
134137
apiError

lib/msal-browser/test/custom_auth/core/auth_flow/mfa/error_type/MfaError.spec.ts

Lines changed: 14 additions & 22 deletions
Original file line numberDiff line numberDiff line change
@@ -73,45 +73,37 @@ describe("MfaRequestChallengeError", () => {
7373
});
7474

7575
describe("isVerificationContactBlocked", () => {
76-
it("returns true when invalid_request with code 550024 and matching description substring", () => {
76+
it("returns true when error is ACCESS_DENIED with subError PROVIDER_BLOCKED_BY_REPUTATION", () => {
7777
const apiError = new CustomAuthApiError(
78-
"invalid_request",
79-
"The multi-factor authentication method is blocked due to too many attempts.",
78+
"access_denied",
79+
"Verification contact blocked by reputation system",
8080
"correlation-id",
81-
[550024]
81+
[],
82+
CustomAuthApiSuberror.PROVIDER_BLOCKED_BY_REPUTATION
8283
);
8384
const mfaError = new MfaRequestChallengeError(apiError);
8485
expect(mfaError.isVerificationContactBlocked()).toBe(true);
8586
});
8687

87-
it("returns false when code 550024 present but description does not contain required phrase", () => {
88+
it("returns false when error is ACCESS_DENIED but subError different", () => {
8889
const apiError = new CustomAuthApiError(
89-
"invalid_request",
90-
"MFA method temporarily disabled.",
90+
"access_denied",
91+
"Some other access denied error",
9192
"correlation-id",
92-
[550024]
93+
[],
94+
CustomAuthApiSuberror.INVALID_OOB_VALUE
9395
);
9496
const mfaError = new MfaRequestChallengeError(apiError);
9597
expect(mfaError.isVerificationContactBlocked()).toBe(false);
9698
});
9799

98-
it("returns false when description contains phrase but error code 550024 missing", () => {
100+
it("returns false when subError matches but error code not ACCESS_DENIED", () => {
99101
const apiError = new CustomAuthApiError(
100102
"invalid_request",
101-
"The multi-factor authentication method is blocked at this time.",
103+
"Verification contact blocked by reputation system",
102104
"correlation-id",
103-
[901001]
104-
);
105-
const mfaError = new MfaRequestChallengeError(apiError);
106-
expect(mfaError.isVerificationContactBlocked()).toBe(false);
107-
});
108-
109-
it("returns false when different error type even if code and description match", () => {
110-
const apiError = new CustomAuthApiError(
111-
"server_error",
112-
"The multi-factor authentication method is blocked by policy.",
113-
"correlation-id",
114-
[550024]
105+
[],
106+
CustomAuthApiSuberror.PROVIDER_BLOCKED_BY_REPUTATION
115107
);
116108
const mfaError = new MfaRequestChallengeError(apiError);
117109
expect(mfaError.isVerificationContactBlocked()).toBe(false);

0 commit comments

Comments
 (0)