Skip to content

Commit a10199d

Browse files
committed
docs: make mfa docs more clear
1 parent 6c20e2b commit a10199d

File tree

2 files changed

+66
-52
lines changed

2 files changed

+66
-52
lines changed

site/pages/react/mfa/email-magic-link.mdx

Lines changed: 66 additions & 47 deletions
Original file line numberDiff line numberDiff line change
@@ -9,7 +9,7 @@ This guide shows you how to implement authentication with Email Magic Link and T
99

1010
## Overview
1111

12-
When a user has MFA enabled with an authenticator app (TOTP), the login flow requires two steps:
12+
When a user has MFA enabled with an authenticator app (TOTP), the login flow requires the following steps:
1313

1414
1. The user enters their email address to request a magic link
1515
2. If MFA is enabled for their account, they're prompted to enter the 6-digit TOTP code from their authenticator app (e.g., Google Authenticator)
@@ -21,9 +21,10 @@ This two-factor approach provides an additional layer of security beyond a stand
2121

2222
## Implementation
2323

24-
### Step 1: Send the Magic Link with MFA Handling
24+
### Step 1: Initialize Authentication and Handle MFA Required Error
2525

26-
When sending a magic link to a user with MFA enabled, you need to handle both parts of the authentication flow:
26+
First, attempt to authenticate with email. If MFA is required, an error will be thrown.
27+
You can handle this error by prompting the user to enter their TOTP code.
2728

2829
```tsx twoslash
2930
import React from "react";
@@ -32,13 +33,10 @@ import { MfaRequiredError } from "@account-kit/signer";
3233
import { useState } from "react";
3334

3435
function MagicLinkWithMFA() {
35-
const [mfaData, setMfaData] = useState({ email: "", multiFactorId: "" });
36-
const [showTotpInput, setShowTotpInput] = useState(false);
37-
const [totpCode, setTotpCode] = useState("");
3836
const { authenticate } = useAuthenticate();
3937

40-
// When the user submits their email to receive a magic link
41-
const handleSendMagicLink = (email: string) => {
38+
// Step 1: Handle initial email submission and check for MFA requirement
39+
const handleInitialAuthentication = (email: string) => {
4240
authenticate(
4341
{
4442
type: "email",
@@ -56,33 +54,52 @@ function MagicLinkWithMFA() {
5654
if (error instanceof MfaRequiredError) {
5755
const { multiFactorId } = error.multiFactors[0];
5856

59-
// Store this information to use when the user enters their TOTP code
60-
setMfaData({ email, multiFactorId });
61-
setShowTotpInput(true);
57+
// Store the multiFactorId to use when the user enters their TOTP code
58+
59+
// In step 2, we will prompt the user to enter their TOTP code (from their authenticator app)
60+
// and we'll use this multiFactorId to verify the TOTP code
6261
}
6362
// Handle other errors
6463
},
6564
}
6665
);
6766
};
6867

69-
// Add a handler for the TOTP input
70-
const handleTotpChange = (e: React.ChangeEvent<HTMLInputElement>) => {
71-
setTotpCode(e.target.value);
72-
};
68+
return <div>{/* Your UI components here */}</div>;
69+
}
70+
```
7371

74-
// When the user provides the TOTP code
75-
const handleMagicLinkWithMFA = () => {
72+
### Step 2: Submit TOTP Code and Complete Magic Link Authentication
73+
74+
Once we have the MFA data from the first step, we can complete the authentication by submitting the TOTP code with the multiFactorId.
75+
You must prompt the user to enter their TOTP code (from their authenticator app) and then submit it with the multiFactorId.
76+
77+
```tsx twoslash
78+
import React from "react";
79+
import { useAuthenticate } from "@account-kit/react";
80+
81+
// Continuing from the previous component...
82+
83+
function MagicLinkWithMFA() {
84+
const { authenticate } = useAuthenticate();
85+
86+
// Prompt the user to enter their TOTP code (from their authenticator app)
87+
// Hardcoded for now, but in a real app you'd get this from the user
88+
const totpCode = "123456";
89+
const multiFactorId = "123456"; // This is the multiFactorId from the first step
90+
91+
// Step 2: Submit the TOTP code with multiFactorId to complete the flow
92+
const handleMfaSubmission = (email: string) => {
7693
authenticate(
7794
{
7895
type: "email",
7996
emailMode: "magicLink",
80-
email: mfaData.email,
97+
email,
8198
// The multiFactors array tells the authentication system which
8299
// factor to verify and what code to use
83100
multiFactors: [
84101
{
85-
multiFactorId: mfaData.multiFactorId,
102+
multiFactorId,
86103
multiFactorCode: totpCode,
87104
},
88105
],
@@ -102,44 +119,46 @@ function MagicLinkWithMFA() {
102119
}
103120
```
104121

105-
### Step 2: Handle the Magic Link Redirect
122+
### Step 3: Handle the Magic Link Redirect
106123

107-
When the user clicks the magic link in their email, your application needs to handle the redirect and complete the authentication:
124+
When the user clicks the magic link in their email, your application needs to handle the redirect and complete the authentication.
125+
The magic link will redirect to your application with a bundle parameter. You must submit this bundle to the `authenticate` function to complete the authentication.
108126

109127
```tsx twoslash
110128
import React, { useEffect } from "react";
111129
import { useAuthenticate } from "@account-kit/react";
112130

113-
// Inside your component
114-
const { authenticate } = useAuthenticate();
131+
function MagicLinkRedirect() {
132+
const { authenticate } = useAuthenticate();
115133

116-
const handleMagicLinkRedirect = () => {
117-
const url = new URL(window.location.href);
118-
const bundle = url.searchParams.get("bundle");
134+
const handleMagicLinkRedirect = () => {
135+
const url = new URL(window.location.href);
136+
const bundle = url.searchParams.get("bundle");
119137

120-
// If there's no bundle parameter, this isn't a magic link redirect
121-
if (!bundle) return;
138+
// If there's no bundle parameter, this isn't a magic link redirect
139+
if (!bundle) return;
122140

123-
authenticate(
124-
{
125-
type: "email",
126-
bundle,
127-
},
128-
{
129-
onSuccess: () => {
130-
// Authentication successful!
131-
},
132-
onError: (error) => {
133-
// Handle error
141+
authenticate(
142+
{
143+
type: "email",
144+
bundle,
134145
},
135-
}
136-
);
137-
};
138-
139-
// Call this function when the component mounts
140-
useEffect(() => {
141-
handleMagicLinkRedirect();
142-
}, []);
146+
{
147+
onSuccess: () => {
148+
// Authentication successful!
149+
},
150+
onError: (error) => {
151+
// Handle error
152+
},
153+
}
154+
);
155+
};
156+
157+
// Call this function when the component mounts
158+
useEffect(() => {
159+
handleMagicLinkRedirect();
160+
}, []);
161+
}
143162
```
144163

145164
## Next Steps

site/pages/react/mfa/setup-mfa.mdx

Lines changed: 0 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -13,17 +13,12 @@ By requiring both a user's primary login (e.g., email OTP, magic link, or social
1313
Multi-factor authentication requires a primary authentication method (Email OTP, Email Magic Link, or Social Login) to be already set up. See the [React Quickstart](/react/quickstart) guide to set up your primary authentication method first.
1414
:::
1515

16-
## Overview
17-
18-
Multi-factor authentication adds an extra layer of security by requiring users to verify their identity using multiple methods. With Account Kit, users can use authenticator apps (like Google Authenticator, Authy, or Microsoft Authenticator) as their second security factor.
19-
2016
## Prerequisites
2117

2218
Before implementing MFA, you need to have:
2319

2420
1. **Set up primary authentication** - MFA requires a primary authentication method to be already set up. Follow the [React Quickstart](/react/quickstart) guide to configure email (OTP or magic link) or social login.
2521
2. **Working authentication flow** - Ensure users can successfully sign in with your primary authentication method.
26-
3. **Proper configuration** - In your `config.ts`, make sure you've enabled email or social login in the authentication sections.
2722

2823
:::info
2924
MFA is an additional security layer that works with your existing authentication system. If you haven't set up basic authentication yet, you won't be able to implement MFA.

0 commit comments

Comments
 (0)