@ariel/auth-module (1.4.2)
Installation
@ariel:registry=npm install @ariel/auth-module@1.4.2"@ariel/auth-module": "1.4.2"About this package
@ariel/auth-module
A production-ready React authentication module with end-to-end encryption, secure session management, and CSRF protection.
Features
- Secure Authentication - Login, registration, and session management
- End-to-End Encryption - AES-256-CBC encryption with PBKDF2 key derivation (100,000 iterations)
- Master Key System - Password-derived encryption keys for sensitive data
- CSRF Protection - Automatic token management on all requests
- Recovery Kit - Encrypted backup keys for account recovery
- Shared Keys - Resource-based key sharing between users
- Pre-built UI Components - Dark-themed, Tailwind-styled components
Installation
npm install @ariel/auth-module
Peer Dependencies
npm install react react-dom lucide-react
Quick Start
Full-Page Authentication
The simplest way to add authentication to your app:
import { AuthPage } from '@ariel/auth-module';
function App() {
return <AuthPage apiBase="https://api.example.com" />;
}
Custom Integration
For more control, use the AuthProvider and useAuth hook:
import { AuthProvider, useAuth } from '@ariel/auth-module';
function App() {
return (
<AuthProvider apiBase="https://api.example.com">
<MyApp />
</AuthProvider>
);
}
function MyApp() {
const { user, masterKey, login, logout, loading } = useAuth();
if (loading) return <div>Loading...</div>;
if (!user) return <LoginForm />;
return (
<div>
<p>Welcome, {user.name}</p>
<button onClick={logout}>Logout</button>
</div>
);
}
API Reference
useAuth() Hook
Returns the authentication context:
const {
user, // { id, email, name } | null
roles, // string[] - array of role names
masterKey, // Uint8Array - decrypted master key
loading, // boolean
error, // string | null
needsUnlock, // boolean - session needs password to unlock
csrfReady, // boolean - CSRF token initialized
// Methods
register, // (email, password, name) => Promise
login, // (email, password) => Promise
logout, // () => Promise
refreshSession, // () => Promise
createRecoveryKit, // () => Promise<string> - returns base64 recovery key
createSharedKey, // (resourceType, resourceId, keyName) => Promise
setError, // (message) => void
encryptData, // (data) => Promise<{ encrypted, iv }> - encrypt with user's key
decryptData, // (encryptedData) => Promise<any> - decrypt with user's key
// Role Methods
hasRole, // (role: string) => boolean
hasAnyRole, // (roles: string[]) => boolean
isAdmin, // () => boolean
refreshRoles, // () => Promise
changeUserRole, // (userId: string, roleName: string) => Promise
} = useAuth();
api Object
Low-level API client with CSRF protection:
import { api, setApiBase } from '@ariel/auth-module';
// Configure base URL
setApiBase('https://api.example.com');
// Available methods
api.requestVerificationCode(email)
api.verifyCode(email, code)
api.register(data)
api.login(email, password)
api.logout()
api.refresh()
api.me()
api.createRecoveryKit(data)
api.recoverAccount(data)
api.createSharedKey(data)
api.shareKey(data)
api.getInvitations()
api.acceptInvitation(data)
api.getSharedKey(id)
// Role Management
api.getRoles()
api.getUserRoles(userId)
api.getMyRoles()
api.changeUserRole(userId, roleName)
CryptoUtils
Cryptographic utilities using the Web Crypto API:
import { CryptoUtils } from '@ariel/auth-module';
// Key derivation
const key = await CryptoUtils.deriveKey(password, salt, iterations);
// Encryption/Decryption
const encrypted = await CryptoUtils.encrypt(data, key, iv);
const decrypted = await CryptoUtils.decrypt(encrypted, key, iv);
// Master key operations
const { encrypted, salt, iv } = await CryptoUtils.encryptMasterKey(masterKey, password);
const masterKey = await CryptoUtils.decryptMasterKey(encrypted, salt, iv, password);
// Utilities
CryptoUtils.generateRandomBytes(length)
CryptoUtils.arrayToBase64(arr)
CryptoUtils.base64ToArray(b64)
CryptoUtils.hashSHA256(data)
SecureStorage
Encrypted session storage:
import { SecureStorage } from '@ariel/auth-module';
const storage = new SecureStorage();
await storage.init(password);
storage.set('key', { sensitive: 'data' });
const data = storage.get('key');
storage.clear();
Components
Pre-built UI Components
| Component | Description |
|---|---|
AuthPage |
Full-page authentication wrapper |
AuthContent |
State-based view router |
LoginForm |
Email/password login form |
RegisterForm |
Registration with email verification |
UnlockScreen |
Password prompt for locked sessions |
Dashboard |
Post-login dashboard view |
LoadingScreen |
Loading spinner |
Input |
Styled input field |
Button |
Styled button |
Alert |
Error/info alerts |
RequireRole |
Conditionally render based on user role |
AdminOnly |
Render only for admin users |
Example: Custom Login Page
import { AuthProvider, LoginForm, RegisterForm } from '@ariel/auth-module';
import { useState } from 'react';
function CustomAuthPage() {
const [isLogin, setIsLogin] = useState(true);
return (
<AuthProvider apiBase="https://api.example.com">
<div className="auth-container">
{isLogin ? <LoginForm /> : <RegisterForm />}
<button onClick={() => setIsLogin(!isLogin)}>
{isLogin ? 'Need an account?' : 'Already have an account?'}
</button>
</div>
</AuthProvider>
);
}
Role Management
The auth module supports role-based access control for managing user permissions.
Role Check Helpers
import { useAuth } from '@ariel/auth-module';
function MyComponent() {
const { user, roles, isAdmin, hasRole, hasAnyRole } = useAuth();
return (
<div>
<p>User: {user?.email}</p>
<p>Roles: {roles.join(', ')}</p>
{isAdmin() && <button>Admin Panel</button>}
{hasRole('moderator') && <button>Moderation Tools</button>}
{hasAnyRole(['editor', 'admin']) && <button>Edit Content</button>}
</div>
);
}
Role-Based Components
import { RequireRole, AdminOnly } from '@ariel/auth-module';
function App() {
return (
<div>
{/* Show only to moderators and admins */}
<RequireRole role={['moderator', 'admin']}>
<ModerationPanel />
</RequireRole>
{/* Show only to admins */}
<AdminOnly>
<AdminPanel />
</AdminOnly>
{/* With fallback content */}
<RequireRole role="premium" fallback={<UpgradePrompt />}>
<PremiumFeatures />
</RequireRole>
</div>
);
}
Admin User Management
import { useAuth } from '@ariel/auth-module';
function UserManagement() {
const { changeUserRole, isAdmin } = useAuth();
if (!isAdmin()) return <div>Access Denied</div>;
const handleChangeRole = async (userId, newRole) => {
try {
await changeUserRole(userId, newRole);
alert('Role changed successfully');
} catch (error) {
alert('Failed: ' + error.message);
}
};
return (
<button onClick={() => handleChangeRole('user-123', 'moderator')}>
Promote to Moderator
</button>
);
}
Security Notes
- Frontend role checks are for UI/UX only
- Backend always validates permissions on API calls
- Roles are automatically fetched on login
- Call
refreshRoles()after role changes to sync state
End-to-End Encryption
Encrypt and decrypt sensitive data using the user's master key:
import { useAuth } from '@ariel/auth-module';
function SecureForm() {
const { encryptData, decryptData } = useAuth();
const handleSave = async (sensitiveData) => {
// Encrypt before sending to server
const encrypted = await encryptData({ secret: sensitiveData });
// encrypted = { encrypted: "base64...", iv: "base64..." }
await api.saveToServer(encrypted);
};
const handleLoad = async () => {
// Fetch encrypted data from server
const encrypted = await api.fetchFromServer();
// Decrypt with user's key
const data = await decryptData(encrypted);
// data = { secret: "original value" }
return data;
};
return <form>...</form>;
}
Both functions require the user to be authenticated (master key must be available).
Security
Encryption Flow
- User registers/logs in with email and password
- Server generates and stores an encrypted master key
- Password derives a key via PBKDF2 (SHA-256, 100,000 iterations)
- Master key is decrypted client-side and stored in memory
- Master key encrypts/decrypts sensitive user data
- Session refresh maintains authentication without re-entering password
Key Security Features
- PBKDF2 Key Derivation - 100,000 iterations with SHA-256
- AES-256-CBC - Industry-standard symmetric encryption
- CSRF Tokens - Automatic token injection on all requests
- HttpOnly Cookies - Secure session cookie handling
- Zero-Knowledge - Server never sees plaintext master key
Requirements
- HTTPS required in production
- Server must implement CSRF token endpoint at
/auth/csrf-token - Cookies must be configured for cross-origin if API is on different domain
Configuration
AuthProvider Props
<AuthProvider
apiBase="https://api.example.com" // API base URL
>
{children}
</AuthProvider>
NPM Registry
This package is published to a private registry. Configure npm:
# .npmrc
@ariel:registry=https://git.horoboro.com/api/packages/Ariel/npm/
Development
Build
npm run build
Outputs:
dist/index.cjs.js- CommonJS bundledist/index.esm.js- ES Module bundle
Project Structure
auth-module/
├── src/
│ ├── index.js # Main exports
│ ├── AuthProvider.js # Context and hooks
│ ├── AuthPage.js # Full-page component
│ ├── api.js # HTTP client
│ ├── crypto.js # Encryption utilities
│ └── components/ # UI components
├── dist/ # Build output
├── package.json
└── rollup.config.mjs
License
Private - All rights reserved.
Dependencies
Development Dependencies
| ID | Version |
|---|---|
| @babel/core | ^7.24.0 |
| @babel/preset-env | ^7.24.0 |
| @babel/preset-react | ^7.24.0 |
| @rollup/plugin-babel | ^6.0.4 |
| @rollup/plugin-node-resolve | ^15.3.0 |
| rollup | ^4.24.0 |
| rollup-plugin-peer-deps-external | ^2.2.4 |
Peer Dependencies
| ID | Version |
|---|---|
| lucide-react | >=0.200.0 |
| react | >=17.0.0 |
| react-dom | >=17.0.0 |