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
4 changes: 2 additions & 2 deletions packages/ack-pay/src/errors.ts
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
export class InvalidPaymentRequestTokenError extends Error {
constructor(message = "Invalid payment request token") {
super(message)
constructor(message = "Invalid payment request token", options?: ErrorOptions) {
super(message, options)
this.name = "InvalidPaymentRequestTokenError"
}
}
60 changes: 36 additions & 24 deletions packages/ack-pay/src/verify-payment-request-token.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,7 @@ import { generateKeypair, type Keypair } from "@agentcommercekit/keys"
import { beforeEach, describe, expect, it } from "vitest"

import { createSignedPaymentRequest } from "./create-signed-payment-request"
import { InvalidPaymentRequestTokenError } from "./errors"
import type { PaymentRequestInit } from "./payment-request"
import { verifyPaymentRequestToken } from "./verify-payment-request-token"

Expand Down Expand Up @@ -78,18 +79,21 @@ describe("verifyPaymentRequestToken", () => {
expect(result.parsed.issuer).toEqual(issuerDid)
})

it("throws for invalid JWT format", async () => {
it("throws for invalid JWT format with original error as cause", async () => {
const resolver = getDidResolver()
resolver.addToCache(issuerDid, issuerDidDocument)

await expect(
verifyPaymentRequestToken("invalid.jwt.token", {
resolver,
}),
).rejects.toThrow("Invalid payment request token")
const error = await verifyPaymentRequestToken("invalid.jwt.token", {
resolver,
}).catch((e) => e)

expect(error).toBeInstanceOf(InvalidPaymentRequestTokenError)
expect(error.message).toBe("Invalid payment request token")
expect(error.cause).toBeDefined()
expect(error.cause).toBeInstanceOf(Error)
})

it("throws for expired JWT", async () => {
it("throws for expired JWT with original error as cause", async () => {
// Create a JWT with an expiration date in the past
const expiredPayload = {
...paymentRequest,
Expand All @@ -111,11 +115,13 @@ describe("verifyPaymentRequestToken", () => {
const resolver = getDidResolver()
resolver.addToCache(issuerDid, issuerDidDocument)

await expect(
verifyPaymentRequestToken(expiredToken, {
resolver,
}),
).rejects.toThrow("Invalid payment request token")
const error = await verifyPaymentRequestToken(expiredToken, {
resolver,
}).catch((e) => e)

expect(error).toBeInstanceOf(InvalidPaymentRequestTokenError)
expect(error.cause).toBeDefined()
expect(error.cause).toBeInstanceOf(Error)
})

it("allows expired JWT when expiry verification is disabled", async () => {
Expand Down Expand Up @@ -150,7 +156,7 @@ describe("verifyPaymentRequestToken", () => {
expect(result.parsed.issuer).toEqual(issuerDid)
})

it("throws for JWT with invalid signature", async () => {
it("throws for JWT with invalid signature with original error as cause", async () => {
const body = await createSignedPaymentRequest(paymentRequest, {
issuer: issuerDid,
signer,
Expand All @@ -168,14 +174,16 @@ describe("verifyPaymentRequestToken", () => {
}),
)

await expect(
verifyPaymentRequestToken(body.paymentRequestToken, {
resolver,
}),
).rejects.toThrow("Invalid payment request token")
const error = await verifyPaymentRequestToken(body.paymentRequestToken, {
resolver,
}).catch((e) => e)

expect(error).toBeInstanceOf(InvalidPaymentRequestTokenError)
expect(error.cause).toBeDefined()
expect(error.cause).toBeInstanceOf(Error)
})

it("throws for a JWT that does not contain a payment config", async () => {
it("throws for a JWT that does not contain a payment config without cause", async () => {
// Create a JWT with valid format but missing payment config
const invalidToken = await createJwt(
{ sub: "test-payment-request-id" },
Expand All @@ -188,10 +196,14 @@ describe("verifyPaymentRequestToken", () => {
const resolver = getDidResolver()
resolver.addToCache(issuerDid, issuerDidDocument)

await expect(
verifyPaymentRequestToken(invalidToken, {
resolver,
}),
).rejects.toThrow("Payment Request token is not a valid PaymentRequest")
const error = await verifyPaymentRequestToken(invalidToken, {
resolver,
}).catch((e) => e)

expect(error).toBeInstanceOf(InvalidPaymentRequestTokenError)
expect(error.message).toBe(
"Payment Request token is not a valid PaymentRequest",
)
expect(error.cause).toBeUndefined()
})
})
4 changes: 2 additions & 2 deletions packages/ack-pay/src/verify-payment-request-token.ts
Original file line number Diff line number Diff line change
Expand Up @@ -43,8 +43,8 @@ export async function verifyPaymentRequestToken(
exp: options.verifyExpiry ?? true,
},
})
} catch (_err) {
throw new InvalidPaymentRequestTokenError()
} catch (err) {
throw new InvalidPaymentRequestTokenError(undefined, { cause: err })
}

const { success, output } = v.safeParse(
Expand Down