feat(auth): replace setup-token with embedded /login terminal flow (#1321)
* feat(auth): replace setup-token with embedded /login terminal flow Migrate OAuth authentication from external `claude setup-token` command to an embedded terminal experience using `claude /login`: - Add AuthTerminal component for in-app authentication - Add session migration between profiles on profile switch - Add keychain utilities for macOS credential detection - Add profile change hook for terminal refresh after switch - Update error messages to reference /login instead of setup-token - Add i18n translations for all auth UI strings (EN + FR) - Fix Windows path handling in session utils - Harden Python temp file security (0o700 permissions, try-finally cleanup) Cross-platform support: - macOS: Full keychain integration - Windows: Credential files + .claude.json verification - Linux: Secret Service + .claude.json verification Co-Authored-By: Claude Opus 4.5 <[email protected]> * feat(auth): enhance OAuth flow with onboarding support - Update OAuth token handling to prioritize configDir over stored tokens, allowing full Keychain credential access including subscription type and rate limit tier. - Introduce `needsOnboarding` flag in OAuthTokenEvent to indicate when users must complete setup in the terminal. - Modify AuthTerminal component to reflect onboarding status and provide user guidance. - Update i18n strings for improved clarity on authentication steps and onboarding messages. - Fix tests This change improves the user experience by ensuring users are aware of necessary onboarding steps after receiving their OAuth token. * feat(auth): add onboarding complete detection and auto-close Detect when Claude Code shows the welcome/ready screen after OAuth login and automatically close the auth terminal. This improves the login UX by: - Adding handleOnboardingComplete() to detect ready state patterns - Auto-closing auth terminal after successful onboarding - Supporting re-authentication flow (logout first, then login) - Extracting email from welcome screen to update profiles - Adding TERMINAL_ONBOARDING_COMPLETE IPC channel * fix(auth): add backwards compatibility for re-authenticating old setup-token profiles When re-authenticating a profile that was set up with the old setup-token system, the browser wasn't opening because Claude CLI detected existing credentials in .claude.json and skipped the OAuth flow. Now when authenticateClaudeProfile is called: - Check if .claude.json exists with oauthAccount credentials - Back up existing credentials to .claude.json.bak - Allow /login to start fresh and open the browser for OAuth This ensures smooth transition from the old setup-token system to the new /login flow for existing profiles. Co-Authored-By: Claude Opus 4.5 <[email protected]> * chore: remove unused isReauth prop from auth terminal components Clean up the isReauth approach that was replaced by the backend fix (backing up .claude.json before re-authentication). Co-Authored-By: Claude Opus 4.5 <[email protected]> * fix(tests): remove obsolete CLAUDE_PROFILE_INITIALIZE tests and fix extractEmail expectation - Remove CLAUDE_PROFILE_INITIALIZE handler tests since the handler was deprecated as part of the migration to the new /login OAuth flow - Fix extractEmail test to expect correct behavior (email extraction now works for "Authenticated as [email protected]" format) Co-Authored-By: Claude Opus 4.5 <[email protected]> * fix(auth): use platform detection functions instead of undefined platform module Replace platform.system() calls with is_macos() and is_windows() functions that are already imported from core.platform. Co-Authored-By: Claude Opus 4.5 <[email protected]> * fix: address PR review findings (8 issues) HIGH priority fixes: - session-utils: Strip Windows drive letters to avoid invalid colons in paths - AuthTerminal: Use Math.max(0, ...) to prevent RangeError on long translations MEDIUM priority fixes: - session-utils: Clean up orphaned session file on partial migration failure - AuthTerminal: Add authCompletedRef to prevent race condition double-callback - AuthTerminal: Add successTimeoutRef for proper cleanup on unmount - claude-code-handlers: Add escapeBashCommand() for Linux terminal defense-in-depth LOW priority fixes: - keychain-utils: Use isMacOS() from platform module instead of direct check - claude-integration-handler: Centralize AUTH_TERMINAL_ID_PATTERN constant Co-Authored-By: Claude Opus 4.5 <[email protected]> * fix: complete remaining PR review issues (#7, #9) Issue #7 (MEDIUM): Code duplication in invokeClaude/invokeClaudeAsync - Add comprehensive unit tests for both functions (265 lines) - Extract shared logic into executeProfileCommand() and executeProfileCommandAsync() - Reduce ~60 lines of duplication while maintaining clarity - All 75 tests passing Issue #9 (LOW): Keychain error handling indistinguishable - Add optional error field to KeychainCredentials interface - Distinguish "not found" (exit 44) from actual failures - Update call site to log appropriate error instead of "will retry" - Backward compatible change Co-Authored-By: Claude Opus 4.5 <[email protected]> * ci: enable CodeQL scanning on all PRs Remove the if condition that was skipping CodeQL on pull requests. CodeQL will now run on all PRs, pushes to main, and weekly schedule. Note: This adds 40-60 min to PR checks but provides full security scanning. Co-Authored-By: Claude Opus 4.5 <[email protected]> * fix: address follow-up PR review findings (6 issues) MEDIUM priority fixes: - NEW-006: Add backup restoration when auth fails (.claude.json.bak) - NEW-002: Add configDir path validation to prevent arbitrary file reads - New utility: config-path-validator.ts - Validates paths in checkProfileAuthentication, CLAUDE_PROFILE_AUTHENTICATE, and CLAUDE_PROFILE_SAVE handlers LOW priority fixes: - NEW-003: Remove token length from warning logs (security hardening) - NEW-004: Eliminate TOCTOU race conditions in session migration - NEW-007: Remove sensitive buffer contents from debug logs - NEW-008: Use private temp directory for expect script (auth.py) FALSE POSITIVE (no fix needed): - NEW-005: Keychain cache keys are already unique per profile (hash-based) Co-Authored-By: Claude Opus 4.5 <[email protected]> * fix: path validator test mock and boundary check - Mock isValidConfigDir in tests to allow temp directory paths - Add path separator boundary check to prevent path traversal (e.g., /home/alice-malicious bypassing /home/alice validation) Co-Authored-By: Claude Opus 4.5 <[email protected]> * fix: address all PR review findings with quality improvements - LOGIC-001: Error results now cache for 10s (vs 5min) for quick recovery - SEC-001: Email logging changed to boolean hasEmail flag for privacy - LOGIC-004: Fixed misleading 'will retry' log message - TEST-001: Added 35 comprehensive unit tests for path validator - LOGIC-002: Replaced string matching with error.code checks - QUAL-002: Moved dynamic require to top-level import - QUAL-003: Refactored nested try-finally to TemporaryDirectory Additional quality improvements: - Extract isNodeError type guard to shared utils/type-guards.ts - Fix logging convention (console.log for success, warn for errors) Co-Authored-By: Claude Opus 4.5 <[email protected]> * fix: address cursor bot and additional review findings Fixes: - Linux command escaping: Remove escapeBashCommand for trusted install commands that use semicolons as statement separators - Session path format: Keep leading dash to match Claude CLI format (-Users-foo-bar instead of Users-foo-bar) - Platform test coverage: Run Unix path tests on all platforms, document Node.js path.resolve() platform-specific behavior - Security executable: Use path resolution instead of hardcoded /usr/bin/security - PII logging: Add maskEmail() helper and redact emails in console.warn calls Additional quality improvements (NEW-003 through NEW-006): - Token validation: Use 'sk-ant-' prefix for future compatibility - Logging level: Use console.debug for successful credential retrieval - Stale backup cleanup: Remove old .claude.json.bak on auth start - Temp directory: Remove predictable prefix for defense-in-depth Co-Authored-By: Claude Opus 4.5 <[email protected]> * fix: remove premature backup deletion that could lose valid credentials NEW-005-REVIEW: The stale backup cleanup at AUTHENTICATE handler was flawed. It assumed "both .claude.json and .bak exist = previous auth succeeded" but this is wrong - the app could have crashed after /login wrote an incomplete .claude.json but before VERIFY_AUTH confirmed valid credentials. Removed the premature cleanup. Backup deletion now only happens: 1. In VERIFY_AUTH after confirming valid credentials (safe) 2. When creating a new backup (removes old backup first) Co-Authored-By: Claude Opus 4.5 <[email protected]> * fix: AUTH_TERMINAL_ID_PATTERN regex to match actual profile IDs The old regex only matched 'default' or 'profile-\d+' but actual profile IDs are sanitized names like 'work', 'my-profile' generated by generateProfileId(). This caused OAuth token capture to silently fail for all non-default profiles. Updated regex to match the actual profile ID format: lowercase letters, numbers, and hyphens with a 13+ digit timestamp suffix. Co-Authored-By: Claude Opus 4.5 <[email protected]> --------- Co-authored-by: Test User <[email protected]> Co-authored-by: Claude Opus 4.5 <[email protected]>
This commit is contained in:
co-authored by
Test User
Claude Opus 4.5
parent
8a2f3acd4a
commit
11f8d572ff
@@ -1,9 +1,8 @@
|
||||
name: Quality Security
|
||||
|
||||
# CodeQL is slow (20-30 min per language), so:
|
||||
# - Run on push to main only (not PRs or develop)
|
||||
# - Run weekly scheduled scan
|
||||
# Bandit is fast (5-10 min), so keep it on all PRs
|
||||
# CodeQL runs on all PRs, pushes to main, and weekly schedule
|
||||
# Note: CodeQL takes 20-30 min per language (40-60 min total)
|
||||
# Bandit is fast (5-10 min)
|
||||
|
||||
on:
|
||||
push:
|
||||
@@ -35,13 +34,10 @@ permissions:
|
||||
actions: read
|
||||
|
||||
jobs:
|
||||
# CodeQL only on push to main or scheduled (NOT on PRs - saves 40-60 min per PR)
|
||||
codeql:
|
||||
name: CodeQL (${{ matrix.language }})
|
||||
runs-on: ubuntu-latest
|
||||
timeout-minutes: 30
|
||||
# Only run on push to main or scheduled - skip PRs for speed
|
||||
if: github.event_name == 'push' || github.event_name == 'schedule'
|
||||
strategy:
|
||||
fail-fast: false
|
||||
matrix:
|
||||
|
||||
Reference in New Issue
Block a user