npm package: @fnd-platform/cognito-auth
Description: AWS Cognito authentication constructs and middleware for fnd-platform applications
Latest version: 1.0.0-alpha.11

# @fnd-platform/cognito-auth

AWS Cognito authentication constructs and middleware for fnd-platform applications. Provides CDK constructs, JWT validation, Lambda authorizers, and Remix authentication utilities.

## Installation

```bash
npm install @fnd-platform/cognito-auth
# or
pnpm add @fnd-platform/cognito-auth
```

## Quick Start

### CDK Construct

```typescript
import { FndCognitoAuth } from '@fnd-platform/cognito-auth';

const auth = new FndCognitoAuth(this, 'Auth', {
  stage: 'dev',
  appName: 'my-app',
  callbackUrls: ['http://localhost:3000/auth/callback'],
  logoutUrls: ['http://localhost:3000'],
});

// Access outputs
auth.userPool;
auth.userPoolClient;
auth.identityPool;
```

### Lambda Middleware

```typescript
import { withCognitoAuth } from '@fnd-platform/cognito-auth';

export const handler = withCognitoAuth({
  userPoolId: process.env.USER_POOL_ID!,
  clientId: process.env.CLIENT_ID!,
})(async (event) => {
  // event.requestContext.authorizer contains user claims
  const userId = event.requestContext.authorizer?.claims?.sub;
  return { statusCode: 200, body: JSON.stringify({ userId }) };
});
```

### Remix Authentication

```typescript
import { requireAuth, getOptionalUser, logout } from '@fnd-platform/cognito-auth';

// In a loader - require authentication
export const loader = async ({ request }) => {
  const user = await requireAuth(request);
  return json({ user });
};

// In a loader - optional authentication
export const loader = async ({ request }) => {
  const user = await getOptionalUser(request);
  return json({ user });
};

// Logout action
export const action = async ({ request }) => {
  return logout(request);
};
```

## Features

- **CDK Construct** - Fully configured Cognito User Pool with best practices
- **JWT Validation** - Verify and extract claims from Cognito tokens
- **Lambda Middleware** - Authenticate Lambda handlers
- **Lambda Authorizer** - API Gateway authorizer function
- **Token Refresh** - Automatic token refresh utilities
- **Remix Integration** - Session management and auth utilities for Remix

## CDK Construct Options

```typescript
interface FndCognitoAuthProps {
  stage: 'dev' | 'staging' | 'prod';
  appName: string;
  callbackUrls: string[];
  logoutUrls: string[];

  // Optional
  selfSignUp?: boolean; // Allow self-registration (default: true)
  mfa?: 'off' | 'optional' | 'required'; // MFA setting (default: 'optional')
  passwordPolicy?: {
    minLength?: number; // Default: 8
    requireUppercase?: boolean; // Default: true
    requireLowercase?: boolean; // Default: true
    requireDigits?: boolean; // Default: true
    requireSymbols?: boolean; // Default: true
  };
}
```

## Examples

### Role-Based Access Control

```typescript
import { requireRole, requireAdmin, hasRole } from '@fnd-platform/cognito-auth';

// Require admin role
export const loader = async ({ request }) => {
  const user = await requireAdmin(request);
  // Only admins can reach this point
  return json({ user });
};

// Require specific roles
export const loader = async ({ request }) => {
  const user = await requireRole(request, ['admin', 'editor']);
  return json({ user });
};

// Check role without redirecting
export const loader = async ({ request }) => {
  const user = await requireAuth(request);
  const isAdmin = hasRole(user, 'admin');
  return json({ user, isAdmin });
};
```

### JWT Verification

```typescript
import { verifyToken, verifyAndExtract, getVerifier } from '@fnd-platform/cognito-auth';

// Verify a token
const isValid = await verifyToken(token, {
  userPoolId: process.env.USER_POOL_ID!,
  clientId: process.env.CLIENT_ID!,
  tokenUse: 'access',
});

// Verify and get claims
const claims = await verifyAndExtract(token, {
  userPoolId: process.env.USER_POOL_ID!,
  clientId: process.env.CLIENT_ID!,
});

// Get a reusable verifier (cached)
const verifier = getVerifier({
  userPoolId: process.env.USER_POOL_ID!,
  clientId: process.env.CLIENT_ID!,
});
```

### Session Management

```typescript
import {
  createSessionStorage,
  getSession,
  createUserSession,
  getUserSession,
} from '@fnd-platform/cognito-auth';

// Create session storage
const sessionStorage = createSessionStorage({
  secret: process.env.SESSION_SECRET!,
  secure: process.env.NODE_ENV === 'production',
});

// Create a user session after login
export const action = async ({ request }) => {
  const tokens = await authenticateUser(credentials);
  return createUserSession(request, {
    accessToken: tokens.accessToken,
    idToken: tokens.idToken,
    refreshToken: tokens.refreshToken,
    redirectTo: '/dashboard',
  });
};
```

### Auth Client

```typescript
import { FndAuthClient, AuthError } from '@fnd-platform/cognito-auth';

const authClient = new FndAuthClient({
  userPoolId: process.env.USER_POOL_ID!,
  clientId: process.env.CLIENT_ID!,
  region: process.env.AWS_REGION!,
});

try {
  // Sign up
  const result = await authClient.signUp({
    email: 'user@example.com',
    password: 'SecurePassword123!',
  });

  // Sign in
  const tokens = await authClient.signIn({
    email: 'user@example.com',
    password: 'SecurePassword123!',
  });

  // Refresh tokens
  const newTokens = await authClient.refreshTokens(tokens.refreshToken);
} catch (error) {
  if (error instanceof AuthError) {
    console.error(error.code, error.message);
  }
}
```

## API Reference

See the [full API documentation](../../docs/api/modules/cognito_auth_src.html) for detailed type definitions and examples.

### CDK Constructs

- `FndCognitoAuth` - Main Cognito User Pool construct
- `FndCognitoAuthProps` - Construct configuration
- `Stage` - Valid stage values type
- `validateStage` - Stage validation utility
- `VALID_STAGES` - Array of valid stages

### JWT Utilities

```typescript
import {
  verifyToken, // Verify token validity
  verifyAndExtract, // Verify and return claims
  getVerifier, // Get cached verifier instance
  clearVerifierCache, // Clear verifier cache
} from '@fnd-platform/cognito-auth';
```

### Middleware

```typescript
import { withCognitoAuth } from '@fnd-platform/cognito-auth';
```

### Lambda Authorizer

```typescript
import { authorizerHandler } from '@fnd-platform/cognito-auth';
```

### Token Utilities

```typescript
import { refreshAccessToken, clearClientCache } from '@fnd-platform/cognito-auth';
```

### Auth Client

```typescript
import { FndAuthClient, AuthError, clearAuthClientCache } from '@fnd-platform/cognito-auth';
```

### Remix Utilities

```typescript
import {
  // Session management
  createSessionStorage,
  getSession,
  createUserSession,
  getUserSession,
  // Auth helpers
  requireAuth,
  getOptionalUser,
  logout,
  // Role-based access
  requireAdmin,
  requireRole,
  hasRole,
  hasAnyRole,
} from '@fnd-platform/cognito-auth';
```

### Types

```typescript
import type {
  FndCognitoAuthProps,
  Stage,
  CognitoAccessTokenPayload,
  CognitoIdTokenPayload,
  CognitoAuthOptions,
  JwtVerifierConfig,
  TokenVerificationResult,
  CognitoAuthenticatedEvent,
  CognitoMiddleware,
  CognitoMiddlewareHandler,
  TokenRefreshConfig,
  RefreshResult,
  AuthClientConfig,
  AuthTokens,
  SignUpResult,
  SessionData,
  SessionUser,
  AuthErrorCode,
} from '@fnd-platform/cognito-auth';
```

## Requirements

- Node.js 20+
- AWS CDK v2 (for constructs)
- @remix-run/node (for Remix utilities)

## Related

- [@fnd-platform/api](../api/README.md) - API handlers with auth middleware
- [@fnd-platform/frontend](../frontend/README.md) - Frontend with auth integration
- [@fnd-platform/constructs](../constructs/README.md) - CDK constructs

## License

MIT