When tests run in parallel, they were sharing the same API key fixtures
which caused Redis rate limit counters to accumulate across test workers,
leading to unexpected rate limit errors.
Changes:
- Create fresh API keys in setup instead of using fixtures
- Each API key gets a unique auto-generated ID
- Clear existing active keys to avoid validation conflicts
- Use different sources (web/mobile) for multiple test keys
- Clear Redis rate limit data in setup to ensure clean state
- Update api_headers helper to use display_key instead of plain_key
This follows the existing pattern used in UsageControllerTest for
handling API keys that interact with Redis state.
* fix: replace hardcoded bg-white with bg-container in notification notice
* fix: replace hardcoded text-white with fg-inverse in notification CTA
* fix: replace hardcoded text-white with fg-inverse in text tooltip
* fix: replace hardcoded bg-gray-900 text-white with bg-inverse fg-inverse in invitations form
* fix: replace hardcoded bg-gray-800 text-white with bg-inverse fg-inverse in AI consent form
* fix: replace hardcoded text-white with fg-inverse in changelog page
* fix: replace hardcoded text-white and border-gray-500 with fg-inverse and border-secondary in investment tooltip
* fix: replace hardcoded text-white with fg-inverse in holdings missing price tooltip
* fix: replace hardcoded text-white and bg-gray-400 with fg-inverse and bg-surface-inset in settings profiles
* fix: replace hardcoded bg-orange-500 text-white with bg-yellow-600 fg-inverse in settings hosting danger zone
---------
Co-authored-by: Eran Avidor <eavidor@Eran-Avidor-MBP.lan>
* Handle reverse calculator starting portfolio generation correctly
* Fix current_holdings to handle different dates and hide zero quantities
- Use DISTINCT ON to get most recent holding per security instead of assuming same date
- Filter out zero quantity holdings from UI display
- Maintain cash display regardless of zero balance
- Use single efficient query with proper Rails syntax
* Continue to process holdings even if one is not resolvable
* Lint fixes
Updates outdated timezone identifiers in the database to their current
equivalents. This resolves ArgumentError exceptions when users have
outdated timezones like "Europe/Kiev" stored in their preferences.
Timezone mappings:
- Europe/Kiev → Europe/Kyiv
- Asia/Calcutta → Asia/Kolkata
- Asia/Katmandu → Asia/Kathmandu
- Asia/Rangoon → Asia/Yangon
- Asia/Saigon → Asia/Ho_Chi_Minh
- Pacific/Ponape → Pacific/Pohnpei
- Pacific/Truk → Pacific/Chuuk
🤖 Generated with Claude Code
Co-Authored-By: Claude <noreply@anthropic.com>
* Separate exclude and one-time transaction handling
- Split transaction "exclude" and "one-time" toggles into separate controls in transaction detail view
- Updated Transaction::Search to show excluded transactions with grayed-out styling instead of filtering them out
- Modified IncomeStatement calculations to exclude both excluded and one_time transactions from totals
- Added migration to convert existing excluded transactions to also be one_time for backward compatibility
- Updated transaction list view to show asterisk for one_time transactions and gray out excluded ones
- Added controller support for kind parameter in transaction updates
🤖 Generated with [Claude Code](https://claude.ai/code)
Co-Authored-By: Claude <noreply@anthropic.com>
* Fix linting issues
- Remove trailing whitespace from migration
- Fix ERB formatting throughout templates
🤖 Generated with [Claude Code](https://claude.ai/code)
Co-Authored-By: Claude <noreply@anthropic.com>
---------
Co-authored-by: Claude <noreply@anthropic.com>
- Remove trailing whitespace in auth controller and mobile device model
- Update API key test to expect new validation message with source
🤖 Generated with [Claude Code](https://claude.ai/code)
Co-Authored-By: Claude <noreply@anthropic.com>
- Replace API keys with OAuth2 tokens for mobile apps
- Add device tracking and management for mobile sessions
- Implement 30-day token expiration with refresh tokens
- Add MFA/2FA support for mobile login
- Create dedicated auth endpoints (signup/login/refresh)
- Skip CSRF protection for API endpoints
- Return plaintext tokens (not hashed) in responses
- Track devices with unique IDs and metadata
- Enable seamless native mobile experience without OAuth redirects
This provides enterprise-grade security for the iOS/Android apps while maintaining a completely native authentication flow.
🤖 Generated with [Claude Code](https://claude.ai/code)
Co-Authored-By: Claude <noreply@anthropic.com>
- Configure Doorkeeper to allow custom URL schemes (maybeapp://)
- Disable force_ssl_in_redirect_uri to support non-HTTPS schemes
- Add custom Doorkeeper views with mobile OAuth detection
- Disable Turbo for mobile OAuth flows to prevent redirect interference
- Add display parameter preservation through OAuth flow
- Create custom Doorkeeper layouts with proper styling
- Add comprehensive integration tests for mobile OAuth flows
- Ensure all OAuth pages use proper doorkeeper/application layout
This allows the mobile app to complete OAuth authorization flows
without the web app interfering with custom URL scheme redirects.
🤖 Generated with Claude Code
Co-Authored-By: Claude <noreply@anthropic.com>
- Add chats#index and chats#show endpoints to list and view AI conversations
- Add messages#create endpoint to send messages to AI chats
- Include API documentation for chat endpoints
- Add controller tests for new endpoints
🤖 Generated with [Claude Code](https://claude.ai/code)
Co-Authored-By: Claude <noreply@anthropic.com>
Auto-generate encryption keys based on SECRET_KEY_BASE when not provided.
This ensures API key encryption works out of the box for self-hosted users
without requiring manual setup steps.
🤖 Generated with [Claude Code](https://claude.ai/code)
Co-Authored-By: Claude <noreply@anthropic.com>
- Fix API key scopes validation in test (only one scope allowed)
- Update validation error test to match actual behavior
- Fix regenerating API key test path assertion
- Fix revoke confirmation dialog test to work with custom modal
- Fix trades test ticker symbol reference
- Add small delays for modal animations in system tests
All 59 system tests now pass.
🤖 Generated with [Claude Code](https://claude.ai/code)
Co-Authored-By: Claude <noreply@anthropic.com>
* OAuth
* Add API test routes and update Doorkeeper token handling for test environment
- Introduced API namespace with test routes for controller testing in the test environment.
- Updated Doorkeeper configuration to allow fallback to plain tokens in the test environment for easier testing.
- Modified schema to change resource_owner_id type from bigint to string.
* Implement API key authentication and enhance access control
- Replaced Doorkeeper OAuth authentication with a custom method supporting both OAuth and API keys in the BaseController.
- Added methods for API key authentication, including validation and logging.
- Introduced scope-based authorization for API keys in the TestController.
- Updated routes to include API key management endpoints.
- Enhanced logging for API access to include authentication method details.
- Added tests for API key functionality, including validation, scope checks, and access control enforcement.
* Add API key rate limiting and usage tracking
- Implemented rate limiting for API key authentication in BaseController.
- Added methods to check rate limits, render appropriate responses, and include rate limit headers in responses.
- Updated routes to include a new usage resource for tracking API usage.
- Enhanced tests to verify rate limit functionality, including exceeding limits and per-key tracking.
- Cleaned up Redis data in tests to ensure isolation between test cases.
* Add Jbuilder for JSON rendering and refactor AccountsController
- Added Jbuilder gem for improved JSON response handling.
- Refactored index action in AccountsController to utilize Jbuilder for rendering JSON.
- Removed manual serialization of accounts and streamlined response structure.
- Implemented a before_action in BaseController to enforce JSON format for all API requests.
* Add transactions resource to API routes
- Added routes for transactions, allowing index, show, create, update, and destroy actions.
- This enhancement supports comprehensive transaction management within the API.
* Enhance API authentication and onboarding handling
- Updated BaseController to skip onboarding requirements for API endpoints and added manual token verification for OAuth authentication.
- Improved error handling and logging for invalid access tokens.
- Introduced a method to set up the current context for API requests, ensuring compatibility with session-like behavior.
- Excluded API paths from onboarding redirects in the Onboardable concern.
- Updated database schema to change resource_owner_id type from bigint to string for OAuth access grants.
* Fix rubocop offenses
- Fix indentation and spacing issues
- Convert single quotes to double quotes
- Add spaces inside array brackets
- Fix comment alignment
- Add missing trailing newlines
- Correct else/end alignment
🤖 Generated with [Claude Code](https://claude.ai/code)
Co-Authored-By: Claude <noreply@anthropic.com>
* Fix API test failures and improve test reliability
- Fix ApiRateLimiterTest by removing mock users method and using fixtures
- Fix UsageControllerTest by removing mock users method and using fixtures
- Fix BaseControllerTest by using different users for multiple API keys
- Use unique display_key values with SecureRandom to avoid conflicts
- Fix double render issue in UsageController by returning after authorize_scope\!
- Specify controller name in routes for usage resource
- Remove trailing whitespace and empty lines per Rubocop
All tests now pass and linting is clean.
🤖 Generated with [Claude Code](https://claude.ai/code)
Co-Authored-By: Claude <noreply@anthropic.com>
* Add API transactions controller warning to brakeman ignore
The account_id parameter in the API transactions controller is properly
validated on line 79: family.accounts.find(transaction_params[:account_id])
This ensures users can only create transactions in accounts belonging to
their family, making this a false positive.
🤖 Generated with [Claude Code](https://claude.ai/code)
Co-Authored-By: Claude <noreply@anthropic.com>
---------
Signed-off-by: Josh Pigford <josh@joshpigford.com>
Co-authored-by: Claude <noreply@anthropic.com>