npm package: @proveanything/smartlinks-auth-ui
Description: Lightweight React authentication UI components with bearer token support and Smartlinks SDK integration
Author: Prove Anything
Latest version: 0.4.6

# @smartlinks/auth-ui

A complete, drop-in React authentication and account management solution built for the Smartlinks platform. Provides beautiful, customizable UI components for authentication flows, session management, and user account operations with seamless Smartlinks SDK integration.

## Features

### Authentication
- 🔐 **Multiple Auth Methods**: Email/Password, Google OAuth, Phone/SMS, Magic Links
- 🎨 **Beautiful Pre-built UI**: Professional, responsive authentication flows
- 🪙 **JWT Bearer Tokens**: Automatic Smartlinks SDK integration with bearer token management
- 🗂️ **Session Management**: Built-in AuthProvider, useAuth hook, ProtectedRoute, and cross-tab sync
- 🏢 **Multi-Tenant Support**: Client ID for identifying different systems/tenants
- 📊 **Custom Account Data**: Store custom metadata per user account
- 🔗 **Deep Link Support**: Email verification, password reset, magic link flows
- 📧 **Passwordless Login**: Magic link authentication via email

### Account Management
- 👤 **Profile Management**: Update display name and contact information
- 🔑 **Password Changes**: Secure password update flow for authenticated users
- 📧 **Email Changes**: Change email with verification flow
- 📱 **Phone Updates**: Update phone number with SMS verification
- 🗑️ **Account Deletion**: Self-service account deletion

### Developer Experience
- ⚡ **Lightweight**: Minimal dependencies, integrates with Smartlinks SDK
- 📱 **Fully Responsive**: Works seamlessly on mobile and desktop
- ♿ **Accessible**: WCAG compliant forms and interactions
- 🎨 **Highly Customizable**: Extensive theming and branding options
- 🔄 **Real-time Sync**: Cross-tab authentication state synchronization
- 💾 **Smart Caching**: Account info caching with configurable TTL
- 🎣 **Auth State Callbacks**: Subscribe to login, logout, and token refresh events
- 📘 **TypeScript First**: Full type definitions included

## Installation

```bash
npm install @smartlinks/auth-ui @proveanything/smartlinks
```

**Note**: This package requires the Smartlinks SDK (`@proveanything/smartlinks`) as a peer dependency.

## Quick Start

### 1. Initialize Smartlinks SDK

Initialize the Smartlinks SDK at the top level of your application:

```tsx
// src/App.tsx or src/main.tsx
import * as smartlinks from '@proveanything/smartlinks';

// Initialize the SDK before your app renders
smartlinks.initializeApi({
  baseUrl: 'https://smartlinks.app/api/v1',
  proxyMode: false, // Set to true if running in iframe
});
```

### 2. Import the CSS (Required!)

Add this import to your app's entry point:

```tsx
import '@smartlinks/auth-ui/dist/index.css';
```

**Important**: Without this CSS import, the authentication UI will not be styled correctly.

### 3. Wrap Your App with AuthProvider

```tsx
import { AuthProvider } from '@smartlinks/auth-ui';
import '@smartlinks/auth-ui/dist/index.css';

function App() {
  return (
    <AuthProvider 
      clientId="your-client-123"
      clientName="Acme Corp"
    >
      <YourApp />
    </AuthProvider>
  );
}
```

### 4. Use the Authentication UI

```tsx
import { SmartlinksAuthUI, useAuth } from '@smartlinks/auth-ui';

function YourApp() {
  const { user, isAuthenticated, logout } = useAuth();
  
  if (isAuthenticated) {
    return (
      <div>
        <h1>Welcome, {user?.displayName || user?.email}!</h1>
        <button onClick={logout}>Logout</button>
      </div>
    );
  }
  
  return (
    <SmartlinksAuthUI
      clientId="your-client-123"
      onAuthSuccess={(response) => {
        console.log('Authenticated!', response.user);
        // Optional: redirect or update UI
      }}
    />
  );
}
```

## Components

### SmartlinksAuthUI

Main authentication component with login, registration, password reset, and provider authentication.

#### Props

