Catalog npm
Back to packageRELEASE DETAILS

1.0.0

npm

2factor-sdk

A TypeScript SDK for sending and validating OTPs with support for rate limiting.

2-factor2-factor-sdk2fa2factor2factor-sdk2factorinauthenticationauthentication-sdkemail-otpotpotp-serviceotp-validationrate-limitingsecuritysms-otptoken-authentication
All keywords (19)
two-factor-apitwo-factor-authentication2factor.in
Published4 Jan 2025
Direct dependencies11
Transitive dependenciesNot calculated

README

Current package documentation

2Factor.in SDK

An sdk for 2Factor.in SMS OTP service with support for rate limiting and built-in validation using Zod.

Installation

npm install 2factor-sdk

Quick Start

  • Go to 2factor , sign up and get the api key.
import { TWOFactor } from '2factor-sdk';

const twofactor = TWOFactor.init({ 
  apiKey: 'YOUR_API_KEY',
  // only when you want to use rate limiting.
  upstashToken: 'YOUR_UPSTASH_TOKEN', // Optional: for rate limiting
  upstashUrl: 'YOUR_UPSTASH_URL' // Optional: for rate limiting
});

// Send OTP
const result = await twofactor.sendOTP({
  phoneNumber: '9XXXXXXXXX',
  templateName: 'Template_Name', //two factor template name (optional)
  interval: '30 s', // Optional: rate limiting interval (default: '30 s')
  limit: 1 // Optional: rate limiting count (default: 1)
});

Validation Rules

If any of the validation fails it will throw an error. Wrap the code in try catch to handle the errors. use handleTFError function to get errors that can be sent to clients.

Phone Number

  • Must be 10 digits
  • Must start with 6, 7, 8, or 9 (Indian phone numbers only).
const response = await twofactor.sendOTP({
  phoneNumber: '9876543210', // Valid format
  templateName: 'Template_Name', // two factor template name (optional)
});

OTP

  • Length: 4-6 digits
  • Must be numeric
const verify = await twofactor.verifyByUID({
  otp: '123456', // Valid 6-digit OTP
  UID: 'session-uid',
});

Rate Limiting

This SDK supports rate limiting using Upstash Redis. To enable rate limiting, provide your Upstash token and URL when initializing the SDK. If these are not provided, rate limiting will not be applied.

To create an Upstash account and get your token and URL, follow these steps:

  1. Go to Upstash and sign up for an account.
  2. Create a new Redis database.
  3. In your database details, you'll find the UPSTASH_REDIS_REST_URL and UPSTASH_REDIS_REST_TOKEN.

You can customize the rate limiting for each method call by providing interval and limit parameters. The default is 1 request per 30 seconds.

const result = await twofactor.sendOTP({
  phoneNumber: '9XXXXXXXXX',
  templateName: 'Template_Name',
  interval: '1 m', // 1 minute
  limit: 5 // 5 requests allowed per minute
});

Error Handling

This sdk has proper support for error handling and will return sanitized errors that we can directly sent to client without exposing other errors.

import { handleTFError, TWOFactor } from '2factor-sdk'

try {
  const response = await client.sendOTP({
    phoneNumber: '9XXXXXXXXX',
    templateName: 'Template_Name'
  });
} catch (error) {
  const handledError = handleTFError(error);
  if (handledError) {
    // return sanitized error to client
  }
}

API Methods

sendOTP()

Generates and sends a random OTP to the specified phone number. Supports both 4-digit and 6-digit OTPs.

const response = await twofactor.sendOTP({
  phoneNumber: "9XXXXXXXXX", // Required: 10-digit number
  // Optional fields
  templateName: "OTP1", // Optional: SMS template
  otpLength: 4, // Optional: 4 or 6 (default: 4)
  interval: "30 s", // Optional: rate limiting interval (default: '30 s')
  limit: 1 // Optional: rate limiting count (default: 1)
});

Returns: { UID: string } - Session UID for verification

sendAndReturnOTP()

Similar to sendOTP but also returns the generated OTP value. Useful for testing or scenarios where you need to know the OTP.

const response = await client.sendAndReturnOTP({
  phoneNumber: "9XXXXXXXXX", // Required: 10-digit number
  // optional fields
  templateName: "OTP1", // Optional: SMS template
  interval: "30 s", // Optional: rate limiting interval (default: '30 s')
  limit: 1 // Optional: rate limiting count (default: 1)
});

Returns: { OTP: string, UID: string } - Both OTP and session UID

sendCustomOTP()

Sends a custom OTP value instead of generating a random one. Useful when you want to control the OTP value.

const response = await twofactor.sendCustomOTP({
  phoneNumber: "9XXXXXXXXX", // Required: 10-digit number
  // optional fields
  templateName: "OTP1", // Optional: SMS template
  otp: "1234", // Required: 4 or 6  digit numeric OTP
  interval: "30 s", // Optional: rate limiting interval (default: '30 s')
  limit: 1 // Optional: rate limiting count (default: 1)
});

Returns: { UID: string } - Session UID for verification

verifyByUID()

Verifies an OTP using the session UID. Most secure method as it validates against a specific session.

const isValid = await client.verifyByUID({
  otp: '1234', // Required: 4-6 digit OTP
  UID: '47dac35a-c9f9-11ef-8b17-0200cd936042', // Required: 36-char session ID
});
if (!isValid)
{
    // throw error
}

