diff --git a/backend/src/auth/RIGHTS.ts b/backend/src/auth/RIGHTS.ts index df4d4a2c1..4b9036eed 100644 --- a/backend/src/auth/RIGHTS.ts +++ b/backend/src/auth/RIGHTS.ts @@ -19,8 +19,8 @@ export enum RIGHTS { UPDATE_USER_INFOS = 'UPDATE_USER_INFOS', HAS_ELOPAGE = 'HAS_ELOPAGE', CREATE_TRANSACTION_LINK = 'CREATE_TRANSACTION_LINK', + DELETE_TRANSACTION_LINK = 'DELETE_TRANSACTION_LINK', QUERY_TRANSACTION_LINK = 'QUERY_TRANSACTION_LINK', - // Admin SEARCH_USERS = 'SEARCH_USERS', CREATE_PENDING_CREATION = 'CREATE_PENDING_CREATION', diff --git a/backend/src/auth/ROLES.ts b/backend/src/auth/ROLES.ts index 37a4e3a67..2a86b5bab 100644 --- a/backend/src/auth/ROLES.ts +++ b/backend/src/auth/ROLES.ts @@ -19,6 +19,7 @@ export const ROLE_USER = new Role('user', [ RIGHTS.UPDATE_USER_INFOS, RIGHTS.HAS_ELOPAGE, RIGHTS.CREATE_TRANSACTION_LINK, + RIGHTS.DELETE_TRANSACTION_LINK, ]) export const ROLE_ADMIN = new Role('admin', Object.values(RIGHTS)) // all rights diff --git a/backend/src/config/index.ts b/backend/src/config/index.ts index 4cd428153..b1fb8e397 100644 --- a/backend/src/config/index.ts +++ b/backend/src/config/index.ts @@ -10,7 +10,7 @@ Decimal.set({ }) const constants = { - DB_VERSION: '0030-transaction_link', + DB_VERSION: '0031-remove_sendEmail_from_transaction_link', DECAY_START_TIME: new Date('2021-05-13 17:46:31'), // GMT+0 } diff --git a/backend/src/graphql/arg/TransactionLinkArgs.ts b/backend/src/graphql/arg/TransactionLinkArgs.ts index 5ccb967d3..553efcfbe 100644 --- a/backend/src/graphql/arg/TransactionLinkArgs.ts +++ b/backend/src/graphql/arg/TransactionLinkArgs.ts @@ -8,7 +8,4 @@ export default class TransactionLinkArgs { @Field(() => String) memo: string - - @Field(() => Boolean, { nullable: true }) - showEmail?: boolean } diff --git a/backend/src/graphql/model/TransactionLink.ts b/backend/src/graphql/model/TransactionLink.ts index f41d34acc..414bba73f 100644 --- a/backend/src/graphql/model/TransactionLink.ts +++ b/backend/src/graphql/model/TransactionLink.ts @@ -14,7 +14,6 @@ export class TransactionLink { this.code = transactionLink.code this.createdAt = transactionLink.createdAt this.validUntil = transactionLink.validUntil - this.showEmail = transactionLink.showEmail this.deletedAt = transactionLink.deletedAt this.redeemedAt = transactionLink.redeemedAt this.redeemedBy = redeemedBy @@ -47,9 +46,6 @@ export class TransactionLink { @Field(() => Date) validUntil: Date - @Field(() => Boolean) - showEmail: boolean - @Field(() => Date, { nullable: true }) redeemedAt: Date | null diff --git a/backend/src/graphql/resolver/TransactionLinkResolver.ts b/backend/src/graphql/resolver/TransactionLinkResolver.ts index 4065bb13a..071444de9 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 } from 'type-graphql' +import { Resolver, Args, Arg, Authorized, Ctx, Mutation, Query } from 'type-graphql' import { getCustomRepository } from '@dbTools/typeorm' import { TransactionLink } from '@model/TransactionLink' import { TransactionLink as dbTransactionLink } from '@entity/TransactionLink' @@ -36,7 +36,7 @@ export class TransactionLinkResolver { @Authorized([RIGHTS.CREATE_TRANSACTION_LINK]) @Mutation(() => TransactionLink) async createTransactionLink( - @Args() { amount, memo, showEmail = false }: TransactionLinkArgs, + @Args() { amount, memo }: TransactionLinkArgs, @Ctx() context: any, ): Promise { const userRepository = getCustomRepository(UserRepository) @@ -61,7 +61,6 @@ export class TransactionLinkResolver { transactionLink.code = transactionLinkCode(createdDate) transactionLink.createdAt = createdDate transactionLink.validUntil = validUntil - transactionLink.showEmail = showEmail await dbTransactionLink.save(transactionLink).catch(() => { throw new Error('Unable to save transaction link') }) @@ -69,6 +68,32 @@ export class TransactionLinkResolver { return new TransactionLink(transactionLink, new User(user)) } + @Authorized([RIGHTS.DELETE_TRANSACTION_LINK]) + @Mutation(() => Boolean) + async deleteTransactionLink(@Arg('id') id: number, @Ctx() context: any): Promise { + const userRepository = getCustomRepository(UserRepository) + const user = await userRepository.findByPubkeyHex(context.pubKey) + + const transactionLink = await dbTransactionLink.findOne({ id }) + if (!transactionLink) { + throw new Error('Transaction Link not found!') + } + + if (transactionLink.userId !== user.id) { + throw new Error('Transaction Link cannot be deleted!') + } + + if (transactionLink.redeemedBy) { + throw new Error('Transaction Link already redeemed!') + } + + await transactionLink.softRemove().catch(() => { + throw new Error('Transaction Link could not be deleted!') + }) + + return true + } + @Authorized([RIGHTS.QUERY_TRANSACTION_LINK]) @Query(() => TransactionLink) async queryTransactionLink( diff --git a/database/entity/0031-remove_sendEmail_from_transaction_link/TransactionLink.ts b/database/entity/0031-remove_sendEmail_from_transaction_link/TransactionLink.ts new file mode 100644 index 000000000..9cd42258a --- /dev/null +++ b/database/entity/0031-remove_sendEmail_from_transaction_link/TransactionLink.ts @@ -0,0 +1,61 @@ +import Decimal from 'decimal.js-light' +import { BaseEntity, Entity, PrimaryGeneratedColumn, Column, DeleteDateColumn } from 'typeorm' +import { DecimalTransformer } from '../../src/typeorm/DecimalTransformer' + +@Entity('transaction_links') +export class TransactionLink extends BaseEntity { + @PrimaryGeneratedColumn('increment', { unsigned: true }) + id: number + + @Column({ unsigned: true, nullable: false }) + userId: number + + @Column({ + type: 'decimal', + precision: 40, + scale: 20, + nullable: false, + transformer: DecimalTransformer, + }) + amount: Decimal + + @Column({ + type: 'decimal', + name: 'hold_available_amount', + precision: 40, + scale: 20, + nullable: false, + transformer: DecimalTransformer, + }) + holdAvailableAmount: Decimal + + @Column({ length: 255, nullable: false, collation: 'utf8mb4_unicode_ci' }) + memo: string + + @Column({ length: 24, nullable: false, collation: 'utf8mb4_unicode_ci' }) + code: string + + @Column({ + type: 'datetime', + nullable: false, + }) + createdAt: Date + + @DeleteDateColumn() + deletedAt: Date | null + + @Column({ + type: 'datetime', + nullable: false, + }) + validUntil: Date + + @Column({ + type: 'datetime', + nullable: true, + }) + redeemedAt: Date | null + + @Column({ type: 'int', unsigned: true, nullable: true }) + redeemedBy: number | null +} diff --git a/database/entity/TransactionLink.ts b/database/entity/TransactionLink.ts index fde2ba9e0..a483f0171 100644 --- a/database/entity/TransactionLink.ts +++ b/database/entity/TransactionLink.ts @@ -1 +1 @@ -export { TransactionLink } from './0030-transaction_link/TransactionLink' +export { TransactionLink } from './0031-remove_sendEmail_from_transaction_link/TransactionLink' diff --git a/database/migrations/0031-remove_sendEmail_from_transaction_link.ts b/database/migrations/0031-remove_sendEmail_from_transaction_link.ts new file mode 100644 index 000000000..76b2ee742 --- /dev/null +++ b/database/migrations/0031-remove_sendEmail_from_transaction_link.ts @@ -0,0 +1,14 @@ +/* MIGRATION TO REMOVE sendEmail FIELD FROM TRANSACTION_LINK TABLE */ + +/* eslint-disable @typescript-eslint/explicit-module-boundary-types */ +/* eslint-disable @typescript-eslint/no-explicit-any */ + +export async function upgrade(queryFn: (query: string, values?: any[]) => Promise>) { + await queryFn('ALTER TABLE `transaction_links` DROP COLUMN `showEmail`;') +} + +export async function downgrade(queryFn: (query: string, values?: any[]) => Promise>) { + await queryFn( + 'ALTER TABLE `transaction_links` ADD COLUMN `showEmail` boolean NOT NULL DEFAULT false AFTER `validUntil`;', + ) +}