Two-Factor Authentication Plugin
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.
Installation
npm i @adminforth/two-factors-auth --save
Plugin is already installed into adminforth, to import:
import TwoFactorsAuthPlugin from '@adminforth/two-factors-auth';
Plugin required some additional setup, to make it work properly. It should be added to the resource auth resource. In our example we will add it to the user resource .
model users {
id String @id
created_at DateTime
email String @unique
role String
password_hash String
secret2fa String?
}
Then:
npx --yes prisma migrate dev --name init
And add it to users.ts
{
table: 'users',
plugins: [
new TwoFactorsAuthPlugin ({ twoFaSecretFieldName: 'secret2fa' }),
],
columns: [
...
{
name: 'secret2fa',
showIn: [],
backendOnly: true,
}
],
}
Thats it! Two-Factor Authentication is now enabled:
Disabling Two-Factor Authentication locally
If it is not convenient to enter the code every time you log in during local development, you can disable Two-Factor Authentication
for the dev environment using usersFilterToApply
option.
plugins: [
new TwoFactorsAuthPlugin ({
twoFaSecretFieldName: 'secret2fa',
usersFilterToApply: (adminUser: AdminUser) => {
// if this method returns true, 2FA will be enforced for this user, if returns false - 2FA will be disabled
if (process.env.NODE_ENV === 'development') {
return false;
}
return true;
},
}),
],
Select which users should use Two-Factor Authentication
By default plugin enforces Two-Factor Authentication for all users.
If you wish to enforce 2FA only for specific users, you can again use usersFilterToApply
option:
usersFilterToApply: (adminUser: AdminUser) => {
// disable 2FA for users which email is 'adminforth' or 'adminguest'
return !(['adminforth', 'adminguest'].includes(adminUser.dbUser.email));
},
You can even add a boolean column to the user table to store whether the user should use 2FA or not:
{
resourceId: 'users',
...
columns: [
...
{
name: 'use2fa',
}
...
],
options: {
allowedActions: {
delete: ({ adminUser }: { adminUser: AdminUser }) => {
// only superadmin can delete users
return adminUser.dbUser.role === 'superadmin';
},
create: ({ adminUser }: { adminUser: AdminUser }) => {
// only superadmin can create users
return adminUser.dbUser.role === 'superadmin';
},
edit: ({ adminUser, meta }: { adminUser: AdminUser }) => {
// user can modify only his own record
const { oldRecord } = meta;
return adminUser.dbUser.id === oldRecord.id;
},
}
},
plugins: [
new TwoFactorsAuthPlugin ({
twoFaSecretFieldName: 'secret2fa',
usersFilterToApply: (adminUser: AdminUser) => {
return adminUser.dbUser.use2fa;
},
}),
],
}