Urgent.News

What's breaking now, across thousands of outlets.

Tech

Node.js SMS Verification Code: Generating and Sending One-Time Passwords via API Integration

Node.js SMS Verification Code: Generating and Sending One-Time Passwords via API Integration Short answer: use Node.js code to generate one-time passwords locally, send them via a generic SMS API integration, and persist an idempotent attempt record so delivery retries cannot create an ambiguous login. If an SMS OTP protects a marketplace login, treat delivery as a state transition, not a single…

Generating and sending one-time passwords (OTPs) via SMS using Node.js involves creating a cryptographically secure OTP locally, sending it through an SMS API integration, and persisting an idempotent attempt record to avoid ambiguity in login processes. The OTP must be generated with a secure source, stored only as a hashed digest with an expiration time and attempt counter, and accepted exactly once.

The send operation must be idempotent to prevent issues such as creating two valid-looking texts on retry, confusing users, and incurring unnecessary delivery charges.

The integration boundary is crucial in securing the process. An OTP endpoint should be small, with a failure surface that is well-managed. A timeout does not indicate whether the message was accepted, and blindly retrying can lead to sending duplicate texts, user confusion, and additional charges. Instead, a success response should only be returned after the provider has accepted the request. Before this acceptance, the application should return a failure status.

To manage this process effectively, the application should maintain an attempt record that includes a random challenge, a normalized destination, an expiry time, delivery status, and the number of verification failures. This record allows a client-supplied request key to replay the same result for duplicate requests. The provider adapter, responsible for calling the SMS API, should be separated from the account service, which decides whether another send is permissible.

For a marketplace scenario, this boundary also protects a common workflow: a buyer signs in using an OTP, then requests a report of orders or seller activity. The report should be generated separately from the OTP request, ensuring that authentication establishes a session while a queue handles the creation and emailing of the report. Mixing these paths can lead to slow report generation being mistaken for an authentication failure.

The provided TypeScript example demonstrates a small implementation that keeps the provider generic, using `SmsGateway` to wrap an HTTP client for any service that accepts a destination and message. It defines an `OtpAttempt` interface to manage the state of each OTP attempt, including fields for the OTP ID, request ID, destination, hashed digest, expiry time, verification attempts, status, and provider message ID (if applicable).

The `digest` function hashes the OTP code using SHA-256 to ensure security, and the `sameDigest` function compares two digests securely using timing-safe equality. The `issueOtp` function generates a random OTP, creates an attempt record, and attempts to send the OTP through the provided `SmsGateway`. It checks for existing attempts to ensure idempotency and returns the attempt ID and status if an existing attempt is found.

If not, it generates a new OTP, records the attempt, and sends it using the SMS gateway. The example highlights the importance of managing the OTP lifecycle carefully to maintain security and avoid common pitfalls in SMS verification processes.

Written by urgent.news from Dev.to's reporting — not their text. Machine-written — may contain errors; check the original before relying on it.

Read the original at dev.to →

More in Tech

Upgrade MySQL 8.0 to 8.4: What Breaks and How to Check

MySQL 8.0 reached end of life in April 2026, which means no more security fixes from Oracle for the community edition. The supported target is MySQL 8.4, the current long-term support (LTS) release.

  • MySQL 8.0 end of life in April 2026, no more security fixes
  • Upgrade recommended to MySQL 8.4, current long-term support release
  • Upgrade checker in MySQL Shell to identify potential issues before upgrade

Every reveal.js gap closed in Kadal Deck 0.11

Kadal Deck borrowed a lot from reveal.js: sections and vertical stacks, fragments, data-background-* , auto-animate, and option names like controls , hash and slideNumber .

  • Kadal Deck 0.11 closes all gaps compared to reveal.js decks
  • 52 of 54 missing features addressed in 23 pull requests
  • Kadal Deck renders KaTeX equations at build time

More from Monday 2 November →