-
Notifications
You must be signed in to change notification settings - Fork 89
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
chore(backend): update wallet address middleware & error handling #2722
Changes from 11 commits
7dfef7a
82ba51c
2dbf255
02abf51
9641dc7
7f1ac04
eeb2d51
1b22bc8
110bd68
b52207d
0e8e820
7f6a65a
bffcaa5
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -24,8 +24,6 @@ import { HttpTokenService } from './payment-method/ilp/peer-http-token/service' | |
import { AssetService, AssetOptions } from './asset/service' | ||
import { AccountingService } from './accounting/service' | ||
import { PeerService } from './payment-method/ilp/peer/service' | ||
import { createWalletAddressMiddleware } from './open_payments/wallet_address/middleware' | ||
import { WalletAddress } from './open_payments/wallet_address/model' | ||
import { WalletAddressService } from './open_payments/wallet_address/service' | ||
import { | ||
createTokenIntrospectionMiddleware, | ||
|
@@ -88,14 +86,22 @@ import { TelemetryService } from './telemetry/service' | |
import { ApolloArmor } from '@escape.tech/graphql-armor' | ||
import { openPaymentsServerErrorMiddleware } from './open_payments/route-errors' | ||
import { verifyApiSignature } from './shared/utils' | ||
import { WalletAddress } from './open_payments/wallet_address/model' | ||
import { | ||
getWalletAddressUrlFromIncomingPayment, | ||
getWalletAddressUrlFromOutgoingPayment, | ||
getWalletAddressUrlFromQueryParams, | ||
getWalletAddressUrlFromQuote, | ||
getWalletAddressUrlFromRequestBody, | ||
getWalletAddressForSubresource, | ||
getWalletAddressUrlFromPath | ||
} from './open_payments/wallet_address/middleware' | ||
|
||
export interface AppContextData { | ||
logger: Logger | ||
container: AppContainer | ||
// Set by @koa/router. | ||
params: { [key: string]: string } | ||
walletAddress?: WalletAddress | ||
walletAddressUrl?: string | ||
} | ||
|
||
export interface ApolloContext { | ||
|
@@ -111,18 +117,15 @@ export type AppRequest<ParamsT extends string = string> = Omit< | |
params: Record<ParamsT, string> | ||
} | ||
|
||
export interface WalletAddressContext extends AppContext { | ||
walletAddress: WalletAddress | ||
export interface WalletAddressUrlContext extends AppContext { | ||
walletAddressUrl: string | ||
grant?: Grant | ||
client?: string | ||
accessAction?: AccessAction | ||
} | ||
|
||
export type WalletAddressKeysContext = Omit< | ||
WalletAddressContext, | ||
'walletAddress' | ||
> & { | ||
walletAddress?: WalletAddress | ||
export interface WalletAddressContext extends WalletAddressUrlContext { | ||
walletAddress: WalletAddress | ||
} | ||
|
||
type HttpSigHeaders = Record<'signature' | 'signature-input', string> | ||
|
@@ -141,7 +144,7 @@ export type HttpSigWithAuthenticatedStatusContext = HttpSigContext & | |
AuthenticatedStatusContext | ||
|
||
// Wallet address subresources | ||
interface GetCollectionQuery { | ||
export interface GetCollectionQuery { | ||
'wallet-address': string | ||
} | ||
|
||
|
@@ -162,7 +165,7 @@ type CollectionContext<BodyT = never, QueryT = ParsedUrlQuery> = Omit< | |
accessAction: NonNullable<WalletAddressContext['accessAction']> | ||
} | ||
|
||
type SignedCollectionContext< | ||
export type SignedCollectionContext< | ||
BodyT = never, | ||
QueryT = ParsedUrlQuery | ||
> = CollectionContext<BodyT, QueryT> & HttpSigContext | ||
|
@@ -426,7 +429,6 @@ export class App { | |
// Create incoming payment | ||
router.post<DefaultState, SignedCollectionContext<IncomingCreateBody>>( | ||
'/incoming-payments', | ||
createWalletAddressMiddleware(), | ||
createValidatorMiddleware< | ||
ContextType<SignedCollectionContext<IncomingCreateBody>> | ||
>( | ||
|
@@ -437,11 +439,13 @@ export class App { | |
}, | ||
validatorMiddlewareOptions | ||
), | ||
getWalletAddressUrlFromRequestBody, | ||
createTokenIntrospectionMiddleware({ | ||
requestType: AccessType.IncomingPayment, | ||
requestAction: RequestAction.Create | ||
}), | ||
httpsigMiddleware, | ||
getWalletAddressForSubresource, | ||
incomingPaymentRoutes.create | ||
) | ||
|
||
|
@@ -452,7 +456,6 @@ export class App { | |
SignedCollectionContext<never, GetCollectionQuery> | ||
>( | ||
'/incoming-payments', | ||
createWalletAddressMiddleware(), | ||
createValidatorMiddleware< | ||
ContextType<SignedCollectionContext<never, GetCollectionQuery>> | ||
>( | ||
|
@@ -463,19 +466,20 @@ export class App { | |
}, | ||
validatorMiddlewareOptions | ||
), | ||
getWalletAddressUrlFromQueryParams, | ||
createTokenIntrospectionMiddleware({ | ||
requestType: AccessType.IncomingPayment, | ||
requestAction: RequestAction.List | ||
}), | ||
httpsigMiddleware, | ||
getWalletAddressForSubresource, | ||
incomingPaymentRoutes.list | ||
) | ||
|
||
// POST /outgoing-payment | ||
// Create outgoing payment | ||
router.post<DefaultState, SignedCollectionContext<OutgoingCreateBody>>( | ||
'/outgoing-payments', | ||
createWalletAddressMiddleware(), | ||
createValidatorMiddleware< | ||
ContextType<SignedCollectionContext<OutgoingCreateBody>> | ||
>( | ||
|
@@ -486,11 +490,13 @@ export class App { | |
}, | ||
validatorMiddlewareOptions | ||
), | ||
getWalletAddressUrlFromRequestBody, | ||
createTokenIntrospectionMiddleware({ | ||
requestType: AccessType.OutgoingPayment, | ||
requestAction: RequestAction.Create | ||
}), | ||
httpsigMiddleware, | ||
getWalletAddressForSubresource, | ||
outgoingPaymentRoutes.create | ||
) | ||
|
||
|
@@ -501,7 +507,6 @@ export class App { | |
SignedCollectionContext<never, GetCollectionQuery> | ||
>( | ||
'/outgoing-payments', | ||
createWalletAddressMiddleware(), | ||
createValidatorMiddleware< | ||
ContextType<SignedCollectionContext<never, GetCollectionQuery>> | ||
>( | ||
|
@@ -512,19 +517,20 @@ export class App { | |
}, | ||
validatorMiddlewareOptions | ||
), | ||
getWalletAddressUrlFromQueryParams, | ||
createTokenIntrospectionMiddleware({ | ||
requestType: AccessType.OutgoingPayment, | ||
requestAction: RequestAction.List | ||
}), | ||
httpsigMiddleware, | ||
getWalletAddressForSubresource, | ||
outgoingPaymentRoutes.list | ||
) | ||
|
||
// POST /quotes | ||
// Create quote | ||
router.post<DefaultState, SignedCollectionContext<QuoteCreateBody>>( | ||
'/quotes', | ||
createWalletAddressMiddleware(), | ||
createValidatorMiddleware< | ||
ContextType<SignedCollectionContext<QuoteCreateBody>> | ||
>( | ||
|
@@ -535,19 +541,20 @@ export class App { | |
}, | ||
validatorMiddlewareOptions | ||
), | ||
getWalletAddressUrlFromRequestBody, | ||
createTokenIntrospectionMiddleware({ | ||
requestType: AccessType.Quote, | ||
requestAction: RequestAction.Create | ||
}), | ||
httpsigMiddleware, | ||
getWalletAddressForSubresource, | ||
quoteRoutes.create | ||
) | ||
|
||
// GET /incoming-payments/{id} | ||
// Read incoming payment | ||
router.get<DefaultState, SubresourceContextWithAuthenticatedStatus>( | ||
'/incoming-payments/:id', | ||
createWalletAddressMiddleware(), | ||
createValidatorMiddleware< | ||
ContextType<SubresourceContextWithAuthenticatedStatus> | ||
>( | ||
|
@@ -558,20 +565,21 @@ export class App { | |
}, | ||
validatorMiddlewareOptions | ||
), | ||
getWalletAddressUrlFromIncomingPayment, | ||
createTokenIntrospectionMiddleware({ | ||
requestType: AccessType.IncomingPayment, | ||
requestAction: RequestAction.Read, | ||
bypassError: true | ||
}), | ||
authenticatedStatusMiddleware, | ||
getWalletAddressForSubresource, | ||
incomingPaymentRoutes.get | ||
) | ||
|
||
// POST /incoming-payments/{id}/complete | ||
// Complete incoming payment | ||
router.post<DefaultState, SignedSubresourceContext>( | ||
'/incoming-payments/:id/complete', | ||
createWalletAddressMiddleware(), | ||
createValidatorMiddleware<ContextType<SignedSubresourceContext>>( | ||
resourceServerSpec, | ||
{ | ||
|
@@ -580,19 +588,20 @@ export class App { | |
}, | ||
validatorMiddlewareOptions | ||
), | ||
getWalletAddressUrlFromIncomingPayment, | ||
createTokenIntrospectionMiddleware({ | ||
requestType: AccessType.IncomingPayment, | ||
requestAction: RequestAction.Complete | ||
}), | ||
httpsigMiddleware, | ||
getWalletAddressForSubresource, | ||
incomingPaymentRoutes.complete | ||
) | ||
|
||
// GET /outgoing-payments/{id} | ||
// Read outgoing payment | ||
router.get<DefaultState, SignedSubresourceContext>( | ||
'/outgoing-payments/:id', | ||
createWalletAddressMiddleware(), | ||
createValidatorMiddleware<ContextType<SignedSubresourceContext>>( | ||
resourceServerSpec, | ||
{ | ||
|
@@ -601,19 +610,20 @@ export class App { | |
}, | ||
validatorMiddlewareOptions | ||
), | ||
getWalletAddressUrlFromOutgoingPayment, | ||
createTokenIntrospectionMiddleware({ | ||
requestType: AccessType.OutgoingPayment, | ||
requestAction: RequestAction.Read | ||
}), | ||
httpsigMiddleware, | ||
getWalletAddressForSubresource, | ||
outgoingPaymentRoutes.get | ||
) | ||
|
||
// GET /quotes/{id} | ||
// Read quote | ||
router.get<DefaultState, SignedSubresourceContext>( | ||
'/quotes/:id', | ||
createWalletAddressMiddleware(), | ||
createValidatorMiddleware<ContextType<SignedSubresourceContext>>( | ||
resourceServerSpec, | ||
{ | ||
|
@@ -622,43 +632,44 @@ export class App { | |
}, | ||
validatorMiddlewareOptions | ||
), | ||
getWalletAddressUrlFromQuote, | ||
createTokenIntrospectionMiddleware({ | ||
requestType: AccessType.Quote, | ||
requestAction: RequestAction.Read | ||
}), | ||
httpsigMiddleware, | ||
getWalletAddressForSubresource, | ||
quoteRoutes.get | ||
) | ||
|
||
router.get( | ||
WALLET_ADDRESS_PATH + '/jwks.json', | ||
createWalletAddressMiddleware(), | ||
createValidatorMiddleware<WalletAddressKeysContext>( | ||
createValidatorMiddleware( | ||
walletAddressServerSpec, | ||
{ | ||
path: '/jwks.json', | ||
method: HttpMethod.GET | ||
}, | ||
validatorMiddlewareOptions | ||
), | ||
async (ctx: WalletAddressKeysContext): Promise<void> => | ||
await walletAddressKeyRoutes.getKeysByWalletAddressId(ctx) | ||
getWalletAddressUrlFromPath, | ||
walletAddressKeyRoutes.get | ||
) | ||
|
||
// Add the wallet address query route last. | ||
// Otherwise it will be matched instead of other Open Payments endpoints. | ||
router.get( | ||
WALLET_ADDRESS_PATH, | ||
createWalletAddressMiddleware(), | ||
createSpspMiddleware(this.config.spspEnabled), | ||
createValidatorMiddleware<WalletAddressContext>( | ||
createValidatorMiddleware( | ||
walletAddressServerSpec, | ||
{ | ||
path: '/', | ||
method: HttpMethod.GET | ||
}, | ||
validatorMiddlewareOptions | ||
), | ||
getWalletAddressUrlFromPath, | ||
createSpspMiddleware(this.config.spspEnabled), | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. do not call |
||
walletAddressRoutes.get | ||
) | ||
|
||
|
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -7,7 +7,7 @@ import { Limits, parseLimits } from '../payment/outgoing/limits' | |
import { | ||
HttpSigContext, | ||
HttpSigWithAuthenticatedStatusContext, | ||
WalletAddressContext | ||
WalletAddressUrlContext | ||
} from '../../app' | ||
import { | ||
AccessAction, | ||
|
@@ -62,7 +62,7 @@ export function createTokenIntrospectionMiddleware({ | |
bypassError?: boolean | ||
}) { | ||
return async ( | ||
ctx: WalletAddressContext, | ||
ctx: WalletAddressUrlContext, | ||
next: () => Promise<void> | ||
): Promise<void> => { | ||
const config = await ctx.container.use('config') | ||
|
@@ -95,7 +95,7 @@ export function createTokenIntrospectionMiddleware({ | |
const access = tokenInfo.access.find((access: Access) => { | ||
if ( | ||
access.type !== requestType || | ||
(access.identifier && access.identifier !== ctx.walletAddress.url) | ||
(access.identifier && access.identifier !== ctx.walletAddressUrl) | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. at this point, in the token introspection middleware, we only have |
||
) { | ||
return false | ||
} | ||
|
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
now, each route follows as such: