0.0.2 • Published 13 days ago

next-otp v0.0.2

Weekly downloads
-
License
MIT
Repository
github
Last release
13 days ago

Next OTP

Revolutionize password recovery with Next OTP: Secure, seamless, and lightning-fast password resets using one-time passwords in Next.js

Key Features

  1. OTP Generation: The package provides utilities to generate secure one-time passwords (OTPs) in compliance with industry standards, ensuring robust security for password reset requests.

  2. Backend Integration: It seamlessly integrates with backend APIs to send OTPs securely for verification and password reset requests. The package abstracts away the complexities of API interactions, making integration straightforward.

  3. User-friendly Interfaces: The package offers user-friendly interfaces for initiating password reset requests, entering OTPs, and setting new passwords. These interfaces are designed to provide an intuitive experience for users throughout the password reset process.

  4. Customizable Configuration: It offers customizable configuration options to adapt to various backend environments and requirements. Developers can configure API endpoints, request payloads, and error handling mechanisms to suit their specific use cases.

Installation

You can install this package via npm or yarn:

npm install next-otp
# or
yarn add next-otp
# or
pnpm add next-otp

Components

  • OTPSender
  • InputOTP
  • ResetPassword

Example With Next API Routes

OTPSender:

The OTPSender component is responsible for generating a 6-digit OTP and sending it to the user's email. It accepts props specifying the server action (an API route or function), the API URL, the URL after sending the email, and an optional side image URL

Usage Example

The following is the usage example of OTPSender

import OTPSender from "next-otp";

const ForgetPasswordPage = () => {
  return (
    <>
      // @params serverAction - server action must be a function that take to
      @params of email and otp // @params apiUrl - api route must be a function
      that take to @params of email and otp // @params afterSendingEmailUrl - it
      is actually the url of your otpInput page // @params sideImageUrl - it is
      the path of image that you want alongside the the email Component
      <OTPSender
        apiUrl="/api/send-email"
        afterSendingEmailUrl="/otp"
        sideImageUrl="/image/1.png"
      />
    </>
  );
};

export default ForgetPasswordPage;

API Route :

The API route is responsible for sending the OTP email to the user. It receives the email and OTP from the request body and sends the email using the Resend library.

/api/dens - email / route.ts;

import { NextRequest, NextResponse } from "next/server";
import { Resend } from "resend";

const resend = new Resend(process.env.RESEND_API_KEY);
export async function POST(req: NextRequest) {
  const { email, otp } = await req.json();

  try {
    await resend.emails.send({
      from: "onboarding@resend.dev",
      to: email,
      subject: "Password Reset OTP",
      html: `<h1>Please find your OTP for reset password the OTP: ${otp}</h1>`,
    });

    return NextResponse.json(
      {
        message: "Email sent successfully",
        success: true,
      },
      {
        status: 200,
      }
    );
  } catch (error) {
    return { success: false, error };
  }
}

InputOTP:

This Will automatically match the otp that send to the the user email

Usage

import InputOTP from "next-otp"
import { sendEmail } from "@/lib/actions"

const OTPPage = () => {
  return (
    <>

    // @params afterVerifyOTPUrl - it is actually the url of your password reset component page
     <InputOTP
     afterVerifyOTPUrl="/reset-password"

     />

  )
}

export default OTPPage

ResetPassword:

The ResetPassword component is responsible for resetting the password based on the user's email. Password validation and toast notifications are provided out of the box.

Usage

import ResetPassword from "next-otp";

const ForgetPasswordPage = () => {
  return (
    <>
      // @params serverAction - server action must be a function that takes @params of email , password ,conformPassword 
      // @params apiUrl - api route must be a function that takes @params of email , password ,conformPassword
      // @params afterResetPasswordUrl - it is actually the url of your login page
      // @params sideImageUrl - it is the path of image that you want alongside the the reset password inputs
      <ResetPassword
        apiUrl="/api/reset-password"
        afterResetPasswordUrl="/login"
        sideImageUrl="/image/1.png"
      />
    </>
  );
};

export default ForgetPasswordPage;

middleware.ts :

// middleware.ts (at the root of your project)

import { NextRequest, NextResponse } from "next/server";

export function middleware(request: NextRequest) {
  const { pathname } = request.nextUrl;

  // Check for restricted routes (modify as needed)
  const restrictedRoutes = ["/otp", "/reset-password"];
  const isRestrictedRoute = restrictedRoutes.some((route) =>
    pathname.startsWith(route)
  );

  // Check if user is authenticated (replace with your authentication logic)
  const isAuthenticated = false; // Replace with your authentication check

  if (isRestrictedRoute && !isAuthenticated) {
    // Redirect to login page or handle differently if not authenticated
    return NextResponse.redirect(new URL("/login", request.url));
  }

  return NextResponse.next();
}

export const config = {
  matcher: ["/"], // Apply middleware to all routes
};

With Server Actions

You can also pass server functions instead of api routes to the components

SendEmail :

The server action the is responsible to send otp to user

"use server";
import { Resend } from "resend";

// send a password reset email to the user via node mailer
const resend = new Resend(process.env.RESEND_API_KEY);
export async function sendEmail({
  email,
  otp,
}: {
  email: string;
  otp: number;
}) {
  try {
    await resend.emails.send({
      from: "onboarding@resend.dev",
      to: email,
      subject: "Password Reset OTP",
      html: `<h1>Please find your OTP for reset password the OTP: ${otp}</h1>`,
    });

    return {
      succes: true,
      message: "Email sent successfully",
    };
  } catch (error) {
    return { success: false, message: "Failed to send email" };
  }
}

You can pass this function to OTPSender Component instead of route url

Example

import OTPSender from "next-otp";
import { sendEmail } from "@/lib/actions";

const ForgetPasswordPage = () => {
  return (
    <>
      // @params serverAction - server action must be a function that take to @params of email and otp 
      // @params apiUrl - api route must be a function that take to @params of email and otp 
      // @params afterSendingEmailUrl - it is actually the url of your otpInput page
      // @params sideImageUrl - it is the path of image that you want alongside the the email Component
      <OTPSender
        serverAction={sendEmail}
        afterSendingEmailUrl="/otp"
        sideImageUrl="/image/1.png"
      />
    </>
  );
};

export default ForgetPasswordPage;

You can same pass serverAction to the ResetPassword Component