From b404d12a5450d8eb2d9e046c5eaaff3ced541dc9 Mon Sep 17 00:00:00 2001 From: Blair Currey <12960453+BlairCurrey@users.noreply.github.com> Date: Thu, 31 Oct 2024 11:21:50 -0400 Subject: [PATCH] test(backend): quote create access control --- .../src/graphql/resolvers/quote.test.ts | 35 +++++++++++++++++++ .../backend/src/graphql/resolvers/quote.ts | 4 +-- .../src/graphql/resolvers/wallet_address.ts | 2 +- 3 files changed, 37 insertions(+), 4 deletions(-) diff --git a/packages/backend/src/graphql/resolvers/quote.test.ts b/packages/backend/src/graphql/resolvers/quote.test.ts index 78b09a93f8..63e16c2183 100644 --- a/packages/backend/src/graphql/resolvers/quote.test.ts +++ b/packages/backend/src/graphql/resolvers/quote.test.ts @@ -361,6 +361,41 @@ describe('Quote Resolvers', (): void => { } expect(createSpy).toHaveBeenCalledWith({ ...input, method: 'ilp' }) }) + + test('cannot access', async (): Promise => { + const spy = jest + .spyOn(walletAddressService, 'canAccess') + .mockImplementation(async () => false) + + expect.assertions(3) + try { + await appContainer.apolloClient + .query({ + query: gql` + mutation CreateQuote($input: CreateQuoteInput!) { + createQuote(input: $input) { + quote { + id + } + } + } + `, + variables: { input } + }) + .then((query): QuoteResponse => query.data?.createQuote) + } catch (error) { + expect(error).toBeInstanceOf(ApolloError) + expect((error as ApolloError).graphQLErrors).toContainEqual( + expect.objectContaining({ + message: 'Unknown wallet address id input', + extensions: expect.objectContaining({ + code: GraphQLErrorCode.BadUserInput + }) + }) + ) + } + expect(spy).toHaveBeenCalled() + }) }) describe('Wallet address quotes', (): void => { diff --git a/packages/backend/src/graphql/resolvers/quote.ts b/packages/backend/src/graphql/resolvers/quote.ts index f1dcaf1a4d..2a8c2c9c91 100644 --- a/packages/backend/src/graphql/resolvers/quote.ts +++ b/packages/backend/src/graphql/resolvers/quote.ts @@ -43,10 +43,8 @@ export const getQuote: QueryResolvers['quote'] = async ( export const createQuote: MutationResolvers['createQuote'] = async (parent, args, ctx): Promise => { - // ACCESS CONTROL CASE: Creates. If operator, OK. Else, get associated wallet address - // tenantId and compare to requestor's tenantId before creating. const walletAddressService = await ctx.container.use('walletAddressService') - const canAccess = walletAddressService.canAccess( + const canAccess = await walletAddressService.canAccess( ctx.isOperator, ctx.tenantId, args.input.walletAddressId diff --git a/packages/backend/src/graphql/resolvers/wallet_address.ts b/packages/backend/src/graphql/resolvers/wallet_address.ts index ced3b0313e..e03de40267 100644 --- a/packages/backend/src/graphql/resolvers/wallet_address.ts +++ b/packages/backend/src/graphql/resolvers/wallet_address.ts @@ -170,7 +170,7 @@ export const updateWalletAddress: MutationResolvers['updateWallet } // TODO: access control? operator only, anyone, or tenanted? -// Perhaps operator only? if tenanted will maybe need to fn +// Perhaps operator only? if tenanted will maybe need fn // like existing processNextWalletAddresses that filters by tenant export const triggerWalletAddressEvents: MutationResolvers['triggerWalletAddressEvents'] = async (