UNPKG

dphelper

Version:

dphelper devtools for developers

339 lines (271 loc) 9.76 kB
# biometric WebAuthn and biometric authentication utilities for secure passwordless login using fingerprint, face recognition, and hardware security keys. ## Functions | Function | Description | Example | |----------|-------------|---------| | `isAvailable` | Check if WebAuthn is available | `dphelper.biometric.isAvailable()` | | `getWebAuthnSupport` | Get detailed support info | `dphelper.biometric.getWebAuthnSupport()` | | `isSensorAvailable` | Check specific sensor (fingerprint/face/iris) | `await dphelper.biometric.isSensorAvailable('fingerprint')` | | `register` | Register new credential | `await dphelper.biometric.register('user123', 'example.com')` | | `authenticate` | Authenticate with credential | `await dphelper.biometric.authenticate('user123', 'example.com')` | | `getCredential` | Get stored credential by ID | `dphelper.biometric.getCredential(credentialId)` | | `deleteCredential` | Delete stored credential | `dphelper.biometric.deleteCredential(credentialId)` | | `listCredentials` | List all stored credentials | `dphelper.biometric.listCredentials()` | ## Description Secure biometric authentication module providing: - **WebAuthn/FIDO2** - Industry-standard passwordless authentication - **Platform Authenticators** - Fingerprint, Face ID, Windows Hello - **Cross-platform** - Works with hardware security keys (YubiKey, etc.) - **Credential Management** - Store, retrieve, and delete credentials - **Sensor Detection** - Check availability of specific biometric types ## Usage Examples ### Checking Availability ```javascript // Simple availability check if (dphelper.biometric.isAvailable()) { console.log('Biometric authentication is available!'); } else { console.log('Biometric auth not supported'); } // Get detailed support information const support = dphelper.biometric.getWebAuthnSupport(); console.log(support); // { // supported: true, // platformAuthenticator: true, // hybridTransport: false, // uvToken: false // } // Check specific sensor const hasFingerprint = await dphelper.biometric.isSensorAvailable('fingerprint'); const hasFace = await dphelper.biometric.isSensorAvailable('face'); console.log('Fingerprint:', hasFingerprint, 'Face:', hasFace); ``` ### Registration (Enrolling a Credential) ```javascript // Register a new biometric credential async function registerUser(userId) { if (!dphelper.biometric.isAvailable()) { return { success: false, error: 'WebAuthn not supported' }; } const result = await dphelper.biometric.register( userId, // User ID 'example.com', // Relying Party ID (your domain) 'My App', // Relying Party Name 'john@example.com' // Display name ); if (result.success) { console.log('Registered! Credential ID:', result.credentialId); // Store credentialId in your database for this user } else { console.error('Registration failed:', result.error); } return result; } // Usage const result = await registerUser('user_123'); ``` ### Authentication (Login) ```javascript // Authenticate with stored credential async function loginUser(userId, credentialId) { if (!dphelper.biometric.isAvailable()) { return { success: false, error: 'WebAuthn not supported' }; } const result = await dphelper.biometric.authenticate( userId, // User ID 'example.com', // Relying Party ID credentialId // Optional: specific credential to use ); if (result.success) { console.log('Authentication successful!'); } else { console.error('Authentication failed:', result.error); } return result; } // Usage - login with known credential const result = await loginUser('user_123', 'stored_credential_id'); ``` ### Credential Management ```javascript // List all stored credentials const credentials = dphelper.biometric.listCredentials(); console.log('Stored credentials:', credentials); // Get a specific credential const cred = dphelper.biometric.getCredential('credential_id_123'); console.log('Credential:', cred); // Delete a credential const deleted = dphelper.biometric.deleteCredential('credential_id_123'); console.log('Deleted:', deleted); // After deletion console.log('Remaining:', dphelper.biometric.listCredentials()); ``` ## Advanced Usage ### Complete Authentication System ```javascript class BiometricAuth { constructor(rpId, rpName) { this.rpId = rpId; this.rpName = rpName; this.available = dphelper.biometric.isAvailable(); } async checkSupport() { if (!this.available) { return { supported: false, reason: 'WebAuthn not supported' }; } const support = dphelper.biometric.getWebAuthnSupport(); const fingerprint = await dphelper.biometric.isSensorAvailable('fingerprint'); const face = await dphelper.biometric.isSensorAvailable('face'); return { supported: true, platformAuthenticator: support.platformAuthenticator, fingerprint, face }; } async register(userId, userName) { if (!this.available) { throw new Error('Biometric authentication not available'); } const result = await dphelper.biometric.register( userId, this.rpId, this.rpName, userName ); if (result.success) { // In production: save credentialId to your backend console.log('Biometric registered:', result.credentialId); } return result; } async login(userId, credentialId) { if (!this.available) { throw new Error('Biometric authentication not available'); } return await dphelper.biometric.authenticate( userId, this.rpId, credentialId ); } getStoredCredentials() { return dphelper.biometric.listCredentials(); } removeCredential(credentialId) { return dphelper.biometric.deleteCredential(credentialId); } } // Usage const auth = new BiometricAuth('example.com', 'My Application'); // Check if biometric is available const support = await auth.checkSupport(); if (support.supported) { console.log('Biometric types available:', support); } // Register new user await auth.register('user_123', 'john@example.com'); // Login const loginResult = await auth.login('user_123'); if (loginResult.success) { console.log('Logged in with biometric!'); } ``` ### Passwordless Login Flow ```javascript // Frontend: Initiate passwordless login async function initiatePasswordlessLogin() { // 1. Check if biometric is available if (!dphelper.biometric.isAvailable()) { alert('Please use a supported browser'); return; } // 2. Get available credentials for this user const credentials = dphelper.biometric.listCredentials(); if (credentials.length === 0) { // No credentials - prompt to register const register = confirm('No biometric credentials found. Register now?'); if (register) { await registerNewUser(); } return; } // 3. Attempt authentication with any stored credential for (const credId of credentials) { const result = await dphelper.biometric.authenticate( 'current_user', window.location.hostname, credId ); if (result.success) { // 4. Verify with server await verifyWithServer(credId); return; } } console.log('All credentials failed'); } // Server verification (pseudo-code) async function verifyWithServer(credentialId) { const response = await fetch('/api/auth/verify', { method: 'POST', headers: { 'Content-Type': 'application/json' }, body: JSON.stringify({ credentialId }) }); if (response.ok) { const { token } = await response.json(); localStorage.setItem('auth_token', token); window.location.href = '/dashboard'; } } ``` ### Progressive Registration ```javascript // Offer biometric as an option during existing login async function offerBiometricUpgrade(userId, userName) { const support = await dphelper.biometric.checkSupport(); if (!support.supported) { console.log('Biometric not available on this device'); return; } // Show modal or prompt const shouldRegister = confirm( `Enable ${support.fingerprint ? 'fingerprint' : 'biometric'} login for faster access?` ); if (shouldRegister) { const result = await dphelper.biometric.register( userId, window.location.hostname, 'My App', userName ); if (result.success) { // Save credential to user account await saveCredentialToUser(userId, result.credentialId); alert('Biometric authentication enabled!'); } else { alert('Registration failed: ' + result.error); } } } ``` ## Security Notes ### WebAuthn Security Features - **Public-key cryptography** - Uses asymmetric keys, never transmitted - **User presence** - Requires user action (touch/face) to authenticate - **Platform binding** - Credentials bound to specific device - **Phishing resistance** - Relying Party ID must match exactly ### Best Practices - Always verify authentication on the server side - Store credential IDs in your database, not the credentials themselves - Support multiple credentials per user (different devices) - Provide fallback for unsupported browsers ## Details - **Author:** Dario Passariello - **Version:** 0.0.1 - **Creation Date:** 20260313 - **Last Modified:** 20260313 - **Environment:** Client-side only (browser with WebAuthn support) --- *Automatically generated document*