feat(auth): OAuth 2.1 + PKCE authentication for browser extensions#270
Merged
feat(auth): OAuth 2.1 + PKCE authentication for browser extensions#270
Conversation
Adds secure PKCE-based authentication for browser extensions, replacing cookie-based auth on Chrome and providing a fallback for Firefox. Key changes: - PKCEManager.ts: Generate code verifier/challenge pairs for OAuth - OAuthService.ts: Orchestrate PKCE flow using browser.identity API - JwtManager: Store OAuth tokens (access + refresh), support token rotation - background.ts: Handle AUTHENTICATE_WITH_PKCE message - auth-shared.js: Try PKCE first, fall back to tab-based flow - AuthPromptController: Trigger PKCE auth directly from prompts - Added 'identity' permission for Chrome Benefits: - No client secrets needed (public client flow) - Secure token refresh via OAuth refresh tokens - Better UX: inline auth popup instead of new tab (Chrome) - Fallback to existing flow for Firefox 🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
…error Vite's modulepreload helper uses `document.createElement` which fails in service workers. Changed from dynamic import to static import to fix: "ReferenceError: document is not defined" 🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
Add isClearing flag to JwtManager to prevent in-flight token refreshes from re-authenticating the user during sign-out. Changes: - Add isClearing flag that blocks refresh operations during sign-out - Make clear() async to properly await storage removal - Add guards to performRefresh(), refresh(), and refreshWithOAuth() - Add isPKCEAuthInProgress flag to prevent cookie listener interference - Update background.ts to await clear() calls Fixes issue where signing out would trigger: 1. clear() sets token to null 2. In-flight refresh completes and writes new token 3. User appears re-authenticated immediately 🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
…rror Follow-up to 190c23b - apply the same static import fix to PKCEManager that was applied to OAuthService. Changes: - Replace dynamic imports with static import for wxt/browser - Disable modulePreload in wxt.config.ts to prevent window-dependent polyfill injection into service worker bundles - Add tests for PKCE state storage functions 🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
Add comprehensive spec document covering: - Why PKCE is needed for browser extensions (public clients) - Chrome Identity API integration details - Required server endpoints and behavior - Redirect URI registration requirements - Acceptance criteria for implementation This document served as the implementation guide for the PKCE auth flow and documents known issues encountered during development. 🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
Also update PKCE spec with implementation status. 🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
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.
Summary
Implements OAuth 2.1 + PKCE (Proof Key for Code Exchange) authentication flow for the SayPi browser extension, replacing the cookie-based authentication on Chrome while maintaining fallback support for Firefox.
Why PKCE?
Changes
New Files
src/auth/PKCEManager.tssrc/auth/OAuthService.tsbrowser.identity.launchWebAuthFlowtest/auth/PKCEManager.spec.tsModified Files
wxt.config.tsidentitypermission for Chromesrc/JwtManager.tssetOAuthTokens(),refreshWithOAuth(),performRefresh()src/svc/background.tsAUTHENTICATE_WITH_PKCEmessage handler, updated alarm handler for OAuth refreshsrc/popup/auth-shared.jssrc/auth/AuthPromptController.tstest/JwtManager.spec.tsoauthRefreshTokenfieldAuthentication Flow
Chrome (Primary - PKCE)
browser.identity.launchWebAuthFlow()opens inline auth popup/api/oauth/tokenFirefox (Fallback - Tab-based)
cookies.onChangedlistener detects auth completionToken Management
jwt:auth:failedTest Plan
Dependencies
Requires the SaaS backend OAuth 2.1 + PKCE endpoints from saypi-saas PR #66.
🤖 Generated with Claude Code