@auth0/auth0-server-js 1.4.0 → 1.6.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/dist/index.cjs +195 -4
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.cts +159 -4
- package/dist/index.d.ts +159 -4
- package/dist/index.js +194 -3
- package/dist/index.js.map +1 -1
- package/package.json +7 -4
package/dist/index.cjs
CHANGED
|
@@ -26,13 +26,19 @@ __export(index_exports, {
|
|
|
26
26
|
CookieTransactionStore: () => CookieTransactionStore,
|
|
27
27
|
InvalidConfigurationError: () => InvalidConfigurationError,
|
|
28
28
|
IssuerValidationError: () => IssuerValidationError,
|
|
29
|
+
MfaChallengeError: () => import_auth0_auth_js2.MfaChallengeError,
|
|
30
|
+
MfaEnrollmentError: () => import_auth0_auth_js2.MfaEnrollmentError,
|
|
31
|
+
MfaListAuthenticatorsError: () => import_auth0_auth_js2.MfaListAuthenticatorsError,
|
|
32
|
+
MfaVerifyError: () => import_auth0_auth_js2.MfaVerifyError,
|
|
29
33
|
MissingRequiredArgumentError: () => MissingRequiredArgumentError,
|
|
30
34
|
MissingSessionError: () => MissingSessionError,
|
|
31
35
|
MissingTransactionError: () => MissingTransactionError,
|
|
32
36
|
ServerClient: () => ServerClient,
|
|
37
|
+
ServerMfaClient: () => ServerMfaClient,
|
|
33
38
|
StartLinkUserError: () => StartLinkUserError,
|
|
34
39
|
StatefulStateStore: () => StatefulStateStore,
|
|
35
|
-
StatelessStateStore: () => StatelessStateStore
|
|
40
|
+
StatelessStateStore: () => StatelessStateStore,
|
|
41
|
+
isMfaRequiredError: () => import_auth0_auth_js2.isMfaRequiredError
|
|
36
42
|
});
|
|
37
43
|
module.exports = __toCommonJS(index_exports);
|
|
38
44
|
|
|
@@ -95,6 +101,17 @@ var createUpdatedTokenSet = (audience, response) => ({
|
|
|
95
101
|
expiresAt: response.expiresAt
|
|
96
102
|
});
|
|
97
103
|
function updateStateData(audience, stateData, tokenEndpointResponse, context) {
|
|
104
|
+
if (stateData && tokenEndpointResponse.claims) {
|
|
105
|
+
const newSub = tokenEndpointResponse.claims.sub;
|
|
106
|
+
const newIss = tokenEndpointResponse.claims.iss;
|
|
107
|
+
const existingSub = stateData.user?.sub;
|
|
108
|
+
const existingIss = stateData.user?.iss;
|
|
109
|
+
const subMismatch = newSub !== void 0 && existingSub !== void 0 && newSub !== existingSub;
|
|
110
|
+
const issMismatch = newIss !== void 0 && existingIss !== void 0 && newIss !== existingIss;
|
|
111
|
+
if (subMismatch || issMismatch) {
|
|
112
|
+
stateData = void 0;
|
|
113
|
+
}
|
|
114
|
+
}
|
|
98
115
|
if (stateData) {
|
|
99
116
|
const isNewTokenSet = !stateData.tokenSets.some(
|
|
100
117
|
(tokenSet) => tokenSet.audience === audience && tokenSet.scope === tokenEndpointResponse.scope
|
|
@@ -172,10 +189,90 @@ function getTelemetryConfig(config) {
|
|
|
172
189
|
return {
|
|
173
190
|
enabled: true,
|
|
174
191
|
name: config?.name ?? "@auth0/auth0-server-js",
|
|
175
|
-
version: config?.version ?? "1.
|
|
192
|
+
version: config?.version ?? "1.6.0"
|
|
176
193
|
};
|
|
177
194
|
}
|
|
178
195
|
|
|
196
|
+
// src/mfa/server-mfa-client.ts
|
|
197
|
+
var ServerMfaClient = class {
|
|
198
|
+
#options;
|
|
199
|
+
/**
|
|
200
|
+
* @internal
|
|
201
|
+
*/
|
|
202
|
+
constructor(options) {
|
|
203
|
+
this.#options = options;
|
|
204
|
+
}
|
|
205
|
+
/**
|
|
206
|
+
* Lists all MFA authenticators enrolled by the user.
|
|
207
|
+
*
|
|
208
|
+
* @param options - Options for listing authenticators
|
|
209
|
+
* @returns Promise resolving to an array of enrolled authenticators
|
|
210
|
+
* @throws {MfaListAuthenticatorsError} When the request fails
|
|
211
|
+
*/
|
|
212
|
+
async listAuthenticators(options) {
|
|
213
|
+
return this.#options.authClient.mfa.listAuthenticators(options);
|
|
214
|
+
}
|
|
215
|
+
/**
|
|
216
|
+
* Enrolls a new MFA authenticator for the user.
|
|
217
|
+
*
|
|
218
|
+
* @param options - Enrollment options
|
|
219
|
+
* @returns Promise resolving to enrollment response with authenticator details
|
|
220
|
+
* @throws {MfaEnrollmentError} When enrollment fails
|
|
221
|
+
*/
|
|
222
|
+
async enrollAuthenticator(options) {
|
|
223
|
+
return this.#options.authClient.mfa.enrollAuthenticator(options);
|
|
224
|
+
}
|
|
225
|
+
/**
|
|
226
|
+
* Initiates an MFA challenge for user verification.
|
|
227
|
+
*
|
|
228
|
+
* @param options - Challenge options
|
|
229
|
+
* @returns Promise resolving to challenge response with challenge details
|
|
230
|
+
* @throws {MfaChallengeError} When the challenge fails
|
|
231
|
+
*/
|
|
232
|
+
async challengeAuthenticator(options) {
|
|
233
|
+
return this.#options.authClient.mfa.challengeAuthenticator(options);
|
|
234
|
+
}
|
|
235
|
+
/**
|
|
236
|
+
* Verifies an MFA challenge and completes the authentication flow.
|
|
237
|
+
*
|
|
238
|
+
* Exchanges the MFA token and verification code for access, ID, and refresh tokens,
|
|
239
|
+
* then saves them into the user's session automatically.
|
|
240
|
+
*
|
|
241
|
+
* @param options - The MFA token, factor type (otp / oob / recovery-code), and the code to verify
|
|
242
|
+
* @param storeOptions - Optional options forwarded to the session store. Can be omitted when
|
|
243
|
+
* using the built-in stores; required if your custom store needs extra context (e.g. a request object).
|
|
244
|
+
* @returns The tokens returned by Auth0 after successful verification
|
|
245
|
+
* @throws {MfaVerifyError} When verification fails (e.g. invalid token, wrong code)
|
|
246
|
+
*/
|
|
247
|
+
async verify(options, storeOptions) {
|
|
248
|
+
const tokenResponse = await this.#options.authClient.mfa.verify(options);
|
|
249
|
+
const audience = options.audience ?? this.#options.defaultAudience;
|
|
250
|
+
const existingStateData = await this.#options.stateStore.get(
|
|
251
|
+
this.#options.stateStoreIdentifier,
|
|
252
|
+
storeOptions
|
|
253
|
+
);
|
|
254
|
+
const updatedStateData = updateStateData(audience, existingStateData, tokenResponse, {
|
|
255
|
+
domain: this.#options.domain
|
|
256
|
+
});
|
|
257
|
+
await this.#options.stateStore.set(
|
|
258
|
+
this.#options.stateStoreIdentifier,
|
|
259
|
+
updatedStateData,
|
|
260
|
+
true,
|
|
261
|
+
storeOptions
|
|
262
|
+
);
|
|
263
|
+
const result = {
|
|
264
|
+
accessToken: tokenResponse.accessToken,
|
|
265
|
+
tokenType: tokenResponse.tokenType ?? "bearer",
|
|
266
|
+
expiresAt: tokenResponse.expiresAt,
|
|
267
|
+
scope: tokenResponse.scope
|
|
268
|
+
};
|
|
269
|
+
if (tokenResponse.idToken) result.idToken = tokenResponse.idToken;
|
|
270
|
+
if (tokenResponse.refreshToken) result.refreshToken = tokenResponse.refreshToken;
|
|
271
|
+
if (tokenResponse.recoveryCode) result.recoveryCode = tokenResponse.recoveryCode;
|
|
272
|
+
return result;
|
|
273
|
+
}
|
|
274
|
+
};
|
|
275
|
+
|
|
179
276
|
// src/server-client.ts
|
|
180
277
|
var DEFAULT_SCOPES = "openid profile email offline_access";
|
|
181
278
|
var normalizeDomain = (value) => {
|
|
@@ -210,6 +307,7 @@ var ServerClient = class {
|
|
|
210
307
|
#authClientOptions;
|
|
211
308
|
#staticDomain;
|
|
212
309
|
#authClient;
|
|
310
|
+
#mfaClient;
|
|
213
311
|
/**
|
|
214
312
|
* The underlying `authClient` instance that can be used to interact with the Auth0 Authentication API.
|
|
215
313
|
* Generally, you should prefer to use the higher-level methods exposed on the `ServerClient` instance.
|
|
@@ -226,6 +324,24 @@ var ServerClient = class {
|
|
|
226
324
|
}
|
|
227
325
|
return this.#authClient;
|
|
228
326
|
}
|
|
327
|
+
/**
|
|
328
|
+
* The MFA client for managing multi-factor authentication operations.
|
|
329
|
+
*
|
|
330
|
+
* Provides methods to list, enroll, and challenge MFA authenticators,
|
|
331
|
+
* as well as verify MFA challenges to complete authentication.
|
|
332
|
+
*
|
|
333
|
+
* The `verify` method integrates with the session state store, persisting tokens
|
|
334
|
+
* and user data after successful MFA verification.
|
|
335
|
+
*
|
|
336
|
+
* This property can only be used when `domain` is configured as a static string.
|
|
337
|
+
* In resolver mode (`domain` as a function), MFA is not supported.
|
|
338
|
+
*/
|
|
339
|
+
get mfa() {
|
|
340
|
+
if (!this.#mfaClient) {
|
|
341
|
+
throw new InvalidConfigurationError("mfa is only available when using a static domain configuration.");
|
|
342
|
+
}
|
|
343
|
+
return this.#mfaClient;
|
|
344
|
+
}
|
|
229
345
|
constructor(options) {
|
|
230
346
|
this.#options = options;
|
|
231
347
|
this.#stateStoreIdentifier = this.#options.stateIdentifier || "__a0_session";
|
|
@@ -259,6 +375,13 @@ var ServerClient = class {
|
|
|
259
375
|
...this.#authClientOptions,
|
|
260
376
|
telemetry: getTelemetryConfig(this.#options.telemetry)
|
|
261
377
|
});
|
|
378
|
+
this.#mfaClient = new ServerMfaClient({
|
|
379
|
+
authClient: this.#authClient,
|
|
380
|
+
domain,
|
|
381
|
+
stateStore: this.#stateStore,
|
|
382
|
+
stateStoreIdentifier: this.#stateStoreIdentifier,
|
|
383
|
+
defaultAudience: this.#options.authorizationParams?.audience ?? "default"
|
|
384
|
+
});
|
|
262
385
|
}
|
|
263
386
|
}
|
|
264
387
|
async #resolveDomain(storeOptions) {
|
|
@@ -568,7 +691,7 @@ var ServerClient = class {
|
|
|
568
691
|
* Also updates the store when a new token was retrieved from Auth0.
|
|
569
692
|
* @param storeOptions Optional options used to pass to the Transaction and State Store.
|
|
570
693
|
*
|
|
571
|
-
* @throws {TokenByRefreshTokenError} If the refresh token was not found or there was an issue requesting the access token.
|
|
694
|
+
* @throws {TokenByRefreshTokenError} If the refresh token was not found or there was an issue requesting the access token. When the cause is `mfa_required`, use `isMfaRequiredError(error)` to narrow the error and read `cause.mfa_token`.
|
|
572
695
|
*
|
|
573
696
|
* @returns The Token Set, containing the access token, as well as additional information.
|
|
574
697
|
*/
|
|
@@ -703,6 +826,65 @@ var ServerClient = class {
|
|
|
703
826
|
}
|
|
704
827
|
return authClient.buildLogoutUrl(options);
|
|
705
828
|
}
|
|
829
|
+
/**
|
|
830
|
+
* Exchanges a custom token for Auth0 tokens and persists the resulting session (RFC 8693).
|
|
831
|
+
*
|
|
832
|
+
* Calls the token endpoint using the RFC 8693 Token Exchange grant, then stores the
|
|
833
|
+
* resulting tokens in the StateStore — effectively logging the user in without an
|
|
834
|
+
* interactive browser flow. Use this when the caller already holds a trusted external
|
|
835
|
+
* token (e.g. a Google ID token, a legacy system token) and wants to establish an
|
|
836
|
+
* Auth0 session from it.
|
|
837
|
+
*
|
|
838
|
+
* Requires a Token Exchange Profile configured in your Auth0 tenant.
|
|
839
|
+
*
|
|
840
|
+
* @param options Options for the custom token exchange, including the subject token and its type.
|
|
841
|
+
* @param storeOptions Optional options passed to the StateStore.
|
|
842
|
+
*
|
|
843
|
+
* @throws {TokenExchangeError} If the exchange fails or the subject token is invalid.
|
|
844
|
+
* @throws {MissingClientAuthError} If client credentials are not configured.
|
|
845
|
+
*
|
|
846
|
+
* @returns A promise resolving to an object containing `authorizationDetails` when RAR was used.
|
|
847
|
+
*/
|
|
848
|
+
async loginWithCustomTokenExchange(options, storeOptions) {
|
|
849
|
+
const domain = await this.#resolveDomain(storeOptions);
|
|
850
|
+
const authClient = this.#getAuthClient(domain);
|
|
851
|
+
const tokenEndpointResponse = await authClient.exchangeToken({
|
|
852
|
+
...options,
|
|
853
|
+
scope: ensureOpenIdScope(options.scope)
|
|
854
|
+
});
|
|
855
|
+
const existingStateData = await this.#stateStore.get(this.#stateStoreIdentifier, storeOptions);
|
|
856
|
+
const stateData = updateStateData(
|
|
857
|
+
this.#options.authorizationParams?.audience ?? "default",
|
|
858
|
+
existingStateData,
|
|
859
|
+
tokenEndpointResponse,
|
|
860
|
+
{ domain }
|
|
861
|
+
);
|
|
862
|
+
await this.#stateStore.set(this.#stateStoreIdentifier, stateData, true, storeOptions);
|
|
863
|
+
return { authorizationDetails: tokenEndpointResponse.authorizationDetails };
|
|
864
|
+
}
|
|
865
|
+
/**
|
|
866
|
+
* Exchanges a custom token for Auth0 tokens without establishing a session (RFC 8693).
|
|
867
|
+
*
|
|
868
|
+
* Performs the same RFC 8693 Token Exchange as `loginWithCustomTokenExchange` but
|
|
869
|
+
* returns the raw token response without writing anything to the StateStore. Use this
|
|
870
|
+
* for delegation or impersonation flows where you need downstream tokens but do not
|
|
871
|
+
* want to create or modify the current user session.
|
|
872
|
+
*
|
|
873
|
+
* Requires a Token Exchange Profile configured in your Auth0 tenant.
|
|
874
|
+
*
|
|
875
|
+
* @param options Options for the custom token exchange, including the subject token and its type.
|
|
876
|
+
* @param storeOptions Optional options passed to the StateStore (used only for domain resolution in resolver mode).
|
|
877
|
+
*
|
|
878
|
+
* @throws {TokenExchangeError} If the exchange fails or the subject token is invalid.
|
|
879
|
+
* @throws {MissingClientAuthError} If client credentials are not configured.
|
|
880
|
+
*
|
|
881
|
+
* @returns A promise resolving to the token response from Auth0.
|
|
882
|
+
*/
|
|
883
|
+
async customTokenExchange(options, storeOptions) {
|
|
884
|
+
const domain = await this.#resolveDomain(storeOptions);
|
|
885
|
+
const authClient = this.#getAuthClient(domain);
|
|
886
|
+
return authClient.exchangeToken(options);
|
|
887
|
+
}
|
|
706
888
|
/**
|
|
707
889
|
* Handles the backchannel logout process by verifying the logout token and deleting the session from the store if the logout token was considered valid.
|
|
708
890
|
* @param logoutToken The logout token to verify and use to delete the session from the store.
|
|
@@ -1049,6 +1231,9 @@ var StatelessStateStore = class extends AbstractSessionStore {
|
|
|
1049
1231
|
};
|
|
1050
1232
|
}
|
|
1051
1233
|
};
|
|
1234
|
+
|
|
1235
|
+
// src/mfa/index.ts
|
|
1236
|
+
var import_auth0_auth_js2 = require("@auth0/auth0-auth-js");
|
|
1052
1237
|
// Annotate the CommonJS export names for ESM import in node:
|
|
1053
1238
|
0 && (module.exports = {
|
|
1054
1239
|
AbstractStateStore,
|
|
@@ -1057,12 +1242,18 @@ var StatelessStateStore = class extends AbstractSessionStore {
|
|
|
1057
1242
|
CookieTransactionStore,
|
|
1058
1243
|
InvalidConfigurationError,
|
|
1059
1244
|
IssuerValidationError,
|
|
1245
|
+
MfaChallengeError,
|
|
1246
|
+
MfaEnrollmentError,
|
|
1247
|
+
MfaListAuthenticatorsError,
|
|
1248
|
+
MfaVerifyError,
|
|
1060
1249
|
MissingRequiredArgumentError,
|
|
1061
1250
|
MissingSessionError,
|
|
1062
1251
|
MissingTransactionError,
|
|
1063
1252
|
ServerClient,
|
|
1253
|
+
ServerMfaClient,
|
|
1064
1254
|
StartLinkUserError,
|
|
1065
1255
|
StatefulStateStore,
|
|
1066
|
-
StatelessStateStore
|
|
1256
|
+
StatelessStateStore,
|
|
1257
|
+
isMfaRequiredError
|
|
1067
1258
|
});
|
|
1068
1259
|
//# sourceMappingURL=index.cjs.map
|