feat: youtube oauth via pkce loopback#99
Merged
ImpulseB23 merged 2 commits intomainfrom Apr 21, 2026
Merged
Conversation
|
This PR has 2875 lines changed. Consider splitting it into smaller PRs for easier review. |
Codecov Report❌ Patch coverage is 📢 Thoughts on this report? Let us know! |
There was a problem hiding this comment.
Pull request overview
Adds a YouTube OAuth sign-in stack to the Tauri (Rust) desktop app using Authorization Code + PKCE with an RFC 8252 loopback redirect, plus a small frontend UI to initiate/complete the flow and persist tokens in the OS keychain.
Changes:
- Introduces shared Rust
oauth_pkceprimitives (PKCE/state generation, loopback listener, token exchange helpers). - Adds
youtube_authRust module (tokens + keychain storage + manager + Tauri commands) and wires it into Taurisetup. - Adds frontend YouTube auth client, tests, and a header
YouTubeSignIncomponent.
Reviewed changes
Copilot reviewed 20 out of 21 changed files in this pull request and generated 8 comments.
Show a summary per file
| File | Description |
|---|---|
| docs/adr.md | Adds ADR 39 documenting YouTube OAuth via PKCE loopback and rationale. |
| apps/desktop/src/lib/youtubeAuth.ts | Frontend Tauri command client + safe opener for Google auth URL. |
| apps/desktop/src/lib/youtubeAuth.test.ts | Vitest coverage for YouTube auth command invokes + URL allowlist behavior. |
| apps/desktop/src/components/YouTubeSignIn.tsx | Header UI for Connect/Waiting/Connected + Disconnect states. |
| apps/desktop/src/components/Header.tsx | Renders the new YouTubeSignIn component in the header. |
| apps/desktop/src-tauri/src/youtube_auth/tokens.rs | Persistable YouTube token DTO + refresh threshold logic + tests. |
| apps/desktop/src-tauri/src/youtube_auth/storage.rs | Keychain + in-memory token store implementations + tests. |
| apps/desktop/src-tauri/src/youtube_auth/mod.rs | Public surface/constants for YouTube OAuth endpoints/scopes. |
| apps/desktop/src-tauri/src/youtube_auth/manager.rs | Core YouTube PKCE flow (start/complete/refresh) + channel identity fetch. |
| apps/desktop/src-tauri/src/youtube_auth/errors.rs | YouTube auth error taxonomy + mapping from PKCE primitives. |
| apps/desktop/src-tauri/src/youtube_auth/commands.rs | Tauri command wrappers for status/start/complete/cancel/logout. |
| apps/desktop/src-tauri/src/youtube_auth/auth_state.rs | Managed auth state shared by commands (pending flow + notify). |
| apps/desktop/src-tauri/src/oauth_pkce/success_page.html | Static “signed in” HTML page served by the loopback listener. |
| apps/desktop/src-tauri/src/oauth_pkce/pkce.rs | PKCE verifier/challenge + CSRF state generation. |
| apps/desktop/src-tauri/src/oauth_pkce/mod.rs | Module exports for shared PKCE/loopback/exchange building blocks. |
| apps/desktop/src-tauri/src/oauth_pkce/loopback.rs | One-shot loopback HTTP redirect listener + query parsing. |
| apps/desktop/src-tauri/src/oauth_pkce/exchange.rs | Form-encoded token exchange + refresh helpers + tests. |
| apps/desktop/src-tauri/src/oauth_pkce/errors.rs | Error types for PKCE primitives. |
| apps/desktop/src-tauri/src/lib.rs | Registers new commands + instantiates/manages YouTube auth state. |
| apps/desktop/src-tauri/Cargo.toml | Adds deps needed for PKCE + URL building and enables extra tokio features. |
| apps/desktop/src-tauri/Cargo.lock | Locks newly added Rust dependencies. |
|
This PR has 3083 lines changed. Consider splitting it into smaller PRs for easier review. |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Adds YouTube OAuth (Authorization Code + PKCE over loopback IP redirect, RFC 8252 §7.3) to match the existing Twitch sign-in stack.
ADR 39 covers the full rationale (DCG ruled out — Google restricts it to "limited-input devices" and YouTube scopes aren't on the allowed-scopes list; implicit / custom URL schemes / embedded WebView all rejected).
What's here:
oauth_pkceRust module (PKCE S256, CSRF state, loopbackTcpListeneron127.0.0.1:0, code-for-token exchange via hand-rolled form encoder since reqwest's.form()lives behind a feature we don't enable)youtube_authmodule mirroring thetwitch_authshape: tokens, keychain storage (prismoid.youtube/active), manager with proactive 5-min refresh (ADR 29), re-auth oninvalid_grant(ADR 31), Tauri commandsyoutube_auth_status,youtube_start_login,youtube_complete_login,youtube_cancel_login,youtube_logout)youtubeAuth.tsclient +YouTubeSignInheader component (Connect / Connected as / Disconnect)docs/adr.mdSidecar wiring for YouTube live-chat ingest is out of scope here; that's for a follow-up PR alongside the Kick OAuth (which will reuse the same
oauth_pkcemodule).Two things to swap before the YouTube button does anything real:
GOOGLE_CLIENT_IDandGOOGLE_CLIENT_SECRETinyoutube_auth/mod.rs(register a Desktop app credential at console.cloud.google.com)Tests: 260 Rust lib tests pass (42 new in
youtube_auth, 31 new inoauth_pkce), 84 vitest tests pass (9 new foryoutubeAuth.ts). Clippy clean, prettier clean, eslint clean, tsc clean.