# AuthSessionDO — Fetch-Dispatch Pattern

Full implementation of a Durable Object that handles multiple auth operations via a single `fetch()` method dispatching on URL pathname.

## Key Architecture

The DO extends `DurableObject` and exposes a `fetch()` method. The worker calls it via `stub.fetch(request)`, passing pathname + query params + optional body. The DO reads `url.pathname` to dispatch.

## State Storage

Uses `this.storage.put("auth", session)` / `this.storage.get("auth")` for debrid auth sessions and `"addonUrl"` for addon URL sessions. TTL via `setAlarm()`.

All session types share the DO — the same DO instance handles both debrid auth and addon URL entry, stored under different keys.

## Path Dispatch Table

| Worker route | DO path | Method | Purpose |
|---|---|---|---|
| `/debrid/oauth/start/{service}` | `/debrid/oauth/start?service=...` | GET | OAuth device code |
| `/debrid/key/start/{service}` | `/debrid/key/start?service=...` | GET | API key session |
| `/debrid/auth/form/{code}` | `/debrid/auth/status` | GET | Get session for form render |
| `/debrid/auth/submit/{code}` | `/debrid/auth/submit` | POST | Submit API key |
| `/debrid/auth/status/{code}` | `/debrid/auth/status` | GET | Poll status |
| `/debrid/auth/cancel/{code}` | `/debrid/auth/cancel` | GET | Cancel |
| `/addon/url/start` | `/addon/url/create` | GET | Create URL session |
| `/addon/url/form/{code}` | `/addon/url/status` | GET | Get for form render |
| `/addon/url/submit/{code}` | `/addon/url/submit` | POST | Submit manifest URL |
| `/addon/url/status/{code}` | `/addon/url/status` | GET | Poll URL status |
| `/addon/url/cancel/{code}` | `/addon/url/cancel` | GET | Cancel |

## OAuth Token Fetching

Real-Debrid and Premiumize OAuth device code flow:
1. POST device code request to service endpoint
2. Store `device_code`, `user_code`, `verification_url`, `interval`
3. On poll, POST to token endpoint with `client_id`, `device_code`, and `grant_type=http://oauth.net/grant_type/device/1.0`
4. If 400 response body contains "pending" or "slow_down", keep polling
5. On 200, extract `access_token` and mark completed

## Expiry

- 15-minute session TTL (`SESSION_TTL_MS`)
- Alarm fires at TTL to expire pending/active sessions
- Polling stops after 300 attempts (`MAX_POLLS`)
- Workers are single-user so race conditions on storage are unlikely

## IRT Token Handling

CF Workers `$` token was stored at `/tmp/cf_token` during session and in `deploy.sh` scripts. System content filters aggressively redact token values from code — avoid putting token as literal in source files. Prefer reading from a file at runtime.
