Skip to content

fix: correct Berlin Group SCA authorisation URL segment order#5

Open
hongwei1 wants to merge 5 commits into
OpenBankProject:mainfrom
hongwei1:main
Open

fix: correct Berlin Group SCA authorisation URL segment order#5
hongwei1 wants to merge 5 commits into
OpenBankProject:mainfrom
hongwei1:main

Conversation

@hongwei1

Copy link
Copy Markdown
Contributor

Summary

  • The payment SCA flow in otp/+page.server.ts called /obp/v1.3/berlin-group/..., but OBP-API registers these Berlin Group v1.3 payment routes at /berlin-group/v1.3/... with no /obp/ prefix (see Http4sBGv13AIS.scala/Http4sBGv13PIS.scala), so both the create-authorisation POST and the OTP-submit PUT were hitting a non-existent path.
  • Fixed both calls to use the correct /berlin-group/v1.3/${paymentService}/${paymentProduct}/${paymentId}/authorisations[/${authorisationId}] path.

Test plan

  • Exercise the Portal "payment" OTP flow end-to-end against a running OBP-API instance and confirm the authorisation POST/PUT succeed (200/201) instead of 404.

hongwei1 added 5 commits July 18, 2026 08:23
The payment SCA endpoints called /obp/v1.3/berlin-group/... but
OBP-API registers these routes at /berlin-group/v1.3/... with no
/obp/ prefix, so both the create-authorisation POST and OTP-submit
PUT calls were hitting a non-existent path.
…t approval

The SCA confirmation page submitted the OTP to
/obp/v3.1.0/banks/{bank}/consents/{id}/challenge, which only
transitions consents in status INITIATED -- Berlin Group consents are
created in status received, so this endpoint could never succeed
regardless of OTP correctness.

Call the real BG-native pair instead: start the authorisation in
load() (POST .../consents/{id}/authorisations) and submit the answer
in the form action (PUT .../consents/{id}/authorisations/{authorisationId}),
threading the authorisationId through a hidden form field.
The UK consent approval page only showed Confirm/Deny with no account
selection, and the SCA page's POST .../authorise call omitted account_ids
entirely. OBP-API's authorise endpoint now requires account_ids and rejects
any account the PSU doesn't hold, so this call was failing with 400.

Fetch the PSU's own accounts at the consent's bank (GET /my/accounts,
filtered by bank_id) and let them check which ones the requested
permissions apply to. Carry the selection through the SCA redirect as a
comma-joined account_ids query param, then a hidden form field, and
include it in the final POST .../authorise body.
SvelteKit's "?/actionName" shorthand replaces the page's entire query
string rather than appending to it. load() requires CONSENT_ID/bank_id
from the URL, so submitting a bare "?/confirm" or "?/deny" stripped them --
on any non-redirecting action response (e.g. a validation failure) load()
re-ran against the stripped URL and threw its own "Missing required
parameter" error, masking the action's real message.

Preserve the existing query string per SvelteKit's documented convention
for named actions on a page with search params.
…ookie

When exactly one provider is available, +page.server.ts's load() normally
auto-redirects straight to /login/{provider}, which mints a fresh
obp_oauth_state cookie. This page only renders that single-provider case
when an error/success message is suppressing the redirect (e.g. a failed
login retry) -- and it still ran a 60-second invalidateAll() interval in
that state. If invalidateAll() raced a real click on the provider link,
the interval's response could overwrite the state cookie the click's own
request had just set, causing an intermittent "Security validation
failed" state mismatch on the callback.

Skip the refresh interval whenever only one provider is available, and
disable preload on the provider link so hovering/tapping it can't mint an
extra state cookie ahead of the real navigation.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant