Skip to content

feat: pass Bearer token credentials through to Rust client#11

Merged
w1am merged 4 commits into
masterfrom
w1am/dev-1644-pass-bearer-token-credentials-through-kurrentbridge-to-rust
May 5, 2026
Merged

feat: pass Bearer token credentials through to Rust client#11
w1am merged 4 commits into
masterfrom
w1am/dev-1644-pass-bearer-token-credentials-through-kurrentbridge-to-rust

Conversation

@w1am
Copy link
Copy Markdown
Contributor

@w1am w1am commented May 5, 2026

Summary

  • Bumps kurrentdb to 1.1.0 (the version DEV-1643 published with the new Authentication enum) and reworks the bridge to detect credential shape on the JS side: { bearerToken } becomes Authentication::Bearer, { username, password } becomes Authentication::Basic.
  • Widens RustReadStreamOptions.credentials and RustReadAllOptions.credentials to a Credentials = BasicCredentials | BearerCredentials discriminated union, mirroring the Node client's shape from DEV-1642.
  • Adds bridge-level integration tests for both readStream and readAll covering basic and bearer credentials. The tests run against the existing insecure docker-compose KurrentDB; success proves the JS->Rust plumbing carries bearer tokens without error (header structure is independently verified by the Rust crate's unit tests in DEV-1643).

Closes DEV-1644. Once this is published, packages/db-client/src/streams/{readStream,readAll}.ts in the Node client can drop their bearer-token guard and resolve authorizationHeaderProvider into a Credentials value before calling the bridge, closing DEV-1341.

Out of scope of this PR

  • Rebuilding platform binaries via release-package.yml and publishing the new @kurrent/bridge npm version — those run as the workflow-driven release step after merge.

Test plan

  • cargo build -p bridge succeeds against kurrentdb = 1.1.0.
  • npx tsc produces the updated lib/index.d.ts with the discriminated union.
  • node --test — all 12 tests pass against docker compose up -d KurrentDB, including the 3 new credential cases.
  • CI matrix (Linux x64/arm64, macOS x64/arm64, Windows x64) builds the Neon binaries on the release workflow.

Detect `{ bearerToken }` vs `{ username, password }` on the JS credentials
object and construct the matching `Authentication` variant from kurrentdb 1.1.0.

- Bump kurrentdb to 1.1.0 (DEV-1643 added the Authentication enum).
- Bridge `read_stream` and `read_all` now branch on credential shape via a
  shared `authentication_from_js` helper and emit `Authentication::Bearer` or
  `Authentication::Basic` accordingly.
- Widen `RustReadStreamOptions.credentials` and `RustReadAllOptions.credentials`
  to a `Credentials = BasicCredentials | BearerCredentials` discriminated
  union, mirroring the Node client's shape from DEV-1642.
- Add bridge-level integration tests covering basic and bearer reads on both
  `readStream` and `readAll`.

Closes DEV-1644.
@qodo-code-review
Copy link
Copy Markdown

Review Summary by Qodo

Support Bearer token credentials in Kurrent bridge

✨ Enhancement

Grey Divider

Walkthroughs

Description
• Support Bearer token credentials alongside basic auth in bridge
• Add authentication_from_js helper to detect credential shape
• Widen credentials types to discriminated union (BasicCredentials | BearerCredentials)
• Add integration tests for bearer token and basic auth flows
Diagram
flowchart LR
  JS["JS Credentials Object<br/>bearerToken or username/password"]
  Helper["authentication_from_js<br/>Helper Function"]
  Auth["Authentication Enum<br/>Bearer or Basic"]
  RustClient["Rust Client<br/>kurrentdb 1.1.0"]
  
  JS -- "Detect shape" --> Helper
  Helper -- "Convert to" --> Auth
  Auth -- "Pass through" --> RustClient
Loading

Grey Divider

File Changes

1. crates/bridge/Cargo.toml Dependencies +1/-1

Update kurrentdb dependency to 1.1.0

• Bump kurrentdb dependency from 1.0.0-alpha.4 to 1.1.0
• Enables use of new Authentication enum with Bearer token support

crates/bridge/Cargo.toml


2. crates/bridge/src/client.rs ✨ Enhancement +17/-16

Add authentication helper for bearer and basic credentials

• Add authentication_from_js helper function to detect credential shape and construct appropriate
 Authentication variant
• Replace inline basic credential extraction with call to new helper in both read_stream and
 read_all functions
• Update imports to include Authentication and remove unused Credentials
• Support both { bearerToken } and { username, password } credential objects

crates/bridge/src/client.rs


3. src/index.ts ✨ Enhancement +6/-2

Add discriminated union types for credentials

• Define BasicCredentials type with username and password fields
• Define BearerCredentials type with bearerToken field
• Create Credentials discriminated union type combining both credential types
• Update RustReadStreamOptions.credentials and RustReadAllOptions.credentials to use new
 Credentials union type

src/index.ts


View more (1)
4. test/read.test.js 🧪 Tests +44/-0

Add integration tests for credential types

• Add test for readStream with basic credentials (username and password)
• Add test for readStream with bearer token credentials
• Add test for readAll with bearer token credentials
• All tests verify correct event count is returned after successful read

test/read.test.js


Grey Divider

Qodo Logo

@qodo-code-review
Copy link
Copy Markdown

qodo-code-review Bot commented May 5, 2026

Code Review by Qodo

🐞 Bugs (0) 📘 Rule violations (0) 📎 Requirement gaps (0)

Grey Divider


Remediation recommended

1. Unclear credentials shape error🐞 Bug ◔ Observability
Description
authentication_from_js implicitly falls back to reading username/password when bearerToken
is absent, so malformed credential objects (e.g. {}, typos like { bearer_token: ... }) throw a
generic Neon missing-property/type error instead of a clear “credentials must be …” validation
error. This makes misconfiguration hard to diagnose for JS callers and surfaces confusing exceptions
at runtime.
Code

crates/bridge/src/client.rs[R64-75]

+fn authentication_from_js<'a>(
+    cx: &mut FunctionContext<'a>,
+    obj: Handle<'a, JsObject>,
+) -> NeonResult<Authentication> {
+    if let Some(token) = obj.get_opt::<JsString, _, _>(cx, "bearerToken")? {
+        return Ok(Authentication::bearer(token.value(cx)));
+    }
+
+    let login = obj.get::<JsString, _, _>(cx, "username")?.value(cx);
+    let password = obj.get::<JsString, _, _>(cx, "password")?.value(cx);
+    Ok(Authentication::basic(login, password))
+}
Evidence
The bridge chooses bearer auth only if bearerToken exists; otherwise it unconditionally attempts
to read username and password as strings, which will throw if either is missing or not a string.
Since the TypeScript API exposes credentials?: Credentials but provides no runtime validation, JS
callers can easily pass malformed objects (from plain JS or from any), leading to cryptic errors
instead of a targeted validation message.

