adaptiveauth-client
v1.0.0
Published
Production-ready JavaScript client library for AdaptiveAuth framework with risk-based authentication
Downloads
20
Maintainers
Readme
AdaptiveAuth JavaScript Client Library
The official JavaScript client library for the AdaptiveAuth framework. This library provides a comprehensive set of tools for integrating risk-based authentication into your JavaScript applications.
Table of Contents
- Installation
- Quick Start
- Advanced Usage
- Features
- API Reference
- Examples
- Best Practices
- Troubleshooting
- Contributing
- License
Installation
Install the AdaptiveAuth client library using npm:
npm install @adaptiveauth/clientOr using yarn:
yarn add @adaptiveauth/clientCDN Usage
For direct browser usage without a build process:
<!-- Latest version -->
<script src="https://cdn.jsdelivr.net/npm/@adaptiveauth/client@latest/dist/adaptiveauth-client.min.js"></script>
<!-- Or specific version -->
<script src="https://unpkg.com/@adaptiveauth/[email protected]/dist/adaptiveauth-client.min.js"></script>Quick Start
ES6 Import (Recommended)
import AdaptiveAuthClient from '@adaptiveauth/client';
// Initialize the client
const auth = new AdaptiveAuthClient({
baseURL: 'https://your-adaptiveauth-backend.com', // Your AdaptiveAuth backend URL
onRiskAlert: (riskLevel, message) => {
console.log(`Risk Alert: ${riskLevel} - ${message}`);
// Handle risk alerts (show notifications, warnings, etc.)
},
tokenStorage: 'localStorage' // 'localStorage' or 'sessionStorage'
});Browser Global
<script src="https://cdn.jsdelivr.net/npm/@adaptiveauth/client/dist/adaptiveauth-client.min.js"></script>
<script>
const auth = new window.AdaptiveAuthClient({
baseURL: 'https://your-adaptiveauth-backend.com'
});
</script>Destructuring Import
import { AdaptiveAuthClient } from '@adaptiveauth/client';
const auth = new AdaptiveAuthClient({
baseURL: 'https://your-adaptiveauth-backend.com'
});Advanced Usage
Production Configuration
import AdaptiveAuthClient from '@adaptiveauth/client';
const auth = new AdaptiveAuthClient({
baseURL: process.env.REACT_APP_ADAPTIVEAUTH_URL || 'https://api.yourdomain.com',
onRiskAlert: (riskLevel, message) => {
// In production, you might want to send this to your analytics service
console.warn(`Security Alert: ${riskLevel} - ${message}`);
// Show user-friendly notification
showNotification(message, 'warning');
},
tokenStorage: 'localStorage' // Use 'sessionStorage' for session-only tokens
});React Hook Example
import { useState, useEffect } from 'react';
import AdaptiveAuthClient from '@adaptiveauth/client';
// Custom hook for authentication
export function useAdaptiveAuth() {
const [auth, setAuth] = useState(null);
const [user, setUser] = useState(null);
const [loading, setLoading] = useState(true);
useEffect(() => {
const adaptiveAuth = new AdaptiveAuthClient({
baseURL: process.env.REACT_APP_API_URL,
onRiskAlert: (level, message) => {
console.log(`Risk: ${level}`, message);
}
});
setAuth(adaptiveAuth);
// Check if user is already logged in
const checkAuth = async () => {
try {
const profile = await adaptiveAuth.getProfile();
setUser(profile);
} catch (error) {
// User not authenticated
setUser(null);
} finally {
setLoading(false);
}
};
checkAuth();
}, []);
return { auth, user, loading };
}Features
The AdaptiveAuth JavaScript client provides comprehensive authentication capabilities:
- Standard Authentication: Traditional username/password authentication
- Risk-Based Authentication: Adaptive authentication based on risk assessment
- Multi-Factor Authentication (2FA): Support for TOTP and SMS-based 2FA
- Password Management: Forgot password, reset password, and change password flows
- Session Management: Session verification and revocation
- Device Trust: Device fingerprinting and trust management
- User Profile Management: Update user information and security settings
- Risk Assessment: Real-time risk evaluation and monitoring
- Cross-Platform Support: Works in browsers, Node.js, and mobile apps
- Tree-Shakable: Only import what you need to reduce bundle size
- TypeScript Support: Full TypeScript definitions included
API Reference
Constructor Options
baseURL(string): The base URL of your AdaptiveAuth backend (default: 'http://localhost:8000')onRiskAlert(function): Callback function triggered when a risk is detected (default: () => {})tokenStorage(string): Where to store authentication tokens ('localStorage' or 'sessionStorage', default: 'localStorage')
Authentication Methods
register(userData)
Register a new user.
const userData = {
email: '[email protected]',
password: 'SecurePassword123',
full_name: 'John Doe'
};
try {
const result = await auth.register(userData);
console.log('Registration successful:', result);
} catch (error) {
console.error('Registration failed:', error);
}login(credentials)
Standard login with username and password.
const credentials = {
email: '[email protected]',
password: 'SecurePassword123'
};
try {
const result = await auth.login(credentials);
console.log('Login successful:', result);
} catch (error) {
console.error('Login failed:', error);
}adaptiveLogin(email, password)
Risk-based adaptive login that assesses the security context.
try {
const result = await auth.adaptiveLogin('[email protected]', 'SecurePassword123');
console.log('Adaptive login result:', result);
} catch (error) {
console.error('Adaptive login failed:', error);
}loginWithOTP(email, otp)
Login using TOTP code only (for 2FA-enabled users).
try {
const result = await auth.loginWithOTP('[email protected]', '123456');
console.log('OTP login successful:', result);
} catch (error) {
console.error('OTP login failed:', error);
}verifyStepUp(challengeId, code)
Complete a step-up authentication challenge.
try {
const result = await auth.verifyStepUp('challenge-id', '123456');
console.log('Step-up verification successful:', result);
} catch (error) {
console.error('Step-up verification failed:', error);
}forgotPassword(email)
Request a password reset.
try {
const result = await auth.forgotPassword('[email protected]');
console.log('Password reset request sent:', result);
} catch (error) {
console.error('Password reset request failed:', error);
}resetPassword(resetToken, newPassword, confirmPassword)
Reset password using a reset token.
try {
const result = await auth.resetPassword('reset-token', 'NewSecurePassword123', 'NewSecurePassword123');
console.log('Password reset successful:', result);
} catch (error) {
console.error('Password reset failed:', error);
}User Management Methods
getProfile()
Get the current user's profile.
try {
const profile = await auth.getProfile();
console.log('User profile:', profile);
} catch (error) {
console.error('Failed to get profile:', error);
}updateProfile(fullName, email)
Update the current user's profile.
try {
const result = await auth.updateProfile('New Full Name', '[email protected]');
console.log('Profile updated:', result);
} catch (error) {
console.error('Profile update failed:', error);
}getSecuritySettings()
Get the current user's security settings.
try {
const settings = await auth.getSecuritySettings();
console.log('Security settings:', settings);
} catch (error) {
console.error('Failed to get security settings:', error);
}changePassword(currentPassword, newPassword, confirmPassword)
Change the current user's password.
try {
const result = await auth.changePassword('oldPassword', 'newPassword123', 'newPassword123');
console.log('Password changed successfully:', result);
} catch (error) {
console.error('Password change failed:', error);
}getDevices()
Get the current user's known devices.
try {
const devices = await auth.getDevices();
console.log('Known devices:', devices);
} catch (error) {
console.error('Failed to get devices:', error);
}removeDevice(deviceId)
Remove a known device.
try {
const result = await auth.removeDevice('device-id');
console.log('Device removed:', result);
} catch (error) {
console.error('Device removal failed:', error);
}getSessions()
Get the current user's active sessions.
try {
const sessions = await auth.getSessions();
console.log('Active sessions:', sessions);
} catch (error) {
console.error('Failed to get sessions:', error);
}revokeSessions(sessionIds, revokeAll)
Revoke specific sessions or all sessions.
// Revoke specific sessions
try {
const result = await auth.revokeSessions([1, 2, 3]);
console.log('Sessions revoked:', result);
} catch (error) {
console.error('Session revocation failed:', error);
}
// Revoke all sessions
try {
const result = await auth.revokeSessions([], true);
console.log('All sessions revoked:', result);
} catch (error) {
console.error('Session revocation failed:', error);
}getUserRiskProfile()
Get the current user's risk profile summary.
try {
const riskProfile = await auth.getUserRiskProfile();
console.log('Risk profile:', riskProfile);
} catch (error) {
console.error('Failed to get risk profile:', error);
}2FA Methods
enable2FA()
Enable 2FA for the current user.
try {
const result = await auth.enable2FA();
console.log('2FA setup initiated:', result);
// Display QR code to user: result.qr_code
// Store backup codes: result.backup_codes
} catch (error) {
console.error('Failed to enable 2FA:', error);
}verify2FA(code)
Verify and activate 2FA.
try {
const result = await auth.verify2FA('123456');
console.log('2FA activated:', result);
} catch (error) {
console.error('2FA verification failed:', error);
}disable2FA(password)
Disable 2FA for the current user.
try {
const result = await auth.disable2FA('current-password');
console.log('2FA disabled:', result);
} catch (error) {
console.error('Failed to disable 2FA:', error);
}Risk Assessment Methods
assessRisk()
Assess the current risk level for the authenticated user.
try {
const result = await auth.assessRisk();
console.log('Risk assessment:', result);
} catch (error) {
console.error('Risk assessment failed:', error);
}verifySession()
Verify that the current session is still valid and not compromised.
try {
const result = await auth.verifySession();
console.log('Session verification:', result);
} catch (error) {
console.error('Session verification failed:', error);
}requestChallenge(challengeType, sessionId)
Request a new authentication challenge for step-up authentication.
try {
const result = await auth.requestChallenge('email'); // or 'otp' or 'sms'
console.log('Challenge requested:', result);
} catch (error) {
console.error('Challenge request failed:', error);
}verifyChallenge(challengeId, code)
Verify a step-up authentication challenge.
try {
const result = await auth.verifyChallenge('challenge-id', '123456');
console.log('Challenge verified:', result);
} catch (error) {
console.error('Challenge verification failed:', error);
}trustCurrentDevice()
Mark the current device as trusted.
try {
const result = await auth.trustCurrentDevice();
console.log('Device trusted:', result);
} catch (error) {
console.error('Failed to trust device:', error);
}removeTrustedDevice(deviceIndex)
Remove a device from trusted devices.
try {
const result = await auth.removeTrustedDevice(0); // Index of device to remove
console.log('Trusted device removed:', result);
} catch (error) {
console.error('Failed to remove trusted device:', error);
}Utility Methods
getSecurityStatus()
Get the current security status.
try {
const status = await auth.getSecurityStatus();
console.log('Security status:', status);
} catch (error) {
console.error('Failed to get security status:', error);
}logout()
Log out the current user.
try {
const result = await auth.logout();
console.log('Logged out:', result);
} catch (error) {
console.error('Logout failed:', error);
}Examples
Complete Authentication Flow
import AdaptiveAuthClient from '@adaptiveauth/client';
// Initialize client
const auth = new AdaptiveAuthClient({
baseURL: 'https://your-adaptiveauth-backend.com',
onRiskAlert: (riskLevel, message) => {
alert(`Risk Alert: ${riskLevel} - ${message}`);
}
});
// Registration
try {
const registrationResult = await auth.register({
email: '[email protected]',
password: 'SecurePassword123',
full_name: 'New User'
});
console.log('Registration successful:', registrationResult);
} catch (error) {
console.error('Registration failed:', error);
}
// Adaptive login
try {
const loginResult = await auth.adaptiveLogin('[email protected]', 'SecurePassword123');
if (loginResult.status === 'challenge_required') {
// Handle challenge (e.g., request OTP)
const challengeResult = await auth.requestChallenge('email');
console.log('Challenge sent:', challengeResult);
// Later, verify the challenge
const verifyResult = await auth.verifyChallenge(challengeResult.challenge_id, '123456');
console.log('Challenge verified:', verifyResult);
} else if (loginResult.status === 'success') {
console.log('Login successful:', loginResult);
}
} catch (error) {
console.error('Login failed:', error);
}
// Get user profile
try {
const profile = await auth.getProfile();
console.log('User profile:', profile);
} catch (error) {
console.error('Failed to get profile:', error);
}
// Logout
try {
await auth.logout();
console.log('Successfully logged out');
} catch (error) {
console.error('Logout failed:', error);
}React Component Example
import React, { useState, useEffect } from 'react';
import AdaptiveAuthClient from '@adaptiveauth/client';
function AuthComponent() {
const [auth, setAuth] = useState(null);
const [user, setUser] = useState(null);
const [loading, setLoading] = useState(true);
const [error, setError] = useState(null);
useEffect(() => {
const initializeAuth = () => {
const client = new AdaptiveAuthClient({
baseURL: process.env.REACT_APP_API_URL || 'http://localhost:8000',
onRiskAlert: (level, message) => {
console.warn(`Security Risk: ${level}`, message);
// Show security notification to user
}
});
setAuth(client);
};
initializeAuth();
}, []);
const handleLogin = async (email, password) => {
if (!auth) return;
try {
setLoading(true);
setError(null);
const result = await auth.adaptiveLogin(email, password);
if (result.status === 'success') {
const profile = await auth.getProfile();
setUser(profile);
} else if (result.status === 'challenge_required') {
// Handle 2FA or other challenges
console.log('Challenge required:', result.challenge_type);
} else {
setError(result.message || 'Login failed');
}
} catch (err) {
setError(err.message);
} finally {
setLoading(false);
}
};
const handleLogout = async () => {
if (auth) {
await auth.logout();
setUser(null);
}
};
if (loading) return <div>Loading...</div>;
if (error) return <div>Error: {error}</div>;
return (
<div>
{user ? (
<div>
<h2>Welcome, {user.full_name || user.email}!</h2>
<button onClick={handleLogout}>Logout</button>
</div>
) : (
<LoginForm onLogin={handleLogin} />
)}
</div>
);
}
function LoginForm({ onLogin }) {
const [email, setEmail] = useState('');
const [password, setPassword] = useState('');
const handleSubmit = (e) => {
e.preventDefault();
onLogin(email, password);
};
return (
<form onSubmit={handleSubmit}>
<input
type="email"
value={email}
onChange={(e) => setEmail(e.target.value)}
placeholder="Email"
required
/>
<input
type="password"
value={password}
onChange={(e) => setPassword(e.target.value)}
placeholder="Password"
required
/>
<button type="submit">Login</button>
</form>
);
}Enable and Verify 2FA
// Enable 2FA
try {
const setupResult = await auth.enable2FA();
console.log('2FA setup initiated');
// Display QR code to user
const qrCodeElement = document.getElementById('qr-code');
qrCodeElement.src = setupResult.qr_code;
// Store backup codes securely
console.log('Backup codes:', setupResult.backup_codes);
} catch (error) {
console.error('Failed to enable 2FA:', error);
}
// Verify 2FA
try {
const verifyResult = await auth.verify2FA('123456');
console.log('2FA activated successfully:', verifyResult);
} catch (error) {
console.error('2FA verification failed:', error);
}Best Practices
1. Security
- Always use HTTPS in production
- Store tokens securely (avoid storing sensitive data in localStorage for highly sensitive applications)
- Implement proper error handling
- Sanitize user inputs before sending to the server
- Use environment variables for configuration
2. Error Handling
async function safeApiCall(apiMethod, ...params) {
try {
return await apiMethod.apply(auth, params);
} catch (error) {
console.error('API call failed:', error);
// Check for specific error types
if (error.response?.status === 401) {
// Token might be expired
console.log('Token expired, redirecting to login...');
window.location.href = '/login';
} else if (error.response?.status === 429) {
// Rate limited
alert('Too many requests. Please try again later.');
} else {
// Generic error
alert('An error occurred. Please try again.');
}
throw error;
}
}3. State Management
// Create a wrapper class for better state management
class AuthManager {
constructor() {
this.client = new AdaptiveAuthClient({
baseURL: process.env.API_URL
});
this.user = null;
}
async initialize() {
try {
this.user = await this.client.getProfile();
return true;
} catch (error) {
// User not authenticated
this.user = null;
return false;
}
}
isLoggedIn() {
return !!this.user;
}
getUser() {
return this.user;
}
async login(email, password) {
const result = await this.client.adaptiveLogin(email, password);
if (result.status === 'success') {
this.user = await this.client.getProfile();
}
return result;
}
async logout() {
await this.client.logout();
this.user = null;
}
}
// Usage
const authManager = new AuthManager();
await authManager.initialize();4. Environment Configuration
// config/auth.js
const authConfig = {
development: {
baseURL: 'http://localhost:8000',
tokenStorage: 'localStorage'
},
staging: {
baseURL: process.env.REACT_APP_STAGING_API_URL,
tokenStorage: 'localStorage'
},
production: {
baseURL: process.env.REACT_APP_PROD_API_URL,
tokenStorage: 'localStorage'
}
};
const env = process.env.NODE_ENV || 'development';
export default authConfig[env];Troubleshooting
Common Issues
Issue: "AdaptiveAuthClient is not defined" in browser Solution: Make sure you're including the script before trying to use it, or use proper import syntax.
Issue: CORS errors Solution: Configure your AdaptiveAuth backend to allow your domain in CORS settings.
Issue: Token storage issues Solution: Check that the browser allows localStorage/sessionStorage, and that there's no quota exceeded.
Issue: Network errors Solution: Verify that your baseURL is correct and the server is accessible.
Debugging Tips
- Enable browser developer tools to check network requests
- Check the console for error messages
- Verify your backend is running and accessible
- Ensure proper authentication flow is followed
Development vs Production
// Different configurations for different environments
const auth = new AdaptiveAuthClient({
baseURL: process.env.NODE_ENV === 'production'
? 'https://api.yourdomain.com'
: 'http://localhost:8000',
onRiskAlert: process.env.NODE_ENV === 'production'
? (level, message) => logSecurityEvent(level, message)
: (level, message) => console.log(`Dev Security: ${level} - ${message}`)
});Contributing
We welcome contributions to the AdaptiveAuth JavaScript client library! Please see our contributing guidelines for more information.
Running Examples
To try out the examples in this package:
# Install dependencies
npm install
# Run development server
npm run dev
# Run example
npm run exampleLicense
This project is licensed under the MIT License - see the LICENSE file for details.
For more information about AdaptiveAuth, visit https://adaptiveauth.dev.