Returns: boolean - true if OTP is valid. Undefined if not valid.

verifyByPhone()

Verifies an OTP using the phone number. Alternative verification method when UID is not available.

const isValid = await client.verifyByPhone({
  otp: string, // Required: 4-6 digit OTP
  phoneNumber: string, // Required: 10-digit number
});
if (!isValid)
{
    // throw error
}

Returns: boolean - true if OTP is valid. Undefined if not valid.

Example Usage (With rate limiting).

import express from 'express';
import dotenv from 'dotenv';
import { TWOFactor, handleTFError } from '2factor-sdk';

// Load environment variables
dotenv.config();

const app = express();
const port = process.env.PORT || 3000;

// Initialize TWOFactor client
const tf = TWOFactor.init({
  apiKey: process.env.TWOFACTOR_API_KEY!,
  upstashToken: process.env.UPSTASH_TOKEN,
  upstashUrl: process.env.UPSTASH_URL,
});

// Middleware to parse JSON bodies
app.use(express.json());

// OTP sending endpoint
app.post('/send-otp', async (req, res) => {
  const { phoneNumber } = req.body;

  try {
    // Send OTP
    const result = await tf.sendOTP({
      phoneNumber: phoneNumber,
      limit: 1,
      interval: '30 s'
    });

    return res.json({
      success: true,
      data: result
    });
  } catch (error) {
    // Handle TWOFactor specific errors including validation errors.
    // can be send to client.
    const handledError = handleTFError(error);
    
    if (handledError) {
      return res.status(400).json({
        success: false,
        error: handledError
      });
    }

    // Handle unexpected errors
    console.error('Unexpected error:', error);
    return res.status(500).json({
      success: false,
      error: 'Internal server error'
    });
  }
});

// Start the server
app.listen(port, () => {
  console.log(`OTP API server running on port ${port}`);
});


License

MIT

Support

For support, email fateennisar121@gmail.com or create an issue in the GitHub repository.

Downloads & popularity

Awaiting observations

No metric observations yet

Download counts and popularity will appear here as the collector receives them.

Declared dependencies 11

Native requirements
11 direct targetsNot calculated transitive count
Package / targetRequirementRelationship
tsc
Environment
{
  "local_name": "tsc",
  "alias": false,
  "peer_metadata": null
}
^2.0.4runtime
zod
Environment
{
  "local_name": "zod",
  "alias": false,
  "peer_metadata": null
}
^3.24.1runtime
axios
Environment
{
  "local_name": "axios",
  "alias": false,
  "peer_metadata": null
}
^1.7.9runtime
typescript
Environment
{
  "local_name": "typescript",
  "alias": false,
  "peer_metadata": null
}
^5.7.2runtime
2factor-sdk
Environment
{
  "local_name": "2factor-sdk",
  "alias": false,
  "peer_metadata": null
}
file:2factor-sdk-1.0.0.tgzruntime
@upstash/redis
Environment
{
  "local_name": "@upstash/redis",
  "alias": false,
  "peer_metadata": null
}
^1.34.3runtime
@upstash/ratelimit
Environment
{
  "local_name": "@upstash/ratelimit",
  "alias": false,
  "peer_metadata": null
}
^2.0.5runtime
tsup
Environment
{
  "local_name": "tsup",
  "alias": false,
  "peer_metadata": null
}
^8.0.1development
rimraf
Environment
{
  "local_name": "rimraf",
  "alias": false,
  "peer_metadata": null
}
^6.0.1development
prettier
Environment
{
  "local_name": "prettier",
  "alias": false,
  "peer_metadata": null
}
^3.4.2development
@arethetypeswrong/cli
Environment
{
  "local_name": "@arethetypeswrong/cli",
  "alias": false,
  "peer_metadata": null
}
^0.17.2development

Distribution files

1 collected
Distribution 1

Source distribution

Source file
Checksums from source
{
  "shasum": "1781c16c682e446dc0959a8f2d8457743e9da6e2",
  "tarball": "https://registry.npmjs.org/2factor-sdk/-/2factor-sdk-1.0.0.tgz",
  "fileCount": 6,
  "integrity": "sha512-E3mEHPVHPbab0vIyxfjt/FLmGqzDOm8JaQRG/me6ARink1DQmgSHsioBJCLpR4iAxvwfn/qQhDfb1QbdntBLJQ==",
  "signatures": [
    {
      "sig": "MEUCIQDWnwIcX4hzMt7CYiiBYPVCbdj3NJLSGgEjq6dvIk0X6AIgbZ2uVdOkd9VBogfDW/MgLe4fxH9mZn7iHBwsi1e8IWE=",
      "keyid": "SHA256:jl3bwswu80PjjokCgh0o2w5c2U4LhQAE57gj9cz1kzA"
    }
  ],
  "unpackedSize": 40125
}

Repository

PENDING
fateennisar/2factor

Shared repository data · GitHub

License detected in repository
Not collected

Metadata history

Meaningful changes
Current collected state Current

Observed since 20 Oct, 19:13 UTC

No superseded metadata states collected. Unchanged observations do not create new revisions.

Record identity

package_version:06861ee8e6c4b4bcdb7c5fb584cae647edf7b2fabe30a88ceda7f122ee2ca0b9

Other collected versions

1.0.722 Mar1.0.610 Jan1.0.57 Jan1.0.45 Jan1.0.35 Jan1.0.25 JanView all collected versions →