From c08aac58a9ca13c723a39f8489fc67f4cfcbe25f Mon Sep 17 00:00:00 2001 From: joseji Date: Thu, 22 Sep 2022 11:44:30 +0200 Subject: [PATCH 01/69] events and half log tests --- .../resolver/ContributionResolver.test.ts | 24 ++++++++++++++++++- .../graphql/resolver/ContributionResolver.ts | 18 ++++++++++++-- 2 files changed, 39 insertions(+), 3 deletions(-) diff --git a/backend/src/graphql/resolver/ContributionResolver.test.ts b/backend/src/graphql/resolver/ContributionResolver.test.ts index 20f11ff9a..b91d3213b 100644 --- a/backend/src/graphql/resolver/ContributionResolver.test.ts +++ b/backend/src/graphql/resolver/ContributionResolver.test.ts @@ -16,6 +16,9 @@ import { userFactory } from '@/seeds/factory/user' import { creationFactory } from '@/seeds/factory/creation' import { creations } from '@/seeds/creation/index' import { peterLustig } from '@/seeds/users/peter-lustig' +import { EventProtocol } from '@entity/EventProtocol' +import { EventProtocolType } from '@/event/EventProtocolType' +import { logger } from '@test/testSetup' let mutate: any, query: any, con: any let testEnv: any @@ -35,6 +38,8 @@ afterAll(async () => { }) describe('ContributionResolver', () => { + let bibi: any + describe('createContribution', () => { describe('unauthenticated', () => { it('returns an error', async () => { @@ -54,7 +59,7 @@ describe('ContributionResolver', () => { describe('authenticated with valid user', () => { beforeAll(async () => { await userFactory(testEnv, bibiBloxberg) - await query({ + bibi = await query({ query: login, variables: { email: 'bibi@bloxberg.de', password: 'Aa12345_' }, }) @@ -84,6 +89,10 @@ describe('ContributionResolver', () => { ) }) + it('logs the error found', () => { + expect(logger.error).toBeCalledWith(`memo text is too short: memo.length=4 < (5)`) + }) + it('throws error when memo length greater than 255 chars', async () => { const date = new Date() await expect( @@ -102,6 +111,10 @@ describe('ContributionResolver', () => { ) }) + it('logs the error found', () => { + expect(logger.error).toBeCalledWith(`memo text is too long: memo.length=259 > (255)`) + }) + it('throws error when creationDate not-valid', async () => { await expect( mutate({ @@ -165,6 +178,15 @@ describe('ContributionResolver', () => { }), ) }) + + it('stores the create contribution event in the database', async () => { + await expect(EventProtocol.find()).resolves.toContainEqual( + expect.objectContaining({ + type: EventProtocolType.CONTRIBUTION_CREATE, + userId: bibi.data.login.id, + }), + ) + }) }) }) }) diff --git a/backend/src/graphql/resolver/ContributionResolver.ts b/backend/src/graphql/resolver/ContributionResolver.ts index fc93880f1..b788384f1 100644 --- a/backend/src/graphql/resolver/ContributionResolver.ts +++ b/backend/src/graphql/resolver/ContributionResolver.ts @@ -13,6 +13,8 @@ import { Contribution, ContributionListResult } from '@model/Contribution' import { UnconfirmedContribution } from '@model/UnconfirmedContribution' import { validateContribution, getUserCreation, updateCreations } from './util/creations' import { MEMO_MAX_CHARS, MEMO_MIN_CHARS } from './const/const' +import { Event, EventConfirmationEmail, EventContributionCreate } from '@/event/Event' +import { eventProtocol } from '@/event/EventProtocolEmitter' @Resolver() export class ContributionResolver { @@ -23,15 +25,17 @@ export class ContributionResolver { @Ctx() context: Context, ): Promise { if (memo.length > MEMO_MAX_CHARS) { - logger.error(`memo text is too long: memo.length=${memo.length} > (${MEMO_MAX_CHARS}`) + logger.error(`memo text is too long: memo.length=${memo.length} > (${MEMO_MAX_CHARS})`) throw new Error(`memo text is too long (${MEMO_MAX_CHARS} characters maximum)`) } if (memo.length < MEMO_MIN_CHARS) { - logger.error(`memo text is too short: memo.length=${memo.length} < (${MEMO_MIN_CHARS}`) + logger.error(`memo text is too short: memo.length=${memo.length} < (${MEMO_MIN_CHARS})`) throw new Error(`memo text is too short (${MEMO_MIN_CHARS} characters minimum)`) } + const event = new Event() + const user = getUser(context) const creations = await getUserCreation(user.id) logger.trace('creations', creations) @@ -49,6 +53,11 @@ export class ContributionResolver { logger.trace('contribution to save', contribution) await dbContribution.save(contribution) + + const eventCreateContribution = new EventContributionCreate() + eventCreateContribution.userId = user.id + await eventProtocol.writeEvent(event.setEventContributionCreate(eventCreateContribution)) + return new UnconfirmedContribution(contribution, user, creations) } @@ -61,12 +70,15 @@ export class ContributionResolver { const user = getUser(context) const contribution = await dbContribution.findOne(id) if (!contribution) { + logger.error('Contribution not found for given id') throw new Error('Contribution not found for given id.') } if (contribution.userId !== user.id) { + logger.error('Can not delete contribution of another user') throw new Error('Can not delete contribution of another user') } if (contribution.confirmedAt) { + logger.error('A confirmed contribution can not be deleted') throw new Error('A confirmed contribution can not be deleted') } contribution.contributionStatus = ContributionStatus.DELETED @@ -154,9 +166,11 @@ export class ContributionResolver { where: { id: contributionId, confirmedAt: IsNull() }, }) if (!contributionToUpdate) { + logger.error('No contribution found for given id') throw new Error('No contribution found to given id.') } if (contributionToUpdate.userId !== user.id) { + logger.error('user of the pending contribution and send user does not correspond') throw new Error('user of the pending contribution and send user does not correspond') } From 0176131c39db97c81c208978957ae0e165aabe29 Mon Sep 17 00:00:00 2001 From: joseji Date: Thu, 22 Sep 2022 12:07:12 +0200 Subject: [PATCH 02/69] errors are now logged, and events are checked --- .../resolver/ContributionResolver.test.ts | 58 ++++++++++++++++++- .../graphql/resolver/ContributionResolver.ts | 4 +- .../src/graphql/resolver/util/creations.ts | 4 ++ 3 files changed, 63 insertions(+), 3 deletions(-) diff --git a/backend/src/graphql/resolver/ContributionResolver.test.ts b/backend/src/graphql/resolver/ContributionResolver.test.ts index b91d3213b..d08396285 100644 --- a/backend/src/graphql/resolver/ContributionResolver.test.ts +++ b/backend/src/graphql/resolver/ContributionResolver.test.ts @@ -134,6 +134,12 @@ describe('ContributionResolver', () => { ) }) + it('logs the error found', () => { + expect(logger.error).toBeCalledWith( + 'No information for available creations for the given date', + ) + }) + it('throws error when creationDate 3 month behind', async () => { const date = new Date() await expect( @@ -153,6 +159,12 @@ describe('ContributionResolver', () => { }), ) }) + + it('logs the error found', () => { + expect(logger.error).toBeCalledWith( + 'No information for available creations for the given date', + ) + }) }) describe('valid input', () => { @@ -369,6 +381,10 @@ describe('ContributionResolver', () => { }), ) }) + + it('logs the error found', () => { + expect(logger.error).toBeCalledWith('No contribution found to given id') + }) }) describe('Memo length smaller than 5 chars', () => { @@ -390,6 +406,10 @@ describe('ContributionResolver', () => { }), ) }) + + it('logs the error found', () => { + expect(logger.error).toBeCalledWith('memo text is too short: memo.length=4 < (5)') + }) }) describe('Memo length greater than 255 chars', () => { @@ -411,6 +431,10 @@ describe('ContributionResolver', () => { }), ) }) + + it('logs the error found', () => { + expect(logger.error).toBeCalledWith('memo text is too long: memo.length=259 > (255)') + }) }) describe('wrong user tries to update the contribution', () => { @@ -442,6 +466,12 @@ describe('ContributionResolver', () => { }), ) }) + + it('logs the error found', () => { + expect(logger.error).toBeCalledWith( + 'user of the pending contribution and send user does not correspond', + ) + }) }) describe('admin tries to update a user contribution', () => { @@ -463,6 +493,8 @@ describe('ContributionResolver', () => { }), ) }) + + // TODO check that the error is logged (need to modify AdminResolver, avoid conflicts) }) describe('update too much so that the limit is exceeded', () => { @@ -494,6 +526,12 @@ describe('ContributionResolver', () => { }), ) }) + + it('logs the error found', () => { + expect(logger.error).toBeCalledWith( + 'The amount (1019 GDD) to be created exceeds the amount (1000 GDD) still available for this month.', + ) + }) }) describe('update creation to a date that is older than 3 months', () => { @@ -517,6 +555,12 @@ describe('ContributionResolver', () => { }), ) }) + + it('logs the error found', () => { + expect(logger.error).toBeCalledWith( + 'No information for available creations for the given date', + ) + }) }) describe('valid input', () => { @@ -686,9 +730,13 @@ describe('ContributionResolver', () => { }), ) }) + + it('logs the error found', () => { + expect(logger.error).toBeCalledWith('Contribution not found for given id') + }) }) - describe('other user sends a deleteContribtuion', () => { + describe('other user sends a deleteContribution', () => { it('returns an error', async () => { await query({ query: login, @@ -707,6 +755,10 @@ describe('ContributionResolver', () => { }), ) }) + + it('logs the error found', () => { + expect(logger.error).toBeCalledWith('Can not delete contribution of another user') + }) }) describe('User deletes own contribution', () => { @@ -751,6 +803,10 @@ describe('ContributionResolver', () => { }), ) }) + + it('logs the error found', () => { + expect(logger.error).toBeCalledWith('A confirmed contribution can not be deleted') + }) }) }) }) diff --git a/backend/src/graphql/resolver/ContributionResolver.ts b/backend/src/graphql/resolver/ContributionResolver.ts index b788384f1..3c33a4e0f 100644 --- a/backend/src/graphql/resolver/ContributionResolver.ts +++ b/backend/src/graphql/resolver/ContributionResolver.ts @@ -13,7 +13,7 @@ import { Contribution, ContributionListResult } from '@model/Contribution' import { UnconfirmedContribution } from '@model/UnconfirmedContribution' import { validateContribution, getUserCreation, updateCreations } from './util/creations' import { MEMO_MAX_CHARS, MEMO_MIN_CHARS } from './const/const' -import { Event, EventConfirmationEmail, EventContributionCreate } from '@/event/Event' +import { Event, EventContributionCreate } from '@/event/Event' import { eventProtocol } from '@/event/EventProtocolEmitter' @Resolver() @@ -166,7 +166,7 @@ export class ContributionResolver { where: { id: contributionId, confirmedAt: IsNull() }, }) if (!contributionToUpdate) { - logger.error('No contribution found for given id') + logger.error('No contribution found to given id') throw new Error('No contribution found to given id.') } if (contributionToUpdate.userId !== user.id) { diff --git a/backend/src/graphql/resolver/util/creations.ts b/backend/src/graphql/resolver/util/creations.ts index ad15ebec6..afbadead1 100644 --- a/backend/src/graphql/resolver/util/creations.ts +++ b/backend/src/graphql/resolver/util/creations.ts @@ -19,10 +19,14 @@ export const validateContribution = ( const index = getCreationIndex(creationDate.getMonth()) if (index < 0) { + logger.error('No information for available creations for the given date') throw new Error('No information for available creations for the given date') } if (amount.greaterThan(creations[index].toString())) { + logger.error( + `The amount (${amount} GDD) to be created exceeds the amount (${creations[index]} GDD) still available for this month.`, + ) throw new Error( `The amount (${amount} GDD) to be created exceeds the amount (${creations[index]} GDD) still available for this month.`, ) From 79f7ebce57d2179d1b365de8dfb6f6118fde103f Mon Sep 17 00:00:00 2001 From: joseji Date: Thu, 22 Sep 2022 17:35:41 +0200 Subject: [PATCH 03/69] updated event working, deletion is not working properly (deeper than the event itself) --- backend/src/event/Event.ts | 16 ++++++++++++ backend/src/event/EventProtocolType.ts | 2 ++ .../resolver/ContributionResolver.test.ts | 21 ++++++++++++++++ .../graphql/resolver/ContributionResolver.ts | 25 ++++++++++++++++++- 4 files changed, 63 insertions(+), 1 deletion(-) diff --git a/backend/src/event/Event.ts b/backend/src/event/Event.ts index 6f07661f1..40eb333fd 100644 --- a/backend/src/event/Event.ts +++ b/backend/src/event/Event.ts @@ -48,6 +48,8 @@ export class EventTransactionCreation extends EventBasicUserId { export class EventTransactionReceive extends EventBasicTx {} export class EventTransactionReceiveRedeem extends EventBasicTx {} export class EventContributionCreate extends EventBasicCt {} +export class EventContributionDelete extends EventBasicCt {} +export class EventContributionUpdate extends EventBasicCt {} export class EventContributionConfirm extends EventBasicCt { xUserId: number xCommunityId: number @@ -206,6 +208,20 @@ export class Event { return this } + public setEventContributionDelete(ev: EventContributionDelete): Event { + this.setByBasicCt(ev.userId, ev.contributionId, ev.amount) + this.type = EventProtocolType.CONTRIBUTION_DELETE + + return this + } + + public setEventContributionUpdate(ev: EventContributionUpdate): Event { + this.setByBasicCt(ev.userId, ev.contributionId, ev.amount) + this.type = EventProtocolType.CONTRIBUTION_UPDATE + + return this + } + public setEventContributionConfirm(ev: EventContributionConfirm): Event { this.setByBasicCt(ev.userId, ev.contributionId, ev.amount) if (ev.xUserId) this.xUserId = ev.xUserId diff --git a/backend/src/event/EventProtocolType.ts b/backend/src/event/EventProtocolType.ts index 0f61f787a..c0fc1bb8e 100644 --- a/backend/src/event/EventProtocolType.ts +++ b/backend/src/event/EventProtocolType.ts @@ -21,4 +21,6 @@ export enum EventProtocolType { CONTRIBUTION_CONFIRM = 'CONTRIBUTION_CONFIRM', CONTRIBUTION_LINK_DEFINE = 'CONTRIBUTION_LINK_DEFINE', CONTRIBUTION_LINK_ACTIVATE_REDEEM = 'CONTRIBUTION_LINK_ACTIVATE_REDEEM', + CONTRIBUTION_DELETE = 'CONTRIBUTION_DELETE', + CONTRIBUTION_UPDATE = 'CONTRIBUTION_UPDATE', } diff --git a/backend/src/graphql/resolver/ContributionResolver.test.ts b/backend/src/graphql/resolver/ContributionResolver.test.ts index d08396285..683946633 100644 --- a/backend/src/graphql/resolver/ContributionResolver.test.ts +++ b/backend/src/graphql/resolver/ContributionResolver.test.ts @@ -19,6 +19,7 @@ import { peterLustig } from '@/seeds/users/peter-lustig' import { EventProtocol } from '@entity/EventProtocol' import { EventProtocolType } from '@/event/EventProtocolType' import { logger } from '@test/testSetup' +import { Contribution } from '@entity/Contribution' let mutate: any, query: any, con: any let testEnv: any @@ -587,6 +588,15 @@ describe('ContributionResolver', () => { }), ) }) + + it('stores the update contribution event in the database', async () => { + await expect(EventProtocol.find()).resolves.toContainEqual( + expect.objectContaining({ + type: EventProtocolType.CONTRIBUTION_UPDATE, + contributionId: result.data.createContribution.id, + }), + ) + }) }) }) }) @@ -763,6 +773,7 @@ describe('ContributionResolver', () => { describe('User deletes own contribution', () => { it('deletes successfully', async () => { + console.log(await Contribution.find({ id: result.data.createContribution.id })) await expect( mutate({ mutation: deleteContribution, @@ -772,6 +783,16 @@ describe('ContributionResolver', () => { }), ).resolves.toBeTruthy() }) + + it('stores the delete contribution event in the database', async () => { + console.log(await Contribution.find({ id: result.data.createContribution.id })) + await expect(EventProtocol.find()).resolves.toContainEqual( + expect.objectContaining({ + type: EventProtocolType.CONTRIBUTION_DELETE, + // id: result.data.createContribution.id, + }), + ) + }) }) describe('User deletes already confirmed contribution', () => { diff --git a/backend/src/graphql/resolver/ContributionResolver.ts b/backend/src/graphql/resolver/ContributionResolver.ts index 3c33a4e0f..9886eeb05 100644 --- a/backend/src/graphql/resolver/ContributionResolver.ts +++ b/backend/src/graphql/resolver/ContributionResolver.ts @@ -13,7 +13,12 @@ import { Contribution, ContributionListResult } from '@model/Contribution' import { UnconfirmedContribution } from '@model/UnconfirmedContribution' import { validateContribution, getUserCreation, updateCreations } from './util/creations' import { MEMO_MAX_CHARS, MEMO_MIN_CHARS } from './const/const' -import { Event, EventContributionCreate } from '@/event/Event' +import { + Event, + EventContributionCreate, + EventContributionDelete, + EventContributionUpdate, +} from '@/event/Event' import { eventProtocol } from '@/event/EventProtocolEmitter' @Resolver() @@ -56,6 +61,8 @@ export class ContributionResolver { const eventCreateContribution = new EventContributionCreate() eventCreateContribution.userId = user.id + eventCreateContribution.amount = amount + eventCreateContribution.contributionId = contribution.id await eventProtocol.writeEvent(event.setEventContributionCreate(eventCreateContribution)) return new UnconfirmedContribution(contribution, user, creations) @@ -67,6 +74,7 @@ export class ContributionResolver { @Arg('id', () => Int) id: number, @Ctx() context: Context, ): Promise { + const event = new Event() const user = getUser(context) const contribution = await dbContribution.findOne(id) if (!contribution) { @@ -81,8 +89,16 @@ export class ContributionResolver { logger.error('A confirmed contribution can not be deleted') throw new Error('A confirmed contribution can not be deleted') } + contribution.contributionStatus = ContributionStatus.DELETED + contribution.deletedAt = new Date() await contribution.save() + + const eventDeleteContribution = new EventContributionDelete() + eventDeleteContribution.userId = user.id + eventDeleteContribution.contributionId = contribution.id + await eventProtocol.writeEvent(event.setEventContributionDelete(eventDeleteContribution)) + const res = await contribution.softRemove() return !!res } @@ -188,6 +204,13 @@ export class ContributionResolver { contributionToUpdate.contributionStatus = ContributionStatus.PENDING dbContribution.save(contributionToUpdate) + const event = new Event() + + const eventUpdateContribution = new EventContributionUpdate() + eventUpdateContribution.userId = user.id + eventUpdateContribution.contributionId = contributionId + await eventProtocol.writeEvent(event.setEventContributionUpdate(eventUpdateContribution)) + return new UnconfirmedContribution(contributionToUpdate, user, creations) } } From 8c6a2348611a16bfc9b65cca6a8a67b81c84ace3 Mon Sep 17 00:00:00 2001 From: elweyn Date: Fri, 23 Sep 2022 16:20:41 +0200 Subject: [PATCH 04/69] Change contributions table to have deleted_by in the object. --- .../Contribution.ts | 92 +++++++++++++++++++ database/entity/Contribution.ts | 2 +- .../0049-add_delete_by_to_contributions.ts | 12 +++ 3 files changed, 105 insertions(+), 1 deletion(-) create mode 100644 database/entity/0049-add_delete_by_to_contributions/Contribution.ts create mode 100644 database/migrations/0049-add_delete_by_to_contributions.ts diff --git a/database/entity/0049-add_delete_by_to_contributions/Contribution.ts b/database/entity/0049-add_delete_by_to_contributions/Contribution.ts new file mode 100644 index 000000000..32c6f32a3 --- /dev/null +++ b/database/entity/0049-add_delete_by_to_contributions/Contribution.ts @@ -0,0 +1,92 @@ +import Decimal from 'decimal.js-light' +import { + BaseEntity, + Column, + Entity, + PrimaryGeneratedColumn, + DeleteDateColumn, + JoinColumn, + ManyToOne, + OneToMany, +} from 'typeorm' +import { DecimalTransformer } from '../../src/typeorm/DecimalTransformer' +import { User } from '../User' +import { ContributionMessage } from '../ContributionMessage' + +@Entity('contributions') +export class Contribution extends BaseEntity { + @PrimaryGeneratedColumn('increment', { unsigned: true }) + id: number + + @Column({ unsigned: true, nullable: false, name: 'user_id' }) + userId: number + + @ManyToOne(() => User, (user) => user.contributions) + @JoinColumn({ name: 'user_id' }) + user: User + + @Column({ type: 'datetime', default: () => 'CURRENT_TIMESTAMP', name: 'created_at' }) + createdAt: Date + + @Column({ type: 'datetime', nullable: false, name: 'contribution_date' }) + contributionDate: Date + + @Column({ length: 255, nullable: false, collation: 'utf8mb4_unicode_ci' }) + memo: string + + @Column({ + type: 'decimal', + precision: 40, + scale: 20, + nullable: false, + transformer: DecimalTransformer, + }) + amount: Decimal + + @Column({ unsigned: true, nullable: true, name: 'moderator_id' }) + moderatorId: number + + @Column({ unsigned: true, nullable: true, name: 'contribution_link_id' }) + contributionLinkId: number + + @Column({ unsigned: true, nullable: true, name: 'confirmed_by' }) + confirmedBy: number + + @Column({ nullable: true, name: 'confirmed_at' }) + confirmedAt: Date + + @Column({ unsigned: true, nullable: true, name: 'denied_by' }) + deniedBy: number + + @Column({ nullable: true, name: 'denied_at' }) + deniedAt: Date + + @Column({ + name: 'contribution_type', + length: 12, + nullable: false, + collation: 'utf8mb4_unicode_ci', + }) + contributionType: string + + @Column({ + name: 'contribution_status', + length: 12, + nullable: false, + collation: 'utf8mb4_unicode_ci', + }) + contributionStatus: string + + @Column({ unsigned: true, nullable: true, name: 'transaction_id' }) + transactionId: number + + @DeleteDateColumn({ name: 'deleted_at' }) + deletedAt: Date | null + + @DeleteDateColumn({ unsigned: true, nullable: true, name: 'deleted_by' }) + deletedBy: number + + @OneToMany(() => ContributionMessage, (message) => message.contribution) + @JoinColumn({ name: 'contribution_id' }) + messages?: ContributionMessage[] +} diff --git a/database/entity/Contribution.ts b/database/entity/Contribution.ts index f6530f00b..b6d2c36c9 100644 --- a/database/entity/Contribution.ts +++ b/database/entity/Contribution.ts @@ -1 +1 @@ -export { Contribution } from './0047-messages_tables/Contribution' +export { Contribution } from './0049-add_delete_by_to_contributions/Contribution' diff --git a/database/migrations/0049-add_delete_by_to_contributions.ts b/database/migrations/0049-add_delete_by_to_contributions.ts new file mode 100644 index 000000000..21d0eda97 --- /dev/null +++ b/database/migrations/0049-add_delete_by_to_contributions.ts @@ -0,0 +1,12 @@ +/* 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 \`contributions\` ADD COLUMN \`deleted_by\` int(10) unsigned DEFAULT NULL;`, + ) +} + +export async function downgrade(queryFn: (query: string, values?: any[]) => Promise>) { + await queryFn(`ALTER TABLE \`contributions\` DROP COLUMN \`deleted_by\`;`) +} From 8c69b94e8ed374007645076de23a6a998692403b Mon Sep 17 00:00:00 2001 From: elweyn Date: Fri, 23 Sep 2022 16:25:22 +0200 Subject: [PATCH 05/69] Throw error if moderator tries to deleted own contribution created as user. Add deletedby value. --- backend/src/graphql/resolver/AdminResolver.ts | 13 ++++++++++++- 1 file changed, 12 insertions(+), 1 deletion(-) diff --git a/backend/src/graphql/resolver/AdminResolver.ts b/backend/src/graphql/resolver/AdminResolver.ts index d71ffc72c..ba7baa703 100644 --- a/backend/src/graphql/resolver/AdminResolver.ts +++ b/backend/src/graphql/resolver/AdminResolver.ts @@ -393,12 +393,23 @@ export class AdminResolver { @Authorized([RIGHTS.ADMIN_DELETE_CONTRIBUTION]) @Mutation(() => Boolean) - async adminDeleteContribution(@Arg('id', () => Int) id: number): Promise { + async adminDeleteContribution( + @Arg('id', () => Int) id: number, + @Ctx() context: Context, + ): Promise { const contribution = await Contribution.findOne(id) if (!contribution) { throw new Error('Contribution not found for given id.') } + const moderator = getUser(context) + if ( + contribution.contributionType === ContributionType.USER && + contribution.userId === moderator.id + ) { + throw new Error('Own contribution can not be deleted as admin') + } contribution.contributionStatus = ContributionStatus.DELETED + contribution.deletedBy = moderator.id await contribution.save() const res = await contribution.softRemove() return !!res From e7b5400db2a2ad1d1c216401267f34464b4e5381 Mon Sep 17 00:00:00 2001 From: elweyn Date: Fri, 23 Sep 2022 16:49:12 +0200 Subject: [PATCH 06/69] Change the database version needed for the backend. --- backend/src/config/index.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/backend/src/config/index.ts b/backend/src/config/index.ts index 6a2ebba87..cd5183693 100644 --- a/backend/src/config/index.ts +++ b/backend/src/config/index.ts @@ -10,7 +10,7 @@ Decimal.set({ }) const constants = { - DB_VERSION: '0048-add_is_moderator_to_contribution_messages', + DB_VERSION: '0049-add_delete_by_to_contributions', // '0048-add_is_moderator_to_contribution_messages', DECAY_START_TIME: new Date('2021-05-13 17:46:31-0000'), // GMT+0 LOG4JS_CONFIG: 'log4js-config.json', // default log level on production should be info From 60d2e2ff7bd0c093bb7b4acbea0b81ca34044e42 Mon Sep 17 00:00:00 2001 From: joseji Date: Fri, 23 Sep 2022 18:46:40 +0200 Subject: [PATCH 07/69] fixed contribution delete event saving and testing --- .../resolver/ContributionResolver.test.ts | 21 +++++++++++++++---- 1 file changed, 17 insertions(+), 4 deletions(-) diff --git a/backend/src/graphql/resolver/ContributionResolver.test.ts b/backend/src/graphql/resolver/ContributionResolver.test.ts index 683946633..ee261c545 100644 --- a/backend/src/graphql/resolver/ContributionResolver.test.ts +++ b/backend/src/graphql/resolver/ContributionResolver.test.ts @@ -19,7 +19,6 @@ import { peterLustig } from '@/seeds/users/peter-lustig' import { EventProtocol } from '@entity/EventProtocol' import { EventProtocolType } from '@/event/EventProtocolType' import { logger } from '@test/testSetup' -import { Contribution } from '@entity/Contribution' let mutate: any, query: any, con: any let testEnv: any @@ -773,7 +772,6 @@ describe('ContributionResolver', () => { describe('User deletes own contribution', () => { it('deletes successfully', async () => { - console.log(await Contribution.find({ id: result.data.createContribution.id })) await expect( mutate({ mutation: deleteContribution, @@ -785,11 +783,26 @@ describe('ContributionResolver', () => { }) it('stores the delete contribution event in the database', async () => { - console.log(await Contribution.find({ id: result.data.createContribution.id })) + const contribution = await mutate({ + mutation: createContribution, + variables: { + amount: 166.0, + memo: 'Whatever contribution', + creationDate: new Date().toString(), + }, + }) + + await mutate({ + mutation: deleteContribution, + variables: { + id: contribution.data.createContribution.id, + }, + }) + await expect(EventProtocol.find()).resolves.toContainEqual( expect.objectContaining({ type: EventProtocolType.CONTRIBUTION_DELETE, - // id: result.data.createContribution.id, + contributionId: contribution.data.createContribution.id, }), ) }) From 744c961c0bcda7595eb6ed1f8269aef5c993d700 Mon Sep 17 00:00:00 2001 From: joseji Date: Fri, 23 Sep 2022 19:33:54 +0200 Subject: [PATCH 08/69] fixed tests with new log message --- backend/src/event/EventProtocolType.ts | 12 ++++++++++++ .../graphql/resolver/ContributionResolver.test.ts | 11 ++++++++--- backend/src/graphql/resolver/util/creations.ts | 5 ++++- 3 files changed, 24 insertions(+), 4 deletions(-) diff --git a/backend/src/event/EventProtocolType.ts b/backend/src/event/EventProtocolType.ts index c0fc1bb8e..4265fb924 100644 --- a/backend/src/event/EventProtocolType.ts +++ b/backend/src/event/EventProtocolType.ts @@ -3,24 +3,36 @@ export enum EventProtocolType { VISIT_GRADIDO = 'VISIT_GRADIDO', REGISTER = 'REGISTER', REDEEM_REGISTER = 'REDEEM_REGISTER', + VERIFY_REDEEM = 'VERIFY_REDEEM', // TODO INACTIVE_ACCOUNT = 'INACTIVE_ACCOUNT', SEND_CONFIRMATION_EMAIL = 'SEND_CONFIRMATION_EMAIL', + SEND_ACCOUNT_MULTIREGISTRATION_EMAIL = 'SEND_ACCOUNT_MULTIREGISTRATION_EMAIL', // TODO CONFIRM_EMAIL = 'CONFIRM_EMAIL', REGISTER_EMAIL_KLICKTIPP = 'REGISTER_EMAIL_KLICKTIPP', LOGIN = 'LOGIN', + LOGOUT = 'LOGOUT', // TODO REDEEM_LOGIN = 'REDEEM_LOGIN', ACTIVATE_ACCOUNT = 'ACTIVATE_ACCOUNT', + SEND_FORGOT_PASSWORD_EMAIL = 'SEND_FORGOT_PASSWORD_EMAIL', // TODO PASSWORD_CHANGE = 'PASSWORD_CHANGE', + SEND_TRANSACTION_SEND_EMAIL = 'SEND_TRANSACTION_SEND_EMAIL', // TODO + SEND_TRANSACTION_RECEIVE_EMAIL = 'SEND_TRANSACTION_RECEIVE_EMAIL', // TODO TRANSACTION_SEND = 'TRANSACTION_SEND', TRANSACTION_SEND_REDEEM = 'TRANSACTION_SEND_REDEEM', TRANSACTION_REPEATE_REDEEM = 'TRANSACTION_REPEATE_REDEEM', TRANSACTION_CREATION = 'TRANSACTION_CREATION', TRANSACTION_RECEIVE = 'TRANSACTION_RECEIVE', TRANSACTION_RECEIVE_REDEEM = 'TRANSACTION_RECEIVE_REDEEM', + SEND_TRANSACTION_LINK_REDEEM_EMAIL = 'SEND_TRANSACTION_LINK_REDEEM_EMAIL', // TODO + SEND_ADDED_CONTRIBUTION_EMAIL = 'SEND_ADDED_CONTRIBUTION_EMAIL', // TODO + SEND_CONTRIBUTION_CONFIRM_EMAIL = 'SEND_CONTRIBUTION_CONFIRM_EMAIL', // TODO CONTRIBUTION_CREATE = 'CONTRIBUTION_CREATE', CONTRIBUTION_CONFIRM = 'CONTRIBUTION_CONFIRM', + CONTRIBUTION_DENY = 'CONTRIBUTION_DENY', // TODO CONTRIBUTION_LINK_DEFINE = 'CONTRIBUTION_LINK_DEFINE', CONTRIBUTION_LINK_ACTIVATE_REDEEM = 'CONTRIBUTION_LINK_ACTIVATE_REDEEM', CONTRIBUTION_DELETE = 'CONTRIBUTION_DELETE', CONTRIBUTION_UPDATE = 'CONTRIBUTION_UPDATE', + USER_CREATE_CONTRIBUTION_MESSAGE = 'USER_CREATE_CONTRIBUTION_MESSAGE', // TODO + ADMIN_CREATE_CONTRIBUTION_MESSAGE = 'ADMIN_CREATE_CONTRIBUTION_MESSAGE', // TODO } diff --git a/backend/src/graphql/resolver/ContributionResolver.test.ts b/backend/src/graphql/resolver/ContributionResolver.test.ts index ee261c545..b8bbebbd9 100644 --- a/backend/src/graphql/resolver/ContributionResolver.test.ts +++ b/backend/src/graphql/resolver/ContributionResolver.test.ts @@ -136,7 +136,8 @@ describe('ContributionResolver', () => { it('logs the error found', () => { expect(logger.error).toBeCalledWith( - 'No information for available creations for the given date', + 'No information for available creations with the given creationDate=', + new Date('non-valid').toDateString, ) }) @@ -161,8 +162,10 @@ describe('ContributionResolver', () => { }) it('logs the error found', () => { + const date = new Date() expect(logger.error).toBeCalledWith( - 'No information for available creations for the given date', + 'No information for available creations with the given creationDate=', + new Date(date.setMonth(date.getMonth() - 3).toString()).toDateString, ) }) }) @@ -557,8 +560,10 @@ describe('ContributionResolver', () => { }) it('logs the error found', () => { + const date = new Date() expect(logger.error).toBeCalledWith( - 'No information for available creations for the given date', + 'No information for available creations with the given creationDate=', + new Date(date.setMonth(date.getMonth() - 3).toString()).toDateString, ) }) }) diff --git a/backend/src/graphql/resolver/util/creations.ts b/backend/src/graphql/resolver/util/creations.ts index afbadead1..0b055e1d0 100644 --- a/backend/src/graphql/resolver/util/creations.ts +++ b/backend/src/graphql/resolver/util/creations.ts @@ -19,7 +19,10 @@ export const validateContribution = ( const index = getCreationIndex(creationDate.getMonth()) if (index < 0) { - logger.error('No information for available creations for the given date') + logger.error( + 'No information for available creations with the given creationDate=', + creationDate.toDateString, + ) throw new Error('No information for available creations for the given date') } From 6df8b9a83f7229eacf41afc05456dd1b64d05941 Mon Sep 17 00:00:00 2001 From: elweyn Date: Sat, 24 Sep 2022 11:32:07 +0200 Subject: [PATCH 09/69] Test that when an admin user create a contribution in FE he can not delete it in admin interface. --- .../graphql/resolver/AdminResolver.test.ts | 34 +++++++++++++++++++ 1 file changed, 34 insertions(+) diff --git a/backend/src/graphql/resolver/AdminResolver.test.ts b/backend/src/graphql/resolver/AdminResolver.test.ts index 75c672bd5..57ccd788f 100644 --- a/backend/src/graphql/resolver/AdminResolver.test.ts +++ b/backend/src/graphql/resolver/AdminResolver.test.ts @@ -16,6 +16,7 @@ import { setUserRole, deleteUser, unDeleteUser, + createContribution, adminCreateContribution, adminCreateContributions, adminUpdateContribution, @@ -77,6 +78,7 @@ afterAll(async () => { let admin: User let user: User let creation: Contribution | void +let result: any describe('AdminResolver', () => { describe('set user role', () => { @@ -1360,6 +1362,38 @@ describe('AdminResolver', () => { }) }) + describe('admin deletes own user contribution', () => { + beforeAll(async () => { + await query({ + query: login, + variables: { email: 'peter@lustig.de', password: 'Aa12345_' }, + }) + result = await mutate({ + mutation: createContribution, + variables: { + amount: 100.0, + memo: 'Test env contribution', + creationDate: new Date().toString(), + }, + }) + }) + + it('throws an error', async () => { + await expect( + mutate({ + mutation: adminDeleteContribution, + variables: { + id: result.data.createContribution.id, + }, + }), + ).resolves.toEqual( + expect.objectContaining({ + errors: [new GraphQLError('Own contribution can not be deleted as admin')], + }), + ) + }) + }) + describe('creation id does exist', () => { it('returns true', async () => { await expect( From f136f3c4adde15e09dea37bbb7a8a1c1b24727da Mon Sep 17 00:00:00 2001 From: elweyn Date: Mon, 26 Sep 2022 08:59:46 +0200 Subject: [PATCH 10/69] Remove unused migration. --- .../0049-add_delete_by_to_contributions.ts | 12 ------------ 1 file changed, 12 deletions(-) delete mode 100644 database/migrations/0049-add_delete_by_to_contributions.ts diff --git a/database/migrations/0049-add_delete_by_to_contributions.ts b/database/migrations/0049-add_delete_by_to_contributions.ts deleted file mode 100644 index 21d0eda97..000000000 --- a/database/migrations/0049-add_delete_by_to_contributions.ts +++ /dev/null @@ -1,12 +0,0 @@ -/* 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 \`contributions\` ADD COLUMN \`deleted_by\` int(10) unsigned DEFAULT NULL;`, - ) -} - -export async function downgrade(queryFn: (query: string, values?: any[]) => Promise>) { - await queryFn(`ALTER TABLE \`contributions\` DROP COLUMN \`deleted_by\`;`) -} From 49378c64e250beccdf72045eaea6598257d39bd0 Mon Sep 17 00:00:00 2001 From: joseji Date: Mon, 26 Sep 2022 22:17:07 +0200 Subject: [PATCH 11/69] new events fully implemented --- backend/src/event/Event.ts | 115 +++++++++++++++++++++++++ backend/src/event/EventProtocolType.ts | 24 +++--- 2 files changed, 127 insertions(+), 12 deletions(-) diff --git a/backend/src/event/Event.ts b/backend/src/event/Event.ts index 40eb333fd..f6e6a554c 100644 --- a/backend/src/event/Event.ts +++ b/backend/src/event/Event.ts @@ -30,11 +30,20 @@ export class EventBasicRedeem extends EventBasicUserId { export class EventVisitGradido extends EventBasic {} export class EventRegister extends EventBasicUserId {} export class EventRedeemRegister extends EventBasicRedeem {} +export class EventVerifyRedeem extends EventBasicRedeem {} export class EventInactiveAccount extends EventBasicUserId {} export class EventSendConfirmationEmail extends EventBasicUserId {} +export class EventSendAccountMultiregistrationEmail extends EventBasicUserId {} +export class EventSendForgotPasswordEmail extends EventBasicUserId {} +export class EventSendTransactionSendEmail extends EventBasicRedeem {} +export class EventSendTransactionReceiveEmail extends EventBasicRedeem {} +export class EventSendTransactionLinkRedeemEmail extends EventBasicRedeem {} +export class EventSendAddedContributionEmail extends EventBasicCt {} +export class EventSendContributionConfirmEmail extends EventBasicCt {} export class EventConfirmationEmail extends EventBasicUserId {} export class EventRegisterEmailKlicktipp extends EventBasicUserId {} export class EventLogin extends EventBasicUserId {} +export class EventLogout extends EventBasicUserId {} export class EventRedeemLogin extends EventBasicRedeem {} export class EventActivateAccount extends EventBasicUserId {} export class EventPasswordChange extends EventBasicUserId {} @@ -48,12 +57,22 @@ export class EventTransactionCreation extends EventBasicUserId { export class EventTransactionReceive extends EventBasicTx {} export class EventTransactionReceiveRedeem extends EventBasicTx {} export class EventContributionCreate extends EventBasicCt {} +export class EventUserCreateContributionMessage extends EventBasicCt { + message: string +} +export class EventAdminCreateContributionMessage extends EventBasicCt { + message: string +} export class EventContributionDelete extends EventBasicCt {} export class EventContributionUpdate extends EventBasicCt {} export class EventContributionConfirm extends EventBasicCt { xUserId: number xCommunityId: number } +export class EventContributionDeny extends EventBasicCt { + xUserId: number + xCommunityId: number +} export class EventContributionLinkDefine extends EventBasicCt {} export class EventContributionLinkActivateRedeem extends EventBasicCt {} @@ -101,6 +120,13 @@ export class Event { return this } + public setEventVerifyRedeem(ev: EventVerifyRedeem): Event { + this.setByBasicRedeem(ev.userId, ev.transactionId, ev.contributionId) + this.type = EventProtocolType.VERIFY_REDEEM + + return this + } + public setEventInactiveAccount(ev: EventInactiveAccount): Event { this.setByBasicUser(ev.userId) this.type = EventProtocolType.INACTIVE_ACCOUNT @@ -115,6 +141,62 @@ export class Event { return this } + public setEventSendAccountMultiregistrationEmail( + ev: EventSendAccountMultiregistrationEmail, + ): Event { + this.setByBasicUser(ev.userId) + this.type = EventProtocolType.SEND_ACCOUNT_MULTIREGISTRATION_EMAIL + + return this + } + + public setEventSendForgotPasswordEmail(ev: EventSendForgotPasswordEmail): Event { + this.setByBasicUser(ev.userId) + this.type = EventProtocolType.SEND_FORGOT_PASSWORD_EMAIL + + return this + } + + public setEventSendTransactionSendEmail(ev: EventSendTransactionSendEmail): Event { + this.setByBasicUser(ev.userId) + this.transactionId = ev.transactionId + this.type = EventProtocolType.SEND_TRANSACTION_SEND_EMAIL + + return this + } + + public setEventSendTransactionReceiveEmail(ev: EventSendTransactionReceiveEmail): Event { + this.setByBasicUser(ev.userId) + this.transactionId = ev.transactionId + this.type = EventProtocolType.SEND_TRANSACTION_RECEIVE_EMAIL + + return this + } + + public setEventSendTransactionLinkRedeemEmail(ev: EventSendTransactionLinkRedeemEmail): Event { + this.setByBasicUser(ev.userId) + this.transactionId = ev.transactionId + this.type = EventProtocolType.SEND_TRANSACTION_LINK_REDEEM_EMAIL + + return this + } + + public setEventSendAddedContributionEmail(ev: EventSendAddedContributionEmail): Event { + this.setByBasicUser(ev.userId) + this.contributionId = ev.contributionId + this.type = EventProtocolType.SEND_ADDED_CONTRIBUTION_EMAIL + + return this + } + + public setEventSendContributionConfirmEmail(ev: EventSendContributionConfirmEmail): Event { + this.setByBasicUser(ev.userId) + this.contributionId = ev.contributionId + this.type = EventProtocolType.SEND_CONTRIBUTION_CONFIRM_EMAIL + + return this + } + public setEventConfirmationEmail(ev: EventConfirmationEmail): Event { this.setByBasicUser(ev.userId) this.type = EventProtocolType.CONFIRM_EMAIL @@ -136,6 +218,13 @@ export class Event { return this } + public setEventLogout(ev: EventLogout): Event { + this.setByBasicUser(ev.userId) + this.type = EventProtocolType.LOGOUT + + return this + } + public setEventRedeemLogin(ev: EventRedeemLogin): Event { this.setByBasicRedeem(ev.userId, ev.transactionId, ev.contributionId) this.type = EventProtocolType.REDEEM_LOGIN @@ -208,6 +297,22 @@ export class Event { return this } + public setEventUserCreateContributionMessage(ev: EventUserCreateContributionMessage): Event { + this.setByBasicCt(ev.userId, ev.contributionId, ev.amount) + if (ev.message) this.message = ev.message + this.type = EventProtocolType.USER_CREATE_CONTRIBUTION_MESSAGE + + return this + } + + public setEventAdminCreateContributionMessage(ev: EventAdminCreateContributionMessage): Event { + this.setByBasicCt(ev.userId, ev.contributionId, ev.amount) + if (ev.message) this.message = ev.message + this.type = EventProtocolType.ADMIN_CREATE_CONTRIBUTION_MESSAGE + + return this + } + public setEventContributionDelete(ev: EventContributionDelete): Event { this.setByBasicCt(ev.userId, ev.contributionId, ev.amount) this.type = EventProtocolType.CONTRIBUTION_DELETE @@ -231,6 +336,15 @@ export class Event { return this } + public setEventContributionDeny(ev: EventContributionDeny): Event { + this.setByBasicCt(ev.userId, ev.contributionId, ev.amount) + if (ev.xUserId) this.xUserId = ev.xUserId + if (ev.xCommunityId) this.xCommunityId = ev.xCommunityId + this.type = EventProtocolType.CONTRIBUTION_DENY + + return this + } + public setEventContributionLinkDefine(ev: EventContributionLinkDefine): Event { this.setByBasicCt(ev.userId, ev.contributionId, ev.amount) this.type = EventProtocolType.CONTRIBUTION_LINK_DEFINE @@ -314,4 +428,5 @@ export class Event { transactionId?: number contributionId?: number amount?: decimal + message?: string } diff --git a/backend/src/event/EventProtocolType.ts b/backend/src/event/EventProtocolType.ts index 4265fb924..d53eb6961 100644 --- a/backend/src/event/EventProtocolType.ts +++ b/backend/src/event/EventProtocolType.ts @@ -3,36 +3,36 @@ export enum EventProtocolType { VISIT_GRADIDO = 'VISIT_GRADIDO', REGISTER = 'REGISTER', REDEEM_REGISTER = 'REDEEM_REGISTER', - VERIFY_REDEEM = 'VERIFY_REDEEM', // TODO + VERIFY_REDEEM = 'VERIFY_REDEEM', INACTIVE_ACCOUNT = 'INACTIVE_ACCOUNT', SEND_CONFIRMATION_EMAIL = 'SEND_CONFIRMATION_EMAIL', - SEND_ACCOUNT_MULTIREGISTRATION_EMAIL = 'SEND_ACCOUNT_MULTIREGISTRATION_EMAIL', // TODO + SEND_ACCOUNT_MULTIREGISTRATION_EMAIL = 'SEND_ACCOUNT_MULTIREGISTRATION_EMAIL', CONFIRM_EMAIL = 'CONFIRM_EMAIL', REGISTER_EMAIL_KLICKTIPP = 'REGISTER_EMAIL_KLICKTIPP', LOGIN = 'LOGIN', - LOGOUT = 'LOGOUT', // TODO + LOGOUT = 'LOGOUT', REDEEM_LOGIN = 'REDEEM_LOGIN', ACTIVATE_ACCOUNT = 'ACTIVATE_ACCOUNT', - SEND_FORGOT_PASSWORD_EMAIL = 'SEND_FORGOT_PASSWORD_EMAIL', // TODO + SEND_FORGOT_PASSWORD_EMAIL = 'SEND_FORGOT_PASSWORD_EMAIL', PASSWORD_CHANGE = 'PASSWORD_CHANGE', - SEND_TRANSACTION_SEND_EMAIL = 'SEND_TRANSACTION_SEND_EMAIL', // TODO - SEND_TRANSACTION_RECEIVE_EMAIL = 'SEND_TRANSACTION_RECEIVE_EMAIL', // TODO + SEND_TRANSACTION_SEND_EMAIL = 'SEND_TRANSACTION_SEND_EMAIL', + SEND_TRANSACTION_RECEIVE_EMAIL = 'SEND_TRANSACTION_RECEIVE_EMAIL', TRANSACTION_SEND = 'TRANSACTION_SEND', TRANSACTION_SEND_REDEEM = 'TRANSACTION_SEND_REDEEM', TRANSACTION_REPEATE_REDEEM = 'TRANSACTION_REPEATE_REDEEM', TRANSACTION_CREATION = 'TRANSACTION_CREATION', TRANSACTION_RECEIVE = 'TRANSACTION_RECEIVE', TRANSACTION_RECEIVE_REDEEM = 'TRANSACTION_RECEIVE_REDEEM', - SEND_TRANSACTION_LINK_REDEEM_EMAIL = 'SEND_TRANSACTION_LINK_REDEEM_EMAIL', // TODO - SEND_ADDED_CONTRIBUTION_EMAIL = 'SEND_ADDED_CONTRIBUTION_EMAIL', // TODO - SEND_CONTRIBUTION_CONFIRM_EMAIL = 'SEND_CONTRIBUTION_CONFIRM_EMAIL', // TODO + SEND_TRANSACTION_LINK_REDEEM_EMAIL = 'SEND_TRANSACTION_LINK_REDEEM_EMAIL', + SEND_ADDED_CONTRIBUTION_EMAIL = 'SEND_ADDED_CONTRIBUTION_EMAIL', + SEND_CONTRIBUTION_CONFIRM_EMAIL = 'SEND_CONTRIBUTION_CONFIRM_EMAIL', CONTRIBUTION_CREATE = 'CONTRIBUTION_CREATE', CONTRIBUTION_CONFIRM = 'CONTRIBUTION_CONFIRM', - CONTRIBUTION_DENY = 'CONTRIBUTION_DENY', // TODO + CONTRIBUTION_DENY = 'CONTRIBUTION_DENY', CONTRIBUTION_LINK_DEFINE = 'CONTRIBUTION_LINK_DEFINE', CONTRIBUTION_LINK_ACTIVATE_REDEEM = 'CONTRIBUTION_LINK_ACTIVATE_REDEEM', CONTRIBUTION_DELETE = 'CONTRIBUTION_DELETE', CONTRIBUTION_UPDATE = 'CONTRIBUTION_UPDATE', - USER_CREATE_CONTRIBUTION_MESSAGE = 'USER_CREATE_CONTRIBUTION_MESSAGE', // TODO - ADMIN_CREATE_CONTRIBUTION_MESSAGE = 'ADMIN_CREATE_CONTRIBUTION_MESSAGE', // TODO + USER_CREATE_CONTRIBUTION_MESSAGE = 'USER_CREATE_CONTRIBUTION_MESSAGE', + ADMIN_CREATE_CONTRIBUTION_MESSAGE = 'ADMIN_CREATE_CONTRIBUTION_MESSAGE', } From 329e6f0893e8a2786c60a2264717965cb578a791 Mon Sep 17 00:00:00 2001 From: joseji Date: Mon, 26 Sep 2022 22:29:48 +0200 Subject: [PATCH 12/69] removed unnecesary previously included parameter 'message' on events --- backend/src/event/Event.ts | 3 --- 1 file changed, 3 deletions(-) diff --git a/backend/src/event/Event.ts b/backend/src/event/Event.ts index f6e6a554c..bebc91915 100644 --- a/backend/src/event/Event.ts +++ b/backend/src/event/Event.ts @@ -299,7 +299,6 @@ export class Event { public setEventUserCreateContributionMessage(ev: EventUserCreateContributionMessage): Event { this.setByBasicCt(ev.userId, ev.contributionId, ev.amount) - if (ev.message) this.message = ev.message this.type = EventProtocolType.USER_CREATE_CONTRIBUTION_MESSAGE return this @@ -307,7 +306,6 @@ export class Event { public setEventAdminCreateContributionMessage(ev: EventAdminCreateContributionMessage): Event { this.setByBasicCt(ev.userId, ev.contributionId, ev.amount) - if (ev.message) this.message = ev.message this.type = EventProtocolType.ADMIN_CREATE_CONTRIBUTION_MESSAGE return this @@ -428,5 +426,4 @@ export class Event { transactionId?: number contributionId?: number amount?: decimal - message?: string } From c8a2d899b88bc563e1363cead9caef1064481605 Mon Sep 17 00:00:00 2001 From: joseji Date: Mon, 26 Sep 2022 22:41:33 +0200 Subject: [PATCH 13/69] all stated according to the events table --- backend/src/event/Event.ts | 29 ++++++++++++++++++----------- 1 file changed, 18 insertions(+), 11 deletions(-) diff --git a/backend/src/event/Event.ts b/backend/src/event/Event.ts index bebc91915..27e188a64 100644 --- a/backend/src/event/Event.ts +++ b/backend/src/event/Event.ts @@ -35,9 +35,9 @@ export class EventInactiveAccount extends EventBasicUserId {} export class EventSendConfirmationEmail extends EventBasicUserId {} export class EventSendAccountMultiregistrationEmail extends EventBasicUserId {} export class EventSendForgotPasswordEmail extends EventBasicUserId {} -export class EventSendTransactionSendEmail extends EventBasicRedeem {} -export class EventSendTransactionReceiveEmail extends EventBasicRedeem {} -export class EventSendTransactionLinkRedeemEmail extends EventBasicRedeem {} +export class EventSendTransactionSendEmail extends EventBasicTx {} +export class EventSendTransactionReceiveEmail extends EventBasicTx {} +export class EventSendTransactionLinkRedeemEmail extends EventBasicTx {} export class EventSendAddedContributionEmail extends EventBasicCt {} export class EventSendContributionConfirmEmail extends EventBasicCt {} export class EventConfirmationEmail extends EventBasicUserId {} @@ -57,9 +57,7 @@ export class EventTransactionCreation extends EventBasicUserId { export class EventTransactionReceive extends EventBasicTx {} export class EventTransactionReceiveRedeem extends EventBasicTx {} export class EventContributionCreate extends EventBasicCt {} -export class EventUserCreateContributionMessage extends EventBasicCt { - message: string -} +export class EventUserCreateContributionMessage extends EventBasicCt {} export class EventAdminCreateContributionMessage extends EventBasicCt { message: string } @@ -159,7 +157,10 @@ export class Event { public setEventSendTransactionSendEmail(ev: EventSendTransactionSendEmail): Event { this.setByBasicUser(ev.userId) - this.transactionId = ev.transactionId + if (ev.transactionId) this.transactionId = ev.transactionId + if (ev.xCommunityId) this.xCommunityId = ev.xCommunityId + if (ev.xUserId) this.xUserId = ev.xUserId + if (ev.amount) this.amount = ev.amount this.type = EventProtocolType.SEND_TRANSACTION_SEND_EMAIL return this @@ -167,7 +168,10 @@ export class Event { public setEventSendTransactionReceiveEmail(ev: EventSendTransactionReceiveEmail): Event { this.setByBasicUser(ev.userId) - this.transactionId = ev.transactionId + if (ev.transactionId) this.transactionId = ev.transactionId + if (ev.xCommunityId) this.xCommunityId = ev.xCommunityId + if (ev.xUserId) this.xUserId = ev.xUserId + if (ev.amount) this.amount = ev.amount this.type = EventProtocolType.SEND_TRANSACTION_RECEIVE_EMAIL return this @@ -175,7 +179,10 @@ export class Event { public setEventSendTransactionLinkRedeemEmail(ev: EventSendTransactionLinkRedeemEmail): Event { this.setByBasicUser(ev.userId) - this.transactionId = ev.transactionId + if (ev.transactionId) this.transactionId = ev.transactionId + if (ev.xCommunityId) this.xCommunityId = ev.xCommunityId + if (ev.xUserId) this.xUserId = ev.xUserId + if (ev.amount) this.amount = ev.amount this.type = EventProtocolType.SEND_TRANSACTION_LINK_REDEEM_EMAIL return this @@ -183,7 +190,7 @@ export class Event { public setEventSendAddedContributionEmail(ev: EventSendAddedContributionEmail): Event { this.setByBasicUser(ev.userId) - this.contributionId = ev.contributionId + if (ev.contributionId) this.contributionId = ev.contributionId this.type = EventProtocolType.SEND_ADDED_CONTRIBUTION_EMAIL return this @@ -191,7 +198,7 @@ export class Event { public setEventSendContributionConfirmEmail(ev: EventSendContributionConfirmEmail): Event { this.setByBasicUser(ev.userId) - this.contributionId = ev.contributionId + if (ev.contributionId) this.contributionId = ev.contributionId this.type = EventProtocolType.SEND_CONTRIBUTION_CONFIRM_EMAIL return this From e97aac759fd33ec0e678789686f78d681d69a5ad Mon Sep 17 00:00:00 2001 From: joseji Date: Mon, 26 Sep 2022 23:00:33 +0200 Subject: [PATCH 14/69] typo camel case in 'send multiregistration email event' --- backend/src/event/Event.ts | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/backend/src/event/Event.ts b/backend/src/event/Event.ts index 7c212978a..a0b5c05ec 100644 --- a/backend/src/event/Event.ts +++ b/backend/src/event/Event.ts @@ -33,7 +33,7 @@ export class EventRedeemRegister extends EventBasicRedeem {} export class EventVerifyRedeem extends EventBasicRedeem {} export class EventInactiveAccount extends EventBasicUserId {} export class EventSendConfirmationEmail extends EventBasicUserId {} -export class EventSendAccountMultiregistrationEmail extends EventBasicUserId {} +export class EventSendAccountMultiRegistrationEmail extends EventBasicUserId {} export class EventSendForgotPasswordEmail extends EventBasicUserId {} export class EventSendTransactionSendEmail extends EventBasicTx {} export class EventSendTransactionReceiveEmail extends EventBasicTx {} @@ -139,8 +139,8 @@ export class Event { return this } - public setEventSendAccountMultiregistrationEmail( - ev: EventSendAccountMultiregistrationEmail, + public setEventSendAccountMultiRegistrationEmail( + ev: EventSendAccountMultiRegistrationEmail, ): Event { this.setByBasicUser(ev.userId) this.type = EventProtocolType.SEND_ACCOUNT_MULTIREGISTRATION_EMAIL From ce280f6320c802ded0d9a422aabdb8a51d26a531 Mon Sep 17 00:00:00 2001 From: joseji Date: Thu, 29 Sep 2022 11:53:32 +0200 Subject: [PATCH 15/69] some conversations solved --- backend/src/event/Event.ts | 31 +++++++++++++++++++++---------- 1 file changed, 21 insertions(+), 10 deletions(-) diff --git a/backend/src/event/Event.ts b/backend/src/event/Event.ts index a0b5c05ec..8b8834b59 100644 --- a/backend/src/event/Event.ts +++ b/backend/src/event/Event.ts @@ -22,11 +22,22 @@ export class EventBasicCt extends EventBasicUserId { amount: decimal } +export class EventBasicCtX extends EventBasicUserId { + xUserId: number + xCommunityId: number + contributionId: number + amount: decimal +} + export class EventBasicRedeem extends EventBasicUserId { transactionId?: number contributionId?: number } +export class EventBasicCtMsg extends EventBasicCt { + message: string +} + export class EventVisitGradido extends EventBasic {} export class EventRegister extends EventBasicUserId {} export class EventRedeemRegister extends EventBasicRedeem {} @@ -57,8 +68,8 @@ export class EventTransactionCreation extends EventBasicUserId { export class EventTransactionReceive extends EventBasicTx {} export class EventTransactionReceiveRedeem extends EventBasicTx {} export class EventContributionCreate extends EventBasicCt {} -export class EventUserCreateContributionMessage extends EventBasicCt {} -export class EventAdminCreateContributionMessage extends EventBasicCt { +export class EventUserCreateContributionMessage extends EventBasicCtMsg {} +export class EventAdminCreateContributionMessage extends EventBasicCtMsg { message: string } export class EventContributionDelete extends EventBasicCt {} @@ -67,10 +78,7 @@ export class EventContributionConfirm extends EventBasicCt { xUserId: number xCommunityId: number } -export class EventContributionDeny extends EventBasicCt { - xUserId: number - xCommunityId: number -} +export class EventContributionDeny extends EventBasicCtX {} export class EventContributionLinkDefine extends EventBasicCt {} export class EventContributionLinkActivateRedeem extends EventBasicCt {} @@ -306,14 +314,14 @@ export class Event { public setEventUserCreateContributionMessage(ev: EventUserCreateContributionMessage): Event { this.setByBasicCt(ev.userId, ev.contributionId, ev.amount) this.type = EventProtocolType.USER_CREATE_CONTRIBUTION_MESSAGE - + this.message = ev.message return this } public setEventAdminCreateContributionMessage(ev: EventAdminCreateContributionMessage): Event { this.setByBasicCt(ev.userId, ev.contributionId, ev.amount) this.type = EventProtocolType.ADMIN_CREATE_CONTRIBUTION_MESSAGE - + this.message = ev.message return this } @@ -341,9 +349,11 @@ export class Event { } public setEventContributionDeny(ev: EventContributionDeny): Event { - this.setByBasicCt(ev.userId, ev.contributionId, ev.amount) - if (ev.xUserId) this.xUserId = ev.xUserId + this.setByBasicTx(ev.userId) + if (ev.contributionId) this.contributionId = ev.contributionId if (ev.xCommunityId) this.xCommunityId = ev.xCommunityId + if (ev.xUserId) this.xUserId = ev.xUserId + if (ev.amount) this.amount = ev.amount this.type = EventProtocolType.CONTRIBUTION_DENY return this @@ -432,4 +442,5 @@ export class Event { transactionId?: number contributionId?: number amount?: decimal + message?: string } From 7061718c1f92aee84ef2c14aeb21055ad59162f9 Mon Sep 17 00:00:00 2001 From: joseji Date: Thu, 29 Sep 2022 12:20:08 +0200 Subject: [PATCH 16/69] all conversations solved --- backend/src/event/Event.ts | 78 ++++++++++--------- .../resolver/ContributionResolver.test.ts | 8 +- .../src/graphql/resolver/util/creations.ts | 2 +- 3 files changed, 46 insertions(+), 42 deletions(-) diff --git a/backend/src/event/Event.ts b/backend/src/event/Event.ts index 8b8834b59..ee24c768b 100644 --- a/backend/src/event/Event.ts +++ b/backend/src/event/Event.ts @@ -22,7 +22,7 @@ export class EventBasicCt extends EventBasicUserId { amount: decimal } -export class EventBasicCtX extends EventBasicUserId { +export class EventBasicCtX extends EventBasicCt { xUserId: number xCommunityId: number contributionId: number @@ -74,10 +74,7 @@ export class EventAdminCreateContributionMessage extends EventBasicCtMsg { } export class EventContributionDelete extends EventBasicCt {} export class EventContributionUpdate extends EventBasicCt {} -export class EventContributionConfirm extends EventBasicCt { - xUserId: number - xCommunityId: number -} +export class EventContributionConfirm extends EventBasicCtX {} export class EventContributionDeny extends EventBasicCtX {} export class EventContributionLinkDefine extends EventBasicCt {} export class EventContributionLinkActivateRedeem extends EventBasicCt {} @@ -164,50 +161,37 @@ export class Event { } public setEventSendTransactionSendEmail(ev: EventSendTransactionSendEmail): Event { - this.setByBasicUser(ev.userId) - if (ev.transactionId) this.transactionId = ev.transactionId - if (ev.xCommunityId) this.xCommunityId = ev.xCommunityId - if (ev.xUserId) this.xUserId = ev.xUserId - if (ev.amount) this.amount = ev.amount + this.setByBasicTx(ev.userId, ev.xUserId, ev.xCommunityId, ev.transactionId, ev.amount) this.type = EventProtocolType.SEND_TRANSACTION_SEND_EMAIL return this } public setEventSendTransactionReceiveEmail(ev: EventSendTransactionReceiveEmail): Event { - this.setByBasicUser(ev.userId) - if (ev.transactionId) this.transactionId = ev.transactionId - if (ev.xCommunityId) this.xCommunityId = ev.xCommunityId - if (ev.xUserId) this.xUserId = ev.xUserId - if (ev.amount) this.amount = ev.amount + this.setByBasicTx(ev.userId, ev.xUserId, ev.xCommunityId, ev.transactionId, ev.amount) this.type = EventProtocolType.SEND_TRANSACTION_RECEIVE_EMAIL return this } public setEventSendTransactionLinkRedeemEmail(ev: EventSendTransactionLinkRedeemEmail): Event { - this.setByBasicUser(ev.userId) - if (ev.transactionId) this.transactionId = ev.transactionId - if (ev.xCommunityId) this.xCommunityId = ev.xCommunityId - if (ev.xUserId) this.xUserId = ev.xUserId - if (ev.amount) this.amount = ev.amount + this.setByBasicTx(ev.userId, ev.xUserId, ev.xCommunityId, ev.transactionId, ev.amount) this.type = EventProtocolType.SEND_TRANSACTION_LINK_REDEEM_EMAIL return this } public setEventSendAddedContributionEmail(ev: EventSendAddedContributionEmail): Event { - this.setByBasicUser(ev.userId) - if (ev.contributionId) this.contributionId = ev.contributionId + this.setByBasicCt(ev.userId, ev.contributionId, ev.amount) this.type = EventProtocolType.SEND_ADDED_CONTRIBUTION_EMAIL return this } public setEventSendContributionConfirmEmail(ev: EventSendContributionConfirmEmail): Event { - this.setByBasicUser(ev.userId) - if (ev.contributionId) this.contributionId = ev.contributionId + this.setByBasicCt(ev.userId, ev.contributionId, ev.amount) this.type = EventProtocolType.SEND_CONTRIBUTION_CONFIRM_EMAIL + return this } @@ -312,16 +296,16 @@ export class Event { } public setEventUserCreateContributionMessage(ev: EventUserCreateContributionMessage): Event { - this.setByBasicCt(ev.userId, ev.contributionId, ev.amount) + this.setByBasicCtMsg(ev.userId, ev.contributionId, ev.amount, ev.message) this.type = EventProtocolType.USER_CREATE_CONTRIBUTION_MESSAGE - this.message = ev.message + return this } public setEventAdminCreateContributionMessage(ev: EventAdminCreateContributionMessage): Event { - this.setByBasicCt(ev.userId, ev.contributionId, ev.amount) + this.setByBasicCtMsg(ev.userId, ev.contributionId, ev.amount, ev.message) this.type = EventProtocolType.ADMIN_CREATE_CONTRIBUTION_MESSAGE - this.message = ev.message + return this } @@ -340,20 +324,14 @@ export class Event { } public setEventContributionConfirm(ev: EventContributionConfirm): Event { - this.setByBasicCt(ev.userId, ev.contributionId, ev.amount) - if (ev.xUserId) this.xUserId = ev.xUserId - if (ev.xCommunityId) this.xCommunityId = ev.xCommunityId + this.setByBasicCtX(ev.userId, ev.xUserId, ev.xCommunityId, ev.contributionId, ev.amount) this.type = EventProtocolType.CONTRIBUTION_CONFIRM return this } public setEventContributionDeny(ev: EventContributionDeny): Event { - this.setByBasicTx(ev.userId) - if (ev.contributionId) this.contributionId = ev.contributionId - if (ev.xCommunityId) this.xCommunityId = ev.xCommunityId - if (ev.xUserId) this.xUserId = ev.xUserId - if (ev.amount) this.amount = ev.amount + this.setByBasicCtX(ev.userId, ev.xUserId, ev.xCommunityId, ev.contributionId, ev.amount) this.type = EventProtocolType.CONTRIBUTION_DENY return this @@ -404,6 +382,34 @@ export class Event { return this } + setByBasicCtMsg( + userId: number, + contributionId: number, + amount?: decimal, + message?: string, + ): Event { + this.setByBasicCt(userId, contributionId, amount) + if (message) this.message = message + + return this + } + + setByBasicCtX( + userId: number, + xUserId?: number, + xCommunityId?: number, + contributionId?: number, + amount?: decimal, + ): Event { + this.setByBasicUser(userId) + if (xUserId) this.xUserId = xUserId + if (xCommunityId) this.xCommunityId = xCommunityId + if (contributionId) this.contributionId = contributionId + if (amount) this.amount = amount + + return this + } + setByBasicRedeem(userId: number, transactionId?: number, contributionId?: number): Event { this.setByBasicUser(userId) if (transactionId) this.transactionId = transactionId diff --git a/backend/src/graphql/resolver/ContributionResolver.test.ts b/backend/src/graphql/resolver/ContributionResolver.test.ts index b8bbebbd9..199fb6c76 100644 --- a/backend/src/graphql/resolver/ContributionResolver.test.ts +++ b/backend/src/graphql/resolver/ContributionResolver.test.ts @@ -137,7 +137,7 @@ describe('ContributionResolver', () => { it('logs the error found', () => { expect(logger.error).toBeCalledWith( 'No information for available creations with the given creationDate=', - new Date('non-valid').toDateString, + 'Invalid Date', ) }) @@ -162,10 +162,9 @@ describe('ContributionResolver', () => { }) it('logs the error found', () => { - const date = new Date() expect(logger.error).toBeCalledWith( 'No information for available creations with the given creationDate=', - new Date(date.setMonth(date.getMonth() - 3).toString()).toDateString, + 'Invalid Date', ) }) }) @@ -560,10 +559,9 @@ describe('ContributionResolver', () => { }) it('logs the error found', () => { - const date = new Date() expect(logger.error).toBeCalledWith( 'No information for available creations with the given creationDate=', - new Date(date.setMonth(date.getMonth() - 3).toString()).toDateString, + 'Invalid Date', ) }) }) diff --git a/backend/src/graphql/resolver/util/creations.ts b/backend/src/graphql/resolver/util/creations.ts index b390e197d..9987dfae6 100644 --- a/backend/src/graphql/resolver/util/creations.ts +++ b/backend/src/graphql/resolver/util/creations.ts @@ -21,7 +21,7 @@ export const validateContribution = ( if (index < 0) { logger.error( 'No information for available creations with the given creationDate=', - creationDate.toDateString, + creationDate.toString(), ) throw new Error('No information for available creations for the given date') } From f05c31f69b90df32e71d424c08a166246dbe277e Mon Sep 17 00:00:00 2001 From: joseji Date: Thu, 29 Sep 2022 12:32:43 +0200 Subject: [PATCH 17/69] removed duplicated code --- backend/src/event/Event.ts | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) diff --git a/backend/src/event/Event.ts b/backend/src/event/Event.ts index ee24c768b..a70df23a2 100644 --- a/backend/src/event/Event.ts +++ b/backend/src/event/Event.ts @@ -69,9 +69,7 @@ export class EventTransactionReceive extends EventBasicTx {} export class EventTransactionReceiveRedeem extends EventBasicTx {} export class EventContributionCreate extends EventBasicCt {} export class EventUserCreateContributionMessage extends EventBasicCtMsg {} -export class EventAdminCreateContributionMessage extends EventBasicCtMsg { - message: string -} +export class EventAdminCreateContributionMessage extends EventBasicCtMsg {} export class EventContributionDelete extends EventBasicCt {} export class EventContributionUpdate extends EventBasicCt {} export class EventContributionConfirm extends EventBasicCtX {} From ce3d9b1708d9ba27f6fabc93fe3787990fa3c32a Mon Sep 17 00:00:00 2001 From: ogerly Date: Tue, 4 Oct 2022 12:43:51 +0200 Subject: [PATCH 18/69] find link and replace to element --- .../slots/ContributionMessagesListItem.vue | 20 +++++++++++++++++++ .../slots/IsModerator.vue | 2 +- .../slots/IsNotModerator.vue | 2 +- .../ContributionMessagesListItem.vue | 17 +++++++++++++++- .../slots/IsModerator.vue | 2 +- .../slots/IsNotModerator.vue | 2 +- 6 files changed, 40 insertions(+), 5 deletions(-) diff --git a/admin/src/components/ContributionMessages/slots/ContributionMessagesListItem.vue b/admin/src/components/ContributionMessages/slots/ContributionMessagesListItem.vue index fa5bdd940..c0bb7558c 100644 --- a/admin/src/components/ContributionMessages/slots/ContributionMessagesListItem.vue +++ b/admin/src/components/ContributionMessages/slots/ContributionMessagesListItem.vue @@ -23,5 +23,25 @@ export default { }, }, }, + data() { + return { + pattern: + // eslint-disable-next-line no-useless-escape + /(https?:\/\/(www\.)?[-a-zA-Z0-9@:%._\+~#=]{1,256}\.[a-zA-Z0-9()]{1,6}\b([-a-zA-Z0-9()@:%_\+.~#?&//=]*))/gi, + messageObject: this.message, + } + }, + methods: { + linkify(inputText) { + // console.log(inputText.match(this.pattern)) + this.messageObject.message = inputText.replace( + this.pattern, + "$1", + ) + }, + }, + created() { + this.linkify(this.messageObject.message) + }, } diff --git a/admin/src/components/ContributionMessages/slots/IsModerator.vue b/admin/src/components/ContributionMessages/slots/IsModerator.vue index 0224e042f..6363e4aa2 100644 --- a/admin/src/components/ContributionMessages/slots/IsModerator.vue +++ b/admin/src/components/ContributionMessages/slots/IsModerator.vue @@ -5,7 +5,7 @@ {{ message.userFirstName }} {{ message.userLastName }} {{ $d(new Date(message.createdAt), 'short') }} {{ $t('moderator') }} -
{{ message.message }}
+
diff --git a/admin/src/components/ContributionMessages/slots/IsNotModerator.vue b/admin/src/components/ContributionMessages/slots/IsNotModerator.vue index 64946c557..f45d4f890 100644 --- a/admin/src/components/ContributionMessages/slots/IsNotModerator.vue +++ b/admin/src/components/ContributionMessages/slots/IsNotModerator.vue @@ -4,7 +4,7 @@ {{ message.userFirstName }} {{ message.userLastName }} {{ $d(new Date(message.createdAt), 'short') }} -
{{ message.message }}
+
diff --git a/frontend/src/components/ContributionMessages/ContributionMessagesListItem.vue b/frontend/src/components/ContributionMessages/ContributionMessagesListItem.vue index 5fde8f825..9e0b49313 100644 --- a/frontend/src/components/ContributionMessages/ContributionMessagesListItem.vue +++ b/frontend/src/components/ContributionMessages/ContributionMessagesListItem.vue @@ -1,6 +1,6 @@ @@ -25,6 +25,9 @@ export default { }, data() { return { + // eslint-disable-next-line no-useless-escape + pattern: /(https?:\/\/(www\.)?[-a-zA-Z0-9@:%._\+~#=]{1,256}\.[a-zA-Z0-9()]{1,6}\b([-a-zA-Z0-9()@:%_\+.~#?&//=]*))/gi, + messageObject: this.message, storeName: `${this.$store.state.firstName} ${this.$store.state.lastName}`, moderationName: `${this.message.userFirstName} ${this.message.userLastName}`, } @@ -34,5 +37,17 @@ export default { return this.storeName === this.moderationName }, }, + methods: { + linkify(inputText) { + // console.log(inputText.match(this.pattern)) + this.messageObject.message = inputText.replace( + this.pattern, + "$1", + ) + }, + }, + created() { + this.linkify(this.messageObject.message) + }, } diff --git a/frontend/src/components/ContributionMessages/slots/IsModerator.vue b/frontend/src/components/ContributionMessages/slots/IsModerator.vue index 343b92d97..d0810d9fb 100644 --- a/frontend/src/components/ContributionMessages/slots/IsModerator.vue +++ b/frontend/src/components/ContributionMessages/slots/IsModerator.vue @@ -4,7 +4,7 @@ {{ message.userFirstName }} {{ message.userLastName }} {{ $d(new Date(message.createdAt), 'short') }} {{ $t('community.moderator') }} -
{{ message.message }}
+
- diff --git a/admin/src/components/ContributionMessages/slots/IsNotModerator.vue b/admin/src/components/ContributionMessages/slots/IsNotModerator.vue deleted file mode 100644 index f45d4f890..000000000 --- a/admin/src/components/ContributionMessages/slots/IsNotModerator.vue +++ /dev/null @@ -1,34 +0,0 @@ - - - diff --git a/frontend/src/components/ContributionMessages/slots/IsModerator.vue b/frontend/src/components/ContributionMessages/slots/IsModerator.vue deleted file mode 100644 index d0810d9fb..000000000 --- a/frontend/src/components/ContributionMessages/slots/IsModerator.vue +++ /dev/null @@ -1,34 +0,0 @@ - - - diff --git a/frontend/src/components/ContributionMessages/slots/IsNotModerator.vue b/frontend/src/components/ContributionMessages/slots/IsNotModerator.vue deleted file mode 100644 index c726cb8ef..000000000 --- a/frontend/src/components/ContributionMessages/slots/IsNotModerator.vue +++ /dev/null @@ -1,36 +0,0 @@ - - - From cb39745b2324bbf2312435ee5fe207be0f6cec54 Mon Sep 17 00:00:00 2001 From: ogerly Date: Sat, 15 Oct 2022 07:54:58 +0200 Subject: [PATCH 39/69] change linkify to computed --- .../slots/ContributionMessagesListItem.vue | 32 ++++++------------- .../ContributionMessagesListItem.vue | 26 +++++---------- 2 files changed, 18 insertions(+), 40 deletions(-) diff --git a/admin/src/components/ContributionMessages/slots/ContributionMessagesListItem.vue b/admin/src/components/ContributionMessages/slots/ContributionMessagesListItem.vue index 70ca24cc4..5eae5d7cd 100644 --- a/admin/src/components/ContributionMessages/slots/ContributionMessagesListItem.vue +++ b/admin/src/components/ContributionMessages/slots/ContributionMessagesListItem.vue @@ -1,21 +1,24 @@