Add AnyClip integration tools and extracted source code

- Add authentication scripts with SubtleCrypto password encryption
- Add sourcemap extraction pipeline (update-urls, download-sourcemaps, extract-sources)
- Add Playwright API interception script for monetization endpoints
- Document two-step auth flow with JWT tokens and dual cookies
- Move extracted source from root to anyclip/ directory
- Add project configuration (.env.example, .gitignore, CLAUDE.md)
This commit is contained in:
2026-01-21 10:36:51 +08:00
parent d4fe4800e6
commit e32d475aa9
3463 changed files with 184648 additions and 64341 deletions

168
docs/auth.md Normal file
View File

@@ -0,0 +1,168 @@
# 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 |

152
docs/monetization-api.md Normal file
View File

@@ -0,0 +1,152 @@
# AnyClip Monetization API Documentation
> **Note:** This document should be populated after running the API interception script.
> Run `bun scripts/intercept-monetization.ts` and interact with the monetization page to capture API endpoints.
## Overview
The monetization analytics page uses several API endpoints to fetch and display revenue data, filtering options, and export capabilities.
## Expected Endpoints
Based on component analysis, the following endpoints should be captured:
### Metrics Totals
Fetches aggregate metrics for the dashboard cards.
```
Endpoint: TBD (populate from captured-apis.json)
Method: POST/GET
```
**Request:**
```json
{
// To be documented after capture
}
```
**Response:**
```json
{
// To be documented after capture
}
```
---
### Chart Data (Time Series)
Fetches time-series data for the monetization charts.
```
Endpoint: TBD
Method: POST/GET
```
**Request:**
```json
{
// To be documented after capture
}
```
**Response:**
```json
{
// To be documented after capture
}
```
---
### Filter Options
#### Demand Sources
```
Endpoint: TBD
Method: GET
```
#### Players
```
Endpoint: TBD
Method: GET
```
#### Domains
```
Endpoint: TBD
Method: GET
```
#### Countries
```
Endpoint: TBD
Method: GET
```
---
### CSV Export
Endpoint for downloading monetization data as CSV.
```
Endpoint: TBD
Method: GET/POST
```
---
## How to Update This Document
1. Run the interception script:
```bash
bun scripts/intercept-monetization.ts
```
2. Log in to AnyClip in the browser window that opens
3. Once logged in, the script navigates to the monetization page
4. Interact with the page:
- Change date ranges
- Apply different filters (demand sources, players, domains, countries)
- Click export buttons
- Switch between chart views
5. Press `Ctrl+C` to stop capturing and save data
6. Review `captured-apis.json` in the project root
7. Update this document with the captured endpoint details
## Captured Data Format
The `captured-apis.json` file contains:
```json
{
"capturedAt": "ISO timestamp",
"totalRequests": 42,
"requests": [
{
"timestamp": "ISO timestamp",
"url": "full URL",
"method": "GET/POST",
"headers": { ... },
"requestBody": "JSON string or null",
"responseStatus": 200,
"responseHeaders": { ... },
"responseBody": "JSON string",
"duration": 123
}
]
}
```