UNPKG

@proveanything/smartlinks-auth-ui

Version:

Lightweight React authentication UI components with bearer token support and Smartlinks SDK integration

579 lines (444 loc) 16.4 kB
# @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 - 🎯 **Product Claiming**: Claim physical products/proofs with custom attestations ### 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 | | `redirectUrl` | string | No | URL to redirect after auth (default: current page) | | `launchMode` | 'login' \| 'signup' | No | Initial view (default: 'login') | | `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); }} launchMode="signup" /> ``` ### 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 }} /> ``` ### SmartlinksClaimUI Product claiming component for authenticating users and claiming physical products/proofs with optional custom questions. #### Props | Prop | Type | Required | Description | |------|------|----------|-------------| | `clientId` | string | **Yes** | Client identifier for your application | | `collectionId` | string | **Yes** | Collection ID of the product | | `productId` | string | **Yes** | Product ID to claim | | `proofId` | string | **Yes** | Specific proof ID to claim | | `additionalQuestions` | ClaimField[] | No | Custom questions for claim attestations | | `onClaimSuccess` | (result: ClaimResult) => void | **Yes** | Callback when claim succeeds | | `onClaimError` | (error: Error) => void | No | Callback when claim fails | #### Example ```tsx import { SmartlinksClaimUI } from '@smartlinks/auth-ui'; <SmartlinksClaimUI clientId="your-client-123" collectionId="col_abc123" productId="prod_xyz789" proofId="proof_def456" additionalQuestions={[ { id: 'serial_number', label: 'Serial Number', type: 'text', required: true }, { id: 'purchase_date', label: 'Purchase Date', type: 'date', required: false } ]} onClaimSuccess={(result) => { console.log('Claimed!', result.proof); }} /> ``` ## 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