Support Two Factor Authentication (2FA) in your application with ease.
Create and verify cryptographically secure Time-based One-time Passwords
(TOTP) using the HMAC-based One-time Password (HOTP) algorithm.
npm install @epic-web/totp
The problem
You want to support 2FA clients or generate safe one-time passwords to otherwise
verify your users.
This solution
This was copy/paste/modified/tested from notp (MIT)
The primary motivation was to support a more secure algorithm than SHA1
(though Google Authenticator only supports SHA1
, longer-lived OTPs should use
a more secure algorithm). The maintainer has not actively responded to issues or
pull requests in years.
Some improvements were made to modernize the code (which was last published
in 2014) and improve the API. But the core algorithm is unchanged.
Terms
- OTP: One Time Password
- HOTP: HMAC-based One Time Password
- TOTP: Time-based One Time Password
The TOTP is what we typically use for verification codes. This can be used
for 2FA (two-factor authentication), but also used for email verification,
password reset, etc.
Usage
This package exports three methods:
generateTOTP
- This generates the OTP and returns the config used to
generate it.verifyTOTP
- This verifies the OTP against the config used to generate it.getTOTPAuthUri
- This generates a URI that can be used to add the OTP to an
authenticator app.
2FA code
Here's the typical process for generating a 2FA auth URI (which the user can add
to their authenticator app).
import { generateTOTP, getTOTPAuthUri, verifyTOTP } from '@epic-web/totp'
const { secret, period, digits, algorithm } = generateTOTP()
const uri = getTOTPAuthUri({
period,
digits,
algorithm,
secret,
accountName: user.email,
issuer: 'Your App Name',
})
const code = await getCodeFromUser()
const isValid = verifyTOTP({ otp: code, secret, period, digits, algorithm })
Verification of email/phone number ownership
Here's the typical process for a one-time verification of a user's email/phone
number/etc.:
import { generateTOTP, verifyTOTP } from '@epic-web/totp'
const { otp, secret, digits, period, algorithm } = generateTOTP({
algorithm: 'SHA256',
period: 10 * 60,
})
await sendOtpToUser({
email: user.email,
otp,
secret,
digits,
period,
algorithm,
})
await saveVerificationToDatabase({
secret,
digits,
period,
algorithm,
target: user.email,
})
const code = await getCodeFromUser()
const userCodeConfig = await getVerificationFromDatabase({
target: user.email,
})
const isValid = verifyTOTP({ otp: code, ...userCodeConfig })
if (isValid) {
await deleteVerificationFromDatabase({ target: user.email })
} else {
}
API
This library is built with jsdoc
, so hopefully your editor supports that and
will show you all this stuff, but just in case, here's that:
generateTOTP
verifyTOTP
getTOTPAuthUri
License
MIT