Files
accounted/app/api/extensions
Mattsson 05dce83a2b feat(connect): Enable Banking client routes through the hosted proxy in connector mode (PR6b-1) (#2094)
* feat(connect): route the Enable Banking client through the hosted proxy in connector mode

PR6b-1 of the instance-side client wiring. Until now bankConnectorMode()
had no consumer but the status label; this makes a self-host with a
connector key and no own EB credentials actually reach Enable Banking
through the hosted bank proxy.

- api-client authenticatedFetch: in connector mode swap the base URL to
  the proxy and send the connector key as a Bearer token. The EB JWT
  signer (getAuthorizationHeader) is never called: the instance holds no
  private key. On hosted and on own-credentials self-hosts the direct
  path is byte-identical.
- startAuthorization forwards X-Connector-Company so the proxy can meter
  the per-company connection quota; index.ts passes companyId at both
  connect sites.
- createSession forwards the signed connector_state so the proxy binds
  the /sessions exchange to the pending ledger row (single-use, race-safe).
- callback route reads connector_state from the query (echoed by the
  hosted callback) and threads it through finalizeConnection.

Tests: connector-mode base/auth/company-header/connector_state assertions
in api-client, direct-path and own-credentials byte-identity, and the
callback threading both connector and direct paths.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01UzNkSsR18pLFitJdYn8QEb

* fix(connect): gate X-Connector-Company on connector mode, not on companyId

Skeptic regression finding: index.ts passes companyId to startAuthorization
unconditionally, and the header was attached whenever companyId was truthy.
On hosted and on own-credentials self-hosts companyId is always set, so every
direct POST /auth to the real Enable Banking API carried the tenant's internal
company UUID: a needless behavior change on the production path and an
identifier leak to a third-party PSD2 processor (the "byte-identical direct
path" claim was false).

Gate the header on bankConnectorMode() so it is sent only when the request
actually goes to the hosted proxy. Adds a direct-path test asserting the header
is absent even when companyId is passed.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01UzNkSsR18pLFitJdYn8QEb

---------

Co-authored-by: Claude Fable 5 <noreply@anthropic.com>
2026-09-01 10:26:40 +02:00
..
2026-07-21 23:00:15 +02:00