Skip to content

Commit

Permalink
feat(backend): return Open Payments wallet address by default, make G…
Browse files Browse the repository at this point in the history
…ET spsp accept header explicit
  • Loading branch information
mkurapov committed May 21, 2024
1 parent 0e8e820 commit 7f6a65a
Show file tree
Hide file tree
Showing 6 changed files with 66 additions and 25 deletions.
27 changes: 27 additions & 0 deletions bruno/collections/Rafiki/SPSP/Get SPSP Payment Pointer.bru
Original file line number Diff line number Diff line change
@@ -0,0 +1,27 @@
meta {
name: Get SPSP Payment Pointer
type: http
seq: 1
}

get {
url: {{receiverWalletAddress}}
body: none
auth: none
}

headers {
Accept: application/spsp4+json
}

script:pre-request {
const scripts = require('./scripts');

scripts.addHostHeader("senderOpenPaymentsHost");
}

tests {
test("Status code is 200", function() {
expect(res.getStatus()).to.equal(200);
});
}
4 changes: 2 additions & 2 deletions packages/backend/src/app.ts
Original file line number Diff line number Diff line change
Expand Up @@ -660,6 +660,8 @@ export class App {
// Otherwise it will be matched instead of other Open Payments endpoints.
router.get(
WALLET_ADDRESS_PATH,
getWalletAddressUrlFromPath,
createSpspMiddleware(this.config.spspEnabled),
createValidatorMiddleware(
walletAddressServerSpec,
{
Expand All @@ -668,8 +670,6 @@ export class App {
},
validatorMiddlewareOptions
),
getWalletAddressUrlFromPath,
createSpspMiddleware(this.config.spspEnabled),
walletAddressRoutes.get
)

Expand Down
11 changes: 7 additions & 4 deletions packages/backend/src/payment-method/ilp/spsp/middleware.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -61,6 +61,8 @@ describe('SPSP Middleware', (): void => {
${'application/json'} | ${false} | ${'calls next'}
${'application/spsp4+json'} | ${true} | ${'calls SPSP route'}
${'application/spsp4+json'} | ${false} | ${'calls next'}
${'*/*'} | ${true} | ${'calls next'}
${'*/*'} | ${false} | ${'calls next'}
`(
'$description for accept header: $header and spspEnabled: $spspEnabled',
async ({ header, spspEnabled }): Promise<void> => {
Expand All @@ -70,17 +72,18 @@ describe('SPSP Middleware', (): void => {
ctx.headers['accept'] = header
const spspMiddleware = createSpspMiddleware(spspEnabled)
await expect(spspMiddleware(ctx, next)).resolves.toBeUndefined()
if (!spspEnabled || header == 'application/json') {
expect(spspSpy).not.toHaveBeenCalled()
expect(next).toHaveBeenCalled()
} else {

if (spspEnabled && header == 'application/spsp4+json') {
expect(spspSpy).toHaveBeenCalledTimes(1)
expect(next).not.toHaveBeenCalled()
expect(ctx.paymentTag).toEqual(walletAddress.id)
expect(ctx.asset).toEqual({
code: walletAddress.asset.code,
scale: walletAddress.asset.scale
})
} else {
expect(spspSpy).not.toHaveBeenCalled()
expect(next).toHaveBeenCalled()
}
}
)
Expand Down
3 changes: 2 additions & 1 deletion packages/backend/src/payment-method/ilp/spsp/middleware.ts
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
import { WalletAddressContext, SPSPContext } from '../../../app'
import { SPSP_CONTENT_TYPE_V4 } from './routes'

export type SPSPWalletAddressContext = WalletAddressContext &
SPSPContext & {
Expand Down Expand Up @@ -38,7 +39,7 @@ const spspMiddleware = async (
ctx: SPSPWalletAddressContext,
next: () => Promise<unknown>
): Promise<void> => {
if (ctx.accepts('application/spsp4+json')) {
if (ctx.request.header.accept?.includes(SPSP_CONTENT_TYPE_V4)) {
const walletAddressService = await ctx.container.use('walletAddressService')

const walletAddress = await walletAddressService.getByUrl(
Expand Down
35 changes: 21 additions & 14 deletions packages/backend/src/payment-method/ilp/spsp/routes.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -74,22 +74,29 @@ describe('SPSP Routes', (): void => {
return ctx
}

test('wrong Accept; returns 406', async () => {
const ctx = createContext<SPSPContext>({
headers: { Accept: 'application/json' }
})
test.each`
acceptHeader
${'application/json'}
${'*/*'}
`(
'Request with incorrect header ($acceptHeader) returns 406',
async ({ acceptHeader }) => {
const ctx = createContext<SPSPContext>({
headers: { Accept: acceptHeader }
})

expect.assertions(2)
try {
await spspRoutes.get(ctx)
} catch (err) {
assert.ok(err instanceof SPSPRouteError)
expect(err.status).toBe(406)
expect(err.message).toBe(
'Request does not support application/spsp4+json'
)
expect.assertions(2)
try {
await spspRoutes.get(ctx)
} catch (err) {
assert.ok(err instanceof SPSPRouteError)
expect(err.status).toBe(406)
expect(err.message).toBe(
'Request does not support application/spsp4+json'
)
}
}
})
)

test('nonce, no secret; returns 400', async () => {
const ctx = setup({ nonce })
Expand Down
11 changes: 7 additions & 4 deletions packages/backend/src/payment-method/ilp/spsp/routes.ts
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@ import base64url from 'base64url'
import { StreamServer } from '@interledger/stream-receiver'
import { SPSPRouteError } from './middleware'

const CONTENT_TYPE_V4 = 'application/spsp4+json'
export const SPSP_CONTENT_TYPE_V4 = 'application/spsp4+json'

export interface SPSPRoutes {
get(ctx: SPSPContext): Promise<void>
Expand Down Expand Up @@ -35,8 +35,11 @@ async function getSPSP(
deps: ServiceDependencies,
ctx: SPSPContext
): Promise<void> {
if (!ctx.accepts(CONTENT_TYPE_V4)) {
throw new SPSPRouteError(406, `Request does not support ${CONTENT_TYPE_V4}`)
if (!ctx.request.headers.accept?.includes(SPSP_CONTENT_TYPE_V4)) {
throw new SPSPRouteError(
406,
`Request does not support ${SPSP_CONTENT_TYPE_V4}`
)
}

const nonce = ctx.request.headers['receipt-nonce']
Expand All @@ -62,7 +65,7 @@ async function getSPSP(
asset: ctx.asset
})

ctx.set('Content-Type', CONTENT_TYPE_V4)
ctx.set('Content-Type', SPSP_CONTENT_TYPE_V4)
ctx.body = JSON.stringify({
destination_account: ilpAddress,
shared_secret: base64url(sharedSecret),
Expand Down

0 comments on commit 7f6a65a

Please sign in to comment.