npm package: @rxbenefits/auth0-nextjs
Description: Shared Auth0 authentication library for RxBenefits Next.js applications
Author: RxBenefits
Latest version: 1.0.0

# @rxbenefits/auth0-nextjs

Shared Auth0 authentication library for RxBenefits Next.js applications. Provides seamless authentication across micro frontends deployed on the same domain.

## Features

✅ **Shared Session** - All apps on the same domain share Auth0 session cookies
✅ **Auto Token Injection** - API handlers automatically include bearer tokens
✅ **Simple Integration** - Same code works for shell and all MFEs
✅ **TypeScript** - Full type safety
✅ **Route Protection** - Built-in middleware for protected routes
✅ **SSO Support** - Single sign-on across all applications

## Installation

```bash
npm install @rxbenefits/auth0-nextjs
```

### Peer Dependencies

This package requires:
- `@auth0/nextjs-auth0` ^3.0.0
- `next` >=13.0.0
- `react` >=18.0.0

```bash
npm install @auth0/nextjs-auth0
```

## Quick Start

### 1. Environment Configuration

Create `.env.local` in your application:

```env
AUTH0_SECRET=<generate-with-openssl-rand-hex-32>
AUTH0_BASE_URL=https://adminportal.rxbenefits.com
AUTH0_ISSUER_BASE_URL=https://your-tenant.auth0.com
AUTH0_CLIENT_ID=<your-client-id>
AUTH0_CLIENT_SECRET=<your-client-secret>
NEXT_PUBLIC_API_URL=https://api.rxbenefits.com
```

### 2. Wrap Your App

**pages/_app.tsx** or **app/layout.tsx**:

```typescript
import { RxAuthProvider } from '@rxbenefits/auth0-nextjs';

export default function App({ Component, pageProps }) {
  return (
    <RxAuthProvider>
      <Component {...pageProps} />
    </RxAuthProvider>
  );
}
```

### 3. Add Auth0 Handler

**pages/api/auth/[...auth0].ts**:

```typescript
import { handleAuth } from '@auth0/nextjs-auth0';

export default handleAuth();
```

### 4. Protect Routes (Optional)

**middleware.ts**:

```typescript
import { withAuthMiddleware, defaultAuthMiddlewareConfig } from '@rxbenefits/auth0-nextjs';

export default withAuthMiddleware();

export const config = defaultAuthMiddlewareConfig;
```

### 5. Create API Routes with Auto Token Injection

**pages/api/organizations.ts**:

```typescript
import { createAuthApiHandler } from '@rxbenefits/auth0-nextjs';

export default createAuthApiHandler({
  backendUrl: process.env.NEXT_PUBLIC_API_URL
});
```

That's it! Your API calls now automatically include Auth0 bearer tokens.

## Usage Examples

### Using the Auth Hook

```typescript
import { useRxAuth } from '@rxbenefits/auth0-nextjs';

function MyComponent() {
  const { user, isLoading, error, login, logout, isAuthenticated } = useRxAuth();

  if (isLoading) return <div>Loading...</div>;
  if (error) return <div>Error: {error.message}</div>;

  return (
    <div>
      {isAuthenticated ? (
        <>
          <p>Welcome, {user.name}!</p>
          <button onClick={() => logout()}>Logout</button>
        </>
      ) : (
        <button onClick={() => login()}>Login</button>
      )}
    </div>
  );
}
```

### Custom API Handler

```typescript
import { createAuthApiHandler } from '@rxbenefits/auth0-nextjs';

export default createAuthApiHandler({
  // Dynamic backend URL
  backendUrl: (req) => {
    if (req.url?.includes('/ben-admin/')) {
      return process.env.BEN_ADMIN_API_URL!;
    }
    return process.env.NEXT_PUBLIC_API_URL!;
  },

  // Custom headers
  customHeaders: {
    'X-App-Name': 'Ben Admin MFE'
  },

  // Transform response
  transformResponse: (data) => {
    return {
      ...data,
      timestamp: new Date().toISOString()
    };
  }
});
```

### Simple API Handler

```typescript
import { createSimpleAuthApiHandler } from '@rxbenefits/auth0-nextjs';

// Just pass the backend URL
export default createSimpleAuthApiHandler(process.env.NEXT_PUBLIC_API_URL!);
```

### Custom Middleware

