Skip to content

Commit

Permalink
fix(pay): invoice url can be distinct from account url
Browse files Browse the repository at this point in the history
  • Loading branch information
wilsonianb committed Nov 9, 2021
1 parent 92c2155 commit dd67b42
Show file tree
Hide file tree
Showing 2 changed files with 3 additions and 48 deletions.
8 changes: 1 addition & 7 deletions packages/pay/src/open-payments.ts
Original file line number Diff line number Diff line change
Expand Up @@ -244,14 +244,8 @@ const validateOpenPaymentsInvoice = (o: any, queryUrl: string): Invoice | undefi
}

const accountUrl = AccountUrl.fromUrl(account)
// The base url has no query string, fragment, or trailing slash
const invoiceBaseUrl = accountUrl && accountUrl.toBaseUrl() + '/invoices' // Safe to append directly

if (
!accountUrl ||
!invoiceBaseUrl ||
!queryUrl.startsWith(invoiceBaseUrl) // Validates invoice is a subresource of this OP account
) {
if (!accountUrl) {
return
}

Expand Down
43 changes: 2 additions & 41 deletions packages/pay/test/setup.spec.ts
Original file line number Diff line number Diff line change
Expand Up @@ -161,12 +161,12 @@ describe('open payments', () => {
const invoiceId = uuid()

const accountUrl = 'https://wallet.example/alice'
const invoiceUrl = `${accountUrl}/invoices/${invoiceId}`
const invoiceUrl = `https://wallet.example/invoices/${invoiceId}`
const expiresAt = Date.now() + 60 * 60 * 1000 * 24 // 1 day in the future
const description = 'Coffee'

const scope = nock('https://wallet.example')
.get(`/alice/invoices/${invoiceId}`)
.get(`/invoices/${invoiceId}`)
.matchHeader('Accept', 'application/ilp-stream+json')
.reply(200, {
id: invoiceUrl,
Expand Down Expand Up @@ -200,45 +200,6 @@ describe('open payments', () => {
scope.done()
})

it('fails on invoice account mismatch', async () => {
const accountUrl = 'https://wallet.example/alice'
const invoiceUrl = `${accountUrl}/invoices/foo`

const invoice = {
id: invoiceUrl,
amount: '100',
received: '0',
assetCode: 'USD',
assetScale: 4,
expiresAt: new Date(Date.now() + 600000000).toISOString(),
description: 'Coffee',
ilpAddress: 'g.wallet.users.alice.~w6247823482374234',
sharedSecret: randomBytes(32).toString('base64'),
}

const scope1 = nock('https://wallet.example')
.get('/alice/invoices/foo')
.matchHeader('Accept', 'application/ilp-stream+json')
.reply(200, {
...invoice,
// Base URL is for a different account!
account: 'https://wallet.example/bob',
})
await expect(fetchPaymentDetails({ invoiceUrl })).resolves.toBe(PaymentError.QueryFailed)
scope1.done()

const scope2 = nock('https://wallet.example')
.get('/alice/invoices/foo')
.matchHeader('Accept', 'application/ilp-stream+json')
.reply(200, {
...invoice,
// Base URL is an invalid accountURL/not HTTPS
account: 'http://foo.bar',
})
await expect(fetchPaymentDetails({ invoiceUrl })).resolves.toBe(PaymentError.QueryFailed)
scope2.done()
})

it('fails if invoice amounts are not positive and u64', async () => {
const invoiceId = uuid()
const accountUrl = 'https://wallet.example/alice'
Expand Down

0 comments on commit dd67b42

Please sign in to comment.