Skip to content

Commit 1e6420e

Browse files
authored
[Native Auth] Introduce the stateType property in state classes for the type detection (#8090)
Introduce a new property stateType in all state classes for avoid the circular dependency issue which may happen in some scenarios.
1 parent ffe81ab commit 1e6420e

File tree

47 files changed

+470
-95
lines changed

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

47 files changed

+470
-95
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": "Introduce the stateType property in state classes for the type detection #8090",
4+
"packageName": "@azure/msal-browser",
5+
"email": "shen.jian@live.com",
6+
"dependentChangeType": "patch"
7+
}

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

Lines changed: 6 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -19,7 +19,12 @@ export interface AuthFlowActionRequiredStateParameters {
1919
/**
2020
* Base class for the state of an authentication flow.
2121
*/
22-
export abstract class AuthFlowStateBase {}
22+
export abstract class AuthFlowStateBase {
23+
/**
24+
* The type of the state.
25+
*/
26+
abstract stateType: string;
27+
}
2328

2429
/**
2530
* Base class for the action requried state in an authentication flow.
Lines changed: 60 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,60 @@
1+
/*
2+
* Copyright (c) Microsoft Corporation. All rights reserved.
3+
* Licensed under the MIT License.
4+
*/
5+
6+
// Sign in state types
7+
export const SIGN_IN_CODE_REQUIRED_STATE_TYPE = "SignInCodeRequiredState";
8+
export const SIGN_IN_PASSWORD_REQUIRED_STATE_TYPE =
9+
"SignInPasswordRequiredState";
10+
export const SIGN_IN_CONTINUATION_STATE_TYPE = "SignInContinuationState";
11+
export const SIGN_IN_COMPLETED_STATE_TYPE = "SignInCompletedState";
12+
export const SIGN_IN_FAILED_STATE_TYPE = "SignInFailedState";
13+
14+
// Sign up state types
15+
export const SIGN_UP_CODE_REQUIRED_STATE_TYPE = "SignUpCodeRequiredState";
16+
export const SIGN_UP_PASSWORD_REQUIRED_STATE_TYPE =
17+
"SignUpPasswordRequiredState";
18+
export const SIGN_UP_ATTRIBUTES_REQUIRED_STATE_TYPE =
19+
"SignUpAttributesRequiredState";
20+
export const SIGN_UP_COMPLETED_STATE_TYPE = "SignUpCompletedState";
21+
export const SIGN_UP_FAILED_STATE_TYPE = "SignUpFailedState";
22+
23+
// Reset password state types
24+
export const RESET_PASSWORD_CODE_REQUIRED_STATE_TYPE =
25+
"ResetPasswordCodeRequiredState";
26+
export const RESET_PASSWORD_PASSWORD_REQUIRED_STATE_TYPE =
27+
"ResetPasswordPasswordRequiredState";
28+
export const RESET_PASSWORD_COMPLETED_STATE_TYPE =
29+
"ResetPasswordCompletedState";
30+
export const RESET_PASSWORD_FAILED_STATE_TYPE = "ResetPasswordFailedState";
31+
32+
// Get account state types
33+
export const GET_ACCOUNT_COMPLETED_STATE_TYPE = "GetAccountCompletedState";
34+
export const GET_ACCOUNT_FAILED_STATE_TYPE = "GetAccountFailedState";
35+
36+
// Get access token state types
37+
export const GET_ACCESS_TOKEN_COMPLETED_STATE_TYPE =
38+
"GetAccessTokenCompletedState";
39+
export const GET_ACCESS_TOKEN_FAILED_STATE_TYPE = "GetAccessTokenFailedState";
40+
41+
// Sign out state types
42+
export const SIGN_OUT_COMPLETED_STATE_TYPE = "SignOutCompletedState";
43+
export const SIGN_OUT_FAILED_STATE_TYPE = "SignOutFailedState";
44+
45+
// MFA state types
46+
export const MFA_AWAITING_STATE_TYPE = "MfaAwaitingState";
47+
export const MFA_VERIFICATION_REQUIRED_STATE_TYPE =
48+
"MfaVerificationRequiredState";
49+
export const MFA_COMPLETED_STATE_TYPE = "MfaCompletedState";
50+
export const MFA_FAILED_STATE_TYPE = "MfaFailedState";
51+
52+
// Auth method registration (JIT) state types
53+
export const AUTH_METHOD_REGISTRATION_REQUIRED_STATE_TYPE =
54+
"AuthMethodRegistrationRequiredState";
55+
export const AUTH_METHOD_VERIFICATION_REQUIRED_STATE_TYPE =
56+
"AuthMethodVerificationRequiredState";
57+
export const AUTH_METHOD_REGISTRATION_COMPLETED_STATE_TYPE =
58+
"AuthMethodRegistrationCompletedState";
59+
export const AUTH_METHOD_REGISTRATION_FAILED_STATE_TYPE =
60+
"AuthMethodRegistrationFailedState";

lib/msal-browser/src/custom_auth/core/auth_flow/jit/result/AuthMethodRegistrationChallengeMethodResult.ts

Lines changed: 21 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -9,6 +9,11 @@ import type { AuthMethodVerificationRequiredState } from "../state/AuthMethodReg
99
import { CustomAuthAccountData } from "../../../../get_account/auth_flow/CustomAuthAccountData.js";
1010
import { AuthMethodRegistrationCompletedState } from "../state/AuthMethodRegistrationCompletedState.js";
1111
import { AuthMethodRegistrationFailedState } from "../state/AuthMethodRegistrationFailedState.js";
12+
import {
13+
AUTH_METHOD_VERIFICATION_REQUIRED_STATE_TYPE,
14+
AUTH_METHOD_REGISTRATION_COMPLETED_STATE_TYPE,
15+
AUTH_METHOD_REGISTRATION_FAILED_STATE_TYPE,
16+
} from "../../AuthFlowStateTypes.js";
1217

1318
/**
1419
* Result of challenging an authentication method for registration.
@@ -41,10 +46,12 @@ export class AuthMethodRegistrationChallengeMethodResult extends AuthFlowResultB
4146
* @returns true if verification is required, false otherwise.
4247
* @warning This API is experimental. It may be changed in the future without notice. Do not use in production applications.
4348
*/
44-
isVerificationRequired(): boolean {
49+
isVerificationRequired(): this is AuthMethodRegistrationChallengeMethodResult & {
50+
state: AuthMethodVerificationRequiredState;
51+
} {
4552
return (
46-
this.state.constructor?.name ===
47-
"AuthMethodVerificationRequiredState"
53+
this.state.stateType ===
54+
AUTH_METHOD_VERIFICATION_REQUIRED_STATE_TYPE
4855
);
4956
}
5057

@@ -53,10 +60,12 @@ export class AuthMethodRegistrationChallengeMethodResult extends AuthFlowResultB
5360
* @returns true if registration is completed, false otherwise.
5461
* @warning This API is experimental. It may be changed in the future without notice. Do not use in production applications.
5562
*/
56-
isCompleted(): boolean {
63+
isCompleted(): this is AuthMethodRegistrationChallengeMethodResult & {
64+
state: AuthMethodRegistrationCompletedState;
65+
} {
5766
return (
58-
this.state.constructor?.name ===
59-
"AuthMethodRegistrationCompletedState"
67+
this.state.stateType ===
68+
AUTH_METHOD_REGISTRATION_COMPLETED_STATE_TYPE
6069
);
6170
}
6271

@@ -65,8 +74,12 @@ export class AuthMethodRegistrationChallengeMethodResult extends AuthFlowResultB
6574
* @returns true if the result is failed, false otherwise.
6675
* @warning This API is experimental. It may be changed in the future without notice. Do not use in production applications.
6776
*/
68-
isFailed(): boolean {
69-
return this.state instanceof AuthMethodRegistrationFailedState;
77+
isFailed(): this is AuthMethodRegistrationChallengeMethodResult & {
78+
state: AuthMethodRegistrationFailedState;
79+
} {
80+
return (
81+
this.state.stateType === AUTH_METHOD_REGISTRATION_FAILED_STATE_TYPE
82+
);
7083
}
7184
}
7285

lib/msal-browser/src/custom_auth/core/auth_flow/jit/result/AuthMethodRegistrationSubmitChallengeResult.ts

Lines changed: 15 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,10 @@ import { AuthMethodRegistrationSubmitChallengeError } from "../error_type/AuthMe
88
import { CustomAuthAccountData } from "../../../../get_account/auth_flow/CustomAuthAccountData.js";
99
import { AuthMethodRegistrationFailedState } from "../state/AuthMethodRegistrationFailedState.js";
1010
import { AuthMethodRegistrationCompletedState } from "../state/AuthMethodRegistrationCompletedState.js";
11+
import {
12+
AUTH_METHOD_REGISTRATION_COMPLETED_STATE_TYPE,
13+
AUTH_METHOD_REGISTRATION_FAILED_STATE_TYPE,
14+
} from "../../AuthFlowStateTypes.js";
1115

1216
/**
1317
* Result of submitting a challenge for authentication method registration.
@@ -39,10 +43,12 @@ export class AuthMethodRegistrationSubmitChallengeResult extends AuthFlowResultB
3943
* @returns true if registration is completed, false otherwise.
4044
* @warning This API is experimental. It may be changed in the future without notice. Do not use in production applications.
4145
*/
42-
isCompleted(): boolean {
46+
isCompleted(): this is AuthMethodRegistrationSubmitChallengeResult & {
47+
state: AuthMethodRegistrationCompletedState;
48+
} {
4349
return (
44-
this.state.constructor?.name ===
45-
"AuthMethodRegistrationCompletedState"
50+
this.state.stateType ===
51+
AUTH_METHOD_REGISTRATION_COMPLETED_STATE_TYPE
4652
);
4753
}
4854

@@ -51,8 +57,12 @@ export class AuthMethodRegistrationSubmitChallengeResult extends AuthFlowResultB
5157
* @returns true if the result is failed, false otherwise.
5258
* @warning This API is experimental. It may be changed in the future without notice. Do not use in production applications.
5359
*/
54-
isFailed(): boolean {
55-
return this.state instanceof AuthMethodRegistrationFailedState;
60+
isFailed(): this is AuthMethodRegistrationSubmitChallengeResult & {
61+
state: AuthMethodRegistrationFailedState;
62+
} {
63+
return (
64+
this.state.stateType === AUTH_METHOD_REGISTRATION_FAILED_STATE_TYPE
65+
);
5666
}
5767
}
5868

lib/msal-browser/src/custom_auth/core/auth_flow/jit/state/AuthMethodRegistrationCompletedState.ts

Lines changed: 10 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -4,5 +4,14 @@
44
*/
55

66
import { AuthFlowStateBase } from "../../AuthFlowState.js";
7+
import { AUTH_METHOD_REGISTRATION_COMPLETED_STATE_TYPE } from "../../AuthFlowStateTypes.js";
78

8-
export class AuthMethodRegistrationCompletedState extends AuthFlowStateBase {}
9+
/**
10+
* State indicating that the auth method registration flow has completed successfully.
11+
*/
12+
export class AuthMethodRegistrationCompletedState extends AuthFlowStateBase {
13+
/**
14+
* The type of the state.
15+
*/
16+
stateType = AUTH_METHOD_REGISTRATION_COMPLETED_STATE_TYPE;
17+
}

lib/msal-browser/src/custom_auth/core/auth_flow/jit/state/AuthMethodRegistrationFailedState.ts

Lines changed: 10 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -4,5 +4,14 @@
44
*/
55

66
import { AuthFlowStateBase } from "../../AuthFlowState.js";
7+
import { AUTH_METHOD_REGISTRATION_FAILED_STATE_TYPE } from "../../AuthFlowStateTypes.js";
78

8-
export class AuthMethodRegistrationFailedState extends AuthFlowStateBase {}
9+
/**
10+
* State indicating that the auth method registration flow has failed.
11+
*/
12+
export class AuthMethodRegistrationFailedState extends AuthFlowStateBase {
13+
/**
14+
* The type of the state.
15+
*/
16+
stateType = AUTH_METHOD_REGISTRATION_FAILED_STATE_TYPE;
17+
}

lib/msal-browser/src/custom_auth/core/auth_flow/jit/state/AuthMethodRegistrationState.ts

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -25,6 +25,10 @@ import { GrantType } from "../../../../CustomAuthConstants.js";
2525
import { AuthMethodRegistrationChallengeMethodResult } from "../result/AuthMethodRegistrationChallengeMethodResult.js";
2626
import { AuthMethodRegistrationSubmitChallengeResult } from "../result/AuthMethodRegistrationSubmitChallengeResult.js";
2727
import { AuthMethodRegistrationCompletedState } from "./AuthMethodRegistrationCompletedState.js";
28+
import {
29+
AUTH_METHOD_REGISTRATION_REQUIRED_STATE_TYPE,
30+
AUTH_METHOD_VERIFICATION_REQUIRED_STATE_TYPE,
31+
} from "../../AuthFlowStateTypes.js";
2832

2933
/**
3034
* Abstract base class for authentication method registration states.
@@ -134,6 +138,11 @@ abstract class AuthMethodRegistrationState<
134138
* State indicating that authentication method registration is required.
135139
*/
136140
export class AuthMethodRegistrationRequiredState extends AuthMethodRegistrationState<AuthMethodRegistrationRequiredStateParameters> {
141+
/**
142+
* The type of the state.
143+
*/
144+
stateType = AUTH_METHOD_REGISTRATION_REQUIRED_STATE_TYPE;
145+
137146
/**
138147
* Gets the available authentication methods for registration.
139148
* @returns Array of available authentication methods.
@@ -160,6 +169,11 @@ export class AuthMethodRegistrationRequiredState extends AuthMethodRegistrationS
160169
* State indicating that verification is required for the challenged authentication method.
161170
*/
162171
export class AuthMethodVerificationRequiredState extends AuthMethodRegistrationState<AuthMethodVerificationRequiredStateParameters> {
172+
/**
173+
* The type of the state.
174+
*/
175+
stateType = AUTH_METHOD_VERIFICATION_REQUIRED_STATE_TYPE;
176+
163177
/**
164178
* Gets the length of the expected verification code.
165179
* @returns The code length.

lib/msal-browser/src/custom_auth/core/auth_flow/mfa/result/MfaRequestChallengeResult.ts

Lines changed: 12 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,10 @@ import { AuthFlowResultBase } from "../../AuthFlowResultBase.js";
77
import { MfaRequestChallengeError } from "../error_type/MfaError.js";
88
import { MfaFailedState } from "../state/MfaFailedState.js";
99
import type { MfaVerificationRequiredState } from "../state/MfaState.js";
10+
import {
11+
MFA_VERIFICATION_REQUIRED_STATE_TYPE,
12+
MFA_FAILED_STATE_TYPE,
13+
} from "../../AuthFlowStateTypes.js";
1014

1115
/**
1216
* Result of requesting an MFA challenge.
@@ -34,17 +38,21 @@ export class MfaRequestChallengeResult extends AuthFlowResultBase<
3438
* @returns true if verification is required, false otherwise.
3539
* @warning This API is experimental. It may be changed in the future without notice. Do not use in production applications.
3640
*/
37-
isVerificationRequired(): boolean {
38-
return this.state.constructor?.name === "MfaVerificationRequiredState";
41+
isVerificationRequired(): this is MfaRequestChallengeResult & {
42+
state: MfaVerificationRequiredState;
43+
} {
44+
return this.state.stateType === MFA_VERIFICATION_REQUIRED_STATE_TYPE;
3945
}
4046

4147
/**
4248
* Checks if the result is in a failed state.
4349
* @returns true if the result is failed, false otherwise.
4450
* @warning This API is experimental. It may be changed in the future without notice. Do not use in production applications.
4551
*/
46-
isFailed(): boolean {
47-
return this.state instanceof MfaFailedState;
52+
isFailed(): this is MfaRequestChallengeResult & {
53+
state: MfaFailedState;
54+
} {
55+
return this.state.stateType === MFA_FAILED_STATE_TYPE;
4856
}
4957
}
5058

lib/msal-browser/src/custom_auth/core/auth_flow/mfa/result/MfaSubmitChallengeResult.ts

Lines changed: 12 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,10 @@ import { MfaSubmitChallengeError } from "../error_type/MfaError.js";
88
import { CustomAuthAccountData } from "../../../../get_account/auth_flow/CustomAuthAccountData.js";
99
import { MfaCompletedState } from "../state/MfaCompletedState.js";
1010
import { MfaFailedState } from "../state/MfaFailedState.js";
11+
import {
12+
MFA_COMPLETED_STATE_TYPE,
13+
MFA_FAILED_STATE_TYPE,
14+
} from "../../AuthFlowStateTypes.js";
1115

1216
/**
1317
* Result of submitting an MFA challenge.
@@ -35,17 +39,21 @@ export class MfaSubmitChallengeResult extends AuthFlowResultBase<
3539
* @returns true if completed, false otherwise.
3640
* @warning This API is experimental. It may be changed in the future without notice. Do not use in production applications.
3741
*/
38-
isCompleted(): boolean {
39-
return this.state instanceof MfaCompletedState;
42+
isCompleted(): this is MfaSubmitChallengeResult & {
43+
state: MfaCompletedState;
44+
} {
45+
return this.state.stateType === MFA_COMPLETED_STATE_TYPE;
4046
}
4147

4248
/**
4349
* Checks if the result is in a failed state.
4450
* @returns true if the result is failed, false otherwise.
4551
* @warning This API is experimental. It may be changed in the future without notice. Do not use in production applications.
4652
*/
47-
isFailed(): boolean {
48-
return this.state instanceof MfaFailedState;
53+
isFailed(): this is MfaSubmitChallengeResult & {
54+
state: MfaFailedState;
55+
} {
56+
return this.state.stateType === MFA_FAILED_STATE_TYPE;
4957
}
5058
}
5159

0 commit comments

Comments
 (0)