From 9a5c5496cae7de3e03060ed3eabb7ebb2e629fbe Mon Sep 17 00:00:00 2001 From: Gyanesh Gouraw Date: Mon, 16 Feb 2026 19:08:49 +0530 Subject: [PATCH 1/2] feat: add Step-Up Authentication section and related examples to documentation --- EXAMPLES.md | 80 +++++++++++++++++++++++++++++++++++++++++++++++++++ src/index.tsx | 2 ++ 2 files changed, 82 insertions(+) diff --git a/EXAMPLES.md b/EXAMPLES.md index e8317742..3c407f9d 100644 --- a/EXAMPLES.md +++ b/EXAMPLES.md @@ -13,6 +13,7 @@ - [Connect Accounts for using Token Vault](#connect-accounts-for-using-token-vault) - [Access SDK Configuration](#access-sdk-configuration) - [Multi-Factor Authentication (MFA)](#multi-factor-authentication-mfa) +- [Step-Up Authentication](#step-up-authentication) ## Use with a Class Component @@ -990,3 +991,82 @@ try { } } ``` + +## Step-Up Authentication + +When a protected API requires MFA (step-up authentication), `getAccessTokenSilently` will receive an `mfa_required` error from Auth0. By configuring the `interactiveErrorHandler` option, the SDK can automatically handle this by opening a Universal Login popup for the user to complete MFA, then return the token transparently. No custom MFA UI is required — the entire flow is handled via Auth0's Universal Login. + +If you need full control over the MFA experience (custom UI for enrollment, challenge, and verification), see the [Multi-Factor Authentication (MFA)](#multi-factor-authentication-mfa) section instead. + +> [!WARNING] +> This feature only works with the refresh token flow (`useRefreshTokens={true}`) and only handles `mfa_required` errors. Other interactive errors are not intercepted. + +### Setup + +Configure `Auth0Provider` with `interactiveErrorHandler` set to `"popup"` and refresh tokens enabled: + +```jsx +import { Auth0Provider } from '@auth0/auth0-react'; + +function App() { + return ( + + + + ); +} +``` + +### Usage + +With this configuration, `getAccessTokenSilently` automatically opens a popup when the token request triggers an `mfa_required` error. Once the user completes MFA in the popup, the token is returned as if the call succeeded normally: + +```jsx +import React, { useEffect, useState } from 'react'; +import { useAuth0 } from '@auth0/auth0-react'; + +const ProtectedResource = () => { + const { getAccessTokenSilently } = useAuth0(); + const [data, setData] = useState(null); + + useEffect(() => { + (async () => { + try { + // If MFA is required, a popup opens automatically. + // The token is returned after the user completes MFA. + const token = await getAccessTokenSilently({ + authorizationParams: { + audience: 'https://api.example.com/', + scope: 'read:sensitive', + }, + }); + const response = await fetch('https://api.example.com/sensitive', { + headers: { Authorization: `Bearer ${token}` }, + }); + setData(await response.json()); + } catch (e) { + console.error(e); + } + })(); + }, [getAccessTokenSilently]); + + if (!data) return
Loading...
; + return
{JSON.stringify(data)}
; +}; + +export default ProtectedResource; +``` + +### Error Handling + +If the popup is blocked, cancelled, or times out, `getAccessTokenSilently` throws `PopupOpenError`, `PopupCancelledError`, or `PopupTimeoutError` respectively. These can be imported from `@auth0/auth0-react`. + diff --git a/src/index.tsx b/src/index.tsx index 2a9b43ba..4db5b72e 100644 --- a/src/index.tsx +++ b/src/index.tsx @@ -35,6 +35,7 @@ export { MfaRequiredError, PopupCancelledError, PopupTimeoutError, + PopupOpenError, AuthenticationError, MissingRefreshTokenError, GenericError, @@ -44,6 +45,7 @@ export { ConnectAccountRedirectResult, ResponseType, ConnectError, + type InteractiveErrorHandler, CustomTokenExchangeOptions, TokenEndpointResponse, ClientConfiguration, From 0cc3668dd9e94b9b98251031c0075e49ec99933c Mon Sep 17 00:00:00 2001 From: Gyanesh Gouraw Date: Tue, 17 Feb 2026 10:44:52 +0530 Subject: [PATCH 2/2] chore: update @auth0/auth0-spa-js dependency to version 2.16.0 --- package-lock.json | 9 ++++----- package.json | 2 +- 2 files changed, 5 insertions(+), 6 deletions(-) diff --git a/package-lock.json b/package-lock.json index 833d35e7..2de9bb08 100644 --- a/package-lock.json +++ b/package-lock.json @@ -9,7 +9,7 @@ "version": "2.14.0", "license": "MIT", "dependencies": { - "@auth0/auth0-spa-js": "^2.15.0" + "@auth0/auth0-spa-js": "^2.16.0" }, "devDependencies": { "@rollup/plugin-node-resolve": "^15.0.1", @@ -91,10 +91,9 @@ } }, "node_modules/@auth0/auth0-spa-js": { - "version": "2.15.0", - "resolved": "https://registry.npmjs.org/@auth0/auth0-spa-js/-/auth0-spa-js-2.15.0.tgz", - "integrity": "sha512-cXv1Isyy4JEc+GxesQPFj3SEbDSnCVQTGiardY9WLSoYTsMMU585Kgm9TJFPJO4dDq3wi+DSJoy3IUcB3rr9nA==", - "license": "MIT", + "version": "2.16.0", + "resolved": "https://registry.npmjs.org/@auth0/auth0-spa-js/-/auth0-spa-js-2.16.0.tgz", + "integrity": "sha512-UTP45NqjC2jVc/WaWh+iYOZt6FajpTJc+3WzljbXBiv2f76wDw4Mt9hW/aShBovsRmvKEIHaCifD3c/Gxmo2ZQ==", "dependencies": { "@auth0/auth0-auth-js": "^1.4.0", "browser-tabs-lock": "^1.2.15", diff --git a/package.json b/package.json index 67339e5a..51d095de 100644 --- a/package.json +++ b/package.json @@ -95,6 +95,6 @@ "react-dom": "^16.11.0 || ^17 || ^18 || ~19.0.1 || ~19.1.2 || ^19.2.1" }, "dependencies": { - "@auth0/auth0-spa-js": "^2.15.0" + "@auth0/auth0-spa-js": "^2.16.0" } }