crates/bridge/src/client.rs[64-75]
crates/bridge/src/client.rs[118-120]
src/index.ts[38-49]

Agent prompt
The issue below was found during a code review. Follow the provided context and guidance below and implement a solution

## Issue description
The bridge currently infers authentication type from the presence of `bearerToken`, otherwise it assumes basic auth and directly reads `username`/`password`. If the object doesn’t match either shape, the code throws a low-level Neon error (missing property / type mismatch) that is hard to interpret.

## Issue Context
This parsing is used by both `read_stream` and `read_all` when `options.credentials` is supplied.

## Fix Focus Areas
- crates/bridge/src/client.rs[64-75]

## Suggested fix
- Validate the credentials object shape explicitly before accessing fields:
 - If `bearerToken` is present:
   - Ensure it’s a non-empty string (or at least a string), otherwise throw `TypeError("credentials.bearerToken must be a string")`.
 - Else:
   - Ensure **both** `username` and `password` exist and are strings; if not, throw `TypeError("credentials must include either { bearerToken } or { username, password }")`.
- Prefer throwing a targeted error via `cx.throw_type_error(...)` / `cx.throw_error(...)` so JS callers get an actionable message.

ⓘ Copy this prompt and use it to remediate the issue with your preferred AI generation tools


Grey Divider

Qodo Logo

w1am added 3 commits May 5, 2026 12:05
Validate credentials shape explicitly so JS callers get a targeted error instead of a low-level Neon property/type message:

- bearerToken present but not a string -> 'credentials.bearerToken must be a string'.
- Otherwise require both username and password as strings -> 'credentials must include either { bearerToken } or { username, password }'.
@w1am w1am merged commit fcf01d5 into master May 5, 2026
2 checks passed
@w1am w1am deleted the w1am/dev-1644-pass-bearer-token-credentials-through-kurrentbridge-to-rust branch May 5, 2026 08:49
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