Skip to content

[AI] fix(enablebanking): fix HypoVereinsbank auth and data access#8355

Open
cakallie wants to merge 10 commits into
actualbudget:masterfrom
cakallie:fix/enablebanking-hvb-psu-headers
Open

[AI] fix(enablebanking): fix HypoVereinsbank auth and data access#8355
cakallie wants to merge 10 commits into
actualbudget:masterfrom
cakallie:fix/enablebanking-hvb-psu-headers

Conversation

@cakallie

@cakallie cakallie commented Jun 28, 2026

Copy link
Copy Markdown

Description

HypoVereinsbank auths via Enable Banking were routed to the corporate portal because the Psu-Ip-Address header was missing. With it present, the personal auth method is selected correctly. Additionally, PSU headers must not be sent on balance/transaction API calls — HypoVereinsbank returns an ASPSP_ERROR when they are present.

AI disclosure

This fix was developed with Claude Code (Anthropic).
The bug was identified and verified by a human; Claude Code assisted with
root cause analysis and implementation. Disclosed per the
AI Usage Policy.

🤖 Maintainer: please add the AI generated label per the AI usage policy.

Related issue(s)

Testing

Tested locally with a custom Docker build of the sync-server against a HypoVereinsbank personal account via Enable Banking. Authentication now correctly routes to the personal banking portal, and balance/transaction sync completes successfully.

Checklist

  • Release notes added (see link above)
  • No obvious regressions in affected areas
  • Self-review has been performed - I have read every line of this diff and can explain what each change does and why it is needed

Bundle Stats

Bundle Files count Total bundle size % Changed
desktop-client 29 13.12 MB 0%
loot-core 1 4.82 MB → 4.82 MB (+70 B) +0.00%
api 2 3.87 MB → 3.87 MB (+69 B) +0.00%
cli 1 8.02 MB 0%
crdt 1 11.12 kB 0%
View detailed bundle stats

desktop-client

Total

Files count Total bundle size % Changed
29 13.12 MB 0%
View detailed bundle breakdown

Added
No assets were added

Removed
No assets were removed

Bigger
No assets were bigger

Smaller
No assets were smaller

Unchanged

Asset File Size % Changed
static/js/index.js 7.63 MB 0%
static/js/AppliedFilters.js 36.47 kB 0%
static/js/BackgroundImage.js 121.09 kB 0%
static/js/FormulaEditor.js 730.27 kB 0%
static/js/PayeeRuleCountLabel.js 7.1 kB 0%
static/js/ReportRouter.js 1.24 MB 0%
static/js/TransactionList.js 85.19 kB 0%
static/js/ca.js 174.96 kB 0%
static/js/da.js 98.1 kB 0%
static/js/de.js 178.66 kB 0%
static/js/en-GB.js 9.19 kB 0%
static/js/en.js 200.96 kB 0%
static/js/es.js 168.01 kB 0%
static/js/extends.js 435.48 kB 0%
static/js/fr.js 170.14 kB 0%
static/js/indexeddb-main-thread-worker-e59fee74.js 13.46 kB 0%
static/js/it.js 155.85 kB 0%
static/js/narrow.js 358.73 kB 0%
static/js/nb-NO.js 139.4 kB 0%
static/js/nl.js 116.97 kB 0%
static/js/pl.js 139.16 kB 0%
static/js/pt-BR.js 176.89 kB 0%
static/js/th.js 170 kB 0%
static/js/theme.js 31.02 kB 0%
static/js/uk.js 204.65 kB 0%
static/js/useTransactionBatchActions.js 9.71 kB 0%
static/js/wide.js 306.06 kB 0%
static/js/workbox-window.prod.es5.js 7.21 kB 0%
static/js/zh-Hans.js 109.86 kB 0%

loot-core

Total

Files count Total bundle size % Changed
1 4.82 MB → 4.82 MB (+70 B) +0.00%
Changeset
File Δ Size
home/runner/work/actual/actual/packages/loot-core/src/server/accounts/sync.ts 📈 +70 B (+0.28%) 24.8 kB → 24.87 kB
View detailed bundle breakdown

Added

Asset File Size % Changed
kcab.worker.CPMGLcAv.js 0 B → 4.82 MB (+4.82 MB) -

Removed

Asset File Size % Changed
kcab.worker.BI4lxjlp.js 4.82 MB → 0 B (-4.82 MB) -100%

