From 0dd17da89b75b52a1c648475def452ba38ad4082 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Claus-Peter=20H=C3=BCbner?= Date: Tue, 21 Jun 2022 04:30:31 +0200 Subject: [PATCH 01/66] create event protocol tables, entities and enums --- backend/src/graphql/enum/EventProtocolType.ts | 31 ++++++ .../EnumEventType.ts | 13 +++ .../EventProtocol.ts | 39 +++++++ database/entity/EnumEventType.ts | 1 + database/entity/EventProtocol.ts | 1 + database/entity/index.ts | 4 + .../0041-add_event_protocol_table.ts | 102 ++++++++++++++++++ database/src/config/index.ts | 2 +- 8 files changed, 192 insertions(+), 1 deletion(-) create mode 100644 backend/src/graphql/enum/EventProtocolType.ts create mode 100644 database/entity/0041-add_event_protocol_table/EnumEventType.ts create mode 100644 database/entity/0041-add_event_protocol_table/EventProtocol.ts create mode 100644 database/entity/EnumEventType.ts create mode 100644 database/entity/EventProtocol.ts create mode 100644 database/migrations/0041-add_event_protocol_table.ts diff --git a/backend/src/graphql/enum/EventProtocolType.ts b/backend/src/graphql/enum/EventProtocolType.ts new file mode 100644 index 000000000..a95ccb819 --- /dev/null +++ b/backend/src/graphql/enum/EventProtocolType.ts @@ -0,0 +1,31 @@ +import { registerEnumType } from 'type-graphql' + +export enum EventProtocolType { + BASIC = '0', + VISIT_GRADIDO = '10', + REGISTER = '20', + REDEEM_REGISTER = '21', + INACTIVE_ACCOUNT = '22', + SEND_CONFIRMATION_EMAIL = '23', + CONFIRM_EMAIL = '24', + REGISTER_EMAIL_KLICKTIPP = '25', + LOGIN = '30', + REDEEM_LOGIN = '31', + ACTIVATE_ACCOUNT = '32', + PASSWORD_CHANGE = '33', + TRANSACTION_SEND = '40', + TRANSACTION_SEND_REDEEM = '41', + TRANSACTION_REPEATE_REDEEM = '42', + TRANSACTION_CREATION = '50', + TRANSACTION_RECEIVE = '51', + TRANSACTION_RECEIVE_REDEEM = '52', + CONTRIBUTION_CREATE = '60', + CONTRIBUTION_CONFIRM = '61', + CONTRIBUTION_LINK_DEFINE = '70', + CONTRIBUTION_LINK_ACTIVATE_REDEEM = '71', +} + +registerEnumType(EventProtocolType, { + name: 'EventProtocolType', // this one is mandatory + description: 'Name of the Type of the EventProtocol', // this one is optional +}) diff --git a/database/entity/0041-add_event_protocol_table/EnumEventType.ts b/database/entity/0041-add_event_protocol_table/EnumEventType.ts new file mode 100644 index 000000000..814ac851b --- /dev/null +++ b/database/entity/0041-add_event_protocol_table/EnumEventType.ts @@ -0,0 +1,13 @@ +import { BaseEntity, Entity, Column, PrimaryColumn } from 'typeorm' + +@Entity('enum_event_type') +export class EnumEventType extends BaseEntity { + @PrimaryColumn({ name: 'key', length: 100, nullable: false, collation: 'utf8mb4_unicode_ci' }) + key: string + + @Column({ name: 'value', unsigned: true, nullable: false }) + value: number + + @Column({ length: 200, nullable: false, collation: 'utf8mb4_unicode_ci' }) + description: string +} diff --git a/database/entity/0041-add_event_protocol_table/EventProtocol.ts b/database/entity/0041-add_event_protocol_table/EventProtocol.ts new file mode 100644 index 000000000..cf7747b77 --- /dev/null +++ b/database/entity/0041-add_event_protocol_table/EventProtocol.ts @@ -0,0 +1,39 @@ +import Decimal from 'decimal.js-light' +import { BaseEntity, Entity, PrimaryGeneratedColumn, Column, DeleteDateColumn } from 'typeorm' +import { DecimalTransformer } from '../../src/typeorm/DecimalTransformer' + +@Entity('event_protocol') +export class EventProtocol extends BaseEntity { + @PrimaryGeneratedColumn('increment', { unsigned: true }) + id: number + + @Column({ length: 100, nullable: false, collation: 'utf8mb4_unicode_ci' }) + type: string + + @Column({ name: 'created_at', type: 'datetime', default: () => 'CURRENT_TIMESTAMP' }) + createdAt: Date + + @Column({ name: 'user_id', unsigned: true, nullable: false }) + userId: number + + @Column({ name: 'x_user_id', unsigned: true, nullable: true }) + xUserId: number + + @Column({ name: 'x_community_id', unsigned: true, nullable: true }) + xCommunityId: number + + @Column({ name: 'transaction_id', unsigned: true, nullable: true }) + transactionId: number + + @Column({ name: 'contribution_id', unsigned: true, nullable: true }) + contributionId: number + + @Column({ + type: 'decimal', + precision: 40, + scale: 20, + nullable: true, + transformer: DecimalTransformer, + }) + amount: Decimal +} diff --git a/database/entity/EnumEventType.ts b/database/entity/EnumEventType.ts new file mode 100644 index 000000000..5b581d25f --- /dev/null +++ b/database/entity/EnumEventType.ts @@ -0,0 +1 @@ +export { EnumEventType } from './0041-add_event_protocol_table/EnumEventType' diff --git a/database/entity/EventProtocol.ts b/database/entity/EventProtocol.ts new file mode 100644 index 000000000..d7cfd869e --- /dev/null +++ b/database/entity/EventProtocol.ts @@ -0,0 +1 @@ +export { EventProtocol } from './0041-add_event_protocol_table/EventProtocol' diff --git a/database/entity/index.ts b/database/entity/index.ts index 266c40740..0974fe900 100644 --- a/database/entity/index.ts +++ b/database/entity/index.ts @@ -6,6 +6,8 @@ import { Transaction } from './Transaction' import { TransactionLink } from './TransactionLink' import { User } from './User' import { Contribution } from './Contribution' +import { EventProtocol } from './EventProtocol' +import { EnumEventType } from './EnumEventType' export const entities = [ Contribution, @@ -16,4 +18,6 @@ export const entities = [ Transaction, TransactionLink, User, + EventProtocol, + EnumEventType, ] diff --git a/database/migrations/0041-add_event_protocol_table.ts b/database/migrations/0041-add_event_protocol_table.ts new file mode 100644 index 000000000..191ef7f41 --- /dev/null +++ b/database/migrations/0041-add_event_protocol_table.ts @@ -0,0 +1,102 @@ +/* MIGRATION TO ADD EVENT_PROTOCOL + * + * This migration adds the table `event_protocol` in order to store all sorts of business event data + */ + +/* 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(` + CREATE TABLE IF NOT EXISTS \`event_protocol\` ( + \`id\` int(10) unsigned NOT NULL AUTO_INCREMENT, + \`type\` varchar(100) COLLATE utf8mb4_unicode_ci NOT NULL, + \`created_at\` datetime NOT NULL DEFAULT CURRENT_TIMESTAMP, + \`user_id\` int(10) unsigned NOT NULL, + \`x_user_id\` int(10) unsigned NULL DEFAULT NULL, + \`x_community_id\` int(10) unsigned NULL DEFAULT NULL, + \`transaction_id\` int(10) unsigned NULL DEFAULT NULL, + \`contribution_id\` int(10) unsigned NULL DEFAULT NULL, + \`amount\` bigint(20) NULL DEFAULT NULL, + PRIMARY KEY (\`id\`) + ) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4;`) + await queryFn(` + CREATE TABLE IF NOT EXISTS \`enum_event_type\` ( + \`key\` varchar(100) COLLATE utf8mb4_unicode_ci NOT NULL, + \`value\` int(10) unsigned NOT NULL, + \`description\` varchar(200) COLLATE utf8mb4_unicode_ci NOT NULL, + PRIMARY KEY (\`key\`) + ) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4;`) + await queryFn( + `INSERT INTO \`enum_event_type\` (\`key\`, \`value\`, \`description\`) VALUES ('BASIC', 0, 'BasicEvent: the basic event is the root of all further extending event types');`, + ) + await queryFn( + `INSERT INTO \`enum_event_type\` (\`key\`, \`value\`, \`description\`) VALUES ('VISIT_GRADIDO', 10, 'VisitGradidoEvent: if a user visits a gradido page without login or register');`, + ) + await queryFn( + `INSERT INTO \`enum_event_type\` (\`key\`, \`value\`, \`description\`) VALUES ('REGISTER', 20, 'RegisterEvent: the user presses the register button');`, + ) + await queryFn( + `INSERT INTO \`enum_event_type\` (\`key\`, \`value\`, \`description\`) VALUES ('REDEEM_REGISTER', 21, 'RedeemRegisterEvent: the user presses the register button initiated by the redeem link');`, + ) + await queryFn( + `INSERT INTO \`enum_event_type\` (\`key\`, \`value\`, \`description\`) VALUES ('INACTIVE_ACCOUNT', 22, 'InActiveAccountEvent: the systems create an inactive account during the register process');`, + ) + await queryFn( + `INSERT INTO \`enum_event_type\` (\`key\`, \`value\`, \`description\`) VALUES ('SEND_CONFIRMATION_EMAIL', 23, 'SendConfirmEmailEvent: the system send a confirmation email to the user during the register process');`, + ) + await queryFn( + `INSERT INTO \`enum_event_type\` (\`key\`, \`value\`, \`description\`) VALUES ('CONFIRM_EMAIL', 24, 'ConfirmEmailEvent: the user confirms his email during the register process');`, + ) + await queryFn( + `INSERT INTO \`enum_event_type\` (\`key\`, \`value\`, \`description\`) VALUES ('REGISTER_EMAIL_KLICKTIPP', 25, 'RegisterEmailKlickTippEvent: the system registers the confirmed email at klicktipp');`, + ) + await queryFn( + `INSERT INTO \`enum_event_type\` (\`key\`, \`value\`, \`description\`) VALUES ('LOGIN', 30, 'LoginEvent: the user presses the login button');`, + ) + await queryFn( + `INSERT INTO \`enum_event_type\` (\`key\`, \`value\`, \`description\`) VALUES ('REDEEM_LOGIN', 31, 'RedeemLoginEvent: the user presses the login button initiated by the redeem link');`, + ) + await queryFn( + `INSERT INTO \`enum_event_type\` (\`key\`, \`value\`, \`description\`) VALUES ('ACTIVATE_ACCOUNT', 32, 'ActivateAccountEvent: the system activates the users account during the first login process');`, + ) + await queryFn( + `INSERT INTO \`enum_event_type\` (\`key\`, \`value\`, \`description\`) VALUES ('PASSWORD_CHANGE', 33, 'PasswordChangeEvent: the user changes his password');`, + ) + await queryFn( + `INSERT INTO \`enum_event_type\` (\`key\`, \`value\`, \`description\`) VALUES ('TRANSACTION_SEND', 40, 'TransactionSendEvent: the user creates a transaction and sends it online');`, + ) + await queryFn( + `INSERT INTO \`enum_event_type\` (\`key\`, \`value\`, \`description\`) VALUES ('TRANSACTION_SEND_REDEEM', 41, 'TransactionSendRedeemEvent: the user creates a transaction and sends it per redeem link');`, + ) + await queryFn( + `INSERT INTO \`enum_event_type\` (\`key\`, \`value\`, \`description\`) VALUES ('TRANSACTION_REPEATE_REDEEM', 42, 'TransactionRepeateRedeemEvent: the user recreates a redeem link of a still open transaction');`, + ) + await queryFn( + `INSERT INTO \`enum_event_type\` (\`key\`, \`value\`, \`description\`) VALUES ('TRANSACTION_CREATION', 50, 'TransactionCreationEvent: the user receives a creation transaction for his confirmed contribution');`, + ) + await queryFn( + `INSERT INTO \`enum_event_type\` (\`key\`, \`value\`, \`description\`) VALUES ('TRANSACTION_RECEIVE', 51, 'TransactionReceiveEvent: the user receives a transaction from an other user and posts the amount on his account');`, + ) + await queryFn( + `INSERT INTO \`enum_event_type\` (\`key\`, \`value\`, \`description\`) VALUES ('TRANSACTION_RECEIVE_REDEEM', 52, 'TransactionReceiveRedeemEvent: the user activates the redeem link and receives the transaction and posts the amount on his account');`, + ) + await queryFn( + `INSERT INTO \`enum_event_type\` (\`key\`, \`value\`, \`description\`) VALUES ('CONTRIBUTION_CREATE', 60, 'ContributionCreateEvent: the user enters his contribution and asks for confirmation');`, + ) + await queryFn( + `INSERT INTO \`enum_event_type\` (\`key\`, \`value\`, \`description\`) VALUES ('CONTRIBUTION_CONFIRM', 61, 'ContributionConfirmEvent: the user confirms a contribution of an other user (for future multi confirmation from several users)');`, + ) + await queryFn( + `INSERT INTO \`enum_event_type\` (\`key\`, \`value\`, \`description\`) VALUES ('CONTRIBUTION_LINK_DEFINE', 70, 'ContributionLinkDefineEvent: the admin user defines a contributionLink, which could be send per Link/QR-Code on an other medium');`, + ) + await queryFn( + `INSERT INTO \`enum_event_type\` (\`key\`, \`value\`, \`description\`) VALUES ('CONTRIBUTION_LINK_ACTIVATE_REDEEM', 71, 'ContributionLinkActivateRedeemEvent: the user activates a received contributionLink to create a contribution entry for the contributionLink');`, + ) +} + +export async function downgrade(queryFn: (query: string, values?: any[]) => Promise>) { + // write downgrade logic as parameter of queryFn + await queryFn(`DROP TABLE IF EXISTS \`event_protocol\`;`) + await queryFn(`DROP TABLE IF EXISTS \`enum_event_type\`;`) +} diff --git a/database/src/config/index.ts b/database/src/config/index.ts index ba41f11d4..d8cd78eae 100644 --- a/database/src/config/index.ts +++ b/database/src/config/index.ts @@ -6,7 +6,7 @@ dotenv.config() const constants = { CONFIG_VERSION: { DEFAULT: 'DEFAULT', - EXPECTED: 'v1.2022-03-18', + EXPECTED: 'v7.2022-06-15', CURRENT: '', }, } From 279a5975f1ae4873c825638d00954fd2ab724683 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Claus-Peter=20H=C3=BCbner?= Date: Tue, 21 Jun 2022 04:31:12 +0200 Subject: [PATCH 02/66] add ContributionLink-Events --- .../BusinessEventProtocol.md | 94 ++++++++++--------- 1 file changed, 48 insertions(+), 46 deletions(-) diff --git a/docu/Concepts/TechnicalRequirements/BusinessEventProtocol.md b/docu/Concepts/TechnicalRequirements/BusinessEventProtocol.md index 5a436d057..f8cf2cd03 100644 --- a/docu/Concepts/TechnicalRequirements/BusinessEventProtocol.md +++ b/docu/Concepts/TechnicalRequirements/BusinessEventProtocol.md @@ -6,29 +6,30 @@ With the business event protocol the gradido application will capture and persis The different event types will be defined as Enum. The following list is a first draft and will grow with further event types in the future. -| EventType | Value | Description | -| --------------------------- | ----- | ---------------------------------------------------------------------------------------------------- | -| BasicEvent | 0 | the basic event is the root of all further extending event types | -| VisitGradidoEvent | 10 | if a user visits a gradido page without login or register | -| RegisterEvent | 20 | the user presses the register button | -| RedeemRegisterEvent | 21 | the user presses the register button initiated by the redeem link | -| InActiveAccountEvent | 22 | the systems create an inactive account during the register process | -| SendConfirmEmailEvent | 23 | the system send a confirmation email to the user during the register process | -| ConfirmEmailEvent | 24 | the user confirms his email during the register process | -| RegisterEmailKlickTippEvent | 25 | the system registers the confirmed email at klicktipp | -| LoginEvent | 30 | the user presses the login button | -| RedeemLoginEvent | 31 | the user presses the login button initiated by the redeem link | -| ActivateAccountEvent | 32 | the system activates the users account during the first login process | -| PasswordChangeEvent | 33 | the user changes his password | -| TxSendEvent | 40 | the user creates a transaction and sends it online | -| TxSendRedeemEvent | 41 | the user creates a transaction and sends it per redeem link | -| TxRepeateRedeemEvent | 42 | the user recreates a redeem link of a still open transaction | -| TxCreationEvent | 50 | the user receives a creation transaction for his confirmed contribution | -| TxReceiveEvent | 51 | the user receives a transaction from an other user and posts the amount on his account | -| TxReceiveRedeemEvent | 52 | the user activates the redeem link and receives the transaction and posts the amount on his account | -| ContribCreateEvent | 60 | the user enters his contribution and asks for confirmation | -| ContribConfirmEvent | 61 | the user confirms a contribution of an other user (for future multi confirmation from several users) | -| | | | +| EventType | Value | Description | +| ----------------------------------- | ----- | ------------------------------------------------------------------------------------------------------ | +| BasicEvent | 0 | the basic event is the root of all further extending event types | +| VisitGradidoEvent | 10 | if a user visits a gradido page without login or register | +| RegisterEvent | 20 | the user presses the register button | +| RedeemRegisterEvent | 21 | the user presses the register button initiated by the redeem link | +| InActiveAccountEvent | 22 | the systems create an inactive account during the register process | +| SendConfirmEmailEvent | 23 | the system send a confirmation email to the user during the register process | +| ConfirmEmailEvent | 24 | the user confirms his email during the register process | +| RegisterEmailKlickTippEvent | 25 | the system registers the confirmed email at klicktipp | +| LoginEvent | 30 | the user presses the login button | +| RedeemLoginEvent | 31 | the user presses the login button initiated by the redeem link | +| ActivateAccountEvent | 32 | the system activates the users account during the first login process | +| PasswordChangeEvent | 33 | the user changes his password | +| TransactionSendEvent | 40 | the user creates a transaction and sends it online | +| TransactionSendRedeemEvent | 41 | the user creates a transaction and sends it per redeem link | +| TransactionRepeateRedeemEvent | 42 | the user recreates a redeem link of a still open transaction | +| TransactionCreationEvent | 50 | the user receives a creation transaction for his confirmed contribution | +| TransactionReceiveEvent | 51 | the user receives a transaction from an other user and posts the amount on his account | +| TransactionReceiveRedeemEvent | 52 | the user activates the redeem link and receives the transaction and posts the amount on his account | +| ContributionCreateEvent | 60 | the user enters his contribution and asks for confirmation | +| ContributionConfirmEvent | 61 | the user confirms a contribution of an other user (for future multi confirmation from several users) | +| ContributionLinkDefineEvent | 70 | the admin user defines a contributionLink, which could be send per Link/QR-Code on an other medium | +| ContributionLinkActivateRedeemEvent | 71 | the user activates a received contributionLink to create a contribution entry for the contributionLink | ## EventProtocol - Entity @@ -50,29 +51,30 @@ The business events will be stored in database in the new table `EventProtocol`. The following table lists for each event type the mandatory attributes, which have to be initialized at event occurence and to be written in the database event protocol table: -| EventType | id | type | createdAt | userID | XuserID | XCommunityID | transactionID | contribID | amount | -| :-------------------------- | :-: | :--: | :-------: | :----: | :-----: | :----------: | :-----------: | :-------: | :----: | -| BasicEvent | x | x | x | | | | | | | -| VisitGradidoEvent | x | x | x | | | | | | | -| RegisterEvent | x | x | x | x | | | | | | -| RedeemRegisterEvent | x | x | x | x | | | | | | -| InActiveAccountEvent | x | x | x | x | | | | | | -| SendConfirmEmailEvent | x | x | x | x | | | | | | -| ConfirmEmailEvent | x | x | x | x | | | | | | -| RegisterEmailKlickTippEvent | x | x | x | x | | | | | | -| LoginEvent | x | x | x | x | | | | | | -| RedeemLoginEvent | x | x | x | x | | | | | | -| ActivateAccountEvent | x | x | x | x | | | | | | -| PasswordChangeEvent | x | x | x | x | | | | | | -| TxSendEvent | x | x | x | x | x | x | x | | x | -| TxSendRedeemEvent | x | x | x | x | x | x | x | | x | -| TxRepeateRedeemEvent | x | x | x | x | x | x | x | | x | -| TxCreationEvent | x | x | x | x | | | x | | x | -| TxReceiveEvent | x | x | x | x | x | x | x | | x | -| TxReceiveRedeemEvent | x | x | x | x | x | x | x | | x | -| ContribCreateEvent | x | x | x | x | | | | x | | -| ContribConfirmEvent | x | x | x | x | x | x | | x | | -| | | | | | | | | | | +| EventType | id | type | createdAt | userID | XuserID | XCommunityID | transactionID | contribID | amount | +| :---------------------------------- | :-: | :--: | :-------: | :----: | :-----: | :----------: | :-----------: | :-------: | :----: | +| BasicEvent | x | x | x | | | | | | | +| VisitGradidoEvent | x | x | x | | | | | | | +| RegisterEvent | x | x | x | x | | | | | | +| RedeemRegisterEvent | x | x | x | x | | | (x) | (x) | | +| InActiveAccountEvent | x | x | x | x | | | | | | +| SendConfirmEmailEvent | x | x | x | x | | | | | | +| ConfirmEmailEvent | x | x | x | x | | | | | | +| RegisterEmailKlickTippEvent | x | x | x | x | | | | | | +| LoginEvent | x | x | x | x | | | | | | +| RedeemLoginEvent | x | x | x | x | | | (x) | (x) | | +| ActivateAccountEvent | x | x | x | x | | | | | | +| PasswordChangeEvent | x | x | x | x | | | | | | +| TransactionSendEvent | x | x | x | x | x | x | x | | x | +| TransactionSendRedeemEvent | x | x | x | x | x | x | x | | x | +| TransactionRepeateRedeemEvent | x | x | x | x | x | x | x | | x | +| TransactionCreationEvent | x | x | x | x | | | x | | x | +| TransactionReceiveEvent | x | x | x | x | x | x | x | | x | +| TransactionReceiveRedeemEvent | x | x | x | x | x | x | x | | x | +| ContributionCreateEvent | x | x | x | x | | | | x | x | +| ContributionConfirmEvent | x | x | x | x | x | x | | x | x | +| ContributionLinkDefineEvent | x | x | x | x | | | | | x | +| ContributionLinkActivateRedeemEvent | x | x | x | x | | | | x | x | ## Event creation From 7ecd96d28b6adf7ec6c1e87b03de5e1965cbe364 Mon Sep 17 00:00:00 2001 From: Moriz Wahl Date: Wed, 22 Jun 2022 15:09:22 +0200 Subject: [PATCH 03/66] undo changes of DB config --- database/src/config/index.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/database/src/config/index.ts b/database/src/config/index.ts index d8cd78eae..ba41f11d4 100644 --- a/database/src/config/index.ts +++ b/database/src/config/index.ts @@ -6,7 +6,7 @@ dotenv.config() const constants = { CONFIG_VERSION: { DEFAULT: 'DEFAULT', - EXPECTED: 'v7.2022-06-15', + EXPECTED: 'v1.2022-03-18', CURRENT: '', }, } From bab867a1bd01660ac89e9d190d79f4036a818bc2 Mon Sep 17 00:00:00 2001 From: Moriz Wahl Date: Wed, 22 Jun 2022 16:02:28 +0200 Subject: [PATCH 04/66] add global event handler middleware --- backend/src/config/index.ts | 2 +- backend/src/graphql/schema.ts | 2 ++ backend/src/middleware/EventHandler.ts | 15 +++++++++++++++ 3 files changed, 18 insertions(+), 1 deletion(-) create mode 100644 backend/src/middleware/EventHandler.ts diff --git a/backend/src/config/index.ts b/backend/src/config/index.ts index 4e6dd8099..eae01a51f 100644 --- a/backend/src/config/index.ts +++ b/backend/src/config/index.ts @@ -10,7 +10,7 @@ Decimal.set({ }) const constants = { - DB_VERSION: '0040-add_contribution_link_id_to_user', + DB_VERSION: '0041-add_event_protocol_table', 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 diff --git a/backend/src/graphql/schema.ts b/backend/src/graphql/schema.ts index f14f45efa..6b1579ea4 100644 --- a/backend/src/graphql/schema.ts +++ b/backend/src/graphql/schema.ts @@ -1,6 +1,7 @@ import { GraphQLSchema } from 'graphql' import { buildSchema } from 'type-graphql' import path from 'path' +import { EventHandler } from '@/middleware/EventHandler' import isAuthorized from './directive/isAuthorized' import DecimalScalar from './scalar/Decimal' @@ -11,6 +12,7 @@ const schema = async (): Promise => { resolvers: [path.join(__dirname, 'resolver', `!(*.test).{js,ts}`)], authChecker: isAuthorized, scalarsMap: [{ type: Decimal, scalar: DecimalScalar }], + globalMiddlewares: [EventHandler], }) } diff --git a/backend/src/middleware/EventHandler.ts b/backend/src/middleware/EventHandler.ts new file mode 100644 index 000000000..35b9d0b7b --- /dev/null +++ b/backend/src/middleware/EventHandler.ts @@ -0,0 +1,15 @@ +import { MiddlewareFn } from 'type-graphql' +import { EventProtocol } from '@entity/EventProtocol' + +export const EventHandler: MiddlewareFn = async ( + /* eslint-disable-next-line @typescript-eslint/no-unused-vars */ + { root, args, context, info }, + next, +) => { + const event = new EventProtocol() + // set values before calling the resolver here + const result = await next() + // set event values here when having the result ... + await event.save() + return result +} From f5ced262d2a9bfd8317ae3b32bb3c8025459432d Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Claus-Peter=20H=C3=BCbner?= Date: Wed, 22 Jun 2022 21:13:16 +0200 Subject: [PATCH 05/66] linting --- database/entity/0041-add_event_protocol_table/EventProtocol.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/database/entity/0041-add_event_protocol_table/EventProtocol.ts b/database/entity/0041-add_event_protocol_table/EventProtocol.ts index cf7747b77..72470d2ed 100644 --- a/database/entity/0041-add_event_protocol_table/EventProtocol.ts +++ b/database/entity/0041-add_event_protocol_table/EventProtocol.ts @@ -1,5 +1,5 @@ import Decimal from 'decimal.js-light' -import { BaseEntity, Entity, PrimaryGeneratedColumn, Column, DeleteDateColumn } from 'typeorm' +import { BaseEntity, Entity, PrimaryGeneratedColumn, Column } from 'typeorm' import { DecimalTransformer } from '../../src/typeorm/DecimalTransformer' @Entity('event_protocol') From ecd38bd184e216313652edcbb94798c6a93f0347 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Claus-Peter=20H=C3=BCbner?= Date: Thu, 23 Jun 2022 00:26:43 +0200 Subject: [PATCH 06/66] mutation createEventProtocol --- backend/src/seeds/graphql/mutations.ts | 31 ++++++++++++++++++++++++++ 1 file changed, 31 insertions(+) diff --git a/backend/src/seeds/graphql/mutations.ts b/backend/src/seeds/graphql/mutations.ts index 7becae274..f2550aafd 100644 --- a/backend/src/seeds/graphql/mutations.ts +++ b/backend/src/seeds/graphql/mutations.ts @@ -224,3 +224,34 @@ export const deleteContributionLink = gql` deleteContributionLink(id: $id) } ` +export const createEventProtocol = gql` + mutation ( + $type: String! + $userId: Int! + $xUserId: Int + $xCommunityId: Int + $transactionId: Int + $contributionId: Int + $amount: Decimal + ) { + createEventProtocol( + type: $type + userId: $userId + xUserId: $xUserId + xCommunityId: $xCommunityId + transactionId: $transactionId + contributionId: $contributionId + amount: $amount + ) { + id + type + createdAt + userId + xUserId + xCommunityId + transactionId + contributionId + amount + } + } +` From 522233913ea15f3931ce919926a19272b0ad76cf Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Claus-Peter=20H=C3=BCbner?= Date: Tue, 28 Jun 2022 04:08:25 +0200 Subject: [PATCH 07/66] define EventEmitter with an EventHandler for each EventProtocolType --- backend/src/event/EventProtocolEmitter.ts | 322 ++++++++++++++++++++++ 1 file changed, 322 insertions(+) create mode 100644 backend/src/event/EventProtocolEmitter.ts diff --git a/backend/src/event/EventProtocolEmitter.ts b/backend/src/event/EventProtocolEmitter.ts new file mode 100644 index 000000000..5b8520882 --- /dev/null +++ b/backend/src/event/EventProtocolEmitter.ts @@ -0,0 +1,322 @@ +import { EventEmitter } from 'events' +import { backendLogger as logger } from '@/server/logger' +import { EventProtocolType } from '@/graphql/enum/EventProtocolType' +import { EventProtocol } from '@entity/EventProtocol' +import Decimal from 'decimal.js-light' + +export class EventProtocolEmitter extends EventEmitter {} +const eventProtocol = new EventProtocolEmitter() + +eventProtocol.on( + EventProtocolType.ACTIVATE_ACCOUNT, + (_event: Event, createdAt: Date, userId: number) => { + logger.info( + `EventProtocol - ACTIVATE_ACCOUNT: _event=${_event}, createdAt=${createdAt}, userId=${userId}`, + ) + writeEvent(EventProtocolType.ACTIVATE_ACCOUNT, createdAt, userId, null, null, null, null, null) + }, +) + +eventProtocol.on(EventProtocolType.BASIC, (_event: Event, createdAt: Date, userId: number) => { + logger.info(`EventProtocol - BASIC: _event=${_event}, createdAt=${createdAt}, userId=${userId}`) + writeEvent(EventProtocolType.BASIC, createdAt, userId, null, null, null, null, null) +}) + +eventProtocol.on( + EventProtocolType.CONFIRM_EMAIL, + (_event: Event, createdAt: Date, userId: number) => { + logger.info( + `EventProtocol - CONFIRM_EMAIL: _event=${_event}, createdAt=${createdAt}, userId=${userId}`, + ) + writeEvent(EventProtocolType.CONFIRM_EMAIL, createdAt, userId, null, null, null, null, null) + }, +) + +eventProtocol.on( + EventProtocolType.CONTRIBUTION_CONFIRM, + ( + _event: Event, + createdAt: Date, + userId: number, + xUserId: number, + xCommunityId: number, + contributionId: number, + ) => { + logger.info( + `EventProtocol - CONTRIBUTION_CONFIRM: _event=${_event}, createdAt=${createdAt}, userId=${userId}, xUserId=${xUserId}, xCommunityId=${xCommunityId}, contributionId=${contributionId}`, + ) + writeEvent( + EventProtocolType.CONTRIBUTION_CONFIRM, + createdAt, + userId, + xUserId, + xCommunityId, + null, + contributionId, + null, + ) + }, +) + +eventProtocol.on( + EventProtocolType.CONTRIBUTION_CREATE, + (_event, createdAt, userId, contributionId) => { + logger.info( + `EventProtocol - CONTRIBUTION_CREATE: _event=${_event}, createdAt=${createdAt}, userId=${userId}, contributionId=${contributionId}`, + ) + writeEvent( + EventProtocolType.CONTRIBUTION_CREATE, + createdAt, + userId, + null, + null, + null, + contributionId, + null, + ) + }, +) + +eventProtocol.on( + EventProtocolType.CONTRIBUTION_LINK_ACTIVATE_REDEEM, + (_event, createdAt, userId) => { + logger.info( + `EventProtocol - CONTRIBUTION_LINK_ACTIVATE_REDEEM: _event=${_event}, createdAt=${createdAt}, userId=${userId}`, + ) + writeEvent( + EventProtocolType.CONTRIBUTION_LINK_ACTIVATE_REDEEM, + createdAt, + userId, + null, + null, + null, + null, + null, + ) + }, +) + +eventProtocol.on(EventProtocolType.CONTRIBUTION_LINK_DEFINE, (_event, createdAt, userId) => { + logger.info( + `EventProtocol - CONTRIBUTION_LINK_DEFINE: _event=${_event}, createdAt=${createdAt}, userId=${userId}`, + ) + writeEvent( + EventProtocolType.CONTRIBUTION_LINK_DEFINE, + createdAt, + userId, + null, + null, + null, + null, + null, + ) +}) + +eventProtocol.on(EventProtocolType.INACTIVE_ACCOUNT, (_event, createdAt, userId) => { + logger.info( + `EventProtocol - INACTIVE_ACCOUNT: _event=${_event}, createdAt=${createdAt}, userId=${userId}`, + ) + writeEvent(EventProtocolType.INACTIVE_ACCOUNT, createdAt, userId, null, null, null, null, null) +}) + +eventProtocol.on(EventProtocolType.LOGIN, (_event, createdAt, userId) => { + logger.info(`EventProtocol - LOGIN: _event=${_event}, createdAt=${createdAt}, userId=${userId}`) + writeEvent(EventProtocolType.LOGIN, createdAt, userId, null, null, null, null, null) +}) + +eventProtocol.on(EventProtocolType.PASSWORD_CHANGE, (_event, createdAt, userId) => { + logger.info( + `EventProtocol - PASSWORD_CHANGE: _event=${_event}, createdAt=${createdAt}, userId=${userId}`, + ) + writeEvent(EventProtocolType.PASSWORD_CHANGE, createdAt, userId, null, null, null, null, null) +}) + +eventProtocol.on( + EventProtocolType.REDEEM_LOGIN, + (_event, createdAt, userId, transactionId, contributionId) => { + logger.info( + `EventProtocol - REDEEM_LOGIN: _event=${_event}, createdAt=${createdAt}, userId=${userId}, transactionId=${transactionId}, contributionId=${contributionId}`, + ) + writeEvent( + EventProtocolType.REDEEM_LOGIN, + createdAt, + userId, + null, + null, + transactionId, + contributionId, + null, + ) + }, +) + +eventProtocol.on( + EventProtocolType.REDEEM_REGISTER, + (_event, createdAt, userId, transactionId, contributionId) => { + logger.info( + `EventProtocol - REDEEM_REGISTER: _event=${_event}, createdAt=${createdAt}, userId=${userId}, transactionId=${transactionId}, contributionId=${contributionId}`, + ) + writeEvent( + EventProtocolType.REDEEM_REGISTER, + createdAt, + userId, + null, + null, + transactionId, + contributionId, + null, + ) + }, +) + +eventProtocol.on(EventProtocolType.REGISTER, (_event, createdAt, userId) => { + logger.info( + `EventProtocol - REGISTER: _event=${_event}, createdAt=${createdAt}, userId=${userId}`, + ) + writeEvent(EventProtocolType.REGISTER, createdAt, userId, null, null, null, null, null) +}) + +eventProtocol.on(EventProtocolType.REGISTER_EMAIL_KLICKTIPP, (_event, createdAt, userId) => { + logger.info( + `EventProtocol - REGISTER_EMAIL_KLICKTIPP: _event=${_event}, createdAt=${createdAt}, userId=${userId}`, + ) + writeEvent( + EventProtocolType.REGISTER_EMAIL_KLICKTIPP, + createdAt, + userId, + null, + null, + null, + null, + null, + ) +}) + +eventProtocol.on(EventProtocolType.SEND_CONFIRMATION_EMAIL, (_event, createdAt, userId) => { + logger.info( + `EventProtocol - SEND_CONFIRMATION_EMAIL: _event=${_event}, createdAt=${createdAt}, userId=${userId}`, + ) + writeEvent( + EventProtocolType.SEND_CONFIRMATION_EMAIL, + createdAt, + userId, + null, + null, + null, + null, + null, + ) +}) + +eventProtocol.on(EventProtocolType.TRANSACTION_CREATION, (_event, createdAt, userId) => { + logger.info( + `EventProtocol - TRANSACTION_CREATION: _event=${_event}, createdAt=${createdAt}, userId=${userId}`, + ) + writeEvent( + EventProtocolType.TRANSACTION_CREATION, + createdAt, + userId, + null, + null, + null, + null, + null, + ) +}) + +eventProtocol.on(EventProtocolType.TRANSACTION_RECEIVE, (_event, createdAt, userId) => { + logger.info( + `EventProtocol - TRANSACTION_RECEIVE: _event=${_event}, createdAt=${createdAt}, userId=${userId}`, + ) + writeEvent(EventProtocolType.TRANSACTION_RECEIVE, createdAt, userId, null, null, null, null, null) +}) + +eventProtocol.on(EventProtocolType.TRANSACTION_RECEIVE_REDEEM, (_event, createdAt, userId) => { + logger.info( + `EventProtocol - TRANSACTION_RECEIVE_REDEEM: _event=${_event}, createdAt=${createdAt}, userId=${userId}`, + ) + writeEvent( + EventProtocolType.TRANSACTION_RECEIVE_REDEEM, + createdAt, + userId, + null, + null, + null, + null, + null, + ) +}) + +eventProtocol.on(EventProtocolType.TRANSACTION_REPEATE_REDEEM, (_event, createdAt, userId) => { + logger.info( + `EventProtocol - TRANSACTION_REPEATE_REDEEM: _event=${_event}, createdAt=${createdAt}, userId=${userId}`, + ) + writeEvent( + EventProtocolType.TRANSACTION_REPEATE_REDEEM, + createdAt, + userId, + null, + null, + null, + null, + null, + ) +}) + +eventProtocol.on(EventProtocolType.TRANSACTION_SEND, (_event, createdAt, userId) => { + logger.info( + `EventProtocol - TRANSACTION_SEND: _event=${_event}, createdAt=${createdAt}, userId=${userId}`, + ) + writeEvent(EventProtocolType.TRANSACTION_SEND, createdAt, userId, null, null, null, null, null) +}) + +eventProtocol.on(EventProtocolType.TRANSACTION_SEND_REDEEM, (_event, createdAt, userId) => { + logger.info( + `EventProtocol - TRANSACTION_SEND_REDEEM: _event=${_event}, createdAt=${createdAt}, userId=${userId}`, + ) + writeEvent( + EventProtocolType.TRANSACTION_SEND_REDEEM, + createdAt, + userId, + null, + null, + null, + null, + null, + ) +}) + +eventProtocol.on(EventProtocolType.VISIT_GRADIDO, (_event, createdAt, userId) => { + logger.info( + `EventProtocol - VISIT_GRADIDO: _event=${_event}, createdAt=${createdAt}, userId=${userId}`, + ) + writeEvent(EventProtocolType.VISIT_GRADIDO, createdAt, userId, null, null, null, null, null) +}) + +async function writeEvent( + type: string, + createdAt: Date, + userId: number, + xUserId: number | null, + xCommunityId: number | null, + transactionId: number | null, + contributionId: number | null, + amount: Decimal | null, +) { + const event = new EventProtocol() + // eslint-disable-next-line no-unused-expressions + amount ? (event.amount = amount) : null + // eslint-disable-next-line no-unused-expressions + contributionId ? (event.contributionId = contributionId) : null + event.createdAt = createdAt + // eslint-disable-next-line no-unused-expressions + transactionId ? (event.transactionId = transactionId) : null + event.type = type + event.userId = userId + // eslint-disable-next-line no-unused-expressions + xCommunityId ? (event.xCommunityId = xCommunityId) : null + // eslint-disable-next-line no-unused-expressions + xUserId ? (event.xUserId = xUserId) : null + // set event values here when having the result ... + await event.save() +} From 0dbce63910264e98cf1baf266a540a095bd60929 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Claus-Peter=20H=C3=BCbner?= Date: Tue, 28 Jun 2022 04:13:26 +0200 Subject: [PATCH 08/66] emit some first events --- backend/src/graphql/resolver/UserResolver.ts | 21 ++++++++++++++++++++ 1 file changed, 21 insertions(+) diff --git a/backend/src/graphql/resolver/UserResolver.ts b/backend/src/graphql/resolver/UserResolver.ts index 0bde22ae6..f3c4bcd3f 100644 --- a/backend/src/graphql/resolver/UserResolver.ts +++ b/backend/src/graphql/resolver/UserResolver.ts @@ -23,6 +23,11 @@ import { sendAccountMultiRegistrationEmail } from '@/mailer/sendAccountMultiRegi import { klicktippSignIn } from '@/apis/KlicktippController' import { RIGHTS } from '@/auth/RIGHTS' import { hasElopageBuys } from '@/util/hasElopageBuys' +import { EventProtocolEmitter } from '@/event/EventProtocolEmitter' +import { EventProtocolType } from '@/graphql/enum/EventProtocolType' + + +const eventProtocol = new EventProtocolEmitter() // eslint-disable-next-line @typescript-eslint/no-var-requires const sodium = require('sodium-native') @@ -290,6 +295,7 @@ export class UserResolver { key: 'token', value: encode(dbUser.pubKey), }) + eventProtocol.emit(EventProtocolType.LOGIN, new Date(Date.now()), user.id) logger.info('successful Login:' + user) return user } @@ -384,12 +390,26 @@ export class UserResolver { logger.info('redeemCode found contributionLink=' + contributionLink) if (contributionLink) { dbUser.contributionLinkId = contributionLink.id + eventProtocol.emit( + EventProtocolType.REDEEM_REGISTER, + new Date(Date.now()), + dbUser.id, + null, + contributionLink.id, + ) } } else { const transactionLink = await dbTransactionLink.findOne({ code: redeemCode }) logger.info('redeemCode found transactionLink=' + transactionLink) if (transactionLink) { dbUser.referrerId = transactionLink.userId + eventProtocol.emit( + EventProtocolType.REDEEM_REGISTER, + new Date(Date.now()), + dbUser.id, + transactionLink.id, + null, + ) } } } @@ -444,6 +464,7 @@ export class UserResolver { await queryRunner.release() } logger.info('createUser() successful...') + eventProtocol.emit(EventProtocolType.REGISTER, new Date(Date.now()), dbUser.id) return new User(dbUser) } From 55f491694a4b6690e3241487a9fc2b60c15a7c43 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Claus-Peter=20H=C3=BCbner?= Date: Tue, 28 Jun 2022 04:23:43 +0200 Subject: [PATCH 09/66] lintting --- backend/src/graphql/resolver/UserResolver.ts | 1 - 1 file changed, 1 deletion(-) diff --git a/backend/src/graphql/resolver/UserResolver.ts b/backend/src/graphql/resolver/UserResolver.ts index f3c4bcd3f..879cf7eaf 100644 --- a/backend/src/graphql/resolver/UserResolver.ts +++ b/backend/src/graphql/resolver/UserResolver.ts @@ -26,7 +26,6 @@ import { hasElopageBuys } from '@/util/hasElopageBuys' import { EventProtocolEmitter } from '@/event/EventProtocolEmitter' import { EventProtocolType } from '@/graphql/enum/EventProtocolType' - const eventProtocol = new EventProtocolEmitter() // eslint-disable-next-line @typescript-eslint/no-var-requires From 1edea38fbb386704a2ad83eb89d0c7cb0ec6ec74 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Claus-Peter=20H=C3=BCbner?= Date: Wed, 29 Jun 2022 02:06:16 +0200 Subject: [PATCH 10/66] move EventProtocolType in event package --- backend/src/{graphql/enum => event}/EventProtocolType.ts | 0 1 file changed, 0 insertions(+), 0 deletions(-) rename backend/src/{graphql/enum => event}/EventProtocolType.ts (100%) diff --git a/backend/src/graphql/enum/EventProtocolType.ts b/backend/src/event/EventProtocolType.ts similarity index 100% rename from backend/src/graphql/enum/EventProtocolType.ts rename to backend/src/event/EventProtocolType.ts From 1d02795562a4f7189436acd46ad621c438425588 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Claus-Peter=20H=C3=BCbner?= Date: Wed, 29 Jun 2022 02:06:44 +0200 Subject: [PATCH 11/66] rework EventProtocol --- backend/src/event/EventProtocolEmitter.ts | 489 +++++++++++----------- backend/src/event/EventProtocolType.ts | 51 +-- 2 files changed, 270 insertions(+), 270 deletions(-) diff --git a/backend/src/event/EventProtocolEmitter.ts b/backend/src/event/EventProtocolEmitter.ts index 5b8520882..64e13cf18 100644 --- a/backend/src/event/EventProtocolEmitter.ts +++ b/backend/src/event/EventProtocolEmitter.ts @@ -1,68 +1,231 @@ import { EventEmitter } from 'events' import { backendLogger as logger } from '@/server/logger' -import { EventProtocolType } from '@/graphql/enum/EventProtocolType' +import { EventProtocolType } from './EventProtocolType' import { EventProtocol } from '@entity/EventProtocol' import Decimal from 'decimal.js-light' -export class EventProtocolEmitter extends EventEmitter {} -const eventProtocol = new EventProtocolEmitter() +class EventProtocolEmitter extends EventEmitter {} +export const eventProtocol = new EventProtocolEmitter() -eventProtocol.on( - EventProtocolType.ACTIVATE_ACCOUNT, - (_event: Event, createdAt: Date, userId: number) => { - logger.info( - `EventProtocol - ACTIVATE_ACCOUNT: _event=${_event}, createdAt=${createdAt}, userId=${userId}`, - ) - writeEvent(EventProtocolType.ACTIVATE_ACCOUNT, createdAt, userId, null, null, null, null, null) - }, -) +eventProtocol.on('error', (err) => { + logger.error(`ERROR in EventProtocol: ${err}`) +}) -eventProtocol.on(EventProtocolType.BASIC, (_event: Event, createdAt: Date, userId: number) => { - logger.info(`EventProtocol - BASIC: _event=${_event}, createdAt=${createdAt}, userId=${userId}`) +eventProtocol.on(EventProtocolType.BASIC, (createdAt: Date, userId: number) => { + logger.info( + `EventProtocol - ${EventProtocolType.BASIC}: createdAt=${createdAt}, userId=${userId}`, + ) writeEvent(EventProtocolType.BASIC, createdAt, userId, null, null, null, null, null) }) +eventProtocol.on(EventProtocolType.VISIT_GRADIDO, (createdAt: Date, userId: number) => { + logger.info( + `EventProtocol - ${EventProtocolType.VISIT_GRADIDO}: createdAt=${createdAt}, userId=${userId}`, + ) + writeEvent(EventProtocolType.VISIT_GRADIDO, createdAt, userId, null, null, null, null, null) +}) + +eventProtocol.on(EventProtocolType.REGISTER, (createdAt: Date, userId: number) => { + logger.info( + `EventProtocol - ${EventProtocolType.REGISTER}: createdAt=${createdAt}, userId=${userId}`, + ) + writeEvent(EventProtocolType.REGISTER, createdAt, userId, null, null, null, null, null) +}) + eventProtocol.on( - EventProtocolType.CONFIRM_EMAIL, - (_event: Event, createdAt: Date, userId: number) => { + EventProtocolType.REDEEM_REGISTER, + (createdAt: Date, userId: number, transactionId: number, contributionId: number) => { logger.info( - `EventProtocol - CONFIRM_EMAIL: _event=${_event}, createdAt=${createdAt}, userId=${userId}`, + `EventProtocol - ${EventProtocolType.REDEEM_REGISTER}: createdAt=${createdAt}, userId=${userId}, transactionId=${transactionId}, contributionId=${contributionId}`, + ) + writeEvent( + EventProtocolType.REDEEM_REGISTER, + createdAt, + userId, + null, + null, + transactionId, + contributionId, + null, ) - writeEvent(EventProtocolType.CONFIRM_EMAIL, createdAt, userId, null, null, null, null, null) }, ) +eventProtocol.on(EventProtocolType.INACTIVE_ACCOUNT, (createdAt: Date, userId: number) => { + logger.info( + `EventProtocol - ${EventProtocolType.INACTIVE_ACCOUNT}: createdAt=${createdAt}, userId=${userId}`, + ) + writeEvent(EventProtocolType.INACTIVE_ACCOUNT, createdAt, userId, null, null, null, null, null) +}) + +eventProtocol.on(EventProtocolType.SEND_CONFIRMATION_EMAIL, (createdAt: Date, userId: number) => { + logger.info( + `EventProtocol - ${EventProtocolType.SEND_CONFIRMATION_EMAIL}: createdAt=${createdAt}, userId=${userId}`, + ) + writeEvent( + EventProtocolType.SEND_CONFIRMATION_EMAIL, + createdAt, + userId, + null, + null, + null, + null, + null, + ) +}) + +eventProtocol.on(EventProtocolType.CONFIRM_EMAIL, (createdAt: Date, userId: number) => { + logger.info( + `EventProtocol - ${EventProtocolType.CONFIRM_EMAIL}: createdAt=${createdAt}, userId=${userId}`, + ) + writeEvent(EventProtocolType.CONFIRM_EMAIL, createdAt, userId, null, null, null, null, null) +}) + +eventProtocol.on(EventProtocolType.REGISTER_EMAIL_KLICKTIPP, (createdAt: Date, userId: number) => { + logger.info( + `EventProtocol - ${EventProtocolType.REGISTER_EMAIL_KLICKTIPP}: createdAt=${createdAt}, userId=${userId}`, + ) + writeEvent( + EventProtocolType.REGISTER_EMAIL_KLICKTIPP, + createdAt, + userId, + null, + null, + null, + null, + null, + ) +}) + +eventProtocol.on(EventProtocolType.LOGIN, (createdAt: Date, userId: number) => { + logger.info( + `EventProtocol - ${EventProtocolType.LOGIN}: createdAt=${createdAt}, userId=${userId}`, + ) + writeEvent(EventProtocolType.LOGIN, createdAt, userId, null, null, null, null, null) +}) + eventProtocol.on( - EventProtocolType.CONTRIBUTION_CONFIRM, - ( - _event: Event, - createdAt: Date, - userId: number, - xUserId: number, - xCommunityId: number, - contributionId: number, - ) => { + EventProtocolType.REDEEM_LOGIN, + (createdAt: Date, userId: number, transactionId: number, contributionId: number) => { logger.info( - `EventProtocol - CONTRIBUTION_CONFIRM: _event=${_event}, createdAt=${createdAt}, userId=${userId}, xUserId=${xUserId}, xCommunityId=${xCommunityId}, contributionId=${contributionId}`, + `EventProtocol - ${EventProtocolType.REDEEM_LOGIN}: createdAt=${createdAt}, userId=${userId}, transactionId=${transactionId}, contributionId=${contributionId}`, ) writeEvent( - EventProtocolType.CONTRIBUTION_CONFIRM, + EventProtocolType.REDEEM_LOGIN, createdAt, userId, - xUserId, - xCommunityId, null, + null, + transactionId, contributionId, null, ) }, ) +eventProtocol.on(EventProtocolType.ACTIVATE_ACCOUNT, (createdAt: Date, userId: number) => { + logger.info( + `EventProtocol - ${EventProtocolType.ACTIVATE_ACCOUNT}: createdAt=${createdAt}, userId=${userId}`, + ) + writeEvent(EventProtocolType.ACTIVATE_ACCOUNT, createdAt, userId, null, null, null, null, null) +}) + +eventProtocol.on(EventProtocolType.PASSWORD_CHANGE, (createdAt: Date, userId: number) => { + logger.info( + `EventProtocol - ${EventProtocolType.PASSWORD_CHANGE}: createdAt=${createdAt}, userId=${userId}`, + ) + writeEvent(EventProtocolType.PASSWORD_CHANGE, createdAt, userId, null, null, null, null, null) +}) + +eventProtocol.on(EventProtocolType.TRANSACTION_SEND, (createdAt: Date, userId: number) => { + logger.info( + `EventProtocol - ${EventProtocolType.TRANSACTION_SEND}: createdAt=${createdAt}, userId=${userId}`, + ) + writeEvent(EventProtocolType.TRANSACTION_SEND, createdAt, userId, null, null, null, null, null) +}) + +eventProtocol.on(EventProtocolType.TRANSACTION_SEND_REDEEM, (createdAt: Date, userId: number) => { + logger.info( + `EventProtocol - ${EventProtocolType.TRANSACTION_SEND_REDEEM}: createdAt=${createdAt}, userId=${userId}`, + ) + writeEvent( + EventProtocolType.TRANSACTION_SEND_REDEEM, + createdAt, + userId, + null, + null, + null, + null, + null, + ) +}) + +eventProtocol.on( + EventProtocolType.TRANSACTION_REPEATE_REDEEM, + (createdAt: Date, userId: number) => { + logger.info( + `EventProtocol - ${EventProtocolType.TRANSACTION_REPEATE_REDEEM}: createdAt=${createdAt}, userId=${userId}`, + ) + writeEvent( + EventProtocolType.TRANSACTION_REPEATE_REDEEM, + createdAt, + userId, + null, + null, + null, + null, + null, + ) + }, +) + +eventProtocol.on(EventProtocolType.TRANSACTION_CREATION, (createdAt: Date, userId: number) => { + logger.info( + `EventProtocol - ${EventProtocolType.TRANSACTION_CREATION}: createdAt=${createdAt}, userId=${userId}`, + ) + writeEvent( + EventProtocolType.TRANSACTION_CREATION, + createdAt, + userId, + null, + null, + null, + null, + null, + ) +}) + +eventProtocol.on(EventProtocolType.TRANSACTION_RECEIVE, (createdAt: Date, userId: number) => { + logger.info( + `EventProtocol - ${EventProtocolType.TRANSACTION_RECEIVE}: createdAt=${createdAt}, userId=${userId}`, + ) + writeEvent(EventProtocolType.TRANSACTION_RECEIVE, createdAt, userId, null, null, null, null, null) +}) + +eventProtocol.on( + EventProtocolType.TRANSACTION_RECEIVE_REDEEM, + (createdAt: Date, userId: number) => { + logger.info( + `EventProtocol - ${EventProtocolType.TRANSACTION_RECEIVE_REDEEM}: createdAt=${createdAt}, userId=${userId}`, + ) + writeEvent( + EventProtocolType.TRANSACTION_RECEIVE_REDEEM, + createdAt, + userId, + null, + null, + null, + null, + null, + ) + }, +) + eventProtocol.on( EventProtocolType.CONTRIBUTION_CREATE, - (_event, createdAt, userId, contributionId) => { + (createdAt: Date, userId: number, contributionId: number) => { logger.info( - `EventProtocol - CONTRIBUTION_CREATE: _event=${_event}, createdAt=${createdAt}, userId=${userId}, contributionId=${contributionId}`, + `EventProtocol - ${EventProtocolType.CONTRIBUTION_CREATE}: createdAt=${createdAt}, userId=${userId}, contributionId=${contributionId}`, ) writeEvent( EventProtocolType.CONTRIBUTION_CREATE, @@ -78,10 +241,51 @@ eventProtocol.on( ) eventProtocol.on( - EventProtocolType.CONTRIBUTION_LINK_ACTIVATE_REDEEM, - (_event, createdAt, userId) => { + EventProtocolType.CONTRIBUTION_CONFIRM, + ( + createdAt: Date, + userId: number, + xUserId: number, + xCommunityId: number, + contributionId: number, + ) => { logger.info( - `EventProtocol - CONTRIBUTION_LINK_ACTIVATE_REDEEM: _event=${_event}, createdAt=${createdAt}, userId=${userId}`, + `EventProtocol - ${EventProtocolType.CONTRIBUTION_CONFIRM}: createdAt=${createdAt}, userId=${userId}, xUserId=${xUserId}, xCommunityId=${xCommunityId}, contributionId=${contributionId}`, + ) + writeEvent( + EventProtocolType.CONTRIBUTION_CONFIRM, + createdAt, + userId, + xUserId, + xCommunityId, + null, + contributionId, + null, + ) + }, +) + +eventProtocol.on(EventProtocolType.CONTRIBUTION_LINK_DEFINE, (createdAt: Date, userId: number) => { + logger.info( + `EventProtocol - ${EventProtocolType.CONTRIBUTION_LINK_DEFINE}: createdAt=${createdAt}, userId=${userId}`, + ) + writeEvent( + EventProtocolType.CONTRIBUTION_LINK_DEFINE, + createdAt, + userId, + null, + null, + null, + null, + null, + ) +}) + +eventProtocol.on( + EventProtocolType.CONTRIBUTION_LINK_ACTIVATE_REDEEM, + (createdAt: Date, userId: number) => { + logger.info( + `EventProtocol - ${EventProtocolType.CONTRIBUTION_LINK_ACTIVATE_REDEEM}: createdAt=${createdAt}, userId=${userId}`, ) writeEvent( EventProtocolType.CONTRIBUTION_LINK_ACTIVATE_REDEEM, @@ -96,203 +300,6 @@ eventProtocol.on( }, ) -eventProtocol.on(EventProtocolType.CONTRIBUTION_LINK_DEFINE, (_event, createdAt, userId) => { - logger.info( - `EventProtocol - CONTRIBUTION_LINK_DEFINE: _event=${_event}, createdAt=${createdAt}, userId=${userId}`, - ) - writeEvent( - EventProtocolType.CONTRIBUTION_LINK_DEFINE, - createdAt, - userId, - null, - null, - null, - null, - null, - ) -}) - -eventProtocol.on(EventProtocolType.INACTIVE_ACCOUNT, (_event, createdAt, userId) => { - logger.info( - `EventProtocol - INACTIVE_ACCOUNT: _event=${_event}, createdAt=${createdAt}, userId=${userId}`, - ) - writeEvent(EventProtocolType.INACTIVE_ACCOUNT, createdAt, userId, null, null, null, null, null) -}) - -eventProtocol.on(EventProtocolType.LOGIN, (_event, createdAt, userId) => { - logger.info(`EventProtocol - LOGIN: _event=${_event}, createdAt=${createdAt}, userId=${userId}`) - writeEvent(EventProtocolType.LOGIN, createdAt, userId, null, null, null, null, null) -}) - -eventProtocol.on(EventProtocolType.PASSWORD_CHANGE, (_event, createdAt, userId) => { - logger.info( - `EventProtocol - PASSWORD_CHANGE: _event=${_event}, createdAt=${createdAt}, userId=${userId}`, - ) - writeEvent(EventProtocolType.PASSWORD_CHANGE, createdAt, userId, null, null, null, null, null) -}) - -eventProtocol.on( - EventProtocolType.REDEEM_LOGIN, - (_event, createdAt, userId, transactionId, contributionId) => { - logger.info( - `EventProtocol - REDEEM_LOGIN: _event=${_event}, createdAt=${createdAt}, userId=${userId}, transactionId=${transactionId}, contributionId=${contributionId}`, - ) - writeEvent( - EventProtocolType.REDEEM_LOGIN, - createdAt, - userId, - null, - null, - transactionId, - contributionId, - null, - ) - }, -) - -eventProtocol.on( - EventProtocolType.REDEEM_REGISTER, - (_event, createdAt, userId, transactionId, contributionId) => { - logger.info( - `EventProtocol - REDEEM_REGISTER: _event=${_event}, createdAt=${createdAt}, userId=${userId}, transactionId=${transactionId}, contributionId=${contributionId}`, - ) - writeEvent( - EventProtocolType.REDEEM_REGISTER, - createdAt, - userId, - null, - null, - transactionId, - contributionId, - null, - ) - }, -) - -eventProtocol.on(EventProtocolType.REGISTER, (_event, createdAt, userId) => { - logger.info( - `EventProtocol - REGISTER: _event=${_event}, createdAt=${createdAt}, userId=${userId}`, - ) - writeEvent(EventProtocolType.REGISTER, createdAt, userId, null, null, null, null, null) -}) - -eventProtocol.on(EventProtocolType.REGISTER_EMAIL_KLICKTIPP, (_event, createdAt, userId) => { - logger.info( - `EventProtocol - REGISTER_EMAIL_KLICKTIPP: _event=${_event}, createdAt=${createdAt}, userId=${userId}`, - ) - writeEvent( - EventProtocolType.REGISTER_EMAIL_KLICKTIPP, - createdAt, - userId, - null, - null, - null, - null, - null, - ) -}) - -eventProtocol.on(EventProtocolType.SEND_CONFIRMATION_EMAIL, (_event, createdAt, userId) => { - logger.info( - `EventProtocol - SEND_CONFIRMATION_EMAIL: _event=${_event}, createdAt=${createdAt}, userId=${userId}`, - ) - writeEvent( - EventProtocolType.SEND_CONFIRMATION_EMAIL, - createdAt, - userId, - null, - null, - null, - null, - null, - ) -}) - -eventProtocol.on(EventProtocolType.TRANSACTION_CREATION, (_event, createdAt, userId) => { - logger.info( - `EventProtocol - TRANSACTION_CREATION: _event=${_event}, createdAt=${createdAt}, userId=${userId}`, - ) - writeEvent( - EventProtocolType.TRANSACTION_CREATION, - createdAt, - userId, - null, - null, - null, - null, - null, - ) -}) - -eventProtocol.on(EventProtocolType.TRANSACTION_RECEIVE, (_event, createdAt, userId) => { - logger.info( - `EventProtocol - TRANSACTION_RECEIVE: _event=${_event}, createdAt=${createdAt}, userId=${userId}`, - ) - writeEvent(EventProtocolType.TRANSACTION_RECEIVE, createdAt, userId, null, null, null, null, null) -}) - -eventProtocol.on(EventProtocolType.TRANSACTION_RECEIVE_REDEEM, (_event, createdAt, userId) => { - logger.info( - `EventProtocol - TRANSACTION_RECEIVE_REDEEM: _event=${_event}, createdAt=${createdAt}, userId=${userId}`, - ) - writeEvent( - EventProtocolType.TRANSACTION_RECEIVE_REDEEM, - createdAt, - userId, - null, - null, - null, - null, - null, - ) -}) - -eventProtocol.on(EventProtocolType.TRANSACTION_REPEATE_REDEEM, (_event, createdAt, userId) => { - logger.info( - `EventProtocol - TRANSACTION_REPEATE_REDEEM: _event=${_event}, createdAt=${createdAt}, userId=${userId}`, - ) - writeEvent( - EventProtocolType.TRANSACTION_REPEATE_REDEEM, - createdAt, - userId, - null, - null, - null, - null, - null, - ) -}) - -eventProtocol.on(EventProtocolType.TRANSACTION_SEND, (_event, createdAt, userId) => { - logger.info( - `EventProtocol - TRANSACTION_SEND: _event=${_event}, createdAt=${createdAt}, userId=${userId}`, - ) - writeEvent(EventProtocolType.TRANSACTION_SEND, createdAt, userId, null, null, null, null, null) -}) - -eventProtocol.on(EventProtocolType.TRANSACTION_SEND_REDEEM, (_event, createdAt, userId) => { - logger.info( - `EventProtocol - TRANSACTION_SEND_REDEEM: _event=${_event}, createdAt=${createdAt}, userId=${userId}`, - ) - writeEvent( - EventProtocolType.TRANSACTION_SEND_REDEEM, - createdAt, - userId, - null, - null, - null, - null, - null, - ) -}) - -eventProtocol.on(EventProtocolType.VISIT_GRADIDO, (_event, createdAt, userId) => { - logger.info( - `EventProtocol - VISIT_GRADIDO: _event=${_event}, createdAt=${createdAt}, userId=${userId}`, - ) - writeEvent(EventProtocolType.VISIT_GRADIDO, createdAt, userId, null, null, null, null, null) -}) - async function writeEvent( type: string, createdAt: Date, @@ -304,19 +311,19 @@ async function writeEvent( amount: Decimal | null, ) { const event = new EventProtocol() - // eslint-disable-next-line no-unused-expressions - amount ? (event.amount = amount) : null - // eslint-disable-next-line no-unused-expressions - contributionId ? (event.contributionId = contributionId) : null - event.createdAt = createdAt - // eslint-disable-next-line no-unused-expressions - transactionId ? (event.transactionId = transactionId) : null event.type = type + event.createdAt = createdAt event.userId = userId // eslint-disable-next-line no-unused-expressions + xUserId ? (event.xUserId = xUserId) : null + // eslint-disable-next-line no-unused-expressions xCommunityId ? (event.xCommunityId = xCommunityId) : null // eslint-disable-next-line no-unused-expressions - xUserId ? (event.xUserId = xUserId) : null + contributionId ? (event.contributionId = contributionId) : null + // eslint-disable-next-line no-unused-expressions + transactionId ? (event.transactionId = transactionId) : null + // eslint-disable-next-line no-unused-expressions + amount ? (event.amount = amount) : null // set event values here when having the result ... await event.save() } diff --git a/backend/src/event/EventProtocolType.ts b/backend/src/event/EventProtocolType.ts index a95ccb819..0f61f787a 100644 --- a/backend/src/event/EventProtocolType.ts +++ b/backend/src/event/EventProtocolType.ts @@ -1,31 +1,24 @@ -import { registerEnumType } from 'type-graphql' - export enum EventProtocolType { - BASIC = '0', - VISIT_GRADIDO = '10', - REGISTER = '20', - REDEEM_REGISTER = '21', - INACTIVE_ACCOUNT = '22', - SEND_CONFIRMATION_EMAIL = '23', - CONFIRM_EMAIL = '24', - REGISTER_EMAIL_KLICKTIPP = '25', - LOGIN = '30', - REDEEM_LOGIN = '31', - ACTIVATE_ACCOUNT = '32', - PASSWORD_CHANGE = '33', - TRANSACTION_SEND = '40', - TRANSACTION_SEND_REDEEM = '41', - TRANSACTION_REPEATE_REDEEM = '42', - TRANSACTION_CREATION = '50', - TRANSACTION_RECEIVE = '51', - TRANSACTION_RECEIVE_REDEEM = '52', - CONTRIBUTION_CREATE = '60', - CONTRIBUTION_CONFIRM = '61', - CONTRIBUTION_LINK_DEFINE = '70', - CONTRIBUTION_LINK_ACTIVATE_REDEEM = '71', + BASIC = 'BASIC', + VISIT_GRADIDO = 'VISIT_GRADIDO', + REGISTER = 'REGISTER', + REDEEM_REGISTER = 'REDEEM_REGISTER', + INACTIVE_ACCOUNT = 'INACTIVE_ACCOUNT', + SEND_CONFIRMATION_EMAIL = 'SEND_CONFIRMATION_EMAIL', + CONFIRM_EMAIL = 'CONFIRM_EMAIL', + REGISTER_EMAIL_KLICKTIPP = 'REGISTER_EMAIL_KLICKTIPP', + LOGIN = 'LOGIN', + REDEEM_LOGIN = 'REDEEM_LOGIN', + ACTIVATE_ACCOUNT = 'ACTIVATE_ACCOUNT', + PASSWORD_CHANGE = 'PASSWORD_CHANGE', + 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', + CONTRIBUTION_CREATE = 'CONTRIBUTION_CREATE', + CONTRIBUTION_CONFIRM = 'CONTRIBUTION_CONFIRM', + CONTRIBUTION_LINK_DEFINE = 'CONTRIBUTION_LINK_DEFINE', + CONTRIBUTION_LINK_ACTIVATE_REDEEM = 'CONTRIBUTION_LINK_ACTIVATE_REDEEM', } - -registerEnumType(EventProtocolType, { - name: 'EventProtocolType', // this one is mandatory - description: 'Name of the Type of the EventProtocol', // this one is optional -}) From 60fde3f6886dc3a398ac3f38e9d70356f977eac1 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Claus-Peter=20H=C3=BCbner?= Date: Wed, 29 Jun 2022 02:07:58 +0200 Subject: [PATCH 12/66] rework EventProtocol --- backend/src/graphql/resolver/UserResolver.ts | 6 ++---- 1 file changed, 2 insertions(+), 4 deletions(-) diff --git a/backend/src/graphql/resolver/UserResolver.ts b/backend/src/graphql/resolver/UserResolver.ts index 879cf7eaf..fed5530f8 100644 --- a/backend/src/graphql/resolver/UserResolver.ts +++ b/backend/src/graphql/resolver/UserResolver.ts @@ -23,10 +23,8 @@ import { sendAccountMultiRegistrationEmail } from '@/mailer/sendAccountMultiRegi import { klicktippSignIn } from '@/apis/KlicktippController' import { RIGHTS } from '@/auth/RIGHTS' import { hasElopageBuys } from '@/util/hasElopageBuys' -import { EventProtocolEmitter } from '@/event/EventProtocolEmitter' -import { EventProtocolType } from '@/graphql/enum/EventProtocolType' - -const eventProtocol = new EventProtocolEmitter() +import { eventProtocol } from '@/event/EventProtocolEmitter' +import { EventProtocolType } from '@/event/EventProtocolType' // eslint-disable-next-line @typescript-eslint/no-var-requires const sodium = require('sodium-native') From 38fcb0e9cf54abf72955e8cb56008a31cfc5c976 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Claus-Peter=20H=C3=BCbner?= Date: Thu, 30 Jun 2022 01:28:27 +0200 Subject: [PATCH 13/66] next try writing event_protocol --- backend/src/event/EventProtocolEmitter.ts | 44 +++++++++++++++++------ 1 file changed, 33 insertions(+), 11 deletions(-) diff --git a/backend/src/event/EventProtocolEmitter.ts b/backend/src/event/EventProtocolEmitter.ts index 64e13cf18..1e70880a4 100644 --- a/backend/src/event/EventProtocolEmitter.ts +++ b/backend/src/event/EventProtocolEmitter.ts @@ -2,9 +2,10 @@ import { EventEmitter } from 'events' import { backendLogger as logger } from '@/server/logger' import { EventProtocolType } from './EventProtocolType' import { EventProtocol } from '@entity/EventProtocol' +import { getConnection } from '@dbTools/typeorm' import Decimal from 'decimal.js-light' -class EventProtocolEmitter extends EventEmitter {} +class EventProtocolEmitter extends EventEmitter { } export const eventProtocol = new EventProtocolEmitter() eventProtocol.on('error', (err) => { @@ -310,20 +311,41 @@ async function writeEvent( contributionId: number | null, amount: Decimal | null, ) { - const event = new EventProtocol() - event.type = type - event.createdAt = createdAt - event.userId = userId + logger.info( + `writeEvent(type=${type}, createdAt=${createdAt}, userId=${userId}, xUserId=${xUserId}, xCommunityId=${xCommunityId}, contributionId=${contributionId}, transactionId=${transactionId}, amount=${amount})`, + ) + const dbEvent = new EventProtocol() + dbEvent.type = type + dbEvent.createdAt = createdAt + dbEvent.userId = userId // eslint-disable-next-line no-unused-expressions - xUserId ? (event.xUserId = xUserId) : null + xUserId ? (dbEvent.xUserId = xUserId) : null // eslint-disable-next-line no-unused-expressions - xCommunityId ? (event.xCommunityId = xCommunityId) : null + xCommunityId ? (dbEvent.xCommunityId = xCommunityId) : null // eslint-disable-next-line no-unused-expressions - contributionId ? (event.contributionId = contributionId) : null + contributionId ? (dbEvent.contributionId = contributionId) : null // eslint-disable-next-line no-unused-expressions - transactionId ? (event.transactionId = transactionId) : null + transactionId ? (dbEvent.transactionId = transactionId) : null // eslint-disable-next-line no-unused-expressions - amount ? (event.amount = amount) : null + amount ? (dbEvent.amount = amount) : null // set event values here when having the result ... - await event.save() + // await dbEvent.save() + + const queryRunner = getConnection().createQueryRunner('master') + await queryRunner.connect() + await queryRunner.startTransaction('READ UNCOMMITTED') + try { + await queryRunner.manager.save(dbEvent).catch((error) => { + logger.error('Error while saving dbEvent', error) + throw new Error('error saving eventProtocol entry') + }) + await queryRunner.commitTransaction() + } catch (e) { + logger.error(`error during write event with ${e}`) + await queryRunner.rollbackTransaction() + throw e + } finally { + await queryRunner.release() + } } + From 7f5995d2fac9ae152a8ead3134a0d3400dce09ea Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Claus-Peter=20H=C3=BCbner?= Date: Fri, 1 Jul 2022 00:40:10 +0200 Subject: [PATCH 14/66] add enable-check to EventProtocol configurable as CONFIG-Property --- backend/.env.dist | 3 ++ backend/src/config/index.ts | 6 ++++ backend/src/event/EventProtocolEmitter.ts | 13 ++++--- backend/src/graphql/resolver/UserResolver.ts | 36 ++++++++++++-------- 4 files changed, 39 insertions(+), 19 deletions(-) diff --git a/backend/.env.dist b/backend/.env.dist index db01cf4cc..aa44057e7 100644 --- a/backend/.env.dist +++ b/backend/.env.dist @@ -52,6 +52,9 @@ EMAIL_CODE_REQUEST_TIME=10 # Webhook WEBHOOK_ELOPAGE_SECRET=secret +# EventProtocol +EVENT_PROTOCOL_ENABLED=true + # SET LOG LEVEL AS NEEDED IN YOUR .ENV # POSSIBLE VALUES: all | trace | debug | info | warn | error | fatal # LOG_LEVEL=info diff --git a/backend/src/config/index.ts b/backend/src/config/index.ts index 641770d4e..a92d20c57 100644 --- a/backend/src/config/index.ts +++ b/backend/src/config/index.ts @@ -94,6 +94,11 @@ const webhook = { WEBHOOK_ELOPAGE_SECRET: process.env.WEBHOOK_ELOPAGE_SECRET || 'secret', } +const eventProtocol = { + // global switch to enable writing of EventProtocol-Entries + EVENT_PROTOCOL_ENABLED: process.env.EVENT_PROTOCOL_ENABLED === 'true' || false, +} + // This is needed by graphql-directive-auth process.env.APP_SECRET = server.JWT_SECRET @@ -118,6 +123,7 @@ const CONFIG = { ...email, ...loginServer, ...webhook, + ...eventProtocol, } export default CONFIG diff --git a/backend/src/event/EventProtocolEmitter.ts b/backend/src/event/EventProtocolEmitter.ts index 1e70880a4..4910bcdfa 100644 --- a/backend/src/event/EventProtocolEmitter.ts +++ b/backend/src/event/EventProtocolEmitter.ts @@ -4,8 +4,14 @@ import { EventProtocolType } from './EventProtocolType' import { EventProtocol } from '@entity/EventProtocol' import { getConnection } from '@dbTools/typeorm' import Decimal from 'decimal.js-light' +import CONFIG from '@/config' -class EventProtocolEmitter extends EventEmitter { } +class EventProtocolEmitter extends EventEmitter { + public isEnabled() { + logger.info(`EventProtocol - isEnabled=${CONFIG.EVENT_PROTOCOL_ENABLED}`) + return CONFIG.EVENT_PROTOCOL_ENABLED + } +} export const eventProtocol = new EventProtocolEmitter() eventProtocol.on('error', (err) => { @@ -329,11 +335,11 @@ async function writeEvent( // eslint-disable-next-line no-unused-expressions amount ? (dbEvent.amount = amount) : null // set event values here when having the result ... - // await dbEvent.save() + // dbEvent.save() const queryRunner = getConnection().createQueryRunner('master') await queryRunner.connect() - await queryRunner.startTransaction('READ UNCOMMITTED') + await queryRunner.startTransaction('REPEATABLE READ') try { await queryRunner.manager.save(dbEvent).catch((error) => { logger.error('Error while saving dbEvent', error) @@ -348,4 +354,3 @@ async function writeEvent( await queryRunner.release() } } - diff --git a/backend/src/graphql/resolver/UserResolver.ts b/backend/src/graphql/resolver/UserResolver.ts index fed5530f8..0bf37e82e 100644 --- a/backend/src/graphql/resolver/UserResolver.ts +++ b/backend/src/graphql/resolver/UserResolver.ts @@ -387,26 +387,30 @@ export class UserResolver { logger.info('redeemCode found contributionLink=' + contributionLink) if (contributionLink) { dbUser.contributionLinkId = contributionLink.id - eventProtocol.emit( - EventProtocolType.REDEEM_REGISTER, - new Date(Date.now()), - dbUser.id, - null, - contributionLink.id, - ) + if (eventProtocol.isEnabled()) { + eventProtocol.emit( + EventProtocolType.REDEEM_REGISTER, + new Date(Date.now()), + dbUser.id, + null, + contributionLink.id, + ) + } } } else { const transactionLink = await dbTransactionLink.findOne({ code: redeemCode }) logger.info('redeemCode found transactionLink=' + transactionLink) if (transactionLink) { dbUser.referrerId = transactionLink.userId - eventProtocol.emit( - EventProtocolType.REDEEM_REGISTER, - new Date(Date.now()), - dbUser.id, - transactionLink.id, - null, - ) + if (eventProtocol.isEnabled()) { + eventProtocol.emit( + EventProtocolType.REDEEM_REGISTER, + new Date(Date.now()), + dbUser.id, + transactionLink.id, + null, + ) + } } } } @@ -461,8 +465,10 @@ export class UserResolver { await queryRunner.release() } logger.info('createUser() successful...') - eventProtocol.emit(EventProtocolType.REGISTER, new Date(Date.now()), dbUser.id) + if (eventProtocol.isEnabled()) { + eventProtocol.emit(EventProtocolType.REGISTER, new Date(Date.now()), dbUser.id) + } return new User(dbUser) } From d9034b1bdb9e5f8ee56124599feb66d8fa54488b Mon Sep 17 00:00:00 2001 From: Moriz Wahl Date: Fri, 1 Jul 2022 17:20:26 +0200 Subject: [PATCH 15/66] changes after session with claus peter --- backend/src/event/EventProtocolEmitter.ts | 330 +++++++++++-------- backend/src/graphql/resolver/UserResolver.ts | 47 +-- backend/src/graphql/schema.ts | 4 +- backend/src/seeds/graphql/mutations.ts | 3 + 4 files changed, 220 insertions(+), 164 deletions(-) diff --git a/backend/src/event/EventProtocolEmitter.ts b/backend/src/event/EventProtocolEmitter.ts index 4910bcdfa..404d1090b 100644 --- a/backend/src/event/EventProtocolEmitter.ts +++ b/backend/src/event/EventProtocolEmitter.ts @@ -1,8 +1,8 @@ import { EventEmitter } from 'events' import { backendLogger as logger } from '@/server/logger' -import { EventProtocolType } from './EventProtocolType' +// import { EventProtocolType } from './EventProtocolType' import { EventProtocol } from '@entity/EventProtocol' -import { getConnection } from '@dbTools/typeorm' +// import { getConnection } from '@dbTools/typeorm' import Decimal from 'decimal.js-light' import CONFIG from '@/config' @@ -18,34 +18,35 @@ eventProtocol.on('error', (err) => { logger.error(`ERROR in EventProtocol: ${err}`) }) -eventProtocol.on(EventProtocolType.BASIC, (createdAt: Date, userId: number) => { +/* +eventProtocol.on(EventProtocolType.BASIC, async (createdAt: Date, userId: number) => { logger.info( `EventProtocol - ${EventProtocolType.BASIC}: createdAt=${createdAt}, userId=${userId}`, ) - writeEvent(EventProtocolType.BASIC, createdAt, userId, null, null, null, null, null) + await writeEvent(EventProtocolType.BASIC, createdAt, userId, null, null, null, null, null) }) -eventProtocol.on(EventProtocolType.VISIT_GRADIDO, (createdAt: Date, userId: number) => { +eventProtocol.on(EventProtocolType.VISIT_GRADIDO, async (createdAt: Date, userId: number) => { logger.info( `EventProtocol - ${EventProtocolType.VISIT_GRADIDO}: createdAt=${createdAt}, userId=${userId}`, ) - writeEvent(EventProtocolType.VISIT_GRADIDO, createdAt, userId, null, null, null, null, null) + await writeEvent(EventProtocolType.VISIT_GRADIDO, createdAt, userId, null, null, null, null, null) }) -eventProtocol.on(EventProtocolType.REGISTER, (createdAt: Date, userId: number) => { +eventProtocol.on(EventProtocolType.REGISTER, async (createdAt: Date, userId: number) => { logger.info( `EventProtocol - ${EventProtocolType.REGISTER}: createdAt=${createdAt}, userId=${userId}`, ) - writeEvent(EventProtocolType.REGISTER, createdAt, userId, null, null, null, null, null) + await writeEvent(EventProtocolType.REGISTER, createdAt, userId, null, null, null, null, null) }) eventProtocol.on( EventProtocolType.REDEEM_REGISTER, - (createdAt: Date, userId: number, transactionId: number, contributionId: number) => { + async (createdAt: Date, userId: number, transactionId: number, contributionId: number) => { logger.info( `EventProtocol - ${EventProtocolType.REDEEM_REGISTER}: createdAt=${createdAt}, userId=${userId}, transactionId=${transactionId}, contributionId=${contributionId}`, ) - writeEvent( + await writeEvent( EventProtocolType.REDEEM_REGISTER, createdAt, userId, @@ -58,19 +59,12 @@ eventProtocol.on( }, ) -eventProtocol.on(EventProtocolType.INACTIVE_ACCOUNT, (createdAt: Date, userId: number) => { +eventProtocol.on(EventProtocolType.INACTIVE_ACCOUNT, async (createdAt: Date, userId: number) => { logger.info( `EventProtocol - ${EventProtocolType.INACTIVE_ACCOUNT}: createdAt=${createdAt}, userId=${userId}`, ) - writeEvent(EventProtocolType.INACTIVE_ACCOUNT, createdAt, userId, null, null, null, null, null) -}) - -eventProtocol.on(EventProtocolType.SEND_CONFIRMATION_EMAIL, (createdAt: Date, userId: number) => { - logger.info( - `EventProtocol - ${EventProtocolType.SEND_CONFIRMATION_EMAIL}: createdAt=${createdAt}, userId=${userId}`, - ) - writeEvent( - EventProtocolType.SEND_CONFIRMATION_EMAIL, + await writeEvent( + EventProtocolType.INACTIVE_ACCOUNT, createdAt, userId, null, @@ -81,43 +75,65 @@ eventProtocol.on(EventProtocolType.SEND_CONFIRMATION_EMAIL, (createdAt: Date, us ) }) -eventProtocol.on(EventProtocolType.CONFIRM_EMAIL, (createdAt: Date, userId: number) => { +eventProtocol.on( + EventProtocolType.SEND_CONFIRMATION_EMAIL, + async (createdAt: Date, userId: number) => { + logger.info( + `EventProtocol - ${EventProtocolType.SEND_CONFIRMATION_EMAIL}: createdAt=${createdAt}, userId=${userId}`, + ) + await writeEvent( + EventProtocolType.SEND_CONFIRMATION_EMAIL, + createdAt, + userId, + null, + null, + null, + null, + null, + ) + }, +) + +eventProtocol.on(EventProtocolType.CONFIRM_EMAIL, async (createdAt: Date, userId: number) => { logger.info( `EventProtocol - ${EventProtocolType.CONFIRM_EMAIL}: createdAt=${createdAt}, userId=${userId}`, ) - writeEvent(EventProtocolType.CONFIRM_EMAIL, createdAt, userId, null, null, null, null, null) + await writeEvent(EventProtocolType.CONFIRM_EMAIL, createdAt, userId, null, null, null, null, null) }) -eventProtocol.on(EventProtocolType.REGISTER_EMAIL_KLICKTIPP, (createdAt: Date, userId: number) => { - logger.info( - `EventProtocol - ${EventProtocolType.REGISTER_EMAIL_KLICKTIPP}: createdAt=${createdAt}, userId=${userId}`, - ) - writeEvent( - EventProtocolType.REGISTER_EMAIL_KLICKTIPP, - createdAt, - userId, - null, - null, - null, - null, - null, - ) -}) +eventProtocol.on( + EventProtocolType.REGISTER_EMAIL_KLICKTIPP, + async (createdAt: Date, userId: number) => { + logger.info( + `EventProtocol - ${EventProtocolType.REGISTER_EMAIL_KLICKTIPP}: createdAt=${createdAt}, userId=${userId}`, + ) + await writeEvent( + EventProtocolType.REGISTER_EMAIL_KLICKTIPP, + createdAt, + userId, + null, + null, + null, + null, + null, + ) + }, +) -eventProtocol.on(EventProtocolType.LOGIN, (createdAt: Date, userId: number) => { +eventProtocol.on(EventProtocolType.LOGIN, async (createdAt: Date, userId: number) => { logger.info( `EventProtocol - ${EventProtocolType.LOGIN}: createdAt=${createdAt}, userId=${userId}`, ) - writeEvent(EventProtocolType.LOGIN, createdAt, userId, null, null, null, null, null) + await writeEvent(EventProtocolType.LOGIN, createdAt, userId, null, null, null, null, null) }) eventProtocol.on( EventProtocolType.REDEEM_LOGIN, - (createdAt: Date, userId: number, transactionId: number, contributionId: number) => { + async (createdAt: Date, userId: number, transactionId: number, contributionId: number) => { logger.info( `EventProtocol - ${EventProtocolType.REDEEM_LOGIN}: createdAt=${createdAt}, userId=${userId}, transactionId=${transactionId}, contributionId=${contributionId}`, ) - writeEvent( + await writeEvent( EventProtocolType.REDEEM_LOGIN, createdAt, userId, @@ -130,33 +146,44 @@ eventProtocol.on( }, ) -eventProtocol.on(EventProtocolType.ACTIVATE_ACCOUNT, (createdAt: Date, userId: number) => { +eventProtocol.on(EventProtocolType.ACTIVATE_ACCOUNT, async (createdAt: Date, userId: number) => { logger.info( `EventProtocol - ${EventProtocolType.ACTIVATE_ACCOUNT}: createdAt=${createdAt}, userId=${userId}`, ) - writeEvent(EventProtocolType.ACTIVATE_ACCOUNT, createdAt, userId, null, null, null, null, null) + await writeEvent( + EventProtocolType.ACTIVATE_ACCOUNT, + createdAt, + userId, + null, + null, + null, + null, + null, + ) }) -eventProtocol.on(EventProtocolType.PASSWORD_CHANGE, (createdAt: Date, userId: number) => { +eventProtocol.on(EventProtocolType.PASSWORD_CHANGE, async (createdAt: Date, userId: number) => { logger.info( `EventProtocol - ${EventProtocolType.PASSWORD_CHANGE}: createdAt=${createdAt}, userId=${userId}`, ) - writeEvent(EventProtocolType.PASSWORD_CHANGE, createdAt, userId, null, null, null, null, null) + await writeEvent( + EventProtocolType.PASSWORD_CHANGE, + createdAt, + userId, + null, + null, + null, + null, + null, + ) }) -eventProtocol.on(EventProtocolType.TRANSACTION_SEND, (createdAt: Date, userId: number) => { +eventProtocol.on(EventProtocolType.TRANSACTION_SEND, async (createdAt: Date, userId: number) => { logger.info( `EventProtocol - ${EventProtocolType.TRANSACTION_SEND}: createdAt=${createdAt}, userId=${userId}`, ) - writeEvent(EventProtocolType.TRANSACTION_SEND, createdAt, userId, null, null, null, null, null) -}) - -eventProtocol.on(EventProtocolType.TRANSACTION_SEND_REDEEM, (createdAt: Date, userId: number) => { - logger.info( - `EventProtocol - ${EventProtocolType.TRANSACTION_SEND_REDEEM}: createdAt=${createdAt}, userId=${userId}`, - ) - writeEvent( - EventProtocolType.TRANSACTION_SEND_REDEEM, + await writeEvent( + EventProtocolType.TRANSACTION_SEND, createdAt, userId, null, @@ -167,13 +194,32 @@ eventProtocol.on(EventProtocolType.TRANSACTION_SEND_REDEEM, (createdAt: Date, us ) }) +eventProtocol.on( + EventProtocolType.TRANSACTION_SEND_REDEEM, + async (createdAt: Date, userId: number) => { + logger.info( + `EventProtocol - ${EventProtocolType.TRANSACTION_SEND_REDEEM}: createdAt=${createdAt}, userId=${userId}`, + ) + await writeEvent( + EventProtocolType.TRANSACTION_SEND_REDEEM, + createdAt, + userId, + null, + null, + null, + null, + null, + ) + }, +) + eventProtocol.on( EventProtocolType.TRANSACTION_REPEATE_REDEEM, - (createdAt: Date, userId: number) => { + async (createdAt: Date, userId: number) => { logger.info( `EventProtocol - ${EventProtocolType.TRANSACTION_REPEATE_REDEEM}: createdAt=${createdAt}, userId=${userId}`, ) - writeEvent( + await writeEvent( EventProtocolType.TRANSACTION_REPEATE_REDEEM, createdAt, userId, @@ -186,12 +232,31 @@ eventProtocol.on( }, ) -eventProtocol.on(EventProtocolType.TRANSACTION_CREATION, (createdAt: Date, userId: number) => { +eventProtocol.on( + EventProtocolType.TRANSACTION_CREATION, + async (createdAt: Date, userId: number) => { + logger.info( + `EventProtocol - ${EventProtocolType.TRANSACTION_CREATION}: createdAt=${createdAt}, userId=${userId}`, + ) + await writeEvent( + EventProtocolType.TRANSACTION_CREATION, + createdAt, + userId, + null, + null, + null, + null, + null, + ) + }, +) + +eventProtocol.on(EventProtocolType.TRANSACTION_RECEIVE, async (createdAt: Date, userId: number) => { logger.info( - `EventProtocol - ${EventProtocolType.TRANSACTION_CREATION}: createdAt=${createdAt}, userId=${userId}`, + `EventProtocol - ${EventProtocolType.TRANSACTION_RECEIVE}: createdAt=${createdAt}, userId=${userId}`, ) - writeEvent( - EventProtocolType.TRANSACTION_CREATION, + await writeEvent( + EventProtocolType.TRANSACTION_RECEIVE, createdAt, userId, null, @@ -202,20 +267,13 @@ eventProtocol.on(EventProtocolType.TRANSACTION_CREATION, (createdAt: Date, userI ) }) -eventProtocol.on(EventProtocolType.TRANSACTION_RECEIVE, (createdAt: Date, userId: number) => { - logger.info( - `EventProtocol - ${EventProtocolType.TRANSACTION_RECEIVE}: createdAt=${createdAt}, userId=${userId}`, - ) - writeEvent(EventProtocolType.TRANSACTION_RECEIVE, createdAt, userId, null, null, null, null, null) -}) - eventProtocol.on( EventProtocolType.TRANSACTION_RECEIVE_REDEEM, - (createdAt: Date, userId: number) => { + async (createdAt: Date, userId: number) => { logger.info( `EventProtocol - ${EventProtocolType.TRANSACTION_RECEIVE_REDEEM}: createdAt=${createdAt}, userId=${userId}`, ) - writeEvent( + await writeEvent( EventProtocolType.TRANSACTION_RECEIVE_REDEEM, createdAt, userId, @@ -230,11 +288,11 @@ eventProtocol.on( eventProtocol.on( EventProtocolType.CONTRIBUTION_CREATE, - (createdAt: Date, userId: number, contributionId: number) => { + async (createdAt: Date, userId: number, contributionId: number) => { logger.info( `EventProtocol - ${EventProtocolType.CONTRIBUTION_CREATE}: createdAt=${createdAt}, userId=${userId}, contributionId=${contributionId}`, ) - writeEvent( + await writeEvent( EventProtocolType.CONTRIBUTION_CREATE, createdAt, userId, @@ -249,7 +307,7 @@ eventProtocol.on( eventProtocol.on( EventProtocolType.CONTRIBUTION_CONFIRM, - ( + async ( createdAt: Date, userId: number, xUserId: number, @@ -259,7 +317,7 @@ eventProtocol.on( logger.info( `EventProtocol - ${EventProtocolType.CONTRIBUTION_CONFIRM}: createdAt=${createdAt}, userId=${userId}, xUserId=${xUserId}, xCommunityId=${xCommunityId}, contributionId=${contributionId}`, ) - writeEvent( + await writeEvent( EventProtocolType.CONTRIBUTION_CONFIRM, createdAt, userId, @@ -272,30 +330,14 @@ eventProtocol.on( }, ) -eventProtocol.on(EventProtocolType.CONTRIBUTION_LINK_DEFINE, (createdAt: Date, userId: number) => { - logger.info( - `EventProtocol - ${EventProtocolType.CONTRIBUTION_LINK_DEFINE}: createdAt=${createdAt}, userId=${userId}`, - ) - writeEvent( - EventProtocolType.CONTRIBUTION_LINK_DEFINE, - createdAt, - userId, - null, - null, - null, - null, - null, - ) -}) - eventProtocol.on( - EventProtocolType.CONTRIBUTION_LINK_ACTIVATE_REDEEM, - (createdAt: Date, userId: number) => { + EventProtocolType.CONTRIBUTION_LINK_DEFINE, + async (createdAt: Date, userId: number) => { logger.info( - `EventProtocol - ${EventProtocolType.CONTRIBUTION_LINK_ACTIVATE_REDEEM}: createdAt=${createdAt}, userId=${userId}`, + `EventProtocol - ${EventProtocolType.CONTRIBUTION_LINK_DEFINE}: createdAt=${createdAt}, userId=${userId}`, ) - writeEvent( - EventProtocolType.CONTRIBUTION_LINK_ACTIVATE_REDEEM, + await writeEvent( + EventProtocolType.CONTRIBUTION_LINK_DEFINE, createdAt, userId, null, @@ -307,50 +349,58 @@ eventProtocol.on( }, ) -async function writeEvent( - type: string, - createdAt: Date, - userId: number, - xUserId: number | null, - xCommunityId: number | null, - transactionId: number | null, - contributionId: number | null, - amount: Decimal | null, -) { - logger.info( - `writeEvent(type=${type}, createdAt=${createdAt}, userId=${userId}, xUserId=${xUserId}, xCommunityId=${xCommunityId}, contributionId=${contributionId}, transactionId=${transactionId}, amount=${amount})`, - ) - const dbEvent = new EventProtocol() - dbEvent.type = type - dbEvent.createdAt = createdAt - dbEvent.userId = userId - // eslint-disable-next-line no-unused-expressions - xUserId ? (dbEvent.xUserId = xUserId) : null - // eslint-disable-next-line no-unused-expressions - xCommunityId ? (dbEvent.xCommunityId = xCommunityId) : null - // eslint-disable-next-line no-unused-expressions - contributionId ? (dbEvent.contributionId = contributionId) : null - // eslint-disable-next-line no-unused-expressions - transactionId ? (dbEvent.transactionId = transactionId) : null - // eslint-disable-next-line no-unused-expressions - amount ? (dbEvent.amount = amount) : null - // set event values here when having the result ... - // dbEvent.save() +eventProtocol.on( + EventProtocolType.CONTRIBUTION_LINK_ACTIVATE_REDEEM, + async (createdAt: Date, userId: number) => { + logger.info( + `EventProtocol - ${EventProtocolType.CONTRIBUTION_LINK_ACTIVATE_REDEEM}: createdAt=${createdAt}, userId=${userId}`, + ) + await writeEvent( + EventProtocolType.CONTRIBUTION_LINK_ACTIVATE_REDEEM, + createdAt, + userId, + null, + null, + null, + null, + null, + ) + }, +) +*/ - const queryRunner = getConnection().createQueryRunner('master') - await queryRunner.connect() - await queryRunner.startTransaction('REPEATABLE READ') - try { - await queryRunner.manager.save(dbEvent).catch((error) => { - logger.error('Error while saving dbEvent', error) - throw new Error('error saving eventProtocol entry') - }) - await queryRunner.commitTransaction() - } catch (e) { - logger.error(`error during write event with ${e}`) - await queryRunner.rollbackTransaction() - throw e - } finally { - await queryRunner.release() - } +export interface EventInterface { + type: string + createdAt: Date + userId: number + xUserId?: number + xCommunityId?: number + transactionId?: number + contributionId?: number + amount?: Decimal +} + +eventProtocol.on('writeEvents', async (events: EventInterface[]) => { + for (let i = 0; i < events.length; i++) { + await writeEvent(events[i]) + } +}) + +eventProtocol.on('writeEvent', async (event: EventInterface) => { + await writeEvent(event) +}) + +const writeEvent = async (event: EventInterface): Promise => { + // if (!eventProtocol.isEnabled()) return + logger.info(`writeEvent(${JSON.stringify(event)})`) + const dbEvent = new EventProtocol() + dbEvent.type = event.type + dbEvent.createdAt = event.createdAt + dbEvent.userId = event.userId + if (event.xUserId) dbEvent.xUserId = event.xUserId + if (event.xCommunityId) dbEvent.xCommunityId = event.xCommunityId + if (event.contributionId) dbEvent.contributionId = event.contributionId + if (event.transactionId) dbEvent.transactionId = event.transactionId + if (event.amount) dbEvent.amount = event.amount + await dbEvent.save() } diff --git a/backend/src/graphql/resolver/UserResolver.ts b/backend/src/graphql/resolver/UserResolver.ts index 0bf37e82e..f7ccb170b 100644 --- a/backend/src/graphql/resolver/UserResolver.ts +++ b/backend/src/graphql/resolver/UserResolver.ts @@ -292,7 +292,11 @@ export class UserResolver { key: 'token', value: encode(dbUser.pubKey), }) - eventProtocol.emit(EventProtocolType.LOGIN, new Date(Date.now()), user.id) + eventProtocol.emit('writeEvent', { + type: EventProtocolType.LOGIN, + createdAt: new Date(), + userId: user.id, + }) logger.info('successful Login:' + user) return user } @@ -387,30 +391,26 @@ export class UserResolver { logger.info('redeemCode found contributionLink=' + contributionLink) if (contributionLink) { dbUser.contributionLinkId = contributionLink.id - if (eventProtocol.isEnabled()) { - eventProtocol.emit( - EventProtocolType.REDEEM_REGISTER, - new Date(Date.now()), - dbUser.id, - null, - contributionLink.id, - ) - } + /* eventProtocol.emit( + EventProtocolType.REDEEM_REGISTER, + new Date(Date.now()), + dbUser.id, + null, + contributionLink.id, + ) */ } } else { const transactionLink = await dbTransactionLink.findOne({ code: redeemCode }) logger.info('redeemCode found transactionLink=' + transactionLink) if (transactionLink) { dbUser.referrerId = transactionLink.userId - if (eventProtocol.isEnabled()) { - eventProtocol.emit( - EventProtocolType.REDEEM_REGISTER, - new Date(Date.now()), - dbUser.id, - transactionLink.id, - null, - ) - } + /* eventProtocol.emit( + EventProtocolType.REDEEM_REGISTER, + new Date(Date.now()), + dbUser.id, + transactionLink.id, + null, + ) */ } } } @@ -466,9 +466,12 @@ export class UserResolver { } logger.info('createUser() successful...') - if (eventProtocol.isEnabled()) { - eventProtocol.emit(EventProtocolType.REGISTER, new Date(Date.now()), dbUser.id) - } + eventProtocol.emit('writeEvent', { + type: EventProtocolType.REGISTER, + createdAt: new Date(), + userId: dbUser.id, + }) + return new User(dbUser) } diff --git a/backend/src/graphql/schema.ts b/backend/src/graphql/schema.ts index 6b1579ea4..5e7dfcf0a 100644 --- a/backend/src/graphql/schema.ts +++ b/backend/src/graphql/schema.ts @@ -1,7 +1,7 @@ import { GraphQLSchema } from 'graphql' import { buildSchema } from 'type-graphql' import path from 'path' -import { EventHandler } from '@/middleware/EventHandler' +// import { EventHandler } from '@/middleware/EventHandler' import isAuthorized from './directive/isAuthorized' import DecimalScalar from './scalar/Decimal' @@ -12,7 +12,7 @@ const schema = async (): Promise => { resolvers: [path.join(__dirname, 'resolver', `!(*.test).{js,ts}`)], authChecker: isAuthorized, scalarsMap: [{ type: Decimal, scalar: DecimalScalar }], - globalMiddlewares: [EventHandler], + // globalMiddlewares: [EventHandler], }) } diff --git a/backend/src/seeds/graphql/mutations.ts b/backend/src/seeds/graphql/mutations.ts index 3895a98b8..e316a37c1 100644 --- a/backend/src/seeds/graphql/mutations.ts +++ b/backend/src/seeds/graphql/mutations.ts @@ -230,6 +230,8 @@ export const deleteContributionLink = gql` deleteContributionLink(id: $id) } ` + +/* export const createEventProtocol = gql` mutation ( $type: String! @@ -261,3 +263,4 @@ export const createEventProtocol = gql` } } ` +*/ From 9816adc745323d3b0922113d913449ba1bef5a3e Mon Sep 17 00:00:00 2001 From: Moriz Wahl Date: Fri, 1 Jul 2022 17:24:51 +0200 Subject: [PATCH 16/66] remove unused global middleware --- backend/src/graphql/schema.ts | 2 -- backend/src/middleware/EventHandler.ts | 15 --------------- 2 files changed, 17 deletions(-) delete mode 100644 backend/src/middleware/EventHandler.ts diff --git a/backend/src/graphql/schema.ts b/backend/src/graphql/schema.ts index 5e7dfcf0a..f14f45efa 100644 --- a/backend/src/graphql/schema.ts +++ b/backend/src/graphql/schema.ts @@ -1,7 +1,6 @@ import { GraphQLSchema } from 'graphql' import { buildSchema } from 'type-graphql' import path from 'path' -// import { EventHandler } from '@/middleware/EventHandler' import isAuthorized from './directive/isAuthorized' import DecimalScalar from './scalar/Decimal' @@ -12,7 +11,6 @@ const schema = async (): Promise => { resolvers: [path.join(__dirname, 'resolver', `!(*.test).{js,ts}`)], authChecker: isAuthorized, scalarsMap: [{ type: Decimal, scalar: DecimalScalar }], - // globalMiddlewares: [EventHandler], }) } diff --git a/backend/src/middleware/EventHandler.ts b/backend/src/middleware/EventHandler.ts deleted file mode 100644 index 35b9d0b7b..000000000 --- a/backend/src/middleware/EventHandler.ts +++ /dev/null @@ -1,15 +0,0 @@ -import { MiddlewareFn } from 'type-graphql' -import { EventProtocol } from '@entity/EventProtocol' - -export const EventHandler: MiddlewareFn = async ( - /* eslint-disable-next-line @typescript-eslint/no-unused-vars */ - { root, args, context, info }, - next, -) => { - const event = new EventProtocol() - // set values before calling the resolver here - const result = await next() - // set event values here when having the result ... - await event.save() - return result -} From 2e2a84f5356f3ab1e619e669522cd0aa7e5de525 Mon Sep 17 00:00:00 2001 From: Moriz Wahl Date: Fri, 1 Jul 2022 17:26:20 +0200 Subject: [PATCH 17/66] remove unused mutation --- backend/src/seeds/graphql/mutations.ts | 34 -------------------------- 1 file changed, 34 deletions(-) diff --git a/backend/src/seeds/graphql/mutations.ts b/backend/src/seeds/graphql/mutations.ts index e316a37c1..f2edf0821 100644 --- a/backend/src/seeds/graphql/mutations.ts +++ b/backend/src/seeds/graphql/mutations.ts @@ -230,37 +230,3 @@ export const deleteContributionLink = gql` deleteContributionLink(id: $id) } ` - -/* -export const createEventProtocol = gql` - mutation ( - $type: String! - $userId: Int! - $xUserId: Int - $xCommunityId: Int - $transactionId: Int - $contributionId: Int - $amount: Decimal - ) { - createEventProtocol( - type: $type - userId: $userId - xUserId: $xUserId - xCommunityId: $xCommunityId - transactionId: $transactionId - contributionId: $contributionId - amount: $amount - ) { - id - type - createdAt - userId - xUserId - xCommunityId - transactionId - contributionId - amount - } - } -` -*/ From a99a568f391b9ea16ed5ee354c03260364d392fd Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Claus-Peter=20H=C3=BCbner?= Date: Tue, 5 Jul 2022 04:20:54 +0200 Subject: [PATCH 18/66] emit Redeem-Events --- backend/src/graphql/model/Event.ts | 57 ++++++++++++++++++++ backend/src/graphql/resolver/UserResolver.ts | 15 +++++- 2 files changed, 70 insertions(+), 2 deletions(-) create mode 100644 backend/src/graphql/model/Event.ts diff --git a/backend/src/graphql/model/Event.ts b/backend/src/graphql/model/Event.ts new file mode 100644 index 000000000..a8c0ef885 --- /dev/null +++ b/backend/src/graphql/model/Event.ts @@ -0,0 +1,57 @@ +import { ObjectType, Field } from 'type-graphql' +import { EventProtocol } from '@entity/EventProtocol' +import { EventProtocolType } from '@/event/EventProtocolType' +import Decimal from 'decimal.js-light' + +export interface EventInterface { + type: string + createdAt: Date + userId: number + xUserId?: number + xCommunityId?: number + transactionId?: number + contributionId?: number + amount?: Decimal +} + +@ObjectType() +export class Event { + constructor(event: EventProtocol) { + this.id = event.id + this.type = event.type + this.createdAt = event.createdAt + this.userId = event.userId + this.xUserId = event.xUserId + this.xCommunityId = event.xCommunityId + this.transactionId = event.transactionId + this.contributionId = event.contributionId + this.amount = event.amount + } + + @Field(() => Number) + id: number + + @Field(() => EventProtocolType) + type: string + + @Field(() => Date) + createdAt: Date + + @Field(() => Number) + userId: number + + @Field(() => Number, { nullable: true }) + xUserId: number | null + + @Field(() => Number, { nullable: true }) + xCommunityId: number | null + + @Field(() => Number, { nullable: true }) + transactionId: number | null + + @Field(() => Number, { nullable: true }) + contributionId: number | null + + @Field(() => Decimal) + amount: Decimal | null +} diff --git a/backend/src/graphql/resolver/UserResolver.ts b/backend/src/graphql/resolver/UserResolver.ts index f7ccb170b..ea4006779 100644 --- a/backend/src/graphql/resolver/UserResolver.ts +++ b/backend/src/graphql/resolver/UserResolver.ts @@ -23,7 +23,7 @@ import { sendAccountMultiRegistrationEmail } from '@/mailer/sendAccountMultiRegi import { klicktippSignIn } from '@/apis/KlicktippController' import { RIGHTS } from '@/auth/RIGHTS' import { hasElopageBuys } from '@/util/hasElopageBuys' -import { eventProtocol } from '@/event/EventProtocolEmitter' +import { EventInterface, eventProtocol } from '@/event/EventProtocolEmitter' import { EventProtocolType } from '@/event/EventProtocolType' // eslint-disable-next-line @typescript-eslint/no-var-requires @@ -374,6 +374,9 @@ export class UserResolver { // const encryptedPrivkey = SecretKeyCryptographyEncrypt(keyPair[1], passwordHash[1]) const emailHash = getEmailHash(email) + let eventType = EventProtocolType.REGISTER + let eventContributionId = null + let eventTransactionId = null const dbUser = new DbUser() dbUser.email = email dbUser.firstName = firstName @@ -391,6 +394,8 @@ export class UserResolver { logger.info('redeemCode found contributionLink=' + contributionLink) if (contributionLink) { dbUser.contributionLinkId = contributionLink.id + eventType = EventProtocolType.REDEEM_REGISTER + eventContributionId = contributionLink.id /* eventProtocol.emit( EventProtocolType.REDEEM_REGISTER, new Date(Date.now()), @@ -404,6 +409,8 @@ export class UserResolver { logger.info('redeemCode found transactionLink=' + transactionLink) if (transactionLink) { dbUser.referrerId = transactionLink.userId + eventType = EventProtocolType.REDEEM_REGISTER + eventTransactionId = transactionLink.id /* eventProtocol.emit( EventProtocolType.REDEEM_REGISTER, new Date(Date.now()), @@ -467,9 +474,13 @@ export class UserResolver { logger.info('createUser() successful...') eventProtocol.emit('writeEvent', { - type: EventProtocolType.REGISTER, + type: eventType, createdAt: new Date(), userId: dbUser.id, + xUserId: null, + xCommunityId: null, + transactionId: eventTransactionId, + contributionId: eventContributionId, }) return new User(dbUser) From 3f706dc5f09deb3ff35513268dd215cf39349e1e Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Claus-Peter=20H=C3=BCbner?= Date: Wed, 6 Jul 2022 02:30:04 +0200 Subject: [PATCH 19/66] add EventType specific handling --- backend/src/event/Event.ts | 314 +++++++++++++++++++++++++++++ backend/src/graphql/model/Event.ts | 57 ------ 2 files changed, 314 insertions(+), 57 deletions(-) create mode 100644 backend/src/event/Event.ts delete mode 100644 backend/src/graphql/model/Event.ts diff --git a/backend/src/event/Event.ts b/backend/src/event/Event.ts new file mode 100644 index 000000000..acfb43519 --- /dev/null +++ b/backend/src/event/Event.ts @@ -0,0 +1,314 @@ +import { EventProtocol } from '@entity/EventProtocol' +import decimal from 'decimal.js-light' +import { EventProtocolType } from './EventProtocolType' + +/* +export interface EventInterface { + type: string + createdAt: Date + userId: number + xUserId?: number + xCommunityId?: number + transactionId?: number + contributionId?: number + amount?: Decimal +} +*/ + +export class EventBasic { + type: string + createdAt: Date +} +export class EventBasicUserId extends EventBasic { + userId: number +} + +export class EventBasicTx extends EventBasicUserId { + xUserId: number + xCommunityId: number + transactionId: number + amount: decimal +} + +export class EventBasicCt extends EventBasicUserId { + contributionId: number + amount: decimal +} + +export class EventBasicRedeem extends EventBasicUserId { + transactionId?: number + contributionId?: number +} + +export class EventVisitGradido extends EventBasic { } +export class EventRegister extends EventBasicUserId { } +export class EventRedeemRegister extends EventBasicRedeem { } +export class EventInactiveAccount extends EventBasicUserId { } +export class EventSendConfirmationEmail extends EventBasicUserId { } +export class EventConfirmationEmail extends EventBasicUserId { } +export class EventRegisterEmailKlicktipp extends EventBasicUserId { } +export class EventLogin extends EventBasicUserId { } +export class EventRedeemLogin extends EventBasicRedeem { } +export class EventActivateAccount extends EventBasicUserId { } +export class EventPasswordChange extends EventBasicUserId { } +export class EventTransactionSend extends EventBasicTx { } +export class EventTransactionSendRedeem extends EventBasicTx { } +export class EventTransactionRepeateRedeem extends EventBasicTx { } +export class EventTransactionCreation extends EventBasicUserId { + transactionId: number + amount: decimal +} +export class EventTransactionReceive extends EventBasicTx { } +export class EventTransactionReceiveRedeem extends EventBasicTx { } +export class EventContributionCreate extends EventBasicCt { } +export class EventContributionConfirm extends EventBasicCt { + xUserId: number + xCommunityId: number +} +export class EventContributionLinkDefine extends EventBasicCt { } +export class EventContributionLinkActivateRedeem extends EventBasicCt { } + +export class Event { + constructor() + constructor(event?: EventProtocol) { + if (event) { + this.id = event.id + this.type = event.type + this.createdAt = event.createdAt + this.userId = event.userId + this.xUserId = event.xUserId + this.xCommunityId = event.xCommunityId + this.transactionId = event.transactionId + this.contributionId = event.contributionId + this.amount = event.amount + } + } + + public setEventBasic(ev?: EventBasic): Event { + this.type = EventProtocolType.BASIC + this.createdAt = new Date() + + return this + } + + public setEventVisitGradido(ev?: EventVisitGradido): Event { + this.setEventBasic(ev) + this.type = EventProtocolType.VISIT_GRADIDO + + return this + } + + public setEventRegister(ev: EventRegister): Event { + this.setByBasicUser(ev.userId) + this.type = EventProtocolType.REGISTER + + return this + } + + public setEventRedeemRegister(ev: EventRedeemRegister): Event { + this.setByBasicRedeem(ev.userId, ev.transactionId, ev.contributionId) + this.type = EventProtocolType.REDEEM_REGISTER + + return this + } + + public setEventInactiveAccount(ev: EventInactiveAccount): Event { + this.setByBasicUser(ev.userId) + this.type = EventProtocolType.INACTIVE_ACCOUNT + + return this + } + + public setEventSendConfirmationEmail(ev: EventSendConfirmationEmail): Event { + this.setByBasicUser(ev.userId) + this.type = EventProtocolType.SEND_CONFIRMATION_EMAIL + + return this + } + + public setEventConfirmationEmail(ev: EventConfirmationEmail): Event { + this.setByBasicUser(ev.userId) + this.type = EventProtocolType.CONFIRM_EMAIL + + return this + } + + public setEventRegisterEmailKlicktipp(ev: EventRegisterEmailKlicktipp): Event { + this.setByBasicUser(ev.userId) + this.type = EventProtocolType.REGISTER_EMAIL_KLICKTIPP + + return this + } + + public setEventLogin(ev: EventLogin): Event { + this.setByBasicUser(ev.userId) + this.type = EventProtocolType.LOGIN + + return this + } + + public setEventRedeemLogin(ev: EventRedeemLogin): Event { + this.setByBasicRedeem(ev.userId, ev.transactionId, ev.contributionId) + this.type = EventProtocolType.REDEEM_LOGIN + + return this + } + + public setEventActivateAccount(ev: EventActivateAccount): Event { + this.setByBasicUser(ev.userId) + this.type = EventProtocolType.ACTIVATE_ACCOUNT + + return this + } + + public setEventPasswordChange(ev: EventPasswordChange): Event { + this.setByBasicUser(ev.userId) + this.type = EventProtocolType.PASSWORD_CHANGE + + return this + } + + public setEventTransactionSend(ev: EventTransactionSend): Event { + this.setByBasicTx(ev.userId, ev.xUserId, ev.xCommunityId, ev.transactionId, ev.amount) + this.type = EventProtocolType.TRANSACTION_SEND + + return this + } + + public setEventTransactionSendRedeem(ev: EventTransactionSendRedeem): Event { + this.setByBasicTx(ev.userId, ev.xUserId, ev.xCommunityId, ev.transactionId, ev.amount) + this.type = EventProtocolType.TRANSACTION_SEND_REDEEM + + return this + } + + public setEventTransactionRepeateRedeem(ev: EventTransactionRepeateRedeem): Event { + this.setByBasicTx(ev.userId, ev.xUserId, ev.xCommunityId, ev.transactionId, ev.amount) + this.type = EventProtocolType.TRANSACTION_REPEATE_REDEEM + + return this + } + + public setEventTransactionCreation(ev: EventTransactionCreation): Event { + this.setByBasicUser(ev.userId) + if (ev.transactionId) this.transactionId = ev.transactionId + if (ev.amount) this.amount = ev.amount + this.type = EventProtocolType.TRANSACTION_CREATION + + return this + } + + public setEventTransactionReceive(ev: EventTransactionReceive): Event { + this.setByBasicTx(ev.userId, ev.xUserId, ev.xCommunityId, ev.transactionId, ev.amount) + this.type = EventProtocolType.TRANSACTION_RECEIVE + + return this + } + + public setEventTransactionReceiveRedeem(ev: EventTransactionReceiveRedeem): Event { + this.setByBasicTx(ev.userId, ev.xUserId, ev.xCommunityId, ev.transactionId, ev.amount) + this.type = EventProtocolType.TRANSACTION_RECEIVE_REDEEM + + return this + } + + public setEventContributionCreate(ev: EventContributionCreate): Event { + this.setByBasicCt(ev.userId, ev.contributionId, ev.amount) + this.type = EventProtocolType.CONTRIBUTION_CREATE + + return this + } + + 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.type = EventProtocolType.CONTRIBUTION_CONFIRM + + return this + } + + public setEventContributionLinkDefine(ev: EventContributionLinkDefine): Event { + this.setByBasicCt(ev.userId, ev.contributionId, ev.amount) + this.type = EventProtocolType.CONTRIBUTION_LINK_DEFINE + + return this + } + + public setEventContributionLinkActivateRedeem(ev: EventContributionLinkActivateRedeem): Event { + this.setByBasicCt(ev.userId, ev.contributionId, ev.amount) + this.type = EventProtocolType.CONTRIBUTION_LINK_ACTIVATE_REDEEM + + return this + } + + setByBasicUser(userId: number): Event { + this.setEventBasic() + this.userId = userId + + return this + } + + setByBasicTx( + userId: number, + xUserId?: number, + xCommunityId?: number, + transactionId?: number, + amount?: decimal, + ): Event { + this.setByBasicUser(userId) + if (xUserId) this.xUserId = xUserId + if (xCommunityId) this.xCommunityId = xCommunityId + if (transactionId) this.transactionId = transactionId + if (amount) this.amount = amount + + return this + } + + setByBasicCt(userId: number, contributionId: number, amount?: decimal): Event { + this.setByBasicUser(userId) + 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 + if (contributionId) this.contributionId = contributionId + + return this + } + + setByEventTransactionCreation(event: EventTransactionCreation): Event { + this.type = event.type + this.createdAt = event.createdAt + this.userId = event.userId + this.transactionId = event.transactionId + this.amount = event.amount + + return this + } + + setByEventContributionConfirm(event: EventContributionConfirm): Event { + this.type = event.type + this.createdAt = event.createdAt + this.userId = event.userId + this.xUserId = event.xUserId + this.xCommunityId = event.xCommunityId + this.amount = event.amount + + return this + } + + id: number + type: string + createdAt: Date + userId: number + xUserId?: number + xCommunityId?: number + transactionId?: number + contributionId?: number + amount?: decimal +} diff --git a/backend/src/graphql/model/Event.ts b/backend/src/graphql/model/Event.ts deleted file mode 100644 index a8c0ef885..000000000 --- a/backend/src/graphql/model/Event.ts +++ /dev/null @@ -1,57 +0,0 @@ -import { ObjectType, Field } from 'type-graphql' -import { EventProtocol } from '@entity/EventProtocol' -import { EventProtocolType } from '@/event/EventProtocolType' -import Decimal from 'decimal.js-light' - -export interface EventInterface { - type: string - createdAt: Date - userId: number - xUserId?: number - xCommunityId?: number - transactionId?: number - contributionId?: number - amount?: Decimal -} - -@ObjectType() -export class Event { - constructor(event: EventProtocol) { - this.id = event.id - this.type = event.type - this.createdAt = event.createdAt - this.userId = event.userId - this.xUserId = event.xUserId - this.xCommunityId = event.xCommunityId - this.transactionId = event.transactionId - this.contributionId = event.contributionId - this.amount = event.amount - } - - @Field(() => Number) - id: number - - @Field(() => EventProtocolType) - type: string - - @Field(() => Date) - createdAt: Date - - @Field(() => Number) - userId: number - - @Field(() => Number, { nullable: true }) - xUserId: number | null - - @Field(() => Number, { nullable: true }) - xCommunityId: number | null - - @Field(() => Number, { nullable: true }) - transactionId: number | null - - @Field(() => Number, { nullable: true }) - contributionId: number | null - - @Field(() => Decimal) - amount: Decimal | null -} From 314e211a4f6f3602bfe42bc521b985bf4dbf873c Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Claus-Peter=20H=C3=BCbner?= Date: Wed, 6 Jul 2022 02:30:52 +0200 Subject: [PATCH 20/66] modify EventEmitter to new Eventtype specific handling --- backend/src/event/EventProtocolEmitter.ts | 380 +--------------------- 1 file changed, 14 insertions(+), 366 deletions(-) diff --git a/backend/src/event/EventProtocolEmitter.ts b/backend/src/event/EventProtocolEmitter.ts index 404d1090b..d4ecea27a 100644 --- a/backend/src/event/EventProtocolEmitter.ts +++ b/backend/src/event/EventProtocolEmitter.ts @@ -1,12 +1,22 @@ import { EventEmitter } from 'events' +import { Event } from '@/event/Event' import { backendLogger as logger } from '@/server/logger' // import { EventProtocolType } from './EventProtocolType' import { EventProtocol } from '@entity/EventProtocol' // import { getConnection } from '@dbTools/typeorm' -import Decimal from 'decimal.js-light' import CONFIG from '@/config' class EventProtocolEmitter extends EventEmitter { + private events: Event[] + + public addEvent(event: Event) { + this.events.push(event) + } + + public getEvents(): Event[] { + return this.events + } + public isEnabled() { logger.info(`EventProtocol - isEnabled=${CONFIG.EVENT_PROTOCOL_ENABLED}`) return CONFIG.EVENT_PROTOCOL_ENABLED @@ -18,379 +28,17 @@ eventProtocol.on('error', (err) => { logger.error(`ERROR in EventProtocol: ${err}`) }) -/* -eventProtocol.on(EventProtocolType.BASIC, async (createdAt: Date, userId: number) => { - logger.info( - `EventProtocol - ${EventProtocolType.BASIC}: createdAt=${createdAt}, userId=${userId}`, - ) - await writeEvent(EventProtocolType.BASIC, createdAt, userId, null, null, null, null, null) -}) - -eventProtocol.on(EventProtocolType.VISIT_GRADIDO, async (createdAt: Date, userId: number) => { - logger.info( - `EventProtocol - ${EventProtocolType.VISIT_GRADIDO}: createdAt=${createdAt}, userId=${userId}`, - ) - await writeEvent(EventProtocolType.VISIT_GRADIDO, createdAt, userId, null, null, null, null, null) -}) - -eventProtocol.on(EventProtocolType.REGISTER, async (createdAt: Date, userId: number) => { - logger.info( - `EventProtocol - ${EventProtocolType.REGISTER}: createdAt=${createdAt}, userId=${userId}`, - ) - await writeEvent(EventProtocolType.REGISTER, createdAt, userId, null, null, null, null, null) -}) - -eventProtocol.on( - EventProtocolType.REDEEM_REGISTER, - async (createdAt: Date, userId: number, transactionId: number, contributionId: number) => { - logger.info( - `EventProtocol - ${EventProtocolType.REDEEM_REGISTER}: createdAt=${createdAt}, userId=${userId}, transactionId=${transactionId}, contributionId=${contributionId}`, - ) - await writeEvent( - EventProtocolType.REDEEM_REGISTER, - createdAt, - userId, - null, - null, - transactionId, - contributionId, - null, - ) - }, -) - -eventProtocol.on(EventProtocolType.INACTIVE_ACCOUNT, async (createdAt: Date, userId: number) => { - logger.info( - `EventProtocol - ${EventProtocolType.INACTIVE_ACCOUNT}: createdAt=${createdAt}, userId=${userId}`, - ) - await writeEvent( - EventProtocolType.INACTIVE_ACCOUNT, - createdAt, - userId, - null, - null, - null, - null, - null, - ) -}) - -eventProtocol.on( - EventProtocolType.SEND_CONFIRMATION_EMAIL, - async (createdAt: Date, userId: number) => { - logger.info( - `EventProtocol - ${EventProtocolType.SEND_CONFIRMATION_EMAIL}: createdAt=${createdAt}, userId=${userId}`, - ) - await writeEvent( - EventProtocolType.SEND_CONFIRMATION_EMAIL, - createdAt, - userId, - null, - null, - null, - null, - null, - ) - }, -) - -eventProtocol.on(EventProtocolType.CONFIRM_EMAIL, async (createdAt: Date, userId: number) => { - logger.info( - `EventProtocol - ${EventProtocolType.CONFIRM_EMAIL}: createdAt=${createdAt}, userId=${userId}`, - ) - await writeEvent(EventProtocolType.CONFIRM_EMAIL, createdAt, userId, null, null, null, null, null) -}) - -eventProtocol.on( - EventProtocolType.REGISTER_EMAIL_KLICKTIPP, - async (createdAt: Date, userId: number) => { - logger.info( - `EventProtocol - ${EventProtocolType.REGISTER_EMAIL_KLICKTIPP}: createdAt=${createdAt}, userId=${userId}`, - ) - await writeEvent( - EventProtocolType.REGISTER_EMAIL_KLICKTIPP, - createdAt, - userId, - null, - null, - null, - null, - null, - ) - }, -) - -eventProtocol.on(EventProtocolType.LOGIN, async (createdAt: Date, userId: number) => { - logger.info( - `EventProtocol - ${EventProtocolType.LOGIN}: createdAt=${createdAt}, userId=${userId}`, - ) - await writeEvent(EventProtocolType.LOGIN, createdAt, userId, null, null, null, null, null) -}) - -eventProtocol.on( - EventProtocolType.REDEEM_LOGIN, - async (createdAt: Date, userId: number, transactionId: number, contributionId: number) => { - logger.info( - `EventProtocol - ${EventProtocolType.REDEEM_LOGIN}: createdAt=${createdAt}, userId=${userId}, transactionId=${transactionId}, contributionId=${contributionId}`, - ) - await writeEvent( - EventProtocolType.REDEEM_LOGIN, - createdAt, - userId, - null, - null, - transactionId, - contributionId, - null, - ) - }, -) - -eventProtocol.on(EventProtocolType.ACTIVATE_ACCOUNT, async (createdAt: Date, userId: number) => { - logger.info( - `EventProtocol - ${EventProtocolType.ACTIVATE_ACCOUNT}: createdAt=${createdAt}, userId=${userId}`, - ) - await writeEvent( - EventProtocolType.ACTIVATE_ACCOUNT, - createdAt, - userId, - null, - null, - null, - null, - null, - ) -}) - -eventProtocol.on(EventProtocolType.PASSWORD_CHANGE, async (createdAt: Date, userId: number) => { - logger.info( - `EventProtocol - ${EventProtocolType.PASSWORD_CHANGE}: createdAt=${createdAt}, userId=${userId}`, - ) - await writeEvent( - EventProtocolType.PASSWORD_CHANGE, - createdAt, - userId, - null, - null, - null, - null, - null, - ) -}) - -eventProtocol.on(EventProtocolType.TRANSACTION_SEND, async (createdAt: Date, userId: number) => { - logger.info( - `EventProtocol - ${EventProtocolType.TRANSACTION_SEND}: createdAt=${createdAt}, userId=${userId}`, - ) - await writeEvent( - EventProtocolType.TRANSACTION_SEND, - createdAt, - userId, - null, - null, - null, - null, - null, - ) -}) - -eventProtocol.on( - EventProtocolType.TRANSACTION_SEND_REDEEM, - async (createdAt: Date, userId: number) => { - logger.info( - `EventProtocol - ${EventProtocolType.TRANSACTION_SEND_REDEEM}: createdAt=${createdAt}, userId=${userId}`, - ) - await writeEvent( - EventProtocolType.TRANSACTION_SEND_REDEEM, - createdAt, - userId, - null, - null, - null, - null, - null, - ) - }, -) - -eventProtocol.on( - EventProtocolType.TRANSACTION_REPEATE_REDEEM, - async (createdAt: Date, userId: number) => { - logger.info( - `EventProtocol - ${EventProtocolType.TRANSACTION_REPEATE_REDEEM}: createdAt=${createdAt}, userId=${userId}`, - ) - await writeEvent( - EventProtocolType.TRANSACTION_REPEATE_REDEEM, - createdAt, - userId, - null, - null, - null, - null, - null, - ) - }, -) - -eventProtocol.on( - EventProtocolType.TRANSACTION_CREATION, - async (createdAt: Date, userId: number) => { - logger.info( - `EventProtocol - ${EventProtocolType.TRANSACTION_CREATION}: createdAt=${createdAt}, userId=${userId}`, - ) - await writeEvent( - EventProtocolType.TRANSACTION_CREATION, - createdAt, - userId, - null, - null, - null, - null, - null, - ) - }, -) - -eventProtocol.on(EventProtocolType.TRANSACTION_RECEIVE, async (createdAt: Date, userId: number) => { - logger.info( - `EventProtocol - ${EventProtocolType.TRANSACTION_RECEIVE}: createdAt=${createdAt}, userId=${userId}`, - ) - await writeEvent( - EventProtocolType.TRANSACTION_RECEIVE, - createdAt, - userId, - null, - null, - null, - null, - null, - ) -}) - -eventProtocol.on( - EventProtocolType.TRANSACTION_RECEIVE_REDEEM, - async (createdAt: Date, userId: number) => { - logger.info( - `EventProtocol - ${EventProtocolType.TRANSACTION_RECEIVE_REDEEM}: createdAt=${createdAt}, userId=${userId}`, - ) - await writeEvent( - EventProtocolType.TRANSACTION_RECEIVE_REDEEM, - createdAt, - userId, - null, - null, - null, - null, - null, - ) - }, -) - -eventProtocol.on( - EventProtocolType.CONTRIBUTION_CREATE, - async (createdAt: Date, userId: number, contributionId: number) => { - logger.info( - `EventProtocol - ${EventProtocolType.CONTRIBUTION_CREATE}: createdAt=${createdAt}, userId=${userId}, contributionId=${contributionId}`, - ) - await writeEvent( - EventProtocolType.CONTRIBUTION_CREATE, - createdAt, - userId, - null, - null, - null, - contributionId, - null, - ) - }, -) - -eventProtocol.on( - EventProtocolType.CONTRIBUTION_CONFIRM, - async ( - createdAt: Date, - userId: number, - xUserId: number, - xCommunityId: number, - contributionId: number, - ) => { - logger.info( - `EventProtocol - ${EventProtocolType.CONTRIBUTION_CONFIRM}: createdAt=${createdAt}, userId=${userId}, xUserId=${xUserId}, xCommunityId=${xCommunityId}, contributionId=${contributionId}`, - ) - await writeEvent( - EventProtocolType.CONTRIBUTION_CONFIRM, - createdAt, - userId, - xUserId, - xCommunityId, - null, - contributionId, - null, - ) - }, -) - -eventProtocol.on( - EventProtocolType.CONTRIBUTION_LINK_DEFINE, - async (createdAt: Date, userId: number) => { - logger.info( - `EventProtocol - ${EventProtocolType.CONTRIBUTION_LINK_DEFINE}: createdAt=${createdAt}, userId=${userId}`, - ) - await writeEvent( - EventProtocolType.CONTRIBUTION_LINK_DEFINE, - createdAt, - userId, - null, - null, - null, - null, - null, - ) - }, -) - -eventProtocol.on( - EventProtocolType.CONTRIBUTION_LINK_ACTIVATE_REDEEM, - async (createdAt: Date, userId: number) => { - logger.info( - `EventProtocol - ${EventProtocolType.CONTRIBUTION_LINK_ACTIVATE_REDEEM}: createdAt=${createdAt}, userId=${userId}`, - ) - await writeEvent( - EventProtocolType.CONTRIBUTION_LINK_ACTIVATE_REDEEM, - createdAt, - userId, - null, - null, - null, - null, - null, - ) - }, -) -*/ - -export interface EventInterface { - type: string - createdAt: Date - userId: number - xUserId?: number - xCommunityId?: number - transactionId?: number - contributionId?: number - amount?: Decimal -} - -eventProtocol.on('writeEvents', async (events: EventInterface[]) => { +eventProtocol.on('writeEvents', async (events: Event[]) => { for (let i = 0; i < events.length; i++) { await writeEvent(events[i]) } }) -eventProtocol.on('writeEvent', async (event: EventInterface) => { +eventProtocol.on('writeEvent', async (event: Event) => { await writeEvent(event) }) -const writeEvent = async (event: EventInterface): Promise => { +const writeEvent = async (event: Event): Promise => { // if (!eventProtocol.isEnabled()) return logger.info(`writeEvent(${JSON.stringify(event)})`) const dbEvent = new EventProtocol() From 575453fd549d90c00387b4ab78a54400acd0615d Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Claus-Peter=20H=C3=BCbner?= Date: Wed, 6 Jul 2022 02:31:37 +0200 Subject: [PATCH 21/66] modify event emitting on new event type specific usage --- backend/src/graphql/resolver/UserResolver.ts | 45 ++++++-------------- 1 file changed, 14 insertions(+), 31 deletions(-) diff --git a/backend/src/graphql/resolver/UserResolver.ts b/backend/src/graphql/resolver/UserResolver.ts index ea4006779..b91b08d9f 100644 --- a/backend/src/graphql/resolver/UserResolver.ts +++ b/backend/src/graphql/resolver/UserResolver.ts @@ -23,8 +23,9 @@ import { sendAccountMultiRegistrationEmail } from '@/mailer/sendAccountMultiRegi import { klicktippSignIn } from '@/apis/KlicktippController' import { RIGHTS } from '@/auth/RIGHTS' import { hasElopageBuys } from '@/util/hasElopageBuys' -import { EventInterface, eventProtocol } from '@/event/EventProtocolEmitter' +import { eventProtocol } from '@/event/EventProtocolEmitter' import { EventProtocolType } from '@/event/EventProtocolType' +import { Event, EventRedeemRegister, EventRegister } from '@/event/Event' // eslint-disable-next-line @typescript-eslint/no-var-requires const sodium = require('sodium-native') @@ -374,9 +375,8 @@ export class UserResolver { // const encryptedPrivkey = SecretKeyCryptographyEncrypt(keyPair[1], passwordHash[1]) const emailHash = getEmailHash(email) - let eventType = EventProtocolType.REGISTER - let eventContributionId = null - let eventTransactionId = null + const eventRegister = new EventRegister() + const eventRedeemRegister = new EventRedeemRegister() const dbUser = new DbUser() dbUser.email = email dbUser.firstName = firstName @@ -394,30 +394,14 @@ export class UserResolver { logger.info('redeemCode found contributionLink=' + contributionLink) if (contributionLink) { dbUser.contributionLinkId = contributionLink.id - eventType = EventProtocolType.REDEEM_REGISTER - eventContributionId = contributionLink.id - /* eventProtocol.emit( - EventProtocolType.REDEEM_REGISTER, - new Date(Date.now()), - dbUser.id, - null, - contributionLink.id, - ) */ + eventRedeemRegister.contributionId = contributionLink.id } } else { const transactionLink = await dbTransactionLink.findOne({ code: redeemCode }) logger.info('redeemCode found transactionLink=' + transactionLink) if (transactionLink) { dbUser.referrerId = transactionLink.userId - eventType = EventProtocolType.REDEEM_REGISTER - eventTransactionId = transactionLink.id - /* eventProtocol.emit( - EventProtocolType.REDEEM_REGISTER, - new Date(Date.now()), - dbUser.id, - transactionLink.id, - null, - ) */ + eventRedeemRegister.transactionId = transactionLink.id } } } @@ -473,15 +457,14 @@ export class UserResolver { } logger.info('createUser() successful...') - eventProtocol.emit('writeEvent', { - type: eventType, - createdAt: new Date(), - userId: dbUser.id, - xUserId: null, - xCommunityId: null, - transactionId: eventTransactionId, - contributionId: eventContributionId, - }) + const event = new Event() + if (redeemCode) { + eventRedeemRegister.userId = dbUser.id + eventProtocol.emit('writeEvent', event.setEventRedeemRegister(eventRedeemRegister)) + } else { + eventRegister.userId = dbUser.id + eventProtocol.emit('writeEvent', event.setEventRegister(eventRegister)) + } return new User(dbUser) } From 127faf45cd072c3a3288fd94a82405f5132317ef Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Claus-Peter=20H=C3=BCbner?= Date: Wed, 6 Jul 2022 03:04:11 +0200 Subject: [PATCH 22/66] Merge remote-tracking branch 'origin/master' into 1794-feature-event-protocol-1-implement-the-basics-of-the-business-event-protocol linting --- backend/src/event/Event.ts | 44 +++++++++++++++++++------------------- 1 file changed, 22 insertions(+), 22 deletions(-) diff --git a/backend/src/event/Event.ts b/backend/src/event/Event.ts index acfb43519..c51acf627 100644 --- a/backend/src/event/Event.ts +++ b/backend/src/event/Event.ts @@ -40,33 +40,33 @@ export class EventBasicRedeem extends EventBasicUserId { contributionId?: number } -export class EventVisitGradido extends EventBasic { } -export class EventRegister extends EventBasicUserId { } -export class EventRedeemRegister extends EventBasicRedeem { } -export class EventInactiveAccount extends EventBasicUserId { } -export class EventSendConfirmationEmail extends EventBasicUserId { } -export class EventConfirmationEmail extends EventBasicUserId { } -export class EventRegisterEmailKlicktipp extends EventBasicUserId { } -export class EventLogin extends EventBasicUserId { } -export class EventRedeemLogin extends EventBasicRedeem { } -export class EventActivateAccount extends EventBasicUserId { } -export class EventPasswordChange extends EventBasicUserId { } -export class EventTransactionSend extends EventBasicTx { } -export class EventTransactionSendRedeem extends EventBasicTx { } -export class EventTransactionRepeateRedeem extends EventBasicTx { } +export class EventVisitGradido extends EventBasic {} +export class EventRegister extends EventBasicUserId {} +export class EventRedeemRegister extends EventBasicRedeem {} +export class EventInactiveAccount extends EventBasicUserId {} +export class EventSendConfirmationEmail extends EventBasicUserId {} +export class EventConfirmationEmail extends EventBasicUserId {} +export class EventRegisterEmailKlicktipp extends EventBasicUserId {} +export class EventLogin extends EventBasicUserId {} +export class EventRedeemLogin extends EventBasicRedeem {} +export class EventActivateAccount extends EventBasicUserId {} +export class EventPasswordChange extends EventBasicUserId {} +export class EventTransactionSend extends EventBasicTx {} +export class EventTransactionSendRedeem extends EventBasicTx {} +export class EventTransactionRepeateRedeem extends EventBasicTx {} export class EventTransactionCreation extends EventBasicUserId { transactionId: number amount: decimal } -export class EventTransactionReceive extends EventBasicTx { } -export class EventTransactionReceiveRedeem extends EventBasicTx { } -export class EventContributionCreate extends EventBasicCt { } +export class EventTransactionReceive extends EventBasicTx {} +export class EventTransactionReceiveRedeem extends EventBasicTx {} +export class EventContributionCreate extends EventBasicCt {} export class EventContributionConfirm extends EventBasicCt { xUserId: number xCommunityId: number } -export class EventContributionLinkDefine extends EventBasicCt { } -export class EventContributionLinkActivateRedeem extends EventBasicCt { } +export class EventContributionLinkDefine extends EventBasicCt {} +export class EventContributionLinkActivateRedeem extends EventBasicCt {} export class Event { constructor() @@ -84,15 +84,15 @@ export class Event { } } - public setEventBasic(ev?: EventBasic): Event { + public setEventBasic(): Event { this.type = EventProtocolType.BASIC this.createdAt = new Date() return this } - public setEventVisitGradido(ev?: EventVisitGradido): Event { - this.setEventBasic(ev) + public setEventVisitGradido(): Event { + this.setEventBasic() this.type = EventProtocolType.VISIT_GRADIDO return this From 4fb135cc36a9124f899fc18e536ce0ff16aeba6e Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Claus-Peter=20H=C3=BCbner?= Date: Wed, 6 Jul 2022 03:05:05 +0200 Subject: [PATCH 23/66] new switch for event protocol enabling --- backend/.env.template | 3 +++ 1 file changed, 3 insertions(+) diff --git a/backend/.env.template b/backend/.env.template index 94bf41550..764203d7f 100644 --- a/backend/.env.template +++ b/backend/.env.template @@ -50,3 +50,6 @@ EMAIL_CODE_REQUEST_TIME=$EMAIL_CODE_REQUEST_TIME # Webhook WEBHOOK_ELOPAGE_SECRET=$WEBHOOK_ELOPAGE_SECRET + +# EventProtocol +EVENT_PROTOCOL_ENABLED=true From c570e5d2e5d67e621dfc5a2d7012f9fa094fa562 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Claus-Peter=20H=C3=BCbner?= Date: Thu, 7 Jul 2022 01:47:07 +0200 Subject: [PATCH 24/66] Merge remote-tracking branch 'origin/master' into 1794-feature-event-protocol-1-implement-the-basics-of-the-business-event-protocol remove EnumEventType table --- .../0041-add_event_protocol_table/EnumEventType.ts | 13 ------------- database/entity/EnumEventType.ts | 1 - database/entity/index.ts | 2 -- .../migrations/0041-add_event_protocol_table.ts | 4 +++- 4 files changed, 3 insertions(+), 17 deletions(-) delete mode 100644 database/entity/0041-add_event_protocol_table/EnumEventType.ts delete mode 100644 database/entity/EnumEventType.ts diff --git a/database/entity/0041-add_event_protocol_table/EnumEventType.ts b/database/entity/0041-add_event_protocol_table/EnumEventType.ts deleted file mode 100644 index 814ac851b..000000000 --- a/database/entity/0041-add_event_protocol_table/EnumEventType.ts +++ /dev/null @@ -1,13 +0,0 @@ -import { BaseEntity, Entity, Column, PrimaryColumn } from 'typeorm' - -@Entity('enum_event_type') -export class EnumEventType extends BaseEntity { - @PrimaryColumn({ name: 'key', length: 100, nullable: false, collation: 'utf8mb4_unicode_ci' }) - key: string - - @Column({ name: 'value', unsigned: true, nullable: false }) - value: number - - @Column({ length: 200, nullable: false, collation: 'utf8mb4_unicode_ci' }) - description: string -} diff --git a/database/entity/EnumEventType.ts b/database/entity/EnumEventType.ts deleted file mode 100644 index 5b581d25f..000000000 --- a/database/entity/EnumEventType.ts +++ /dev/null @@ -1 +0,0 @@ -export { EnumEventType } from './0041-add_event_protocol_table/EnumEventType' diff --git a/database/entity/index.ts b/database/entity/index.ts index 0974fe900..733c99a3a 100644 --- a/database/entity/index.ts +++ b/database/entity/index.ts @@ -7,7 +7,6 @@ import { TransactionLink } from './TransactionLink' import { User } from './User' import { Contribution } from './Contribution' import { EventProtocol } from './EventProtocol' -import { EnumEventType } from './EnumEventType' export const entities = [ Contribution, @@ -19,5 +18,4 @@ export const entities = [ TransactionLink, User, EventProtocol, - EnumEventType, ] diff --git a/database/migrations/0041-add_event_protocol_table.ts b/database/migrations/0041-add_event_protocol_table.ts index 191ef7f41..65155f238 100644 --- a/database/migrations/0041-add_event_protocol_table.ts +++ b/database/migrations/0041-add_event_protocol_table.ts @@ -20,6 +20,7 @@ export async function upgrade(queryFn: (query: string, values?: any[]) => Promis \`amount\` bigint(20) NULL DEFAULT NULL, PRIMARY KEY (\`id\`) ) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4;`) +/* await queryFn(` CREATE TABLE IF NOT EXISTS \`enum_event_type\` ( \`key\` varchar(100) COLLATE utf8mb4_unicode_ci NOT NULL, @@ -93,10 +94,11 @@ export async function upgrade(queryFn: (query: string, values?: any[]) => Promis await queryFn( `INSERT INTO \`enum_event_type\` (\`key\`, \`value\`, \`description\`) VALUES ('CONTRIBUTION_LINK_ACTIVATE_REDEEM', 71, 'ContributionLinkActivateRedeemEvent: the user activates a received contributionLink to create a contribution entry for the contributionLink');`, ) + */ } export async function downgrade(queryFn: (query: string, values?: any[]) => Promise>) { // write downgrade logic as parameter of queryFn await queryFn(`DROP TABLE IF EXISTS \`event_protocol\`;`) - await queryFn(`DROP TABLE IF EXISTS \`enum_event_type\`;`) + // await queryFn(`DROP TABLE IF EXISTS \`enum_event_type\`;`) } From 46e2473a88b828c65ae594a7f899b4d7a9a3e2c8 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Claus-Peter=20H=C3=BCbner?= Date: Thu, 7 Jul 2022 01:48:33 +0200 Subject: [PATCH 25/66] remove EventEmitter from events-modul and replace it with writeEvent-Methode --- backend/src/event/EventProtocolEmitter.ts | 36 ++++++++++++----------- 1 file changed, 19 insertions(+), 17 deletions(-) diff --git a/backend/src/event/EventProtocolEmitter.ts b/backend/src/event/EventProtocolEmitter.ts index d4ecea27a..1040feb32 100644 --- a/backend/src/event/EventProtocolEmitter.ts +++ b/backend/src/event/EventProtocolEmitter.ts @@ -1,4 +1,3 @@ -import { EventEmitter } from 'events' import { Event } from '@/event/Event' import { backendLogger as logger } from '@/server/logger' // import { EventProtocolType } from './EventProtocolType' @@ -6,7 +5,8 @@ import { EventProtocol } from '@entity/EventProtocol' // import { getConnection } from '@dbTools/typeorm' import CONFIG from '@/config' -class EventProtocolEmitter extends EventEmitter { +class EventProtocolEmitter { + /* }extends EventEmitter { */ private events: Event[] public addEvent(event: Event) { @@ -21,9 +21,25 @@ class EventProtocolEmitter extends EventEmitter { logger.info(`EventProtocol - isEnabled=${CONFIG.EVENT_PROTOCOL_ENABLED}`) return CONFIG.EVENT_PROTOCOL_ENABLED } + + public async writeEvent(event: Event): Promise { + // if (!eventProtocol.isEnabled()) return + logger.info(`writeEvent(${JSON.stringify(event)})`) + const dbEvent = new EventProtocol() + dbEvent.type = event.type + dbEvent.createdAt = event.createdAt + dbEvent.userId = event.userId + if (event.xUserId) dbEvent.xUserId = event.xUserId + if (event.xCommunityId) dbEvent.xCommunityId = event.xCommunityId + if (event.contributionId) dbEvent.contributionId = event.contributionId + if (event.transactionId) dbEvent.transactionId = event.transactionId + if (event.amount) dbEvent.amount = event.amount + await dbEvent.save() + } } export const eventProtocol = new EventProtocolEmitter() +/* eventProtocol.on('error', (err) => { logger.error(`ERROR in EventProtocol: ${err}`) }) @@ -37,18 +53,4 @@ eventProtocol.on('writeEvents', async (events: Event[]) => { eventProtocol.on('writeEvent', async (event: Event) => { await writeEvent(event) }) - -const writeEvent = async (event: Event): Promise => { - // if (!eventProtocol.isEnabled()) return - logger.info(`writeEvent(${JSON.stringify(event)})`) - const dbEvent = new EventProtocol() - dbEvent.type = event.type - dbEvent.createdAt = event.createdAt - dbEvent.userId = event.userId - if (event.xUserId) dbEvent.xUserId = event.xUserId - if (event.xCommunityId) dbEvent.xCommunityId = event.xCommunityId - if (event.contributionId) dbEvent.contributionId = event.contributionId - if (event.transactionId) dbEvent.transactionId = event.transactionId - if (event.amount) dbEvent.amount = event.amount - await dbEvent.save() -} +*/ From d6fe7985453b365ce861451012a68198b96c4f8f Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Claus-Peter=20H=C3=BCbner?= Date: Thu, 7 Jul 2022 01:49:16 +0200 Subject: [PATCH 26/66] replace event emitting with event writing --- backend/src/graphql/resolver/UserResolver.ts | 15 ++++++--------- 1 file changed, 6 insertions(+), 9 deletions(-) diff --git a/backend/src/graphql/resolver/UserResolver.ts b/backend/src/graphql/resolver/UserResolver.ts index b91b08d9f..ff687bb3a 100644 --- a/backend/src/graphql/resolver/UserResolver.ts +++ b/backend/src/graphql/resolver/UserResolver.ts @@ -24,8 +24,7 @@ import { klicktippSignIn } from '@/apis/KlicktippController' import { RIGHTS } from '@/auth/RIGHTS' import { hasElopageBuys } from '@/util/hasElopageBuys' import { eventProtocol } from '@/event/EventProtocolEmitter' -import { EventProtocolType } from '@/event/EventProtocolType' -import { Event, EventRedeemRegister, EventRegister } from '@/event/Event' +import { Event, EventLogin, EventRedeemRegister, EventRegister } from '@/event/Event' // eslint-disable-next-line @typescript-eslint/no-var-requires const sodium = require('sodium-native') @@ -293,11 +292,9 @@ export class UserResolver { key: 'token', value: encode(dbUser.pubKey), }) - eventProtocol.emit('writeEvent', { - type: EventProtocolType.LOGIN, - createdAt: new Date(), - userId: user.id, - }) + const ev = new EventLogin() + ev.userId = user.id + eventProtocol.writeEvent(new Event().setEventLogin(ev)) logger.info('successful Login:' + user) return user } @@ -460,10 +457,10 @@ export class UserResolver { const event = new Event() if (redeemCode) { eventRedeemRegister.userId = dbUser.id - eventProtocol.emit('writeEvent', event.setEventRedeemRegister(eventRedeemRegister)) + eventProtocol.writeEvent(event.setEventRedeemRegister(eventRedeemRegister)) } else { eventRegister.userId = dbUser.id - eventProtocol.emit('writeEvent', event.setEventRegister(eventRegister)) + eventProtocol.writeEvent(event.setEventRegister(eventRegister)) } return new User(dbUser) From 642a3e647c7cf2b5a6408df0925fdbfa0ebeac4c Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Claus-Peter=20H=C3=BCbner?= Date: Thu, 7 Jul 2022 02:53:04 +0200 Subject: [PATCH 27/66] increase CONFIG_VERSION after adding Event-Protocol Switch --- 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 5e0978f3b..8903752c0 100644 --- a/backend/src/config/index.ts +++ b/backend/src/config/index.ts @@ -17,7 +17,7 @@ const constants = { LOG_LEVEL: process.env.LOG_LEVEL || 'info', CONFIG_VERSION: { DEFAULT: 'DEFAULT', - EXPECTED: 'v8.2022-06-20', + EXPECTED: 'v9.2022-07-07', CURRENT: '', }, } From 859ac2cebd13ca52878661ac9facc3e0798bd9a9 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Claus-Peter=20H=C3=BCbner?= Date: Thu, 7 Jul 2022 02:53:43 +0200 Subject: [PATCH 28/66] increase CONFIG_VERSION --- backend/.env.dist | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/backend/.env.dist b/backend/.env.dist index 0d1a14d7c..0e8148a8a 100644 --- a/backend/.env.dist +++ b/backend/.env.dist @@ -1,4 +1,4 @@ -CONFIG_VERSION=v8.2022-06-20 +CONFIG_VERSION=v9.2022-07-07 # Server PORT=4000 From 3e471eb81ee0037e40c6d127e90ef546250378aa Mon Sep 17 00:00:00 2001 From: ogerly Date: Tue, 12 Jul 2022 16:54:37 +0200 Subject: [PATCH 29/66] add creation on login query and store --- frontend/src/graphql/queries.js | 2 ++ frontend/src/store/store.js | 6 ++++++ frontend/src/store/store.test.js | 25 +++++++++++++++++++++++-- 3 files changed, 31 insertions(+), 2 deletions(-) diff --git a/frontend/src/graphql/queries.js b/frontend/src/graphql/queries.js index adcd653a4..27e63d568 100644 --- a/frontend/src/graphql/queries.js +++ b/frontend/src/graphql/queries.js @@ -13,6 +13,7 @@ export const login = gql` hasElopage publisherId isAdmin + creation } } ` @@ -30,6 +31,7 @@ export const verifyLogin = gql` hasElopage publisherId isAdmin + creation } } ` diff --git a/frontend/src/store/store.js b/frontend/src/store/store.js index e95eec7b9..8fdbc519e 100644 --- a/frontend/src/store/store.js +++ b/frontend/src/store/store.js @@ -47,6 +47,9 @@ export const mutations = { hasElopage: (state, hasElopage) => { state.hasElopage = hasElopage }, + creation: (state, creation) => { + state.creation = creation + }, } export const actions = { @@ -60,6 +63,7 @@ export const actions = { commit('hasElopage', data.hasElopage) commit('publisherId', data.publisherId) commit('isAdmin', data.isAdmin) + commit('creation', data.creation) }, logout: ({ commit, state }) => { commit('token', null) @@ -71,6 +75,7 @@ export const actions = { commit('hasElopage', false) commit('publisherId', null) commit('isAdmin', false) + commit('creation', null) localStorage.clear() }, } @@ -96,6 +101,7 @@ try { newsletterState: null, hasElopage: false, publisherId: null, + creation: null, }, getters: {}, // Syncronous mutation of the state diff --git a/frontend/src/store/store.test.js b/frontend/src/store/store.test.js index 3f942fa35..0493d7f53 100644 --- a/frontend/src/store/store.test.js +++ b/frontend/src/store/store.test.js @@ -30,6 +30,7 @@ const { publisherId, isAdmin, hasElopage, + creation, } = mutations const { login, logout } = actions @@ -139,6 +140,14 @@ describe('Vuex store', () => { expect(state.hasElopage).toBeTruthy() }) }) + + describe('creation', () => { + it('sets the state of creation', () => { + const state = { creation: null } + creation(state, true) + expect(state.creation).toEqual(true) + }) + }) }) describe('actions', () => { @@ -156,11 +165,12 @@ describe('Vuex store', () => { hasElopage: false, publisherId: 1234, isAdmin: true, + creation: ['1000', '1000', '1000'], } it('calls nine commits', () => { login({ commit, state }, commitedData) - expect(commit).toHaveBeenCalledTimes(8) + expect(commit).toHaveBeenCalledTimes(9) }) it('commits email', () => { @@ -202,6 +212,11 @@ describe('Vuex store', () => { login({ commit, state }, commitedData) expect(commit).toHaveBeenNthCalledWith(8, 'isAdmin', true) }) + + it('commits creation', () => { + login({ commit, state }, commitedData) + expect(commit).toHaveBeenNthCalledWith(9, 'creation', ['1000', '1000', '1000']) + }) }) describe('logout', () => { @@ -210,7 +225,7 @@ describe('Vuex store', () => { it('calls nine commits', () => { logout({ commit, state }) - expect(commit).toHaveBeenCalledTimes(8) + expect(commit).toHaveBeenCalledTimes(9) }) it('commits token', () => { @@ -253,6 +268,12 @@ describe('Vuex store', () => { expect(commit).toHaveBeenNthCalledWith(8, 'isAdmin', false) }) + it('commits creation', () => { + logout({ commit, state }) + expect(commit).toHaveBeenNthCalledWith(9, 'creation', null) + }) + + // how to get this working? it.skip('calls localStorage.clear()', () => { const clearStorageMock = jest.fn() From bc8078c427883aa5192a5d1b54556fb8f285e5d6 Mon Sep 17 00:00:00 2001 From: ogerly Date: Tue, 12 Jul 2022 16:55:50 +0200 Subject: [PATCH 30/66] fix lint --- frontend/src/store/store.test.js | 1 - 1 file changed, 1 deletion(-) diff --git a/frontend/src/store/store.test.js b/frontend/src/store/store.test.js index 0493d7f53..651a3ccc5 100644 --- a/frontend/src/store/store.test.js +++ b/frontend/src/store/store.test.js @@ -273,7 +273,6 @@ describe('Vuex store', () => { expect(commit).toHaveBeenNthCalledWith(9, 'creation', null) }) - // how to get this working? it.skip('calls localStorage.clear()', () => { const clearStorageMock = jest.fn() From 1a2bb1a29a1b3d24f64fee37ac8b2bf7fe7e2702 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Claus-Peter=20H=C3=BCbner?= Date: Wed, 13 Jul 2022 01:59:37 +0200 Subject: [PATCH 31/66] add eventSendConfirmEmail during createUser() --- backend/src/graphql/resolver/UserResolver.ts | 8 ++++++-- 1 file changed, 6 insertions(+), 2 deletions(-) diff --git a/backend/src/graphql/resolver/UserResolver.ts b/backend/src/graphql/resolver/UserResolver.ts index 26a265071..55ed76e01 100644 --- a/backend/src/graphql/resolver/UserResolver.ts +++ b/backend/src/graphql/resolver/UserResolver.ts @@ -24,7 +24,7 @@ import { klicktippSignIn } from '@/apis/KlicktippController' import { RIGHTS } from '@/auth/RIGHTS' import { hasElopageBuys } from '@/util/hasElopageBuys' import { eventProtocol } from '@/event/EventProtocolEmitter' -import { Event, EventLogin, EventRedeemRegister, EventRegister } from '@/event/Event' +import { Event, EventLogin, EventRedeemRegister, EventRegister, EventSendConfirmationEmail } from '@/event/Event' import { getUserCreation } from './util/creations' // eslint-disable-next-line @typescript-eslint/no-var-requires @@ -375,6 +375,7 @@ export class UserResolver { const eventRegister = new EventRegister() const eventRedeemRegister = new EventRedeemRegister() + const eventSendConfirmEmail = new EventSendConfirmationEmail() const dbUser = new DbUser() dbUser.email = email dbUser.firstName = firstName @@ -410,6 +411,7 @@ export class UserResolver { // loginUser.pubKey = keyPair[0] // loginUser.privKey = encryptedPrivkey + const event = new Event() const queryRunner = getConnection().createQueryRunner() await queryRunner.connect() await queryRunner.startTransaction('READ UNCOMMITTED') @@ -439,6 +441,9 @@ export class UserResolver { duration: printTimeDuration(CONFIG.EMAIL_CODE_VALID_TIME), }) logger.info(`sendAccountActivationEmail of ${firstName}.${lastName} to ${email}`) + eventSendConfirmEmail.userId = dbUser.id + eventProtocol.writeEvent(event.setEventSendConfirmationEmail(eventSendConfirmEmail)) + /* uncomment this, when you need the activation link on the console */ // In case EMails are disabled log the activation link for the user if (!emailSent) { @@ -455,7 +460,6 @@ export class UserResolver { } logger.info('createUser() successful...') - const event = new Event() if (redeemCode) { eventRedeemRegister.userId = dbUser.id eventProtocol.writeEvent(event.setEventRedeemRegister(eventRedeemRegister)) From 63d84199b018c9a126f7af98038c48fd777cdb6c Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Claus-Peter=20H=C3=BCbner?= Date: Wed, 13 Jul 2022 02:06:36 +0200 Subject: [PATCH 32/66] linting --- backend/src/graphql/resolver/UserResolver.ts | 8 +++++++- 1 file changed, 7 insertions(+), 1 deletion(-) diff --git a/backend/src/graphql/resolver/UserResolver.ts b/backend/src/graphql/resolver/UserResolver.ts index 55ed76e01..a89a8cb0b 100644 --- a/backend/src/graphql/resolver/UserResolver.ts +++ b/backend/src/graphql/resolver/UserResolver.ts @@ -24,7 +24,13 @@ import { klicktippSignIn } from '@/apis/KlicktippController' import { RIGHTS } from '@/auth/RIGHTS' import { hasElopageBuys } from '@/util/hasElopageBuys' import { eventProtocol } from '@/event/EventProtocolEmitter' -import { Event, EventLogin, EventRedeemRegister, EventRegister, EventSendConfirmationEmail } from '@/event/Event' +import { + Event, + EventLogin, + EventRedeemRegister, + EventRegister, + EventSendConfirmationEmail, +} from '@/event/Event' import { getUserCreation } from './util/creations' // eslint-disable-next-line @typescript-eslint/no-var-requires From 9d9d1a78f18abda66333139ac1b4ffd66e631607 Mon Sep 17 00:00:00 2001 From: elweyn Date: Wed, 13 Jul 2022 11:01:44 +0200 Subject: [PATCH 33/66] Add confirmedBy and confirmedAt for the contribution query. --- backend/src/graphql/model/Contribution.ts | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/backend/src/graphql/model/Contribution.ts b/backend/src/graphql/model/Contribution.ts index dc1dd39e9..348a6eb98 100644 --- a/backend/src/graphql/model/Contribution.ts +++ b/backend/src/graphql/model/Contribution.ts @@ -12,6 +12,8 @@ export class Contribution { this.memo = contribution.memo this.createdAt = contribution.createdAt this.deletedAt = contribution.deletedAt + this.confirmedAt = contribution.confirmedAt + this.confirmedBy = contribution.confirmedBy } @Field(() => Number) @@ -31,6 +33,12 @@ export class Contribution { @Field(() => Date, { nullable: true }) deletedAt: Date | null + + @Field(() => Date, { nullable: true }) + confirmedAt: Date | null + + @Field(() => Number, { nullable: true }) + confirmedBy: number | null } @ObjectType() From 99c4e8367048fe1d100a307be5febd84b6036177 Mon Sep 17 00:00:00 2001 From: elweyn Date: Wed, 13 Jul 2022 11:26:18 +0200 Subject: [PATCH 34/66] Add deleted contribution to the list of contribution. --- backend/src/graphql/resolver/ContributionResolver.ts | 1 + 1 file changed, 1 insertion(+) diff --git a/backend/src/graphql/resolver/ContributionResolver.ts b/backend/src/graphql/resolver/ContributionResolver.ts index 4424b40d0..562859116 100644 --- a/backend/src/graphql/resolver/ContributionResolver.ts +++ b/backend/src/graphql/resolver/ContributionResolver.ts @@ -58,6 +58,7 @@ export class ContributionResolver { order: { createdAt: order, }, + withDeleted: true, skip: (currentPage - 1) * pageSize, take: pageSize, }) From b7c24978392ae1f74baf3442ed32521d167c6637 Mon Sep 17 00:00:00 2001 From: elweyn Date: Wed, 13 Jul 2022 12:18:47 +0200 Subject: [PATCH 35/66] Add new right LIST_ALL_CONFIRMED_CONTRIBUTIONS. --- backend/src/auth/RIGHTS.ts | 1 + backend/src/auth/ROLES.ts | 1 + 2 files changed, 2 insertions(+) diff --git a/backend/src/auth/RIGHTS.ts b/backend/src/auth/RIGHTS.ts index 6a6f8b7c0..975c2006a 100644 --- a/backend/src/auth/RIGHTS.ts +++ b/backend/src/auth/RIGHTS.ts @@ -27,6 +27,7 @@ export enum RIGHTS { GDT_BALANCE = 'GDT_BALANCE', CREATE_CONTRIBUTION = 'CREATE_CONTRIBUTION', LIST_CONTRIBUTIONS = 'LIST_CONTRIBUTIONS', + LIST_ALL_CONFIRMED_CONTRIBUTIONS = 'LIST_ALL_CONFIRMED_CONTRIBUTIONS', // Admin SEARCH_USERS = 'SEARCH_USERS', SET_USER_ROLE = 'SET_USER_ROLE', diff --git a/backend/src/auth/ROLES.ts b/backend/src/auth/ROLES.ts index f56106664..e5628bb62 100644 --- a/backend/src/auth/ROLES.ts +++ b/backend/src/auth/ROLES.ts @@ -25,6 +25,7 @@ export const ROLE_USER = new Role('user', [ RIGHTS.GDT_BALANCE, RIGHTS.CREATE_CONTRIBUTION, RIGHTS.LIST_CONTRIBUTIONS, + RIGHTS.LIST_ALL_CONFIRMED_CONTRIBUTIONS, ]) export const ROLE_ADMIN = new Role('admin', Object.values(RIGHTS)) // all rights From 14619384a4f7171f8505fa9047480309814ccde5 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Claus-Peter=20H=C3=BCbner?= Date: Wed, 13 Jul 2022 18:52:11 +0200 Subject: [PATCH 36/66] remove comments --- backend/src/event/Event.ts | 13 ------------- backend/src/event/EventProtocolEmitter.ts | 20 +------------------- 2 files changed, 1 insertion(+), 32 deletions(-) diff --git a/backend/src/event/Event.ts b/backend/src/event/Event.ts index c51acf627..6f07661f1 100644 --- a/backend/src/event/Event.ts +++ b/backend/src/event/Event.ts @@ -2,19 +2,6 @@ import { EventProtocol } from '@entity/EventProtocol' import decimal from 'decimal.js-light' import { EventProtocolType } from './EventProtocolType' -/* -export interface EventInterface { - type: string - createdAt: Date - userId: number - xUserId?: number - xCommunityId?: number - transactionId?: number - contributionId?: number - amount?: Decimal -} -*/ - export class EventBasic { type: string createdAt: Date diff --git a/backend/src/event/EventProtocolEmitter.ts b/backend/src/event/EventProtocolEmitter.ts index 1040feb32..5991bbded 100644 --- a/backend/src/event/EventProtocolEmitter.ts +++ b/backend/src/event/EventProtocolEmitter.ts @@ -1,8 +1,6 @@ import { Event } from '@/event/Event' import { backendLogger as logger } from '@/server/logger' -// import { EventProtocolType } from './EventProtocolType' import { EventProtocol } from '@entity/EventProtocol' -// import { getConnection } from '@dbTools/typeorm' import CONFIG from '@/config' class EventProtocolEmitter { @@ -23,7 +21,7 @@ class EventProtocolEmitter { } public async writeEvent(event: Event): Promise { - // if (!eventProtocol.isEnabled()) return + if (!eventProtocol.isEnabled()) return logger.info(`writeEvent(${JSON.stringify(event)})`) const dbEvent = new EventProtocol() dbEvent.type = event.type @@ -38,19 +36,3 @@ class EventProtocolEmitter { } } export const eventProtocol = new EventProtocolEmitter() - -/* -eventProtocol.on('error', (err) => { - logger.error(`ERROR in EventProtocol: ${err}`) -}) - -eventProtocol.on('writeEvents', async (events: Event[]) => { - for (let i = 0; i < events.length; i++) { - await writeEvent(events[i]) - } -}) - -eventProtocol.on('writeEvent', async (event: Event) => { - await writeEvent(event) -}) -*/ From 7c698de325294811d144f6ac7bac058d44200735 Mon Sep 17 00:00:00 2001 From: elweyn Date: Thu, 14 Jul 2022 12:25:45 +0200 Subject: [PATCH 37/66] Add constructor to ContributionListResult. --- backend/src/graphql/model/Contribution.ts | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/backend/src/graphql/model/Contribution.ts b/backend/src/graphql/model/Contribution.ts index dc1dd39e9..989296848 100644 --- a/backend/src/graphql/model/Contribution.ts +++ b/backend/src/graphql/model/Contribution.ts @@ -35,6 +35,11 @@ export class Contribution { @ObjectType() export class ContributionListResult { + constructor(count: number, list: Contribution[]) { + this.linkCount = count + this.linkList = list + } + @Field(() => Int) linkCount: number From 2f90bd981126ef77f744beacb5fa8d27bc3cc225 Mon Sep 17 00:00:00 2001 From: elweyn Date: Thu, 14 Jul 2022 12:58:01 +0200 Subject: [PATCH 38/66] Withdrew User from Contribution object and replaced it with userId, firstName and lastName. --- backend/src/graphql/model/Contribution.ts | 14 +++++++++++--- 1 file changed, 11 insertions(+), 3 deletions(-) diff --git a/backend/src/graphql/model/Contribution.ts b/backend/src/graphql/model/Contribution.ts index 989296848..324b0ff07 100644 --- a/backend/src/graphql/model/Contribution.ts +++ b/backend/src/graphql/model/Contribution.ts @@ -7,7 +7,9 @@ import { User } from './User' export class Contribution { constructor(contribution: dbContribution, user: User) { this.id = contribution.id - this.user = user + this.userId = user ? user.id : null + this.firstName = user ? user.firstName : null + this.lastName = user ? user.lastName : null this.amount = contribution.amount this.memo = contribution.memo this.createdAt = contribution.createdAt @@ -17,8 +19,14 @@ export class Contribution { @Field(() => Number) id: number - @Field(() => User) - user: User + @Field(() => Number, { nullable: true }) + userId: number | null + + @Field(() => String, { nullable: true }) + firstName: string | null + + @Field(() => String, { nullable: true }) + lastName: string | null @Field(() => Decimal) amount: Decimal From c02f575780166a8f2e6c29df4a83ffac59fcd36d Mon Sep 17 00:00:00 2001 From: elweyn Date: Thu, 14 Jul 2022 12:59:21 +0200 Subject: [PATCH 39/66] Withdrew userid from contribution object. --- backend/src/graphql/model/Contribution.ts | 4 ---- 1 file changed, 4 deletions(-) diff --git a/backend/src/graphql/model/Contribution.ts b/backend/src/graphql/model/Contribution.ts index 324b0ff07..a1537244d 100644 --- a/backend/src/graphql/model/Contribution.ts +++ b/backend/src/graphql/model/Contribution.ts @@ -7,7 +7,6 @@ import { User } from './User' export class Contribution { constructor(contribution: dbContribution, user: User) { this.id = contribution.id - this.userId = user ? user.id : null this.firstName = user ? user.firstName : null this.lastName = user ? user.lastName : null this.amount = contribution.amount @@ -19,9 +18,6 @@ export class Contribution { @Field(() => Number) id: number - @Field(() => Number, { nullable: true }) - userId: number | null - @Field(() => String, { nullable: true }) firstName: string | null From 8c6ec08e88aa4350134c2efd812a77ddfbeea2d6 Mon Sep 17 00:00:00 2001 From: elweyn Date: Thu, 14 Jul 2022 16:42:55 +0200 Subject: [PATCH 40/66] Gives a list of allCreations and calls the User one time in the creation. --- .../graphql/resolver/ContributionResolver.ts | 38 ++++++++++++++++++- 1 file changed, 36 insertions(+), 2 deletions(-) diff --git a/backend/src/graphql/resolver/ContributionResolver.ts b/backend/src/graphql/resolver/ContributionResolver.ts index 4424b40d0..8a23b3150 100644 --- a/backend/src/graphql/resolver/ContributionResolver.ts +++ b/backend/src/graphql/resolver/ContributionResolver.ts @@ -2,12 +2,13 @@ import { RIGHTS } from '@/auth/RIGHTS' import { Context, getUser } from '@/server/context' import { backendLogger as logger } from '@/server/logger' import { Contribution as dbContribution } from '@entity/Contribution' +import { User as dbUser } from '@entity/User' import { Arg, Args, Authorized, Ctx, Mutation, Query, Resolver } from 'type-graphql' -import { FindOperator, IsNull } from '@dbTools/typeorm' +import { FindOperator, IsNull, Not } from '@dbTools/typeorm' import ContributionArgs from '@arg/ContributionArgs' import Paginated from '@arg/Paginated' import { Order } from '@enum/Order' -import { Contribution } from '@model/Contribution' +import { Contribution, ContributionListResult } from '@model/Contribution' import { UnconfirmedContribution } from '@model/UnconfirmedContribution' import { User } from '@model/User' import { validateContribution, getUserCreation } from './util/creations' @@ -63,4 +64,37 @@ export class ContributionResolver { }) return contributions.map((contribution) => new Contribution(contribution, new User(user))) } + + @Authorized([RIGHTS.LIST_ALL_CONFIRMED_CONTRIBUTIONS]) + @Query(() => ContributionListResult) + async listAllConfirmedContributions( + @Args() + { currentPage = 1, pageSize = 5, order = Order.DESC }: Paginated, + ): Promise { + const dbContributions = await dbContribution.find({ + order: { + createdAt: order, + }, + skip: (currentPage - 1) * pageSize, + take: pageSize, + }) + const contributions: Contribution[] = [] + const userIds: number[] = [] + dbContributions.forEach(async (dbContribution) => { + userIds.push(dbContribution.userId) + }) + userIds.filter((elem, index, self) => { + return index === self.indexOf(elem) + }) + const users = new Map() + for (let i = 0; i < userIds.length; i++) { + const id = userIds[i] + const user = await dbUser.findOneOrFail({ id }) + users.set(id, user) + } + dbContributions.forEach((dbContribution) => { + contributions.push(new Contribution(dbContribution, users.get(dbContribution.userId))) + }) + return new ContributionListResult(contributions.length, contributions) + } } From fdea5f68ef8fd78176ce3ea5707c6cc270d2abbd Mon Sep 17 00:00:00 2001 From: elweyn Date: Thu, 14 Jul 2022 16:43:20 +0200 Subject: [PATCH 41/66] Add confirmedBy and confirmedAt for the contribution query. --- backend/src/graphql/model/Contribution.ts | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/backend/src/graphql/model/Contribution.ts b/backend/src/graphql/model/Contribution.ts index a1537244d..34bffd6d7 100644 --- a/backend/src/graphql/model/Contribution.ts +++ b/backend/src/graphql/model/Contribution.ts @@ -13,6 +13,8 @@ export class Contribution { this.memo = contribution.memo this.createdAt = contribution.createdAt this.deletedAt = contribution.deletedAt + this.confirmedAt = contribution.confirmedAt + this.confirmedBy = contribution.confirmedBy } @Field(() => Number) @@ -35,6 +37,12 @@ export class Contribution { @Field(() => Date, { nullable: true }) deletedAt: Date | null + + @Field(() => Date, { nullable: true }) + confirmedAt: Date | null + + @Field(() => Number, { nullable: true }) + confirmedBy: number | null } @ObjectType() From cbbe0ffad2cf8a528d5a3c5c5a336cfed7afe82b Mon Sep 17 00:00:00 2001 From: elweyn Date: Thu, 14 Jul 2022 16:45:19 +0200 Subject: [PATCH 42/66] Change the method name from listAllConfirmedContributions to listAllContributions. --- backend/src/auth/RIGHTS.ts | 2 +- backend/src/auth/ROLES.ts | 2 +- backend/src/graphql/resolver/ContributionResolver.ts | 4 ++-- 3 files changed, 4 insertions(+), 4 deletions(-) diff --git a/backend/src/auth/RIGHTS.ts b/backend/src/auth/RIGHTS.ts index 975c2006a..5258c9e3b 100644 --- a/backend/src/auth/RIGHTS.ts +++ b/backend/src/auth/RIGHTS.ts @@ -27,7 +27,7 @@ export enum RIGHTS { GDT_BALANCE = 'GDT_BALANCE', CREATE_CONTRIBUTION = 'CREATE_CONTRIBUTION', LIST_CONTRIBUTIONS = 'LIST_CONTRIBUTIONS', - LIST_ALL_CONFIRMED_CONTRIBUTIONS = 'LIST_ALL_CONFIRMED_CONTRIBUTIONS', + LIST_ALL_CONTRIBUTIONS = 'LIST_ALL_CONTRIBUTIONS', // Admin SEARCH_USERS = 'SEARCH_USERS', SET_USER_ROLE = 'SET_USER_ROLE', diff --git a/backend/src/auth/ROLES.ts b/backend/src/auth/ROLES.ts index e5628bb62..4a96d4813 100644 --- a/backend/src/auth/ROLES.ts +++ b/backend/src/auth/ROLES.ts @@ -25,7 +25,7 @@ export const ROLE_USER = new Role('user', [ RIGHTS.GDT_BALANCE, RIGHTS.CREATE_CONTRIBUTION, RIGHTS.LIST_CONTRIBUTIONS, - RIGHTS.LIST_ALL_CONFIRMED_CONTRIBUTIONS, + RIGHTS.LIST_ALL_CONTRIBUTIONS, ]) export const ROLE_ADMIN = new Role('admin', Object.values(RIGHTS)) // all rights diff --git a/backend/src/graphql/resolver/ContributionResolver.ts b/backend/src/graphql/resolver/ContributionResolver.ts index 8a23b3150..c015496c1 100644 --- a/backend/src/graphql/resolver/ContributionResolver.ts +++ b/backend/src/graphql/resolver/ContributionResolver.ts @@ -65,9 +65,9 @@ export class ContributionResolver { return contributions.map((contribution) => new Contribution(contribution, new User(user))) } - @Authorized([RIGHTS.LIST_ALL_CONFIRMED_CONTRIBUTIONS]) + @Authorized([RIGHTS.LIST_ALL_CONTRIBUTIONS]) @Query(() => ContributionListResult) - async listAllConfirmedContributions( + async listAllContributions( @Args() { currentPage = 1, pageSize = 5, order = Order.DESC }: Paginated, ): Promise { From ab77a798f589c4907ae149f127e9e7c7c56219bb Mon Sep 17 00:00:00 2001 From: elweyn Date: Thu, 14 Jul 2022 16:57:25 +0200 Subject: [PATCH 43/66] Add query seed for listAllContributions. --- backend/src/seeds/graphql/queries.ts | 18 ++++++++++++++++++ 1 file changed, 18 insertions(+) diff --git a/backend/src/seeds/graphql/queries.ts b/backend/src/seeds/graphql/queries.ts index c27ecdd66..deae5f97b 100644 --- a/backend/src/seeds/graphql/queries.ts +++ b/backend/src/seeds/graphql/queries.ts @@ -191,6 +191,24 @@ export const listContributions = gql` } } ` + +export const listAllContributions = ` +query ($currentPage: Int = 1, $pageSize: Int = 5, $order: Order = DESC) { + listAllContributions(currentPage: $currentPage, pageSize: $pageSize, order: $order) { + linkCount + linkList { + id + firstName + lastName + amount + memo + createdAt + confirmedAt + confirmedBy + } + } +} +` // from admin interface export const listUnconfirmedContributions = gql` From ba90911aec704026ee6953e9db0f3731ef263116 Mon Sep 17 00:00:00 2001 From: elweyn Date: Thu, 14 Jul 2022 16:57:57 +0200 Subject: [PATCH 44/66] Test that unauthenticated user can not query listAllContributions. --- .../resolver/ContributionResolver.test.ts | 56 ++++++++++++++++++- 1 file changed, 55 insertions(+), 1 deletion(-) diff --git a/backend/src/graphql/resolver/ContributionResolver.test.ts b/backend/src/graphql/resolver/ContributionResolver.test.ts index 9b0f6a3bc..a4cb1d714 100644 --- a/backend/src/graphql/resolver/ContributionResolver.test.ts +++ b/backend/src/graphql/resolver/ContributionResolver.test.ts @@ -3,7 +3,7 @@ import { bibiBloxberg } from '@/seeds/users/bibi-bloxberg' import { createContribution } from '@/seeds/graphql/mutations' -import { listContributions, login } from '@/seeds/graphql/queries' +import { listAllContributions, listContributions, login } from '@/seeds/graphql/queries' import { cleanDB, resetToken, testEnvironment } from '@test/helpers' import { GraphQLError } from 'graphql' import { userFactory } from '@/seeds/factory/user' @@ -168,6 +168,11 @@ describe('ContributionResolver', () => { }) }) + afterAll(async () => { + await cleanDB() + await con.close() + }) + describe('filter confirmed is false', () => { it('returns creations', async () => { await expect( @@ -230,4 +235,53 @@ describe('ContributionResolver', () => { }) }) }) + + describe('listAllContribution', () => { + describe('unauthenticated', () => { + it('returns an error', async () => { + await expect( + query({ + query: listAllContributions, + variables: { + currentPage: 1, + pageSize: 25, + order: 'DESC', + filterConfirmed: false, + }, + }), + ).resolves.toEqual( + expect.objectContaining({ + errors: [new GraphQLError('401 Unauthorized')], + }), + ) + }) + }) + + describe('authenticated', () => { + beforeAll(async () => { + await userFactory(testEnv, bibiBloxberg) + await userFactory(testEnv, peterLustig) + const bibisCreation = creations.find((creation) => creation.email === 'bibi@bloxberg.de') + // eslint-disable-next-line @typescript-eslint/no-non-null-assertion + await creationFactory(testEnv, bibisCreation!) + await query({ + query: login, + variables: { email: 'bibi@bloxberg.de', password: 'Aa12345_' }, + }) + await mutate({ + mutation: createContribution, + variables: { + amount: 100.0, + memo: 'Test env contribution', + creationDate: new Date().toString(), + }, + }) + }) + + afterAll(async () => { + await cleanDB() + await con.close() + }) + }) + }) }) From 246edadc1314e6092eb51daa7ffdf9eeff72e72f Mon Sep 17 00:00:00 2001 From: elweyn Date: Thu, 14 Jul 2022 17:22:22 +0200 Subject: [PATCH 45/66] Test that authenticated user gets allContributions. --- .../resolver/ContributionResolver.test.ts | 35 +++++++++++++++++-- 1 file changed, 33 insertions(+), 2 deletions(-) diff --git a/backend/src/graphql/resolver/ContributionResolver.test.ts b/backend/src/graphql/resolver/ContributionResolver.test.ts index a4cb1d714..9aa247d4e 100644 --- a/backend/src/graphql/resolver/ContributionResolver.test.ts +++ b/backend/src/graphql/resolver/ContributionResolver.test.ts @@ -261,9 +261,9 @@ describe('ContributionResolver', () => { beforeAll(async () => { await userFactory(testEnv, bibiBloxberg) await userFactory(testEnv, peterLustig) - const bibisCreation = creations.find((creation) => creation.email === 'bibi@bloxberg.de') + creations.forEach(async (creation) => await creationFactory(testEnv, creation!)) // eslint-disable-next-line @typescript-eslint/no-non-null-assertion - await creationFactory(testEnv, bibisCreation!) + // await creationFactory(testEnv, creations!) await query({ query: login, variables: { email: 'bibi@bloxberg.de', password: 'Aa12345_' }, @@ -282,6 +282,37 @@ describe('ContributionResolver', () => { await cleanDB() await con.close() }) + + it('returns allCreation', async () => { + await expect( + query({ + query: listAllContributions, + variables: { + currentPage: 1, + pageSize: 25, + order: 'DESC', + filterConfirmed: false, + }, + }), + ).resolves.toEqual( + expect.objectContaining({ + data: { + listAllContributions: expect.arrayContaining([ + expect.objectContaining({ + id: expect.any(Number), + memo: 'Herzlich Willkommen bei Gradido!', + amount: '1000', + }), + expect.objectContaining({ + id: expect.any(Number), + memo: 'Test env contribution', + amount: '100', + }), + ]), + }, + }), + ) + }) }) }) }) From 3733bf511483f09fae6d37c2e5926c75ae247487 Mon Sep 17 00:00:00 2001 From: elweyn Date: Thu, 14 Jul 2022 17:30:21 +0200 Subject: [PATCH 46/66] Change con.close to resetToken method. --- backend/src/graphql/resolver/ContributionResolver.test.ts | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/backend/src/graphql/resolver/ContributionResolver.test.ts b/backend/src/graphql/resolver/ContributionResolver.test.ts index 9aa247d4e..124adff18 100644 --- a/backend/src/graphql/resolver/ContributionResolver.test.ts +++ b/backend/src/graphql/resolver/ContributionResolver.test.ts @@ -170,7 +170,7 @@ describe('ContributionResolver', () => { afterAll(async () => { await cleanDB() - await con.close() + resetToken() }) describe('filter confirmed is false', () => { @@ -280,7 +280,7 @@ describe('ContributionResolver', () => { afterAll(async () => { await cleanDB() - await con.close() + resetToken() }) it('returns allCreation', async () => { From 34de4bb9014497a0db5a2d0d5cdcf662ff954ee2 Mon Sep 17 00:00:00 2001 From: elweyn Date: Thu, 14 Jul 2022 17:42:49 +0200 Subject: [PATCH 47/66] Merge conflict on contribution resolver test file --- .../resolver/ContributionResolver.test.ts | 142 ++++++++++-------- 1 file changed, 78 insertions(+), 64 deletions(-) diff --git a/backend/src/graphql/resolver/ContributionResolver.test.ts b/backend/src/graphql/resolver/ContributionResolver.test.ts index fd9636439..4f57cc0a1 100644 --- a/backend/src/graphql/resolver/ContributionResolver.test.ts +++ b/backend/src/graphql/resolver/ContributionResolver.test.ts @@ -2,17 +2,12 @@ /* eslint-disable @typescript-eslint/explicit-module-boundary-types */ import { bibiBloxberg } from '@/seeds/users/bibi-bloxberg' -<<<<<<< HEAD -import { createContribution } from '@/seeds/graphql/mutations' -import { listAllContributions, listContributions, login } from '@/seeds/graphql/queries' -======= import { adminUpdateContribution, createContribution, updateContribution, } from '@/seeds/graphql/mutations' -import { listContributions, login } from '@/seeds/graphql/queries' ->>>>>>> master +import { listAllContributions, listContributions, login } from '@/seeds/graphql/queries' import { cleanDB, resetToken, testEnvironment } from '@test/helpers' import { GraphQLError } from 'graphql' import { userFactory } from '@/seeds/factory/user' @@ -246,19 +241,6 @@ describe('ContributionResolver', () => { }) }) -<<<<<<< HEAD - describe('listAllContribution', () => { - describe('unauthenticated', () => { - it('returns an error', async () => { - await expect( - query({ - query: listAllContributions, - variables: { - currentPage: 1, - pageSize: 25, - order: 'DESC', - filterConfirmed: false, -======= describe('updateContribution', () => { describe('unauthenticated', () => { it('returns an error', async () => { @@ -270,7 +252,6 @@ describe('ContributionResolver', () => { amount: 100.0, memo: 'Test Contribution', creationDate: 'not-valid', ->>>>>>> master }, }), ).resolves.toEqual( @@ -283,25 +264,13 @@ describe('ContributionResolver', () => { describe('authenticated', () => { beforeAll(async () => { -<<<<<<< HEAD - await userFactory(testEnv, bibiBloxberg) - await userFactory(testEnv, peterLustig) - creations.forEach(async (creation) => await creationFactory(testEnv, creation!)) - // eslint-disable-next-line @typescript-eslint/no-non-null-assertion - // await creationFactory(testEnv, creations!) -======= await userFactory(testEnv, peterLustig) await userFactory(testEnv, bibiBloxberg) ->>>>>>> master await query({ query: login, variables: { email: 'bibi@bloxberg.de', password: 'Aa12345_' }, }) -<<<<<<< HEAD - await mutate({ -======= result = await mutate({ ->>>>>>> master mutation: createContribution, variables: { amount: 100.0, @@ -316,37 +285,6 @@ describe('ContributionResolver', () => { resetToken() }) -<<<<<<< HEAD - it('returns allCreation', async () => { - await expect( - query({ - query: listAllContributions, - variables: { - currentPage: 1, - pageSize: 25, - order: 'DESC', - filterConfirmed: false, - }, - }), - ).resolves.toEqual( - expect.objectContaining({ - data: { - listAllContributions: expect.arrayContaining([ - expect.objectContaining({ - id: expect.any(Number), - memo: 'Herzlich Willkommen bei Gradido!', - amount: '1000', - }), - expect.objectContaining({ - id: expect.any(Number), - memo: 'Test env contribution', - amount: '100', - }), - ]), - }, - }), - ) -======= describe('wrong contribution id', () => { it('throws an error', async () => { await expect( @@ -497,8 +435,84 @@ describe('ContributionResolver', () => { }), ) }) ->>>>>>> master + }) + + describe('listAllContribution', () => { + describe('unauthenticated', () => { + it('returns an error', async () => { + await expect( + query({ + query: listAllContributions, + variables: { + currentPage: 1, + pageSize: 25, + order: 'DESC', + filterConfirmed: false, + }, + }), + ).resolves.toEqual( + expect.objectContaining({ + errors: [new GraphQLError('401 Unauthorized')], + }), + ) + }) + }) }) }) }) + + describe('authenticated', () => { + beforeAll(async () => { + await userFactory(testEnv, bibiBloxberg) + await userFactory(testEnv, peterLustig) + creations.forEach(async (creation) => await creationFactory(testEnv, creation!)) + // eslint-disable-next-line @typescript-eslint/no-non-null-assertion + // await creationFactory(testEnv, creations!) + await userFactory(testEnv, peterLustig) + await userFactory(testEnv, bibiBloxberg) + await query({ + query: login, + variables: { email: 'bibi@bloxberg.de', password: 'Aa12345_' }, + }) + result = await mutate({ + mutation: createContribution, + variables: { + amount: 100.0, + memo: 'Test env contribution', + creationDate: new Date().toString(), + }, + }) + }) + + it('returns allCreation', async () => { + await expect( + query({ + query: listAllContributions, + variables: { + currentPage: 1, + pageSize: 25, + order: 'DESC', + filterConfirmed: false, + }, + }), + ).resolves.toEqual( + expect.objectContaining({ + data: { + listAllContributions: expect.arrayContaining([ + expect.objectContaining({ + id: expect.any(Number), + memo: 'Herzlich Willkommen bei Gradido!', + amount: '1000', + }), + expect.objectContaining({ + id: expect.any(Number), + memo: 'Test env contribution', + amount: '100', + }), + ]), + }, + }), + ) + }) + }) }) From c242f977337a5e048dcd1cfecf818f3d92d0456d Mon Sep 17 00:00:00 2001 From: elweyn Date: Thu, 14 Jul 2022 17:52:31 +0200 Subject: [PATCH 48/66] Change the test for listAllContributions to have every seed user and create all creations, add Test suite that checks if every seeded data arrives as well. --- .../resolver/ContributionResolver.test.ts | 141 +++++++++--------- 1 file changed, 72 insertions(+), 69 deletions(-) diff --git a/backend/src/graphql/resolver/ContributionResolver.test.ts b/backend/src/graphql/resolver/ContributionResolver.test.ts index 4f57cc0a1..b294fb40d 100644 --- a/backend/src/graphql/resolver/ContributionResolver.test.ts +++ b/backend/src/graphql/resolver/ContributionResolver.test.ts @@ -14,6 +14,8 @@ 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 { bobBaumeister } from '@/seeds/users/bob-baumeister' +import { raeuberHotzenplotz } from '@/seeds/users/raeuber-hotzenplotz' let mutate: any, query: any, con: any let testEnv: any @@ -436,83 +438,84 @@ describe('ContributionResolver', () => { ) }) }) - - describe('listAllContribution', () => { - describe('unauthenticated', () => { - it('returns an error', async () => { - await expect( - query({ - query: listAllContributions, - variables: { - currentPage: 1, - pageSize: 25, - order: 'DESC', - filterConfirmed: false, - }, - }), - ).resolves.toEqual( - expect.objectContaining({ - errors: [new GraphQLError('401 Unauthorized')], - }), - ) - }) - }) - }) }) }) - describe('authenticated', () => { - beforeAll(async () => { - await userFactory(testEnv, bibiBloxberg) - await userFactory(testEnv, peterLustig) - creations.forEach(async (creation) => await creationFactory(testEnv, creation!)) - // eslint-disable-next-line @typescript-eslint/no-non-null-assertion - // await creationFactory(testEnv, creations!) - await userFactory(testEnv, peterLustig) - await userFactory(testEnv, bibiBloxberg) - await query({ - query: login, - variables: { email: 'bibi@bloxberg.de', password: 'Aa12345_' }, - }) - result = await mutate({ - mutation: createContribution, - variables: { - amount: 100.0, - memo: 'Test env contribution', - creationDate: new Date().toString(), - }, + describe('listAllContribution', () => { + describe('unauthenticated', () => { + it('returns an error', async () => { + await expect( + query({ + query: listAllContributions, + variables: { + currentPage: 1, + pageSize: 25, + order: 'DESC', + filterConfirmed: false, + }, + }), + ).resolves.toEqual( + expect.objectContaining({ + errors: [new GraphQLError('401 Unauthorized')], + }), + ) }) }) - it('returns allCreation', async () => { - await expect( - query({ - query: listAllContributions, + describe('authenticated', () => { + beforeAll(async () => { + await userFactory(testEnv, bibiBloxberg) + await userFactory(testEnv, peterLustig) + await userFactory(testEnv, raeuberHotzenplotz) + await userFactory(testEnv, bobBaumeister) + creations.forEach(async (creation) => await creationFactory(testEnv, creation!)) + await query({ + query: login, + variables: { email: 'bibi@bloxberg.de', password: 'Aa12345_' }, + }) + result = await mutate({ + mutation: createContribution, variables: { - currentPage: 1, - pageSize: 25, - order: 'DESC', - filterConfirmed: false, + amount: 100.0, + memo: 'Test env contribution', + creationDate: new Date().toString(), }, - }), - ).resolves.toEqual( - expect.objectContaining({ - data: { - listAllContributions: expect.arrayContaining([ - expect.objectContaining({ - id: expect.any(Number), - memo: 'Herzlich Willkommen bei Gradido!', - amount: '1000', - }), - expect.objectContaining({ - id: expect.any(Number), - memo: 'Test env contribution', - amount: '100', - }), - ]), - }, - }), - ) + }) + }) + + it('returns allCreation', async () => { + await expect( + query({ + query: listAllContributions, + variables: { + currentPage: 1, + pageSize: 25, + order: 'DESC', + filterConfirmed: false, + }, + }), + ).resolves.toEqual( + expect.objectContaining({ + data: { + listAllContributions: { + linkCount: 25, + linkList: expect.arrayContaining([ + expect.objectContaining({ + id: expect.any(Number), + memo: 'Herzlich Willkommen bei Gradido!', + amount: '1000', + }), + expect.objectContaining({ + id: expect.any(Number), + memo: 'Test env contribution', + amount: '100', + }), + ]), + }, + }, + }), + ) + }) }) }) }) From b86ddbf8b0be90856de0a3a3e2b990745e9a5804 Mon Sep 17 00:00:00 2001 From: elweyn Date: Thu, 14 Jul 2022 18:08:51 +0200 Subject: [PATCH 49/66] Fix linting. --- backend/src/graphql/resolver/ContributionResolver.test.ts | 1 + backend/src/graphql/resolver/ContributionResolver.ts | 2 +- 2 files changed, 2 insertions(+), 1 deletion(-) diff --git a/backend/src/graphql/resolver/ContributionResolver.test.ts b/backend/src/graphql/resolver/ContributionResolver.test.ts index b294fb40d..247d1be0e 100644 --- a/backend/src/graphql/resolver/ContributionResolver.test.ts +++ b/backend/src/graphql/resolver/ContributionResolver.test.ts @@ -468,6 +468,7 @@ describe('ContributionResolver', () => { await userFactory(testEnv, peterLustig) await userFactory(testEnv, raeuberHotzenplotz) await userFactory(testEnv, bobBaumeister) + // eslint-disable-next-line @typescript-eslint/no-non-null-assertion creations.forEach(async (creation) => await creationFactory(testEnv, creation!)) await query({ query: login, diff --git a/backend/src/graphql/resolver/ContributionResolver.ts b/backend/src/graphql/resolver/ContributionResolver.ts index 3faffb95d..cdaa5faa3 100644 --- a/backend/src/graphql/resolver/ContributionResolver.ts +++ b/backend/src/graphql/resolver/ContributionResolver.ts @@ -4,7 +4,7 @@ import { backendLogger as logger } from '@/server/logger' import { Contribution as dbContribution } from '@entity/Contribution' import { User as dbUser } from '@entity/User' import { Arg, Args, Authorized, Ctx, Int, Mutation, Query, Resolver } from 'type-graphql' -import { FindOperator, IsNull, Not } from '@dbTools/typeorm' +import { FindOperator, IsNull } from '@dbTools/typeorm' import ContributionArgs from '@arg/ContributionArgs' import Paginated from '@arg/Paginated' import { Order } from '@enum/Order' From 9af614d437b845e8c5e3eafb48de78a2b21da61b Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Claus-Peter=20H=C3=BCbner?= Date: Fri, 15 Jul 2022 00:37:07 +0200 Subject: [PATCH 50/66] invert default setting of EVENT_PROTOCOL_ENABLED --- backend/.env.dist | 120 +++++----- backend/.env.template | 110 ++++----- backend/src/config/index.ts | 258 +++++++++++----------- backend/src/event/EventProtocolEmitter.ts | 77 +++---- deployment/bare_metal/.env.dist | 158 ++++++------- 5 files changed, 362 insertions(+), 361 deletions(-) diff --git a/backend/.env.dist b/backend/.env.dist index 0e8148a8a..fc8544b96 100644 --- a/backend/.env.dist +++ b/backend/.env.dist @@ -1,60 +1,60 @@ -CONFIG_VERSION=v9.2022-07-07 - -# Server -PORT=4000 -JWT_SECRET=secret123 -JWT_EXPIRES_IN=10m -GRAPHIQL=false -GDT_API_URL=https://gdt.gradido.net - -# Database -DB_HOST=localhost -DB_PORT=3306 -DB_USER=root -DB_PASSWORD= -DB_DATABASE=gradido_community -TYPEORM_LOGGING_RELATIVE_PATH=typeorm.backend.log - -# Klicktipp -KLICKTIPP=false -KLICKTTIPP_API_URL=https://api.klicktipp.com -KLICKTIPP_USER=gradido_test -KLICKTIPP_PASSWORD=secret321 -KLICKTIPP_APIKEY_DE=SomeFakeKeyDE -KLICKTIPP_APIKEY_EN=SomeFakeKeyEN - -# Community -COMMUNITY_NAME=Gradido Entwicklung -COMMUNITY_URL=http://localhost/ -COMMUNITY_REGISTER_URL=http://localhost/register -COMMUNITY_REDEEM_URL=http://localhost/redeem/{code} -COMMUNITY_REDEEM_CONTRIBUTION_URL=http://localhost/redeem/CL-{code} -COMMUNITY_DESCRIPTION=Die lokale Entwicklungsumgebung von Gradido. - -# Login Server -LOGIN_APP_SECRET=21ffbbc616fe -LOGIN_SERVER_KEY=a51ef8ac7ef1abf162fb7a65261acd7a - -# EMail -EMAIL=false -EMAIL_USERNAME=gradido_email -EMAIL_SENDER=info@gradido.net -EMAIL_PASSWORD=xxx -EMAIL_SMTP_URL=gmail.com -EMAIL_SMTP_PORT=587 -EMAIL_LINK_VERIFICATION=http://localhost/checkEmail/{optin}{code} -EMAIL_LINK_SETPASSWORD=http://localhost/reset-password/{optin} -EMAIL_LINK_FORGOTPASSWORD=http://localhost/forgot-password -EMAIL_LINK_OVERVIEW=http://localhost/overview -EMAIL_CODE_VALID_TIME=1440 -EMAIL_CODE_REQUEST_TIME=10 - -# Webhook -WEBHOOK_ELOPAGE_SECRET=secret - -# EventProtocol -EVENT_PROTOCOL_ENABLED=true - -# SET LOG LEVEL AS NEEDED IN YOUR .ENV -# POSSIBLE VALUES: all | trace | debug | info | warn | error | fatal -# LOG_LEVEL=info +CONFIG_VERSION=v9.2022-07-07 + +# Server +PORT=4000 +JWT_SECRET=secret123 +JWT_EXPIRES_IN=10m +GRAPHIQL=false +GDT_API_URL=https://gdt.gradido.net + +# Database +DB_HOST=localhost +DB_PORT=3306 +DB_USER=root +DB_PASSWORD= +DB_DATABASE=gradido_community +TYPEORM_LOGGING_RELATIVE_PATH=typeorm.backend.log + +# Klicktipp +KLICKTIPP=false +KLICKTTIPP_API_URL=https://api.klicktipp.com +KLICKTIPP_USER=gradido_test +KLICKTIPP_PASSWORD=secret321 +KLICKTIPP_APIKEY_DE=SomeFakeKeyDE +KLICKTIPP_APIKEY_EN=SomeFakeKeyEN + +# Community +COMMUNITY_NAME=Gradido Entwicklung +COMMUNITY_URL=http://localhost/ +COMMUNITY_REGISTER_URL=http://localhost/register +COMMUNITY_REDEEM_URL=http://localhost/redeem/{code} +COMMUNITY_REDEEM_CONTRIBUTION_URL=http://localhost/redeem/CL-{code} +COMMUNITY_DESCRIPTION=Die lokale Entwicklungsumgebung von Gradido. + +# Login Server +LOGIN_APP_SECRET=21ffbbc616fe +LOGIN_SERVER_KEY=a51ef8ac7ef1abf162fb7a65261acd7a + +# EMail +EMAIL=false +EMAIL_USERNAME=gradido_email +EMAIL_SENDER=info@gradido.net +EMAIL_PASSWORD=xxx +EMAIL_SMTP_URL=gmail.com +EMAIL_SMTP_PORT=587 +EMAIL_LINK_VERIFICATION=http://localhost/checkEmail/{optin}{code} +EMAIL_LINK_SETPASSWORD=http://localhost/reset-password/{optin} +EMAIL_LINK_FORGOTPASSWORD=http://localhost/forgot-password +EMAIL_LINK_OVERVIEW=http://localhost/overview +EMAIL_CODE_VALID_TIME=1440 +EMAIL_CODE_REQUEST_TIME=10 + +# Webhook +WEBHOOK_ELOPAGE_SECRET=secret + +# EventProtocol +EVENT_PROTOCOL_ENABLED=true + +# SET LOG LEVEL AS NEEDED IN YOUR .ENV +# POSSIBLE VALUES: all | trace | debug | info | warn | error | fatal +# LOG_LEVEL=info diff --git a/backend/.env.template b/backend/.env.template index 764203d7f..c6c0819e3 100644 --- a/backend/.env.template +++ b/backend/.env.template @@ -1,55 +1,55 @@ -CONFIG_VERSION=$BACKEND_CONFIG_VERSION - -# Server -JWT_SECRET=$JWT_SECRET -JWT_EXPIRES_IN=$JWT_EXPIRES_IN -GRAPHIQL=false -GDT_API_URL=$GDT_API_URL - -# Database -DB_HOST=localhost -DB_PORT=3306 -DB_USER=$DB_USER -DB_PASSWORD=$DB_PASSWORD -DB_DATABASE=gradido_community -TYPEORM_LOGGING_RELATIVE_PATH=$TYPEORM_LOGGING_RELATIVE_PATH - -# Klicktipp -KLICKTIPP=$KLICKTIPP -KLICKTTIPP_API_URL=https://api.klicktipp.com -KLICKTIPP_USER=$KLICKTIPP_USER -KLICKTIPP_PASSWORD=$KLICKTIPP_PASSWORD -KLICKTIPP_APIKEY_DE=$KLICKTIPP_APIKEY_DE -KLICKTIPP_APIKEY_EN=$KLICKTIPP_APIKEY_EN - -# Community -COMMUNITY_NAME=$COMMUNITY_NAME -COMMUNITY_URL=$COMMUNITY_URL -COMMUNITY_REGISTER_URL=$COMMUNITY_REGISTER_URL -COMMUNITY_REDEEM_URL=$COMMUNITY_REDEEM_URL -COMMUNITY_REDEEM_CONTRIBUTION_URL=$COMMUNITY_REDEEM_CONTRIBUTION_URL -COMMUNITY_DESCRIPTION=$COMMUNITY_DESCRIPTION - -# Login Server -LOGIN_APP_SECRET=21ffbbc616fe -LOGIN_SERVER_KEY=a51ef8ac7ef1abf162fb7a65261acd7a - -# EMail -EMAIL=$EMAIL -EMAIL_USERNAME=$EMAIL_USERNAME -EMAIL_SENDER=$EMAIL_SENDER -EMAIL_PASSWORD=$EMAIL_PASSWORD -EMAIL_SMTP_URL=$EMAIL_SMTP_URL -EMAIL_SMTP_PORT=587 -EMAIL_LINK_VERIFICATION=$EMAIL_LINK_VERIFICATION -EMAIL_LINK_SETPASSWORD=$EMAIL_LINK_SETPASSWORD -EMAIL_LINK_FORGOTPASSWORD=$EMAIL_LINK_FORGOTPASSWORD -EMAIL_LINK_OVERVIEW=$EMAIL_LINK_OVERVIEW -EMAIL_CODE_VALID_TIME=$EMAIL_CODE_VALID_TIME -EMAIL_CODE_REQUEST_TIME=$EMAIL_CODE_REQUEST_TIME - -# Webhook -WEBHOOK_ELOPAGE_SECRET=$WEBHOOK_ELOPAGE_SECRET - -# EventProtocol -EVENT_PROTOCOL_ENABLED=true +CONFIG_VERSION=$BACKEND_CONFIG_VERSION + +# Server +JWT_SECRET=$JWT_SECRET +JWT_EXPIRES_IN=$JWT_EXPIRES_IN +GRAPHIQL=false +GDT_API_URL=$GDT_API_URL + +# Database +DB_HOST=localhost +DB_PORT=3306 +DB_USER=$DB_USER +DB_PASSWORD=$DB_PASSWORD +DB_DATABASE=gradido_community +TYPEORM_LOGGING_RELATIVE_PATH=$TYPEORM_LOGGING_RELATIVE_PATH + +# Klicktipp +KLICKTIPP=$KLICKTIPP +KLICKTTIPP_API_URL=https://api.klicktipp.com +KLICKTIPP_USER=$KLICKTIPP_USER +KLICKTIPP_PASSWORD=$KLICKTIPP_PASSWORD +KLICKTIPP_APIKEY_DE=$KLICKTIPP_APIKEY_DE +KLICKTIPP_APIKEY_EN=$KLICKTIPP_APIKEY_EN + +# Community +COMMUNITY_NAME=$COMMUNITY_NAME +COMMUNITY_URL=$COMMUNITY_URL +COMMUNITY_REGISTER_URL=$COMMUNITY_REGISTER_URL +COMMUNITY_REDEEM_URL=$COMMUNITY_REDEEM_URL +COMMUNITY_REDEEM_CONTRIBUTION_URL=$COMMUNITY_REDEEM_CONTRIBUTION_URL +COMMUNITY_DESCRIPTION=$COMMUNITY_DESCRIPTION + +# Login Server +LOGIN_APP_SECRET=21ffbbc616fe +LOGIN_SERVER_KEY=a51ef8ac7ef1abf162fb7a65261acd7a + +# EMail +EMAIL=$EMAIL +EMAIL_USERNAME=$EMAIL_USERNAME +EMAIL_SENDER=$EMAIL_SENDER +EMAIL_PASSWORD=$EMAIL_PASSWORD +EMAIL_SMTP_URL=$EMAIL_SMTP_URL +EMAIL_SMTP_PORT=587 +EMAIL_LINK_VERIFICATION=$EMAIL_LINK_VERIFICATION +EMAIL_LINK_SETPASSWORD=$EMAIL_LINK_SETPASSWORD +EMAIL_LINK_FORGOTPASSWORD=$EMAIL_LINK_FORGOTPASSWORD +EMAIL_LINK_OVERVIEW=$EMAIL_LINK_OVERVIEW +EMAIL_CODE_VALID_TIME=$EMAIL_CODE_VALID_TIME +EMAIL_CODE_REQUEST_TIME=$EMAIL_CODE_REQUEST_TIME + +# Webhook +WEBHOOK_ELOPAGE_SECRET=$WEBHOOK_ELOPAGE_SECRET + +# EventProtocol +EVENT_PROTOCOL_ENABLED=true diff --git a/backend/src/config/index.ts b/backend/src/config/index.ts index cb56f7971..240b4d61e 100644 --- a/backend/src/config/index.ts +++ b/backend/src/config/index.ts @@ -1,129 +1,129 @@ -// ATTENTION: DO NOT PUT ANY SECRETS IN HERE (or the .env) - -import dotenv from 'dotenv' -import Decimal from 'decimal.js-light' -dotenv.config() - -Decimal.set({ - precision: 25, - rounding: Decimal.ROUND_HALF_UP, -}) - -const constants = { - DB_VERSION: '0043-add_event_protocol_table', - 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 - LOG_LEVEL: process.env.LOG_LEVEL || 'info', - CONFIG_VERSION: { - DEFAULT: 'DEFAULT', - EXPECTED: 'v9.2022-07-07', - CURRENT: '', - }, -} - -const server = { - PORT: process.env.PORT || 4000, - JWT_SECRET: process.env.JWT_SECRET || 'secret123', - JWT_EXPIRES_IN: process.env.JWT_EXPIRES_IN || '10m', - GRAPHIQL: process.env.GRAPHIQL === 'true' || false, - GDT_API_URL: process.env.GDT_API_URL || 'https://gdt.gradido.net', - PRODUCTION: process.env.NODE_ENV === 'production' || false, -} - -const database = { - DB_HOST: process.env.DB_HOST || 'localhost', - DB_PORT: process.env.DB_PORT ? parseInt(process.env.DB_PORT) : 3306, - DB_USER: process.env.DB_USER || 'root', - DB_PASSWORD: process.env.DB_PASSWORD || '', - DB_DATABASE: process.env.DB_DATABASE || 'gradido_community', - TYPEORM_LOGGING_RELATIVE_PATH: process.env.TYPEORM_LOGGING_RELATIVE_PATH || 'typeorm.backend.log', -} - -const klicktipp = { - KLICKTIPP: process.env.KLICKTIPP === 'true' || false, - KLICKTTIPP_API_URL: process.env.KLICKTIPP_API_URL || 'https://api.klicktipp.com', - KLICKTIPP_USER: process.env.KLICKTIPP_USER || 'gradido_test', - KLICKTIPP_PASSWORD: process.env.KLICKTIPP_PASSWORD || 'secret321', - KLICKTIPP_APIKEY_DE: process.env.KLICKTIPP_APIKEY_DE || 'SomeFakeKeyDE', - KLICKTIPP_APIKEY_EN: process.env.KLICKTIPP_APIKEY_EN || 'SomeFakeKeyEN', -} - -const community = { - COMMUNITY_NAME: process.env.COMMUNITY_NAME || 'Gradido Entwicklung', - COMMUNITY_URL: process.env.COMMUNITY_URL || 'http://localhost/', - COMMUNITY_REGISTER_URL: process.env.COMMUNITY_REGISTER_URL || 'http://localhost/register', - COMMUNITY_REDEEM_URL: process.env.COMMUNITY_REDEEM_URL || 'http://localhost/redeem/{code}', - COMMUNITY_REDEEM_CONTRIBUTION_URL: - process.env.COMMUNITY_REDEEM_CONTRIBUTION_URL || 'http://localhost/redeem/CL-{code}', - COMMUNITY_DESCRIPTION: - process.env.COMMUNITY_DESCRIPTION || 'Die lokale Entwicklungsumgebung von Gradido.', -} - -const loginServer = { - LOGIN_APP_SECRET: process.env.LOGIN_APP_SECRET || '21ffbbc616fe', - LOGIN_SERVER_KEY: process.env.LOGIN_SERVER_KEY || 'a51ef8ac7ef1abf162fb7a65261acd7a', -} - -const email = { - EMAIL: process.env.EMAIL === 'true' || false, - EMAIL_USERNAME: process.env.EMAIL_USERNAME || 'gradido_email', - EMAIL_SENDER: process.env.EMAIL_SENDER || 'info@gradido.net', - EMAIL_PASSWORD: process.env.EMAIL_PASSWORD || 'xxx', - EMAIL_SMTP_URL: process.env.EMAIL_SMTP_URL || 'gmail.com', - EMAIL_SMTP_PORT: process.env.EMAIL_SMTP_PORT || '587', - EMAIL_LINK_VERIFICATION: - process.env.EMAIL_LINK_VERIFICATION || 'http://localhost/checkEmail/{optin}{code}', - EMAIL_LINK_SETPASSWORD: - process.env.EMAIL_LINK_SETPASSWORD || 'http://localhost/reset-password/{optin}', - EMAIL_LINK_FORGOTPASSWORD: - process.env.EMAIL_LINK_FORGOTPASSWORD || 'http://localhost/forgot-password', - EMAIL_LINK_OVERVIEW: process.env.EMAIL_LINK_OVERVIEW || 'http://localhost/overview', - // time in minutes a optin code is valid - EMAIL_CODE_VALID_TIME: process.env.EMAIL_CODE_VALID_TIME - ? parseInt(process.env.EMAIL_CODE_VALID_TIME) || 1440 - : 1440, - // time in minutes that must pass to request a new optin code - EMAIL_CODE_REQUEST_TIME: process.env.EMAIL_CODE_REQUEST_TIME - ? parseInt(process.env.EMAIL_CODE_REQUEST_TIME) || 10 - : 10, -} - -const webhook = { - // Elopage - WEBHOOK_ELOPAGE_SECRET: process.env.WEBHOOK_ELOPAGE_SECRET || 'secret', -} - -const eventProtocol = { - // global switch to enable writing of EventProtocol-Entries - EVENT_PROTOCOL_ENABLED: process.env.EVENT_PROTOCOL_ENABLED === 'true' || false, -} - -// This is needed by graphql-directive-auth -process.env.APP_SECRET = server.JWT_SECRET - -// Check config version -constants.CONFIG_VERSION.CURRENT = process.env.CONFIG_VERSION || constants.CONFIG_VERSION.DEFAULT -if ( - ![constants.CONFIG_VERSION.EXPECTED, constants.CONFIG_VERSION.DEFAULT].includes( - constants.CONFIG_VERSION.CURRENT, - ) -) { - throw new Error( - `Fatal: Config Version incorrect - expected "${constants.CONFIG_VERSION.EXPECTED}" or "${constants.CONFIG_VERSION.DEFAULT}", but found "${constants.CONFIG_VERSION.CURRENT}"`, - ) -} - -const CONFIG = { - ...constants, - ...server, - ...database, - ...klicktipp, - ...community, - ...email, - ...loginServer, - ...webhook, - ...eventProtocol, -} - -export default CONFIG +// ATTENTION: DO NOT PUT ANY SECRETS IN HERE (or the .env) + +import dotenv from 'dotenv' +import Decimal from 'decimal.js-light' +dotenv.config() + +Decimal.set({ + precision: 25, + rounding: Decimal.ROUND_HALF_UP, +}) + +const constants = { + DB_VERSION: '0043-add_event_protocol_table', + 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 + LOG_LEVEL: process.env.LOG_LEVEL || 'info', + CONFIG_VERSION: { + DEFAULT: 'DEFAULT', + EXPECTED: 'v9.2022-07-07', + CURRENT: '', + }, +} + +const server = { + PORT: process.env.PORT || 4000, + JWT_SECRET: process.env.JWT_SECRET || 'secret123', + JWT_EXPIRES_IN: process.env.JWT_EXPIRES_IN || '10m', + GRAPHIQL: process.env.GRAPHIQL === 'true' || false, + GDT_API_URL: process.env.GDT_API_URL || 'https://gdt.gradido.net', + PRODUCTION: process.env.NODE_ENV === 'production' || false, +} + +const database = { + DB_HOST: process.env.DB_HOST || 'localhost', + DB_PORT: process.env.DB_PORT ? parseInt(process.env.DB_PORT) : 3306, + DB_USER: process.env.DB_USER || 'root', + DB_PASSWORD: process.env.DB_PASSWORD || '', + DB_DATABASE: process.env.DB_DATABASE || 'gradido_community', + TYPEORM_LOGGING_RELATIVE_PATH: process.env.TYPEORM_LOGGING_RELATIVE_PATH || 'typeorm.backend.log', +} + +const klicktipp = { + KLICKTIPP: process.env.KLICKTIPP === 'true' || false, + KLICKTTIPP_API_URL: process.env.KLICKTIPP_API_URL || 'https://api.klicktipp.com', + KLICKTIPP_USER: process.env.KLICKTIPP_USER || 'gradido_test', + KLICKTIPP_PASSWORD: process.env.KLICKTIPP_PASSWORD || 'secret321', + KLICKTIPP_APIKEY_DE: process.env.KLICKTIPP_APIKEY_DE || 'SomeFakeKeyDE', + KLICKTIPP_APIKEY_EN: process.env.KLICKTIPP_APIKEY_EN || 'SomeFakeKeyEN', +} + +const community = { + COMMUNITY_NAME: process.env.COMMUNITY_NAME || 'Gradido Entwicklung', + COMMUNITY_URL: process.env.COMMUNITY_URL || 'http://localhost/', + COMMUNITY_REGISTER_URL: process.env.COMMUNITY_REGISTER_URL || 'http://localhost/register', + COMMUNITY_REDEEM_URL: process.env.COMMUNITY_REDEEM_URL || 'http://localhost/redeem/{code}', + COMMUNITY_REDEEM_CONTRIBUTION_URL: + process.env.COMMUNITY_REDEEM_CONTRIBUTION_URL || 'http://localhost/redeem/CL-{code}', + COMMUNITY_DESCRIPTION: + process.env.COMMUNITY_DESCRIPTION || 'Die lokale Entwicklungsumgebung von Gradido.', +} + +const loginServer = { + LOGIN_APP_SECRET: process.env.LOGIN_APP_SECRET || '21ffbbc616fe', + LOGIN_SERVER_KEY: process.env.LOGIN_SERVER_KEY || 'a51ef8ac7ef1abf162fb7a65261acd7a', +} + +const email = { + EMAIL: process.env.EMAIL === 'true' || false, + EMAIL_USERNAME: process.env.EMAIL_USERNAME || 'gradido_email', + EMAIL_SENDER: process.env.EMAIL_SENDER || 'info@gradido.net', + EMAIL_PASSWORD: process.env.EMAIL_PASSWORD || 'xxx', + EMAIL_SMTP_URL: process.env.EMAIL_SMTP_URL || 'gmail.com', + EMAIL_SMTP_PORT: process.env.EMAIL_SMTP_PORT || '587', + EMAIL_LINK_VERIFICATION: + process.env.EMAIL_LINK_VERIFICATION || 'http://localhost/checkEmail/{optin}{code}', + EMAIL_LINK_SETPASSWORD: + process.env.EMAIL_LINK_SETPASSWORD || 'http://localhost/reset-password/{optin}', + EMAIL_LINK_FORGOTPASSWORD: + process.env.EMAIL_LINK_FORGOTPASSWORD || 'http://localhost/forgot-password', + EMAIL_LINK_OVERVIEW: process.env.EMAIL_LINK_OVERVIEW || 'http://localhost/overview', + // time in minutes a optin code is valid + EMAIL_CODE_VALID_TIME: process.env.EMAIL_CODE_VALID_TIME + ? parseInt(process.env.EMAIL_CODE_VALID_TIME) || 1440 + : 1440, + // time in minutes that must pass to request a new optin code + EMAIL_CODE_REQUEST_TIME: process.env.EMAIL_CODE_REQUEST_TIME + ? parseInt(process.env.EMAIL_CODE_REQUEST_TIME) || 10 + : 10, +} + +const webhook = { + // Elopage + WEBHOOK_ELOPAGE_SECRET: process.env.WEBHOOK_ELOPAGE_SECRET || 'secret', +} + +const eventProtocol = { + // global switch to enable writing of EventProtocol-Entries + EVENT_PROTOCOL_ENABLED: process.env.EVENT_PROTOCOL_ENABLED || true, +} + +// This is needed by graphql-directive-auth +process.env.APP_SECRET = server.JWT_SECRET + +// Check config version +constants.CONFIG_VERSION.CURRENT = process.env.CONFIG_VERSION || constants.CONFIG_VERSION.DEFAULT +if ( + ![constants.CONFIG_VERSION.EXPECTED, constants.CONFIG_VERSION.DEFAULT].includes( + constants.CONFIG_VERSION.CURRENT, + ) +) { + throw new Error( + `Fatal: Config Version incorrect - expected "${constants.CONFIG_VERSION.EXPECTED}" or "${constants.CONFIG_VERSION.DEFAULT}", but found "${constants.CONFIG_VERSION.CURRENT}"`, + ) +} + +const CONFIG = { + ...constants, + ...server, + ...database, + ...klicktipp, + ...community, + ...email, + ...loginServer, + ...webhook, + ...eventProtocol, +} + +export default CONFIG diff --git a/backend/src/event/EventProtocolEmitter.ts b/backend/src/event/EventProtocolEmitter.ts index 5991bbded..4ee092772 100644 --- a/backend/src/event/EventProtocolEmitter.ts +++ b/backend/src/event/EventProtocolEmitter.ts @@ -1,38 +1,39 @@ -import { Event } from '@/event/Event' -import { backendLogger as logger } from '@/server/logger' -import { EventProtocol } from '@entity/EventProtocol' -import CONFIG from '@/config' - -class EventProtocolEmitter { - /* }extends EventEmitter { */ - private events: Event[] - - public addEvent(event: Event) { - this.events.push(event) - } - - public getEvents(): Event[] { - return this.events - } - - public isEnabled() { - logger.info(`EventProtocol - isEnabled=${CONFIG.EVENT_PROTOCOL_ENABLED}`) - return CONFIG.EVENT_PROTOCOL_ENABLED - } - - public async writeEvent(event: Event): Promise { - if (!eventProtocol.isEnabled()) return - logger.info(`writeEvent(${JSON.stringify(event)})`) - const dbEvent = new EventProtocol() - dbEvent.type = event.type - dbEvent.createdAt = event.createdAt - dbEvent.userId = event.userId - if (event.xUserId) dbEvent.xUserId = event.xUserId - if (event.xCommunityId) dbEvent.xCommunityId = event.xCommunityId - if (event.contributionId) dbEvent.contributionId = event.contributionId - if (event.transactionId) dbEvent.transactionId = event.transactionId - if (event.amount) dbEvent.amount = event.amount - await dbEvent.save() - } -} -export const eventProtocol = new EventProtocolEmitter() +import { Event } from '@/event/Event' +import { backendLogger as logger } from '@/server/logger' +import { EventProtocol } from '@entity/EventProtocol' +import CONFIG from '@/config' + +class EventProtocolEmitter { + /* }extends EventEmitter { */ + private events: Event[] + + public addEvent(event: Event) { + this.events.push(event) + } + + public getEvents(): Event[] { + return this.events + } + + public isEnabled() { + logger.info(`EventProtocol - isEnabled=${CONFIG.EVENT_PROTOCOL_ENABLED}`) + return CONFIG.EVENT_PROTOCOL_ENABLED === true + } + + public async writeEvent(event: Event): Promise { + if (eventProtocol.isEnabled()) { + logger.info(`writeEvent(${JSON.stringify(event)})`) + const dbEvent = new EventProtocol() + dbEvent.type = event.type + dbEvent.createdAt = event.createdAt + dbEvent.userId = event.userId + if (event.xUserId) dbEvent.xUserId = event.xUserId + if (event.xCommunityId) dbEvent.xCommunityId = event.xCommunityId + if (event.contributionId) dbEvent.contributionId = event.contributionId + if (event.transactionId) dbEvent.transactionId = event.transactionId + if (event.amount) dbEvent.amount = event.amount + await dbEvent.save() + } + } +} +export const eventProtocol = new EventProtocolEmitter() diff --git a/deployment/bare_metal/.env.dist b/deployment/bare_metal/.env.dist index edb878040..5747e40ef 100644 --- a/deployment/bare_metal/.env.dist +++ b/deployment/bare_metal/.env.dist @@ -1,80 +1,80 @@ -GRADIDO_LOG_PATH=/home/gradido/gradido/deployment/bare_metal/log - -# start script -DEPLOY_SEED_DATA=false - -# nginx -NGINX_REWRITE_LEGACY_URLS=true -NGINX_SSL=true -NGINX_SERVER_NAME=stage1.gradido.net -NGINX_SSL_CERTIFICATE=/etc/letsencrypt/live/stage1.gradido.net/fullchain.pem -NGINX_SSL_CERTIFICATE_KEY=/etc/letsencrypt/live/stage1.gradido.net/privkey.pem -NGINX_SSL_DHPARAM=/etc/letsencrypt/ssl-dhparams.pem -NGINX_SSL_INCLUDE=/etc/letsencrypt/options-ssl-nginx.conf -NGINX_UPDATE_PAGE_ROOT=/home/gradido/gradido/deployment/bare_metal/nginx/update-page - -# webhook -WEBHOOK_GITHUB_SECRET=secret -WEBHOOK_GITHUB_BRANCH=master - -# community -COMMUNITY_NAME="Gradido Development Stage1" -COMMUNITY_URL=https://stage1.gradido.net/ -COMMUNITY_REGISTER_URL=https://stage1.gradido.net/register -COMMUNITY_REDEEM_URL=https://stage1.gradido.net/redeem/{code} -COMMUNITY_REDEEM_CONTRIBUTION_URL=https://stage1.gradido.net/redeem/CL-{code} -COMMUNITY_DESCRIPTION="Gradido Development Stage1 Test Community" - -# backend -BACKEND_CONFIG_VERSION=v8.2022-06-20 - -JWT_EXPIRES_IN=10m -GDT_API_URL=https://gdt.gradido.net - -TYPEORM_LOGGING_RELATIVE_PATH=../deployment/bare_metal/log/typeorm.backend.log - -KLICKTIPP=false -KLICKTIPP_USER= -KLICKTIPP_PASSWORD= -KLICKTIPP_APIKEY_DE= -KLICKTIPP_APIKEY_EN= - -EMAIL=true -EMAIL_USERNAME=peter@lustig.de -EMAIL_SENDER=peter@lustig.de -EMAIL_PASSWORD=1234 -EMAIL_SMTP_URL=smtp.lustig.de -EMAIL_LINK_VERIFICATION=https://stage1.gradido.net/checkEmail/{optin}{code} -EMAIL_LINK_SETPASSWORD=https://stage1.gradido.net/reset-password/{optin} -EMAIL_LINK_FORGOTPASSWORD=https://stage1.gradido.net/forgot-password -EMAIL_LINK_OVERVIEW=https://stage1.gradido.net/overview -EMAIL_CODE_VALID_TIME=1440 -EMAIL_CODE_REQUEST_TIME=10 - -WEBHOOK_ELOPAGE_SECRET=secret - -# database -DATABASE_CONFIG_VERSION=v1.2022-03-18 - -# frontend -FRONTEND_CONFIG_VERSION=v2.2022-04-07 - -GRAPHQL_URI=https://stage1.gradido.net/graphql -ADMIN_AUTH_URL=https://stage1.gradido.net/admin/authenticate?token={token} - -DEFAULT_PUBLISHER_ID=2896 - -META_URL=http://localhost -META_TITLE_DE="Gradido – Dein Dankbarkeitskonto" -META_TITLE_EN="Gradido - Your gratitude account" -META_DESCRIPTION_DE="Dankbarkeit ist die Währung der neuen Zeit. Immer mehr Menschen entfalten ihr Potenzial und gestalten eine gute Zukunft für alle." -META_DESCRIPTION_EN="Gratitude is the currency of the new age. More and more people are unleashing their potential and shaping a good future for all." -META_KEYWORDS_DE="Grundeinkommen, Währung, Dankbarkeit, Schenk-Ökonomie, Natürliche Ökonomie des Lebens, Ökonomie, Ökologie, Potenzialentfaltung, Schenken und Danken, Kreislauf des Lebens, Geldsystem" -META_KEYWORDS_EN="Basic Income, Currency, Gratitude, Gift Economy, Natural Economy of Life, Economy, Ecology, Potential Development, Giving and Thanking, Cycle of Life, Monetary System" -META_AUTHOR="Bernd Hückstädt - Gradido-Akademie" - -# admin -ADMIN_CONFIG_VERSION=v1.2022-03-18 - -WALLET_AUTH_URL=https://stage1.gradido.net/authenticate?token={token} +GRADIDO_LOG_PATH=/home/gradido/gradido/deployment/bare_metal/log + +# start script +DEPLOY_SEED_DATA=false + +# nginx +NGINX_REWRITE_LEGACY_URLS=true +NGINX_SSL=true +NGINX_SERVER_NAME=stage1.gradido.net +NGINX_SSL_CERTIFICATE=/etc/letsencrypt/live/stage1.gradido.net/fullchain.pem +NGINX_SSL_CERTIFICATE_KEY=/etc/letsencrypt/live/stage1.gradido.net/privkey.pem +NGINX_SSL_DHPARAM=/etc/letsencrypt/ssl-dhparams.pem +NGINX_SSL_INCLUDE=/etc/letsencrypt/options-ssl-nginx.conf +NGINX_UPDATE_PAGE_ROOT=/home/gradido/gradido/deployment/bare_metal/nginx/update-page + +# webhook +WEBHOOK_GITHUB_SECRET=secret +WEBHOOK_GITHUB_BRANCH=master + +# community +COMMUNITY_NAME="Gradido Development Stage1" +COMMUNITY_URL=https://stage1.gradido.net/ +COMMUNITY_REGISTER_URL=https://stage1.gradido.net/register +COMMUNITY_REDEEM_URL=https://stage1.gradido.net/redeem/{code} +COMMUNITY_REDEEM_CONTRIBUTION_URL=https://stage1.gradido.net/redeem/CL-{code} +COMMUNITY_DESCRIPTION="Gradido Development Stage1 Test Community" + +# backend +BACKEND_CONFIG_VERSION=v9.2022-07-07 + +JWT_EXPIRES_IN=10m +GDT_API_URL=https://gdt.gradido.net + +TYPEORM_LOGGING_RELATIVE_PATH=../deployment/bare_metal/log/typeorm.backend.log + +KLICKTIPP=false +KLICKTIPP_USER= +KLICKTIPP_PASSWORD= +KLICKTIPP_APIKEY_DE= +KLICKTIPP_APIKEY_EN= + +EMAIL=true +EMAIL_USERNAME=peter@lustig.de +EMAIL_SENDER=peter@lustig.de +EMAIL_PASSWORD=1234 +EMAIL_SMTP_URL=smtp.lustig.de +EMAIL_LINK_VERIFICATION=https://stage1.gradido.net/checkEmail/{optin}{code} +EMAIL_LINK_SETPASSWORD=https://stage1.gradido.net/reset-password/{optin} +EMAIL_LINK_FORGOTPASSWORD=https://stage1.gradido.net/forgot-password +EMAIL_LINK_OVERVIEW=https://stage1.gradido.net/overview +EMAIL_CODE_VALID_TIME=1440 +EMAIL_CODE_REQUEST_TIME=10 + +WEBHOOK_ELOPAGE_SECRET=secret + +# database +DATABASE_CONFIG_VERSION=v1.2022-03-18 + +# frontend +FRONTEND_CONFIG_VERSION=v2.2022-04-07 + +GRAPHQL_URI=https://stage1.gradido.net/graphql +ADMIN_AUTH_URL=https://stage1.gradido.net/admin/authenticate?token={token} + +DEFAULT_PUBLISHER_ID=2896 + +META_URL=http://localhost +META_TITLE_DE="Gradido – Dein Dankbarkeitskonto" +META_TITLE_EN="Gradido - Your gratitude account" +META_DESCRIPTION_DE="Dankbarkeit ist die Währung der neuen Zeit. Immer mehr Menschen entfalten ihr Potenzial und gestalten eine gute Zukunft für alle." +META_DESCRIPTION_EN="Gratitude is the currency of the new age. More and more people are unleashing their potential and shaping a good future for all." +META_KEYWORDS_DE="Grundeinkommen, Währung, Dankbarkeit, Schenk-Ökonomie, Natürliche Ökonomie des Lebens, Ökonomie, Ökologie, Potenzialentfaltung, Schenken und Danken, Kreislauf des Lebens, Geldsystem" +META_KEYWORDS_EN="Basic Income, Currency, Gratitude, Gift Economy, Natural Economy of Life, Economy, Ecology, Potential Development, Giving and Thanking, Cycle of Life, Monetary System" +META_AUTHOR="Bernd Hückstädt - Gradido-Akademie" + +# admin +ADMIN_CONFIG_VERSION=v1.2022-03-18 + +WALLET_AUTH_URL=https://stage1.gradido.net/authenticate?token={token} WALLET_URL=https://stage1.gradido.net/login \ No newline at end of file From 175bc514be7fea2f1737e4e6861c1fa7c5680e5b Mon Sep 17 00:00:00 2001 From: Moriz Wahl Date: Fri, 15 Jul 2022 13:36:31 +0200 Subject: [PATCH 51/66] feat: Do not log IntrospectionQuery from Query Browser --- backend/src/server/plugins.ts | 22 +++++++++++++--------- 1 file changed, 13 insertions(+), 9 deletions(-) diff --git a/backend/src/server/plugins.ts b/backend/src/server/plugins.ts index 1972bc1c8..24df45baa 100644 --- a/backend/src/server/plugins.ts +++ b/backend/src/server/plugins.ts @@ -31,20 +31,24 @@ const filterVariables = (variables: any) => { const logPlugin = { requestDidStart(requestContext: any) { const { logger } = requestContext - const { query, mutation, variables } = requestContext.request - logger.info(`Request: + const { query, mutation, variables, operationName } = requestContext.request + if (operationName !== 'IntrospectionQuery') { + logger.info(`Request: ${mutation || query}variables: ${JSON.stringify(filterVariables(variables), null, 2)}`) + } return { willSendResponse(requestContext: any) { - if (requestContext.context.user) logger.info(`User ID: ${requestContext.context.user.id}`) - if (requestContext.response.data) { - logger.info('Response Success!') - logger.trace(`Response-Data: + if (operationName !== 'IntrospectionQuery') { + if (requestContext.context.user) logger.info(`User ID: ${requestContext.context.user.id}`) + if (requestContext.response.data) { + logger.info('Response Success!') + logger.trace(`Response-Data: ${JSON.stringify(requestContext.response.data, null, 2)}`) - } - if (requestContext.response.errors) - logger.error(`Response-Errors: + } + if (requestContext.response.errors) + logger.error(`Response-Errors: ${JSON.stringify(requestContext.response.errors, null, 2)}`) + } return requestContext }, } From d0662270431f112710c23748c72c6577c99eef3e Mon Sep 17 00:00:00 2001 From: elweyn Date: Fri, 15 Jul 2022 14:13:33 +0200 Subject: [PATCH 52/66] Change the Contribution entity to join on user. --- .../0039-contributions_table/Contribution.ts | 15 ++++++++++++++- 1 file changed, 14 insertions(+), 1 deletion(-) diff --git a/database/entity/0039-contributions_table/Contribution.ts b/database/entity/0039-contributions_table/Contribution.ts index 6c7358f90..ee6e0f73f 100644 --- a/database/entity/0039-contributions_table/Contribution.ts +++ b/database/entity/0039-contributions_table/Contribution.ts @@ -1,6 +1,15 @@ import Decimal from 'decimal.js-light' -import { BaseEntity, Column, Entity, PrimaryGeneratedColumn, DeleteDateColumn } from 'typeorm' +import { + BaseEntity, + Column, + Entity, + PrimaryGeneratedColumn, + DeleteDateColumn, + OneToOne, + JoinColumn, +} from 'typeorm' import { DecimalTransformer } from '../../src/typeorm/DecimalTransformer' +import { User } from '../User' @Entity('contributions') export class Contribution extends BaseEntity { @@ -10,6 +19,10 @@ export class Contribution extends BaseEntity { @Column({ unsigned: true, nullable: false, name: 'user_id' }) userId: number + @OneToOne(() => User) + @JoinColumn({ name: 'user_id' }) + user: User + @Column({ type: 'datetime', default: () => 'CURRENT_TIMESTAMP', name: 'created_at' }) createdAt: Date From 5f5c19e6ba364ee036284fb47a197a6da3683832 Mon Sep 17 00:00:00 2001 From: elweyn Date: Fri, 15 Jul 2022 14:14:15 +0200 Subject: [PATCH 53/66] Change find to much more efficient code. --- .../graphql/resolver/ContributionResolver.ts | 28 ++++++------------- 1 file changed, 8 insertions(+), 20 deletions(-) diff --git a/backend/src/graphql/resolver/ContributionResolver.ts b/backend/src/graphql/resolver/ContributionResolver.ts index 812e81527..d71ecac59 100644 --- a/backend/src/graphql/resolver/ContributionResolver.ts +++ b/backend/src/graphql/resolver/ContributionResolver.ts @@ -2,7 +2,6 @@ import { RIGHTS } from '@/auth/RIGHTS' import { Context, getUser } from '@/server/context' import { backendLogger as logger } from '@/server/logger' import { Contribution as dbContribution } from '@entity/Contribution' -import { User as dbUser } from '@entity/User' import { Arg, Args, Authorized, Ctx, Int, Mutation, Query, Resolver } from 'type-graphql' import { FindOperator, IsNull } from '@dbTools/typeorm' import ContributionArgs from '@arg/ContributionArgs' @@ -72,31 +71,20 @@ export class ContributionResolver { @Args() { currentPage = 1, pageSize = 5, order = Order.DESC }: Paginated, ): Promise { - const dbContributions = await dbContribution.find({ + const [dbContributions, count] = await dbContribution.findAndCount({ + relations: ['user'], order: { createdAt: order, }, skip: (currentPage - 1) * pageSize, take: pageSize, }) - const contributions: Contribution[] = [] - const userIds: number[] = [] - dbContributions.forEach(async (dbContribution) => { - userIds.push(dbContribution.userId) - }) - userIds.filter((elem, index, self) => { - return index === self.indexOf(elem) - }) - const users = new Map() - for (let i = 0; i < userIds.length; i++) { - const id = userIds[i] - const user = await dbUser.findOneOrFail({ id }) - users.set(id, user) - } - dbContributions.forEach((dbContribution) => { - contributions.push(new Contribution(dbContribution, users.get(dbContribution.userId))) - }) - return new ContributionListResult(contributions.length, contributions) + return new ContributionListResult( + count, + dbContributions.map( + (contribution) => new Contribution(contribution, new User(contribution.user)), + ), + ) } @Authorized([RIGHTS.UPDATE_CONTRIBUTION]) From 382211f3ca12fa9585ef853751d886672997876e Mon Sep 17 00:00:00 2001 From: elweyn Date: Fri, 15 Jul 2022 14:14:55 +0200 Subject: [PATCH 54/66] Adapt test so that we check findAllContributions. --- .../src/graphql/resolver/ContributionResolver.test.ts | 9 ++++----- 1 file changed, 4 insertions(+), 5 deletions(-) diff --git a/backend/src/graphql/resolver/ContributionResolver.test.ts b/backend/src/graphql/resolver/ContributionResolver.test.ts index 247d1be0e..fd5ff68a2 100644 --- a/backend/src/graphql/resolver/ContributionResolver.test.ts +++ b/backend/src/graphql/resolver/ContributionResolver.test.ts @@ -466,15 +466,14 @@ describe('ContributionResolver', () => { beforeAll(async () => { await userFactory(testEnv, bibiBloxberg) await userFactory(testEnv, peterLustig) - await userFactory(testEnv, raeuberHotzenplotz) - await userFactory(testEnv, bobBaumeister) + const bibisCreation = creations.find((creation) => creation.email === 'bibi@bloxberg.de') // eslint-disable-next-line @typescript-eslint/no-non-null-assertion - creations.forEach(async (creation) => await creationFactory(testEnv, creation!)) + await creationFactory(testEnv, bibisCreation!) await query({ query: login, variables: { email: 'bibi@bloxberg.de', password: 'Aa12345_' }, }) - result = await mutate({ + await mutate({ mutation: createContribution, variables: { amount: 100.0, @@ -499,7 +498,7 @@ describe('ContributionResolver', () => { expect.objectContaining({ data: { listAllContributions: { - linkCount: 25, + linkCount: 2, linkList: expect.arrayContaining([ expect.objectContaining({ id: expect.any(Number), From cada4eca19cfa95b3ba7603838f2f163effb05ad Mon Sep 17 00:00:00 2001 From: elweyn Date: Fri, 15 Jul 2022 14:32:20 +0200 Subject: [PATCH 55/66] Change OneToOne relation to OneToMany / ManyToOne. --- .../0039-contributions_table/Contribution.ts | 3 ++- .../0040-add_contribution_link_id_to_user/User.ts | 15 ++++++++++++++- 2 files changed, 16 insertions(+), 2 deletions(-) diff --git a/database/entity/0039-contributions_table/Contribution.ts b/database/entity/0039-contributions_table/Contribution.ts index ee6e0f73f..5df527530 100644 --- a/database/entity/0039-contributions_table/Contribution.ts +++ b/database/entity/0039-contributions_table/Contribution.ts @@ -7,6 +7,7 @@ import { DeleteDateColumn, OneToOne, JoinColumn, + ManyToOne, } from 'typeorm' import { DecimalTransformer } from '../../src/typeorm/DecimalTransformer' import { User } from '../User' @@ -19,7 +20,7 @@ export class Contribution extends BaseEntity { @Column({ unsigned: true, nullable: false, name: 'user_id' }) userId: number - @OneToOne(() => User) + @ManyToOne(() => User, (user) => user.contributions) @JoinColumn({ name: 'user_id' }) user: User diff --git a/database/entity/0040-add_contribution_link_id_to_user/User.ts b/database/entity/0040-add_contribution_link_id_to_user/User.ts index 9bf76e5f5..56047345a 100644 --- a/database/entity/0040-add_contribution_link_id_to_user/User.ts +++ b/database/entity/0040-add_contribution_link_id_to_user/User.ts @@ -1,4 +1,13 @@ -import { BaseEntity, Entity, PrimaryGeneratedColumn, Column, DeleteDateColumn } from 'typeorm' +import { + BaseEntity, + Entity, + PrimaryGeneratedColumn, + Column, + DeleteDateColumn, + OneToMany, + JoinColumn, +} from 'typeorm' +import { Contribution } from '../Contribution' @Entity('users', { engine: 'InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_ci' }) export class User extends BaseEntity { @@ -76,4 +85,8 @@ export class User extends BaseEntity { default: null, }) passphrase: string + + @OneToMany(() => Contribution, (contribution) => contribution.user) + @JoinColumn({ name: 'user_id' }) + contributions?: Contribution[] } From 843993e34085397eb86b8e67477bf58e94debd6a Mon Sep 17 00:00:00 2001 From: elweyn Date: Fri, 15 Jul 2022 14:34:47 +0200 Subject: [PATCH 56/66] Fix linting. --- backend/src/graphql/resolver/ContributionResolver.test.ts | 2 -- 1 file changed, 2 deletions(-) diff --git a/backend/src/graphql/resolver/ContributionResolver.test.ts b/backend/src/graphql/resolver/ContributionResolver.test.ts index fd5ff68a2..e6478ffc2 100644 --- a/backend/src/graphql/resolver/ContributionResolver.test.ts +++ b/backend/src/graphql/resolver/ContributionResolver.test.ts @@ -14,8 +14,6 @@ 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 { bobBaumeister } from '@/seeds/users/bob-baumeister' -import { raeuberHotzenplotz } from '@/seeds/users/raeuber-hotzenplotz' let mutate: any, query: any, con: any let testEnv: any From 5892f7b42947db8270fe4d26a4faed587abe68c3 Mon Sep 17 00:00:00 2001 From: elweyn Date: Fri, 15 Jul 2022 14:48:51 +0200 Subject: [PATCH 57/66] Remove OneToOne import from contribution entity. --- database/entity/0039-contributions_table/Contribution.ts | 1 - 1 file changed, 1 deletion(-) diff --git a/database/entity/0039-contributions_table/Contribution.ts b/database/entity/0039-contributions_table/Contribution.ts index 5df527530..b5e6ac0e0 100644 --- a/database/entity/0039-contributions_table/Contribution.ts +++ b/database/entity/0039-contributions_table/Contribution.ts @@ -5,7 +5,6 @@ import { Entity, PrimaryGeneratedColumn, DeleteDateColumn, - OneToOne, JoinColumn, ManyToOne, } from 'typeorm' From 5810235cec56053a6413b5601544a14b1d2b77db Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Claus-Peter=20H=C3=BCbner?= Date: Fri, 15 Jul 2022 16:40:46 +0200 Subject: [PATCH 58/66] add EVENT_PROTOCOL_ENABLED --- deployment/bare_metal/.env.dist | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/deployment/bare_metal/.env.dist b/deployment/bare_metal/.env.dist index 5747e40ef..a7f63fa27 100644 --- a/deployment/bare_metal/.env.dist +++ b/deployment/bare_metal/.env.dist @@ -53,6 +53,10 @@ EMAIL_CODE_REQUEST_TIME=10 WEBHOOK_ELOPAGE_SECRET=secret +# EventProtocol +EVENT_PROTOCOL_ENABLED=true + + # database DATABASE_CONFIG_VERSION=v1.2022-03-18 From 1ec317259b2e1b65eb70303355395c081d060004 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Wolfgang=20Hu=C3=9F?= Date: Mon, 18 Jul 2022 11:35:31 +0200 Subject: [PATCH 59/66] Document the setup of the GraphQL Playground --- backend/README.md | 52 ++++++++++++++++++++++++++++++++++++++++++++--- 1 file changed, 49 insertions(+), 3 deletions(-) diff --git a/backend/README.md b/backend/README.md index e74750c46..173450fe7 100644 --- a/backend/README.md +++ b/backend/README.md @@ -1,16 +1,18 @@ # backend ## Project setup -``` + +```bash yarn install ``` ## Seed DB -``` + +```bash yarn seed ``` -Deletes all data in database. Then seeds data in database. +Deletes all data in database. Then seeds data in database. ## Seeded Users @@ -22,3 +24,47 @@ Deletes all data in database. Then seeds data in database. | bob@baumeister.de | `Aa12345_` | `false` | `true` | `false` | | garrick@ollivander.com | | `false` | `false` | `false` | | stephen@hawking.uk | `Aa12345_` | `false` | `true` | `true` | + +## Setup GraphQL Playground + +### Setup In The Code + +Setting up the GraphQL Playground in our code requires the following steps: + +- Create an empty `.env` file in the `backend` folder and set "GRAPHIQL=true" there. +- Start or restart Docker Compose. +- For verification, Docker should display `GraphQL available at http://localhost:4000` in the terminal. +- If you open "http://localhost:4000/" in your browser, you should see the GraphQL Playground. + +### Authentication + +To authenticate yourself in GraphQL Playground to be able to send queries and mutations, follow the steps below: + +- in Firefox go to "Network Analysis" and delete all entries +- enter and send the login query: + +```gql +{ + login(email: "bibi@bloxberg.de", password:"Aa12345_") { + id + publisherId + email + firstName + lastName + emailChecked + language + hasElopage + } +} +``` + +- search in Firefox under „Network Analysis" for the smallest size of a header and copy the token +- open the header section in GraphQL Playground and set your current token by filling in and replacing `XXX`: + +```qgl +{ + "Authorization": "XXX" +} +``` + +Now you can open a new tap in the Playground and enter your query or mutation there. From c6279a3ba141f4a93dc29783ef42f718db517ab8 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Wolfgang=20Hu=C3=9F?= Date: Mon, 18 Jul 2022 12:25:36 +0200 Subject: [PATCH 60/66] Update backend/README.md Co-authored-by: Hannes Heine --- backend/README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/backend/README.md b/backend/README.md index 173450fe7..c28469aa9 100644 --- a/backend/README.md +++ b/backend/README.md @@ -38,7 +38,7 @@ Setting up the GraphQL Playground in our code requires the following steps: ### Authentication -To authenticate yourself in GraphQL Playground to be able to send queries and mutations, follow the steps below: +You need to authenticate yourself in GraphQL Playground to be able to send queries and mutations, to do so follow the steps below: - in Firefox go to "Network Analysis" and delete all entries - enter and send the login query: From b7949a62201e5592a8ddc4d0c6af113a335d0903 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Wolfgang=20Hu=C3=9F?= Date: Mon, 18 Jul 2022 12:25:58 +0200 Subject: [PATCH 61/66] Update backend/README.md Co-authored-by: Hannes Heine --- backend/README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/backend/README.md b/backend/README.md index c28469aa9..b27ab16d9 100644 --- a/backend/README.md +++ b/backend/README.md @@ -58,7 +58,7 @@ You need to authenticate yourself in GraphQL Playground to be able to send queri } ``` -- search in Firefox under „Network Analysis" for the smallest size of a header and copy the token +- search in Firefox under „Network Analysis" for the smallest size of a header and copy the value of the token - open the header section in GraphQL Playground and set your current token by filling in and replacing `XXX`: ```qgl From 212952cf5658478e2cf914a4bc1f90178589e2fc Mon Sep 17 00:00:00 2001 From: clauspeterhuebner <86960882+clauspeterhuebner@users.noreply.github.com> Date: Mon, 18 Jul 2022 19:30:25 +0200 Subject: [PATCH 62/66] Update backend/.env.dist Co-authored-by: Moriz Wahl --- backend/.env.dist | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/backend/.env.dist b/backend/.env.dist index fc8544b96..ae89985e3 100644 --- a/backend/.env.dist +++ b/backend/.env.dist @@ -53,7 +53,7 @@ EMAIL_CODE_REQUEST_TIME=10 WEBHOOK_ELOPAGE_SECRET=secret # EventProtocol -EVENT_PROTOCOL_ENABLED=true +EVENT_PROTOCOL_DISABLED=false # SET LOG LEVEL AS NEEDED IN YOUR .ENV # POSSIBLE VALUES: all | trace | debug | info | warn | error | fatal From d4f32f42e050a069c87621716f08dcda8d13a700 Mon Sep 17 00:00:00 2001 From: clauspeterhuebner <86960882+clauspeterhuebner@users.noreply.github.com> Date: Mon, 18 Jul 2022 19:30:56 +0200 Subject: [PATCH 63/66] Update backend/.env.template Co-authored-by: Moriz Wahl --- backend/.env.template | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/backend/.env.template b/backend/.env.template index c6c0819e3..8812806cc 100644 --- a/backend/.env.template +++ b/backend/.env.template @@ -52,4 +52,4 @@ EMAIL_CODE_REQUEST_TIME=$EMAIL_CODE_REQUEST_TIME WEBHOOK_ELOPAGE_SECRET=$WEBHOOK_ELOPAGE_SECRET # EventProtocol -EVENT_PROTOCOL_ENABLED=true +EVENT_PROTOCOL_DISABLED=$EVENT_PROTOCOL_DISABLED From 3e617fdf9596b075dd720750109d68444cdf870c Mon Sep 17 00:00:00 2001 From: clauspeterhuebner <86960882+clauspeterhuebner@users.noreply.github.com> Date: Mon, 18 Jul 2022 19:31:24 +0200 Subject: [PATCH 64/66] Update deployment/bare_metal/.env.dist Co-authored-by: Moriz Wahl --- deployment/bare_metal/.env.dist | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/deployment/bare_metal/.env.dist b/deployment/bare_metal/.env.dist index a7f63fa27..d53ffebbe 100644 --- a/deployment/bare_metal/.env.dist +++ b/deployment/bare_metal/.env.dist @@ -54,7 +54,7 @@ EMAIL_CODE_REQUEST_TIME=10 WEBHOOK_ELOPAGE_SECRET=secret # EventProtocol -EVENT_PROTOCOL_ENABLED=true +EVENT_PROTOCOL_DISABLED=false # database From e9b8691b388aad7032d4db11316e318f62acc9cd Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Claus-Peter=20H=C3=BCbner?= Date: Mon, 18 Jul 2022 23:53:59 +0200 Subject: [PATCH 65/66] turned around the logic --- backend/src/config/index.ts | 2 +- backend/src/event/EventProtocolEmitter.ts | 8 ++++---- 2 files changed, 5 insertions(+), 5 deletions(-) diff --git a/backend/src/config/index.ts b/backend/src/config/index.ts index 240b4d61e..2120fce71 100644 --- a/backend/src/config/index.ts +++ b/backend/src/config/index.ts @@ -96,7 +96,7 @@ const webhook = { const eventProtocol = { // global switch to enable writing of EventProtocol-Entries - EVENT_PROTOCOL_ENABLED: process.env.EVENT_PROTOCOL_ENABLED || true, + EVENT_PROTOCOL_DISABLED: process.env.EVENT_PROTOCOL_DISABLED === 'true' || false, } // This is needed by graphql-directive-auth diff --git a/backend/src/event/EventProtocolEmitter.ts b/backend/src/event/EventProtocolEmitter.ts index 4ee092772..6dea99810 100644 --- a/backend/src/event/EventProtocolEmitter.ts +++ b/backend/src/event/EventProtocolEmitter.ts @@ -15,13 +15,13 @@ class EventProtocolEmitter { return this.events } - public isEnabled() { - logger.info(`EventProtocol - isEnabled=${CONFIG.EVENT_PROTOCOL_ENABLED}`) - return CONFIG.EVENT_PROTOCOL_ENABLED === true + public isDisabled() { + logger.info(`EventProtocol - isDisabled=${CONFIG.EVENT_PROTOCOL_DISABLED}`) + return CONFIG.EVENT_PROTOCOL_DISABLED === true } public async writeEvent(event: Event): Promise { - if (eventProtocol.isEnabled()) { + if (!eventProtocol.isDisabled()) { logger.info(`writeEvent(${JSON.stringify(event)})`) const dbEvent = new EventProtocol() dbEvent.type = event.type From 86487a2ddb08dec60dc9f8a596bc0dbfeed687d0 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Claus-Peter=20H=C3=BCbner?= Date: Mon, 18 Jul 2022 23:55:13 +0200 Subject: [PATCH 66/66] change to Unix LF --- backend/.env.template | 110 +++++++++++++++++++++--------------------- 1 file changed, 55 insertions(+), 55 deletions(-) diff --git a/backend/.env.template b/backend/.env.template index 8812806cc..beaa256ef 100644 --- a/backend/.env.template +++ b/backend/.env.template @@ -1,55 +1,55 @@ -CONFIG_VERSION=$BACKEND_CONFIG_VERSION - -# Server -JWT_SECRET=$JWT_SECRET -JWT_EXPIRES_IN=$JWT_EXPIRES_IN -GRAPHIQL=false -GDT_API_URL=$GDT_API_URL - -# Database -DB_HOST=localhost -DB_PORT=3306 -DB_USER=$DB_USER -DB_PASSWORD=$DB_PASSWORD -DB_DATABASE=gradido_community -TYPEORM_LOGGING_RELATIVE_PATH=$TYPEORM_LOGGING_RELATIVE_PATH - -# Klicktipp -KLICKTIPP=$KLICKTIPP -KLICKTTIPP_API_URL=https://api.klicktipp.com -KLICKTIPP_USER=$KLICKTIPP_USER -KLICKTIPP_PASSWORD=$KLICKTIPP_PASSWORD -KLICKTIPP_APIKEY_DE=$KLICKTIPP_APIKEY_DE -KLICKTIPP_APIKEY_EN=$KLICKTIPP_APIKEY_EN - -# Community -COMMUNITY_NAME=$COMMUNITY_NAME -COMMUNITY_URL=$COMMUNITY_URL -COMMUNITY_REGISTER_URL=$COMMUNITY_REGISTER_URL -COMMUNITY_REDEEM_URL=$COMMUNITY_REDEEM_URL -COMMUNITY_REDEEM_CONTRIBUTION_URL=$COMMUNITY_REDEEM_CONTRIBUTION_URL -COMMUNITY_DESCRIPTION=$COMMUNITY_DESCRIPTION - -# Login Server -LOGIN_APP_SECRET=21ffbbc616fe -LOGIN_SERVER_KEY=a51ef8ac7ef1abf162fb7a65261acd7a - -# EMail -EMAIL=$EMAIL -EMAIL_USERNAME=$EMAIL_USERNAME -EMAIL_SENDER=$EMAIL_SENDER -EMAIL_PASSWORD=$EMAIL_PASSWORD -EMAIL_SMTP_URL=$EMAIL_SMTP_URL -EMAIL_SMTP_PORT=587 -EMAIL_LINK_VERIFICATION=$EMAIL_LINK_VERIFICATION -EMAIL_LINK_SETPASSWORD=$EMAIL_LINK_SETPASSWORD -EMAIL_LINK_FORGOTPASSWORD=$EMAIL_LINK_FORGOTPASSWORD -EMAIL_LINK_OVERVIEW=$EMAIL_LINK_OVERVIEW -EMAIL_CODE_VALID_TIME=$EMAIL_CODE_VALID_TIME -EMAIL_CODE_REQUEST_TIME=$EMAIL_CODE_REQUEST_TIME - -# Webhook -WEBHOOK_ELOPAGE_SECRET=$WEBHOOK_ELOPAGE_SECRET - -# EventProtocol -EVENT_PROTOCOL_DISABLED=$EVENT_PROTOCOL_DISABLED +CONFIG_VERSION=$BACKEND_CONFIG_VERSION + +# Server +JWT_SECRET=$JWT_SECRET +JWT_EXPIRES_IN=$JWT_EXPIRES_IN +GRAPHIQL=false +GDT_API_URL=$GDT_API_URL + +# Database +DB_HOST=localhost +DB_PORT=3306 +DB_USER=$DB_USER +DB_PASSWORD=$DB_PASSWORD +DB_DATABASE=gradido_community +TYPEORM_LOGGING_RELATIVE_PATH=$TYPEORM_LOGGING_RELATIVE_PATH + +# Klicktipp +KLICKTIPP=$KLICKTIPP +KLICKTTIPP_API_URL=https://api.klicktipp.com +KLICKTIPP_USER=$KLICKTIPP_USER +KLICKTIPP_PASSWORD=$KLICKTIPP_PASSWORD +KLICKTIPP_APIKEY_DE=$KLICKTIPP_APIKEY_DE +KLICKTIPP_APIKEY_EN=$KLICKTIPP_APIKEY_EN + +# Community +COMMUNITY_NAME=$COMMUNITY_NAME +COMMUNITY_URL=$COMMUNITY_URL +COMMUNITY_REGISTER_URL=$COMMUNITY_REGISTER_URL +COMMUNITY_REDEEM_URL=$COMMUNITY_REDEEM_URL +COMMUNITY_REDEEM_CONTRIBUTION_URL=$COMMUNITY_REDEEM_CONTRIBUTION_URL +COMMUNITY_DESCRIPTION=$COMMUNITY_DESCRIPTION + +# Login Server +LOGIN_APP_SECRET=21ffbbc616fe +LOGIN_SERVER_KEY=a51ef8ac7ef1abf162fb7a65261acd7a + +# EMail +EMAIL=$EMAIL +EMAIL_USERNAME=$EMAIL_USERNAME +EMAIL_SENDER=$EMAIL_SENDER +EMAIL_PASSWORD=$EMAIL_PASSWORD +EMAIL_SMTP_URL=$EMAIL_SMTP_URL +EMAIL_SMTP_PORT=587 +EMAIL_LINK_VERIFICATION=$EMAIL_LINK_VERIFICATION +EMAIL_LINK_SETPASSWORD=$EMAIL_LINK_SETPASSWORD +EMAIL_LINK_FORGOTPASSWORD=$EMAIL_LINK_FORGOTPASSWORD +EMAIL_LINK_OVERVIEW=$EMAIL_LINK_OVERVIEW +EMAIL_CODE_VALID_TIME=$EMAIL_CODE_VALID_TIME +EMAIL_CODE_REQUEST_TIME=$EMAIL_CODE_REQUEST_TIME + +# Webhook +WEBHOOK_ELOPAGE_SECRET=$WEBHOOK_ELOPAGE_SECRET + +# EventProtocol +EVENT_PROTOCOL_DISABLED=$EVENT_PROTOCOL_DISABLED