code
Clone this repository
https://tangled.org/bretton.dev/coves-mobile
git@knot.bretton.dev:bretton.dev/coves-mobile
For self-hosted knots, clone URLs may differ based on your setup.
Update CovesApiService and VoteService with automatic 401 handling
and token refresh. With sealed tokens, the backend must proxy all
authenticated requests to user PDSs.
CovesApiService changes:
- Add tokenGetter, tokenRefresher, signOutHandler callbacks
- Dio interceptor for fresh token on each request
- Automatic retry on 401 with token refresh
- Prevent infinite loops with retried flag
- Sign out user if refresh fails
VoteService changes:
- Switch from direct PDS writes to backend-proxied votes
- Backend unseals token and uses stored DPoP keys
- Same 401 retry pattern as CovesApiService
- Remove OAuthSession dependency (was for DPoP)
New tests:
- Token refresh on 401 scenarios
- Retry prevention for refresh endpoint
- Sign out on failed refresh
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude <noreply@anthropic.com>
Simplify AuthProvider by delegating OAuth operations to the new
CovesAuthService. The provider now focuses on state management while
the service handles authentication logic.
Key changes:
- Use CovesSession instead of OAuthSession
- Simplified token access (sealed tokens are opaque)
- Dependency injection support for testing
- Token refresh delegated to CovesAuthService
Removed:
- Complex session getter with DPoP key management
- Direct PDS URL handling (backend proxies requests)
- Manual OAuth state machine management
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude <noreply@anthropic.com>
Switch from development callback URL to proper atproto-compliant
private-use URI scheme (RFC 8252):
- Scheme: social.coves:/callback (single slash per spec)
- Works on both Android and iOS without Universal Links complexity
Platform changes:
- Android: Update CallbackActivity intent filter scheme
- iOS: Update CFBundleURLSchemes in Info.plist
- Remove taskAffinity from MainActivity (not needed)
Dependencies:
- Add flutter_web_auth_2 for browser-based OAuth
- Remove atproto_oauth_flutter path dependency (to be deleted)
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude <noreply@anthropic.com>
New authentication service that delegates OAuth complexity to the Coves
backend. Instead of managing DPoP keys, PKCE, and token exchange client-side,
the backend handles everything and returns sealed tokens.
Key features:
- Browser-based OAuth via flutter_web_auth_2
- Secure token storage per environment (prevents cross-env token reuse)
- Mutex pattern for concurrent token refresh handling
- Handle/DID validation with Bluesky profile URL extraction
- Singleton pattern with test instance creation
The backend's /oauth/mobile/login endpoint handles:
- Handle → DID resolution
- PDS discovery
- PKCE/DPoP key generation
- Token exchange and sealing (AES-256-GCM)
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude <noreply@anthropic.com>
Simplified session model that works with the Coves backend's sealed token
architecture. The backend handles all OAuth complexity (DPoP, PKCE, token
refresh) and gives us an opaque AES-256-GCM encrypted token.
Key features:
- Parse session from OAuth callback URI (RFC 8252 private-use scheme)
- JSON serialization for secure storage persistence
- Immutable with copyWithToken for refresh operations
- Proper redaction of sensitive data in toString()
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude <noreply@anthropic.com>
- Add Android productFlavors (dev: social.coves.dev, prod: social.coves)
- Create iOS flavor xcconfig files for future scheme setup
- Update EnvironmentConfig to support flavor-based environment detection
- Add VSCode launch configurations for easy flavor switching
- Update app icon to lil_dude mascot with proper adaptive icon padding
Dev flavor points to local server, prod flavor points to coves.social.
Both apps can be installed side-by-side on the same device.
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude <noreply@anthropic.com>
- Store timeout timer reference and cancel it in finally block to prevent
stale timer from firing after operation completes
- Check if stream controller is closed before adding cancellation event
to prevent "Cannot add event after closing" error