@auth0/auth0-spa-js 2.11.3 → 2.13.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +4 -2
- package/dist/auth0-spa-js.development.js +6040 -920
- package/dist/auth0-spa-js.development.js.map +1 -1
- package/dist/auth0-spa-js.production.esm.js +1 -1
- package/dist/auth0-spa-js.production.esm.js.map +1 -1
- package/dist/auth0-spa-js.production.js +1 -1
- package/dist/auth0-spa-js.production.js.map +1 -1
- package/dist/auth0-spa-js.worker.development.js +13 -8
- package/dist/auth0-spa-js.worker.development.js.map +1 -1
- package/dist/auth0-spa-js.worker.production.js +1 -1
- package/dist/auth0-spa-js.worker.production.js.map +1 -1
- package/dist/lib/auth0-spa-js.cjs.js +6450 -913
- package/dist/lib/auth0-spa-js.cjs.js.map +1 -1
- package/dist/typings/Auth0Client.d.ts +51 -1
- package/dist/typings/errors.d.ts +15 -1
- package/dist/typings/global.d.ts +17 -2
- package/dist/typings/index.d.ts +3 -0
- package/dist/typings/mfa/MfaApiClient.d.ts +225 -0
- package/dist/typings/mfa/MfaContextManager.d.ts +79 -0
- package/dist/typings/mfa/constants.d.ts +23 -0
- package/dist/typings/mfa/errors.d.ts +117 -0
- package/dist/typings/mfa/index.d.ts +4 -0
- package/dist/typings/mfa/types.d.ts +181 -0
- package/dist/typings/mfa/utils.d.ts +23 -0
- package/dist/typings/utils.d.ts +2 -1
- package/dist/typings/version.d.ts +1 -1
- package/package.json +8 -4
- package/src/Auth0Client.ts +88 -5
- package/src/dpop/utils.ts +4 -1
- package/src/errors.ts +12 -1
- package/src/global.ts +41 -1
- package/src/http.ts +1 -1
- package/src/index.ts +22 -0
- package/src/mfa/MfaApiClient.ts +425 -0
- package/src/mfa/MfaContextManager.ts +128 -0
- package/src/mfa/constants.ts +48 -0
- package/src/mfa/errors.ts +154 -0
- package/src/mfa/index.ts +24 -0
- package/src/mfa/types.ts +209 -0
- package/src/mfa/utils.ts +41 -0
- package/src/utils.ts +7 -1
- package/src/version.ts +1 -1
|
@@ -1,7 +1,8 @@
|
|
|
1
|
-
import { Auth0ClientOptions, RedirectLoginOptions, PopupLoginOptions, PopupConfigOptions, RedirectLoginResult, GetTokenSilentlyOptions, GetTokenWithPopupOptions, LogoutOptions, User, IdToken, GetTokenSilentlyVerboseResponse, TokenEndpointResponse, ConnectAccountRedirectResult, RedirectConnectAccountOptions } from './global';
|
|
1
|
+
import { Auth0ClientOptions, RedirectLoginOptions, PopupLoginOptions, PopupConfigOptions, RedirectLoginResult, GetTokenSilentlyOptions, GetTokenWithPopupOptions, LogoutOptions, User, IdToken, GetTokenSilentlyVerboseResponse, TokenEndpointResponse, ConnectAccountRedirectResult, RedirectConnectAccountOptions, ClientConfiguration } from './global';
|
|
2
2
|
import { CustomTokenExchangeOptions } from './TokenExchange';
|
|
3
3
|
import { Dpop } from './dpop/dpop';
|
|
4
4
|
import { Fetcher, type FetcherConfig, type CustomFetchMinimalOutput } from './fetcher';
|
|
5
|
+
import { MfaApiClient } from './mfa';
|
|
5
6
|
/**
|
|
6
7
|
* Auth0 SDK for Single Page Applications using [Authorization Code Grant Flow with PKCE](https://auth0.com/docs/api-auth/tutorials/authorization-code-grant-pkce).
|
|
7
8
|
*/
|
|
@@ -21,10 +22,38 @@ export declare class Auth0Client {
|
|
|
21
22
|
private readonly options;
|
|
22
23
|
private readonly userCache;
|
|
23
24
|
private readonly myAccountApi;
|
|
25
|
+
/**
|
|
26
|
+
* MFA API client for multi-factor authentication operations.
|
|
27
|
+
*
|
|
28
|
+
* Provides methods for:
|
|
29
|
+
* - Listing enrolled authenticators
|
|
30
|
+
* - Enrolling new authenticators (OTP, SMS, Voice, Push, Email)
|
|
31
|
+
* - Initiating MFA challenges
|
|
32
|
+
* - Verifying MFA challenges
|
|
33
|
+
*/
|
|
34
|
+
readonly mfa: MfaApiClient;
|
|
24
35
|
private worker?;
|
|
25
36
|
private readonly activeLockKeys;
|
|
37
|
+
private readonly authJsClient;
|
|
26
38
|
private readonly defaultOptions;
|
|
27
39
|
constructor(options: Auth0ClientOptions);
|
|
40
|
+
/**
|
|
41
|
+
* Returns a readonly copy of the initialization configuration.
|
|
42
|
+
*
|
|
43
|
+
* @returns An object containing domain and clientId
|
|
44
|
+
*
|
|
45
|
+
* @example
|
|
46
|
+
* ```typescript
|
|
47
|
+
* const auth0 = new Auth0Client({
|
|
48
|
+
* domain: 'tenant.auth0.com',
|
|
49
|
+
* clientId: 'abc123'
|
|
50
|
+
* });
|
|
51
|
+
*
|
|
52
|
+
* const config = auth0.getConfiguration();
|
|
53
|
+
* // { domain: 'tenant.auth0.com', clientId: 'abc123' }
|
|
54
|
+
* ```
|
|
55
|
+
*/
|
|
56
|
+
getConfiguration(): Readonly<ClientConfiguration>;
|
|
28
57
|
private _url;
|
|
29
58
|
private _authorizeUrl;
|
|
30
59
|
private _verifyIdToken;
|
|
@@ -324,4 +353,25 @@ export declare class Auth0Client {
|
|
|
324
353
|
* @throws {MyAccountApiError} If the connect request to the My Account API fails.
|
|
325
354
|
*/
|
|
326
355
|
connectAccountWithRedirect<TAppState = any>(options: RedirectConnectAccountOptions<TAppState>): Promise<void>;
|
|
356
|
+
/**
|
|
357
|
+
* @internal
|
|
358
|
+
* Internal method used by MfaApiClient to exchange MFA tokens for access tokens.
|
|
359
|
+
* This method should not be called directly by applications.
|
|
360
|
+
*/
|
|
361
|
+
_requestTokenForMfa(options: {
|
|
362
|
+
grant_type: string;
|
|
363
|
+
mfaToken: string;
|
|
364
|
+
scope?: string;
|
|
365
|
+
audience?: string;
|
|
366
|
+
otp?: string;
|
|
367
|
+
binding_code?: string;
|
|
368
|
+
oob_code?: string;
|
|
369
|
+
recovery_code?: string;
|
|
370
|
+
}, additionalParameters?: RequestTokenAdditionalParameters): Promise<TokenEndpointResponse>;
|
|
371
|
+
}
|
|
372
|
+
interface RequestTokenAdditionalParameters {
|
|
373
|
+
nonceIn?: string;
|
|
374
|
+
organization?: string;
|
|
375
|
+
scopesToRequest?: string;
|
|
327
376
|
}
|
|
377
|
+
export {};
|
package/dist/typings/errors.d.ts
CHANGED
|
@@ -1,3 +1,16 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* MFA requirements from an mfa_required error response
|
|
3
|
+
*/
|
|
4
|
+
export interface MfaRequirements {
|
|
5
|
+
/** Required enrollment types */
|
|
6
|
+
enroll?: Array<{
|
|
7
|
+
type: string;
|
|
8
|
+
}>;
|
|
9
|
+
/** Required challenge types */
|
|
10
|
+
challenge?: Array<{
|
|
11
|
+
type: string;
|
|
12
|
+
}>;
|
|
13
|
+
}
|
|
1
14
|
/**
|
|
2
15
|
* Thrown when network requests to the Auth server fail.
|
|
3
16
|
*/
|
|
@@ -55,7 +68,8 @@ export declare class PopupOpenError extends GenericError {
|
|
|
55
68
|
*/
|
|
56
69
|
export declare class MfaRequiredError extends GenericError {
|
|
57
70
|
mfa_token: string;
|
|
58
|
-
|
|
71
|
+
mfa_requirements: MfaRequirements;
|
|
72
|
+
constructor(error: string, error_description: string, mfa_token: string, mfa_requirements: MfaRequirements);
|
|
59
73
|
}
|
|
60
74
|
/**
|
|
61
75
|
* Error thrown when there is no refresh token to use
|
package/dist/typings/global.d.ts
CHANGED
|
@@ -265,9 +265,24 @@ export interface Auth0ClientOptions {
|
|
|
265
265
|
/**
|
|
266
266
|
* URL parameters that will be sent back to the Authorization Server. This can be known parameters
|
|
267
267
|
* defined by Auth0 or custom parameters that you define.
|
|
268
|
-
|
|
268
|
+
*/
|
|
269
269
|
authorizationParams?: ClientAuthorizationParams;
|
|
270
270
|
}
|
|
271
|
+
/**
|
|
272
|
+
* Configuration details exposed by the Auth0Client after initialization.
|
|
273
|
+
*
|
|
274
|
+
* @category Main
|
|
275
|
+
*/
|
|
276
|
+
export interface ClientConfiguration {
|
|
277
|
+
/**
|
|
278
|
+
* The Auth0 domain that was configured
|
|
279
|
+
*/
|
|
280
|
+
domain: string;
|
|
281
|
+
/**
|
|
282
|
+
* The Auth0 client ID that was configured
|
|
283
|
+
*/
|
|
284
|
+
clientId: string;
|
|
285
|
+
}
|
|
271
286
|
/**
|
|
272
287
|
* The possible locations where tokens can be stored
|
|
273
288
|
*/
|
|
@@ -738,4 +753,4 @@ export type FetchResponse = {
|
|
|
738
753
|
json: any;
|
|
739
754
|
};
|
|
740
755
|
export type GetTokenSilentlyVerboseResponse = Omit<TokenEndpointResponse, 'refresh_token'>;
|
|
741
|
-
export {};
|
|
756
|
+
export type { Authenticator, AuthenticatorType, OobChannel, MfaFactorType, EnrollParams, EnrollOtpParams, EnrollSmsParams, EnrollVoiceParams, EnrollEmailParams, EnrollPushParams, EnrollmentResponse, OtpEnrollmentResponse, OobEnrollmentResponse, ChallengeAuthenticatorParams, ChallengeResponse, VerifyParams, MfaGrantType, EnrollmentFactor } from './mfa/types';
|
package/dist/typings/index.d.ts
CHANGED
|
@@ -14,6 +14,9 @@ export * from './global';
|
|
|
14
14
|
export declare function createAuth0Client(options: Auth0ClientOptions): Promise<Auth0Client>;
|
|
15
15
|
export { Auth0Client };
|
|
16
16
|
export { ConnectError, GenericError, AuthenticationError, TimeoutError, PopupTimeoutError, PopupCancelledError, PopupOpenError, MfaRequiredError, MissingRefreshTokenError, UseDpopNonceError } from './errors';
|
|
17
|
+
export { MfaError, MfaListAuthenticatorsError, MfaEnrollmentError, MfaChallengeError, MfaVerifyError, MfaEnrollmentFactorsError } from './mfa/errors';
|
|
18
|
+
export { MfaApiClient } from './mfa';
|
|
19
|
+
export type { MfaFactorType, EnrollParams, EnrollOtpParams, EnrollSmsParams, EnrollVoiceParams, EnrollEmailParams, EnrollPushParams, VerifyParams } from './mfa';
|
|
17
20
|
export { ICache, LocalStorageCache, InMemoryCache, Cacheable, DecodedToken, CacheEntry, WrappedCacheEntry, KeyManifestEntry, MaybePromise, CacheKey, CacheKeyData } from './cache';
|
|
18
21
|
export type { FetcherConfig, Fetcher, CustomFetchMinimalOutput } from './fetcher';
|
|
19
22
|
export { MyAccountApiError } from './MyAccountApiClient';
|
|
@@ -0,0 +1,225 @@
|
|
|
1
|
+
import { Auth0Client } from '../Auth0Client';
|
|
2
|
+
import type { TokenEndpointResponse } from '../global';
|
|
3
|
+
import type { Authenticator, EnrollParams, EnrollmentResponse, ChallengeAuthenticatorParams, ChallengeResponse, VerifyParams, EnrollmentFactor } from './types';
|
|
4
|
+
import { MfaClient as Auth0AuthJsMfaClient } from '@auth0/auth0-auth-js';
|
|
5
|
+
import { MfaRequirements } from '../errors';
|
|
6
|
+
/**
|
|
7
|
+
* Client for Auth0 MFA API operations
|
|
8
|
+
*
|
|
9
|
+
* Manages multi-factor authentication including:
|
|
10
|
+
* - Listing enrolled authenticators
|
|
11
|
+
* - Enrolling new authenticators (OTP, SMS, Voice, Push, Email)
|
|
12
|
+
* - Initiating MFA challenges
|
|
13
|
+
* - Verifying MFA challenges
|
|
14
|
+
*
|
|
15
|
+
* This is a wrapper around auth0-auth-js MfaClient that maintains
|
|
16
|
+
* backward compatibility with the existing spa-js API.
|
|
17
|
+
*
|
|
18
|
+
* MFA context (scope, audience) is stored internally keyed by mfaToken,
|
|
19
|
+
* enabling concurrent MFA flows without state conflicts.
|
|
20
|
+
*
|
|
21
|
+
* @example
|
|
22
|
+
* ```typescript
|
|
23
|
+
* try {
|
|
24
|
+
* await auth0.getTokenSilently({ authorizationParams: { audience: 'https://api.example.com' } });
|
|
25
|
+
* } catch (e) {
|
|
26
|
+
* if (e instanceof MfaRequiredError) {
|
|
27
|
+
* // SDK automatically stores context for this mfaToken
|
|
28
|
+
* const authenticators = await auth0.mfa.getAuthenticators({ mfaToken: e.mfa_token });
|
|
29
|
+
* // ... complete MFA flow
|
|
30
|
+
* }
|
|
31
|
+
* }
|
|
32
|
+
* ```
|
|
33
|
+
*/
|
|
34
|
+
export declare class MfaApiClient {
|
|
35
|
+
private authJsMfaClient;
|
|
36
|
+
private auth0Client;
|
|
37
|
+
private contextManager;
|
|
38
|
+
/**
|
|
39
|
+
* @internal
|
|
40
|
+
* Do not instantiate directly. Use Auth0Client.mfa instead.
|
|
41
|
+
*/
|
|
42
|
+
constructor(authJsMfaClient: Auth0AuthJsMfaClient, auth0Client: Auth0Client);
|
|
43
|
+
/**
|
|
44
|
+
* @internal
|
|
45
|
+
* Stores authentication details (scope, audience, and MFA requirements) for MFA token verification.
|
|
46
|
+
* This is automatically called by Auth0Client when an mfa_required error occurs.
|
|
47
|
+
*
|
|
48
|
+
* The context is stored keyed by the MFA token, enabling concurrent MFA flows.
|
|
49
|
+
*
|
|
50
|
+
* @param mfaToken - The MFA token from the mfa_required error response
|
|
51
|
+
* @param scope - The OAuth scope from the original request (optional)
|
|
52
|
+
* @param audience - The API audience from the original request (optional)
|
|
53
|
+
* @param mfaRequirements - The MFA requirements from the mfa_required error (optional)
|
|
54
|
+
*/
|
|
55
|
+
setMFAAuthDetails(mfaToken: string, scope?: string, audience?: string, mfaRequirements?: MfaRequirements): void;
|
|
56
|
+
/**
|
|
57
|
+
* Gets enrolled MFA authenticators filtered by challenge types from context.
|
|
58
|
+
*
|
|
59
|
+
* Challenge types are automatically resolved from the stored MFA context
|
|
60
|
+
* (set when mfa_required error occurred).
|
|
61
|
+
*
|
|
62
|
+
* @param mfaToken - MFA token from mfa_required error
|
|
63
|
+
* @returns Array of enrolled authenticators matching the challenge types
|
|
64
|
+
* @throws {MfaListAuthenticatorsError} If the request fails or context not found
|
|
65
|
+
*
|
|
66
|
+
* @example Basic usage
|
|
67
|
+
* ```typescript
|
|
68
|
+
* try {
|
|
69
|
+
* await auth0.getTokenSilently();
|
|
70
|
+
* } catch (e) {
|
|
71
|
+
* if (e instanceof MfaRequiredError) {
|
|
72
|
+
* // SDK automatically uses challenge types from error context
|
|
73
|
+
* const authenticators = await auth0.mfa.getAuthenticators(e.mfa_token);
|
|
74
|
+
* }
|
|
75
|
+
* }
|
|
76
|
+
* ```
|
|
77
|
+
*/
|
|
78
|
+
getAuthenticators(mfaToken: string): Promise<Authenticator[]>;
|
|
79
|
+
/**
|
|
80
|
+
* Enrolls a new MFA authenticator
|
|
81
|
+
*
|
|
82
|
+
* Requires MFA access token with 'enroll' scope
|
|
83
|
+
*
|
|
84
|
+
* @param params - Enrollment parameters including mfaToken and factorType
|
|
85
|
+
* @returns Enrollment response with authenticator details
|
|
86
|
+
* @throws {MfaEnrollmentError} If enrollment fails
|
|
87
|
+
*
|
|
88
|
+
* @example OTP enrollment
|
|
89
|
+
* ```typescript
|
|
90
|
+
* const enrollment = await mfa.enroll({
|
|
91
|
+
* mfaToken: mfaToken,
|
|
92
|
+
* factorType: 'otp'
|
|
93
|
+
* });
|
|
94
|
+
* console.log(enrollment.secret); // Base32 secret
|
|
95
|
+
* console.log(enrollment.barcodeUri); // QR code URI
|
|
96
|
+
* ```
|
|
97
|
+
*
|
|
98
|
+
* @example SMS enrollment
|
|
99
|
+
* ```typescript
|
|
100
|
+
* const enrollment = await mfa.enroll({
|
|
101
|
+
* mfaToken: mfaToken,
|
|
102
|
+
* factorType: 'sms',
|
|
103
|
+
* phoneNumber: '+12025551234'
|
|
104
|
+
* });
|
|
105
|
+
* ```
|
|
106
|
+
*/
|
|
107
|
+
enroll(params: EnrollParams): Promise<EnrollmentResponse>;
|
|
108
|
+
/**
|
|
109
|
+
* Initiates an MFA challenge
|
|
110
|
+
*
|
|
111
|
+
* Sends OTP via SMS, initiates push notification, or prepares for OTP entry
|
|
112
|
+
*
|
|
113
|
+
* @param params - Challenge parameters including mfaToken
|
|
114
|
+
* @returns Challenge response with oobCode if applicable
|
|
115
|
+
* @throws {MfaChallengeError} If challenge initiation fails
|
|
116
|
+
*
|
|
117
|
+
* @example OTP challenge
|
|
118
|
+
* ```typescript
|
|
119
|
+
* const challenge = await mfa.challenge({
|
|
120
|
+
* mfaToken: mfaTokenFromLogin,
|
|
121
|
+
* challengeType: 'otp',
|
|
122
|
+
* authenticatorId: 'otp|dev_xxx'
|
|
123
|
+
* });
|
|
124
|
+
* // User enters OTP from their authenticator app
|
|
125
|
+
* ```
|
|
126
|
+
*
|
|
127
|
+
* @example SMS challenge
|
|
128
|
+
* ```typescript
|
|
129
|
+
* const challenge = await mfa.challenge({
|
|
130
|
+
* mfaToken: mfaTokenFromLogin,
|
|
131
|
+
* challengeType: 'oob',
|
|
132
|
+
* authenticatorId: 'sms|dev_xxx'
|
|
133
|
+
* });
|
|
134
|
+
* console.log(challenge.oobCode); // Use for verification
|
|
135
|
+
* ```
|
|
136
|
+
*/
|
|
137
|
+
challenge(params: ChallengeAuthenticatorParams): Promise<ChallengeResponse>;
|
|
138
|
+
/**
|
|
139
|
+
* Gets available MFA enrollment factors from the stored context.
|
|
140
|
+
*
|
|
141
|
+
* This method exposes the enrollment options from the mfa_required error's
|
|
142
|
+
* mfaRequirements.enroll array, eliminating the need for manual parsing.
|
|
143
|
+
*
|
|
144
|
+
* @param mfaToken - MFA token from mfa_required error
|
|
145
|
+
* @returns Array of enrollment factors available for the user (empty array if no enrollment required)
|
|
146
|
+
* @throws {MfaEnrollmentFactorsError} If MFA context not found
|
|
147
|
+
*
|
|
148
|
+
* @example Basic usage
|
|
149
|
+
* ```typescript
|
|
150
|
+
* try {
|
|
151
|
+
* await auth0.getTokenSilently();
|
|
152
|
+
* } catch (error) {
|
|
153
|
+
* if (error.error === 'mfa_required') {
|
|
154
|
+
* // Get enrollment options from SDK
|
|
155
|
+
* const enrollOptions = await auth0.mfa.getEnrollmentFactors(error.mfa_token);
|
|
156
|
+
* // [{ type: 'otp' }, { type: 'phone' }, { type: 'push-notification' }]
|
|
157
|
+
*
|
|
158
|
+
* showEnrollmentOptions(enrollOptions);
|
|
159
|
+
* }
|
|
160
|
+
* }
|
|
161
|
+
* ```
|
|
162
|
+
*
|
|
163
|
+
* @example Check if enrollment is required
|
|
164
|
+
* ```typescript
|
|
165
|
+
* try {
|
|
166
|
+
* const factors = await auth0.mfa.getEnrollmentFactors(mfaToken);
|
|
167
|
+
* if (factors.length > 0) {
|
|
168
|
+
* // User needs to enroll in MFA
|
|
169
|
+
* renderEnrollmentUI(factors);
|
|
170
|
+
* } else {
|
|
171
|
+
* // No enrollment required, proceed with challenge
|
|
172
|
+
* }
|
|
173
|
+
* } catch (error) {
|
|
174
|
+
* if (error instanceof MfaEnrollmentFactorsError) {
|
|
175
|
+
* console.error('Context not found:', error.error_description);
|
|
176
|
+
* }
|
|
177
|
+
* }
|
|
178
|
+
* ```
|
|
179
|
+
*/
|
|
180
|
+
getEnrollmentFactors(mfaToken: string): Promise<EnrollmentFactor[]>;
|
|
181
|
+
/**
|
|
182
|
+
* Verifies an MFA challenge and completes authentication
|
|
183
|
+
*
|
|
184
|
+
* The scope and audience are retrieved from the stored context (set when the
|
|
185
|
+
* mfa_required error occurred). The grant_type is automatically inferred from
|
|
186
|
+
* which verification field is provided (otp, oobCode, or recoveryCode).
|
|
187
|
+
*
|
|
188
|
+
* @param params - Verification parameters with OTP, OOB code, or recovery code
|
|
189
|
+
* @returns Token response with access_token, id_token, refresh_token
|
|
190
|
+
* @throws {MfaVerifyError} If verification fails (invalid code, expired, rate limited)
|
|
191
|
+
* @throws {MfaVerifyError} If MFA context not found
|
|
192
|
+
* @throws {MfaVerifyError} If grant_type cannot be inferred
|
|
193
|
+
*
|
|
194
|
+
* Rate limits:
|
|
195
|
+
* - 10 verification attempts allowed
|
|
196
|
+
* - Refreshes at 1 attempt per 6 minutes
|
|
197
|
+
*
|
|
198
|
+
* @example OTP verification (grant_type inferred from otp field)
|
|
199
|
+
* ```typescript
|
|
200
|
+
* const tokens = await mfa.verify({
|
|
201
|
+
* mfaToken: mfaTokenFromLogin,
|
|
202
|
+
* otp: '123456'
|
|
203
|
+
* });
|
|
204
|
+
* console.log(tokens.access_token);
|
|
205
|
+
* ```
|
|
206
|
+
*
|
|
207
|
+
* @example OOB verification (grant_type inferred from oobCode field)
|
|
208
|
+
* ```typescript
|
|
209
|
+
* const tokens = await mfa.verify({
|
|
210
|
+
* mfaToken: mfaTokenFromLogin,
|
|
211
|
+
* oobCode: challenge.oobCode,
|
|
212
|
+
* bindingCode: '123456' // Code user received via SMS
|
|
213
|
+
* });
|
|
214
|
+
* ```
|
|
215
|
+
*
|
|
216
|
+
* @example Recovery code verification (grant_type inferred from recoveryCode field)
|
|
217
|
+
* ```typescript
|
|
218
|
+
* const tokens = await mfa.verify({
|
|
219
|
+
* mfaToken: mfaTokenFromLogin,
|
|
220
|
+
* recoveryCode: 'XXXX-XXXX-XXXX'
|
|
221
|
+
* });
|
|
222
|
+
* ```
|
|
223
|
+
*/
|
|
224
|
+
verify(params: VerifyParams): Promise<TokenEndpointResponse>;
|
|
225
|
+
}
|
|
@@ -0,0 +1,79 @@
|
|
|
1
|
+
import { MfaRequirements } from '../errors';
|
|
2
|
+
/**
|
|
3
|
+
* Represents the stored context for an MFA flow
|
|
4
|
+
*/
|
|
5
|
+
export interface MfaContext {
|
|
6
|
+
/** The OAuth scope for the original token request */
|
|
7
|
+
scope?: string;
|
|
8
|
+
/** The API audience for the original token request */
|
|
9
|
+
audience?: string;
|
|
10
|
+
/** MFA requirements from the mfa_required error (camelCase for TypeScript conventions) */
|
|
11
|
+
mfaRequirements?: MfaRequirements;
|
|
12
|
+
/** Timestamp when the context was created */
|
|
13
|
+
createdAt: number;
|
|
14
|
+
}
|
|
15
|
+
/**
|
|
16
|
+
* Manages MFA authentication contexts keyed by MFA token.
|
|
17
|
+
*
|
|
18
|
+
* When an mfa_required error occurs, the SDK stores the original request's
|
|
19
|
+
* scope and audience. When the user later provides an MFA token for verification,
|
|
20
|
+
* the SDK retrieves the matching context to complete the token exchange.
|
|
21
|
+
*
|
|
22
|
+
* This enables concurrent MFA flows without state conflicts.
|
|
23
|
+
*
|
|
24
|
+
* @example
|
|
25
|
+
* ```typescript
|
|
26
|
+
* const manager = new MfaContextManager();
|
|
27
|
+
*
|
|
28
|
+
* // Store context when mfa_required error occurs
|
|
29
|
+
* manager.set('mfaTokenAbc', { scope: 'openid profile', audience: 'https://api.example.com' });
|
|
30
|
+
*
|
|
31
|
+
* // Retrieve context when user completes MFA
|
|
32
|
+
* const context = manager.get('mfaTokenAbc');
|
|
33
|
+
* // { scope: 'openid profile', audience: 'https://api.example.com', createdAt: ... }
|
|
34
|
+
*
|
|
35
|
+
* // Remove after successful verification
|
|
36
|
+
* manager.remove('mfaTokenAbc');
|
|
37
|
+
* ```
|
|
38
|
+
*/
|
|
39
|
+
export declare class MfaContextManager {
|
|
40
|
+
private contexts;
|
|
41
|
+
private readonly ttlMs;
|
|
42
|
+
/**
|
|
43
|
+
* Creates a new MfaContextManager
|
|
44
|
+
* @param ttlMs - Time-to-live for contexts in milliseconds (default: 10 minutes)
|
|
45
|
+
*/
|
|
46
|
+
constructor(ttlMs?: number);
|
|
47
|
+
/**
|
|
48
|
+
* Stores an MFA context keyed by the MFA token.
|
|
49
|
+
* Runs cleanup to remove expired entries before storing.
|
|
50
|
+
*
|
|
51
|
+
* @param mfaToken - The MFA token from the mfa_required error
|
|
52
|
+
* @param context - The scope and audience from the original request
|
|
53
|
+
*/
|
|
54
|
+
set(mfaToken: string, context: Omit<MfaContext, 'createdAt'>): void;
|
|
55
|
+
/**
|
|
56
|
+
* Retrieves the MFA context for a given token.
|
|
57
|
+
* Returns undefined if the token is not found or has expired.
|
|
58
|
+
*
|
|
59
|
+
* @param mfaToken - The MFA token to look up
|
|
60
|
+
* @returns The stored context, or undefined if not found/expired
|
|
61
|
+
*/
|
|
62
|
+
get(mfaToken: string): MfaContext | undefined;
|
|
63
|
+
/**
|
|
64
|
+
* Removes an MFA context.
|
|
65
|
+
* Should be called after successful MFA verification.
|
|
66
|
+
*
|
|
67
|
+
* @param mfaToken - The MFA token to remove
|
|
68
|
+
*/
|
|
69
|
+
remove(mfaToken: string): void;
|
|
70
|
+
/**
|
|
71
|
+
* Removes all expired contexts from the Map.
|
|
72
|
+
* Called automatically on every `set` operation.
|
|
73
|
+
*/
|
|
74
|
+
private cleanup;
|
|
75
|
+
/**
|
|
76
|
+
* Returns the number of stored contexts
|
|
77
|
+
*/
|
|
78
|
+
get size(): number;
|
|
79
|
+
}
|
|
@@ -0,0 +1,23 @@
|
|
|
1
|
+
import type { MfaFactorType, OobChannel } from './types';
|
|
2
|
+
/**
|
|
3
|
+
* Mapping configuration for a factor type
|
|
4
|
+
*/
|
|
5
|
+
export interface FactorMapping {
|
|
6
|
+
authenticatorTypes: ['otp'] | ['oob'];
|
|
7
|
+
oobChannels?: OobChannel[];
|
|
8
|
+
}
|
|
9
|
+
/**
|
|
10
|
+
* Maps MFA factor types to auth-js enrollment parameters
|
|
11
|
+
*/
|
|
12
|
+
export declare const FACTOR_MAPPING: Record<MfaFactorType, FactorMapping>;
|
|
13
|
+
/**
|
|
14
|
+
* MFA grant type constants for verification
|
|
15
|
+
*/
|
|
16
|
+
export declare const MfaGrantTypes: {
|
|
17
|
+
/** Grant type for OTP (TOTP) verification */
|
|
18
|
+
readonly OTP: "http://auth0.com/oauth/grant-type/mfa-otp";
|
|
19
|
+
/** Grant type for OOB (SMS, Email, Push) verification */
|
|
20
|
+
readonly OOB: "http://auth0.com/oauth/grant-type/mfa-oob";
|
|
21
|
+
/** Grant type for recovery code verification */
|
|
22
|
+
readonly RECOVERY_CODE: "http://auth0.com/oauth/grant-type/mfa-recovery-code";
|
|
23
|
+
};
|
|
@@ -0,0 +1,117 @@
|
|
|
1
|
+
import { MfaApiErrorResponse } from '@auth0/auth0-auth-js';
|
|
2
|
+
import { GenericError } from '../errors';
|
|
3
|
+
/**
|
|
4
|
+
* Base class for MFA-related errors in auth0-spa-js.
|
|
5
|
+
* Extends GenericError for unified error hierarchy across the SDK.
|
|
6
|
+
*/
|
|
7
|
+
export declare class MfaError extends GenericError {
|
|
8
|
+
constructor(error: string, error_description: string);
|
|
9
|
+
static fromPayload({ error, error_description }: {
|
|
10
|
+
error: string;
|
|
11
|
+
error_description: string;
|
|
12
|
+
}): MfaError;
|
|
13
|
+
}
|
|
14
|
+
/**
|
|
15
|
+
* Error thrown when listing MFA authenticators fails.
|
|
16
|
+
*
|
|
17
|
+
* @example
|
|
18
|
+
* ```typescript
|
|
19
|
+
* try {
|
|
20
|
+
* const authenticators = await mfa.getAuthenticators();
|
|
21
|
+
* } catch (error) {
|
|
22
|
+
* if (error instanceof MfaListAuthenticatorsError) {
|
|
23
|
+
* console.log(error.error); // 'access_denied'
|
|
24
|
+
* console.log(error.error_description); // 'Unauthorized'
|
|
25
|
+
* }
|
|
26
|
+
* }
|
|
27
|
+
* ```
|
|
28
|
+
*/
|
|
29
|
+
export declare class MfaListAuthenticatorsError extends MfaError {
|
|
30
|
+
constructor(error: string, error_description: string);
|
|
31
|
+
}
|
|
32
|
+
/**
|
|
33
|
+
* Error thrown when enrolling an MFA authenticator fails.
|
|
34
|
+
*
|
|
35
|
+
* @example
|
|
36
|
+
* ```typescript
|
|
37
|
+
* try {
|
|
38
|
+
* const enrollment = await mfa.enroll({
|
|
39
|
+
* authenticator_types: ['otp']
|
|
40
|
+
* });
|
|
41
|
+
* } catch (error) {
|
|
42
|
+
* if (error instanceof MfaEnrollmentError) {
|
|
43
|
+
* console.log(error.error); // 'invalid_phone_number'
|
|
44
|
+
* console.log(error.error_description); // 'Invalid phone number format'
|
|
45
|
+
* }
|
|
46
|
+
* }
|
|
47
|
+
* ```
|
|
48
|
+
*/
|
|
49
|
+
export declare class MfaEnrollmentError extends MfaError {
|
|
50
|
+
constructor(error: string, error_description: string);
|
|
51
|
+
}
|
|
52
|
+
/**
|
|
53
|
+
* Error thrown when initiating an MFA challenge fails.
|
|
54
|
+
*
|
|
55
|
+
* @example
|
|
56
|
+
* ```typescript
|
|
57
|
+
* try {
|
|
58
|
+
* const challenge = await mfa.challenge({
|
|
59
|
+
* mfaToken: mfaToken,
|
|
60
|
+
* challengeType: 'otp',
|
|
61
|
+
* authenticatorId: 'otp|dev_123'
|
|
62
|
+
* });
|
|
63
|
+
* } catch (error) {
|
|
64
|
+
* if (error instanceof MfaChallengeError) {
|
|
65
|
+
* console.log(error.error); // 'too_many_attempts'
|
|
66
|
+
* console.log(error.error_description); // 'Rate limit exceeded'
|
|
67
|
+
* }
|
|
68
|
+
* }
|
|
69
|
+
* ```
|
|
70
|
+
*/
|
|
71
|
+
export declare class MfaChallengeError extends MfaError {
|
|
72
|
+
constructor(error: string, error_description: string);
|
|
73
|
+
}
|
|
74
|
+
/**
|
|
75
|
+
* Error thrown when verifying an MFA challenge fails.
|
|
76
|
+
*
|
|
77
|
+
* @example
|
|
78
|
+
* ```typescript
|
|
79
|
+
* try {
|
|
80
|
+
* const tokens = await mfa.verify({
|
|
81
|
+
* mfaToken: mfaToken,
|
|
82
|
+
* grant_type: 'http://auth0.com/oauth/grant-type/mfa-otp',
|
|
83
|
+
* otp: '123456'
|
|
84
|
+
* });
|
|
85
|
+
* } catch (error) {
|
|
86
|
+
* if (error instanceof MfaVerifyError) {
|
|
87
|
+
* console.log(error.error); // 'invalid_otp' or 'context_not_found'
|
|
88
|
+
* console.log(error.error_description); // Error details
|
|
89
|
+
* }
|
|
90
|
+
* }
|
|
91
|
+
* ```
|
|
92
|
+
*/
|
|
93
|
+
export declare class MfaVerifyError extends MfaError {
|
|
94
|
+
constructor(error: string, error_description: string);
|
|
95
|
+
}
|
|
96
|
+
/**
|
|
97
|
+
* Error thrown when getting enrollment factors fails.
|
|
98
|
+
*
|
|
99
|
+
* @example
|
|
100
|
+
* ```typescript
|
|
101
|
+
* try {
|
|
102
|
+
* const factors = await mfa.getEnrollmentFactors(mfaToken);
|
|
103
|
+
* } catch (error) {
|
|
104
|
+
* if (error instanceof MfaEnrollmentFactorsError) {
|
|
105
|
+
* console.log(error.error); // 'mfa_context_not_found'
|
|
106
|
+
* console.log(error.error_description); // 'MFA context not found...'
|
|
107
|
+
* }
|
|
108
|
+
* }
|
|
109
|
+
* ```
|
|
110
|
+
*/
|
|
111
|
+
export declare class MfaEnrollmentFactorsError extends MfaError {
|
|
112
|
+
constructor(error: string, error_description: string);
|
|
113
|
+
}
|
|
114
|
+
/**
|
|
115
|
+
* Re-export MfaApiErrorResponse type for convenience
|
|
116
|
+
*/
|
|
117
|
+
export type { MfaApiErrorResponse };
|
|
@@ -0,0 +1,4 @@
|
|
|
1
|
+
export { MfaApiClient } from './MfaApiClient';
|
|
2
|
+
export { MfaContextManager } from './MfaContextManager';
|
|
3
|
+
export type { MfaContext } from './MfaContextManager';
|
|
4
|
+
export type { Authenticator, AuthenticatorType, OobChannel, MfaFactorType, EnrollBaseParams, EnrollParams, EnrollOtpParams, EnrollSmsParams, EnrollVoiceParams, EnrollEmailParams, EnrollPushParams, EnrollmentResponse, OtpEnrollmentResponse, OobEnrollmentResponse, ChallengeAuthenticatorParams, ChallengeResponse, VerifyParams, MfaGrantType, EnrollmentFactor } from './types';
|