Package Exports
- rauth-provider
Readme
RauthProvider
A lightweight, plug-and-play Node.js library for phone number authentication using the Rauth.io reverse verification flow via WhatsApp or SMS. It handles everything from session creation to revocation — with real-time webhook updates and Express.js support, all with minimal setup.
✅ Features
📲 Reverse Authentication – Authenticate users via WhatsApp or SMS without sending OTPs
🔐 Session Management – Track sessions, verify tokens, and revoke access automatically
📡 Webhook Support – Listen for number verification and session revocation in real-time
🧩 Plug-and-Play API – Simple, developer-friendly API surface
⚡ Express Middleware – Drop-in Express.js integration
🛡️ Secure by Design – Signature-based verification and session validation
🧠 Smart Caching – In-memory session tracking with fallback to API
🔗 Rauth API Ready – Built to connect seamlessly with the Rauth.io platform
🟪 TypeScript Native – Full TypeScript typings included for modern development
Installation
npm install rauth-providerQuick Start (Hybrid ESM + CommonJS)
ESM / TypeScript (Recommended)
import { RauthProvider } from 'rauth-provider';
const rp = new RauthProvider();
rp.init({
rauth_api_key: process.env.RAUTH_API_KEY,
app_id: process.env.RAUTH_APP_ID,
webhook_secret: process.env.RAUTH_WEBHOOK_SECRET,
});
app.post('/rauth/webhook', rp.webhookHandler());CommonJS (Legacy Node.js)
const { RauthProvider } = require('rauth-provider');
const rp = new RauthProvider();
rp.init({
rauth_api_key: process.env.RAUTH_API_KEY,
app_id: process.env.RAUTH_APP_ID,
webhook_secret: process.env.RAUTH_WEBHOOK_SECRET,
});
app.post('/rauth/webhook', rp.webhookHandler());Note: This package now supports both ESM and CommonJS. Use named imports for ESM/TypeScript, and require for CommonJS.
Usage Examples
ESM / TypeScript (Express + JWT + Webhook)
import express from 'express';
import jwt from 'jsonwebtoken';
import { RauthProvider } from 'rauth-provider';
const app = express();
const rp = new RauthProvider();
rp.init({
rauth_api_key: process.env.RAUTH_API_KEY!,
app_id: process.env.RAUTH_APP_ID!,
webhook_secret: process.env.RAUTH_WEBHOOK_SECRET!,
});
// Webhook endpoint
app.post('/rauth/webhook', rp.webhookHandler());
// Session verification endpoint
app.post('/api/login', async (req, res) => {
const { sessionToken, userPhone } = req.body;
const isVerified = await rp.verifySession(sessionToken, userPhone);
if (!isVerified) {
return res.status(401).json({ error: 'Phone number not verified' });
}
const jwtToken = jwt.sign({ userPhone, sessionToken }, process.env.JWT_SECRET!);
res.json({ jwtToken });
});
// Protected route
app.get('/api/protected', async (req, res) => {
try {
const jwtToken = req.headers.authorization?.replace('Bearer ', '');
const decoded = jwt.verify(jwtToken, process.env.JWT_SECRET!);
const isRevoked = await rp.isSessionRevoked(decoded.sessionToken);
if (isRevoked) {
return res.status(401).json({ error: 'Session revoked. Please log in again.' });
}
res.json({ message: 'Protected route accessed', user: decoded.userPhone });
} catch (error) {
res.status(401).json({ error: 'Invalid token' });
}
});
app.listen(3000, () => {
console.log('Server running on port 3000');
});CommonJS (Express + JWT + Webhook)
const express = require('express');
const jwt = require('jsonwebtoken');
const { RauthProvider } = require('rauth-provider');
const app = express();
const rp = new RauthProvider();
rp.init({
rauth_api_key: process.env.RAUTH_API_KEY,
app_id: process.env.RAUTH_APP_ID,
webhook_secret: process.env.RAUTH_WEBHOOK_SECRET,
});
// Webhook endpoint
app.post('/rauth/webhook', rp.webhookHandler());
// Session verification endpoint
app.post('/api/login', async (req, res) => {
const { sessionToken, userPhone } = req.body;
const isVerified = await rp.verifySession(sessionToken, userPhone);
if (!isVerified) {
return res.status(401).json({ error: 'Phone number not verified' });
}
const jwtToken = jwt.sign({ userPhone, sessionToken }, process.env.JWT_SECRET);
res.json({ jwtToken });
});
// Protected route
app.get('/api/protected', async (req, res) => {
try {
const jwtToken = req.headers.authorization?.replace('Bearer ', '');
const decoded = jwt.verify(jwtToken, process.env.JWT_SECRET);
const isRevoked = await rp.isSessionRevoked(decoded.sessionToken);
if (isRevoked) {
return res.status(401).json({ error: 'Session revoked. Please log in again.' });
}
res.json({ message: 'Protected route accessed', user: decoded.userPhone });
} catch (error) {
res.status(401).json({ error: 'Invalid token' });
}
});
app.listen(3000, () => {
console.log('Server running on port 3000');
});API Reference
new RauthProvider()
Create a new instance of the provider.
rp.init(options)
Initialize the RauthProvider with configuration options.
rp.init({
rauth_api_key: 'your-api-key',
app_id: 'your-app-id',
webhook_secret: 'your-webhook-secret',
default_session_ttl: 900, // 15 minutes (optional)
default_revoked_ttl: 3600, // 1 hour (optional)
});rp.verifySession(sessionToken, userPhone)
Verify if a session is valid and matches the phone number.
const isValid = await rp.verifySession('session-token', '+1234567890');
// Returns: Promise<boolean>rp.isSessionRevoked(sessionToken)
Check if a session has been revoked.
const isRevoked = await rp.isSessionRevoked('session-token');
// Returns: Promise<boolean>rp.checkApiHealth()
Check if the rauth.io API is reachable.
const isHealthy = await rp.checkApiHealth();
// Returns: Promise<boolean>rp.webhookHandler()
Returns Express middleware to handle webhook events.
app.post('/rauth/webhook', rp.webhookHandler());Environment Variables
Create a .env file with the following variables:
RAUTH_API_KEY=your-rauth-api-key
RAUTH_APP_ID=your-app-id
RAUTH_WEBHOOK_SECRET=your-webhook-secret
JWT_SECRET=your-jwt-secretError Handling
The library provides detailed error messages:
try {
rp.init({
// missing required fields
});
} catch (error) {
console.error(error.message);
// "RauthProvider.init(): Missing required fields: rauth_api_key, app_id, webhook_secret"
}Hybrid Compatibility
- ESM/TypeScript: Use named imports (
import { RauthProvider } from 'rauth-provider'). - CommonJS: Use require destructuring (
const { RauthProvider } = require('rauth-provider')). - All features and API are identical in both modes.