From 96dcdf01702def086a0d1e4c6fe87f5b5eba5dd1 Mon Sep 17 00:00:00 2001 From: Moriz Wahl Date: Wed, 9 Mar 2022 17:09:57 +0100 Subject: [PATCH 01/15] add deletedAt to constructor --- backend/src/graphql/model/TransactionLink.ts | 1 + 1 file changed, 1 insertion(+) diff --git a/backend/src/graphql/model/TransactionLink.ts b/backend/src/graphql/model/TransactionLink.ts index 52fc6ce78..25cf5ac36 100644 --- a/backend/src/graphql/model/TransactionLink.ts +++ b/backend/src/graphql/model/TransactionLink.ts @@ -15,6 +15,7 @@ export class TransactionLink { this.createdAt = transactionLink.createdAt this.validUntil = transactionLink.validUntil this.showEmail = transactionLink.showEmail + this.deletedAt = null this.redeemedAt = null this.redeemedBy = null } From 8107066d2bfc958438aa82cf7c1f3f39492592d4 Mon Sep 17 00:00:00 2001 From: Moriz Wahl Date: Wed, 9 Mar 2022 18:18:22 +0100 Subject: [PATCH 02/15] balance includes transactions to hold available, calculateBalance checks for pending transaction links --- .../resolver/TransactionLinkResolver.ts | 20 +++---------------- .../graphql/resolver/TransactionResolver.ts | 8 ++++++-- backend/src/util/validate.ts | 20 +++++++++++++++++-- 3 files changed, 27 insertions(+), 21 deletions(-) diff --git a/backend/src/graphql/resolver/TransactionLinkResolver.ts b/backend/src/graphql/resolver/TransactionLinkResolver.ts index 7cd76a954..76ed41308 100644 --- a/backend/src/graphql/resolver/TransactionLinkResolver.ts +++ b/backend/src/graphql/resolver/TransactionLinkResolver.ts @@ -2,7 +2,7 @@ /* eslint-disable @typescript-eslint/explicit-module-boundary-types */ import { Resolver, Args, Authorized, Ctx, Mutation } from 'type-graphql' -import { getCustomRepository, MoreThan } from '@dbTools/typeorm' +import { getCustomRepository } from '@dbTools/typeorm' import { TransactionLink } from '@model/TransactionLink' import { TransactionLink as dbTransactionLink } from '@entity/TransactionLink' import TransactionLinkArgs from '@arg/TransactionLinkArgs' @@ -43,24 +43,10 @@ export class TransactionLinkResolver { const createdDate = new Date() const validUntil = transactionLinkExpireDate(createdDate) - const holdAvailableAmount = amount.add( - calculateDecay(amount, createdDate, validUntil).decay.mul(-1), - ) - - const openTransactionLinks = await dbTransactionLink.find({ - select: ['holdAvailableAmount'], - where: { userId: user.id, redeemedAt: null, validUntil: MoreThan(createdDate) }, - }) - - const holdAvailable = openTransactionLinks.reduce( - (previousValue, currentValue) => - previousValue.add(currentValue.holdAvailableAmount.toString()), - holdAvailableAmount, - ) + const holdAvailableAmount = amount.minus(calculateDecay(amount, createdDate, validUntil).decay) // validate amount - // TODO taken from transaction resolver, duplicate code - const sendBalance = await calculateBalance(user.id, holdAvailable.mul(-1), createdDate) + const sendBalance = await calculateBalance(user.id, holdAvailableAmount.mul(-1), createdDate) if (!sendBalance) { throw new Error("user hasn't enough GDD or amount is < 0") } diff --git a/backend/src/graphql/resolver/TransactionResolver.ts b/backend/src/graphql/resolver/TransactionResolver.ts index d674fc69e..f04050fbf 100644 --- a/backend/src/graphql/resolver/TransactionResolver.ts +++ b/backend/src/graphql/resolver/TransactionResolver.ts @@ -25,7 +25,7 @@ import { Transaction as dbTransaction } from '@entity/Transaction' import { apiPost } from '@/apis/HttpRequest' import { TransactionTypeId } from '@enum/TransactionTypeId' -import { calculateBalance, isHexPublicKey } from '@/util/validate' +import { calculateBalance, isHexPublicKey, holdAvailable } from '@/util/validate' import { RIGHTS } from '@/auth/RIGHTS' import { User } from '@model/User' import { communityUser } from '@/util/communityUser' @@ -127,9 +127,13 @@ export class TransactionResolver { transactions.push(new Transaction(userTransaction, self, linkedUser)) }) + const toHoldAvailable = await holdAvailable(user.id, now) + // Construct Result return new TransactionList( - calculateDecay(lastTransaction.balance, lastTransaction.balanceDate, now).balance, + calculateDecay(lastTransaction.balance, lastTransaction.balanceDate, now).balance.minus( + toHoldAvailable.toString(), + ), transactions, userTransactionsCount, balanceGDT, diff --git a/backend/src/util/validate.ts b/backend/src/util/validate.ts index 3699fe511..c79cca076 100644 --- a/backend/src/util/validate.ts +++ b/backend/src/util/validate.ts @@ -2,6 +2,8 @@ import { calculateDecay } from './decay' import Decimal from 'decimal.js-light' import { Transaction } from '@entity/Transaction' import { Decay } from '@model/Decay' +import { TransactionLink as dbTransactionLink } from '@entity/TransactionLink' +import { MoreThan } from '@dbTools/typeorm' function isStringBoolean(value: string): boolean { const lowerValue = value.toLowerCase() @@ -24,12 +26,26 @@ async function calculateBalance( if (!lastTransaction) return null const decay = calculateDecay(lastTransaction.balance, lastTransaction.balanceDate, time) + // TODO why we have to use toString() here? const balance = decay.balance.add(amount.toString()) - if (balance.lessThan(0)) { + const toHoldAvailable = await holdAvailable(userId, time) + if (balance.minus(toHoldAvailable.toString()).lessThan(0)) { return null } return { balance, lastTransactionId: lastTransaction.id, decay } } -export { isHexPublicKey, calculateBalance, isStringBoolean } +async function holdAvailable(userId: number, date: Date): Promise { + const openTransactionLinks = await dbTransactionLink.find({ + select: ['holdAvailableAmount'], + where: { userId, redeemedAt: null, validUntil: MoreThan(date) }, + }) + + return openTransactionLinks.reduce( + (previousValue, currentValue) => previousValue.add(currentValue.holdAvailableAmount.toString()), + new Decimal(0), + ) +} + +export { isHexPublicKey, calculateBalance, isStringBoolean, holdAvailable } From 5f42748358f6db3adb619b12805f4c195c80b54a Mon Sep 17 00:00:00 2001 From: Moriz Wahl Date: Wed, 9 Mar 2022 18:25:17 +0100 Subject: [PATCH 03/15] error message and constant for transaction link duration --- backend/src/graphql/resolver/TransactionLinkResolver.ts | 9 +++++---- 1 file changed, 5 insertions(+), 4 deletions(-) diff --git a/backend/src/graphql/resolver/TransactionLinkResolver.ts b/backend/src/graphql/resolver/TransactionLinkResolver.ts index 76ed41308..d60146096 100644 --- a/backend/src/graphql/resolver/TransactionLinkResolver.ts +++ b/backend/src/graphql/resolver/TransactionLinkResolver.ts @@ -23,10 +23,11 @@ export const transactionLinkCode = (date: Date): string => { ) } +const CODE_VALID_DAYS_DURATION = 14 + const transactionLinkExpireDate = (date: Date): Date => { const validUntil = new Date(date) - // valid for 14 days - return new Date(validUntil.setDate(date.getDate() + 14)) + return new Date(validUntil.setDate(date.getDate() + CODE_VALID_DAYS_DURATION)) } @Resolver() @@ -60,8 +61,8 @@ export class TransactionLinkResolver { transactionLink.createdAt = createdDate transactionLink.validUntil = validUntil transactionLink.showEmail = showEmail - await dbTransactionLink.save(transactionLink).catch((error) => { - throw error + await dbTransactionLink.save(transactionLink).catch(() => { + throw new Error('Unable to save transaction link') }) return new TransactionLink(transactionLink, new User(user)) From 91fe38fe8f6675194ae99fc2530696d787d76b28 Mon Sep 17 00:00:00 2001 From: Moriz Wahl Date: Thu, 10 Mar 2022 14:28:42 +0100 Subject: [PATCH 04/15] use db values instead of null --- backend/src/graphql/model/TransactionLink.ts | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/backend/src/graphql/model/TransactionLink.ts b/backend/src/graphql/model/TransactionLink.ts index 25cf5ac36..97cded71a 100644 --- a/backend/src/graphql/model/TransactionLink.ts +++ b/backend/src/graphql/model/TransactionLink.ts @@ -15,9 +15,9 @@ export class TransactionLink { this.createdAt = transactionLink.createdAt this.validUntil = transactionLink.validUntil this.showEmail = transactionLink.showEmail - this.deletedAt = null - this.redeemedAt = null - this.redeemedBy = null + this.deletedAt = transactionLink.deletedAt + this.redeemedAt = transactionLink.redeemedAt + this.redeemedBy = transactionLink.redeemedBy } @Field(() => Number) From 9143990535f5cd85f6a065ccf3c95288360a8d62 Mon Sep 17 00:00:00 2001 From: Moriz Wahl Date: Thu, 10 Mar 2022 15:05:32 +0100 Subject: [PATCH 05/15] turn of logger when NODE_ENV === '"development"' --- backend/src/server/plugins.ts | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/backend/src/server/plugins.ts b/backend/src/server/plugins.ts index a407135ea..8d21178f3 100644 --- a/backend/src/server/plugins.ts +++ b/backend/src/server/plugins.ts @@ -40,6 +40,8 @@ const apolloLogPlugin = ApolloLogPlugin({ }) const plugins = - process.env.NODE_ENV === 'development' ? [setHeadersPlugin] : [setHeadersPlugin, apolloLogPlugin] + process.env.NODE_ENV === 'development' || process.env.NODE_ENV === '"development"' + ? [setHeadersPlugin] + : [setHeadersPlugin, apolloLogPlugin] export default plugins From 3436253bbef0ac945430985a3cae22afb0d2b2d6 Mon Sep 17 00:00:00 2001 From: Moriz Wahl Date: Thu, 10 Mar 2022 15:33:26 +0100 Subject: [PATCH 06/15] transaction link repository, use raw query to get sum of hold available amount --- backend/src/graphql/model/TransactionLink.ts | 6 ++--- .../graphql/resolver/TransactionResolver.ts | 6 +++-- .../src/typeorm/repository/TransactionLink.ts | 16 ++++++++++++++ backend/src/util/validate.ts | 22 +++++-------------- 4 files changed, 29 insertions(+), 21 deletions(-) create mode 100644 backend/src/typeorm/repository/TransactionLink.ts diff --git a/backend/src/graphql/model/TransactionLink.ts b/backend/src/graphql/model/TransactionLink.ts index 97cded71a..fec02b9fd 100644 --- a/backend/src/graphql/model/TransactionLink.ts +++ b/backend/src/graphql/model/TransactionLink.ts @@ -15,9 +15,9 @@ export class TransactionLink { this.createdAt = transactionLink.createdAt this.validUntil = transactionLink.validUntil this.showEmail = transactionLink.showEmail - this.deletedAt = transactionLink.deletedAt - this.redeemedAt = transactionLink.redeemedAt - this.redeemedBy = transactionLink.redeemedBy + this.deletedAt = null // transactionLink.deletedAt + this.redeemedAt = null // transactionLink.redeemedAt + this.redeemedBy = null // transactionLink.redeemedBy } @Field(() => Number) diff --git a/backend/src/graphql/resolver/TransactionResolver.ts b/backend/src/graphql/resolver/TransactionResolver.ts index f04050fbf..1d1a00c39 100644 --- a/backend/src/graphql/resolver/TransactionResolver.ts +++ b/backend/src/graphql/resolver/TransactionResolver.ts @@ -19,13 +19,14 @@ import { Order } from '@enum/Order' import { UserRepository } from '@repository/User' import { TransactionRepository } from '@repository/Transaction' +import { TransactionLinkRepository } from '@repository/TransactionLink' import { User as dbUser } from '@entity/User' import { Transaction as dbTransaction } from '@entity/Transaction' import { apiPost } from '@/apis/HttpRequest' import { TransactionTypeId } from '@enum/TransactionTypeId' -import { calculateBalance, isHexPublicKey, holdAvailable } from '@/util/validate' +import { calculateBalance, isHexPublicKey } from '@/util/validate' import { RIGHTS } from '@/auth/RIGHTS' import { User } from '@model/User' import { communityUser } from '@/util/communityUser' @@ -127,7 +128,8 @@ export class TransactionResolver { transactions.push(new Transaction(userTransaction, self, linkedUser)) }) - const toHoldAvailable = await holdAvailable(user.id, now) + const transactionLinkRepository = getCustomRepository(TransactionLinkRepository) + const toHoldAvailable = await transactionLinkRepository.sumAmountToHoldAvailable(user.id, now) // Construct Result return new TransactionList( diff --git a/backend/src/typeorm/repository/TransactionLink.ts b/backend/src/typeorm/repository/TransactionLink.ts new file mode 100644 index 000000000..5f7531bc8 --- /dev/null +++ b/backend/src/typeorm/repository/TransactionLink.ts @@ -0,0 +1,16 @@ +import { Repository, EntityRepository } from '@dbTools/typeorm' +import { TransactionLink as dbTransactionLink } from '@entity/TransactionLink' +import Decimal from 'decimal.js-light' + +@EntityRepository(dbTransactionLink) +export class TransactionLinkRepository extends Repository { + async sumAmountToHoldAvailable(userId: number, date: Date): Promise { + const { sum } = await this.createQueryBuilder('transactionLinks') + .select('SUM(transactionLinks.holdAvailableAmount)', 'sum') + .where('transactionLinks.userId = :userId', { userId }) + .andWhere('transactionLinks.redeemedAt is NULL') + .andWhere('transactionLinks.validUntil > :date', { date }) + .getRawOne() + return sum ? new Decimal(sum) : new Decimal(0) + } +} diff --git a/backend/src/util/validate.ts b/backend/src/util/validate.ts index c79cca076..0858ea50f 100644 --- a/backend/src/util/validate.ts +++ b/backend/src/util/validate.ts @@ -2,8 +2,8 @@ import { calculateDecay } from './decay' import Decimal from 'decimal.js-light' import { Transaction } from '@entity/Transaction' import { Decay } from '@model/Decay' -import { TransactionLink as dbTransactionLink } from '@entity/TransactionLink' -import { MoreThan } from '@dbTools/typeorm' +import { getCustomRepository } from '@dbTools/typeorm' +import { TransactionLinkRepository } from '@repository/TransactionLink' function isStringBoolean(value: string): boolean { const lowerValue = value.toLowerCase() @@ -29,23 +29,13 @@ async function calculateBalance( // TODO why we have to use toString() here? const balance = decay.balance.add(amount.toString()) - const toHoldAvailable = await holdAvailable(userId, time) + const transactionLinkRepository = getCustomRepository(TransactionLinkRepository) + const toHoldAvailable = await transactionLinkRepository.sumAmountToHoldAvailable(userId, time) + if (balance.minus(toHoldAvailable.toString()).lessThan(0)) { return null } return { balance, lastTransactionId: lastTransaction.id, decay } } -async function holdAvailable(userId: number, date: Date): Promise { - const openTransactionLinks = await dbTransactionLink.find({ - select: ['holdAvailableAmount'], - where: { userId, redeemedAt: null, validUntil: MoreThan(date) }, - }) - - return openTransactionLinks.reduce( - (previousValue, currentValue) => previousValue.add(currentValue.holdAvailableAmount.toString()), - new Decimal(0), - ) -} - -export { isHexPublicKey, calculateBalance, isStringBoolean, holdAvailable } +export { isHexPublicKey, calculateBalance, isStringBoolean } From fae9d9100466838e7e72a3b61f7427fe50d0a05a Mon Sep 17 00:00:00 2001 From: Moriz Wahl Date: Thu, 10 Mar 2022 16:00:15 +0100 Subject: [PATCH 07/15] add comment to explain why set to null in constructor --- backend/src/graphql/model/TransactionLink.ts | 1 + 1 file changed, 1 insertion(+) diff --git a/backend/src/graphql/model/TransactionLink.ts b/backend/src/graphql/model/TransactionLink.ts index fec02b9fd..a87d4a68a 100644 --- a/backend/src/graphql/model/TransactionLink.ts +++ b/backend/src/graphql/model/TransactionLink.ts @@ -15,6 +15,7 @@ export class TransactionLink { this.createdAt = transactionLink.createdAt this.validUntil = transactionLink.validUntil this.showEmail = transactionLink.showEmail + // Type 'Date | null | undefined' is not assignable to type 'Date | null'. this.deletedAt = null // transactionLink.deletedAt this.redeemedAt = null // transactionLink.redeemedAt this.redeemedBy = null // transactionLink.redeemedBy From 80650e60b81a23840f87569529e2d38496f7dbb3 Mon Sep 17 00:00:00 2001 From: Moriz Wahl Date: Thu, 10 Mar 2022 18:00:47 +0100 Subject: [PATCH 08/15] remove apollo log plugin hack, improve model --- backend/src/graphql/model/TransactionLink.ts | 9 ++++----- backend/src/server/plugins.ts | 4 +--- 2 files changed, 5 insertions(+), 8 deletions(-) diff --git a/backend/src/graphql/model/TransactionLink.ts b/backend/src/graphql/model/TransactionLink.ts index a87d4a68a..f41d34acc 100644 --- a/backend/src/graphql/model/TransactionLink.ts +++ b/backend/src/graphql/model/TransactionLink.ts @@ -5,7 +5,7 @@ import { User } from './User' @ObjectType() export class TransactionLink { - constructor(transactionLink: dbTransactionLink, user: User) { + constructor(transactionLink: dbTransactionLink, user: User, redeemedBy: User | null = null) { this.id = transactionLink.id this.user = user this.amount = transactionLink.amount @@ -15,10 +15,9 @@ export class TransactionLink { this.createdAt = transactionLink.createdAt this.validUntil = transactionLink.validUntil this.showEmail = transactionLink.showEmail - // Type 'Date | null | undefined' is not assignable to type 'Date | null'. - this.deletedAt = null // transactionLink.deletedAt - this.redeemedAt = null // transactionLink.redeemedAt - this.redeemedBy = null // transactionLink.redeemedBy + this.deletedAt = transactionLink.deletedAt + this.redeemedAt = transactionLink.redeemedAt + this.redeemedBy = redeemedBy } @Field(() => Number) diff --git a/backend/src/server/plugins.ts b/backend/src/server/plugins.ts index 8d21178f3..a407135ea 100644 --- a/backend/src/server/plugins.ts +++ b/backend/src/server/plugins.ts @@ -40,8 +40,6 @@ const apolloLogPlugin = ApolloLogPlugin({ }) const plugins = - process.env.NODE_ENV === 'development' || process.env.NODE_ENV === '"development"' - ? [setHeadersPlugin] - : [setHeadersPlugin, apolloLogPlugin] + process.env.NODE_ENV === 'development' ? [setHeadersPlugin] : [setHeadersPlugin, apolloLogPlugin] export default plugins From 47e491db84b819b751bf784d97646f78624ea02c Mon Sep 17 00:00:00 2001 From: Moriz Wahl Date: Thu, 10 Mar 2022 18:01:13 +0100 Subject: [PATCH 09/15] update entity --- database/entity/0030-transaction_link/TransactionLink.ts | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/database/entity/0030-transaction_link/TransactionLink.ts b/database/entity/0030-transaction_link/TransactionLink.ts index 6ea708547..177f23561 100644 --- a/database/entity/0030-transaction_link/TransactionLink.ts +++ b/database/entity/0030-transaction_link/TransactionLink.ts @@ -42,7 +42,7 @@ export class TransactionLink extends BaseEntity { createdAt: Date @DeleteDateColumn() - deletedAt?: Date | null + deletedAt: Date | null @Column({ type: 'datetime', @@ -61,8 +61,8 @@ export class TransactionLink extends BaseEntity { type: 'datetime', nullable: true, }) - redeemedAt?: Date | null + redeemedAt: Date | null @Column({ type: 'int', unsigned: true, nullable: true }) - redeemedBy?: number | null + redeemedBy: number | null } From def310fa3b14f1e3bd8b91993d8bf624091e1430 Mon Sep 17 00:00:00 2001 From: elweyn Date: Thu, 10 Mar 2022 18:10:03 +0100 Subject: [PATCH 10/15] 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 11/15] 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 12/15] 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 13/15] 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 14/15] 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 15/15] 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'