UNPKG

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
/** * 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;