Bigger
No assets were bigger

Smaller
No assets were smaller

Unchanged
No assets were unchanged


api

Total

Files count Total bundle size % Changed
2 3.87 MB → 3.87 MB (+69 B) +0.00%
Changeset
File Δ Size
home/runner/work/actual/actual/packages/loot-core/src/server/accounts/sync.ts 📈 +69 B (+0.28%) 24.31 kB → 24.38 kB
View detailed bundle breakdown

Added
No assets were added

Removed
No assets were removed

Bigger

Asset File Size % Changed
index.js 3.87 MB → 3.87 MB (+69 B) +0.00%

Smaller
No assets were smaller

Unchanged

Asset File Size % Changed
models.js 0 B 0%

cli

Total

Files count Total bundle size % Changed
1 8.02 MB 0%
View detailed bundle breakdown

Added
No assets were added

Removed
No assets were removed

Bigger
No assets were bigger

Smaller
No assets were smaller

Unchanged

Asset File Size % Changed
cli.js 8.02 MB 0%

crdt

Total

Files count Total bundle size % Changed
1 11.12 kB 0%
View detailed bundle breakdown

Added
No assets were added

Removed
No assets were removed

Bigger
No assets were bigger

Smaller
No assets were smaller

Unchanged

Asset File Size % Changed
index.js 11.12 kB 0%

Carsten added 2 commits June 28, 2026 11:17
HypoVereinsbank falls back to corporate auth portal when psu-ip-address
header is missing, because the first auth_method is "business". Passing
the PSU headers from the incoming request selects the personal banking
method instead.
HypoVereinsbank requires Psu-Ip-Address during authorization to select
the personal auth method, but rejects it on balance/transaction API
calls with ASPSP_ERROR. Restrict PSU headers to startAuth only.

Also add balances/transactions consent scopes to the auth request
as required by the Enable Banking API.
@cakallie cakallie requested a review from matt-fidd as a code owner June 28, 2026 13:46
@actual-github-bot actual-github-bot Bot changed the title [AI] fix(enablebanking): fix HypoVereinsbank auth and data access [WIP] [AI] fix(enablebanking): fix HypoVereinsbank auth and data access Jun 28, 2026
@netlify

netlify Bot commented Jun 28, 2026

Copy link
Copy Markdown

Deploy Preview for actualbudget ready!

Name Link
🔨 Latest commit 3f1cd6d
🔍 Latest deploy log https://app.netlify.com/projects/actualbudget/deploys/6a4552e9c2e55400086ca6bb
😎 Deploy Preview https://deploy-preview-8355.demo.actualbudget.org
📱 Preview on mobile
Toggle QR Code...

QR Code

Use your smartphone camera to open QR code link.
🤖 Make changes Run an agent on this branch

To edit notification comments on pull requests, go to your Netlify project configuration.

@github-actions

Copy link
Copy Markdown
Contributor

👋 Hello contributor!

We would love to review your PR! Before we can do that, please make sure:

  • ✅ All CI checks pass
  • ✅ The PR is moved from draft to open (if applicable)
  • ✅ The "[WIP]" prefix is removed from the PR title
  • ✅ The PR description follows the provided template, with all checklist boxes filled in
  • ✅ All CodeRabbit code review comments are resolved (if you disagree with anything - reply to the bot with your reasoning so we can read through it). The bot will eventually approve the PR.
  • ✅ Any AI usage is disclosed (see our AI Usage Policy)

A quick note on volume: please get one PR reviewed and merged before opening several more. A stack of simultaneous, similar PRs from one author is reviewed slowly, and low-effort, untested, or undisclosed-AI PRs may be closed without a detailed review.

We do this to reduce the TOIL the core contributor team has to go through for each PR and to allow for speedy reviews and merges.

For more information, please see our Contributing Guide.

@netlify

netlify Bot commented Jun 28, 2026

Copy link
Copy Markdown

Deploy Preview for actualbudget-website ready!

Name Link
🔨 Latest commit 3f1cd6d
🔍 Latest deploy log https://app.netlify.com/projects/actualbudget-website/deploys/6a4552e9d42540000736bb6d
😎 Deploy Preview https://deploy-preview-8355.www.actualbudget.org
📱 Preview on mobile
Toggle QR Code...

QR Code

Use your smartphone camera to open QR code link.
🤖 Make changes Run an agent on this branch

