You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
Copy file name to clipboardExpand all lines: adminforth/documentation/docs/tutorial/07-Plugins/02-TwoFactorsAuth.md
+73-26Lines changed: 73 additions & 26 deletions
Display the source diff
Display the rich diff
Original file line number
Diff line number
Diff line change
@@ -2,13 +2,23 @@
2
2
3
3
The Two-Factor Authentication Plugin provides an additional layer of security to the application by requiring users to provide a second form of authentication in addition to their password. This plugin supports authenticator apps.
4
4
5
+
Plugin supports next 2FA methods:
6
+
- TOTP (Time-based One-Time Password) via authenticator apps (Google Authenticator, Authy, Microsoft Authenticator, etc)
7
+
- Upgrade to Passkeys (WebAuthn) alongside TOTP (with TOTP as alternative method)
8
+
9
+
Also it supports both:
10
+
11
+
- Multi-Factor Authentication (MFA): asking for 2FA on every login (or single WebAuthn passkey login)
12
+
- Step-Up MFA: asking for 2FA again on critical operations (custom actions, secure save etc)
13
+
14
+
5
15
## Installation
6
16
7
17
```bash
8
18
npm i @adminforth/two-factors-auth --save
9
19
```
10
20
11
-
Plugin is already installed into adminforth, to import:
@@ -78,8 +88,7 @@ Thats it! Two-Factor Authentication is now enabled:
78
88
79
89
## Disabling Two-Factor Authentication locally
80
90
81
-
If it is not convenient to enter the code every time you log in during local development, you can disable Two-Factor Authentication
82
-
for the dev environment using `usersFilterToApply` option.
91
+
If it is not convenient to enter the code every time during local development, you can disable Two-Factor Authentication for the dev environment using `usersFilterToApply` option:
83
92
84
93
```tstitle='./index.ts'
85
94
@@ -104,6 +113,8 @@ for the dev environment using `usersFilterToApply` option.
104
113
],
105
114
```
106
115
116
+
> Note: you can enable it temporarey while testing two-factor authentication flow locally and then disable.
117
+
107
118
## Select which users should use Two-Factor Authentication
108
119
109
120
By default plugin enforces Two-Factor Authentication for all users.
@@ -117,6 +128,10 @@ If you wish to enforce 2FA only for specific users, you can again use `usersFilt
117
128
},
118
129
```
119
130
131
+
Other users (for whom this function returns false) will not be even suggested to setup 2FA and it will be not requested for them, nor on login, nor on step-up MFA requests (such requests will be automatically passed for them without any popups)
132
+
133
+
### Control 2FA per-user via DB field
134
+
120
135
You can even add a boolean column to the user table to store whether the user should use 2FA or not:
121
136
122
137
In `schema.prisma`:
@@ -129,7 +144,7 @@ model adminuser {
129
144
roleString
130
145
password_hashString
131
146
secret2faString?
132
-
//diff-add
147
+
//diff-add
133
148
use2faBoolean? @default(false)
134
149
}
135
150
```
@@ -184,30 +199,35 @@ Then in `adminuser.ts`:
184
199
185
200
## Allow Specific Users to Skip Two-Factor Authentication Setup
186
201
187
-
By default, all users are required to setup Two-Factor Authentication if it is enabled.
202
+
By default, all users are required to setup Two-Factor Authentication if it is enabled (enforced).
188
203
189
-
If you want to allow specific users to **skip** the 2FA setup, you can use the `usersFilterToAllowSkipSetup` option:
204
+
If you want to allow specific users to **skip** the 2FA setup (but still suggest it as optional possibility), you can use the `usersFilterToAllowSkipSetup` option:
So such users will have suggestion to setup 2FA, but will be able to skip it with "Skip for now" button.
226
+
227
+
228
+
## Step-Up MFA (Two-Factor re-authentication on critical operations)
229
+
230
+
### Request 2FA on custom Actions
211
231
212
232
You might want to to allow to call some custom critical/money related actions with additional 2FA approval. This eliminates risks caused by user cookies theft by some virous/doorway software after login.
213
233
@@ -225,15 +245,18 @@ To do it, first, create frontend custom component which wraps and intercepts cli
const verificationResult =awaitwindow.adminforthTwoFaModal.get2FaConfirmationResult(); // this will ask user to enter code
252
+
const verificationResult =awaitwindow.adminforthTwoFaModal.get2FaConfirmationResult(); // this will ask user to enter code
253
+
231
254
emit('callAction', { verificationResult }); // then we pass this verification result to action (from fronted to backend)
232
255
}
233
256
</script>
234
257
```
235
258
236
-
Now we need to use verification result which we got from user on frontend, inside of backend action handler and verify that it is valid (and not expired):
259
+
Now we need to use verification result which we got from user on frontend, inside of backend action handler and verify that it is valid (and not expired):
237
260
238
261
```tstitle='/adminuser.ts'
239
262
options: {
@@ -303,7 +326,7 @@ options: {
303
326
}
304
327
```
305
328
306
-
## Request 2FA for create/edit (secure save gating)
329
+
### Request 2FA for create/edit (secure save gating)
307
330
308
331
To protect create and edit operations, collect the result of the 2FA modal on the frontend and send it along with the save payload. The server must verify it before writing changes.
309
332
@@ -371,7 +394,7 @@ This approach ensures 2FA cannot be bypassed by calling the API directly:
371
394
- The client collects verification via the modal and forwards it under `meta.confirmationResult`.
372
395
- The server validates it in `beforeSave` with access to `extra.cookies` and the `adminUser`.
373
396
374
-
## Request 2FA from custom components
397
+
### Request 2FA from custom components
375
398
376
399
Imagine you have some button which does some API call
377
400
@@ -451,7 +474,7 @@ async function callAdminAPI() {
> 💡** Note ** this feature is now in development and might be not yet available.
535
+
536
+
By default, step-up authentication is required every time the user performs a critical operation.
537
+
538
+
While it might be nessesary for high-security applications, it can be inconvenient for users who perform multiple critical actions in a short period. To fix the issue (by lowering security a bit), you can enable grace period between step-up authentication requests:
539
+
540
+
541
+
```tstitle='./adminuser.ts'
542
+
newTwoFactorsAuthPlugin ({
543
+
twoFaSecretFieldName: 'secret2fa',
544
+
...
545
+
//diff-add
546
+
stepUpMfaGracePeriodSeconds: 300, // 5 minutes grace period
547
+
...
548
+
}),
549
+
```
550
+
551
+
This configuration still remembers user browser fingerprint and IP address, and if at least one of them changes, it will ask for 2FA again, ignoring grace period.
552
+
553
+
554
+
Any popups asking for 2FA would be automatically resolved during grace period without user interaction if both browser fingerprint and IP address are the same as during last successful 2FA and time since last 2FA is less than grace period.
555
+
509
556
510
557
## Custom label prefix in authenticator app
511
558
@@ -522,7 +569,7 @@ If you want to have custom label prefix for some reason:
522
569
],
523
570
```
524
571
525
-
## Passkeys setup
572
+
## Passkeys setup (WebAuthn) alongside TOTP
526
573
527
574
If you want to use both passkeys and TOTP simultaneously, you can set them up as follows:
0 commit comments