
Security News
Attackers Are Hunting High-Impact Node.js Maintainers in a Coordinated Social Engineering Campaign
Multiple high-impact npm maintainers confirm they have been targeted in the same social engineering campaign that compromised Axios.
adaptiveauth-client
Advanced tools
Production-ready JavaScript client library for AdaptiveAuth framework with risk-based authentication
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.
Install the AdaptiveAuth client library using npm:
npm install @adaptiveauth/client
Or using yarn:
yarn add @adaptiveauth/client
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/client@1.0.0/dist/adaptiveauth-client.min.js"></script>
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'
});
<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>
import { AdaptiveAuthClient } from '@adaptiveauth/client';
const auth = new AdaptiveAuthClient({
baseURL: 'https://your-adaptiveauth-backend.com'
});
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
});
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 };
}
The AdaptiveAuth JavaScript client provides comprehensive authentication capabilities:
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')register(userData)Register a new user.
const userData = {
email: 'user@example.com',
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: 'user@example.com',
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('user@example.com', '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('user@example.com', '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('user@example.com');
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);
}
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', 'newemail@example.com');
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);
}
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);
}
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);
}
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);
}
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: 'newuser@example.com',
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('user@example.com', '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);
}
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 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);
}
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;
}
}
// 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();
// 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];
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.
// 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}`)
});
We welcome contributions to the AdaptiveAuth JavaScript client library! Please see our contributing guidelines for more information.
To try out the examples in this package:
# Install dependencies
npm install
# Run development server
npm run dev
# Run example
npm run example
This project is licensed under the MIT License - see the LICENSE file for details.
For more information about AdaptiveAuth, visit https://adaptiveauth.dev.
FAQs
Production-ready JavaScript client library for AdaptiveAuth framework with risk-based authentication
We found that adaptiveauth-client demonstrated a healthy version release cadence and project activity because the last version was released less than a year ago. It has 1 open source maintainer collaborating on the project.
Did you know?

Socket for GitHub automatically highlights issues in each pull request and monitors the health of all your open source dependencies. Discover the contents of your packages and block harmful activity before you install or update your dependencies.

Security News
Multiple high-impact npm maintainers confirm they have been targeted in the same social engineering campaign that compromised Axios.

Security News
Axios compromise traced to social engineering, showing how attacks on maintainers can bypass controls and expose the broader software supply chain.

Security News
Node.js has paused its bug bounty program after funding ended, removing payouts for vulnerability reports but keeping its security process unchanged.