Skip to content

Commit 646f388

Browse files
feat: directed identity (#26)
* feat: support JWK client for directed identity * refactor: mv client formatting to meet api spec closer to api boundary * fix: non null type assertion * chore: changeset * chore: rm ts ignore comments * undo JWK client implementation for redesign * feat: client override * fix: lint * fix: changeset * chore: add clientOverride field doc string * feat: only allow JWK as a clientOverride --------- Co-authored-by: Max Kurapov <max@interledger.org>
1 parent 7c09bcd commit 646f388

3 files changed

Lines changed: 47 additions & 5 deletions

File tree

.changeset/early-monkeys-shave.md

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,5 @@
1+
---
2+
'@interledger/open-payments': minor
3+
---
4+
5+
Added optional client override (JWK) to grant request.

packages/open-payments/src/client/grant.test.ts

Lines changed: 32 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,12 @@
11
/* eslint-disable @typescript-eslint/no-explicit-any */
22
import { createGrantRoutes } from './grant'
33
import { OpenAPI, HttpMethod } from '@interledger/openapi'
4-
import { createTestDeps, mockGrantRequest, mockSubject } from '../test/helpers'
4+
import {
5+
createTestDeps,
6+
mockGrantRequest,
7+
mockJwk,
8+
mockSubject
9+
} from '../test/helpers'
510
import * as requestors from './requests'
611
import { v4 as uuid } from 'uuid'
712
import { getAuthServerOpenAPI } from '../openapi'
@@ -211,6 +216,32 @@ describe('grant', (): void => {
211216
)
212217
})
213218

219+
test('POST grant request with clientOverride uses override instead of default', async (): Promise<void> => {
220+
const postSpy = jest.spyOn(requestors, 'post')
221+
const grantRequest = mockGrantRequest()
222+
// eslint-disable-next-line @typescript-eslint/no-unused-vars
223+
const { client: _client, ...grantRequestWithoutClient } = grantRequest
224+
const jwk = mockJwk()
225+
226+
await createGrantRoutes({
227+
openApi,
228+
client,
229+
...deps
230+
}).request({ url }, grantRequestWithoutClient, { jwk })
231+
232+
expect(postSpy).toHaveBeenCalledWith(
233+
deps,
234+
{
235+
url,
236+
body: {
237+
...grantRequestWithoutClient,
238+
client: { jwk }
239+
}
240+
},
241+
true
242+
)
243+
})
244+
214245
test('POST grant request with neither access_token nor subject fails', async (): Promise<void> => {
215246
const emptyRequest: any = {
216247
interact: {

packages/open-payments/src/client/grant.ts

Lines changed: 10 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -13,7 +13,8 @@ import {
1313
GrantRequest,
1414
GrantContinuationRequest,
1515
AccessOutgoingWithDebitAmount,
16-
AccessOutgoingWithReceiveAmount
16+
AccessOutgoingWithReceiveAmount,
17+
JWK
1718
} from '../types'
1819
import { post, deleteRequest } from './requests'
1920

@@ -24,7 +25,11 @@ export interface GrantRouteDeps extends RouteDeps {
2425
export interface GrantRoutes {
2526
request(
2627
postArgs: UnauthenticatedResourceRequestArgs,
27-
args: Omit<GrantRequest, 'client'>
28+
args: Omit<GrantRequest, 'client'>,
29+
/**
30+
* Optionally override the default client configuration with a JWK for this specific grant request.
31+
*/
32+
clientOverride?: { jwk: JWK }
2833
): Promise<PendingGrant | Grant>
2934
continue(
3035
postArgs: GrantOrTokenRequestArgs,
@@ -58,7 +63,8 @@ export const createGrantRoutes = (deps: GrantRouteDeps): GrantRoutes => {
5863
return {
5964
request: async (
6065
{ url }: UnauthenticatedResourceRequestArgs,
61-
args: Omit<GrantRequest, 'client'>
66+
args: Omit<GrantRequest, 'client'>,
67+
clientOverride?: { jwk: JWK }
6268
) => {
6369
if (!args.access_token && !args.subject) {
6470
throw new OpenPaymentsClientError('Invalid Grant Request', {
@@ -90,7 +96,7 @@ export const createGrantRoutes = (deps: GrantRouteDeps): GrantRoutes => {
9096
url,
9197
body: {
9298
...args,
93-
client
99+
client: clientOverride ?? client
94100
}
95101
},
96102
requestGrantValidator

0 commit comments

Comments
 (0)