| Prop | Type | Required | Description |
|------|------|----------|-------------|
| `clientId` | string | **Yes** | Client identifier for your application |
| `clientName` | string | No | Client name for branded emails |
| `accountData` | Record<string, any> | No | Custom metadata to store on registration |
| `onAuthSuccess` | (response: AuthResponse) => void | No | Callback when authentication succeeds |
| `onAuthError` | (error: Error) => void | No | Callback when authentication fails |
| `onRedirect` | (url: string, reason: RedirectReason) => void | No | Callback for navigation after deep-link auth. When provided, disables automatic redirects. |
| `redirectUrl` | string | No | URL to redirect after auth (default: current page) |
| `initialMode` | 'login' \| 'register' | No | Initial view (default: 'login', or 'register' if signupProminence is 'emphasized') |
| `signupProminence` | 'minimal' \| 'balanced' \| 'emphasized' | No | How prominently to feature signup vs login (default: 'minimal') |
| `customization` | AuthUIConfig | No | UI customization (colors, fonts, logo) |

#### Example

```tsx
<SmartlinksAuthUI
  clientId="your-client-123"
  clientName="Acme Corp"
  accountData={{
    companyName: "Acme Corp",
    plan: "enterprise"
  }}
  onAuthSuccess={(response) => {
    console.log('User:', response.user);
    console.log('Token:', response.token);
    console.log('Account Data:', response.accountData);
  }}
  onAuthError={(error) => {
    console.error('Auth error:', error);
  }}
  initialMode="register"
/>
```

### Redirect Handling (`onRedirect`)

By default, after deep-link authentication (email verification, magic link, phone auth), the component performs a direct `window.location.href` redirect. This can cause issues in iframe environments or when you want custom navigation.

The `onRedirect` callback gives the parent app full control over navigation:

```tsx
// React Router integration
<SmartlinksAuthUI
  clientId="your-client-123"
  onAuthSuccess={(token, user) => {
    console.log('Logged in:', user);
  }}
  onRedirect={(url, reason) => {
    console.log(`Auth complete (${reason}), navigating to:`, url);
    navigate(url); // React Router navigation
  }}
/>

// Iframe with postMessage to parent
<SmartlinksAuthUI
  clientId="your-client-123"
  onAuthSuccess={(token, user) => {
    window.parent.postMessage({
      type: 'auth-success',
      payload: { token, user }
    }, '*');
  }}
  onRedirect={(url, reason) => {
    window.parent.postMessage({
      type: 'auth-redirect',
      payload: { url, reason }
    }, '*');
  }}
/>

// Close modal instead of redirect
<SmartlinksAuthUI
  clientId="your-client-123"
  onAuthSuccess={(token, user) => {
    setUser(user);
  }}
  onRedirect={(url, reason) => {
    // Ignore the URL, just close the auth modal
    setShowAuthModal(false);
  }}
/>
```

**RedirectReason values:**
- `'email-verified'` - User clicked email verification link
- `'magic-link'` - User clicked magic link to log in  
- `'phone-verified'` - User completed phone verification

### Signup Prominence

Control how prominently signup is featured vs login using the `signupProminence` prop. This is useful for different user journey contexts:

| Mode | Use Case | Behavior |
|------|----------|----------|
| `minimal` (default) | Returning user access | Login form with small "Sign up" link at bottom |
| `balanced` | General purpose | Equal-weight toggle for "Sign In" / "Create Account" |
| `emphasized` | Product claiming, new users | Signup form with small "Sign in" link at bottom |

#### Examples

**Product Claiming (new users expected):**
```tsx
<SmartlinksAuthUI
  clientId="your-client-123"
  signupProminence="emphasized"
  onAuthSuccess={handleAuth}
/>
```

**Accessing Protected Content (existing users):**
```tsx
<SmartlinksAuthUI
  clientId="your-client-123"
  signupProminence="minimal"
  onAuthSuccess={handleAuth}
/>
```

**General Purpose Portal:**
```tsx
<SmartlinksAuthUI
  clientId="your-client-123"
  signupProminence="balanced"
  onAuthSuccess={handleAuth}
/>
```

### AccountManagement

Account management component for authenticated users to update their profile, change passwords, update contact info, and delete their account.

#### Props

| Prop | Type | Required | Description |
|------|------|----------|-------------|
| `clientId` | string | **Yes** | Client identifier for your application |
| `showHeader` | boolean | No | Show component header (default: false) |
| `onProfileUpdate` | () => void | No | Callback after profile update |
| `onAccountDelete` | () => void | No | Callback after account deletion |

#### Example

```tsx
import { AccountManagement } from '@smartlinks/auth-ui';

<AccountManagement
  clientId="your-client-123"
  onProfileUpdate={() => {
    console.log('Profile updated!');
  }}
  onAccountDelete={() => {
    console.log('Account deleted');
    // Redirect to home or login
  }}
/>
```