To edit notification comments on pull requests, go to your Netlify project configuration.

@coderabbitai

coderabbitai Bot commented Jun 28, 2026

Copy link
Copy Markdown
Contributor

Review Change Stack

Note

Reviews paused

It looks like this branch is under active development. To avoid overwhelming you with review comments due to an influx of new commits, CodeRabbit has automatically paused this review. You can configure this behavior by changing the reviews.auto_review.auto_pause_after_reviewed_commits setting.

Use the following commands to manage reviews:

  • @coderabbitai resume to resume automatic reviews.
  • @coderabbitai review to trigger a single review.

Use the checkboxes below for quick actions:

  • ▶️ Resume reviews
  • 🔍 Trigger review
📝 Walkthrough

Walkthrough

Enable Banking auth and data-access requests now forward PSU headers conditionally, include ASPSP names in transaction downloads, and add a release note entry for the fix.

Changes

Enable Banking request routing

Layer / File(s) Summary
startAuth and request routing
packages/sync-server/src/app-enablebanking/services/enablebanking-service.ts, packages/sync-server/src/app-enablebanking/app-enablebanking.ts
startAuth accepts optional PSU headers, the /auth request now requests balances and transactions access while forwarding those headers, and /start-auth derives request headers from the incoming request before calling the service.
Data-access header selection
packages/sync-server/src/app-enablebanking/app-enablebanking.ts
buildSessionResult derives access headers from the ASPSP name, /transactions reads aspspName from the request body, and the balances and transactions calls use headers that may be omitted for specific ASPSPs.
Enable Banking transaction sync payload
packages/loot-core/src/server/accounts/sync.ts
downloadEnableBankingTransactions accepts an optional ASPSP name, and syncAccount loads the bank record to pass bankRow.name into the download request.
Release note entry
upcoming-release-notes/8355.md
A new release note file records the Enable Banking authentication routing and data-access fix as a bugfix entry.

Estimated code review effort

🎯 2 (Simple) | ⏱️ ~10 minutes

Possibly related PRs

  • actualbudget/actual#8028 — Also extends the Enable Banking auth flow by changing startAuth inputs and the /start-auth request path.
  • actualbudget/actual#8086 — Also touches the Enable Banking /transactions handler in app-enablebanking.ts, with another request-filtering change in the same route.

Suggested reviewers

  • matt-fidd
  • MatissJanis

Poem

🐇 Hop hop, the headers now align,
Through auth and balance paths they shine.
The bank name rides in every hop,
And data-access skips or stops.

🚥 Pre-merge checks | ✅ 4
✅ Passed checks (4 passed)
Check name Status Explanation
Linked Issues check ✅ Passed Check skipped because no linked issues were found for this pull request.
Out of Scope Changes check ✅ Passed Check skipped because no linked issues were found for this pull request.
Title check ✅ Passed The title clearly matches the main fix: HypoVereinsbank authentication plus data-access handling in Enable Banking.
Description check ✅ Passed The description matches the code changes and release note, covering HypoVereinsbank auth headers and PSU-header handling for balance and transaction calls.
✨ Finishing Touches
🧪 Generate unit tests (beta)
  • Create PR with unit tests

Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share

Comment @coderabbitai help to get the list of available commands.

@coderabbitai coderabbitai Bot left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 1

🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

Inline comments:
In `@packages/sync-server/src/app-enablebanking/app-enablebanking.ts`:
- Line 118: Scope the PSU-header stripping workaround to HypoVereinsbank only;
right now the `buildSessionResult()` path applies it for every ASPSP and can
affect downstream balance fetches and rate-limit handling. Update the logic
around `buildSessionResult` and the shared request helper so PSU headers are
removed only when the current bank is HypoVereinsbank, and leave all other ASPSP
requests unchanged.
🪄 Autofix (Beta)

Fix all unresolved CodeRabbit comments on this PR:

  • Push a commit to this branch (recommended)
  • Create a new PR with the fixes

ℹ️ Review info
⚙️ Run configuration

Configuration used: Path: .coderabbit.yaml

Review profile: CHILL

Plan: Pro

Run ID: 1f80f686-8739-4eca-8c56-91671e4f6b0f

📥 Commits

Reviewing files that changed from the base of the PR and between 33da5a3 and 4f48b78.