```typescript
import { withAuthMiddleware } from '@rxbenefits/auth0-nextjs';

export default withAuthMiddleware({
  // Skip auth for specific paths
  beforeAuth: (req) => {
    if (req.nextUrl.pathname.startsWith('/public')) {
      return false; // Skip auth
    }
    return true; // Require auth
  },

  // Add custom logic after auth
  afterAuth: (req, res) => {
    // Add custom headers
    res.headers.set('X-Authenticated', 'true');
    return res;
  }
});
```

### Permission Checks

```typescript
import { useRxAuth } from '@rxbenefits/auth0-nextjs';

function AdminPanel() {
  const { hasPermission, hasRole } = useRxAuth();

  if (!hasPermission('admin:write')) {
    return <div>Access Denied</div>;
  }

  if (!hasRole('admin')) {
    return <div>Admin role required</div>;
  }

  return <div>Admin Panel Content</div>;
}
```

## API Reference

### RxAuthProvider

Provider component that wraps your application with Auth0 authentication.

```typescript
<RxAuthProvider
  loginUrl="/custom-login"  // Optional
  profileUrl="/custom-profile"  // Optional
>
  {children}
</RxAuthProvider>
```

### createAuthApiHandler(options)

Creates an API route handler with automatic token injection.

**Options:**
- `backendUrl` - Backend API base URL (string or function)
- `pathResolver` - Custom path resolver function
- `customHeaders` - Additional headers (object or function)
- `requireAuth` - Whether to require authentication (default: true)
- `transformResponse` - Response transformation function

### withAuthMiddleware(options)

Creates authentication middleware for route protection.

**Options:**
- `loginUrl` - Custom login redirect URL
- `beforeAuth` - Function to execute before auth check
- `afterAuth` - Function to execute after successful auth

### useRxAuth()

Hook for accessing authentication state and methods.

**Returns:**
- `user` - Authenticated user object
- `isLoading` - Loading state
- `error` - Error object if auth failed
- `isAuthenticated` - Boolean authentication status
- `login(returnTo?)` - Function to redirect to login
- `logout(returnTo?)` - Function to logout
- `hasPermission(permission)` - Check user permission
- `hasRole(role)` - Check user role

## Architecture

### Same Domain Deployment

All applications must be deployed on the same domain for shared session cookies:

```
adminportal.rxbenefits.com/          ← Shell
adminportal.rxbenefits.com/ben-admin ← MFE 1
adminportal.rxbenefits.com/admin-tools ← MFE 2
```

### How It Works

1. User logs in → Auth0 session cookie set on `.rxbenefits.com`
2. All apps can access the same session cookie
3. Each app independently calls `getAccessToken()` from shared session
4. Tokens are automatically injected into API calls

### Independent Development

Each MFE can run standalone with its own Auth0 configuration:

```bash
# Shell
cd admin-portal-shell
npm run dev  # http://localhost:3000

# Ben Admin MFE
cd ben-admin-mfe
npm run dev  # http://localhost:3001
```

In development, each app has its own session. In production (same domain), they share the session.

## Production Deployment

### Auth0 Configuration

Configure allowed callback URLs for all apps:

```
https://adminportal.rxbenefits.com/api/auth/callback
https://adminportal.rxbenefits.com/ben-admin/api/auth/callback
https://adminportal.rxbenefits.com/admin-tools/api/auth/callback
```

### Environment Variables

Each app needs the same Auth0 configuration:

```env
AUTH0_SECRET=<same-for-all-apps>
AUTH0_BASE_URL=https://adminportal.rxbenefits.com
AUTH0_ISSUER_BASE_URL=https://your-tenant.auth0.com
AUTH0_CLIENT_ID=<same-for-all-apps>
AUTH0_CLIENT_SECRET=<same-for-all-apps>
```

## Troubleshooting

### "Missing authentication token" errors

**Cause**: API handler can't access Auth0 session
**Fix**: Ensure all apps are on the same domain in production

### CORS errors

**Cause**: Different domains in development
**Fix**: Expected in dev. Will work in production on same domain.

### Token not found

**Cause**: User not logged in or session expired
**Fix**: Redirect to `/api/auth/login`

## License

MIT © RxBenefits

## Support

For issues and questions:
- GitHub Issues: https://github.com/RxBenefits/auth0-nextjs/issues
- Internal Slack: #engineering

---

Built with ❤️ by RxBenefits Engineering