Files
accounted/lib/connect/instance/__tests__/config.test.ts
T
Mattsson ca12b1855e fix(connect): PR #1758 CodeRabbit follow-up: connector status hardening, i18n strings, doc alignment (#2098)
* fix(connect): PR #1758 CodeRabbit follow-up: harden connector status, i18n the connector-mode strings, align docs

- getConnectorConfig() rebuilds baseUrl as origin + path: userinfo, query
  and fragment are stripped (warn-logged without the raw value) so nothing
  secret-shaped pasted into GNUBOK_CONNECT_URL survives into the
  /api/connector/status echo or the derived proxy URLs (CWE-200)
- /api/connector/status responds Cache-Control: no-store on both branches
  (key prefix + wiring layout out of shared browser caches, CWE-525)
- CWE-319 thread verified as no-change: both connector-mode helpers derive
  from getConnectorConfig(), which fails closed on non-https
- SkatteverketConnectPanel tooltips and BankSyncNowButton gate/upsell
  strings moved to messages/sv.json + messages/en.json keys
- DECISIONS.md: MD037 fix on line 1146 (backtick the glob), line 1147
  reworded to grants-written-wiring-pending, decision lines appended
  (incl. declining the UpgradeNote children-append suggestion)
- docs/SOVEREIGN.md availability wording aligned with SELF-HOSTING.md:
  infra merged, keys issued manually on request, client wiring pending

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

* docs(connect): skeptic follow-up: bank client wiring is merged (#2094), SKV pending, no keys issued until it lands

Skeptic refutation on PR #2098: SOVEREIGN.md claimed the services 'do not
carry traffic' while this branch already contains #2094 (EB client proxy
routing), and 'issued manually on request' contradicted the standing
no-key-before-full-PR6b rule while skatteverketConnectorMode() has no
client consumer yet. SOVEREIGN.md, SELF-HOSTING.md and DECISIONS.md line
1147 now all say: bank client wiring merged and carries traffic with a
key, Skatteverket client wiring ships in a following release, keys are
not issued until it lands.

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

---------

Co-authored-by: Claude Fable 5 <noreply@anthropic.com>
2026-09-01 11:16:37 +02:00

57 lines
2.5 KiB
TypeScript

import { describe, it, expect, afterEach, vi } from 'vitest'
import { getConnectorConfig, isConnectorConfigured } from '../config'
afterEach(() => vi.unstubAllEnvs())
describe('getConnectorConfig', () => {
it('is null without a key (hosted, or a self-host without a subscription)', () => {
vi.stubEnv('GNUBOK_CONNECTOR_KEY', '')
expect(getConnectorConfig()).toBeNull()
expect(isConnectorConfigured()).toBe(false)
})
it('defaults the hosted origin to app.gnubok.se and strips trailing slashes from an override', () => {
vi.stubEnv('GNUBOK_CONNECTOR_KEY', 'gnubok_ck_x')
vi.stubEnv('GNUBOK_CONNECT_URL', '')
expect(getConnectorConfig()).toEqual({ key: 'gnubok_ck_x', baseUrl: 'https://app.gnubok.se' })
vi.stubEnv('GNUBOK_CONNECT_URL', 'https://connect.example.se/')
expect(getConnectorConfig()?.baseUrl).toBe('https://connect.example.se')
})
it('rejects non-https and malformed GNUBOK_CONNECT_URL (fail closed: the key is never sent in plaintext)', () => {
vi.stubEnv('GNUBOK_CONNECTOR_KEY', 'gnubok_ck_x')
for (const bad of ['http://connect.example.se', 'ftp://connect.example.se', 'not a url', 'connect.example.se']) {
vi.stubEnv('GNUBOK_CONNECT_URL', bad)
expect(getConnectorConfig(), bad).toBeNull()
expect(isConnectorConfigured(), bad).toBe(false)
}
})
it('strips userinfo, query and fragment from the base URL (status echoes it back)', () => {
vi.stubEnv('GNUBOK_CONNECTOR_KEY', 'gnubok_ck_x')
for (const [dirty, clean] of [
['https://user:secret@connect.example.se', 'https://connect.example.se'],
['https://connect.example.se?token=secret', 'https://connect.example.se'],
['https://connect.example.se/base#fragment', 'https://connect.example.se/base'],
['https://user:secret@connect.example.se/base/?token=s#f', 'https://connect.example.se/base'],
]) {
vi.stubEnv('GNUBOK_CONNECT_URL', dirty)
expect(getConnectorConfig()?.baseUrl, dirty).toBe(clean)
}
})
it('keeps a clean override byte-identical (no surprise normalization)', () => {
vi.stubEnv('GNUBOK_CONNECTOR_KEY', 'gnubok_ck_x')
vi.stubEnv('GNUBOK_CONNECT_URL', 'https://connect.example.se/base')
expect(getConnectorConfig()?.baseUrl).toBe('https://connect.example.se/base')
})
it('allows plain http for loopback development hosts only', () => {
vi.stubEnv('GNUBOK_CONNECTOR_KEY', 'gnubok_ck_x')
for (const ok of ['http://localhost:3000', 'http://127.0.0.1:3000']) {
vi.stubEnv('GNUBOK_CONNECT_URL', ok)
expect(getConnectorConfig()?.baseUrl, ok).toBe(ok)
}
})
})