• Joined on 2025-04-17

@ariel/auth-module (1.3.0)

Published 2026-02-08 22:20:12 +00:00 by Ariel

Installation

@ariel:registry=
npm install @ariel/auth-module@1.3.0
"@ariel/auth-module": "1.3.0"

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

  1. User registers/logs in with email and password
  2. Server generates and stores an encrypted master key
  3. Password derives a key via PBKDF2 (SHA-256, 100,000 iterations)
  4. Master key is decrypted client-side and stored in memory
  5. Master key encrypts/decrypts sensitive user data
  6. 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 bundle
  • dist/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
Details
npm
2026-02-08 22:20:12 +00:00
1
UNLICENSED
51 KiB
Assets (1)
Versions (7) View all
1.4.2 2026-02-09
1.4.1 2026-02-09
1.4.0 2026-02-09
1.3.0 2026-02-08
1.2.0 2026-02-08