otp-authentication
v0.1.2
Published
Typed package that allows the for the generation, sending and verifying an OTP token
Downloads
8
Maintainers
Readme
OTP Authentication
This package simplifies the integration of one-time password (OTP) functionality into your Node.js project. It consists of three main components:
- OTP Generator: Generates one-time passwords.
- Cache Service: Manages the storage of OTPs.
- Delivery Service: Sends OTPs via email or SMS.
By default, it utilizes the otp-generator package for OTP generation, Redis for caching, and Nodemailer and Twilio for email and SMS delivery, respectively. However, you can also implement custom solutions using abstract classes provided.
Content
Installation
npm install otp-authentication
Configuration
The default configuration includes settings for Nodemailer, Twilio, and Redis. For Nodemailer and Twilio, additional properties are available for email and SMS body templates, as explained below.
EmailOTPAuthentication
class EmailOTPAuthentication extends OTPAuthentication {
constructor(redisOptions: RedisCacheServiceOptions, deliveryServiceOptions: {
nodemailerOptions: NodemailerDeliveryServiceOptions;
mailOptions: MailOptions;
});
}
The default implementation for email delivery uses the otp-generator
package to generate the OTP code, the Redis
package for the cache service and the Nodemailer
package as the delivery service.
Cache Service Configuration
type RedisCacheServiceOptions = RedisClientOptions<RedisModules, RedisFunctions, RedisScripts> & {
prefix?: string;
};
You can configure the cache service using default Redis settings, with an optional prefix for keys
Delivery Service Configuration
type NodemailerDeliveryServiceOptions = SMTPTransport.Options;
Configuration for Nodemailer follows its default settings.
type MailOptions = {
from: string;
subject: string;
html: string;
text?: string;
};
Mail options are used to construct the email that will be sent.
| Property | Description |
| -------: | :--------------------------------------------------------------------------------------------- |
| from | The sender's email address. Example: Carlos Pinho <[email protected]>
|
| subject | The email subject. |
| html | HTML template where {{otp}}
or {{OTP}}
will be replaced with the generated OTP code. |
| text | Plain text template where {{otp}}
or {{OTP}}
will be replaced with the generated OTP code. |
Example
const otpAuth = new EmailOTPAuthentication(
{
socket: {
host: Env.REDIS.HOST,
port: Env.REDIS.PORT,
},
},
{
nodemailerOptions: {
host: Env.SMTP.HOST,
port: Env.SMTP.PORT,
secure: Env.SMTP.PORT === 465,
auth: {
user: Env.SMTP.AUTH.USER,
pass: Env.SMTP.AUTH.PASS,
},
},
mailOptions: {
from: 'Carlos Pinho <[email protected]>',
subject: 'OTP Code',
html: '<b>OTP:</b> {{OTP}}',
text: 'OTP: {{otp}}',
},
},
);
SMSOTPAuthentication
class SMSOTPAuthentication extends OTPAuthentication {
constructor(redisOptions: RedisCacheServiceOptions, deliveryServiceOptions: {
accountSid: string;
authToken: string;
opts: TwilioOpts;
});
}
The default implementation for SMS delivery uses the otp-generator
package to generate the OTP code, the Redis
package for the cache service and the Twilio
package as the delivery service.
Cache Service Configuration
type RedisCacheServiceOptions = RedisClientOptions<RedisModules, RedisFunctions, RedisScripts> & {
prefix?: string;
};
The cache service configuration follows default Redis settings with an optional key prefix.
Delivery Service Configuration
type TwilioOpts = ClientOpts & InnerOpts;
The delivery service configuration uses the default configuration of the Twilio
package. Therefor the accountSid
and authToken
properties are related with the Twilio
package.
type InnerOpts = {
smsTemplate: string;
from: string;
};
The inner options are used to construct how and were the SMS is sent..
| Property | Description |
| ----------: | :--------------------------------------------------------------------------------------------- |
| smsTemplate | Plain text template where {{otp}}
or {{OTP}}
will be replaced with the generated OTP code. |
| from | The SMS sender's number. |
Example
import { SMSOTPAuthentication } from 'otp-authentication';
const otpAuth = new SMSOTPAuthentication(
{
socket: {
host: Env.REDIS.HOST,
port: Env.REDIS.PORT,
},
},
{
accountSid: Env.TWILIO.ACCOUNT_SID,
authToken: Env.TWILIO.AUTH_TOKEN,
opts: {
smsTemplate: 'OTP: {{otp}}',
from: '+12563848581',
},
},
);
Usage
Below is an example of how to use this package in an Express.js
application, regardless on the chosen implementation.
Request OTP code
Method signature:
request(to: string, ttl?: number) => Promise<void>;
The cache Time-To-Live (TTL) can be leveraged as a security measure for expiring OTPs. By setting an appropriate TTL, you can ensure that OTPs become invalid after a certain period, enhancing the security of your authentication system.
Example
app.post('/api/auth', async (req, resp) => {
const {
body: { to },
} = req;
if (typeof to !== 'string') {
return resp.status(400).send({ error: 'to string is mandatory' });
}
await otpAuth.request(to);
return resp.sendStatus(200);
});
Verify OTP code
Method signature:
verify(to: string, otp: string) => Promise<boolean>;
Example
app.post('/api/auth/verify', async (req, resp) => {
const {
body: { to, otp },
} = req;
if (typeof to !== 'string') {
return resp.status(400).send({ error: 'to string is mandatory' });
}
if (typeof otp !== 'string') {
return resp.status(400).send({ error: 'OTP string is mandatory' });
}
const verified = await otpAuth.verify(to, otp);
if (!verified) {
return resp.status(401).send({ error: 'Invalid OTP' });
}
return resp.status(200).send({
access: 'access-token',
refres: 'refresh-token',
});
});