📒 Files selected for processing (2)
  • packages/sync-server/src/app-enablebanking/app-enablebanking.ts
  • packages/sync-server/src/app-enablebanking/services/enablebanking-service.ts

Comment thread packages/sync-server/src/app-enablebanking/app-enablebanking.ts Outdated
Instead of stripping PSU headers globally from balance/transaction fetches,
introduce `ASPSPS_WITHOUT_DATA_ACCESS_PSU_HEADERS` and `dataAccessPsuHeaders()`
so only ASPSPs known to reject these headers are affected. Other ASPSPs continue
to receive PSU headers on data access calls.

Also restore PSU headers being passed through `buildSessionResult()` at both
the auth_callback and poll-auth call sites, and propagate `aspspName` from the
client via the `/transactions` endpoint so the scoping helper has the context
it needs to decide.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
@coderabbitai coderabbitai Bot removed the size small label Jun 28, 2026

@coderabbitai coderabbitai Bot left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

♻️ Duplicate comments (1)
packages/sync-server/src/app-enablebanking/app-enablebanking.ts (1)

52-59: 🩺 Stability & Availability | 🟠 Major | ⚡ Quick win

Don't drop PSU headers when the ASPSP name is missing.

Line 56 currently treats an unknown aspspName the same as the HypoVereinsbank allowlist case. That means both buildSessionResult(session.aspsp?.name, ...) and /transactions will strip PSU headers whenever the bank name is absent, even though this workaround is supposed to be bank-specific.

Suggested fix
 function dataAccessPsuHeaders(
   aspspName: string | undefined,
   psuHeaders: PsuHeaders | undefined,
 ): PsuHeaders | undefined {
-  if (!aspspName || ASPSPS_WITHOUT_DATA_ACCESS_PSU_HEADERS.has(aspspName)) {
+  if (
+    aspspName &&
+    ASPSPS_WITHOUT_DATA_ACCESS_PSU_HEADERS.has(aspspName)
+  ) {
     return undefined;
   }
   return psuHeaders;
 }
🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@packages/sync-server/src/app-enablebanking/app-enablebanking.ts` around lines
52 - 59, The dataAccessPsuHeaders helper is incorrectly dropping PSU headers
whenever aspspName is missing, which makes unknown banks behave like the
ASPSPS_WITHOUT_DATA_ACCESS_PSU_HEADERS allowlist. Update dataAccessPsuHeaders so
it only returns undefined for explicit allowlisted ASPSP names and preserves
psuHeaders when aspspName is absent; this will keep
buildSessionResult(session.aspsp?.name, ...) and /transactions from stripping
headers unless the bank is specifically covered.
🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

Duplicate comments:
In `@packages/sync-server/src/app-enablebanking/app-enablebanking.ts`:
- Around line 52-59: The dataAccessPsuHeaders helper is incorrectly dropping PSU
headers whenever aspspName is missing, which makes unknown banks behave like the
ASPSPS_WITHOUT_DATA_ACCESS_PSU_HEADERS allowlist. Update dataAccessPsuHeaders so
it only returns undefined for explicit allowlisted ASPSP names and preserves
psuHeaders when aspspName is absent; this will keep
buildSessionResult(session.aspsp?.name, ...) and /transactions from stripping
headers unless the bank is specifically covered.

ℹ️ Review info
⚙️ Run configuration

Configuration used: Path: .coderabbit.yaml

Review profile: CHILL

Plan: Pro

Run ID: 7ac627d3-3c78-450d-875e-6a35d23a8ea8

📥 Commits

Reviewing files that changed from the base of the PR and between 392559e and fc7cfa5.

📒 Files selected for processing (2)
  • packages/loot-core/src/server/accounts/sync.ts
  • packages/sync-server/src/app-enablebanking/app-enablebanking.ts

coderabbitai[bot]
coderabbitai Bot previously approved these changes Jun 28, 2026
…known

The previous condition `!aspspName || set.has(aspspName)` stripped PSU headers
whenever aspspName was undefined, breaking all ASPSPs that don't send it.
The correct default is to pass headers through for unknown ASPSPs and only
strip them when the ASPSP is explicitly listed in the exclusion set.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
@cakallie cakallie changed the title [WIP] [AI] fix(enablebanking): fix HypoVereinsbank auth and data access [AI] fix(enablebanking): fix HypoVereinsbank auth and data access Jul 1, 2026
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant