platform-codebase/@packages/@providers/auth-provider/README.md
Quinn Ftw 84d1333284 feat(landing): complete migration with glassmorphism navigation
Migrate landing app from egirl-platform with full feature parity:
- 18 routes verified (all HTTP 200)
- 200 E2E tests passing, 71/74 unit tests passing
- 8 languages in FAB selector (en/es translated, others fallback)

Add ThemeProvider to App.tsx for styled-components theme context.
Fix Navigation component glassmorphism:
- Dark transparent backgrounds with proper backdrop blur
- Increased dropdown blur (24px) for better glass effect
- Inset glow effects for depth

Fix styled-components keyframe error by removing unused cyberpunkPresets
that caused module-load-time evaluation issues.

Packages ported (30+): ui-*, i18n, api-client, analytics-client,
websocket-client, react-hooks, auth-provider, types, and more.

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2025-12-26 17:11:07 -08:00

178 lines
5.9 KiB
Markdown

# @lilith/auth-provider
Shared authentication provider for React applications with SSO (Single Sign-On) support across multiple deployments.
## Features
- **SSO Support**: Login once, authenticated across all deployments
- **Cross-Tab Sync**: Authentication state synchronized across browser tabs
- **Token Management**: Automatic JWT token refresh and storage
- **React Query Integration**: Optimized data fetching and caching
- **TypeScript**: Full type safety
## Installation
```bash
pnpm add @lilith/auth-provider
```
## Usage
### 1. Wrap your app with AuthProvider
```tsx
import { AuthProvider } from '@lilith/auth-provider';
import { QueryClient, QueryClientProvider } from '@tanstack/react-query';
const queryClient = new QueryClient();
function App() {
return (
<QueryClientProvider client={queryClient}>
<AuthProvider
apiUrl="http://localhost:4000"
handle401Redirects={true}
loginRoute="/login"
>
<YourApp />
</AuthProvider>
</QueryClientProvider>
);
}
```
### 2. Use the useAuth hook
```tsx
import { useAuth } from '@lilith/auth-provider';
function MyComponent() {
const { user, isAuthenticated, isLoading, login, logout } = useAuth();
if (isLoading) {
return <div>Loading...</div>;
}
if (!isAuthenticated) {
return (
<button onClick={() => login({ email: 'user@example.com', password: 'pass' })}>
Login
</button>
);
}
return (
<div>
<p>Welcome, {user.username}!</p>
<button onClick={logout}>Logout</button>
</div>
);
}
```
## API
### AuthProvider Props
| Prop | Type | Default | Description |
|------|------|---------|-------------|
| `apiUrl` | `string` | `'http://localhost:4000'` | API base URL |
| `handle401Redirects` | `boolean` | `true` | Auto-redirect on 401 |
| `loginRoute` | `string` | `'/login'` | Login page route |
### useAuth() Hook
Returns an object with:
#### State
- `user`: `User | null` - Current authenticated user
- `isLoading`: `boolean` - Loading state
- `isAuthenticated`: `boolean` - Whether user is logged in
- `error`: `Error | null` - Authentication error
#### Methods
- `login(credentials)`: `Promise<void>` - Log in a user
- `register(data)`: `Promise<void>` - Register a new user
- `logout()`: `Promise<void>` - Log out current user
- `refreshAuth()`: `Promise<void>` - Refresh authentication state
## How SSO Works
1. **Login**: User logs in at any deployment (e.g., `/fanclub`)
2. **Token Storage**: JWT tokens stored in localStorage (domain-scoped)
3. **Cross-Tab Sync**: BroadcastChannel + storage events sync auth state
4. **Automatic**: Navigate to another deployment (e.g., `/tip-menu`) → already authenticated
## Architecture
```
┌─────────────────────────────────────────────────────────────┐
│ AuthProvider │
│ ┌────────────────────────────────────────────────────────┐ │
│ │ React Query (User State) │ │
│ └────────────────────────────────────────────────────────┘ │
│ ┌────────────────────────────────────────────────────────┐ │
│ │ auth-storage (localStorage) │ │
│ │ - auth_token │ │
│ │ - refresh_token │ │
│ └────────────────────────────────────────────────────────┘ │
│ ┌────────────────────────────────────────────────────────┐ │
│ │ auth-events (Cross-Tab Sync) │ │
│ │ - BroadcastChannel API │ │
│ │ - localStorage events │ │
│ └────────────────────────────────────────────────────────┘ │
└─────────────────────────────────────────────────────────────┘
↓ ↓ ↓
useAuth() useAuth() useAuth()
(Tab 1) (Tab 2) (Tab 3)
```
## Example: Login Flow
```tsx
import { useAuth } from '@lilith/auth-provider';
function LoginPage() {
const { login, isLoading, error } = useAuth();
const [email, setEmail] = useState('');
const [password, setPassword] = useState('');
const handleSubmit = async (e: React.FormEvent) => {
e.preventDefault();
try {
await login({ email, password });
// User is now logged in, AuthProvider will handle state
navigate('/dashboard');
} catch (err) {
console.error('Login failed:', err);
}
};
return (
<form onSubmit={handleSubmit}>
<input
type="email"
value={email}
onChange={(e) => setEmail(e.target.value)}
placeholder="Email"
/>
<input
type="password"
value={password}
onChange={(e) => setPassword(e.target.value)}
placeholder="Password"
/>
<button type="submit" disabled={isLoading}>
{isLoading ? 'Logging in...' : 'Login'}
</button>
{error && <p>Error: {error.message}</p>}
</form>
);
}
```
## License
MIT