Files
LlamaCasty/TASKS/task-02-oauth2-auth.md
gramps 87509bcf99 docs: restructure TASKS.md into a catalog — one file per task in TASKS/
TASKS.md is now the index (status table, open items, research pointer).
33 files: 32 task files + 1 research facts file. The full take-saga
narrative and all design decisions are preserved verbatim; the catalog
makes the queue readable without opening every task body. Schema and
AGENTS.md updated to reflect the new layout.
2026-09-05 16:31:46 -07:00

4.1 KiB

TASK 2 — YouTube OAuth2 Authentication

Catalog: TASKS.md — status and requirements live here.

Goal: Fully working Google OAuth2 flow — user clicks "YouTube", browser opens, authorization callback lands, channel info is stored.

Status: ✅ Done

  1. ✅ Two-state Start/End Stream button, go-live dialog (account + title/description/visibility), red top bar, pulsing LIVE badge + elapsed timer, preview glow, taskbar red dot
  2. ✅ Real OAuth2 wiring — baked-in Google credentials (desktop client; loopback callback) + YouTubeAuthService complete: browser launch, HttpListener callback, token exchange, refresh, channel fetch
  3. ✅ Token persistence via Windows DPAPI (Helpers/TokenStore.cs → %APPDATA%\ytLlive\ytLlive.auth), best-effort reload + proactive refresh at startup, saved after every exchange/refresh
  4. ✅ Account sign-in/change surfaced in the GoLive dialog (saved account shown with "Change Account"; "Sign in to YouTube" when none; Start disabled until signed in)
  5. ✅ End Livestream signs out SUPERSEDED by TASK 18 (2026-08-29): explicit sign-out only — StopStream() no longer clears the session (sign out via Logout / Change Account, SignOutYouTubeAsync); stopping a stream or recording leaves the creator signed in. Originally shipped as: a graceful end completes the session: StopStream() calls YouTubeAuthService.ClearSession() + TokenStore.Clear() + IsConnected = false, so the next Start Stream dialog requires a fresh sign-in. A crash never runs End, so the DPAPI token survives and the creator stays signed in. Resume/reconnect after a midstream crash is deliberately deferred to TASK 3: the socket can't be resumed (it dies with the process), so "resume" = fast reconnect with a saved broadcast ID/stream key within YouTube's disconnect-grace window; too slow and enableAutoStop ends the broadcast. Orphan closed 2026-09-01: this mechanism is owned by TASK 32 (Stream resilience) — in-session blip retry inside the grace window; cross-process "resume" of a dead broadcast is officially out-of-product (the API makes it impossible — creator ruling).
  6. ✅ Tests in ytLive.Tests (xUnit, net8.0-windows): TokenStore DPAPI roundtrip/corrupt/missing/clear + mocked exchange channel-parse + refresh expiry bump + ClearSession — 7 passing

Design constraint: Sign-in must NEVER block core exploration. Users can build scenes, add sources, and audition the software without authenticating. But going live requires authentication — the "Start Stream" dialog is where the account sign-in lives, alongside all stream metadata.

Two-state flow: There is no separate "Connect" button. The top bar shows a single button — Start Stream when idle, End Stream when live. Clicking Start Stream opens one dialog that supplies everything: account (previously-saved account shown as default, with a Change Account action) + title/description/visibility.

Live indicators (unmissable): Top bar + window title bar flip red, a pulsing ● LIVE badge with elapsed timer appears in the top bar, the preview area gets a red glow, and the taskbar icon shows a red overlay dot. Window title bar shows the stream title once validated.

Requirements:

  1. Google Cloud OAuth credentials — client ID + secret, baked into Helpers/OAuthCredentials.cs (desktop "Desktop app" OAuth client; loopback callback — no console redirect URI registration needed; creators never configure)
  2. Local HTTP listener — HttpListener on http://localhost:PORT/oauth2/callback to catch the redirect
  3. Browser launch — open the authorization URL in the default browser
  4. Token persistence — store access/refresh tokens securely (Windows DPAPI), reload on startup
  5. UI state — account shown in the Start Stream dialog; "Change Account" action triggers re-auth
  6. Go Live gated on auth — Start Stream dialog requires sign-in to enable the Start button; scene building works without it

Tests:

  1. Mock token exchange response, verify channel info parsed
  2. Verify token refresh triggers when near expiry
  3. Verify credential load/save roundtrip