# Debrid Auth Worker Fixes — 2026-06-01

## Problem
The Cloudflare Worker QR debrid auth flow was broken — users saw "HTTP 404" when scanning QR codes. Multiple root causes conspired to produce the failure.

## Root Causes Found & Fixed

### 1. `setAlarm` Duration vs Timestamp Bug (CRITICAL)
**Symptom:** Sessions created but immediately cancelled (status switched to "cancelled" within seconds).

**Root cause:** `DurableObjectStorage.setAlarm(SESSION_TTL_MS)` was called with a **duration** (900000 = 15 minutes in milliseconds). But Cloudflare's `setAlarm()` interprets a numeric argument as an **absolute epoch timestamp**, not a duration. 900000ms since epoch = Jan 1, 1970 00:15:00 = already in the past → alarm fired immediately → all sessions cancelled.

**Fix:** Change all `setAlarm(SESSION_TTL_MS)` calls to `setAlarm(Date.now() + SESSION_TTL_MS)`.

**Affected files:** `src/auth_session_do.ts` — three call sites (handleOAuthStart, handleKeyStart, handleCreateUrlSession).

### 2. Provider ID Normalization
**Symptom:** `real_debrid` (with underscore) rejected as "Unknown provider."

**Root cause:** Android enum `DebridProvider.REAL_DEBRID.name.lowercase()` → `"real_debrid"` (underscore). Worker expected `"realdebrid"` (no underscore).

**Fix — Two layers:**
- **Kotlin side:** `provider.name.lowercase().replace("_", "")` in `DebridAuthViewModel.kt`
- **Worker side:** `(body.providerId || "").replace(/_/g, "").toLowerCase()` in `handleApiAuthCreate`

### 3. `configuredApiKey` Missing in Response
**Symptom:** Android app polled for session completion but never received the API key, even after successful form submission.

**Root cause:** `handleAuthStatus` returned a subset of session fields but filtered out `apiKey`/`token`. The DO stored `s.apiKey = apiKey` and `s.token = data.access_token`, but the index.ts handler mapped only `{code, service, authType, status, userCode}`.

**Fix:** Add `configuredApiKey: s.apiKey || s.token || null` to `handleAuthStatus` and `handleAuthSubmit` responses. The Android `DebridAuthSessionResponse` expects the field `configuredApiKey`.

### 4. `handleKeyStart` Validation List Mismatch
**Symptom:** Real-Debrid/Premiumize sessions returned "Unsupported" error.

**Root cause:** Three separate validation lists existed:
1. `handleApiAuthCreate` in index.ts — routes to `handleOAuthStart` or `handleKeyStart`
2. `handleKeyStart` in index.ts — had `["torbox","alldebrid","debrider","offcloud"]` only (missing realdebrid/premiumize)
3. `handleKeyStart` in the DO — had a separate validation list

When `handleApiAuthCreate` was patched to route all providers to key-based, the index.ts `handleKeyStart` still blocked realdebrid/premiumize with its own validation.

**Fix:** Updated both index.ts `handleKeyStart` and DO's `handleKeyStart` to include all six providers.

### 5. Real-Debrid OAuth → API Key Switch
**Symptom:** RD OAuth device code flow returned "HTTP 404" and "unknown_method" from Real-Debrid API.

**Root cause:** The RD OAuth device code endpoint (`/rest/1.0/oauth/device/code`) was deprecated. The v2 endpoint (`/oauth/v2/device/code`) returned "unknown_method". The registered client ID may have been invalid or unregistered.

**Fix:** Removed OAuth device code flow entirely. All 6 debrid providers (RD, PM, TB, AD, Debrider, Offcloud) now use API key entry. The QR page always shows an API key input form where the user pastes their debrid API key from the provider's website.

**Affected code:**
- Removed OAuth routing in `handleApiAuthCreate` — now routes all to `handleKeyStart`
- Removed OAuth page rendering in `handleAuthForm` — always renders `renderApiKeyForm`
- Removed OAuth polling logic in `handleAuthStatus`
- Updated `handleKeyStart` validation lists in both index.ts and auth_session_do.ts
- Updated `renderOAuthPage` import (still exists but unused for debrid)

## Deployment Notes
- All fixes deployed to `unspooled-config-v3.tw24fr.workers.dev` (the merged config+auth worker)
- CF API token: stored in `/tmp/cf_token` and `~/.wrangler/config/default.toml`
- Deploy command: `cd services/addon-config-worker && npx wrangler deploy`
- Token format: `cfut_...` (53 chars), generated at https://dash.cloudflare.com/profile/api-tokens
- Token may expire quickly — redeploy with `CLOUDFLARE_API_TOKEN=cfut_u...ac68 npx wrangler deploy`
- Beware: `$()` subshell in terminal tool sometimes breaks — use `execute_code` with f-strings for reliable token injection

## Verification
```bash
# Create session
curl -s 'https://unspooled-config-v3.tw24fr.workers.dev/api/debrid/auth-sessions' \
  -X POST -H 'Content-Type: application/json' \
  -d '{"providerId":"realdebrid"}'
# → {"code":"...","service":"realdebrid","authType":"apikey","status":"pending",...}

# Submit API key
curl -s 'https://unspooled-config-v3.tw24fr.workers.dev/debrid/auth/submit/{code}' \
  -X POST -H 'Content-Type: application/json' \
  -d '{"apiKey":"my-rd-token"}'
# → {"status":"completed","configuredApiKey":"my-rd-token"}

# Poll for key
curl -s 'https://unspooled-config-v3.tw24fr.workers.dev/api/debrid/auth-sessions/{code}'
# → {"status":"completed","configuredApiKey":"my-rd-token"}
```