## Session Management

### AuthProvider

The AuthProvider component manages authentication state across your application. It handles token persistence, cross-tab synchronization, and automatic token refresh.

#### Props

| Prop | Type | Required | Description |
|------|------|----------|-------------|
| `clientId` | string | **Yes** | Client identifier for your application |
| `clientName` | string | No | Client name for branded communications |
| `accountCacheTTL` | number | No | Account cache TTL in ms (default: 300000 / 5 min) |
| `preloadAccountInfo` | boolean | No | Fetch account info on login (default: false) |

#### Example

```tsx
<AuthProvider 
  clientId="your-client-123"
  clientName="Acme Corp"
  accountCacheTTL={600000} // 10 minutes
  preloadAccountInfo={true}
>
  <App />
</AuthProvider>
```

### useAuth Hook

Access authentication state and methods anywhere in your app:

```tsx
import { useAuth } from '@smartlinks/auth-ui';

function MyComponent() {
  const { 
    user,              // Current user object (email, displayName, uid)
    token,             // Current JWT bearer token
    accountData,       // Custom account metadata
    accountInfo,       // Cached account information
    isAuthenticated,   // Boolean auth status
    isLoading,         // Loading state
    login,             // Manual login function
    logout,            // Logout function
    getToken,          // Get current token
    getAccount,        // Fetch account info (uses cache)
    refreshAccount,    // Force refresh account info
  } = useAuth();
  
  return (
    <div>
      {isAuthenticated ? (
        <p>Welcome, {user.displayName}!</p>
      ) : (
        <p>Please log in</p>
      )}
    </div>
  );
}
```

### ProtectedRoute

Protect routes that require authentication:

```tsx
import { ProtectedRoute } from '@smartlinks/auth-ui';

<ProtectedRoute 
  fallback={<LoginPage />}
  redirectTo="/login"
>
  <DashboardPage />
</ProtectedRoute>
```

### Auth State Change Callbacks

Subscribe to authentication events:

```tsx
import { onAuthStateChange } from '@smartlinks/auth-ui';

useEffect(() => {
  const unsubscribe = onAuthStateChange((event, session) => {
    switch (event) {
      case 'LOGIN':
        console.log('User logged in:', session.user);
        navigate('/dashboard');
        break;
      case 'LOGOUT':
        console.log('User logged out');
        navigate('/');
        break;
      case 'CROSS_TAB_SYNC':
        console.log('Auth state synced from another tab');
        break;
      case 'TOKEN_REFRESH':
        console.log('Token refreshed');
        break;
      case 'ACCOUNT_REFRESH':
        console.log('Account info refreshed');
        break;
    }
  });
  
  return () => unsubscribe();
}, []);
```

## Account Caching

The auth module includes intelligent account info caching to reduce API calls:

```tsx
const { getAccount, refreshAccount, accountInfo } = useAuth();

// Get account (uses cache if fresh)
const account = await getAccount();

// Force refresh
const freshAccount = await getAccount(true);
// or
const freshAccount = await refreshAccount();

// Access cached data synchronously
const cachedAccount = accountInfo;
```

**Configuration:**
- Default cache TTL: 5 minutes
- Configure via `accountCacheTTL` prop on AuthProvider
- Enable automatic preload with `preloadAccountInfo={true}`

See [ACCOUNT_CACHING.md](./ACCOUNT_CACHING.md) for detailed documentation.

## Authentication Methods

### Email/Password

Standard email and password authentication with registration, login, password reset, and email verification.

```tsx
<SmartlinksAuthUI
  clientId="your-client-123"
  launchMode="signup"
/>
```

### Google OAuth

One-click Google authentication with automatic account creation.

```tsx
<SmartlinksAuthUI
  clientId="your-client-123"
  // Google Auth is enabled by default
/>
```

### Phone/SMS

Phone number authentication with SMS verification codes.

```tsx
<SmartlinksAuthUI
  clientId="your-client-123"
  // Phone auth is enabled by default
/>
```

### Magic Links

Passwordless authentication via email magic links.

```tsx
<SmartlinksAuthUI
  clientId="your-client-123"
  // Magic links are enabled by default
/>
```

## Customization

### Branding & Theming

Customize colors, fonts, and logo via the admin interface or programmatically:

```tsx
<SmartlinksAuthUI
  clientId="your-client-123"
  customization={{
    branding: {
      logoUrl: "https://yourdomain.com/logo.png",
      title: "Welcome to Acme",
      subtitle: "Sign in to your account",
      primaryColor: "#6366f1",
      secondaryColor: "#4f46e5",
      backgroundColor: "#f0f9ff",
      fontFamily: "Inter, sans-serif"
    }
  }}
/>
```

### Provider Configuration

Configure which authentication providers are available and their display order through the Smartlinks admin interface.

### Email Templates

Customize email templates for password reset, email verification, and magic links through the admin interface with support for:
- Custom logos and hero images
- Branded colors and fonts
- Custom intro text and CTAs
- Footer links and company information

See [CUSTOMIZATION_GUIDE.md](./CUSTOMIZATION_GUIDE.md) for detailed customization options.

## Advanced Features

### Multi-Tenant Support

The `clientId` parameter enables multi-tenant authentication, allowing different applications or customers to use the same auth infrastructure with isolated configurations:

```tsx
// App 1
<SmartlinksAuthUI clientId="app-1-prod" />

// App 2
<SmartlinksAuthUI clientId="app-2-prod" />
```

### Custom Account Data

Store custom metadata per user account during registration:

```tsx
<SmartlinksAuthUI
  clientId="your-client-123"
  accountData={{
    companyName: "Acme Corp",
    plan: "enterprise",
    seats: 50,
    customFields: {
      industry: "Technology",
      region: "North America"
    }
  }}
/>
```

### Deep Link Handling

The component automatically handles URL-based authentication flows:

- **Email Verification**: `?mode=verifyEmail&token=xxx`
- **Password Reset**: `?mode=resetPassword&token=xxx`
- **Magic Links**: `?mode=magicLink&token=xxx`

### Cross-Tab Synchronization

Authentication state automatically syncs across browser tabs using BroadcastChannel API and IndexedDB. When a user logs in or out in one tab, all other tabs update immediately.

## TypeScript Support

Full TypeScript definitions included:

```tsx
import type { 
  AuthUser, 
  AuthToken, 
  AuthResponse,
  AuthProvider,
  AuthUIConfig,
  SmartlinksAuthUIProps,
  AccountManagementProps,
  ClaimField,
  ClaimResult
} from '@smartlinks/auth-ui';
```

## Documentation

- **[AUTH_STATE_MANAGEMENT.md](./AUTH_STATE_MANAGEMENT.md)** - Complete guide to authentication state, callbacks, and cross-tab sync
- **[ACCOUNT_CACHING.md](./ACCOUNT_CACHING.md)** - Account information caching strategies and configuration
- **[CUSTOMIZATION_GUIDE.md](./CUSTOMIZATION_GUIDE.md)** - Detailed customization and theming guide
- **[SMARTLINKS_INTEGRATION.md](./SMARTLINKS_INTEGRATION.md)** - Smartlinks SDK integration details

## Troubleshooting

### Styles Not Appearing

**Problem**: The authentication UI appears unstyled or has no layout.

**Solution**: Make sure you've imported the CSS file:
```tsx
import '@smartlinks/auth-ui/dist/index.css';
```

This import should be at the top of your app's entry point (before your component imports).

### Smartlinks SDK Not Initialized

**Problem**: `Cannot read property 'authKit' of undefined` or similar SDK errors.

**Solution**: Initialize the Smartlinks SDK before rendering components:
```tsx
import * as smartlinks from '@proveanything/smartlinks';

smartlinks.initializeApi({
  baseUrl: 'https://smartlinks.app/api/v1',
  proxyMode: false,
});
```

### Session Not Persisting

**Problem**: Users get logged out on page refresh.

**Solution**: 
1. Ensure AuthProvider wraps your entire app
2. Check that IndexedDB is enabled in the browser
3. Verify that third-party cookies aren't blocked (affects cross-tab sync)

### TypeScript Errors

**Problem**: Type errors when using the components.

**Solution**: The package includes TypeScript definitions. Make sure:
```tsx
import type { AuthUser, AuthResponse } from '@smartlinks/auth-ui';
```

## Support

For issues, questions, or feature requests:
- GitHub Issues: [github.com/smartlinks/auth-ui](https://github.com/smartlinks/auth-ui)
- Documentation: [docs.smartlinks.app/auth-ui](https://docs.smartlinks.app/auth-ui)
- Smartlinks Platform: [smartlinks.app](https://smartlinks.app)

## License

MIT © Smartlinks