rauth-provider
Version:
A lightweight, plug-and-play Node.js library for phone number authentication using the Rauth.io reverse verification flow via WhatsApp or SMS.
188 lines (159 loc) • 5.73 kB
JavaScript
/**
* Example usage of the RauthProvider library
*/
const express = require('express');
const jwt = require('jsonwebtoken');
const { RauthProvider } = require('./index');
const app = express();
// Parse JSON bodies
app.use(express.json());
// Initialize RauthProvider
RauthProvider.init({
rauth_api_key: process.env.RAUTH_API_KEY || 'test-api-key',
app_id: process.env.RAUTH_APP_ID || 'test-app-id',
webhook_secret: process.env.RAUTH_WEBHOOK_SECRET || 'test-webhook-secret',
default_session_ttl: 900, // 15 minutes
default_revoked_ttl: 3600, // 1 hour
});
// Webhook endpoint - handles session_created and session_revoked events
app.post('/rauth/webhook', RauthProvider.webhookHandler());
// Health check endpoint
app.get('/rauth/health', async (req, res) => {
try {
const apiHealth = await RauthProvider.checkApiHealth();
res.json({
status: 'healthy',
library: 'rauth-provider',
version: '1.0.0',
stats,
apiHealth
});
} catch (error) {
res.status(500).json({
status: 'error',
error: error.message
});
}
});
// Session verification endpoint
app.post('/api/login', async (req, res) => {
try {
const { sessionToken, userPhone } = req.body;
if (!sessionToken || !userPhone) {
return res.status(400).json({
success: false,
error: 'sessionToken and userPhone are required'
});
}
// Verify session (checks local memory first, then API)
const isVerified = await RauthProvider.verifySession(sessionToken, userPhone);
if (!isVerified) {
return res.status(401).json({
success: false,
error: 'Phone number not verified or session expired'
});
}
// Generate JWT token
const jwtToken = jwt.sign(
{ userPhone, sessionToken },
process.env.JWT_SECRET || 'test-jwt-secret',
{ expiresIn: '24h' }
);
res.json({
success: true,
jwtToken,
user: { phone: userPhone }
});
} catch (error) {
res.status(400).json({
success: false,
error: error.message
});
}
});
// Protected route
app.get('/api/protected', async (req, res) => {
try {
const authHeader = req.headers.authorization;
if (!authHeader || !authHeader.startsWith('Bearer ')) {
return res.status(401).json({
success: false,
error: 'Authorization header required'
});
}
const jwtToken = authHeader.replace('Bearer ', '');
const decoded = jwt.verify(jwtToken, process.env.JWT_SECRET || 'test-jwt-secret');
// Check if session has been revoked (checks local memory first, then API)
const isRevoked = await RauthProvider.isSessionRevoked(decoded.sessionToken);
if (isRevoked) {
return res.status(401).json({
success: false,
error: 'Session revoked. Please log in again.'
});
}
res.json({
success: true,
message: 'Protected route accessed successfully',
user: { phone: decoded.userPhone },
sessionToken: decoded.sessionToken
});
} catch (error) {
res.status(401).json({
success: false,
error: 'Invalid token'
});
}
});
// Test webhook events endpoint (for testing)
app.post('/test/webhook', (req, res) => {
const { event, session_token, phone, ttl, reason } = req.body;
// Simulate webhook events
if (event === 'session_created') {
RauthProvider.createSession(phone, session_token, ttl);
res.json({ success: true, message: 'Session created' });
} else if (event === 'session_revoked') {
RauthProvider.revokeSession(session_token, ttl, reason);
res.json({ success: true, message: 'Session revoked' });
} else {
res.status(400).json({ success: false, error: 'Unknown event' });
}
});
// Start server
const port = process.env.PORT || 3000;
app.listen(port, () => {
console.log(`🚀 RauthProvider Example Server running on port ${port}`);
console.log(`🔍 Health: http://localhost:${port}/health`);
console.log(`🔐 API Endpoints:`);
console.log(` POST /api/login - Verify session`);
console.log(` GET /api/protected - Protected route`);
console.log(` POST /rauth/webhook - Webhook handler`);
console.log(` POST /test/webhook - Test webhook events`);
});
// Example usage in terminal:
/*
# Initialize a session (calls rauth.io API)
curl -X POST http://localhost:3000/api/login/init \
-H "Content-Type: application/json" \
-d '{"phone": "+1234567890"}'
# Response will include session_token and verification links from rauth.io API:
# {
# "success": true,
# "session_token": "api-generated-token",
# "wa_link": "https://wa.me/918888888888?text=fhad-dfsfd-eqwt-l4dt-lueb",
# "qr_image_link": "https://cdn.rauth.io/qr/15523456.png"
# }
# Simulate session creation (testing - for webhook simulation)
curl -X POST http://localhost:3000/test/webhook \
-H "Content-Type: application/json" \
-d '{"event": "session_created", "session_token": "api-generated-token", "phone": "+1234567890", "ttl": 900}'
# Verify session (checks local cache first, then rauth.io API)
curl -X POST http://localhost:3000/api/login \
-H "Content-Type: application/json" \
-d '{"sessionToken": "api-generated-token", "userPhone": "+1234567890"}'
# Access protected route (checks local cache first, then rauth.io API)
curl -X GET http://localhost:3000/api/protected \
-H "Authorization: Bearer your-jwt-token"
# Check health (includes API connectivity)
curl -X GET http://localhost:3000/health
*/
module.exports = app;