Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
12 changes: 12 additions & 0 deletions .changeset/fix-signer-unsupported-algorithm-error.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
---
"@agentcommercekit/jwt": patch
---

`createJwtSigner` now reports which curve it could not handle.

The `default` branch called `new Error("Unsupported algorithm", keypair.curve)`.
`Error`'s second argument is an `ErrorOptions` object (`{ cause }`), not a
message part, so passing a string there is silently dropped at runtime and
fails to type-check under `strict` TypeScript. The curve is now interpolated
into the message instead, so the thrown error actually names the unsupported
curve.
19 changes: 18 additions & 1 deletion packages/jwt/src/signer.test.ts
Original file line number Diff line number Diff line change
@@ -1,6 +1,5 @@
import { generateKeypair } from "@agentcommercekit/keys"
import { describe, expect, test } from "vitest"

import { createJwtSigner } from "./signer"

describe("createJwtSigner", () => {
Expand Down Expand Up @@ -68,6 +67,24 @@ describe("createJwtSigner", () => {
expect(signature1).not.toBe(signature2)
})

test("throws a descriptive error for an unsupported curve", async () => {
const keypair = await generateKeypair("secp256k1")
// Simulate a Keypair with an invalid/unsupported curve, e.g. one that
// arrived from untrusted or future data and was never runtime-validated.
const invalidKeypair = {
...keypair,
curve: "invalid-curve",
}
// oxlint-disable-next-line typescript/no-unsafe-type-assertion -- intentionally passing invalid input to exercise runtime validation
const signerInput = invalidKeypair as unknown as Parameters<
typeof createJwtSigner
>[0]

expect(() => createJwtSigner(signerInput)).toThrow(
"Unsupported algorithm: invalid-curve",
)
})

test("handles both string and Uint8Array input", async () => {
const keypair = await generateKeypair("secp256k1")
const signer = createJwtSigner(keypair)
Expand Down
2 changes: 1 addition & 1 deletion packages/jwt/src/signer.ts
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,6 @@ export function createJwtSigner(keypair: Keypair): JwtSigner {
case "Ed25519":
return EdDSASigner(keypair.privateKey)
default:
throw new Error("Unsupported algorithm", keypair.curve)
throw new Error(`Unsupported algorithm: ${String(keypair.curve)}`)
}
}