whisper-money/app/Http/Requests/OpenBanking
Víctor Falcón 690be20f21
feat(open-banking): add update credentials flow for API-key connections (#154)
## Why

### Problem

When API tokens for Indexa Capital, Binance, or Bitpanda expire or are
revoked, syncs fail silently with 401/403 errors. Users have no way to
replace their credentials without disconnecting and recreating the
entire connection (losing account mappings and history).

## What

### Changes

- **Auth failure email notification**: on the final retry attempt (3rd
of 3), if a sync job fails with 401/403 for an API-key provider, an
email is sent to the user with a link to the connections settings page
- **Update credentials endpoint**: `PATCH
/settings/connections/{connection}/credentials` validates new
credentials against the provider API before saving, then triggers a sync
- **Update credentials dialog**: provider-specific form (API token for
Indexa/Bitpanda, API key + secret for Binance) shown via an "Update
Credentials" button in the error banner and dropdown menu
- **Mailable**: `BankingConnectionAuthFailedEmail` follows existing
patterns (queued, rate-limited, Markdown template)
- **Form request**: `UpdateConnectionCredentialsRequest` with dynamic
validation rules per provider and authorization check

### Files changed

| File | Change |
|------|--------|
| `app/Jobs/SyncBankingConnectionJob.php` | Send auth failed email on
final attempt for auth errors on API-key providers |
| `app/Mail/BankingConnectionAuthFailedEmail.php` | New queued mailable
|
| `resources/views/mail/banking-connection-auth-failed.blade.php` |
Email template |
| `app/Http/Controllers/OpenBanking/ConnectionController.php` |
`updateCredentials()` action with provider credential validation |
| `app/Http/Requests/OpenBanking/UpdateConnectionCredentialsRequest.php`
| Dynamic validation per provider |
| `routes/settings.php` | PATCH route for credential updates |
| `resources/js/components/open-banking/update-credentials-dialog.tsx` |
Dialog with provider-specific fields |
| `resources/js/pages/settings/connections.tsx` | Update Credentials
button in error state and dropdown |

## Verification

### Tests

- **12 new tests** across 2 test files, all passing:
- `SyncBankingConnectionJobTest`: 5 tests covering email sent on final
retry (Indexa 401, Binance 403), not sent before final retry, not sent
for non-auth errors, not sent for EnableBanking
- `ConnectionControllerTest`: 7 tests covering valid credential update
for each provider, invalid credentials, EnableBanking rejection,
authorization, feature flag, required field validation
- Full OpenBanking test suite: **145 tests, 473 assertions** passing
2026-02-25 13:41:24 +01:00
..
ConnectBinanceRequest.php feat: Add Binance integration (#131) 2026-02-18 15:23:46 +01:00
ConnectBitpandaRequest.php feat: Add Bitpanda exchange integration (#132) 2026-02-19 09:26:31 +01:00
ConnectIndexaCapitalRequest.php feat: Add Indexa Capital integration (#130) 2026-02-18 10:42:13 +01:00
DestroyConnectionRequest.php feat: Integrate EnableBanking as open banking provider (#106) 2026-02-12 09:09:28 +01:00
ListInstitutionsRequest.php feat: Integrate EnableBanking as open banking provider (#106) 2026-02-12 09:09:28 +01:00
MapAccountsRequest.php feat: Integrate EnableBanking as open banking provider (#106) 2026-02-12 09:09:28 +01:00
StartAuthorizationRequest.php feat: Integrate EnableBanking as open banking provider (#106) 2026-02-12 09:09:28 +01:00
UpdateConnectionCredentialsRequest.php feat(open-banking): add update credentials flow for API-key connections (#154) 2026-02-25 13:41:24 +01:00