From a0e241e6b08a31e9394432d97662bbd98b53d338 Mon Sep 17 00:00:00 2001 From: elweyn Date: Wed, 9 Mar 2022 15:16:13 +0100 Subject: [PATCH 1/7] Created Query that search for an TransactionLink with a given code --- backend/src/auth/RIGHTS.ts | 1 + .../src/graphql/resolver/TransactionLinkResolver.ts | 11 ++++++++++- 2 files changed, 11 insertions(+), 1 deletion(-) diff --git a/backend/src/auth/RIGHTS.ts b/backend/src/auth/RIGHTS.ts index a18f0132a..6bcd3fa43 100644 --- a/backend/src/auth/RIGHTS.ts +++ b/backend/src/auth/RIGHTS.ts @@ -19,6 +19,7 @@ export enum RIGHTS { UPDATE_USER_INFOS = 'UPDATE_USER_INFOS', HAS_ELOPAGE = 'HAS_ELOPAGE', CREATE_TRANSACTION_LINK = 'CREATE_TRANSACTION_LINK', + QUERY_TRANSACTION_LINK = 'QUERY_TRANSACTION_LINK', // Admin SEARCH_USERS = 'SEARCH_USERS', CREATE_PENDING_CREATION = 'CREATE_PENDING_CREATION', diff --git a/backend/src/graphql/resolver/TransactionLinkResolver.ts b/backend/src/graphql/resolver/TransactionLinkResolver.ts index 920e18569..3091465d5 100644 --- a/backend/src/graphql/resolver/TransactionLinkResolver.ts +++ b/backend/src/graphql/resolver/TransactionLinkResolver.ts @@ -1,7 +1,7 @@ /* eslint-disable @typescript-eslint/no-explicit-any */ /* eslint-disable @typescript-eslint/explicit-module-boundary-types */ -import { Resolver, Args, Authorized, Ctx, Mutation } from 'type-graphql' +import { Resolver, Args, Authorized, Ctx, Mutation, Query, Arg } from 'type-graphql' import { getCustomRepository } from '@dbTools/typeorm' import { TransactionLink } from '@model/TransactionLink' import { TransactionLink as dbTransactionLink } from '@entity/TransactionLink' @@ -62,4 +62,13 @@ export class TransactionLinkResolver { return new TransactionLink(transactionLink, new User(user)) } + + @Authorized([RIGHTS.QUERY_TRANSACTION_LINK]) + @Query(() => TransactionLink) + async queryTransactionLink(@Arg('code') code: string): Promise { + const transactionLink = await dbTransactionLink.findOneOrFail({ code }) + const userRepository = getCustomRepository(UserRepository) + const user = await userRepository.findOneOrFail({ id: transactionLink.userId }) + return new TransactionLink(transactionLink, new User(user)) + } } From def310fa3b14f1e3bd8b91993d8bf624091e1430 Mon Sep 17 00:00:00 2001 From: elweyn Date: Thu, 10 Mar 2022 18:10:03 +0100 Subject: [PATCH 2/7] Add QUERY_TRANSACTION_LINK to inalienable rights. --- backend/src/auth/INALIENABLE_RIGHTS.ts | 1 + 1 file changed, 1 insertion(+) diff --git a/backend/src/auth/INALIENABLE_RIGHTS.ts b/backend/src/auth/INALIENABLE_RIGHTS.ts index 10d745806..fa9ea2224 100644 --- a/backend/src/auth/INALIENABLE_RIGHTS.ts +++ b/backend/src/auth/INALIENABLE_RIGHTS.ts @@ -7,4 +7,5 @@ export const INALIENABLE_RIGHTS = [ RIGHTS.CREATE_USER, RIGHTS.SEND_RESET_PASSWORD_EMAIL, RIGHTS.SET_PASSWORD, + RIGHTS.QUERY_TRANSACTION_LINK, ] From ade691426e750c997cbddea55cb999e60bbdbbf9 Mon Sep 17 00:00:00 2001 From: elweyn Date: Thu, 10 Mar 2022 21:24:42 +0100 Subject: [PATCH 3/7] Add logic for user that redeem the link. --- .../src/graphql/resolver/TransactionLinkResolver.ts | 13 ++++++++++--- 1 file changed, 10 insertions(+), 3 deletions(-) diff --git a/backend/src/graphql/resolver/TransactionLinkResolver.ts b/backend/src/graphql/resolver/TransactionLinkResolver.ts index afcfe48b2..dece0ddc3 100644 --- a/backend/src/graphql/resolver/TransactionLinkResolver.ts +++ b/backend/src/graphql/resolver/TransactionLinkResolver.ts @@ -12,7 +12,7 @@ import { RIGHTS } from '@/auth/RIGHTS' import { randomBytes } from 'crypto' import { User } from '@model/User' import { calculateDecay } from '@/util/decay' -^ + // TODO: do not export, test it inside the resolver export const transactionLinkCode = (date: Date): string => { const time = date.getTime().toString(16) @@ -70,10 +70,17 @@ export class TransactionLinkResolver { @Authorized([RIGHTS.QUERY_TRANSACTION_LINK]) @Query(() => TransactionLink) - async queryTransactionLink(@Arg('code') code: string): Promise { + async queryTransactionLink( + @Args() { code, redeemedByUserId }: QueryTransactionLinkArgs, + ): Promise { const transactionLink = await dbTransactionLink.findOneOrFail({ code }) const userRepository = getCustomRepository(UserRepository) const user = await userRepository.findOneOrFail({ id: transactionLink.userId }) - return new TransactionLink(transactionLink, new User(user)) + let userRedeem = null + if (redeemedByUserId) { + const redeemedByUser = await userRepository.findOne({ id: redeemedByUserId }) + if (redeemedByUser) userRedeem = new User(redeemedByUser) + } + return new TransactionLink(transactionLink, new User(user), userRedeem) } } From 280de3df9e2d18042c5efd932ceba0fa90f2720b Mon Sep 17 00:00:00 2001 From: elweyn Date: Thu, 10 Mar 2022 21:36:53 +0100 Subject: [PATCH 4/7] Add Args for the queryTransactionLink. --- backend/src/graphql/arg/QueryTransactionLinkArgs.ts | 10 ++++++++++ 1 file changed, 10 insertions(+) create mode 100644 backend/src/graphql/arg/QueryTransactionLinkArgs.ts diff --git a/backend/src/graphql/arg/QueryTransactionLinkArgs.ts b/backend/src/graphql/arg/QueryTransactionLinkArgs.ts new file mode 100644 index 000000000..2dcd29572 --- /dev/null +++ b/backend/src/graphql/arg/QueryTransactionLinkArgs.ts @@ -0,0 +1,10 @@ +import { ArgsType, Field, Int } from 'type-graphql' + +@ArgsType() +export default class QueryTransactionLinkArgs { + @Field(() => String) + code: string + + @Field(() => Int, { nullable: true }) + redeemUserId?: number +} From a805f659200dd16d8bee3e14d1c784594ddefca5 Mon Sep 17 00:00:00 2001 From: elweyn Date: Thu, 10 Mar 2022 21:37:23 +0100 Subject: [PATCH 5/7] Change the logic to a better argument name for redeemUserId. --- backend/src/graphql/resolver/TransactionLinkResolver.ts | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) diff --git a/backend/src/graphql/resolver/TransactionLinkResolver.ts b/backend/src/graphql/resolver/TransactionLinkResolver.ts index dece0ddc3..9cc10f165 100644 --- a/backend/src/graphql/resolver/TransactionLinkResolver.ts +++ b/backend/src/graphql/resolver/TransactionLinkResolver.ts @@ -6,6 +6,7 @@ import { getCustomRepository } from '@dbTools/typeorm' import { TransactionLink } from '@model/TransactionLink' import { TransactionLink as dbTransactionLink } from '@entity/TransactionLink' import TransactionLinkArgs from '@arg/TransactionLinkArgs' +import QueryTransactionLinkArgs from '@arg/QueryTransactionLinkArgs' import { UserRepository } from '@repository/User' import { calculateBalance } from '@/util/validate' import { RIGHTS } from '@/auth/RIGHTS' @@ -71,14 +72,14 @@ export class TransactionLinkResolver { @Authorized([RIGHTS.QUERY_TRANSACTION_LINK]) @Query(() => TransactionLink) async queryTransactionLink( - @Args() { code, redeemedByUserId }: QueryTransactionLinkArgs, + @Args() { code, redeemUserId }: QueryTransactionLinkArgs, ): Promise { const transactionLink = await dbTransactionLink.findOneOrFail({ code }) const userRepository = getCustomRepository(UserRepository) const user = await userRepository.findOneOrFail({ id: transactionLink.userId }) let userRedeem = null - if (redeemedByUserId) { - const redeemedByUser = await userRepository.findOne({ id: redeemedByUserId }) + if (redeemUserId) { + const redeemedByUser = await userRepository.findOne({ id: redeemUserId }) if (redeemedByUser) userRedeem = new User(redeemedByUser) } return new TransactionLink(transactionLink, new User(user), userRedeem) From bfba633b7831802343105fc8c22be73fadff7cf2 Mon Sep 17 00:00:00 2001 From: elweyn Date: Thu, 10 Mar 2022 21:52:49 +0100 Subject: [PATCH 6/7] Change the logic to store the redeemer in transactionLink table. --- .../graphql/resolver/TransactionLinkResolver.ts | 17 +++++++++++++++-- 1 file changed, 15 insertions(+), 2 deletions(-) diff --git a/backend/src/graphql/resolver/TransactionLinkResolver.ts b/backend/src/graphql/resolver/TransactionLinkResolver.ts index 9cc10f165..a681d773a 100644 --- a/backend/src/graphql/resolver/TransactionLinkResolver.ts +++ b/backend/src/graphql/resolver/TransactionLinkResolver.ts @@ -78,9 +78,22 @@ export class TransactionLinkResolver { const userRepository = getCustomRepository(UserRepository) const user = await userRepository.findOneOrFail({ id: transactionLink.userId }) let userRedeem = null - if (redeemUserId) { + if (redeemUserId && !transactionLink.redeemedBy) { const redeemedByUser = await userRepository.findOne({ id: redeemUserId }) - if (redeemedByUser) userRedeem = new User(redeemedByUser) + if (!redeemedByUser) { + throw new Error('Unable to find user that redeem the link') + } + userRedeem = new User(redeemedByUser) + transactionLink.redeemedBy = userRedeem.id + await dbTransactionLink.save(transactionLink).catch(() => { + throw new Error('Unable to save transaction link') + }) + } else if (transactionLink.redeemedBy) { + const redeemedByUser = await userRepository.findOne({ id: redeemUserId }) + if (!redeemedByUser) { + throw new Error('Unable to find user that has redeemed the link') + } + userRedeem = new User(redeemedByUser) } return new TransactionLink(transactionLink, new User(user), userRedeem) } From 7e3f86f60e00a7c695b5b138719e7a12ce79121f Mon Sep 17 00:00:00 2001 From: elweyn Date: Thu, 10 Mar 2022 23:49:28 +0100 Subject: [PATCH 7/7] Remove unused import. --- backend/src/graphql/resolver/TransactionLinkResolver.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/backend/src/graphql/resolver/TransactionLinkResolver.ts b/backend/src/graphql/resolver/TransactionLinkResolver.ts index a681d773a..4065bb13a 100644 --- a/backend/src/graphql/resolver/TransactionLinkResolver.ts +++ b/backend/src/graphql/resolver/TransactionLinkResolver.ts @@ -1,7 +1,7 @@ /* eslint-disable @typescript-eslint/no-explicit-any */ /* eslint-disable @typescript-eslint/explicit-module-boundary-types */ -import { Resolver, Args, Authorized, Ctx, Mutation, Query, Arg } from 'type-graphql' +import { Resolver, Args, Authorized, Ctx, Mutation, Query } from 'type-graphql' import { getCustomRepository } from '@dbTools/typeorm' import { TransactionLink } from '@model/TransactionLink' import { TransactionLink as dbTransactionLink } from '@entity/TransactionLink'