UNPKG

@safepassage/sdk

Version:

SafePassage SDK - Lightweight redirect-based age verification

267 lines (214 loc) 7.33 kB
# SafePassage SDK v3.0.0 - Redirect Implementation A lightweight SDK for integrating SafePassage age verification using a simple redirect flow. ## Features - **Ultra-lightweight**: Only 4.9KB minified (1.9KB gzipped) - **Simple integration**: Just 10 lines of code - **Two modes**: Same-tab redirect or new-tab popup - **TypeScript support**: Full type definitions included - **Auto-environment detection**: Works seamlessly in development - **Secure**: Merchant-generated session IDs prevent attacks - **Compliant**: Enforces minimum age of 25 ## Installation ```bash npm install @safepassage/sdk ``` ## Quick Start ```javascript // Initialize SDK const safePassage = new SafePassage({ apiKey: 'sk_live_xxxxx', // Your API key returnUrl: 'https://yoursite.com/verified', cancelUrl: 'https://yoursite.com/cancelled' }); // Generate a session ID (must be UUID v4) const sessionId = crypto.randomUUID(); // Trigger verification safePassage.verify({ sessionId: sessionId, // Required: merchant-generated UUID challengeAge: 25, // Optional: minimum age (25 or higher) verificationMode: 'L1' // Optional: 'L1' or 'L2' }); ``` ## Configuration | Option | Type | Required | Description | |--------|------|----------|-------------| | apiKey | string | Yes | Your API key (sk_live_xxx or sk_test_xxx) | | returnUrl | string | Yes | URL to redirect after successful verification | | cancelUrl | string | Yes | URL to redirect if user cancels | | environment | string | No | 'production', 'staging', or 'development' (auto-detected) | | mode | string | No | 'redirect' (default) or 'new-tab' | | onComplete | function | No | Callback for new-tab mode completion | | onCancel | function | No | Callback for new-tab mode cancellation | | onError | function | No | Error handler | ## Verification Options ```javascript safePassage.verify({ sessionId: 'uuid-v4', // Required: merchant-generated UUID challengeAge: 30, // Optional: min 25 (overrides dashboard setting) verificationMode: 'L2' // Optional: 'L1' or 'L2' (overrides dashboard setting) }); ``` ### Configuration Override Behavior When you pass `challengeAge` or `verificationMode` to the `verify()` method, these values take precedence over your dashboard configuration for that specific verification session: - **No overrides**: Uses your current dashboard settings - **With overrides**: SDK values are used instead of dashboard settings - **Challenge age**: Must be 25 or higher (lower values will be rejected) - **Verification mode**: - `'L1'`: Age estimation with computer vision - `'L2'`: Always requires ID verification Example use cases: ```javascript // Use dashboard defaults safePassage.verify({ sessionId: crypto.randomUUID() }); // Override just challenge age safePassage.verify({ sessionId: crypto.randomUUID(), challengeAge: 30 // Require age 30+ for this session }); // Override just verification mode safePassage.verify({ sessionId: crypto.randomUUID(), verificationMode: 'L2' // Force ID check for this session }); // Override both safePassage.verify({ sessionId: crypto.randomUUID(), challengeAge: 30, verificationMode: 'L2' // ID required for 30+ verification }); ``` ## Modes ### Same-Tab Redirect (Default) User is redirected to SafePassage, then back to your site: ```javascript const safePassage = new SafePassage({ apiKey: 'sk_live_xxxxx', returnUrl: '/age-verified', cancelUrl: '/age-gate' }); safePassage.verify({ sessionId: crypto.randomUUID() }); ``` ### New-Tab Mode Verification opens in a popup window: ```javascript const safePassage = new SafePassage({ apiKey: 'sk_live_xxxxx', returnUrl: '/age-verified', cancelUrl: '/age-gate', mode: 'new-tab', onComplete: (result) => { console.log('Verified:', result.sessionId); // Validate on your server! }, onCancel: () => { console.log('User cancelled'); } }); safePassage.verify({ sessionId: crypto.randomUUID() }); ``` ## Server-Side Validation (Required!) Always validate the session on your server: ```javascript // Node.js example const response = await fetch('https://api.safepassageapp.com/v1/sessions/validate', { method: 'POST', headers: { 'Authorization': 'Bearer sk_live_xxxxx', // Secret key 'Content-Type': 'application/json' }, body: JSON.stringify({ sessionId }) }); const result = await response.json(); if (result.verified && result.estimatedAge >= result.challengeAge) { // Grant access } ``` ## UUID Generation You must generate session IDs on your end. Use the built-in crypto.randomUUID() when available: ```javascript // Modern browsers and Node.js 16+ const sessionId = crypto.randomUUID(); // Fallback for older environments function generateUUID() { return 'xxxxxxxx-xxxx-4xxx-yxxx-xxxxxxxxxxxx'.replace(/[xy]/g, function(c) { const r = Math.random() * 16 | 0; const v = c === 'x' ? r : (r & 0x3 | 0x8); return v.toString(16); }); } ``` ## Complete Example ```html <!DOCTYPE html> <html> <head> <!-- Install via NPM: npm install @safepassage/sdk --> <script src="node_modules/@safepassage/sdk/dist/safepassage.min.js"></script> </head> <body> <button onclick="verifyAge()">Verify Your Age</button> <script> const safePassage = new SafePassage({ apiKey: 'sk_live_xxxxx', returnUrl: window.location.href + '?verified=true', cancelUrl: window.location.href }); function verifyAge() { // Use crypto.randomUUID() if available, otherwise fallback const sessionId = typeof crypto.randomUUID === 'function' ? crypto.randomUUID() : 'xxxxxxxx-xxxx-4xxx-yxxx-xxxxxxxxxxxx'.replace(/[xy]/g, function(c) { const r = Math.random() * 16 | 0; const v = c === 'x' ? r : (r & 0x3 | 0x8); return v.toString(16); }); sessionStorage.setItem('pendingVerification', sessionId); safePassage.verify({ sessionId }); } // Check if returning from verification const urlParams = new URLSearchParams(window.location.search); if (urlParams.get('verified') === 'true') { const sessionId = sessionStorage.getItem('pendingVerification'); // Validate session server-side here console.log('Validate session:', sessionId); } </script> </body> </html> ``` ## TypeScript Full TypeScript support included: ```typescript import { SafePassage, SafePassageConfig } from '@safepassage/sdk'; const config: SafePassageConfig = { apiKey: process.env.SAFEPASSAGE_PUBLIC_KEY!, returnUrl: '/verified', cancelUrl: '/cancelled' }; const safePassage = new SafePassage(config); ``` ## Migration from v2 (iframe) Old iframe approach (1000+ lines): ```javascript // Complex iframe setup... ``` New redirect approach (10 lines): ```javascript const safePassage = new SafePassage({ apiKey: 'sk_live_xxxxx', returnUrl: '/verified', cancelUrl: '/cancelled' }); safePassage.verify({ sessionId: crypto.randomUUID() }); ``` ## Browser Support - Chrome 60+ - Firefox 60+ - Safari 12+ - Edge 79+ - Mobile browsers ## Security Notes 1. Always generate session IDs on the merchant side 2. Validate sessions server-side before granting access 3. Pre-register callback URLs in your dashboard 4. Never expose your secret key (sk_live_xxx)