# AnyClip Authentication

## Overview

AnyClip uses a two-step authentication flow with JWT tokens and cookie-based session management.

## Password Encryption

Passwords are encrypted client-side using AES-256-GCM with a static salt.

**Salt:** `$2b$04$wwky7rvtr6BFNaCqntwyie`

**Output format:** `<iv_hex>:<hex_encoded_base64_ciphertext>`

Our implementation uses SubtleCrypto (Web Crypto API) with zero external dependencies:

```typescript
import { encryptString } from './scripts/crypto-subtle';

const PASS_CRYPTO_SALT = '$2b$04$wwky7rvtr6BFNaCqntwyie';
const encryptedPassword = await encryptString(password, PASS_CRYPTO_SALT);
```

**Note:** The original AnyClip client uses `string-crypto@2.0.2`. Version 3.x uses different encoding (base64 vs hex) and is NOT compatible.

## Authentication Flow

### Step 1: External API Login

**Endpoint:** `POST https://videomanager-api.anyclip.com/public/auth/login`

**Request:**
```json
{
  "email": "user@example.com",
  "password": "<hashed_password>"
}
```

Note: Password appears to be client-side hashed before sending (format: `hash:base64data`)

**Response:**
```json
{
  "cookieName": "anyclip_2020",
  "cookieValue": "<session_token>",
  "token": "<jwt_token>",
  "user": "<base64_encoded_user_json>"
}
```

### Step 2: Main App Login

**Endpoint:** `POST https://videomanager.anyclip.com/api/auth/login`

**Request:**
```json
{
  "token": "<jwt_token_from_step_1>",
  "tcname": "anyclip_2020",
  "tcvalue": "<cookie_value_from_step_1>"
}
```

**Response:** Sets `session` cookie via `Set-Cookie` header (iron-sealed format: `Fe26.2*...`)

**Important:** You must capture this session cookie from the response headers and include it with the `anyclip_2020` cookie in all subsequent requests.

## JWT Token Structure

The JWT token contains:

```json
{
  "role": {
    "id": 15,
    "name": "publisher_admin",
    "displayName": "Account Admin",
    "type": "ACCOUNT"
  },
  "slug": "2240",
  "userId": 16086,
  "context": "<bcrypt_hash>",
  "userEmail": "user@example.com",
  "timezone": "America/New_York",
  "accountId": 1599,
  "publisherId": 2240,
  "salesforceId": "001Te000004ZYO7IAO",
  "iat": 1768891600,
  "exp": 1768920400
}
```

**Token Expiry:** ~8 hours from issuance

## User Object (Base64 Decoded)

Contains extensive user and account data:

- **User info:** id, firstName, lastName, email, roleId, timezone
- **Account info:** id, name, status, type, features, publishers
- **Permissions:** Array of permission strings (e.g., "get/analytics", "post/video")
- **Account features:** Enabled features like watch, forms, x-ray, video targeting
- **Account dashboards:** Available analytics dashboards (Monetization, Video Performance, etc.)
- **Publishers:** List of publisher sites associated with the account

## Session Management

**Two cookies are required for authentication:**

| Cookie | Source | Format |
|--------|--------|--------|
| `anyclip_2020` | External API response body | Plain session token |
| `session` | Main API `Set-Cookie` header | Iron-sealed (encrypted) |

Both cookies must be sent with all authenticated requests:

```typescript
headers: {
  Cookie: `anyclip_2020=<token>; session=Fe26.2*...`
}
```

- **Cookie scope:** `videomanager.anyclip.com`
- All API requests include cookies via `credentials: 'same-origin'`

## Logout

**Endpoint:** `POST https://videomanager.anyclip.com/api/auth/logout`

Clears the session cookie.

## API Request Authentication

After login, all requests to `videomanager.anyclip.com/api/*` are authenticated via the session cookie.

**GraphQL Endpoint:** `POST https://videomanager.anyclip.com/api/graphql`

## Permission System

Permissions are returned in the user object as an array of strings:

```
analytics-monetization
analytics-video-external
analytics-custom-reports
get/analytics
post/video
put/video
...
```

These control access to:
- API endpoints (get/post/put/delete patterns)
- UI features (analytics-*, video-*, hosted-watch-*)
- Specific capabilities (video-embed, video-share, etc.)

## Role Types

- `publisher_admin` - Account Admin (full access)
- Other roles with restricted permissions

## Two Servers

| Server | Purpose |
|--------|---------|
| `videomanager-api.anyclip.com` | External auth API (login only) |
| `videomanager.anyclip.com` | Main application API |
