npm package: @oneaccount/express
Description: OneAccount SDK for Express.js - Authentication, entitlements, and Stripe Connect
Author: OneAccount
Latest version: 0.2.10

# @oneaccount/express

Express.js SDK for OneAccount - Authentication, entitlements, and Stripe Connect integration.

## Installation

```bash
npm install @oneaccount/express
```

## Quick Start

```javascript
import express from 'express';
import { oneAccount } from '@oneaccount/express';

const app = express();
app.use(express.json());

// Initialize SDK
const oa = oneAccount({
  apiKey: process.env.ONEACCOUNT_API_KEY,
  accountProUrl: 'https://accountpro.replit.app', // optional
  debug: true, // optional - logs auth errors
});

// Add auth middleware to all routes
app.use(oa.middleware);

// Mount Stripe Connect routes
oa.mountRoutes(app, '/api/connect');

// Protected route - requires authentication
app.get('/api/profile', oa.requireAuth, (req, res) => {
  res.json({ user: req.oneAccount.user });
});

// Protected route - requires specific entitlement
app.get('/api/classes', oa.requireEntitlement('classy'), (req, res) => {
  res.json({ message: 'Welcome to Classy!' });
});

// Admin-only route
app.get('/api/admin', oa.requireSuperAdmin, (req, res) => {
  res.json({ message: 'Admin access granted' });
});

app.listen(3000);
```

## Configuration

| Option | Type | Default | Description |
|--------|------|---------|-------------|
| `apiKey` | string | required | Your OneAccount API key |
| `accountProUrl` | string | `https://accountpro.replit.app` | OneAccount server URL |
| `jwksUrl` | string | auto | JWKS endpoint URL (auto-derived from accountProUrl) |
| `debug` | boolean | `false` | Log authentication errors |

## Middleware

### `oa.middleware`

Parses JWT from `Authorization: Bearer <token>` header and populates `req.oneAccount.user`.

### `oa.requireAuth`

Returns 401 if no authenticated user.

### `oa.requireEntitlement(entitlement)`

Returns 403 if user doesn't have the specified entitlement (`sweetcart` or `classy`).

### `oa.requireSuperAdmin`

Returns 403 if user is not a super admin.

## Stripe Connect Routes

When you call `oa.mountRoutes(app, '/api/connect')`, the following routes are available:

| Method | Path | Description |
|--------|------|-------------|
| GET | `/api/connect/account` | Get Stripe Connect status |
| POST | `/api/connect/account` | Create Stripe Express account |
| POST | `/api/connect/onboarding-link` | Get Stripe onboarding URL |
| POST | `/api/connect/dashboard-link` | Get Stripe Express dashboard URL |
| GET | `/api/connect/transactions` | List transactions |
| GET | `/api/connect/balance` | Get account balance |
| POST | `/api/connect/payment` | Create marketplace payment |
| POST | `/api/connect/refund` | Refund a payment |

## Buyer Authentication

For marketplace apps where sellers have their own customers (buyers), the SDK provides buyer authentication:

```typescript
import type { BuyerAuthRequest } from '@oneaccount/express';

// Mount buyer auth routes
oa.mountBuyerRoutes(app, '/api/buyer');

// Add buyer middleware to routes that need buyer auth
app.use('/api/customer', oa.buyerMiddleware);

// Protected buyer route - use BuyerAuthRequest for typing
app.get('/api/customer/orders', oa.requireBuyerAuth, (req: BuyerAuthRequest, res) => {
  const buyer = req.buyer!; // Non-null after requireBuyerAuth
  res.json({ buyerId: buyer.buyerId, sellerId: buyer.sellerId });
});

// Restrict to specific seller's buyers
app.get('/api/customer/classes', oa.requireBuyerForSeller('seller-uuid'), (req: BuyerAuthRequest, res) => {
  res.json({ message: 'Welcome!' });
});
```

### Buyer Auth Routes

When you call `oa.mountBuyerRoutes(app, '/api/buyer')`:

| Method | Path | Description |
|--------|------|-------------|
| POST | `/api/buyer/magic/request` | Request magic login link (email or SMS) |
| GET | `/api/buyer/magic/verify` | Verify magic token and get JWT |
| GET | `/api/buyer/profile` | Get buyer profile (requires auth) |

### Magic Link Request Body

```json
{
  "email": "customer@example.com",
  "sellerId": "seller-uuid",
  "channel": "email"
}
```

Or for SMS:

```json
{
  "phone": "+15551234567",
  "sellerId": "seller-uuid", 
  "channel": "sms"
}
```

### Buyer Middleware

- `oa.buyerMiddleware` - Parses buyer JWT from `Authorization: Bearer <token>` header
- `oa.requireBuyerAuth` - Returns 401 if no authenticated buyer
- `oa.requireBuyerForSeller(sellerId)` - Returns 403 if buyer doesn't belong to seller

## TypeScript

The SDK is fully typed. Import types as needed:

```typescript
import type { 
  OneAccountRequest, 
  OneAccountUser, 
  Entitlements,
  BuyerAuthRequest,
  BuyerUser,
} from '@oneaccount/express';
```

## License

MIT