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 001/137] 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 002/137] 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 003/137] 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 004/137] 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 005/137] 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 006/137] 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 007/137] 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 008/137] 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 009/137] 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 bf086e7866d5d4cc3d26a6375c6497f9314de6b8 Mon Sep 17 00:00:00 2001 From: Einhornimmond Date: Tue, 28 Jun 2022 16:41:43 +0200 Subject: [PATCH 010/137] add migration script begin --- ...0041-update_transactions_for_blockchain.ts | 81 +++++++++++++++++++ 1 file changed, 81 insertions(+) create mode 100644 database/migrations/0041-update_transactions_for_blockchain.ts diff --git a/database/migrations/0041-update_transactions_for_blockchain.ts b/database/migrations/0041-update_transactions_for_blockchain.ts new file mode 100644 index 000000000..9662d84cf --- /dev/null +++ b/database/migrations/0041-update_transactions_for_blockchain.ts @@ -0,0 +1,81 @@ +/* MIGRATION for updating transactions from the past to follow the blockchain rules*/ +/* 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>) { + // split creation transaction with 3000 GDD created in one transaction what isn't allowed + const transactionDivData = [ + {date: new Date('2019-12-01T01:00:00'), memo: 'Aktives Grundeinkommen für GL. Dez'}, + {date: new Date('2019-01-01T01:00:00'), memo: 'Aktives Grundeinkommen für GL. Jan'}, + {date: new Date('2019-02-01T01:00:00'), memo: 'Aktives Grundeinkommen für GL. Feb'} + ] + /* + | id | int(10) unsigned | NO | PRI | NULL | auto_increment | + | user_id | int(10) | YES | | NULL | | + | previous | int(10) unsigned | YES | UNI | NULL | | + | type_id | int(10) | YES | | NULL | | + | amount | decimal(40,20) | YES | | NULL | | + | balance | decimal(40,20) | YES | | NULL | | + | balance_date | datetime | NO | | current_timestamp() | | + | decay | decimal(40,20) | YES | | NULL | | + | decay_start | datetime | YES | | NULL | | + | memo | varchar(255) | NO | | NULL | | + | creation_date | datetime | YES | | NULL | | + | linked_user_id | int(10) unsigned | YES | | NULL | | + | linked_transaction_id | int(10) | YES | | NULL | | + | transaction_link_id | int(10) unsigned | YES | | NULL | | + + */ + + transactionDivData.forEach(({date:Date, memo:string}, index)=> { + if(!index) { + queryFn(` + INSERT INTO transactions( + user_id, type_id, amount, balance, + balance_date, decay, decay_start, + memo, creation_date, linked_user_id + ) VALUES( + 275, 1, 1000, ?, + ? + )`, [1000 * (index + 1), date]) + + } else { + //queryFn('INSERT INTO transactions(user_id, previous, type_id, amount, balance, balance_date, decay, decay_start, memo, creation_date, linked_user_id)') + } + + }) + /* + Profiler splitTransactionTime; + Poco::Data::Statement insertTransactions(dbSession); + std::string memo; + Poco::DateTime received(2020, 3, 30, 8, 59, 55); + insertTransactions << "INSERT INTO " << mTempTransactionsTableName + << "(transaction_type_id, memo, received) VALUES(1, ?, ?)", + use(memo), use(received); + + Poco::Data::Statement insertCreationTransactions(dbSession); + int amount = 10000000; + Poco::DateTime targetDate(2019, 12, 1, 1, 0, 0); + insertCreationTransactions << "INSERT INTO " << mTempCreationTableName + << "(transaction_id, state_user_id, amount, target_date) VALUES(LAST_INSERT_ID(), 275, ?, ?)", + use(amount), use(targetDate); + + for (auto it = transactionDivData.begin(); it != transactionDivData.end(); it++) { + targetDate = it->first; + memo = it->second; + insertTransactions.execute(); + insertCreationTransactions.execute(); + } + Poco::Data::Statement removeInvalidTransaction(dbSession); + removeInvalidTransaction << "delete from " << mTempCreationTableName << " where id = 150", now; + removeInvalidTransaction.reset(dbSession); + removeInvalidTransaction << "delete from " << mTempTransactionsTableName << " where id = 224", now; + speedLog.information("time for split transaction: %s", splitTransactionTime.string()); + */ + //await queryFn('DROP TABLE `user_setting`;') + } + + export async function downgrade(queryFn: (query: string, values?: any[]) => Promise>) { + + } + \ No newline at end of file From dbe2ec4845390e116dd210cb1f04ae4356a1c4df Mon Sep 17 00:00:00 2001 From: Dario bb Date: Tue, 28 Jun 2022 18:29:00 +0200 Subject: [PATCH 011/137] implement code translated in js from c++ from gradido blockchain connector --- ...0041-update_transactions_for_blockchain.ts | 170 ++++++++++++------ 1 file changed, 112 insertions(+), 58 deletions(-) diff --git a/database/migrations/0041-update_transactions_for_blockchain.ts b/database/migrations/0041-update_transactions_for_blockchain.ts index 9662d84cf..3f4e47abb 100644 --- a/database/migrations/0041-update_transactions_for_blockchain.ts +++ b/database/migrations/0041-update_transactions_for_blockchain.ts @@ -1,15 +1,19 @@ -/* MIGRATION for updating transactions from the past to follow the blockchain rules*/ +/* MIGRATION for updating transactions from the past to follow the blockchain rules */ /* 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>) { - // split creation transaction with 3000 GDD created in one transaction what isn't allowed - const transactionDivData = [ - {date: new Date('2019-12-01T01:00:00'), memo: 'Aktives Grundeinkommen für GL. Dez'}, - {date: new Date('2019-01-01T01:00:00'), memo: 'Aktives Grundeinkommen für GL. Jan'}, - {date: new Date('2019-02-01T01:00:00'), memo: 'Aktives Grundeinkommen für GL. Feb'} - ] - /* + interface TransactionDivData { + date: Date + memo: string + } + // split creation transaction with 3000 GDD created in one transaction what isn't allowed + const transactionDivData: TransactionDivData[] = [ + { date: new Date('2019-12-01T01:00:00'), memo: 'Aktives Grundeinkommen für GL. Dez' }, + { date: new Date('2019-01-01T01:00:00'), memo: 'Aktives Grundeinkommen für GL. Jan' }, + { date: new Date('2019-02-01T01:00:00'), memo: 'Aktives Grundeinkommen für GL. Feb' }, + ] + /* | id | int(10) unsigned | NO | PRI | NULL | auto_increment | | user_id | int(10) | YES | | NULL | | | previous | int(10) unsigned | YES | UNI | NULL | | @@ -26,56 +30,106 @@ export async function upgrade(queryFn: (query: string, values?: any[]) => Promis | transaction_link_id | int(10) unsigned | YES | | NULL | | */ - - transactionDivData.forEach(({date:Date, memo:string}, index)=> { - if(!index) { - queryFn(` - INSERT INTO transactions( - user_id, type_id, amount, balance, - balance_date, decay, decay_start, - memo, creation_date, linked_user_id - ) VALUES( - 275, 1, 1000, ?, - ? - )`, [1000 * (index + 1), date]) - - } else { - //queryFn('INSERT INTO transactions(user_id, previous, type_id, amount, balance, balance_date, decay, decay_start, memo, creation_date, linked_user_id)') - } - - }) - /* - Profiler splitTransactionTime; - Poco::Data::Statement insertTransactions(dbSession); - std::string memo; - Poco::DateTime received(2020, 3, 30, 8, 59, 55); - insertTransactions << "INSERT INTO " << mTempTransactionsTableName - << "(transaction_type_id, memo, received) VALUES(1, ?, ?)", - use(memo), use(received); - Poco::Data::Statement insertCreationTransactions(dbSession); - int amount = 10000000; - Poco::DateTime targetDate(2019, 12, 1, 1, 0, 0); - insertCreationTransactions << "INSERT INTO " << mTempCreationTableName - << "(transaction_id, state_user_id, amount, target_date) VALUES(LAST_INSERT_ID(), 275, ?, ?)", - use(amount), use(targetDate); - - for (auto it = transactionDivData.begin(); it != transactionDivData.end(); it++) { - targetDate = it->first; - memo = it->second; - insertTransactions.execute(); - insertCreationTransactions.execute(); + transactionDivData.forEach((transactionDivData, index) => { + let sqlQuery = "INSERT INTO 'transactions'(user_id," + let sqlValues = 'VALUES(275,' + if (index) { + sqlQuery += 'previous,' + sqlValues += 'LAST_INSERT_ID()' } - Poco::Data::Statement removeInvalidTransaction(dbSession); - removeInvalidTransaction << "delete from " << mTempCreationTableName << " where id = 150", now; - removeInvalidTransaction.reset(dbSession); - removeInvalidTransaction << "delete from " << mTempTransactionsTableName << " where id = 224", now; - speedLog.information("time for split transaction: %s", splitTransactionTime.string()); - */ - //await queryFn('DROP TABLE `user_setting`;') + sqlQuery += `type_id, amount, balance, + balance_date, + memo, creation_date` + sqlValues += '1, 1000, ?, ?, ?, ?' + + sqlQuery += ')' + sqlValues += ')' + queryFn(sqlQuery + sqlValues, [ + 1000 * (index + 1), + transactionDivData.date, + transactionDivData.memo, + transactionDivData.date, + ]) + }) + // remove original transaction + queryFn("DELETE FROM 'transactions' where id = 150") + + // update previous field of first transaction after splitted transaction + queryFn("UPDATE 'transactions' SET 'previous' = LAST_INSERT_ID() WHERE 'previous' = 150") + + // ---------------------------------------------------------------------------------------------- + // update creation_date for transactions with creation_date == balance_date + // !cannot made be undone easily! + + // update entries from which memo contain month name (most cases) + interface ReplaceSet { + monthName: string + monthValue: number + yearValue: number } - - export async function downgrade(queryFn: (query: string, values?: any[]) => Promise>) { - - } - \ No newline at end of file + const replaceSets: ReplaceSet[] = [ + { monthName: 'Dez', monthValue: 12, yearValue: 2019 }, + { monthName: 'Jan', monthValue: 1, yearValue: 2020 }, + { monthName: 'Feb', monthValue: 2, yearValue: 2020 }, + { monthName: 'M_rz', monthValue: 3, yearValue: 2020 }, + { monthName: 'April', monthValue: 4, yearValue: 2020 }, + ] + replaceSets.forEach((replaceSet) => { + let sqlQuery = `update 'transactions' + SET 'creation_date' = DATE_FORMAT('creation_date', CONCAT(?, '-', ?, '-', ` + if (replaceSet.monthName === 'Feb') { + sqlQuery += "IF(DATE_FORMAT(creation_date, '%d') <= 28, '%d', 28)" + } else { + sqlQuery += "'%d'" + } + sqlQuery += `, ' %H:%i:%s')) + WHERE balance_date = creation_date + AND type_id = 1 + AND memo LIKE '%?%'` + + queryFn(sqlQuery, [replaceSet.yearValue, replaceSet.monthValue, replaceSet.monthName]) + }) + + // update entries without month name in memo, simply move creation_date 1 month before balance_date + queryFn(`UPDATE 'transactions' + set creation_date = CAST(DATE_FORMAT(creation_date, CONCAT( + IF(DATE_FORMAT(creation_date, '%m') = 1, DATE_FORMAT(creation_date, '%Y') - 1, '%Y'), + '-', + IF(DATE_FORMAT(creation_date, '%m') = 1, 12, DATE_FORMAT(creation_date, '%m') - 1), + '-', + IF(DATE_FORMAT(creation_date, '%m') = 3, IF(DATE_FORMAT(creation_date, '%d') <= 28, '%d', 28), '%d'), + ' %H:%i:%s')) AS DATETIME) + WHERE balance_date = creation_date + `) +} + +export async function downgrade(queryFn: (query: string, values?: any[]) => Promise>) { + // remove in upgrade added transactions + const creationDates: Date[] = [ + new Date('2019-12-01T01:00:00'), + new Date('2019-01-01T01:00:00'), + new Date('2019-02-01T01:00:00'), + ] + queryFn( + "DELETE FROM 'transactions' WHERE 'user_id' = 275 AND 'creation_date' IN(?,?,?)", + creationDates, + ) + // put back removed transaction + queryFn( + `INSERT INTO 'transactions'( + id, user_id, + type_id, amount, + balance, balance_date, + memo, creation_date + ) VALUES( + 150, 275, + 1, 3000, + 3000, '2020-03-30 06:59:55', + 'Aktives Grundeinkommen für GL. Dez, Jan, Feb', '2020-03-30 06:59:55' + )`, + ) + + // restore previous field of first transaction after splitted transaction + queryFn("UPDATE 'transactions' SET 'previous' = 150 WHERE 'id' = 278") +} 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 012/137] 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 013/137] 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 014/137] 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 ac18a11256dce888091de1307d9a19dc799d0d50 Mon Sep 17 00:00:00 2001 From: Einhornimmond Date: Wed, 29 Jun 2022 12:38:20 +0200 Subject: [PATCH 015/137] simplify code --- ...0041-update_transactions_for_blockchain.ts | 100 +++++------------- 1 file changed, 26 insertions(+), 74 deletions(-) diff --git a/database/migrations/0041-update_transactions_for_blockchain.ts b/database/migrations/0041-update_transactions_for_blockchain.ts index 3f4e47abb..98f794693 100644 --- a/database/migrations/0041-update_transactions_for_blockchain.ts +++ b/database/migrations/0041-update_transactions_for_blockchain.ts @@ -3,60 +3,31 @@ /* eslint-disable @typescript-eslint/no-explicit-any */ export async function upgrade(queryFn: (query: string, values?: any[]) => Promise>) { - interface TransactionDivData { - date: Date - memo: string - } // split creation transaction with 3000 GDD created in one transaction what isn't allowed - const transactionDivData: TransactionDivData[] = [ - { date: new Date('2019-12-01T01:00:00'), memo: 'Aktives Grundeinkommen für GL. Dez' }, - { date: new Date('2019-01-01T01:00:00'), memo: 'Aktives Grundeinkommen für GL. Jan' }, - { date: new Date('2019-02-01T01:00:00'), memo: 'Aktives Grundeinkommen für GL. Feb' }, + const transactionMemos: string[] = [ + 'Aktives Grundeinkommen für GL. Dez', + 'Aktives Grundeinkommen für GL. Jan', + 'Aktives Grundeinkommen für GL. Feb', ] - /* - | id | int(10) unsigned | NO | PRI | NULL | auto_increment | - | user_id | int(10) | YES | | NULL | | - | previous | int(10) unsigned | YES | UNI | NULL | | - | type_id | int(10) | YES | | NULL | | - | amount | decimal(40,20) | YES | | NULL | | - | balance | decimal(40,20) | YES | | NULL | | - | balance_date | datetime | NO | | current_timestamp() | | - | decay | decimal(40,20) | YES | | NULL | | - | decay_start | datetime | YES | | NULL | | - | memo | varchar(255) | NO | | NULL | | - | creation_date | datetime | YES | | NULL | | - | linked_user_id | int(10) unsigned | YES | | NULL | | - | linked_transaction_id | int(10) | YES | | NULL | | - | transaction_link_id | int(10) unsigned | YES | | NULL | | + const creationDate = new Date('2020-03-30 06:59:55') - */ - - transactionDivData.forEach((transactionDivData, index) => { - let sqlQuery = "INSERT INTO 'transactions'(user_id," - let sqlValues = 'VALUES(275,' - if (index) { - sqlQuery += 'previous,' - sqlValues += 'LAST_INSERT_ID()' - } - sqlQuery += `type_id, amount, balance, - balance_date, - memo, creation_date` - sqlValues += '1, 1000, ?, ?, ?, ?' - - sqlQuery += ')' - sqlValues += ')' - queryFn(sqlQuery + sqlValues, [ - 1000 * (index + 1), - transactionDivData.date, - transactionDivData.memo, - transactionDivData.date, - ]) - }) - // remove original transaction - queryFn("DELETE FROM 'transactions' where id = 150") - - // update previous field of first transaction after splitted transaction - queryFn("UPDATE 'transactions' SET 'previous' = LAST_INSERT_ID() WHERE 'previous' = 150") + queryFn(`UPDATE 'transactions' set amount = 1000, memo = ? WHERE id = 150`, [transactionMemos[0]]) + queryFn( + `INSERT INTO 'transactions'( + user_id, previous, type_id, amount, balance, balance_date, memo, creation_date + ) VALUES( + 275, 150, 1, 1000, 2000, ?, ?, ? + )`, + [creationDate, transactionMemos[1], creationDate], + ) + queryFn( + `INSERT INTO 'transactions'( + user_id, previous, type_id, amount, balance, balance_date, memo, creation_date + ) VALUES( + 275, LAST_INSERT_ID(), 1, 1000, 3000, ?, ?, ? + )`, + [creationDate, transactionMemos[2], creationDate], + ) // ---------------------------------------------------------------------------------------------- // update creation_date for transactions with creation_date == balance_date @@ -105,31 +76,12 @@ export async function upgrade(queryFn: (query: string, values?: any[]) => Promis } export async function downgrade(queryFn: (query: string, values?: any[]) => Promise>) { - // remove in upgrade added transactions - const creationDates: Date[] = [ - new Date('2019-12-01T01:00:00'), - new Date('2019-01-01T01:00:00'), - new Date('2019-02-01T01:00:00'), - ] + // remove added transaction queryFn( - "DELETE FROM 'transactions' WHERE 'user_id' = 275 AND 'creation_date' IN(?,?,?)", - creationDates, + "DELETE FROM 'transactions' WHERE 'user_id' = 275 AND 'balance' IN(2000, 3000) AND 'amount' = 1000", ) - // put back removed transaction + // rewind transaction to split queryFn( - `INSERT INTO 'transactions'( - id, user_id, - type_id, amount, - balance, balance_date, - memo, creation_date - ) VALUES( - 150, 275, - 1, 3000, - 3000, '2020-03-30 06:59:55', - 'Aktives Grundeinkommen für GL. Dez, Jan, Feb', '2020-03-30 06:59:55' - )`, + `UPDATE 'transactions' set amount = 3000, memo = 'Aktives Grundeinkommen für GL. Dez, Jan, Feb' WHERE id = 150`, ) - - // restore previous field of first transaction after splitted transaction - queryFn("UPDATE 'transactions' SET 'previous' = 150 WHERE 'id' = 278") } From 88e789c53edfd1c711a37e30e6b846d0e0d4362d Mon Sep 17 00:00:00 2001 From: Einhornimmond Date: Wed, 29 Jun 2022 16:09:31 +0200 Subject: [PATCH 016/137] tested and fixed --- ...0041-update_transactions_for_blockchain.ts | 87 ++++++++++++------- 1 file changed, 56 insertions(+), 31 deletions(-) diff --git a/database/migrations/0041-update_transactions_for_blockchain.ts b/database/migrations/0041-update_transactions_for_blockchain.ts index 98f794693..6ecdfffa9 100644 --- a/database/migrations/0041-update_transactions_for_blockchain.ts +++ b/database/migrations/0041-update_transactions_for_blockchain.ts @@ -11,28 +11,46 @@ export async function upgrade(queryFn: (query: string, values?: any[]) => Promis ] const creationDate = new Date('2020-03-30 06:59:55') - queryFn(`UPDATE 'transactions' set amount = 1000, memo = ? WHERE id = 150`, [transactionMemos[0]]) - queryFn( - `INSERT INTO 'transactions'( - user_id, previous, type_id, amount, balance, balance_date, memo, creation_date + await queryFn(`UPDATE \`transactions\` set \`amount\` = 1000, \`balance\` = 1000, \`memo\` = ? WHERE \`id\` = 150`, [ + transactionMemos[0], + ]) + + // [ RowDataPacket { 'MAX(`id`)': 6828 } ] + const lastTransactionId = (await queryFn(`SELECT MAX(\`id\`) as max_id from \`transactions\``))[0].max_id + // dummy id to insert two transactions before this (previous has an index on it) + await queryFn(`UPDATE \`transactions\` set \`previous\` = ? WHERE \`id\` = 278`, [lastTransactionId + 30]) + + await queryFn( + `INSERT INTO \`transactions\`( + \`user_id\`, \`previous\`, \`type_id\`, \`amount\`, \`balance\`, + \`balance_date\`, \`decay\`, \`memo\`, \`creation_date\` ) VALUES( - 275, 150, 1, 1000, 2000, ?, ?, ? + 275, 150, 1, 1000, 2000, + ?, 0, ?, ? )`, [creationDate, transactionMemos[1], creationDate], ) - queryFn( - `INSERT INTO 'transactions'( - user_id, previous, type_id, amount, balance, balance_date, memo, creation_date + await queryFn( + `INSERT INTO \`transactions\`( + \`user_id\`, \`previous\`, \`type_id\`, \`amount\`, \`balance\`, + \`balance_date\`, \`decay\`, \`memo\`, \`creation_date\` ) VALUES( - 275, LAST_INSERT_ID(), 1, 1000, 3000, ?, ?, ? + 275, LAST_INSERT_ID(), 1, 1000, 3000, + ?, 0, ?, ? )`, - [creationDate, transactionMemos[2], creationDate], + [creationDate, transactionMemos[2], creationDate], ) + await queryFn(`UPDATE \`transactions\` set \`previous\` = LAST_INSERT_ID() WHERE \`id\` = 278`) // ---------------------------------------------------------------------------------------------- // update creation_date for transactions with creation_date == balance_date // !cannot made be undone easily! + // make copy of transaction_creations table for easy debugging workflow + await queryFn(`DROP TABLE IF EXISTS \`transactions_temp\``) + await queryFn(`CREATE TABLE \`transactions_temp\` LIKE transactions`) + await queryFn(`INSERT INTO \`transactions_temp\` SELECT * FROM \`transactions\``) + // update entries from which memo contain month name (most cases) interface ReplaceSet { monthName: string @@ -40,30 +58,30 @@ export async function upgrade(queryFn: (query: string, values?: any[]) => Promis yearValue: number } const replaceSets: ReplaceSet[] = [ - { monthName: 'Dez', monthValue: 12, yearValue: 2019 }, - { monthName: 'Jan', monthValue: 1, yearValue: 2020 }, - { monthName: 'Feb', monthValue: 2, yearValue: 2020 }, - { monthName: 'M_rz', monthValue: 3, yearValue: 2020 }, - { monthName: 'April', monthValue: 4, yearValue: 2020 }, + { monthName: '%Dez%', monthValue: 12, yearValue: 2019 }, + { monthName: '%Jan%', monthValue: 1, yearValue: 2020 }, + { monthName: '%Feb%', monthValue: 2, yearValue: 2020 }, + { monthName: '%M_rz%', monthValue: 3, yearValue: 2020 }, + { monthName: '%April%', monthValue: 4, yearValue: 2020 }, ] - replaceSets.forEach((replaceSet) => { - let sqlQuery = `update 'transactions' - SET 'creation_date' = DATE_FORMAT('creation_date', CONCAT(?, '-', ?, '-', ` - if (replaceSet.monthName === 'Feb') { - sqlQuery += "IF(DATE_FORMAT(creation_date, '%d') <= 28, '%d', 28)" + for(const replaceSet of replaceSets) { + let sqlQuery = `update \`transactions_temp\` + SET \`creation_date\` = DATE_FORMAT(\`creation_date\`, CONCAT(?, '-', ?, '-', ` + if (replaceSet.monthName === '%Feb%') { + sqlQuery += "IF(DATE_FORMAT(`creation_date`, '%d') <= 28, '%d', 28)" } else { sqlQuery += "'%d'" } sqlQuery += `, ' %H:%i:%s')) - WHERE balance_date = creation_date - AND type_id = 1 - AND memo LIKE '%?%'` + WHERE \`balance_date\` = \`creation_date\` + AND \`type_id\` = 1 + AND \`memo\` LIKE ?` - queryFn(sqlQuery, [replaceSet.yearValue, replaceSet.monthValue, replaceSet.monthName]) - }) + await queryFn(sqlQuery, [replaceSet.yearValue, replaceSet.monthValue, replaceSet.monthName]) + } // update entries without month name in memo, simply move creation_date 1 month before balance_date - queryFn(`UPDATE 'transactions' + await queryFn(`UPDATE \`transactions_temp\` set creation_date = CAST(DATE_FORMAT(creation_date, CONCAT( IF(DATE_FORMAT(creation_date, '%m') = 1, DATE_FORMAT(creation_date, '%Y') - 1, '%Y'), '-', @@ -71,17 +89,24 @@ export async function upgrade(queryFn: (query: string, values?: any[]) => Promis '-', IF(DATE_FORMAT(creation_date, '%m') = 3, IF(DATE_FORMAT(creation_date, '%d') <= 28, '%d', 28), '%d'), ' %H:%i:%s')) AS DATETIME) - WHERE balance_date = creation_date + WHERE balance_date = creation_date `) } + export async function downgrade(queryFn: (query: string, values?: any[]) => Promise>) { + // remove added transaction - queryFn( - "DELETE FROM 'transactions' WHERE 'user_id' = 275 AND 'balance' IN(2000, 3000) AND 'amount' = 1000", + await queryFn( + `DELETE FROM \`transactions\` + WHERE \`user_id\` = 275 AND \`balance\` IN (2000, 3000) AND \`amount\` = 1000`, ) + // rewind transaction to split - queryFn( - `UPDATE 'transactions' set amount = 3000, memo = 'Aktives Grundeinkommen für GL. Dez, Jan, Feb' WHERE id = 150`, + await queryFn( + `UPDATE \`transactions\` set \`amount\` = 3000, \`memo\` = 'Aktives Grundeinkommen für GL. Dez, Jan, Feb' + WHERE \`id\` = 150`, ) + + await queryFn(`UPDATE \`transactions\` set \`previous\` = 150 WHERE \`id\` = 278`) } 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 017/137] 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 f8b0d52afd9b68be757e609bd215fa2c35e3c912 Mon Sep 17 00:00:00 2001 From: elweyn Date: Thu, 30 Jun 2022 13:57:30 +0200 Subject: [PATCH 018/137] Add ROLES and RIGHTS for users to query listContributions. --- 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 c10fc96de..6a6f8b7c0 100644 --- a/backend/src/auth/RIGHTS.ts +++ b/backend/src/auth/RIGHTS.ts @@ -26,6 +26,7 @@ export enum RIGHTS { LIST_TRANSACTION_LINKS = 'LIST_TRANSACTION_LINKS', GDT_BALANCE = 'GDT_BALANCE', CREATE_CONTRIBUTION = 'CREATE_CONTRIBUTION', + LIST_CONTRIBUTIONS = 'LIST_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 2d9ac2deb..f56106664 100644 --- a/backend/src/auth/ROLES.ts +++ b/backend/src/auth/ROLES.ts @@ -24,6 +24,7 @@ export const ROLE_USER = new Role('user', [ RIGHTS.LIST_TRANSACTION_LINKS, RIGHTS.GDT_BALANCE, RIGHTS.CREATE_CONTRIBUTION, + RIGHTS.LIST_CONTRIBUTIONS, ]) export const ROLE_ADMIN = new Role('admin', Object.values(RIGHTS)) // all rights From f19a6f1d15a14331711305e83e7a0df848c98923 Mon Sep 17 00:00:00 2001 From: elweyn Date: Thu, 30 Jun 2022 13:58:21 +0200 Subject: [PATCH 019/137] Create model for Contribution and create function to query listContributions. --- backend/src/graphql/model/Contribution.ts | 44 ++++++++++++++++ .../graphql/resolver/ContributionResolver.ts | 51 +++++++++++++++++-- 2 files changed, 91 insertions(+), 4 deletions(-) create mode 100644 backend/src/graphql/model/Contribution.ts diff --git a/backend/src/graphql/model/Contribution.ts b/backend/src/graphql/model/Contribution.ts new file mode 100644 index 000000000..cd8c94d74 --- /dev/null +++ b/backend/src/graphql/model/Contribution.ts @@ -0,0 +1,44 @@ +import { ObjectType, Field, Int } from 'type-graphql' +import Decimal from 'decimal.js-light' +import { Contribution as dbContribution } from '@entity/Contribution' +import { User } from './User' +import CONFIG from '@/config' + +@ObjectType() +export class Contribution { + constructor(contribution: dbContribution, user: User) { + this.id = contribution.id + this.user = user + this.amount = contribution.amount + this.memo = contribution.memo + this.createdAt = contribution.createdAt + this.deletedAt = contribution.deletedAt + } + + @Field(() => Number) + id: number + + @Field(() => User) + user: User + + @Field(() => Decimal) + amount: Decimal + + @Field(() => String) + memo: string + + @Field(() => Date) + createdAt: Date + + @Field(() => Date, { nullable: true }) + deletedAt: Date | null +} + +@ObjectType() +export class ContributionListResult { + @Field(() => Int) + linkCount: number + + @Field(() => [Contribution]) + linkList: Contribution[] +} diff --git a/backend/src/graphql/resolver/ContributionResolver.ts b/backend/src/graphql/resolver/ContributionResolver.ts index 924108f87..c3b4c2127 100644 --- a/backend/src/graphql/resolver/ContributionResolver.ts +++ b/backend/src/graphql/resolver/ContributionResolver.ts @@ -1,10 +1,15 @@ import { RIGHTS } from '@/auth/RIGHTS' import { Context, getUser } from '@/server/context' import { backendLogger as logger } from '@/server/logger' -import { Contribution } from '@entity/Contribution' -import { Args, Authorized, Ctx, Mutation, Resolver } from 'type-graphql' +import { Contribution as dbContribution } from '@entity/Contribution' +import { Arg, Args, Authorized, Ctx, Mutation, Query, Resolver } from 'type-graphql' +import { IsNull, Not } from '../../../../database/node_modules/typeorm' import ContributionArgs from '../arg/ContributionArgs' +import Paginated from '../arg/Paginated' +import { Order } from '../enum/Order' +import { Contribution } from '../model/Contribution' import { UnconfirmedContribution } from '../model/UnconfirmedContribution' +import { User } from '../model/User' import { isContributionValid, getUserCreation } from './util/isContributionValid' @Resolver() @@ -21,7 +26,7 @@ export class ContributionResolver { const creationDateObj = new Date(creationDate) isContributionValid(creations, amount, creationDateObj) - const contribution = Contribution.create() + const contribution = dbContribution.create() contribution.userId = user.id contribution.amount = amount contribution.createdAt = new Date() @@ -29,7 +34,45 @@ export class ContributionResolver { contribution.memo = memo logger.trace('contribution to save', contribution) - await Contribution.save(contribution) + await dbContribution.save(contribution) return new UnconfirmedContribution(contribution, user, creations) } + + @Authorized([RIGHTS.LIST_CONTRIBUTIONS]) + @Query(() => [Contribution]) + async listContributions( + @Args() + { currentPage = 1, pageSize = 5, order = Order.DESC }: Paginated, + @Arg('filterConfirmed', () => Boolean) + filterConfirmed: boolean | null, + @Ctx() context: Context, + ): Promise { + const user = getUser(context) + let contribution + if (filterConfirmed) { + contribution = await dbContribution.find({ + where: { + userId: user.id, + confirmedBy: IsNull(), + }, + order: { + createdAt: order, + }, + skip: (currentPage - 1) * pageSize, + take: pageSize, + }) + } else { + contribution = await dbContribution.find({ + where: { + userId: user.id, + }, + order: { + createdAt: order, + }, + skip: (currentPage - 1) * pageSize, + take: pageSize, + }) + } + return contribution.map((contr) => new Contribution(contr, new User(user))) + } } From 7e31b5957edbea824894734d4b1471635f379735 Mon Sep 17 00:00:00 2001 From: Moriz Wahl Date: Thu, 30 Jun 2022 16:43:07 +0200 Subject: [PATCH 020/137] explain how .env files are working --- README.md | 13 +++++++++++++ 1 file changed, 13 insertions(+) diff --git a/README.md b/README.md index 289a39109..b98d0f741 100644 --- a/README.md +++ b/README.md @@ -121,6 +121,19 @@ After generating a new version you should commit the changes. This will be the C Note: The Changelog will be regenerated with all tags on release on the external builder tool, but will not be checked in there. The Changelog on the github release will therefore always be correct, on the repo it might be incorrect due to missing tags when executing the `yarn release` command. +## How the different .env work on deploy + +Each component (frontend, admin, backend and database) has its own `.env` file. When running in development you usually do not have to care about the `.env`. The defaults are set by the respetive config file, found in the `src/config/` folder of each component. But if you have a local `.env`, the defaults set in the config are overwritten by the `.env`. + +Each component has a `.env.dist` file. This file contains all environment variables used by the component. If you want to use a local `.env`, copy the `.env.dist` and adjust the variables accordingly. + +Each component has a `.env.template` file. These files are very important on deploy. + +There is one `.env.dist` in the `deployment/bare_metal/` folder. This `.env` contains all variables used by the components. On deploy, we set all variables in this file. The deploy script loads this variables and provides them by the `.env.templates` of each component, creating a `.env` for each component. + +To avoid forgetting to update the global `.env` when deploying, we have a environment version variable inside the codebase of each component. You should update this version, when environment variables must be changed or added on deploy. The code checks, that the environement version provided by the `.env` is the one expected by the codebase. + + ## Troubleshooting | Problem | Issue | Solution | Description | From 3ce80fc081101df68d6ecb92287c6fd19e921517 Mon Sep 17 00:00:00 2001 From: elweyn Date: Thu, 30 Jun 2022 16:47:44 +0200 Subject: [PATCH 021/137] Remove unused imports. --- backend/src/graphql/model/Contribution.ts | 1 - backend/src/graphql/resolver/ContributionResolver.ts | 2 +- 2 files changed, 1 insertion(+), 2 deletions(-) diff --git a/backend/src/graphql/model/Contribution.ts b/backend/src/graphql/model/Contribution.ts index cd8c94d74..dc1dd39e9 100644 --- a/backend/src/graphql/model/Contribution.ts +++ b/backend/src/graphql/model/Contribution.ts @@ -2,7 +2,6 @@ import { ObjectType, Field, Int } from 'type-graphql' import Decimal from 'decimal.js-light' import { Contribution as dbContribution } from '@entity/Contribution' import { User } from './User' -import CONFIG from '@/config' @ObjectType() export class Contribution { diff --git a/backend/src/graphql/resolver/ContributionResolver.ts b/backend/src/graphql/resolver/ContributionResolver.ts index c3b4c2127..6669ef20d 100644 --- a/backend/src/graphql/resolver/ContributionResolver.ts +++ b/backend/src/graphql/resolver/ContributionResolver.ts @@ -3,7 +3,7 @@ import { Context, getUser } from '@/server/context' import { backendLogger as logger } from '@/server/logger' import { Contribution as dbContribution } from '@entity/Contribution' import { Arg, Args, Authorized, Ctx, Mutation, Query, Resolver } from 'type-graphql' -import { IsNull, Not } from '../../../../database/node_modules/typeorm' +import { IsNull } from '../../../../database/node_modules/typeorm' import ContributionArgs from '../arg/ContributionArgs' import Paginated from '../arg/Paginated' import { Order } from '../enum/Order' 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 022/137] 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 7d23be6901ce1859aeebb81965ef2b38090f6fed Mon Sep 17 00:00:00 2001 From: elweyn Date: Fri, 1 Jul 2022 12:54:04 +0200 Subject: [PATCH 023/137] Add query for listContributions. --- 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 531aebf0f..cf0fd09bd 100644 --- a/backend/src/seeds/graphql/queries.ts +++ b/backend/src/seeds/graphql/queries.ts @@ -172,6 +172,24 @@ export const queryTransactionLink = gql` } ` +export const listContributions = gql` + query ( + $currentPage: Int = 1 + $pageSize: Int = 5 + $order: Order + $filterConfirmed: Boolean = false + ) { + listContributions( + currentPage: $currentPage + pageSize: $pageSize + order: $order + filterConfirmed: $filterConfirmed + ) { + amount + memo + } + } +` // from admin interface export const listUnconfirmedContributions = gql` From 58a350155bfd8dc2183ac775cfac4b09ce87fcdb Mon Sep 17 00:00:00 2001 From: elweyn Date: Fri, 1 Jul 2022 12:54:46 +0200 Subject: [PATCH 024/137] Add tests that confirmed contribution are found and no unconfirmed contributions are found. --- .../resolver/ContributionResolver.test.ts | 93 ++++++++++++++++++- 1 file changed, 92 insertions(+), 1 deletion(-) diff --git a/backend/src/graphql/resolver/ContributionResolver.test.ts b/backend/src/graphql/resolver/ContributionResolver.test.ts index 01e9b123e..2308cd4e7 100644 --- a/backend/src/graphql/resolver/ContributionResolver.test.ts +++ b/backend/src/graphql/resolver/ContributionResolver.test.ts @@ -3,10 +3,13 @@ import { bibiBloxberg } from '@/seeds/users/bibi-bloxberg' import { createContribution } from '@/seeds/graphql/mutations' -import { login } from '@/seeds/graphql/queries' +import { listContributions, login } from '@/seeds/graphql/queries' import { cleanDB, resetToken, testEnvironment } from '@test/helpers' import { GraphQLError } from 'graphql' 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' let mutate: any, query: any, con: any let testEnv: any @@ -121,4 +124,92 @@ describe('ContributionResolver', () => { }) }) }) + + describe('listContributions', () => { + describe('unauthenticated', () => { + it('returns an error', async () => { + await expect( + query({ + query: listContributions, + 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, peterLustig) + await userFactory(testEnv, bibiBloxberg) + // bibi needs GDDs + 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 userFactory(testEnv, bibiBloxberg) + await query({ + query: login, + variables: { email: 'bibi@bloxberg.de', password: 'Aa12345_' }, + }) + }) + + afterAll(async () => { + await cleanDB() + resetToken() + }) + + it('returns an empty array for unconfirmed creation filter', async () => { + await expect( + query({ + query: listContributions, + variables: { + currentPage: 1, + pageSize: 25, + order: 'DESC', + filterConfirmed: true, + }, + }), + ).resolves.toEqual( + expect.objectContaining({ + data: { + listContributions: [], + }, + }), + ) + }) + + it('returns confirmed creation', async () => { + await expect( + query({ + query: listContributions, + variables: { + currentPage: 1, + pageSize: 25, + order: 'DESC', + filterConfirmed: false, + }, + }), + ).resolves.toEqual( + expect.objectContaining({ + data: { + listContributions: expect.arrayContaining([ + expect.objectContaining({ + memo: 'Herzlich Willkommen bei Gradido!', + amount: '1000', + }), + ]), + }, + }), + ) + }) + }) + }) }) From d9034b1bdb9e5f8ee56124599feb66d8fa54488b Mon Sep 17 00:00:00 2001 From: Moriz Wahl Date: Fri, 1 Jul 2022 17:20:26 +0200 Subject: [PATCH 025/137] 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 026/137] 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 027/137] 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 78195612c2c4abbf83151f7faed47ad4f4d1767f Mon Sep 17 00:00:00 2001 From: elweyn Date: Mon, 4 Jul 2022 07:39:11 +0200 Subject: [PATCH 028/137] Add ROLES and RIGHTS to updateContribution. --- 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..1d0fd2856 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', + UPDATE_CONTRIBUTION = 'UPDATE_CONTRIBUTION', // 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..75e552e79 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.UPDATE_CONTRIBUTION, ]) export const ROLE_ADMIN = new Role('admin', Object.values(RIGHTS)) // all rights From b580f8755da0a0034f58eb6b8871bab68c366d3e Mon Sep 17 00:00:00 2001 From: elweyn Date: Mon, 4 Jul 2022 07:40:10 +0200 Subject: [PATCH 029/137] Refactor updateCreations. --- backend/src/graphql/resolver/AdminResolver.ts | 11 +---------- .../src/graphql/resolver/util/isContributionValid.ts | 11 +++++++++++ 2 files changed, 12 insertions(+), 10 deletions(-) diff --git a/backend/src/graphql/resolver/AdminResolver.ts b/backend/src/graphql/resolver/AdminResolver.ts index 5476fd8a1..962c13e9b 100644 --- a/backend/src/graphql/resolver/AdminResolver.ts +++ b/backend/src/graphql/resolver/AdminResolver.ts @@ -52,6 +52,7 @@ import { getUserCreations, isContributionValid, isStartEndDateValid, + updateCreations, } from './util/isContributionValid' import { CONTRIBUTIONLINK_MEMO_MAX_CHARS, @@ -688,13 +689,3 @@ export class AdminResolver { return new ContributionLink(dbContributionLink) } } - -function updateCreations(creations: Decimal[], contribution: Contribution): Decimal[] { - const index = getCreationIndex(contribution.contributionDate.getMonth()) - - if (index < 0) { - throw new Error('You cannot create GDD for a month older than the last three months.') - } - creations[index] = creations[index].plus(contribution.amount.toString()) - return creations -} diff --git a/backend/src/graphql/resolver/util/isContributionValid.ts b/backend/src/graphql/resolver/util/isContributionValid.ts index 0a9b57170..552370f4c 100644 --- a/backend/src/graphql/resolver/util/isContributionValid.ts +++ b/backend/src/graphql/resolver/util/isContributionValid.ts @@ -1,6 +1,7 @@ import { TransactionTypeId } from '@/graphql/enum/TransactionTypeId' import { backendLogger as logger } from '@/server/logger' import { getConnection } from '@dbTools/typeorm' +import { Contribution } from '@entity/Contribution' import Decimal from 'decimal.js-light' import { FULL_CREATION_AVAILABLE, MAX_CREATION_AMOUNT } from '../const/const' @@ -117,3 +118,13 @@ export const isStartEndDateValid = ( throw new Error(`The value of validFrom must before or equals the validTo!`) } } + +export const updateCreations = (creations: Decimal[], contribution: Contribution): Decimal[] => { + const index = getCreationIndex(contribution.contributionDate.getMonth()) + + if (index < 0) { + throw new Error('You cannot create GDD for a month older than the last three months.') + } + creations[index] = creations[index].plus(contribution.amount.toString()) + return creations +} From 03db4ed125cd2bcd7d7288f081bc25fa08b071af Mon Sep 17 00:00:00 2001 From: elweyn Date: Mon, 4 Jul 2022 07:41:21 +0200 Subject: [PATCH 030/137] Add mutation to updateContribution. --- .../resolver/ContributionResolver.test.ts | 24 ++++++++++++++++++- backend/src/seeds/graphql/mutations.ts | 14 +++++++++++ 2 files changed, 37 insertions(+), 1 deletion(-) diff --git a/backend/src/graphql/resolver/ContributionResolver.test.ts b/backend/src/graphql/resolver/ContributionResolver.test.ts index 2308cd4e7..c9302cf64 100644 --- a/backend/src/graphql/resolver/ContributionResolver.test.ts +++ b/backend/src/graphql/resolver/ContributionResolver.test.ts @@ -2,7 +2,7 @@ /* eslint-disable @typescript-eslint/explicit-module-boundary-types */ import { bibiBloxberg } from '@/seeds/users/bibi-bloxberg' -import { createContribution } from '@/seeds/graphql/mutations' +import { createContribution, updateContribution } from '@/seeds/graphql/mutations' import { listContributions, login } from '@/seeds/graphql/queries' import { cleanDB, resetToken, testEnvironment } from '@test/helpers' import { GraphQLError } from 'graphql' @@ -212,4 +212,26 @@ describe('ContributionResolver', () => { }) }) }) + + describe('updateContribution', () => { + describe('unauthenticated', () => { + it('returns an error', async () => { + await expect( + mutate({ + mutation: updateContribution, + variables: { + contributionId: 1, + amount: 100.0, + memo: 'Test Contribution', + creationDate: 'not-valid', + }, + }), + ).resolves.toEqual( + expect.objectContaining({ + errors: [new GraphQLError('401 Unauthorized')], + }), + ) + }) + }) + }) }) diff --git a/backend/src/seeds/graphql/mutations.ts b/backend/src/seeds/graphql/mutations.ts index 4926f706f..45adeacc8 100644 --- a/backend/src/seeds/graphql/mutations.ts +++ b/backend/src/seeds/graphql/mutations.ts @@ -239,3 +239,17 @@ export const createContribution = gql` } } ` + +export const updateContribution = gql` + mutation ($contributionId: Int!, $amount: Decimal!, $memo: String!, $creationDate: String!) { + updateContribution( + contributionId: $contributionId + amount: $amount + memo: $memo + creationDate: $creationDate + ) { + amount + memo + } + } +` From 7b38fe7f931ad45697d67d1d3ce4d06cb0e535ec Mon Sep 17 00:00:00 2001 From: elweyn Date: Mon, 4 Jul 2022 07:41:41 +0200 Subject: [PATCH 031/137] Function for updateContribution. --- .../graphql/resolver/ContributionResolver.ts | 41 ++++++++++++++++++- 1 file changed, 39 insertions(+), 2 deletions(-) diff --git a/backend/src/graphql/resolver/ContributionResolver.ts b/backend/src/graphql/resolver/ContributionResolver.ts index 6669ef20d..2399593c2 100644 --- a/backend/src/graphql/resolver/ContributionResolver.ts +++ b/backend/src/graphql/resolver/ContributionResolver.ts @@ -2,7 +2,7 @@ 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 { Arg, Args, Authorized, Ctx, Mutation, Query, Resolver } from 'type-graphql' +import { Arg, Args, Authorized, Ctx, Int, Mutation, Query, Resolver } from 'type-graphql' import { IsNull } from '../../../../database/node_modules/typeorm' import ContributionArgs from '../arg/ContributionArgs' import Paginated from '../arg/Paginated' @@ -10,7 +10,7 @@ import { Order } from '../enum/Order' import { Contribution } from '../model/Contribution' import { UnconfirmedContribution } from '../model/UnconfirmedContribution' import { User } from '../model/User' -import { isContributionValid, getUserCreation } from './util/isContributionValid' +import { isContributionValid, getUserCreation, updateCreations } from './util/isContributionValid' @Resolver() export class ContributionResolver { @@ -75,4 +75,41 @@ export class ContributionResolver { } return contribution.map((contr) => new Contribution(contr, new User(user))) } + + @Authorized([RIGHTS.UPDATE_CONTRIBUTION]) + @Mutation(() => UnconfirmedContribution) + async updateContribution( + @Arg('contributionId', () => Int) + contributionId: number, + @Args() { amount, memo, creationDate }: ContributionArgs, + @Ctx() context: Context, + ): Promise { + const user = getUser(context) + + const contributionToUpdate = await dbContribution.findOne({ + where: { id: contributionId, confirmedAt: IsNull() }, + }) + if (!contributionToUpdate) { + throw new Error('No contribution found to given id.') + } + if (contributionToUpdate.userId !== user.id) { + throw new Error('user of the pending contribution and send user does not correspond') + } + + const creationDateObj = new Date(creationDate) + let creations = await getUserCreation(user.id) + if (contributionToUpdate.contributionDate.getMonth() === creationDateObj.getMonth()) { + creations = updateCreations(creations, contributionToUpdate) + } + + // all possible cases not to be true are thrown in this function + isContributionValid(creations, amount, creationDateObj) + contributionToUpdate.amount = amount + contributionToUpdate.memo = memo + contributionToUpdate.contributionDate = new Date(creationDate) + dbContribution.save(contributionToUpdate) + + const result = new UnconfirmedContribution(contributionToUpdate, user, creations) + return result + } } From 8c4664e39180557faa856734ccb1a3f08dc2a5a7 Mon Sep 17 00:00:00 2001 From: einhorn_b Date: Mon, 4 Jul 2022 13:46:04 +0200 Subject: [PATCH 032/137] add line to downgrade --- database/migrations/0041-update_transactions_for_blockchain.ts | 2 ++ 1 file changed, 2 insertions(+) diff --git a/database/migrations/0041-update_transactions_for_blockchain.ts b/database/migrations/0041-update_transactions_for_blockchain.ts index 6ecdfffa9..44f5bd87d 100644 --- a/database/migrations/0041-update_transactions_for_blockchain.ts +++ b/database/migrations/0041-update_transactions_for_blockchain.ts @@ -109,4 +109,6 @@ export async function downgrade(queryFn: (query: string, values?: any[]) => Prom ) await queryFn(`UPDATE \`transactions\` set \`previous\` = 150 WHERE \`id\` = 278`) + // drop temp table + await queryFn(`DROP TABLE IF EXISTS \`transactions_temp\``) } 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 033/137] 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 8e7476ecb07d0ede3ff6270f1077f18d93ec17a8 Mon Sep 17 00:00:00 2001 From: elweyn Date: Tue, 5 Jul 2022 09:07:29 +0200 Subject: [PATCH 034/137] Refactor return value so that their is only one return value. --- backend/src/graphql/resolver/ContributionResolver.ts | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/backend/src/graphql/resolver/ContributionResolver.ts b/backend/src/graphql/resolver/ContributionResolver.ts index 2399593c2..f14aa4f36 100644 --- a/backend/src/graphql/resolver/ContributionResolver.ts +++ b/backend/src/graphql/resolver/ContributionResolver.ts @@ -109,7 +109,6 @@ export class ContributionResolver { contributionToUpdate.contributionDate = new Date(creationDate) dbContribution.save(contributionToUpdate) - const result = new UnconfirmedContribution(contributionToUpdate, user, creations) - return result + return new UnconfirmedContribution(contributionToUpdate, user, creations) } } From 61d4c138e1d196bd02f2c360555ec19866c80187 Mon Sep 17 00:00:00 2001 From: elweyn Date: Tue, 5 Jul 2022 09:17:48 +0200 Subject: [PATCH 035/137] Remove unused import. --- backend/src/graphql/resolver/AdminResolver.ts | 1 - 1 file changed, 1 deletion(-) diff --git a/backend/src/graphql/resolver/AdminResolver.ts b/backend/src/graphql/resolver/AdminResolver.ts index 962c13e9b..291ee6ed8 100644 --- a/backend/src/graphql/resolver/AdminResolver.ts +++ b/backend/src/graphql/resolver/AdminResolver.ts @@ -47,7 +47,6 @@ import { sendAccountActivationEmail } from '@/mailer/sendAccountActivationEmail' import { transactionLinkCode as contributionLinkCode } from './TransactionLinkResolver' import CONFIG from '@/config' import { - getCreationIndex, getUserCreation, getUserCreations, isContributionValid, From be7a40be18fe497d7bdf02b6265930ab87c00dc3 Mon Sep 17 00:00:00 2001 From: Moriz Wahl Date: Tue, 5 Jul 2022 11:57:08 +0200 Subject: [PATCH 036/137] fix typo --- README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/README.md b/README.md index b98d0f741..75a9e7e55 100644 --- a/README.md +++ b/README.md @@ -123,7 +123,7 @@ Note: The Changelog will be regenerated with all tags on release on the external ## How the different .env work on deploy -Each component (frontend, admin, backend and database) has its own `.env` file. When running in development you usually do not have to care about the `.env`. The defaults are set by the respetive config file, found in the `src/config/` folder of each component. But if you have a local `.env`, the defaults set in the config are overwritten by the `.env`. +Each component (frontend, admin, backend and database) has its own `.env` file. When running in development you usually do not have to care about the `.env`. The defaults are set by the respective config file, found in the `src/config/` folder of each component. But if you have a local `.env`, the defaults set in the config are overwritten by the `.env`. Each component has a `.env.dist` file. This file contains all environment variables used by the component. If you want to use a local `.env`, copy the `.env.dist` and adjust the variables accordingly. From 19253d7ce79935e5c240cada9940df4dc22017c7 Mon Sep 17 00:00:00 2001 From: einhorn_b Date: Tue, 5 Jul 2022 16:18:34 +0200 Subject: [PATCH 037/137] change generic mysql query to easy raw mysql queries --- ...0041-update_transactions_for_blockchain.ts | 1919 ++++++++++++++++- 1 file changed, 1867 insertions(+), 52 deletions(-) diff --git a/database/migrations/0041-update_transactions_for_blockchain.ts b/database/migrations/0041-update_transactions_for_blockchain.ts index 44f5bd87d..066c78ee0 100644 --- a/database/migrations/0041-update_transactions_for_blockchain.ts +++ b/database/migrations/0041-update_transactions_for_blockchain.ts @@ -11,15 +11,19 @@ export async function upgrade(queryFn: (query: string, values?: any[]) => Promis ] const creationDate = new Date('2020-03-30 06:59:55') - await queryFn(`UPDATE \`transactions\` set \`amount\` = 1000, \`balance\` = 1000, \`memo\` = ? WHERE \`id\` = 150`, [ - transactionMemos[0], - ]) + await queryFn( + `UPDATE \`transactions\` set \`amount\` = 1000, \`balance\` = 1000, \`memo\` = ? WHERE \`id\` = 150`, + [transactionMemos[0]], + ) // [ RowDataPacket { 'MAX(`id`)': 6828 } ] - const lastTransactionId = (await queryFn(`SELECT MAX(\`id\`) as max_id from \`transactions\``))[0].max_id + const lastTransactionId = (await queryFn(`SELECT MAX(\`id\`) as max_id from \`transactions\``))[0] + .max_id // dummy id to insert two transactions before this (previous has an index on it) - await queryFn(`UPDATE \`transactions\` set \`previous\` = ? WHERE \`id\` = 278`, [lastTransactionId + 30]) - + await queryFn(`UPDATE \`transactions\` set \`previous\` = ? WHERE \`id\` = 278`, [ + lastTransactionId + 30, + ]) + await queryFn( `INSERT INTO \`transactions\`( \`user_id\`, \`previous\`, \`type_id\`, \`amount\`, \`balance\`, @@ -38,76 +42,1887 @@ export async function upgrade(queryFn: (query: string, values?: any[]) => Promis 275, LAST_INSERT_ID(), 1, 1000, 3000, ?, 0, ?, ? )`, - [creationDate, transactionMemos[2], creationDate], + [creationDate, transactionMemos[2], creationDate], ) await queryFn(`UPDATE \`transactions\` set \`previous\` = LAST_INSERT_ID() WHERE \`id\` = 278`) // ---------------------------------------------------------------------------------------------- // update creation_date for transactions with creation_date == balance_date - // !cannot made be undone easily! - - // make copy of transaction_creations table for easy debugging workflow - await queryFn(`DROP TABLE IF EXISTS \`transactions_temp\``) - await queryFn(`CREATE TABLE \`transactions_temp\` LIKE transactions`) - await queryFn(`INSERT INTO \`transactions_temp\` SELECT * FROM \`transactions\``) - - // update entries from which memo contain month name (most cases) + /* js code for generating mysql raw queries + // print mysql raw querys interface ReplaceSet { - monthName: string + monthName: RegExp monthValue: number - yearValue: number } + // js month starting with 0 for Jan const replaceSets: ReplaceSet[] = [ - { monthName: '%Dez%', monthValue: 12, yearValue: 2019 }, - { monthName: '%Jan%', monthValue: 1, yearValue: 2020 }, - { monthName: '%Feb%', monthValue: 2, yearValue: 2020 }, - { monthName: '%M_rz%', monthValue: 3, yearValue: 2020 }, - { monthName: '%April%', monthValue: 4, yearValue: 2020 }, + { monthName: new RegExp('.*Dez.*'), monthValue: -1}, + { monthName: new RegExp('.*Jan.*'), monthValue: 0 }, + { monthName: new RegExp('.*Feb.*'), monthValue: 1 }, + { monthName: new RegExp('.*M.rz.*'), monthValue: 2 }, + { monthName: new RegExp('.*April.*'), monthValue: 3 }, ] - for(const replaceSet of replaceSets) { - let sqlQuery = `update \`transactions_temp\` - SET \`creation_date\` = DATE_FORMAT(\`creation_date\`, CONCAT(?, '-', ?, '-', ` - if (replaceSet.monthName === '%Feb%') { - sqlQuery += "IF(DATE_FORMAT(`creation_date`, '%d') <= 28, '%d', 28)" - } else { - sqlQuery += "'%d'" - } - sqlQuery += `, ' %H:%i:%s')) - WHERE \`balance_date\` = \`creation_date\` - AND \`type_id\` = 1 - AND \`memo\` LIKE ?` - - await queryFn(sqlQuery, [replaceSet.yearValue, replaceSet.monthValue, replaceSet.monthName]) - } - - // update entries without month name in memo, simply move creation_date 1 month before balance_date - await queryFn(`UPDATE \`transactions_temp\` - set creation_date = CAST(DATE_FORMAT(creation_date, CONCAT( - IF(DATE_FORMAT(creation_date, '%m') = 1, DATE_FORMAT(creation_date, '%Y') - 1, '%Y'), - '-', - IF(DATE_FORMAT(creation_date, '%m') = 1, 12, DATE_FORMAT(creation_date, '%m') - 1), - '-', - IF(DATE_FORMAT(creation_date, '%m') = 3, IF(DATE_FORMAT(creation_date, '%d') <= 28, '%d', 28), '%d'), - ' %H:%i:%s')) AS DATETIME) - WHERE balance_date = creation_date + const transaction_ids = await queryFn(` + SELECT id, balance_date, creation_date, memo + FROM \`transactions\` + WHERE \`balance_date\` = \`creation_date\` + AND \`type_id\` = 1 `) + let downgradeQueries = '' + for(let id in transaction_ids) { + const transaction = transaction_ids[id] + let updatedCreationDate: Date | null = null + // determine correct creation date + for(const replaceSet of replaceSets) { + // check if target creation can be determine which help of the memo + if(transaction.memo.match(replaceSet.monthName)) { + const oldCreationDate = transaction.creation_date + updatedCreationDate = new Date(oldCreationDate) + updatedCreationDate.setMonth(replaceSet.monthValue) + break + } + } + // couldn't find info in memo, simply set date 1 month back + if(updatedCreationDate === null) { + //date.setMonth(date.getMonth() - numOfMonths); + updatedCreationDate = new Date(transaction.creation_date) + updatedCreationDate.setMonth(transaction.creation_date.getMonth() - 1) + } + if(updatedCreationDate.getMonth() == 1) { + // only 28 februars exist so let us fix it + if(updatedCreationDate.getDate() > 28) { + updatedCreationDate.setDate(28) + } + } + console.log('// %s, original creation date: %s\nawait queryFn(`UPDATE \\`transactions\\` SET creation_date = \'%s\' WHERE \\`id\\` = %d`)\n', + transaction.memo, + transaction.creation_date.toISOString().slice(0, 19).replace('T', ' '), + updatedCreationDate.toISOString().slice(0, 19).replace('T', ' '), + transaction.id + ) + downgradeQueries += 'await queryFn(`UPDATE \\`transactions\\` SET creation_date = \'' + downgradeQueries += transaction.creation_date.toISOString().slice(0, 19).replace('T', ' ') + downgradeQueries += '\' WHERE \\`id\\` = ' + downgradeQueries += transaction.id + downgradeQueries += '`)\n' + } + console.log("downgrade: \n%s", downgradeQueries) + console.log("transactions count: %d", transaction_ids.length) // 224 +*/ + + // Erste Schöpfung, viel Spaß damit ;), original creation date: 2019-12-17 13:06:13 + await queryFn( + `UPDATE \`transactions\` SET creation_date = '2019-11-17 13:06:13' WHERE \`id\` = 1`, + ) + + // Erste Schöpfung, viel Spaß damit ;), original creation date: 2019-12-17 13:06:16 + await queryFn( + `UPDATE \`transactions\` SET creation_date = '2019-11-17 13:06:16' WHERE \`id\` = 2`, + ) + + // Erste Schöpfung, viel Spaß damit ;), original creation date: 2019-12-17 13:06:19 + await queryFn( + `UPDATE \`transactions\` SET creation_date = '2019-11-17 13:06:19' WHERE \`id\` = 3`, + ) + + // Erste Schöpfung, viel Spaß damit ;), original creation date: 2019-12-17 13:06:21 + await queryFn( + `UPDATE \`transactions\` SET creation_date = '2019-11-17 13:06:21' WHERE \`id\` = 4`, + ) + + // Test1 , original creation date: 2019-12-17 13:07:01 + await queryFn( + `UPDATE \`transactions\` SET creation_date = '2019-11-17 13:07:01' WHERE \`id\` = 5`, + ) + + // EIn bisschen Nachschub für dich ;), original creation date: 2019-12-19 17:35:16 + await queryFn( + `UPDATE \`transactions\` SET creation_date = '2019-11-19 17:35:16' WHERE \`id\` = 6`, + ) + + // AGE Dezember 2019, original creation date: 2020-01-08 10:34:40 + await queryFn( + `UPDATE \`transactions\` SET creation_date = '2019-12-08 10:34:40' WHERE \`id\` = 7`, + ) + + // AGE Dezember 2019, original creation date: 2020-01-08 11:02:41 + await queryFn( + `UPDATE \`transactions\` SET creation_date = '2019-12-08 11:02:41' WHERE \`id\` = 8`, + ) + + // AGE Dezember 2019, original creation date: 2020-01-08 11:06:42 + await queryFn( + `UPDATE \`transactions\` SET creation_date = '2019-12-08 11:06:42' WHERE \`id\` = 9`, + ) + + // AGE Dezember 2019, original creation date: 2020-01-08 11:16:11 + await queryFn( + `UPDATE \`transactions\` SET creation_date = '2019-12-08 11:16:11' WHERE \`id\` = 10`, + ) + + // AGE Dezember 2019, original creation date: 2020-01-08 11:16:15 + await queryFn( + `UPDATE \`transactions\` SET creation_date = '2019-12-08 11:16:15' WHERE \`id\` = 11`, + ) + + // Für deine tolle Arbeit ;), original creation date: 2020-01-08 13:24:29 + await queryFn( + `UPDATE \`transactions\` SET creation_date = '2019-12-08 13:24:29' WHERE \`id\` = 12`, + ) + + // AGE Dezember 2019, original creation date: 2020-01-09 12:02:48 + await queryFn( + `UPDATE \`transactions\` SET creation_date = '2019-12-09 12:02:48' WHERE \`id\` = 13`, + ) + + // AGE Dezember 2019, original creation date: 2020-01-09 12:02:52 + await queryFn( + `UPDATE \`transactions\` SET creation_date = '2019-12-09 12:02:52' WHERE \`id\` = 14`, + ) + + // AGE Dezember 2019, original creation date: 2020-01-09 12:02:54 + await queryFn( + `UPDATE \`transactions\` SET creation_date = '2019-12-09 12:02:54' WHERE \`id\` = 15`, + ) + + // AGE Dezember 2019, original creation date: 2020-01-09 12:09:08 + await queryFn( + `UPDATE \`transactions\` SET creation_date = '2019-12-09 12:09:08' WHERE \`id\` = 16`, + ) + + // AGE Dezember 2019, original creation date: 2020-01-11 11:10:55 + await queryFn( + `UPDATE \`transactions\` SET creation_date = '2019-12-11 11:10:55' WHERE \`id\` = 17`, + ) + + // AGE Dezember 2019, original creation date: 2020-01-11 11:11:24 + await queryFn( + `UPDATE \`transactions\` SET creation_date = '2019-12-11 11:11:24' WHERE \`id\` = 18`, + ) + + // AGE Dezember 2019, original creation date: 2020-01-11 11:12:09 + await queryFn( + `UPDATE \`transactions\` SET creation_date = '2019-12-11 11:12:09' WHERE \`id\` = 19`, + ) + + // AGE Dezember 2019, original creation date: 2020-01-11 11:31:20 + await queryFn( + `UPDATE \`transactions\` SET creation_date = '2019-12-11 11:31:20' WHERE \`id\` = 20`, + ) + + // AGE Dezember 2019, original creation date: 2020-01-11 11:37:13 + await queryFn( + `UPDATE \`transactions\` SET creation_date = '2019-12-11 11:37:13' WHERE \`id\` = 21`, + ) + + // AGE Dezember 2019, original creation date: 2020-01-11 11:37:42 + await queryFn( + `UPDATE \`transactions\` SET creation_date = '2019-12-11 11:37:42' WHERE \`id\` = 22`, + ) + + // AGE Dezember 2019, original creation date: 2020-01-11 19:01:06 + await queryFn( + `UPDATE \`transactions\` SET creation_date = '2019-12-11 19:01:06' WHERE \`id\` = 23`, + ) + + // AGE Dezember 2019, original creation date: 2020-01-13 16:27:07 + await queryFn( + `UPDATE \`transactions\` SET creation_date = '2019-12-13 16:27:07' WHERE \`id\` = 24`, + ) + + // AGE Dezember 2019, original creation date: 2020-01-13 16:28:05 + await queryFn( + `UPDATE \`transactions\` SET creation_date = '2019-12-13 16:28:05' WHERE \`id\` = 25`, + ) + + // AGE Dezember 2019, original creation date: 2020-01-13 16:28:57 + await queryFn( + `UPDATE \`transactions\` SET creation_date = '2019-12-13 16:28:57' WHERE \`id\` = 26`, + ) + + // AGE Dezember 2019, original creation date: 2020-01-13 16:29:45 + await queryFn( + `UPDATE \`transactions\` SET creation_date = '2019-12-13 16:29:45' WHERE \`id\` = 27`, + ) + + // AGE Dezember 2019, original creation date: 2020-01-17 13:47:28 + await queryFn( + `UPDATE \`transactions\` SET creation_date = '2019-12-17 13:47:28' WHERE \`id\` = 28`, + ) + + // AGE Dezember 2019, original creation date: 2020-01-17 13:48:52 + await queryFn( + `UPDATE \`transactions\` SET creation_date = '2019-12-17 13:48:52' WHERE \`id\` = 29`, + ) + + // AGE Dezember 2019, original creation date: 2020-01-17 13:49:21 + await queryFn( + `UPDATE \`transactions\` SET creation_date = '2019-12-17 13:49:21' WHERE \`id\` = 30`, + ) + + // AGE Dezember 2019, original creation date: 2020-01-23 13:08:44 + await queryFn( + `UPDATE \`transactions\` SET creation_date = '2019-12-23 13:08:44' WHERE \`id\` = 31`, + ) + + // AGE Dezember 2019, original creation date: 2020-01-27 08:12:16 + await queryFn( + `UPDATE \`transactions\` SET creation_date = '2019-12-27 08:12:16' WHERE \`id\` = 32`, + ) + + // AGE Dezember 2019, original creation date: 2020-01-30 14:49:58 + await queryFn( + `UPDATE \`transactions\` SET creation_date = '2019-12-30 14:49:58' WHERE \`id\` = 33`, + ) + + // AGE Dezember 2019, original creation date: 2020-01-30 14:50:35 + await queryFn( + `UPDATE \`transactions\` SET creation_date = '2019-12-30 14:50:35' WHERE \`id\` = 34`, + ) + + // AGE Dezember 2019, original creation date: 2020-01-30 14:50:55 + await queryFn( + `UPDATE \`transactions\` SET creation_date = '2019-12-30 14:50:55' WHERE \`id\` = 35`, + ) + + // AGE Dezember 2019, original creation date: 2020-01-30 14:52:03 + await queryFn( + `UPDATE \`transactions\` SET creation_date = '2019-12-30 14:52:03' WHERE \`id\` = 36`, + ) + + // AGE Dezember 2019, original creation date: 2020-01-30 14:52:33 + await queryFn( + `UPDATE \`transactions\` SET creation_date = '2019-12-30 14:52:33' WHERE \`id\` = 37`, + ) + + // AGE Dezember 2019, original creation date: 2020-01-30 14:52:53 + await queryFn( + `UPDATE \`transactions\` SET creation_date = '2019-12-30 14:52:53' WHERE \`id\` = 38`, + ) + + // AGE Dezember 2019, original creation date: 2020-01-30 14:53:45 + await queryFn( + `UPDATE \`transactions\` SET creation_date = '2019-12-30 14:53:45' WHERE \`id\` = 39`, + ) + + // AGE Dezember 2019, original creation date: 2020-01-30 14:54:13 + await queryFn( + `UPDATE \`transactions\` SET creation_date = '2019-12-30 14:54:13' WHERE \`id\` = 40`, + ) + + // AGE Dezember 2019, original creation date: 2020-01-30 14:54:50 + await queryFn( + `UPDATE \`transactions\` SET creation_date = '2019-12-30 14:54:50' WHERE \`id\` = 41`, + ) + + // AGE Dezember 2019, original creation date: 2020-01-30 15:03:26 + await queryFn( + `UPDATE \`transactions\` SET creation_date = '2019-12-30 15:03:26' WHERE \`id\` = 42`, + ) + + // AGE Dezember 2019, original creation date: 2020-01-30 15:10:39 + await queryFn( + `UPDATE \`transactions\` SET creation_date = '2019-12-30 15:10:39' WHERE \`id\` = 43`, + ) + + // AGE Dezember 2019, original creation date: 2020-01-30 15:13:10 + await queryFn( + `UPDATE \`transactions\` SET creation_date = '2019-12-30 15:13:10' WHERE \`id\` = 44`, + ) + + // AGE Dezember 2019, original creation date: 2020-01-30 15:26:45 + await queryFn( + `UPDATE \`transactions\` SET creation_date = '2019-12-30 15:26:45' WHERE \`id\` = 45`, + ) + + // Grundeinkommen für Gemeinschaftsleistungen Jan. 2020, original creation date: 2020-02-19 08:54:31 + await queryFn( + `UPDATE \`transactions\` SET creation_date = '2020-01-19 08:54:31' WHERE \`id\` = 46`, + ) + + // Grundeinkommen für Gemeinschaftsleistungen Jan. 2020, original creation date: 2020-02-19 08:55:30 + await queryFn( + `UPDATE \`transactions\` SET creation_date = '2020-01-19 08:55:30' WHERE \`id\` = 47`, + ) + + // Grundeinkommen für Gemeinschaftsleistungen Jan. 2020, original creation date: 2020-02-19 08:55:33 + await queryFn( + `UPDATE \`transactions\` SET creation_date = '2020-01-19 08:55:33' WHERE \`id\` = 48`, + ) + + // Grundeinkommen für Gemeinschaftsleistungen Jan. 2020, original creation date: 2020-02-19 08:55:36 + await queryFn( + `UPDATE \`transactions\` SET creation_date = '2020-01-19 08:55:36' WHERE \`id\` = 49`, + ) + + // Grundeinkommen für Gemeinschaftsleistungen Jan. 2020, original creation date: 2020-02-19 08:55:39 + await queryFn( + `UPDATE \`transactions\` SET creation_date = '2020-01-19 08:55:39' WHERE \`id\` = 50`, + ) + + // Grundeinkommen für Gemeinschaftsleistungen Jan. 2020, original creation date: 2020-02-19 08:55:43 + await queryFn( + `UPDATE \`transactions\` SET creation_date = '2020-01-19 08:55:43' WHERE \`id\` = 51`, + ) + + // Grundeinkommen für Gemeinschaftsleistungen Jan. 2020, original creation date: 2020-02-19 08:55:46 + await queryFn( + `UPDATE \`transactions\` SET creation_date = '2020-01-19 08:55:46' WHERE \`id\` = 52`, + ) + + // Grundeinkommen für Gemeinschaftsleistungen Jan. 2020, original creation date: 2020-02-19 08:55:48 + await queryFn( + `UPDATE \`transactions\` SET creation_date = '2020-01-19 08:55:48' WHERE \`id\` = 53`, + ) + + // Grundeinkommen für Gemeinschaftsleistungen Jan. 2020, original creation date: 2020-02-19 08:55:50 + await queryFn( + `UPDATE \`transactions\` SET creation_date = '2020-01-19 08:55:50' WHERE \`id\` = 54`, + ) + + // Grundeinkommen für Gemeinschaftsleistungen Jan. 2020, original creation date: 2020-02-19 08:55:52 + await queryFn( + `UPDATE \`transactions\` SET creation_date = '2020-01-19 08:55:52' WHERE \`id\` = 55`, + ) + + // Grundeinkommen für Gemeinschaftsleistungen Jan. 2020, original creation date: 2020-02-19 08:55:54 + await queryFn( + `UPDATE \`transactions\` SET creation_date = '2020-01-19 08:55:54' WHERE \`id\` = 56`, + ) + + // Grundeinkommen für Gemeinschaftsleistungen Jan. 2020, original creation date: 2020-02-19 08:55:56 + await queryFn( + `UPDATE \`transactions\` SET creation_date = '2020-01-19 08:55:56' WHERE \`id\` = 57`, + ) + + // Grundeinkommen für Gemeinschaftsleistungen Jan. 2020, original creation date: 2020-02-19 08:55:59 + await queryFn( + `UPDATE \`transactions\` SET creation_date = '2020-01-19 08:55:59' WHERE \`id\` = 58`, + ) + + // Grundeinkommen für Gemeinschaftsleistungen Jan. 2020, original creation date: 2020-02-19 08:56:02 + await queryFn( + `UPDATE \`transactions\` SET creation_date = '2020-01-19 08:56:02' WHERE \`id\` = 59`, + ) + + // Grundeinkommen für Gemeinschaftsleistungen Jan. 2020, original creation date: 2020-02-19 08:56:05 + await queryFn( + `UPDATE \`transactions\` SET creation_date = '2020-01-19 08:56:05' WHERE \`id\` = 60`, + ) + + // Grundeinkommen für Gemeinschaftsleistungen Jan. 2020, original creation date: 2020-02-19 08:56:07 + await queryFn( + `UPDATE \`transactions\` SET creation_date = '2020-01-19 08:56:07' WHERE \`id\` = 61`, + ) + + // Grundeinkommen für Gemeinschaftsleistungen Jan. 2020, original creation date: 2020-02-19 08:56:10 + await queryFn( + `UPDATE \`transactions\` SET creation_date = '2020-01-19 08:56:10' WHERE \`id\` = 62`, + ) + + // Grundeinkommen für Gemeinschaftsleistungen Jan. 2020, original creation date: 2020-02-19 08:56:12 + await queryFn( + `UPDATE \`transactions\` SET creation_date = '2020-01-19 08:56:12' WHERE \`id\` = 63`, + ) + + // Grundeinkommen für Gemeinschaftsleistungen Jan. 2020, original creation date: 2020-02-19 08:56:14 + await queryFn( + `UPDATE \`transactions\` SET creation_date = '2020-01-19 08:56:14' WHERE \`id\` = 64`, + ) + + // Grundeinkommen für Gemeinschaftsleistungen Jan. 2020, original creation date: 2020-02-19 08:56:21 + await queryFn( + `UPDATE \`transactions\` SET creation_date = '2020-01-19 08:56:21' WHERE \`id\` = 65`, + ) + + // Grundeinkommen für Gemeinschaftsleistungen Jan. 2020, original creation date: 2020-02-19 08:56:24 + await queryFn( + `UPDATE \`transactions\` SET creation_date = '2020-01-19 08:56:24' WHERE \`id\` = 66`, + ) + + // Grundeinkommen für Gemeinschaftsleistungen Jan. 2020, original creation date: 2020-02-19 08:56:26 + await queryFn( + `UPDATE \`transactions\` SET creation_date = '2020-01-19 08:56:26' WHERE \`id\` = 67`, + ) + + // Grundeinkommen für Gemeinschaftsleistungen Jan. 2020, original creation date: 2020-02-19 08:56:28 + await queryFn( + `UPDATE \`transactions\` SET creation_date = '2020-01-19 08:56:28' WHERE \`id\` = 68`, + ) + + // Grundeinkommen für Gemeinschaftsleistungen Jan. 2020, original creation date: 2020-02-19 08:56:31 + await queryFn( + `UPDATE \`transactions\` SET creation_date = '2020-01-19 08:56:31' WHERE \`id\` = 69`, + ) + + // Grundeinkommen rückwirkend Dezember, original creation date: 2020-02-20 06:40:36 + await queryFn( + `UPDATE \`transactions\` SET creation_date = '2019-12-20 06:40:36' WHERE \`id\` = 70`, + ) + + // Grundeinkommen für GLJanuar 2020, original creation date: 2020-02-20 06:43:41 + await queryFn( + `UPDATE \`transactions\` SET creation_date = '2020-01-20 06:43:41' WHERE \`id\` = 71`, + ) + + // Grundeinkommen für GLJanuar 2020, original creation date: 2020-02-20 06:43:43 + await queryFn( + `UPDATE \`transactions\` SET creation_date = '2020-01-20 06:43:43' WHERE \`id\` = 72`, + ) + + // Grundeinkommen für GLJanuar 2020, original creation date: 2020-02-20 06:43:45 + await queryFn( + `UPDATE \`transactions\` SET creation_date = '2020-01-20 06:43:45' WHERE \`id\` = 73`, + ) + + // Grundeinkommen für GLJanuar 2020, original creation date: 2020-02-20 06:43:47 + await queryFn( + `UPDATE \`transactions\` SET creation_date = '2020-01-20 06:43:47' WHERE \`id\` = 74`, + ) + + // Grundeinkommen, original creation date: 2020-02-20 07:09:05 + await queryFn( + `UPDATE \`transactions\` SET creation_date = '2020-01-20 07:09:05' WHERE \`id\` = 75`, + ) + + // Grundeinkommen für GLJanuar 2020, original creation date: 2020-02-20 08:03:31 + await queryFn( + `UPDATE \`transactions\` SET creation_date = '2020-01-20 08:03:31' WHERE \`id\` = 76`, + ) + + // AGE für Gemeinschaftsleistungen Januar 2020, original creation date: 2020-02-29 16:17:24 + await queryFn( + `UPDATE \`transactions\` SET creation_date = '2020-01-29 16:17:24' WHERE \`id\` = 77`, + ) + + // AGE für Gemeinschaftsleistungen Januar 2020, original creation date: 2020-02-29 16:17:35 + await queryFn( + `UPDATE \`transactions\` SET creation_date = '2020-01-29 16:17:35' WHERE \`id\` = 78`, + ) + + // AGE für Gemeinschaftsleistungen Januar 2020, original creation date: 2020-02-29 16:17:42 + await queryFn( + `UPDATE \`transactions\` SET creation_date = '2020-01-29 16:17:42' WHERE \`id\` = 79`, + ) + + // AGE für Gemeinschaftsleistungen Januar 2020, original creation date: 2020-02-29 16:29:47 + await queryFn( + `UPDATE \`transactions\` SET creation_date = '2020-01-29 16:29:47' WHERE \`id\` = 80`, + ) + + // AGE für Gemeinschaftsleistungen Januar 2020, original creation date: 2020-02-29 16:29:48 + await queryFn( + `UPDATE \`transactions\` SET creation_date = '2020-01-29 16:29:48' WHERE \`id\` = 81`, + ) + + // AGE für Gemeinschaftsleistungen Januar 2020, original creation date: 2020-02-29 16:29:55 + await queryFn( + `UPDATE \`transactions\` SET creation_date = '2020-01-29 16:29:55' WHERE \`id\` = 82`, + ) + + // AGE rückwirkend für Januar 2020, original creation date: 2020-03-04 09:08:54 + await queryFn( + `UPDATE \`transactions\` SET creation_date = '2020-01-04 09:08:54' WHERE \`id\` = 83`, + ) + + // AGE für Gemeinschaftsleitungen Januar, original creation date: 2020-03-07 07:59:42 + await queryFn( + `UPDATE \`transactions\` SET creation_date = '2020-01-07 07:59:42' WHERE \`id\` = 84`, + ) + + // AGE für Gemeinschaftsleitungen Januar, original creation date: 2020-03-07 07:59:51 + await queryFn( + `UPDATE \`transactions\` SET creation_date = '2020-01-07 07:59:51' WHERE \`id\` = 85`, + ) + + // AGE für Gemeinschaftsleitungen Januar, original creation date: 2020-03-07 07:59:54 + await queryFn( + `UPDATE \`transactions\` SET creation_date = '2020-01-07 07:59:54' WHERE \`id\` = 86`, + ) + + // AGE für Gemeinschaftsleitungen Januar, original creation date: 2020-03-07 07:59:57 + await queryFn( + `UPDATE \`transactions\` SET creation_date = '2020-01-07 07:59:57' WHERE \`id\` = 87`, + ) + + // AGE für Gemeinschaftsleistungen Februar 2020, original creation date: 2020-03-07 08:15:48 + await queryFn( + `UPDATE \`transactions\` SET creation_date = '2020-02-07 08:15:48' WHERE \`id\` = 88`, + ) + + // AGE für Gemeinschaftsleistungen Februar 2020, original creation date: 2020-03-07 08:15:53 + await queryFn( + `UPDATE \`transactions\` SET creation_date = '2020-02-07 08:15:53' WHERE \`id\` = 89`, + ) + + // AGE für Gemeinschaftsleistungen Februar 2020, original creation date: 2020-03-07 08:15:56 + await queryFn( + `UPDATE \`transactions\` SET creation_date = '2020-02-07 08:15:56' WHERE \`id\` = 90`, + ) + + // AGE für Gemeinschaftsleistungen Februar 2020, original creation date: 2020-03-07 08:15:59 + await queryFn( + `UPDATE \`transactions\` SET creation_date = '2020-02-07 08:15:59' WHERE \`id\` = 91`, + ) + + // AGE für Gemeinschaftsleistungen Februar 2020, original creation date: 2020-03-07 08:16:01 + await queryFn( + `UPDATE \`transactions\` SET creation_date = '2020-02-07 08:16:01' WHERE \`id\` = 92`, + ) + + // AGE für Gemeinschaftsleistungen Februar 2020, original creation date: 2020-03-07 08:16:05 + await queryFn( + `UPDATE \`transactions\` SET creation_date = '2020-02-07 08:16:05' WHERE \`id\` = 93`, + ) + + // AGE für Gemeinschaftsleistungen Februar 2020, original creation date: 2020-03-07 08:16:07 + await queryFn( + `UPDATE \`transactions\` SET creation_date = '2020-02-07 08:16:07' WHERE \`id\` = 94`, + ) + + // AGE für Gemeinschaftsleistungen Februar 2020, original creation date: 2020-03-07 08:16:10 + await queryFn( + `UPDATE \`transactions\` SET creation_date = '2020-02-07 08:16:10' WHERE \`id\` = 95`, + ) + + // AGE für Gemeinschaftsleistungen Februar 2020, original creation date: 2020-03-07 08:17:00 + await queryFn( + `UPDATE \`transactions\` SET creation_date = '2020-02-07 08:17:00' WHERE \`id\` = 96`, + ) + + // AGE für Gemeinschaftsleistungen Februar 2020, original creation date: 2020-03-07 08:17:03 + await queryFn( + `UPDATE \`transactions\` SET creation_date = '2020-02-07 08:17:03' WHERE \`id\` = 97`, + ) + + // AGE für Gemeinschaftsleistungen Februar 2020, original creation date: 2020-03-07 08:17:05 + await queryFn( + `UPDATE \`transactions\` SET creation_date = '2020-02-07 08:17:05' WHERE \`id\` = 98`, + ) + + // AGE für Gemeinschaftsleistungen Februar 2020, original creation date: 2020-03-07 08:17:07 + await queryFn( + `UPDATE \`transactions\` SET creation_date = '2020-02-07 08:17:07' WHERE \`id\` = 99`, + ) + + // AGE für Gemeinschaftsleistungen Februar 2020, original creation date: 2020-03-07 08:17:09 + await queryFn( + `UPDATE \`transactions\` SET creation_date = '2020-02-07 08:17:09' WHERE \`id\` = 100`, + ) + + // AGE für Gemeinschaftsleistungen Februar 2020, original creation date: 2020-03-07 08:17:11 + await queryFn( + `UPDATE \`transactions\` SET creation_date = '2020-02-07 08:17:11' WHERE \`id\` = 101`, + ) + + // AGE für Gemeinschaftsleistungen Februar 2020, original creation date: 2020-03-07 08:17:13 + await queryFn( + `UPDATE \`transactions\` SET creation_date = '2020-02-07 08:17:13' WHERE \`id\` = 102`, + ) + + // AGE für Gemeinschaftsleistungen Februar 2020, original creation date: 2020-03-07 08:17:21 + await queryFn( + `UPDATE \`transactions\` SET creation_date = '2020-02-07 08:17:21' WHERE \`id\` = 103`, + ) + + // AGE für Gemeinschaftsleistungen Februar 2020, original creation date: 2020-03-07 08:17:25 + await queryFn( + `UPDATE \`transactions\` SET creation_date = '2020-02-07 08:17:25' WHERE \`id\` = 104`, + ) + + // AGE für Gemeinschaftsleistungen Februar 2020, original creation date: 2020-03-07 08:17:28 + await queryFn( + `UPDATE \`transactions\` SET creation_date = '2020-02-07 08:17:28' WHERE \`id\` = 105`, + ) + + // AGE für Gemeinschaftsleistungen Februar, original creation date: 2020-03-07 08:19:15 + await queryFn( + `UPDATE \`transactions\` SET creation_date = '2020-02-07 08:19:15' WHERE \`id\` = 106`, + ) + + // AGE für Gemeinschaftsleistungen Februar 2020 geschöpft und gutgeschrieben., original creation date: 2020-03-08 18:00:20 + await queryFn( + `UPDATE \`transactions\` SET creation_date = '2020-02-08 18:00:20' WHERE \`id\` = 107`, + ) + + // AGE für Februar, original creation date: 2020-03-09 11:43:30 + await queryFn( + `UPDATE \`transactions\` SET creation_date = '2020-02-09 11:43:30' WHERE \`id\` = 108`, + ) + + // AGE für Gemeinschaftsleistungen Februar 2020, original creation date: 2020-03-09 17:48:34 + await queryFn( + `UPDATE \`transactions\` SET creation_date = '2020-02-09 17:48:34' WHERE \`id\` = 109`, + ) + + // AGE für Gemeinschaftsleistungen Februar 2020, original creation date: 2020-03-09 17:48:36 + await queryFn( + `UPDATE \`transactions\` SET creation_date = '2020-02-09 17:48:36' WHERE \`id\` = 110`, + ) + + // AGE für Gemeinschaftsleistungen Februar 2020, original creation date: 2020-03-09 17:48:38 + await queryFn( + `UPDATE \`transactions\` SET creation_date = '2020-02-09 17:48:38' WHERE \`id\` = 111`, + ) + + // AGE für Gemeinschaftsleistungen Februar 2020, original creation date: 2020-03-09 17:48:40 + await queryFn( + `UPDATE \`transactions\` SET creation_date = '2020-02-09 17:48:40' WHERE \`id\` = 112`, + ) + + // AGE für Gemeinschaftsleistungen Februar 2020, original creation date: 2020-03-09 17:48:43 + await queryFn( + `UPDATE \`transactions\` SET creation_date = '2020-02-09 17:48:43' WHERE \`id\` = 113`, + ) + + // AGE für Gemeinschaftsleistungen rückwirkend für Januar 2020 , original creation date: 2020-03-11 21:11:03 + await queryFn( + `UPDATE \`transactions\` SET creation_date = '2020-01-11 21:11:03' WHERE \`id\` = 114`, + ) + + // AGE für Gemeinschaftsleistungen Februar 2020 , original creation date: 2020-03-11 21:17:22 + await queryFn( + `UPDATE \`transactions\` SET creation_date = '2020-02-11 21:17:22' WHERE \`id\` = 115`, + ) + + // AGE für Gemeinschaftsleistungen Februar 2020 , original creation date: 2020-03-11 21:17:26 + await queryFn( + `UPDATE \`transactions\` SET creation_date = '2020-02-11 21:17:26' WHERE \`id\` = 116`, + ) + + // AGE für Gemeinschaftsleistungen rückwirkend für Januar, original creation date: 2020-03-18 15:44:07 + await queryFn( + `UPDATE \`transactions\` SET creation_date = '2020-01-18 15:44:07' WHERE \`id\` = 117`, + ) + + // AGE für Gemeinschaftsleistungen Februar 2020 , original creation date: 2020-03-18 15:54:59 + await queryFn( + `UPDATE \`transactions\` SET creation_date = '2020-02-18 15:54:59' WHERE \`id\` = 118`, + ) + + // AGE für Gemeinschaftsleistungen Februar 2020 , original creation date: 2020-03-18 15:55:32 + await queryFn( + `UPDATE \`transactions\` SET creation_date = '2020-02-18 15:55:32' WHERE \`id\` = 119`, + ) + + // AGE für Gemeinschaftsleistungen Februar 2020 , original creation date: 2020-03-18 15:56:32 + await queryFn( + `UPDATE \`transactions\` SET creation_date = '2020-02-18 15:56:32' WHERE \`id\` = 120`, + ) + + // AGE für Gemeinschaftsleistungen Februar 2020 , original creation date: 2020-03-18 15:56:48 + await queryFn( + `UPDATE \`transactions\` SET creation_date = '2020-02-18 15:56:48' WHERE \`id\` = 121`, + ) + + // AGE für Gemeinschaftsleistungen Februar 2020 , original creation date: 2020-03-18 15:57:14 + await queryFn( + `UPDATE \`transactions\` SET creation_date = '2020-02-18 15:57:14' WHERE \`id\` = 122`, + ) + + // AGE für Gemeinschaftsleistungen Februar 2020 , original creation date: 2020-03-18 15:58:41 + await queryFn( + `UPDATE \`transactions\` SET creation_date = '2020-02-18 15:58:41' WHERE \`id\` = 123`, + ) + + // AGE für Gemeinschaftsleistungen Februar 2020 , original creation date: 2020-03-18 15:59:03 + await queryFn( + `UPDATE \`transactions\` SET creation_date = '2020-02-18 15:59:03' WHERE \`id\` = 124`, + ) + + // AGE für Gemeinschaftsleistungen Februar 2020 , original creation date: 2020-03-18 15:59:26 + await queryFn( + `UPDATE \`transactions\` SET creation_date = '2020-02-18 15:59:26' WHERE \`id\` = 125`, + ) + + // AGE für Gemeinschaftsleistungen Februar 2020 , original creation date: 2020-03-18 16:00:05 + await queryFn( + `UPDATE \`transactions\` SET creation_date = '2020-02-18 16:00:05' WHERE \`id\` = 126`, + ) + + // AGE für Gemeinschaftsleistungen Februar 2020 , original creation date: 2020-03-18 16:00:12 + await queryFn( + `UPDATE \`transactions\` SET creation_date = '2020-02-18 16:00:12' WHERE \`id\` = 127`, + ) + + // Aktives Grundeinkommen, original creation date: 2020-03-23 07:35:35 + await queryFn( + `UPDATE \`transactions\` SET creation_date = '2020-02-23 07:35:35' WHERE \`id\` = 128`, + ) + + // Aktives Grundeinkommen, original creation date: 2020-03-23 07:35:38 + await queryFn( + `UPDATE \`transactions\` SET creation_date = '2020-02-23 07:35:38' WHERE \`id\` = 129`, + ) + + // Aktives Grundeinkommen, original creation date: 2020-03-23 07:35:42 + await queryFn( + `UPDATE \`transactions\` SET creation_date = '2020-02-23 07:35:42' WHERE \`id\` = 130`, + ) + + // Aktives Grundeinkommen Januar , original creation date: 2020-03-24 17:00:05 + await queryFn( + `UPDATE \`transactions\` SET creation_date = '2020-01-24 17:00:05' WHERE \`id\` = 131`, + ) + + // Aktives Grundeinkommen Februar, original creation date: 2020-03-24 17:06:50 + await queryFn( + `UPDATE \`transactions\` SET creation_date = '2020-02-24 17:06:50' WHERE \`id\` = 132`, + ) + + // Aktives Grundeinkommen Februar, original creation date: 2020-03-24 17:06:54 + await queryFn( + `UPDATE \`transactions\` SET creation_date = '2020-02-24 17:06:54' WHERE \`id\` = 133`, + ) + + // Aktives Grundeinkommen März, original creation date: 2020-03-24 17:14:21 + await queryFn( + `UPDATE \`transactions\` SET creation_date = '2020-03-24 17:14:21' WHERE \`id\` = 134`, + ) + + // Aktives Grundeinkommen März, original creation date: 2020-03-24 17:14:27 + await queryFn( + `UPDATE \`transactions\` SET creation_date = '2020-03-24 17:14:27' WHERE \`id\` = 135`, + ) + + // Aktives Grundeinkommen März, original creation date: 2020-03-24 17:14:28 + await queryFn( + `UPDATE \`transactions\` SET creation_date = '2020-03-24 17:14:28' WHERE \`id\` = 136`, + ) + + // Aktives Grundeinkommen März, original creation date: 2020-03-24 17:14:30 + await queryFn( + `UPDATE \`transactions\` SET creation_date = '2020-03-24 17:14:30' WHERE \`id\` = 137`, + ) + + // Aktives Grundeinkommen geschöpft , original creation date: 2020-03-27 09:06:16 + await queryFn( + `UPDATE \`transactions\` SET creation_date = '2020-02-27 09:06:16' WHERE \`id\` = 138`, + ) + + // Aktives Grundeinkommen für GL Februar, original creation date: 2020-03-27 09:44:27 + await queryFn( + `UPDATE \`transactions\` SET creation_date = '2020-02-27 09:44:27' WHERE \`id\` = 139`, + ) + + // Aktives Grundeinkommen für GL Februar, original creation date: 2020-03-27 09:44:29 + await queryFn( + `UPDATE \`transactions\` SET creation_date = '2020-02-27 09:44:29' WHERE \`id\` = 140`, + ) + + // Aktives Grundeinkommen für GL Februar, original creation date: 2020-03-27 09:44:30 + await queryFn( + `UPDATE \`transactions\` SET creation_date = '2020-02-27 09:44:30' WHERE \`id\` = 141`, + ) + + // Aktives Grundeinkommen für GL Februar, original creation date: 2020-03-27 09:44:35 + await queryFn( + `UPDATE \`transactions\` SET creation_date = '2020-02-27 09:44:35' WHERE \`id\` = 142`, + ) + + // Aktives Grundeinkommen für GL Februar, original creation date: 2020-03-27 09:44:36 + await queryFn( + `UPDATE \`transactions\` SET creation_date = '2020-02-27 09:44:36' WHERE \`id\` = 143`, + ) + + // Aktives Grundeinkommen für GL Februar, original creation date: 2020-03-27 09:44:40 + await queryFn( + `UPDATE \`transactions\` SET creation_date = '2020-02-27 09:44:40' WHERE \`id\` = 144`, + ) + + // Aktives Grundeinkommen für GL Februar, original creation date: 2020-03-27 09:44:42 + await queryFn( + `UPDATE \`transactions\` SET creation_date = '2020-02-27 09:44:42' WHERE \`id\` = 145`, + ) + + // Aktives Grundeinkommen für GL. März, original creation date: 2020-03-28 09:28:24 + await queryFn( + `UPDATE \`transactions\` SET creation_date = '2020-03-28 09:28:24' WHERE \`id\` = 146`, + ) + + // Aktives Grundeinkommen für GL. März, original creation date: 2020-03-28 09:34:30 + await queryFn( + `UPDATE \`transactions\` SET creation_date = '2020-03-28 09:34:30' WHERE \`id\` = 147`, + ) + + // , original creation date: 2020-03-29 17:21:33 + await queryFn( + `UPDATE \`transactions\` SET creation_date = '2020-02-28 17:21:33' WHERE \`id\` = 148`, + ) + + // , original creation date: 2020-03-29 17:21:35 + await queryFn( + `UPDATE \`transactions\` SET creation_date = '2020-02-28 17:21:35' WHERE \`id\` = 149`, + ) + + // Aktives Grundeinkommen für GL. Dez, original creation date: 2020-03-30 06:59:55 + await queryFn( + `UPDATE \`transactions\` SET creation_date = '2019-12-30 06:59:55' WHERE \`id\` = 150`, + ) + + // Aktives Grundeinkommen für GL. Dez 2019, original creation date: 2020-03-30 07:05:14 + await queryFn( + `UPDATE \`transactions\` SET creation_date = '2019-12-30 07:05:14' WHERE \`id\` = 151`, + ) + + // Aktives Grundeinkommen für GL. Jan 2020, original creation date: 2020-03-30 07:09:52 + await queryFn( + `UPDATE \`transactions\` SET creation_date = '2020-01-30 07:09:52' WHERE \`id\` = 152`, + ) + + // Aktives Grundeinkommen für GL. Februar 2020, original creation date: 2020-03-30 07:15:43 + await queryFn( + `UPDATE \`transactions\` SET creation_date = '2020-03-01 07:15:43' WHERE \`id\` = 153`, + ) + + // Aktives Grundeinkommen für GL., original creation date: 2020-03-30 07:16:33 + await queryFn( + `UPDATE \`transactions\` SET creation_date = '2020-03-01 07:16:33' WHERE \`id\` = 154`, + ) + + // Aktives Grundeinkommen für GL. März, original creation date: 2020-03-30 07:21:07 + await queryFn( + `UPDATE \`transactions\` SET creation_date = '2020-03-30 07:21:07' WHERE \`id\` = 155`, + ) + + // Aktives Grundeinkommen für GL. Feb. 2020, original creation date: 2020-03-30 11:47:55 + await queryFn( + `UPDATE \`transactions\` SET creation_date = '2020-03-01 11:47:55' WHERE \`id\` = 156`, + ) + + // Aktives Grundeinkommen für GL. März, original creation date: 2020-04-01 06:56:20 + await queryFn( + `UPDATE \`transactions\` SET creation_date = '2020-03-01 06:56:20' WHERE \`id\` = 157`, + ) + + // Aktives Grundeinkommen für GL. März, original creation date: 2020-04-01 06:56:26 + await queryFn( + `UPDATE \`transactions\` SET creation_date = '2020-03-01 06:56:26' WHERE \`id\` = 158`, + ) + + // Aktives Grundeinkommen für GL. März, original creation date: 2020-04-01 06:56:29 + await queryFn( + `UPDATE \`transactions\` SET creation_date = '2020-03-01 06:56:29' WHERE \`id\` = 159`, + ) + + // Aktives Grundeinkommen für GL. März, original creation date: 2020-04-01 06:56:31 + await queryFn( + `UPDATE \`transactions\` SET creation_date = '2020-03-01 06:56:31' WHERE \`id\` = 160`, + ) + + // Aktives Grundeinkommen für GL. März, original creation date: 2020-04-01 06:58:10 + await queryFn( + `UPDATE \`transactions\` SET creation_date = '2020-03-01 06:58:10' WHERE \`id\` = 161`, + ) + + // Aktives Grundeinkommen für GL. März, original creation date: 2020-04-07 14:09:26 + await queryFn( + `UPDATE \`transactions\` SET creation_date = '2020-03-07 14:09:26' WHERE \`id\` = 162`, + ) + + // Aktives Grundeinkommen für GL. März, original creation date: 2020-04-07 14:09:28 + await queryFn( + `UPDATE \`transactions\` SET creation_date = '2020-03-07 14:09:28' WHERE \`id\` = 163`, + ) + + // Aktives Grundeinkommen für GL. März, original creation date: 2020-04-07 14:09:29 + await queryFn( + `UPDATE \`transactions\` SET creation_date = '2020-03-07 14:09:29' WHERE \`id\` = 164`, + ) + + // Aktives Grundeinkommen für GL. März, original creation date: 2020-04-07 14:09:32 + await queryFn( + `UPDATE \`transactions\` SET creation_date = '2020-03-07 14:09:32' WHERE \`id\` = 165`, + ) + + // Aktives Grundeinkommen für GL. März, original creation date: 2020-04-08 18:41:17 + await queryFn( + `UPDATE \`transactions\` SET creation_date = '2020-03-08 18:41:17' WHERE \`id\` = 166`, + ) + + // Aktives Grundeinkommen für GL. März, original creation date: 2020-04-08 18:41:20 + await queryFn( + `UPDATE \`transactions\` SET creation_date = '2020-03-08 18:41:20' WHERE \`id\` = 167`, + ) + + // Aktives Grundeinkommen für GL. März, original creation date: 2020-04-08 18:41:21 + await queryFn( + `UPDATE \`transactions\` SET creation_date = '2020-03-08 18:41:21' WHERE \`id\` = 168`, + ) + + // Aktives Grundeinkommen für GL. März, original creation date: 2020-04-08 18:41:23 + await queryFn( + `UPDATE \`transactions\` SET creation_date = '2020-03-08 18:41:23' WHERE \`id\` = 169`, + ) + + // Aktives Grundeinkommen für GL. März, original creation date: 2020-04-08 18:41:27 + await queryFn( + `UPDATE \`transactions\` SET creation_date = '2020-03-08 18:41:27' WHERE \`id\` = 170`, + ) + + // Aktives Grundeinkommen für GL. März, original creation date: 2020-04-08 18:58:15 + await queryFn( + `UPDATE \`transactions\` SET creation_date = '2020-03-08 18:58:15' WHERE \`id\` = 171`, + ) + + // Aktives Grundeinkommen für GL. März, original creation date: 2020-04-15 16:10:54 + await queryFn( + `UPDATE \`transactions\` SET creation_date = '2020-03-15 16:10:54' WHERE \`id\` = 172`, + ) + + // Aktives Grundeinkommen für GL. März, original creation date: 2020-04-15 16:10:56 + await queryFn( + `UPDATE \`transactions\` SET creation_date = '2020-03-15 16:10:56' WHERE \`id\` = 173`, + ) + + // Aktives Grundeinkommen für GL. März, original creation date: 2020-04-15 16:10:58 + await queryFn( + `UPDATE \`transactions\` SET creation_date = '2020-03-15 16:10:58' WHERE \`id\` = 174`, + ) + + // Aktives Grundeinkommen für GL. März, original creation date: 2020-04-15 16:11:01 + await queryFn( + `UPDATE \`transactions\` SET creation_date = '2020-03-15 16:11:01' WHERE \`id\` = 175`, + ) + + // Aktives Grundeinkommen für GL. März, original creation date: 2020-04-15 16:11:02 + await queryFn( + `UPDATE \`transactions\` SET creation_date = '2020-03-15 16:11:02' WHERE \`id\` = 176`, + ) + + // Aktives Grundeinkommen für GL. März, original creation date: 2020-04-15 16:11:04 + await queryFn( + `UPDATE \`transactions\` SET creation_date = '2020-03-15 16:11:04' WHERE \`id\` = 177`, + ) + + // Aktives Grundeinkommen für GL. März, original creation date: 2020-04-15 16:11:07 + await queryFn( + `UPDATE \`transactions\` SET creation_date = '2020-03-15 16:11:07' WHERE \`id\` = 178`, + ) + + // Aktives Grundeinkommen für GL.März 2020, original creation date: 2020-04-17 16:54:39 + await queryFn( + `UPDATE \`transactions\` SET creation_date = '2020-03-17 16:54:39' WHERE \`id\` = 179`, + ) + + // Aktives Grundeinkommen für GL.März 2020, original creation date: 2020-04-17 16:54:40 + await queryFn( + `UPDATE \`transactions\` SET creation_date = '2020-03-17 16:54:40' WHERE \`id\` = 180`, + ) + + // Aktives Grundeinkommen für GL.März 2020, original creation date: 2020-04-17 16:54:42 + await queryFn( + `UPDATE \`transactions\` SET creation_date = '2020-03-17 16:54:42' WHERE \`id\` = 181`, + ) + + // Aktives Grundeinkommen für GL.März 2020, original creation date: 2020-04-17 16:54:44 + await queryFn( + `UPDATE \`transactions\` SET creation_date = '2020-03-17 16:54:44' WHERE \`id\` = 182`, + ) + + // Aktives Grundeinkommen geschöpft und gutgeschrieben. + // Tausend Dank, weil Du bei uns bist und gemeinsam mit uns das Lebensgeld der Zukunft erschaffst!, original creation date: 2020-04-18 08:58:42 + await queryFn( + `UPDATE \`transactions\` SET creation_date = '2020-03-18 08:58:42' WHERE \`id\` = 183`, + ) + + // Aktives Grundeinkommen geschöpft und gutgeschrieben. + // Tausend Dank, weil Du bei uns bist und gemeinsam mit uns das Lebensgeld der Zukunft erschaffst!, original creation date: 2020-04-18 08:58:44 + await queryFn( + `UPDATE \`transactions\` SET creation_date = '2020-03-18 08:58:44' WHERE \`id\` = 184`, + ) + + // Aktives Grundeinkommen für GL.März 2020, original creation date: 2020-04-20 17:44:36 + await queryFn( + `UPDATE \`transactions\` SET creation_date = '2020-03-20 17:44:36' WHERE \`id\` = 185`, + ) + + // Aktives Grundeinkommen für GL.März 2020, original creation date: 2020-04-20 17:44:38 + await queryFn( + `UPDATE \`transactions\` SET creation_date = '2020-03-20 17:44:38' WHERE \`id\` = 186`, + ) + + // Aktives Grundeinkommen für GL.März 2020, original creation date: 2020-04-20 17:44:40 + await queryFn( + `UPDATE \`transactions\` SET creation_date = '2020-03-20 17:44:40' WHERE \`id\` = 187`, + ) + + // Aktives Grundeinkommen für GL.März 2020, original creation date: 2020-04-20 17:44:43 + await queryFn( + `UPDATE \`transactions\` SET creation_date = '2020-03-20 17:44:43' WHERE \`id\` = 188`, + ) + + // Aktives Grundeinkommen für GL März 2020, original creation date: 2020-04-25 06:30:13 + await queryFn( + `UPDATE \`transactions\` SET creation_date = '2020-03-25 06:30:13' WHERE \`id\` = 189`, + ) + + // Aktives Grundeinkommen für GL März 2020, original creation date: 2020-04-25 06:30:19 + await queryFn( + `UPDATE \`transactions\` SET creation_date = '2020-03-25 06:30:19' WHERE \`id\` = 190`, + ) + + // Aktives Grundeinkommen für GL März 2020, original creation date: 2020-04-25 06:30:21 + await queryFn( + `UPDATE \`transactions\` SET creation_date = '2020-03-25 06:30:21' WHERE \`id\` = 191`, + ) + + // Aktives Grundeinkommen für GL März 2020, original creation date: 2020-04-25 06:30:23 + await queryFn( + `UPDATE \`transactions\` SET creation_date = '2020-03-25 06:30:23' WHERE \`id\` = 192`, + ) + + // Aktives Grundeinkommen für GL März 2020, original creation date: 2020-04-25 06:30:24 + await queryFn( + `UPDATE \`transactions\` SET creation_date = '2020-03-25 06:30:24' WHERE \`id\` = 193`, + ) + + // Aktives Grundeinkommen für GL März 2020, original creation date: 2020-04-25 06:30:26 + await queryFn( + `UPDATE \`transactions\` SET creation_date = '2020-03-25 06:30:26' WHERE \`id\` = 194`, + ) + + // Aktives Grundeinkommen für G März 2020, original creation date: 2020-04-25 18:41:55 + await queryFn( + `UPDATE \`transactions\` SET creation_date = '2020-03-25 18:41:55' WHERE \`id\` = 195`, + ) + + // Aktives Grundeinkommen für G März 2020, original creation date: 2020-04-25 18:42:25 + await queryFn( + `UPDATE \`transactions\` SET creation_date = '2020-03-25 18:42:25' WHERE \`id\` = 196`, + ) + + // Aktives Grundeinkommen für März 2020, original creation date: 2020-04-25 18:46:01 + await queryFn( + `UPDATE \`transactions\` SET creation_date = '2020-03-25 18:46:01' WHERE \`id\` = 197`, + ) + + // Aktives Grundeinkommen für März 2020, original creation date: 2020-04-30 06:40:39 + await queryFn( + `UPDATE \`transactions\` SET creation_date = '2020-03-30 06:40:39' WHERE \`id\` = 198`, + ) + + // Aktives Grundeinkommen für März 2020, original creation date: 2020-04-30 06:40:41 + await queryFn( + `UPDATE \`transactions\` SET creation_date = '2020-03-30 06:40:41' WHERE \`id\` = 199`, + ) + + // Aktives Grundeinkommen für März 2020, original creation date: 2020-04-30 06:40:42 + await queryFn( + `UPDATE \`transactions\` SET creation_date = '2020-03-30 06:40:42' WHERE \`id\` = 200`, + ) + + // Aktives Grundeinkommen für März 2020, original creation date: 2020-04-30 06:40:45 + await queryFn( + `UPDATE \`transactions\` SET creation_date = '2020-03-30 06:40:45' WHERE \`id\` = 201`, + ) + + // Aktives Grundeinkommen für März 2020, original creation date: 2020-04-30 06:40:46 + await queryFn( + `UPDATE \`transactions\` SET creation_date = '2020-03-30 06:40:46' WHERE \`id\` = 202`, + ) + + // Aktives Grundeinkommen für März 2020, original creation date: 2020-04-30 06:40:50 + await queryFn( + `UPDATE \`transactions\` SET creation_date = '2020-03-30 06:40:50' WHERE \`id\` = 203`, + ) + + // Aktives Grundeinkommen für März 2020, original creation date: 2020-05-02 08:25:27 + await queryFn( + `UPDATE \`transactions\` SET creation_date = '2020-03-02 08:25:27' WHERE \`id\` = 204`, + ) + + // Aktives Grundeinkommen für März 2020, original creation date: 2020-05-02 08:25:29 + await queryFn( + `UPDATE \`transactions\` SET creation_date = '2020-03-02 08:25:29' WHERE \`id\` = 205`, + ) + + // Aktives Grundeinkommen für März 2020, original creation date: 2020-05-02 08:25:32 + await queryFn( + `UPDATE \`transactions\` SET creation_date = '2020-03-02 08:25:32' WHERE \`id\` = 206`, + ) + + // Aktives Grundeinkommen für März 2020, original creation date: 2020-05-02 08:28:14 + await queryFn( + `UPDATE \`transactions\` SET creation_date = '2020-03-02 08:28:14' WHERE \`id\` = 207`, + ) + + // Aktives Grundeinkommen für April 2020, original creation date: 2020-05-02 08:43:49 + await queryFn( + `UPDATE \`transactions\` SET creation_date = '2020-04-02 08:43:49' WHERE \`id\` = 208`, + ) + + // Aktives Grundeinkommen für April 2020, original creation date: 2020-05-02 08:43:51 + await queryFn( + `UPDATE \`transactions\` SET creation_date = '2020-04-02 08:43:51' WHERE \`id\` = 209`, + ) + + // Aktives Grundeinkommen für April 2020, original creation date: 2020-05-02 08:43:54 + await queryFn( + `UPDATE \`transactions\` SET creation_date = '2020-04-02 08:43:54' WHERE \`id\` = 210`, + ) + + // Aktives Grundeinkommen für April 2020, original creation date: 2020-05-02 08:43:56 + await queryFn( + `UPDATE \`transactions\` SET creation_date = '2020-04-02 08:43:56' WHERE \`id\` = 211`, + ) + + // Aktives Grundeinkommen für April 2020, original creation date: 2020-05-02 08:43:57 + await queryFn( + `UPDATE \`transactions\` SET creation_date = '2020-04-02 08:43:57' WHERE \`id\` = 212`, + ) + + // Aktives Grundeinkommen für April 2020, original creation date: 2020-05-02 08:43:59 + await queryFn( + `UPDATE \`transactions\` SET creation_date = '2020-04-02 08:43:59' WHERE \`id\` = 213`, + ) + + // Aktives Grundeinkommen für April 2020, original creation date: 2020-05-02 08:44:01 + await queryFn( + `UPDATE \`transactions\` SET creation_date = '2020-04-02 08:44:01' WHERE \`id\` = 214`, + ) + + // Aktives Grundeinkommen für April 2020, original creation date: 2020-05-02 08:44:02 + await queryFn( + `UPDATE \`transactions\` SET creation_date = '2020-04-02 08:44:02' WHERE \`id\` = 215`, + ) + + // Aktives Grundeinkommen für April 2020, original creation date: 2020-05-02 08:44:05 + await queryFn( + `UPDATE \`transactions\` SET creation_date = '2020-04-02 08:44:05' WHERE \`id\` = 216`, + ) + + // Aktives Grundeinkommen für April 2020, original creation date: 2020-05-02 08:44:10 + await queryFn( + `UPDATE \`transactions\` SET creation_date = '2020-04-02 08:44:10' WHERE \`id\` = 217`, + ) + + // Aktives Grundeinkommen für April 2020, original creation date: 2020-05-02 08:44:12 + await queryFn( + `UPDATE \`transactions\` SET creation_date = '2020-04-02 08:44:12' WHERE \`id\` = 218`, + ) + + // Aktives Grundeinkommen für April 2020, original creation date: 2020-05-02 08:44:14 + await queryFn( + `UPDATE \`transactions\` SET creation_date = '2020-04-02 08:44:14' WHERE \`id\` = 219`, + ) + + // Aktives Grundeinkommen für April 2020, original creation date: 2020-05-02 08:44:17 + await queryFn( + `UPDATE \`transactions\` SET creation_date = '2020-04-02 08:44:17' WHERE \`id\` = 220`, + ) + + // Aktives Grundeinkommen für April 2020, original creation date: 2020-05-03 09:00:04 + await queryFn( + `UPDATE \`transactions\` SET creation_date = '2020-04-03 09:00:04' WHERE \`id\` = 221`, + ) + + // Aktives Grundeinkommen für April 2020, original creation date: 2020-05-03 09:00:07 + await queryFn( + `UPDATE \`transactions\` SET creation_date = '2020-04-03 09:00:07' WHERE \`id\` = 222`, + ) + + // Aktives Grundeinkommen für GL. Jan, original creation date: 2020-03-30 06:59:55 + await queryFn( + `UPDATE \`transactions\` SET creation_date = '2020-01-30 06:59:55' WHERE \`id\` = 6869`, + ) + + // Aktives Grundeinkommen für GL. Feb, original creation date: 2020-03-30 06:59:55 + await queryFn( + `UPDATE \`transactions\` SET creation_date = '2020-03-01 06:59:55' WHERE \`id\` = 6870`, + ) } - export async function downgrade(queryFn: (query: string, values?: any[]) => Promise>) { - + // reverse creation date changes + + await queryFn( + `UPDATE \`transactions\` SET creation_date = '2019-12-17 13:06:13' WHERE \`id\` = 1`, + ) + await queryFn( + `UPDATE \`transactions\` SET creation_date = '2019-12-17 13:06:16' WHERE \`id\` = 2`, + ) + await queryFn( + `UPDATE \`transactions\` SET creation_date = '2019-12-17 13:06:19' WHERE \`id\` = 3`, + ) + await queryFn( + `UPDATE \`transactions\` SET creation_date = '2019-12-17 13:06:21' WHERE \`id\` = 4`, + ) + await queryFn( + `UPDATE \`transactions\` SET creation_date = '2019-12-17 13:07:01' WHERE \`id\` = 5`, + ) + await queryFn( + `UPDATE \`transactions\` SET creation_date = '2019-12-19 17:35:16' WHERE \`id\` = 6`, + ) + await queryFn( + `UPDATE \`transactions\` SET creation_date = '2020-01-08 10:34:40' WHERE \`id\` = 7`, + ) + await queryFn( + `UPDATE \`transactions\` SET creation_date = '2020-01-08 11:02:41' WHERE \`id\` = 8`, + ) + await queryFn( + `UPDATE \`transactions\` SET creation_date = '2020-01-08 11:06:42' WHERE \`id\` = 9`, + ) + await queryFn( + `UPDATE \`transactions\` SET creation_date = '2020-01-08 11:16:11' WHERE \`id\` = 10`, + ) + await queryFn( + `UPDATE \`transactions\` SET creation_date = '2020-01-08 11:16:15' WHERE \`id\` = 11`, + ) + await queryFn( + `UPDATE \`transactions\` SET creation_date = '2020-01-08 13:24:29' WHERE \`id\` = 12`, + ) + await queryFn( + `UPDATE \`transactions\` SET creation_date = '2020-01-09 12:02:48' WHERE \`id\` = 13`, + ) + await queryFn( + `UPDATE \`transactions\` SET creation_date = '2020-01-09 12:02:52' WHERE \`id\` = 14`, + ) + await queryFn( + `UPDATE \`transactions\` SET creation_date = '2020-01-09 12:02:54' WHERE \`id\` = 15`, + ) + await queryFn( + `UPDATE \`transactions\` SET creation_date = '2020-01-09 12:09:08' WHERE \`id\` = 16`, + ) + await queryFn( + `UPDATE \`transactions\` SET creation_date = '2020-01-11 11:10:55' WHERE \`id\` = 17`, + ) + await queryFn( + `UPDATE \`transactions\` SET creation_date = '2020-01-11 11:11:24' WHERE \`id\` = 18`, + ) + await queryFn( + `UPDATE \`transactions\` SET creation_date = '2020-01-11 11:12:09' WHERE \`id\` = 19`, + ) + await queryFn( + `UPDATE \`transactions\` SET creation_date = '2020-01-11 11:31:20' WHERE \`id\` = 20`, + ) + await queryFn( + `UPDATE \`transactions\` SET creation_date = '2020-01-11 11:37:13' WHERE \`id\` = 21`, + ) + await queryFn( + `UPDATE \`transactions\` SET creation_date = '2020-01-11 11:37:42' WHERE \`id\` = 22`, + ) + await queryFn( + `UPDATE \`transactions\` SET creation_date = '2020-01-11 19:01:06' WHERE \`id\` = 23`, + ) + await queryFn( + `UPDATE \`transactions\` SET creation_date = '2020-01-13 16:27:07' WHERE \`id\` = 24`, + ) + await queryFn( + `UPDATE \`transactions\` SET creation_date = '2020-01-13 16:28:05' WHERE \`id\` = 25`, + ) + await queryFn( + `UPDATE \`transactions\` SET creation_date = '2020-01-13 16:28:57' WHERE \`id\` = 26`, + ) + await queryFn( + `UPDATE \`transactions\` SET creation_date = '2020-01-13 16:29:45' WHERE \`id\` = 27`, + ) + await queryFn( + `UPDATE \`transactions\` SET creation_date = '2020-01-17 13:47:28' WHERE \`id\` = 28`, + ) + await queryFn( + `UPDATE \`transactions\` SET creation_date = '2020-01-17 13:48:52' WHERE \`id\` = 29`, + ) + await queryFn( + `UPDATE \`transactions\` SET creation_date = '2020-01-17 13:49:21' WHERE \`id\` = 30`, + ) + await queryFn( + `UPDATE \`transactions\` SET creation_date = '2020-01-23 13:08:44' WHERE \`id\` = 31`, + ) + await queryFn( + `UPDATE \`transactions\` SET creation_date = '2020-01-27 08:12:16' WHERE \`id\` = 32`, + ) + await queryFn( + `UPDATE \`transactions\` SET creation_date = '2020-01-30 14:49:58' WHERE \`id\` = 33`, + ) + await queryFn( + `UPDATE \`transactions\` SET creation_date = '2020-01-30 14:50:35' WHERE \`id\` = 34`, + ) + await queryFn( + `UPDATE \`transactions\` SET creation_date = '2020-01-30 14:50:55' WHERE \`id\` = 35`, + ) + await queryFn( + `UPDATE \`transactions\` SET creation_date = '2020-01-30 14:52:03' WHERE \`id\` = 36`, + ) + await queryFn( + `UPDATE \`transactions\` SET creation_date = '2020-01-30 14:52:33' WHERE \`id\` = 37`, + ) + await queryFn( + `UPDATE \`transactions\` SET creation_date = '2020-01-30 14:52:53' WHERE \`id\` = 38`, + ) + await queryFn( + `UPDATE \`transactions\` SET creation_date = '2020-01-30 14:53:45' WHERE \`id\` = 39`, + ) + await queryFn( + `UPDATE \`transactions\` SET creation_date = '2020-01-30 14:54:13' WHERE \`id\` = 40`, + ) + await queryFn( + `UPDATE \`transactions\` SET creation_date = '2020-01-30 14:54:50' WHERE \`id\` = 41`, + ) + await queryFn( + `UPDATE \`transactions\` SET creation_date = '2020-01-30 15:03:26' WHERE \`id\` = 42`, + ) + await queryFn( + `UPDATE \`transactions\` SET creation_date = '2020-01-30 15:10:39' WHERE \`id\` = 43`, + ) + await queryFn( + `UPDATE \`transactions\` SET creation_date = '2020-01-30 15:13:10' WHERE \`id\` = 44`, + ) + await queryFn( + `UPDATE \`transactions\` SET creation_date = '2020-01-30 15:26:45' WHERE \`id\` = 45`, + ) + await queryFn( + `UPDATE \`transactions\` SET creation_date = '2020-02-19 08:54:31' WHERE \`id\` = 46`, + ) + await queryFn( + `UPDATE \`transactions\` SET creation_date = '2020-02-19 08:55:30' WHERE \`id\` = 47`, + ) + await queryFn( + `UPDATE \`transactions\` SET creation_date = '2020-02-19 08:55:33' WHERE \`id\` = 48`, + ) + await queryFn( + `UPDATE \`transactions\` SET creation_date = '2020-02-19 08:55:36' WHERE \`id\` = 49`, + ) + await queryFn( + `UPDATE \`transactions\` SET creation_date = '2020-02-19 08:55:39' WHERE \`id\` = 50`, + ) + await queryFn( + `UPDATE \`transactions\` SET creation_date = '2020-02-19 08:55:43' WHERE \`id\` = 51`, + ) + await queryFn( + `UPDATE \`transactions\` SET creation_date = '2020-02-19 08:55:46' WHERE \`id\` = 52`, + ) + await queryFn( + `UPDATE \`transactions\` SET creation_date = '2020-02-19 08:55:48' WHERE \`id\` = 53`, + ) + await queryFn( + `UPDATE \`transactions\` SET creation_date = '2020-02-19 08:55:50' WHERE \`id\` = 54`, + ) + await queryFn( + `UPDATE \`transactions\` SET creation_date = '2020-02-19 08:55:52' WHERE \`id\` = 55`, + ) + await queryFn( + `UPDATE \`transactions\` SET creation_date = '2020-02-19 08:55:54' WHERE \`id\` = 56`, + ) + await queryFn( + `UPDATE \`transactions\` SET creation_date = '2020-02-19 08:55:56' WHERE \`id\` = 57`, + ) + await queryFn( + `UPDATE \`transactions\` SET creation_date = '2020-02-19 08:55:59' WHERE \`id\` = 58`, + ) + await queryFn( + `UPDATE \`transactions\` SET creation_date = '2020-02-19 08:56:02' WHERE \`id\` = 59`, + ) + await queryFn( + `UPDATE \`transactions\` SET creation_date = '2020-02-19 08:56:05' WHERE \`id\` = 60`, + ) + await queryFn( + `UPDATE \`transactions\` SET creation_date = '2020-02-19 08:56:07' WHERE \`id\` = 61`, + ) + await queryFn( + `UPDATE \`transactions\` SET creation_date = '2020-02-19 08:56:10' WHERE \`id\` = 62`, + ) + await queryFn( + `UPDATE \`transactions\` SET creation_date = '2020-02-19 08:56:12' WHERE \`id\` = 63`, + ) + await queryFn( + `UPDATE \`transactions\` SET creation_date = '2020-02-19 08:56:14' WHERE \`id\` = 64`, + ) + await queryFn( + `UPDATE \`transactions\` SET creation_date = '2020-02-19 08:56:21' WHERE \`id\` = 65`, + ) + await queryFn( + `UPDATE \`transactions\` SET creation_date = '2020-02-19 08:56:24' WHERE \`id\` = 66`, + ) + await queryFn( + `UPDATE \`transactions\` SET creation_date = '2020-02-19 08:56:26' WHERE \`id\` = 67`, + ) + await queryFn( + `UPDATE \`transactions\` SET creation_date = '2020-02-19 08:56:28' WHERE \`id\` = 68`, + ) + await queryFn( + `UPDATE \`transactions\` SET creation_date = '2020-02-19 08:56:31' WHERE \`id\` = 69`, + ) + await queryFn( + `UPDATE \`transactions\` SET creation_date = '2020-02-20 06:40:36' WHERE \`id\` = 70`, + ) + await queryFn( + `UPDATE \`transactions\` SET creation_date = '2020-02-20 06:43:41' WHERE \`id\` = 71`, + ) + await queryFn( + `UPDATE \`transactions\` SET creation_date = '2020-02-20 06:43:43' WHERE \`id\` = 72`, + ) + await queryFn( + `UPDATE \`transactions\` SET creation_date = '2020-02-20 06:43:45' WHERE \`id\` = 73`, + ) + await queryFn( + `UPDATE \`transactions\` SET creation_date = '2020-02-20 06:43:47' WHERE \`id\` = 74`, + ) + await queryFn( + `UPDATE \`transactions\` SET creation_date = '2020-02-20 07:09:05' WHERE \`id\` = 75`, + ) + await queryFn( + `UPDATE \`transactions\` SET creation_date = '2020-02-20 08:03:31' WHERE \`id\` = 76`, + ) + await queryFn( + `UPDATE \`transactions\` SET creation_date = '2020-02-29 16:17:24' WHERE \`id\` = 77`, + ) + await queryFn( + `UPDATE \`transactions\` SET creation_date = '2020-02-29 16:17:35' WHERE \`id\` = 78`, + ) + await queryFn( + `UPDATE \`transactions\` SET creation_date = '2020-02-29 16:17:42' WHERE \`id\` = 79`, + ) + await queryFn( + `UPDATE \`transactions\` SET creation_date = '2020-02-29 16:29:47' WHERE \`id\` = 80`, + ) + await queryFn( + `UPDATE \`transactions\` SET creation_date = '2020-02-29 16:29:48' WHERE \`id\` = 81`, + ) + await queryFn( + `UPDATE \`transactions\` SET creation_date = '2020-02-29 16:29:55' WHERE \`id\` = 82`, + ) + await queryFn( + `UPDATE \`transactions\` SET creation_date = '2020-03-04 09:08:54' WHERE \`id\` = 83`, + ) + await queryFn( + `UPDATE \`transactions\` SET creation_date = '2020-03-07 07:59:42' WHERE \`id\` = 84`, + ) + await queryFn( + `UPDATE \`transactions\` SET creation_date = '2020-03-07 07:59:51' WHERE \`id\` = 85`, + ) + await queryFn( + `UPDATE \`transactions\` SET creation_date = '2020-03-07 07:59:54' WHERE \`id\` = 86`, + ) + await queryFn( + `UPDATE \`transactions\` SET creation_date = '2020-03-07 07:59:57' WHERE \`id\` = 87`, + ) + await queryFn( + `UPDATE \`transactions\` SET creation_date = '2020-03-07 08:15:48' WHERE \`id\` = 88`, + ) + await queryFn( + `UPDATE \`transactions\` SET creation_date = '2020-03-07 08:15:53' WHERE \`id\` = 89`, + ) + await queryFn( + `UPDATE \`transactions\` SET creation_date = '2020-03-07 08:15:56' WHERE \`id\` = 90`, + ) + await queryFn( + `UPDATE \`transactions\` SET creation_date = '2020-03-07 08:15:59' WHERE \`id\` = 91`, + ) + await queryFn( + `UPDATE \`transactions\` SET creation_date = '2020-03-07 08:16:01' WHERE \`id\` = 92`, + ) + await queryFn( + `UPDATE \`transactions\` SET creation_date = '2020-03-07 08:16:05' WHERE \`id\` = 93`, + ) + await queryFn( + `UPDATE \`transactions\` SET creation_date = '2020-03-07 08:16:07' WHERE \`id\` = 94`, + ) + await queryFn( + `UPDATE \`transactions\` SET creation_date = '2020-03-07 08:16:10' WHERE \`id\` = 95`, + ) + await queryFn( + `UPDATE \`transactions\` SET creation_date = '2020-03-07 08:17:00' WHERE \`id\` = 96`, + ) + await queryFn( + `UPDATE \`transactions\` SET creation_date = '2020-03-07 08:17:03' WHERE \`id\` = 97`, + ) + await queryFn( + `UPDATE \`transactions\` SET creation_date = '2020-03-07 08:17:05' WHERE \`id\` = 98`, + ) + await queryFn( + `UPDATE \`transactions\` SET creation_date = '2020-03-07 08:17:07' WHERE \`id\` = 99`, + ) + await queryFn( + `UPDATE \`transactions\` SET creation_date = '2020-03-07 08:17:09' WHERE \`id\` = 100`, + ) + await queryFn( + `UPDATE \`transactions\` SET creation_date = '2020-03-07 08:17:11' WHERE \`id\` = 101`, + ) + await queryFn( + `UPDATE \`transactions\` SET creation_date = '2020-03-07 08:17:13' WHERE \`id\` = 102`, + ) + await queryFn( + `UPDATE \`transactions\` SET creation_date = '2020-03-07 08:17:21' WHERE \`id\` = 103`, + ) + await queryFn( + `UPDATE \`transactions\` SET creation_date = '2020-03-07 08:17:25' WHERE \`id\` = 104`, + ) + await queryFn( + `UPDATE \`transactions\` SET creation_date = '2020-03-07 08:17:28' WHERE \`id\` = 105`, + ) + await queryFn( + `UPDATE \`transactions\` SET creation_date = '2020-03-07 08:19:15' WHERE \`id\` = 106`, + ) + await queryFn( + `UPDATE \`transactions\` SET creation_date = '2020-03-08 18:00:20' WHERE \`id\` = 107`, + ) + await queryFn( + `UPDATE \`transactions\` SET creation_date = '2020-03-09 11:43:30' WHERE \`id\` = 108`, + ) + await queryFn( + `UPDATE \`transactions\` SET creation_date = '2020-03-09 17:48:34' WHERE \`id\` = 109`, + ) + await queryFn( + `UPDATE \`transactions\` SET creation_date = '2020-03-09 17:48:36' WHERE \`id\` = 110`, + ) + await queryFn( + `UPDATE \`transactions\` SET creation_date = '2020-03-09 17:48:38' WHERE \`id\` = 111`, + ) + await queryFn( + `UPDATE \`transactions\` SET creation_date = '2020-03-09 17:48:40' WHERE \`id\` = 112`, + ) + await queryFn( + `UPDATE \`transactions\` SET creation_date = '2020-03-09 17:48:43' WHERE \`id\` = 113`, + ) + await queryFn( + `UPDATE \`transactions\` SET creation_date = '2020-03-11 21:11:03' WHERE \`id\` = 114`, + ) + await queryFn( + `UPDATE \`transactions\` SET creation_date = '2020-03-11 21:17:22' WHERE \`id\` = 115`, + ) + await queryFn( + `UPDATE \`transactions\` SET creation_date = '2020-03-11 21:17:26' WHERE \`id\` = 116`, + ) + await queryFn( + `UPDATE \`transactions\` SET creation_date = '2020-03-18 15:44:07' WHERE \`id\` = 117`, + ) + await queryFn( + `UPDATE \`transactions\` SET creation_date = '2020-03-18 15:54:59' WHERE \`id\` = 118`, + ) + await queryFn( + `UPDATE \`transactions\` SET creation_date = '2020-03-18 15:55:32' WHERE \`id\` = 119`, + ) + await queryFn( + `UPDATE \`transactions\` SET creation_date = '2020-03-18 15:56:32' WHERE \`id\` = 120`, + ) + await queryFn( + `UPDATE \`transactions\` SET creation_date = '2020-03-18 15:56:48' WHERE \`id\` = 121`, + ) + await queryFn( + `UPDATE \`transactions\` SET creation_date = '2020-03-18 15:57:14' WHERE \`id\` = 122`, + ) + await queryFn( + `UPDATE \`transactions\` SET creation_date = '2020-03-18 15:58:41' WHERE \`id\` = 123`, + ) + await queryFn( + `UPDATE \`transactions\` SET creation_date = '2020-03-18 15:59:03' WHERE \`id\` = 124`, + ) + await queryFn( + `UPDATE \`transactions\` SET creation_date = '2020-03-18 15:59:26' WHERE \`id\` = 125`, + ) + await queryFn( + `UPDATE \`transactions\` SET creation_date = '2020-03-18 16:00:05' WHERE \`id\` = 126`, + ) + await queryFn( + `UPDATE \`transactions\` SET creation_date = '2020-03-18 16:00:12' WHERE \`id\` = 127`, + ) + await queryFn( + `UPDATE \`transactions\` SET creation_date = '2020-03-23 07:35:35' WHERE \`id\` = 128`, + ) + await queryFn( + `UPDATE \`transactions\` SET creation_date = '2020-03-23 07:35:38' WHERE \`id\` = 129`, + ) + await queryFn( + `UPDATE \`transactions\` SET creation_date = '2020-03-23 07:35:42' WHERE \`id\` = 130`, + ) + await queryFn( + `UPDATE \`transactions\` SET creation_date = '2020-03-24 17:00:05' WHERE \`id\` = 131`, + ) + await queryFn( + `UPDATE \`transactions\` SET creation_date = '2020-03-24 17:06:50' WHERE \`id\` = 132`, + ) + await queryFn( + `UPDATE \`transactions\` SET creation_date = '2020-03-24 17:06:54' WHERE \`id\` = 133`, + ) + await queryFn( + `UPDATE \`transactions\` SET creation_date = '2020-03-24 17:14:21' WHERE \`id\` = 134`, + ) + await queryFn( + `UPDATE \`transactions\` SET creation_date = '2020-03-24 17:14:27' WHERE \`id\` = 135`, + ) + await queryFn( + `UPDATE \`transactions\` SET creation_date = '2020-03-24 17:14:28' WHERE \`id\` = 136`, + ) + await queryFn( + `UPDATE \`transactions\` SET creation_date = '2020-03-24 17:14:30' WHERE \`id\` = 137`, + ) + await queryFn( + `UPDATE \`transactions\` SET creation_date = '2020-03-27 09:06:16' WHERE \`id\` = 138`, + ) + await queryFn( + `UPDATE \`transactions\` SET creation_date = '2020-03-27 09:44:27' WHERE \`id\` = 139`, + ) + await queryFn( + `UPDATE \`transactions\` SET creation_date = '2020-03-27 09:44:29' WHERE \`id\` = 140`, + ) + await queryFn( + `UPDATE \`transactions\` SET creation_date = '2020-03-27 09:44:30' WHERE \`id\` = 141`, + ) + await queryFn( + `UPDATE \`transactions\` SET creation_date = '2020-03-27 09:44:35' WHERE \`id\` = 142`, + ) + await queryFn( + `UPDATE \`transactions\` SET creation_date = '2020-03-27 09:44:36' WHERE \`id\` = 143`, + ) + await queryFn( + `UPDATE \`transactions\` SET creation_date = '2020-03-27 09:44:40' WHERE \`id\` = 144`, + ) + await queryFn( + `UPDATE \`transactions\` SET creation_date = '2020-03-27 09:44:42' WHERE \`id\` = 145`, + ) + await queryFn( + `UPDATE \`transactions\` SET creation_date = '2020-03-28 09:28:24' WHERE \`id\` = 146`, + ) + await queryFn( + `UPDATE \`transactions\` SET creation_date = '2020-03-28 09:34:30' WHERE \`id\` = 147`, + ) + await queryFn( + `UPDATE \`transactions\` SET creation_date = '2020-03-29 17:21:33' WHERE \`id\` = 148`, + ) + await queryFn( + `UPDATE \`transactions\` SET creation_date = '2020-03-29 17:21:35' WHERE \`id\` = 149`, + ) + await queryFn( + `UPDATE \`transactions\` SET creation_date = '2020-03-30 06:59:55' WHERE \`id\` = 150`, + ) + await queryFn( + `UPDATE \`transactions\` SET creation_date = '2020-03-30 07:05:14' WHERE \`id\` = 151`, + ) + await queryFn( + `UPDATE \`transactions\` SET creation_date = '2020-03-30 07:09:52' WHERE \`id\` = 152`, + ) + await queryFn( + `UPDATE \`transactions\` SET creation_date = '2020-03-30 07:15:43' WHERE \`id\` = 153`, + ) + await queryFn( + `UPDATE \`transactions\` SET creation_date = '2020-03-30 07:16:33' WHERE \`id\` = 154`, + ) + await queryFn( + `UPDATE \`transactions\` SET creation_date = '2020-03-30 07:21:07' WHERE \`id\` = 155`, + ) + await queryFn( + `UPDATE \`transactions\` SET creation_date = '2020-03-30 11:47:55' WHERE \`id\` = 156`, + ) + await queryFn( + `UPDATE \`transactions\` SET creation_date = '2020-04-01 06:56:20' WHERE \`id\` = 157`, + ) + await queryFn( + `UPDATE \`transactions\` SET creation_date = '2020-04-01 06:56:26' WHERE \`id\` = 158`, + ) + await queryFn( + `UPDATE \`transactions\` SET creation_date = '2020-04-01 06:56:29' WHERE \`id\` = 159`, + ) + await queryFn( + `UPDATE \`transactions\` SET creation_date = '2020-04-01 06:56:31' WHERE \`id\` = 160`, + ) + await queryFn( + `UPDATE \`transactions\` SET creation_date = '2020-04-01 06:58:10' WHERE \`id\` = 161`, + ) + await queryFn( + `UPDATE \`transactions\` SET creation_date = '2020-04-07 14:09:26' WHERE \`id\` = 162`, + ) + await queryFn( + `UPDATE \`transactions\` SET creation_date = '2020-04-07 14:09:28' WHERE \`id\` = 163`, + ) + await queryFn( + `UPDATE \`transactions\` SET creation_date = '2020-04-07 14:09:29' WHERE \`id\` = 164`, + ) + await queryFn( + `UPDATE \`transactions\` SET creation_date = '2020-04-07 14:09:32' WHERE \`id\` = 165`, + ) + await queryFn( + `UPDATE \`transactions\` SET creation_date = '2020-04-08 18:41:17' WHERE \`id\` = 166`, + ) + await queryFn( + `UPDATE \`transactions\` SET creation_date = '2020-04-08 18:41:20' WHERE \`id\` = 167`, + ) + await queryFn( + `UPDATE \`transactions\` SET creation_date = '2020-04-08 18:41:21' WHERE \`id\` = 168`, + ) + await queryFn( + `UPDATE \`transactions\` SET creation_date = '2020-04-08 18:41:23' WHERE \`id\` = 169`, + ) + await queryFn( + `UPDATE \`transactions\` SET creation_date = '2020-04-08 18:41:27' WHERE \`id\` = 170`, + ) + await queryFn( + `UPDATE \`transactions\` SET creation_date = '2020-04-08 18:58:15' WHERE \`id\` = 171`, + ) + await queryFn( + `UPDATE \`transactions\` SET creation_date = '2020-04-15 16:10:54' WHERE \`id\` = 172`, + ) + await queryFn( + `UPDATE \`transactions\` SET creation_date = '2020-04-15 16:10:56' WHERE \`id\` = 173`, + ) + await queryFn( + `UPDATE \`transactions\` SET creation_date = '2020-04-15 16:10:58' WHERE \`id\` = 174`, + ) + await queryFn( + `UPDATE \`transactions\` SET creation_date = '2020-04-15 16:11:01' WHERE \`id\` = 175`, + ) + await queryFn( + `UPDATE \`transactions\` SET creation_date = '2020-04-15 16:11:02' WHERE \`id\` = 176`, + ) + await queryFn( + `UPDATE \`transactions\` SET creation_date = '2020-04-15 16:11:04' WHERE \`id\` = 177`, + ) + await queryFn( + `UPDATE \`transactions\` SET creation_date = '2020-04-15 16:11:07' WHERE \`id\` = 178`, + ) + await queryFn( + `UPDATE \`transactions\` SET creation_date = '2020-04-17 16:54:39' WHERE \`id\` = 179`, + ) + await queryFn( + `UPDATE \`transactions\` SET creation_date = '2020-04-17 16:54:40' WHERE \`id\` = 180`, + ) + await queryFn( + `UPDATE \`transactions\` SET creation_date = '2020-04-17 16:54:42' WHERE \`id\` = 181`, + ) + await queryFn( + `UPDATE \`transactions\` SET creation_date = '2020-04-17 16:54:44' WHERE \`id\` = 182`, + ) + await queryFn( + `UPDATE \`transactions\` SET creation_date = '2020-04-18 08:58:42' WHERE \`id\` = 183`, + ) + await queryFn( + `UPDATE \`transactions\` SET creation_date = '2020-04-18 08:58:44' WHERE \`id\` = 184`, + ) + await queryFn( + `UPDATE \`transactions\` SET creation_date = '2020-04-20 17:44:36' WHERE \`id\` = 185`, + ) + await queryFn( + `UPDATE \`transactions\` SET creation_date = '2020-04-20 17:44:38' WHERE \`id\` = 186`, + ) + await queryFn( + `UPDATE \`transactions\` SET creation_date = '2020-04-20 17:44:40' WHERE \`id\` = 187`, + ) + await queryFn( + `UPDATE \`transactions\` SET creation_date = '2020-04-20 17:44:43' WHERE \`id\` = 188`, + ) + await queryFn( + `UPDATE \`transactions\` SET creation_date = '2020-04-25 06:30:13' WHERE \`id\` = 189`, + ) + await queryFn( + `UPDATE \`transactions\` SET creation_date = '2020-04-25 06:30:19' WHERE \`id\` = 190`, + ) + await queryFn( + `UPDATE \`transactions\` SET creation_date = '2020-04-25 06:30:21' WHERE \`id\` = 191`, + ) + await queryFn( + `UPDATE \`transactions\` SET creation_date = '2020-04-25 06:30:23' WHERE \`id\` = 192`, + ) + await queryFn( + `UPDATE \`transactions\` SET creation_date = '2020-04-25 06:30:24' WHERE \`id\` = 193`, + ) + await queryFn( + `UPDATE \`transactions\` SET creation_date = '2020-04-25 06:30:26' WHERE \`id\` = 194`, + ) + await queryFn( + `UPDATE \`transactions\` SET creation_date = '2020-04-25 18:41:55' WHERE \`id\` = 195`, + ) + await queryFn( + `UPDATE \`transactions\` SET creation_date = '2020-04-25 18:42:25' WHERE \`id\` = 196`, + ) + await queryFn( + `UPDATE \`transactions\` SET creation_date = '2020-04-25 18:46:01' WHERE \`id\` = 197`, + ) + await queryFn( + `UPDATE \`transactions\` SET creation_date = '2020-04-30 06:40:39' WHERE \`id\` = 198`, + ) + await queryFn( + `UPDATE \`transactions\` SET creation_date = '2020-04-30 06:40:41' WHERE \`id\` = 199`, + ) + await queryFn( + `UPDATE \`transactions\` SET creation_date = '2020-04-30 06:40:42' WHERE \`id\` = 200`, + ) + await queryFn( + `UPDATE \`transactions\` SET creation_date = '2020-04-30 06:40:45' WHERE \`id\` = 201`, + ) + await queryFn( + `UPDATE \`transactions\` SET creation_date = '2020-04-30 06:40:46' WHERE \`id\` = 202`, + ) + await queryFn( + `UPDATE \`transactions\` SET creation_date = '2020-04-30 06:40:50' WHERE \`id\` = 203`, + ) + await queryFn( + `UPDATE \`transactions\` SET creation_date = '2020-05-02 08:25:27' WHERE \`id\` = 204`, + ) + await queryFn( + `UPDATE \`transactions\` SET creation_date = '2020-05-02 08:25:29' WHERE \`id\` = 205`, + ) + await queryFn( + `UPDATE \`transactions\` SET creation_date = '2020-05-02 08:25:32' WHERE \`id\` = 206`, + ) + await queryFn( + `UPDATE \`transactions\` SET creation_date = '2020-05-02 08:28:14' WHERE \`id\` = 207`, + ) + await queryFn( + `UPDATE \`transactions\` SET creation_date = '2020-05-02 08:43:49' WHERE \`id\` = 208`, + ) + await queryFn( + `UPDATE \`transactions\` SET creation_date = '2020-05-02 08:43:51' WHERE \`id\` = 209`, + ) + await queryFn( + `UPDATE \`transactions\` SET creation_date = '2020-05-02 08:43:54' WHERE \`id\` = 210`, + ) + await queryFn( + `UPDATE \`transactions\` SET creation_date = '2020-05-02 08:43:56' WHERE \`id\` = 211`, + ) + await queryFn( + `UPDATE \`transactions\` SET creation_date = '2020-05-02 08:43:57' WHERE \`id\` = 212`, + ) + await queryFn( + `UPDATE \`transactions\` SET creation_date = '2020-05-02 08:43:59' WHERE \`id\` = 213`, + ) + await queryFn( + `UPDATE \`transactions\` SET creation_date = '2020-05-02 08:44:01' WHERE \`id\` = 214`, + ) + await queryFn( + `UPDATE \`transactions\` SET creation_date = '2020-05-02 08:44:02' WHERE \`id\` = 215`, + ) + await queryFn( + `UPDATE \`transactions\` SET creation_date = '2020-05-02 08:44:05' WHERE \`id\` = 216`, + ) + await queryFn( + `UPDATE \`transactions\` SET creation_date = '2020-05-02 08:44:10' WHERE \`id\` = 217`, + ) + await queryFn( + `UPDATE \`transactions\` SET creation_date = '2020-05-02 08:44:12' WHERE \`id\` = 218`, + ) + await queryFn( + `UPDATE \`transactions\` SET creation_date = '2020-05-02 08:44:14' WHERE \`id\` = 219`, + ) + await queryFn( + `UPDATE \`transactions\` SET creation_date = '2020-05-02 08:44:17' WHERE \`id\` = 220`, + ) + await queryFn( + `UPDATE \`transactions\` SET creation_date = '2020-05-03 09:00:04' WHERE \`id\` = 221`, + ) + await queryFn( + `UPDATE \`transactions\` SET creation_date = '2020-05-03 09:00:07' WHERE \`id\` = 222`, + ) + + // from upgrade added, could be also delete because nevertheless they will be deleted + await queryFn( + `UPDATE \`transactions\` SET creation_date = '2020-03-30 06:59:55' WHERE \`id\` = 6869`, + ) + await queryFn( + `UPDATE \`transactions\` SET creation_date = '2020-03-30 06:59:55' WHERE \`id\` = 6870`, + ) + // remove added transaction await queryFn( `DELETE FROM \`transactions\` WHERE \`user_id\` = 275 AND \`balance\` IN (2000, 3000) AND \`amount\` = 1000`, ) - + // rewind transaction to split await queryFn( `UPDATE \`transactions\` set \`amount\` = 3000, \`memo\` = 'Aktives Grundeinkommen für GL. Dez, Jan, Feb' WHERE \`id\` = 150`, ) - + await queryFn(`UPDATE \`transactions\` set \`previous\` = 150 WHERE \`id\` = 278`) // drop temp table await queryFn(`DROP TABLE IF EXISTS \`transactions_temp\``) From 6b3813a0c8ee52087e48e57791bc22b26c69600a Mon Sep 17 00:00:00 2001 From: einhorn_b Date: Tue, 5 Jul 2022 17:09:31 +0200 Subject: [PATCH 038/137] add code for moving user creation date if transaction before exist --- .../0042-move_users_creation_date.ts | 130 ++++++++++++++++++ 1 file changed, 130 insertions(+) create mode 100644 database/migrations/0042-move_users_creation_date.ts diff --git a/database/migrations/0042-move_users_creation_date.ts b/database/migrations/0042-move_users_creation_date.ts new file mode 100644 index 000000000..27353a5b4 --- /dev/null +++ b/database/migrations/0042-move_users_creation_date.ts @@ -0,0 +1,130 @@ +/* eslint-disable @typescript-eslint/explicit-module-boundary-types */ +/* eslint-disable @typescript-eslint/no-explicit-any */ + +/* +Move forward the creation date of the users by 1 or 2 hours, +for which there are transactions created before their account creation. + +Because of a error by importing data from old db format into new, all older transactions balance_date +are 1 or 2 hours off + +*/ + +export async function upgrade(queryFn: (query: string, values?: any[]) => Promise>) { + /* generate raw mysql queries + const usersToMove = await queryFn( + ` + SELECT u.id, u.created, t.balance_date + FROM \`users\` as u + LEFT JOIN \`transactions\` as t + ON t.user_id = u.id where t.balance_date < u.created + order by id + ` + ) + let downgradeQueries = '' + for(const id in usersToMove) { + const user = usersToMove[id] + const diff = (user.created - user.balance_date) / 1000 + const correcture = diff < 3600 ? 1: 2 + const correctedDate = new Date(user.created) + correctedDate.setHours(correctedDate.getHours() - correcture) + //console.log("%d, %s, %s, %s, %d", user.id, user.created, user.balance_date, diff, correcture) + console.log('await queryFn(`UPDATE \\`users\\` SET \\`created\\` = \'%s\' WHERE \\`id\\` = %d`)', + correctedDate.toISOString().slice(0, 19).replace('T', ' '), + user.id + ) + downgradeQueries += 'await queryFn(`UPDATE \\`users\\` SET \\`created\\` = \'' + downgradeQueries += user.created.toISOString().slice(0, 19).replace('T', ' ') + downgradeQueries += '\' WHERE \\`id\\` = ' + downgradeQueries += user.id + downgradeQueries += '`)\n' + } + console.log('downgrade: \n%s', downgradeQueries) + */ + + await queryFn(`UPDATE \`users\` SET \`created\` = '2020-01-25 08:01:52' WHERE \`id\` = 179`) + await queryFn(`UPDATE \`users\` SET \`created\` = '2020-05-26 10:21:57' WHERE \`id\` = 443`) + await queryFn(`UPDATE \`users\` SET \`created\` = '2020-06-08 17:04:41' WHERE \`id\` = 490`) + await queryFn(`UPDATE \`users\` SET \`created\` = '2020-06-12 20:07:17' WHERE \`id\` = 508`) + await queryFn(`UPDATE \`users\` SET \`created\` = '2020-07-17 19:20:36' WHERE \`id\` = 621`) + await queryFn(`UPDATE \`users\` SET \`created\` = '2020-11-22 16:31:48' WHERE \`id\` = 788`) + await queryFn(`UPDATE \`users\` SET \`created\` = '2020-12-17 20:09:16' WHERE \`id\` = 825`) + await queryFn(`UPDATE \`users\` SET \`created\` = '2021-01-26 13:09:35' WHERE \`id\` = 949`) + await queryFn(`UPDATE \`users\` SET \`created\` = '2021-03-20 16:55:46' WHERE \`id\` = 1057`) + await queryFn(`UPDATE \`users\` SET \`created\` = '2021-05-13 15:59:30' WHERE \`id\` = 1228`) + await queryFn(`UPDATE \`users\` SET \`created\` = '2021-05-13 17:38:47' WHERE \`id\` = 1229`) + await queryFn(`UPDATE \`users\` SET \`created\` = '2021-05-13 17:38:47' WHERE \`id\` = 1229`) + await queryFn(`UPDATE \`users\` SET \`created\` = '2021-05-13 17:38:47' WHERE \`id\` = 1229`) + await queryFn(`UPDATE \`users\` SET \`created\` = '2021-05-13 17:58:15' WHERE \`id\` = 1230`) + await queryFn(`UPDATE \`users\` SET \`created\` = '2021-05-13 17:58:15' WHERE \`id\` = 1230`) + await queryFn(`UPDATE \`users\` SET \`created\` = '2021-05-14 14:27:49' WHERE \`id\` = 1231`) + await queryFn(`UPDATE \`users\` SET \`created\` = '2021-05-14 14:27:49' WHERE \`id\` = 1231`) + await queryFn(`UPDATE \`users\` SET \`created\` = '2021-05-14 14:27:49' WHERE \`id\` = 1231`) + await queryFn(`UPDATE \`users\` SET \`created\` = '2021-05-14 14:27:49' WHERE \`id\` = 1231`) + await queryFn(`UPDATE \`users\` SET \`created\` = '2021-05-17 22:51:19' WHERE \`id\` = 1239`) + await queryFn(`UPDATE \`users\` SET \`created\` = '2021-06-03 07:23:28' WHERE \`id\` = 1273`) + await queryFn(`UPDATE \`users\` SET \`created\` = '2021-06-09 06:16:18' WHERE \`id\` = 1287`) + await queryFn(`UPDATE \`users\` SET \`created\` = '2021-06-17 11:26:41' WHERE \`id\` = 1298`) + await queryFn(`UPDATE \`users\` SET \`created\` = '2021-06-30 15:56:27' WHERE \`id\` = 1315`) + await queryFn(`UPDATE \`users\` SET \`created\` = '2021-06-30 15:56:27' WHERE \`id\` = 1315`) + await queryFn(`UPDATE \`users\` SET \`created\` = '2021-06-30 15:56:27' WHERE \`id\` = 1315`) + await queryFn(`UPDATE \`users\` SET \`created\` = '2021-07-08 07:24:57' WHERE \`id\` = 1326`) + await queryFn(`UPDATE \`users\` SET \`created\` = '2021-07-08 07:24:57' WHERE \`id\` = 1326`) + await queryFn(`UPDATE \`users\` SET \`created\` = '2021-07-13 12:07:29' WHERE \`id\` = 1342`) + await queryFn(`UPDATE \`users\` SET \`created\` = '2021-07-16 15:32:48' WHERE \`id\` = 1348`) + await queryFn(`UPDATE \`users\` SET \`created\` = '2021-09-30 14:06:40' WHERE \`id\` = 1470`) + await queryFn(`UPDATE \`users\` SET \`created\` = '2021-10-15 14:35:37' WHERE \`id\` = 1490`) + await queryFn(`UPDATE \`users\` SET \`created\` = '2021-10-16 06:42:00' WHERE \`id\` = 1492`) + await queryFn(`UPDATE \`users\` SET \`created\` = '2021-10-16 06:42:00' WHERE \`id\` = 1492`) + await queryFn(`UPDATE \`users\` SET \`created\` = '2021-11-22 09:45:15' WHERE \`id\` = 1576`) + await queryFn(`UPDATE \`users\` SET \`created\` = '2021-11-23 13:55:37' WHERE \`id\` = 1582`) + await queryFn(`UPDATE \`users\` SET \`created\` = '2022-01-11 14:58:12' WHERE \`id\` = 1729`) + await queryFn(`UPDATE \`users\` SET \`created\` = '2022-01-11 18:03:10' WHERE \`id\` = 1732`) + await queryFn(`UPDATE \`users\` SET \`created\` = '2022-01-19 15:00:38' WHERE \`id\` = 1756`) + await queryFn(`UPDATE \`users\` SET \`created\` = '2022-01-19 20:01:58' WHERE \`id\` = 1757`) + await queryFn(`UPDATE \`users\` SET \`created\` = '2022-01-21 15:58:48' WHERE \`id\` = 1762`) +} + +export async function downgrade(queryFn: (query: string, values?: any[]) => Promise>) { + await queryFn(`UPDATE \`users\` SET \`created\` = '2020-01-25 09:01:52' WHERE \`id\` = 179`) + await queryFn(`UPDATE \`users\` SET \`created\` = '2020-05-26 11:21:57' WHERE \`id\` = 443`) + await queryFn(`UPDATE \`users\` SET \`created\` = '2020-06-08 19:04:41' WHERE \`id\` = 490`) + await queryFn(`UPDATE \`users\` SET \`created\` = '2020-06-12 22:07:17' WHERE \`id\` = 508`) + await queryFn(`UPDATE \`users\` SET \`created\` = '2020-07-17 21:20:36' WHERE \`id\` = 621`) + await queryFn(`UPDATE \`users\` SET \`created\` = '2020-11-22 17:31:48' WHERE \`id\` = 788`) + await queryFn(`UPDATE \`users\` SET \`created\` = '2020-12-17 21:09:16' WHERE \`id\` = 825`) + await queryFn(`UPDATE \`users\` SET \`created\` = '2021-01-26 14:09:35' WHERE \`id\` = 949`) + await queryFn(`UPDATE \`users\` SET \`created\` = '2021-03-20 17:55:46' WHERE \`id\` = 1057`) + await queryFn(`UPDATE \`users\` SET \`created\` = '2021-05-13 17:59:30' WHERE \`id\` = 1228`) + await queryFn(`UPDATE \`users\` SET \`created\` = '2021-05-13 19:38:47' WHERE \`id\` = 1229`) + await queryFn(`UPDATE \`users\` SET \`created\` = '2021-05-13 19:38:47' WHERE \`id\` = 1229`) + await queryFn(`UPDATE \`users\` SET \`created\` = '2021-05-13 19:38:47' WHERE \`id\` = 1229`) + await queryFn(`UPDATE \`users\` SET \`created\` = '2021-05-13 19:58:15' WHERE \`id\` = 1230`) + await queryFn(`UPDATE \`users\` SET \`created\` = '2021-05-13 19:58:15' WHERE \`id\` = 1230`) + await queryFn(`UPDATE \`users\` SET \`created\` = '2021-05-14 16:27:49' WHERE \`id\` = 1231`) + await queryFn(`UPDATE \`users\` SET \`created\` = '2021-05-14 16:27:49' WHERE \`id\` = 1231`) + await queryFn(`UPDATE \`users\` SET \`created\` = '2021-05-14 16:27:49' WHERE \`id\` = 1231`) + await queryFn(`UPDATE \`users\` SET \`created\` = '2021-05-14 16:27:49' WHERE \`id\` = 1231`) + await queryFn(`UPDATE \`users\` SET \`created\` = '2021-05-18 00:51:19' WHERE \`id\` = 1239`) + await queryFn(`UPDATE \`users\` SET \`created\` = '2021-06-03 09:23:28' WHERE \`id\` = 1273`) + await queryFn(`UPDATE \`users\` SET \`created\` = '2021-06-09 08:16:18' WHERE \`id\` = 1287`) + await queryFn(`UPDATE \`users\` SET \`created\` = '2021-06-17 13:26:41' WHERE \`id\` = 1298`) + await queryFn(`UPDATE \`users\` SET \`created\` = '2021-06-30 17:56:27' WHERE \`id\` = 1315`) + await queryFn(`UPDATE \`users\` SET \`created\` = '2021-06-30 17:56:27' WHERE \`id\` = 1315`) + await queryFn(`UPDATE \`users\` SET \`created\` = '2021-06-30 17:56:27' WHERE \`id\` = 1315`) + await queryFn(`UPDATE \`users\` SET \`created\` = '2021-07-08 09:24:57' WHERE \`id\` = 1326`) + await queryFn(`UPDATE \`users\` SET \`created\` = '2021-07-08 09:24:57' WHERE \`id\` = 1326`) + await queryFn(`UPDATE \`users\` SET \`created\` = '2021-07-13 14:07:29' WHERE \`id\` = 1342`) + await queryFn(`UPDATE \`users\` SET \`created\` = '2021-07-16 16:32:48' WHERE \`id\` = 1348`) + await queryFn(`UPDATE \`users\` SET \`created\` = '2021-09-30 16:06:40' WHERE \`id\` = 1470`) + await queryFn(`UPDATE \`users\` SET \`created\` = '2021-10-15 16:35:37' WHERE \`id\` = 1490`) + await queryFn(`UPDATE \`users\` SET \`created\` = '2021-10-16 08:42:00' WHERE \`id\` = 1492`) + await queryFn(`UPDATE \`users\` SET \`created\` = '2021-10-16 08:42:00' WHERE \`id\` = 1492`) + await queryFn(`UPDATE \`users\` SET \`created\` = '2021-11-22 10:45:15' WHERE \`id\` = 1576`) + await queryFn(`UPDATE \`users\` SET \`created\` = '2021-11-23 14:55:37' WHERE \`id\` = 1582`) + await queryFn(`UPDATE \`users\` SET \`created\` = '2022-01-11 15:58:12' WHERE \`id\` = 1729`) + await queryFn(`UPDATE \`users\` SET \`created\` = '2022-01-11 19:03:10' WHERE \`id\` = 1732`) + await queryFn(`UPDATE \`users\` SET \`created\` = '2022-01-19 16:00:38' WHERE \`id\` = 1756`) + await queryFn(`UPDATE \`users\` SET \`created\` = '2022-01-19 21:01:58' WHERE \`id\` = 1757`) + await queryFn(`UPDATE \`users\` SET \`created\` = '2022-01-21 16:58:48' WHERE \`id\` = 1762`) +} 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 039/137] 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 040/137] 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 041/137] 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 042/137] 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 043/137] 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 a2ffab2d4d96c1420d80654d1686433a6c900238 Mon Sep 17 00:00:00 2001 From: einhornimmond Date: Wed, 6 Jul 2022 10:27:21 +0200 Subject: [PATCH 044/137] Update database/migrations/0041-update_transactions_for_blockchain.ts Co-authored-by: Moriz Wahl --- database/migrations/0041-update_transactions_for_blockchain.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/database/migrations/0041-update_transactions_for_blockchain.ts b/database/migrations/0041-update_transactions_for_blockchain.ts index 066c78ee0..ca44d0d3b 100644 --- a/database/migrations/0041-update_transactions_for_blockchain.ts +++ b/database/migrations/0041-update_transactions_for_blockchain.ts @@ -32,7 +32,7 @@ export async function upgrade(queryFn: (query: string, values?: any[]) => Promis 275, 150, 1, 1000, 2000, ?, 0, ?, ? )`, - [creationDate, transactionMemos[1], creationDate], + [creationDate, transactionMemos[1], new Date(creationDate.getFullYear(), creationDate.getMonth() - 1, 1)], ) await queryFn( `INSERT INTO \`transactions\`( From 2774594f1362791bec4b34749c1a9062d388a1fd Mon Sep 17 00:00:00 2001 From: einhorn_b Date: Wed, 6 Jul 2022 10:32:34 +0200 Subject: [PATCH 045/137] apply suggestions, remove added transactions from creation date fix sql queries --- ...0041-update_transactions_for_blockchain.ts | 30 +++++++------------ 1 file changed, 10 insertions(+), 20 deletions(-) diff --git a/database/migrations/0041-update_transactions_for_blockchain.ts b/database/migrations/0041-update_transactions_for_blockchain.ts index ca44d0d3b..c4e025e86 100644 --- a/database/migrations/0041-update_transactions_for_blockchain.ts +++ b/database/migrations/0041-update_transactions_for_blockchain.ts @@ -32,7 +32,11 @@ export async function upgrade(queryFn: (query: string, values?: any[]) => Promis 275, 150, 1, 1000, 2000, ?, 0, ?, ? )`, - [creationDate, transactionMemos[1], new Date(creationDate.getFullYear(), creationDate.getMonth() - 1, 1)], + [ + creationDate, + transactionMemos[1], + new Date(creationDate.getFullYear(), creationDate.getMonth() - 1, 1), + ], ) await queryFn( `INSERT INTO \`transactions\`( @@ -42,7 +46,11 @@ export async function upgrade(queryFn: (query: string, values?: any[]) => Promis 275, LAST_INSERT_ID(), 1, 1000, 3000, ?, 0, ?, ? )`, - [creationDate, transactionMemos[2], creationDate], + [ + creationDate, + transactionMemos[2], + new Date(creationDate.getFullYear(), creationDate.getMonth() - 2, 1), + ], ) await queryFn(`UPDATE \`transactions\` set \`previous\` = LAST_INSERT_ID() WHERE \`id\` = 278`) @@ -1221,16 +1229,6 @@ export async function upgrade(queryFn: (query: string, values?: any[]) => Promis await queryFn( `UPDATE \`transactions\` SET creation_date = '2020-04-03 09:00:07' WHERE \`id\` = 222`, ) - - // Aktives Grundeinkommen für GL. Jan, original creation date: 2020-03-30 06:59:55 - await queryFn( - `UPDATE \`transactions\` SET creation_date = '2020-01-30 06:59:55' WHERE \`id\` = 6869`, - ) - - // Aktives Grundeinkommen für GL. Feb, original creation date: 2020-03-30 06:59:55 - await queryFn( - `UPDATE \`transactions\` SET creation_date = '2020-03-01 06:59:55' WHERE \`id\` = 6870`, - ) } export async function downgrade(queryFn: (query: string, values?: any[]) => Promise>) { @@ -1903,14 +1901,6 @@ export async function downgrade(queryFn: (query: string, values?: any[]) => Prom `UPDATE \`transactions\` SET creation_date = '2020-05-03 09:00:07' WHERE \`id\` = 222`, ) - // from upgrade added, could be also delete because nevertheless they will be deleted - await queryFn( - `UPDATE \`transactions\` SET creation_date = '2020-03-30 06:59:55' WHERE \`id\` = 6869`, - ) - await queryFn( - `UPDATE \`transactions\` SET creation_date = '2020-03-30 06:59:55' WHERE \`id\` = 6870`, - ) - // remove added transaction await queryFn( `DELETE FROM \`transactions\` From 067e7c3ef7540e473bfa8f656803c6aa3234d900 Mon Sep 17 00:00:00 2001 From: Moriz Wahl Date: Wed, 6 Jul 2022 10:56:02 +0200 Subject: [PATCH 046/137] improve documentation --- README.md | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/README.md b/README.md index 75a9e7e55..a707639ac 100644 --- a/README.md +++ b/README.md @@ -125,13 +125,13 @@ Note: The Changelog will be regenerated with all tags on release on the external Each component (frontend, admin, backend and database) has its own `.env` file. When running in development you usually do not have to care about the `.env`. The defaults are set by the respective config file, found in the `src/config/` folder of each component. But if you have a local `.env`, the defaults set in the config are overwritten by the `.env`. -Each component has a `.env.dist` file. This file contains all environment variables used by the component. If you want to use a local `.env`, copy the `.env.dist` and adjust the variables accordingly. +Each component has a `.env.dist` file. This file contains all environment variables used by the component and can be used as pattern. If you want to use a local `.env`, copy the `.env.dist` and adjust the variables accordingly. Each component has a `.env.template` file. These files are very important on deploy. -There is one `.env.dist` in the `deployment/bare_metal/` folder. This `.env` contains all variables used by the components. On deploy, we set all variables in this file. The deploy script loads this variables and provides them by the `.env.templates` of each component, creating a `.env` for each component. +There is one `.env.dist` in the `deployment/bare_metal/` folder. This `.env.dist` contains all variables used by the components, e.g. unites all `.env.dist` from the components. On deploy, we copy this `.env.dist` to `.env` and set all variables in this new file. The deploy script loads this variables and provides them by the `.env.templates` of each component, creating a `.env` for each component (see in `deployment/bare_metal/start.sh` the `envsubst`). -To avoid forgetting to update the global `.env` when deploying, we have a environment version variable inside the codebase of each component. You should update this version, when environment variables must be changed or added on deploy. The code checks, that the environement version provided by the `.env` is the one expected by the codebase. +To avoid forgetting to update an existing `.env` in the `deployment/bare_metal/` folder when deploying, we have a environment version variable inside the codebase of each component. You should update this version, when environment variables must be changed or added on deploy. The code checks, that the environement version provided by the `.env` is the one expected by the codebase. ## Troubleshooting 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 047/137] 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 048/137] 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 049/137] 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 050/137] 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 051/137] 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 ca84fc3bae8d9c0943cafa5a6d6f6589db1530cd Mon Sep 17 00:00:00 2001 From: ogerly Date: Thu, 7 Jul 2022 07:42:39 +0200 Subject: [PATCH 052/137] change text from page --- frontend/src/components/Auth/AuthMobileStart.vue | 2 +- frontend/src/locales/de.json | 3 +-- frontend/src/locales/en.json | 1 - 3 files changed, 2 insertions(+), 4 deletions(-) diff --git a/frontend/src/components/Auth/AuthMobileStart.vue b/frontend/src/components/Auth/AuthMobileStart.vue index 09985dd77..690b8f895 100644 --- a/frontend/src/components/Auth/AuthMobileStart.vue +++ b/frontend/src/components/Auth/AuthMobileStart.vue @@ -6,7 +6,7 @@ {{ $t('auth.left.gratitude') }}
- {{ $t('auth.left.newCurrency') }} + {{ $t('auth.left.oneGratitude') }}
Date: Thu, 7 Jul 2022 13:47:14 +0200 Subject: [PATCH 053/137] Update README.md MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Co-authored-by: Wolfgang Huß --- README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/README.md b/README.md index a707639ac..d12edfb89 100644 --- a/README.md +++ b/README.md @@ -129,7 +129,7 @@ Each component has a `.env.dist` file. This file contains all environment variab Each component has a `.env.template` file. These files are very important on deploy. -There is one `.env.dist` in the `deployment/bare_metal/` folder. This `.env.dist` contains all variables used by the components, e.g. unites all `.env.dist` from the components. On deploy, we copy this `.env.dist` to `.env` and set all variables in this new file. The deploy script loads this variables and provides them by the `.env.templates` of each component, creating a `.env` for each component (see in `deployment/bare_metal/start.sh` the `envsubst`). +There is one `.env.dist` in the `deployment/bare_metal/` folder. This `.env.dist` contains all variables used by the components, e.g. unites all `.env.dist` from the components. On deploy, we copy this `.env.dist` to `.env` and set all variables in this new file. The deploy script loads this variables and provides them by the `.env.templates` of each component, creating an `.env` for each component (see in `deployment/bare_metal/start.sh` the `envsubst`). To avoid forgetting to update an existing `.env` in the `deployment/bare_metal/` folder when deploying, we have a environment version variable inside the codebase of each component. You should update this version, when environment variables must be changed or added on deploy. The code checks, that the environement version provided by the `.env` is the one expected by the codebase. From 9840017f0cd0048ad0bd561ecbb6cc56876632cc Mon Sep 17 00:00:00 2001 From: Moriz Wahl Date: Thu, 7 Jul 2022 13:47:24 +0200 Subject: [PATCH 054/137] Update README.md MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Co-authored-by: Wolfgang Huß --- README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/README.md b/README.md index d12edfb89..145ce4141 100644 --- a/README.md +++ b/README.md @@ -131,7 +131,7 @@ Each component has a `.env.template` file. These files are very important on dep There is one `.env.dist` in the `deployment/bare_metal/` folder. This `.env.dist` contains all variables used by the components, e.g. unites all `.env.dist` from the components. On deploy, we copy this `.env.dist` to `.env` and set all variables in this new file. The deploy script loads this variables and provides them by the `.env.templates` of each component, creating an `.env` for each component (see in `deployment/bare_metal/start.sh` the `envsubst`). -To avoid forgetting to update an existing `.env` in the `deployment/bare_metal/` folder when deploying, we have a environment version variable inside the codebase of each component. You should update this version, when environment variables must be changed or added on deploy. The code checks, that the environement version provided by the `.env` is the one expected by the codebase. +To avoid forgetting to update an existing `.env` in the `deployment/bare_metal/` folder when deploying, we have an environment version variable inside the codebase of each component. You should update this version, when environment variables must be changed or added on deploy. The code checks, that the environement version provided by the `.env` is the one expected by the codebase. ## Troubleshooting From d9c6836f894566e0ee3fbe0e086410748d8743b3 Mon Sep 17 00:00:00 2001 From: Einhornimmond Date: Sun, 10 Jul 2022 08:10:26 +0200 Subject: [PATCH 055/137] finalize, merge with current master --- 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 aa4197a43..cd24ee0c8 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-update_transactions_for_blockchain', DECAY_START_TIME: new Date('2021-05-13 17:46:31-0000'), // GMT+0 LOG4JS_CONFIG: 'log4js-config.json', // default log level on production should be info From 1841d9969d9689d7745baa5caa1d0faf5466c5d9 Mon Sep 17 00:00:00 2001 From: Einhornimmond Date: Sun, 10 Jul 2022 08:39:25 +0200 Subject: [PATCH 056/137] finalize --- 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 aa4197a43..1f355623c 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: '0042-move_users_creation_date', DECAY_START_TIME: new Date('2021-05-13 17:46:31-0000'), // GMT+0 LOG4JS_CONFIG: 'log4js-config.json', // default log level on production should be info From 971473965afed6642ddabdf5dc6102dec882e759 Mon Sep 17 00:00:00 2001 From: Alexander Friedland Date: Mon, 11 Jul 2022 10:59:27 +0200 Subject: [PATCH 057/137] Update en.json --- frontend/src/locales/en.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/frontend/src/locales/en.json b/frontend/src/locales/en.json index 4271e85f8..0bfde65ed 100644 --- a/frontend/src/locales/en.json +++ b/frontend/src/locales/en.json @@ -14,7 +14,7 @@ "learnMore": "Learn more …", "oneDignity": "We gift to each other and give thanks with Gradido.", "oneDonation": "You are a gift for the community. 1000 thanks because you are with us.", - "oneGratitude": "The new currency. For each other, for all people, for nature." + "oneGratitude": "For each other, for all people, for nature." }, "navbar": { "aboutGradido": "About Gradido" From 3718f0dc56ef3d0363c2911bca6c4da9891f3959 Mon Sep 17 00:00:00 2001 From: elweyn Date: Mon, 11 Jul 2022 11:42:24 +0200 Subject: [PATCH 058/137] Change the test so that we can test if the contribution list finds only created but not confirmed contribution --- .../resolver/ContributionResolver.test.ts | 91 ++++++++++++------- backend/src/seeds/graphql/mutations.ts | 1 + backend/src/seeds/graphql/queries.ts | 1 + 3 files changed, 59 insertions(+), 34 deletions(-) diff --git a/backend/src/graphql/resolver/ContributionResolver.test.ts b/backend/src/graphql/resolver/ContributionResolver.test.ts index 2308cd4e7..01ece7440 100644 --- a/backend/src/graphql/resolver/ContributionResolver.test.ts +++ b/backend/src/graphql/resolver/ContributionResolver.test.ts @@ -13,6 +13,7 @@ import { peterLustig } from '@/seeds/users/peter-lustig' let mutate: any, query: any, con: any let testEnv: any +let result: any beforeAll(async () => { testEnv = await testEnvironment() @@ -114,6 +115,7 @@ describe('ContributionResolver', () => { expect.objectContaining({ data: { createContribution: { + id: expect.any(Number), amount: '100', memo: 'Test env contribution', }, @@ -148,25 +150,22 @@ describe('ContributionResolver', () => { describe('authenticated', () => { beforeAll(async () => { - await userFactory(testEnv, peterLustig) await userFactory(testEnv, bibiBloxberg) - // bibi needs GDDs - 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 userFactory(testEnv, bibiBloxberg) 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() - resetToken() - }) - - it('returns an empty array for unconfirmed creation filter', async () => { + it('returns only unconfirmed creations', async () => { await expect( query({ query: listContributions, @@ -177,39 +176,63 @@ describe('ContributionResolver', () => { filterConfirmed: true, }, }), - ).resolves.toEqual( - expect.objectContaining({ - data: { - listContributions: [], - }, - }), - ) - }) - - it('returns confirmed creation', async () => { - await expect( - query({ - query: listContributions, - variables: { - currentPage: 1, - pageSize: 25, - order: 'DESC', - filterConfirmed: false, - }, - }), ).resolves.toEqual( expect.objectContaining({ data: { listContributions: expect.arrayContaining([ expect.objectContaining({ - memo: 'Herzlich Willkommen bei Gradido!', - amount: '1000', + id: expect.any(Number), + memo: 'Test env contribution', + amount: '100', }), ]), }, }), ) }) + + describe('Adding confirmed creations', () => { + beforeAll(async () => { + await userFactory(testEnv, peterLustig) + const bibisCreation = creations.find((creation) => creation.email === 'bibi@bloxberg.de') + await creationFactory(testEnv, bibisCreation!) + await query({ + query: login, + variables: { email: 'bibi@bloxberg.de', password: 'Aa12345_' }, + }) + }) + + it('returns confirmed and unconfirmed creation', async () => { + await expect( + query({ + query: listContributions, + variables: { + currentPage: 1, + pageSize: 25, + order: 'DESC', + filterConfirmed: false, + }, + }), + ).resolves.toEqual( + expect.objectContaining({ + data: { + listContributions: 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', + }), + ]), + }, + }), + ) + }) + }) }) }) }) diff --git a/backend/src/seeds/graphql/mutations.ts b/backend/src/seeds/graphql/mutations.ts index 4926f706f..185485f2c 100644 --- a/backend/src/seeds/graphql/mutations.ts +++ b/backend/src/seeds/graphql/mutations.ts @@ -234,6 +234,7 @@ export const deleteContributionLink = gql` export const createContribution = gql` mutation ($amount: Decimal!, $memo: String!, $creationDate: String!) { createContribution(amount: $amount, memo: $memo, creationDate: $creationDate) { + id amount memo } diff --git a/backend/src/seeds/graphql/queries.ts b/backend/src/seeds/graphql/queries.ts index cf0fd09bd..c27ecdd66 100644 --- a/backend/src/seeds/graphql/queries.ts +++ b/backend/src/seeds/graphql/queries.ts @@ -185,6 +185,7 @@ export const listContributions = gql` order: $order filterConfirmed: $filterConfirmed ) { + id amount memo } From a2eccb12ed5b2e421d3ee8fd328afcc94c4def13 Mon Sep 17 00:00:00 2001 From: elweyn Date: Mon, 11 Jul 2022 11:42:39 +0200 Subject: [PATCH 059/137] Change the variable name contribution to contributions. --- backend/src/graphql/resolver/ContributionResolver.ts | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/backend/src/graphql/resolver/ContributionResolver.ts b/backend/src/graphql/resolver/ContributionResolver.ts index 59f1f359f..0925fac9c 100644 --- a/backend/src/graphql/resolver/ContributionResolver.ts +++ b/backend/src/graphql/resolver/ContributionResolver.ts @@ -48,9 +48,9 @@ export class ContributionResolver { @Ctx() context: Context, ): Promise { const user = getUser(context) - let contribution + let contributions if (filterConfirmed) { - contribution = await dbContribution.find({ + contributions = await dbContribution.find({ where: { userId: user.id, confirmedBy: IsNull(), @@ -62,7 +62,7 @@ export class ContributionResolver { take: pageSize, }) } else { - contribution = await dbContribution.find({ + contributions = await dbContribution.find({ where: { userId: user.id, }, @@ -73,6 +73,6 @@ export class ContributionResolver { take: pageSize, }) } - return contribution.map((contr) => new Contribution(contr, new User(user))) + return contributions.map((contribution) => new Contribution(contribution, new User(user))) } } From ae52b520dd0288e08f1fff35d461687bf3b96446 Mon Sep 17 00:00:00 2001 From: elweyn Date: Mon, 11 Jul 2022 12:04:46 +0200 Subject: [PATCH 060/137] Withdrew where clause to an variable with inline condition. --- .../graphql/resolver/ContributionResolver.ts | 35 +++++++------------ 1 file changed, 13 insertions(+), 22 deletions(-) diff --git a/backend/src/graphql/resolver/ContributionResolver.ts b/backend/src/graphql/resolver/ContributionResolver.ts index 0925fac9c..acf1b4cb0 100644 --- a/backend/src/graphql/resolver/ContributionResolver.ts +++ b/backend/src/graphql/resolver/ContributionResolver.ts @@ -48,31 +48,22 @@ export class ContributionResolver { @Ctx() context: Context, ): Promise { const user = getUser(context) - let contributions - if (filterConfirmed) { - contributions = await dbContribution.find({ - where: { + const where = filterConfirmed + ? { userId: user.id, confirmedBy: IsNull(), - }, - order: { - createdAt: order, - }, - skip: (currentPage - 1) * pageSize, - take: pageSize, - }) - } else { - contributions = await dbContribution.find({ - where: { + } + : { userId: user.id, - }, - order: { - createdAt: order, - }, - skip: (currentPage - 1) * pageSize, - take: pageSize, - }) - } + } + const contributions = await dbContribution.find({ + where, + order: { + createdAt: order, + }, + skip: (currentPage - 1) * pageSize, + take: pageSize, + }) return contributions.map((contribution) => new Contribution(contribution, new User(user))) } } From 9239f93096afe579bc1f2a0cc0b44bed1d730d7f Mon Sep 17 00:00:00 2001 From: elweyn Date: Mon, 11 Jul 2022 12:21:51 +0200 Subject: [PATCH 061/137] Add no non nullable assertion to admin Creation. --- backend/src/graphql/resolver/ContributionResolver.test.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/backend/src/graphql/resolver/ContributionResolver.test.ts b/backend/src/graphql/resolver/ContributionResolver.test.ts index 01ece7440..fcaaca11a 100644 --- a/backend/src/graphql/resolver/ContributionResolver.test.ts +++ b/backend/src/graphql/resolver/ContributionResolver.test.ts @@ -13,7 +13,6 @@ import { peterLustig } from '@/seeds/users/peter-lustig' let mutate: any, query: any, con: any let testEnv: any -let result: any beforeAll(async () => { testEnv = await testEnvironment() @@ -195,6 +194,7 @@ describe('ContributionResolver', () => { beforeAll(async () => { 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, From 72a4c1145d41108f62d3d9c4c092dc2adf8bca1e Mon Sep 17 00:00:00 2001 From: Einhornimmond Date: Mon, 11 Jul 2022 12:39:35 +0200 Subject: [PATCH 062/137] remove forgotten drop transactions_temp table --- .../migrations/0041-update_transactions_for_blockchain.ts | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) diff --git a/database/migrations/0041-update_transactions_for_blockchain.ts b/database/migrations/0041-update_transactions_for_blockchain.ts index c4e025e86..9d41ac4df 100644 --- a/database/migrations/0041-update_transactions_for_blockchain.ts +++ b/database/migrations/0041-update_transactions_for_blockchain.ts @@ -1913,7 +1913,5 @@ export async function downgrade(queryFn: (query: string, values?: any[]) => Prom WHERE \`id\` = 150`, ) - await queryFn(`UPDATE \`transactions\` set \`previous\` = 150 WHERE \`id\` = 278`) - // drop temp table - await queryFn(`DROP TABLE IF EXISTS \`transactions_temp\``) + await queryFn(`UPDATE \`transactions\` set \`previous\` = 150 WHERE \`id\` = 278`) } From caf4e9ae3e627cc6440636edf720cedd51fa51ec Mon Sep 17 00:00:00 2001 From: elweyn Date: Mon, 11 Jul 2022 14:04:38 +0200 Subject: [PATCH 063/137] Change the test name to filterConfirmed is false. --- backend/src/graphql/resolver/ContributionResolver.test.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/backend/src/graphql/resolver/ContributionResolver.test.ts b/backend/src/graphql/resolver/ContributionResolver.test.ts index fcaaca11a..1e3034b59 100644 --- a/backend/src/graphql/resolver/ContributionResolver.test.ts +++ b/backend/src/graphql/resolver/ContributionResolver.test.ts @@ -202,7 +202,7 @@ describe('ContributionResolver', () => { }) }) - it('returns confirmed and unconfirmed creation', async () => { + it('filter confirmed is false', async () => { await expect( query({ query: listContributions, From 2113061629310c0eee75049f300af42ba79bdaa1 Mon Sep 17 00:00:00 2001 From: elweyn Date: Mon, 11 Jul 2022 14:05:57 +0200 Subject: [PATCH 064/137] Change the imports to the standard. --- .../src/graphql/resolver/ContributionResolver.ts | 14 +++++++------- 1 file changed, 7 insertions(+), 7 deletions(-) diff --git a/backend/src/graphql/resolver/ContributionResolver.ts b/backend/src/graphql/resolver/ContributionResolver.ts index acf1b4cb0..a54a5e6bf 100644 --- a/backend/src/graphql/resolver/ContributionResolver.ts +++ b/backend/src/graphql/resolver/ContributionResolver.ts @@ -3,13 +3,13 @@ import { Context, getUser } from '@/server/context' import { backendLogger as logger } from '@/server/logger' import { Contribution as dbContribution } from '@entity/Contribution' import { Arg, Args, Authorized, Ctx, Mutation, Query, Resolver } from 'type-graphql' -import { IsNull } from '../../../../database/node_modules/typeorm' -import ContributionArgs from '../arg/ContributionArgs' -import Paginated from '../arg/Paginated' -import { Order } from '../enum/Order' -import { Contribution } from '../model/Contribution' -import { UnconfirmedContribution } from '../model/UnconfirmedContribution' -import { User } from '../model/User' +import { IsNull } from '@dbTools/typeorm' +import ContributionArgs from '@arg/ContributionArgs' +import Paginated from '@arg/Paginated' +import { Order } from '@enum/Order' +import { Contribution } from '@model/Contribution' +import { UnconfirmedContribution } from '@model/UnconfirmedContribution' +import { User } from '@model/User' import { validateContribution, getUserCreation } from './util/creations' @Resolver() From f8cdad7e58bfb232d7780543974a6f39787fadfd Mon Sep 17 00:00:00 2001 From: elweyn Date: Mon, 11 Jul 2022 14:07:57 +0200 Subject: [PATCH 065/137] Change the where clause to a defined object. --- .../src/graphql/resolver/ContributionResolver.ts | 15 ++++++--------- 1 file changed, 6 insertions(+), 9 deletions(-) diff --git a/backend/src/graphql/resolver/ContributionResolver.ts b/backend/src/graphql/resolver/ContributionResolver.ts index a54a5e6bf..3e13c404c 100644 --- a/backend/src/graphql/resolver/ContributionResolver.ts +++ b/backend/src/graphql/resolver/ContributionResolver.ts @@ -3,7 +3,7 @@ import { Context, getUser } from '@/server/context' import { backendLogger as logger } from '@/server/logger' import { Contribution as dbContribution } from '@entity/Contribution' import { Arg, Args, Authorized, Ctx, Mutation, Query, Resolver } from 'type-graphql' -import { IsNull } from '@dbTools/typeorm' +import { FindOperator, IsNull } from '@dbTools/typeorm' import ContributionArgs from '@arg/ContributionArgs' import Paginated from '@arg/Paginated' import { Order } from '@enum/Order' @@ -48,14 +48,11 @@ export class ContributionResolver { @Ctx() context: Context, ): Promise { const user = getUser(context) - const where = filterConfirmed - ? { - userId: user.id, - confirmedBy: IsNull(), - } - : { - userId: user.id, - } + const where: { + userId: number + confirmedBy?: FindOperator | null + } = { userId: user.id } + if (filterConfirmed) where.confirmedBy = IsNull() const contributions = await dbContribution.find({ where, order: { From 70db65044cfd5bf3bb42cce63968257616f1f1ed Mon Sep 17 00:00:00 2001 From: elweyn Date: Mon, 11 Jul 2022 14:09:40 +0200 Subject: [PATCH 066/137] Fix linting. --- 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 3e13c404c..41f6c9cd4 100644 --- a/backend/src/graphql/resolver/ContributionResolver.ts +++ b/backend/src/graphql/resolver/ContributionResolver.ts @@ -50,6 +50,7 @@ export class ContributionResolver { const user = getUser(context) const where: { userId: number + // eslint-disable-next-line @typescript-eslint/no-explicit-any confirmedBy?: FindOperator | null } = { userId: user.id } if (filterConfirmed) where.confirmedBy = IsNull() From d423e2d097b3e323b2408075baf48a16b750bf44 Mon Sep 17 00:00:00 2001 From: Einhornimmond Date: Mon, 11 Jul 2022 14:47:34 +0200 Subject: [PATCH 067/137] lint fix --- database/migrations/0041-update_transactions_for_blockchain.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/database/migrations/0041-update_transactions_for_blockchain.ts b/database/migrations/0041-update_transactions_for_blockchain.ts index 9d41ac4df..d7b26abbd 100644 --- a/database/migrations/0041-update_transactions_for_blockchain.ts +++ b/database/migrations/0041-update_transactions_for_blockchain.ts @@ -1913,5 +1913,5 @@ export async function downgrade(queryFn: (query: string, values?: any[]) => Prom WHERE \`id\` = 150`, ) - await queryFn(`UPDATE \`transactions\` set \`previous\` = 150 WHERE \`id\` = 278`) + await queryFn(`UPDATE \`transactions\` set \`previous\` = 150 WHERE \`id\` = 278`) } From eeafe2ddabb7262a7ee9fbaedd3b99a74c571a0c Mon Sep 17 00:00:00 2001 From: Einhornimmond Date: Mon, 11 Jul 2022 15:07:07 +0200 Subject: [PATCH 068/137] change order with other migration --- backend/src/config/index.ts | 2 +- ...blockchain.ts => 0042-update_transactions_for_blockchain.ts} | 0 2 files changed, 1 insertion(+), 1 deletion(-) rename database/migrations/{0041-update_transactions_for_blockchain.ts => 0042-update_transactions_for_blockchain.ts} (100%) diff --git a/backend/src/config/index.ts b/backend/src/config/index.ts index cd24ee0c8..8b84c059d 100644 --- a/backend/src/config/index.ts +++ b/backend/src/config/index.ts @@ -10,7 +10,7 @@ Decimal.set({ }) const constants = { - DB_VERSION: '0041-update_transactions_for_blockchain', + DB_VERSION: '0042-update_transactions_for_blockchain', 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/database/migrations/0041-update_transactions_for_blockchain.ts b/database/migrations/0042-update_transactions_for_blockchain.ts similarity index 100% rename from database/migrations/0041-update_transactions_for_blockchain.ts rename to database/migrations/0042-update_transactions_for_blockchain.ts From 6d4d03013602569ce8543227bb324c9610a9220e Mon Sep 17 00:00:00 2001 From: Einhornimmond Date: Mon, 11 Jul 2022 15:08:41 +0200 Subject: [PATCH 069/137] exchanged order with other migration --- backend/src/config/index.ts | 2 +- ..._users_creation_date.ts => 0041-move_users_creation_date.ts} | 0 2 files changed, 1 insertion(+), 1 deletion(-) rename database/migrations/{0042-move_users_creation_date.ts => 0041-move_users_creation_date.ts} (100%) diff --git a/backend/src/config/index.ts b/backend/src/config/index.ts index 1f355623c..490ac0121 100644 --- a/backend/src/config/index.ts +++ b/backend/src/config/index.ts @@ -10,7 +10,7 @@ Decimal.set({ }) const constants = { - DB_VERSION: '0042-move_users_creation_date', + DB_VERSION: '0041-move_users_creation_date', 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/database/migrations/0042-move_users_creation_date.ts b/database/migrations/0041-move_users_creation_date.ts similarity index 100% rename from database/migrations/0042-move_users_creation_date.ts rename to database/migrations/0041-move_users_creation_date.ts From 339b32a02f76d41eb10d49934c16d7c8cb31a94f Mon Sep 17 00:00:00 2001 From: elweyn Date: Mon, 11 Jul 2022 17:16:31 +0200 Subject: [PATCH 070/137] Change FindOperator to --- backend/src/graphql/resolver/ContributionResolver.ts | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/backend/src/graphql/resolver/ContributionResolver.ts b/backend/src/graphql/resolver/ContributionResolver.ts index 41f6c9cd4..4424b40d0 100644 --- a/backend/src/graphql/resolver/ContributionResolver.ts +++ b/backend/src/graphql/resolver/ContributionResolver.ts @@ -50,8 +50,7 @@ export class ContributionResolver { const user = getUser(context) const where: { userId: number - // eslint-disable-next-line @typescript-eslint/no-explicit-any - confirmedBy?: FindOperator | null + confirmedBy?: FindOperator | null } = { userId: user.id } if (filterConfirmed) where.confirmedBy = IsNull() const contributions = await dbContribution.find({ From b6f1b0730a51dcfc6c8a97a84b021cadd0644bbf Mon Sep 17 00:00:00 2001 From: elweyn Date: Tue, 12 Jul 2022 08:44:36 +0200 Subject: [PATCH 071/137] Change the orders and structure from the tests for listContributions. --- .../resolver/ContributionResolver.test.ts | 75 +++++++++---------- 1 file changed, 35 insertions(+), 40 deletions(-) diff --git a/backend/src/graphql/resolver/ContributionResolver.test.ts b/backend/src/graphql/resolver/ContributionResolver.test.ts index 1e3034b59..b3d6aeb3c 100644 --- a/backend/src/graphql/resolver/ContributionResolver.test.ts +++ b/backend/src/graphql/resolver/ContributionResolver.test.ts @@ -150,6 +150,10 @@ describe('ContributionResolver', () => { 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_' }, @@ -163,46 +167,9 @@ describe('ContributionResolver', () => { }, }) }) - - it('returns only unconfirmed creations', async () => { - await expect( - query({ - query: listContributions, - variables: { - currentPage: 1, - pageSize: 25, - order: 'DESC', - filterConfirmed: true, - }, - }), - ).resolves.toEqual( - expect.objectContaining({ - data: { - listContributions: expect.arrayContaining([ - expect.objectContaining({ - id: expect.any(Number), - memo: 'Test env contribution', - amount: '100', - }), - ]), - }, - }), - ) - }) - - describe('Adding confirmed creations', () => { - beforeAll(async () => { - 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_' }, - }) - }) - - it('filter confirmed is false', async () => { + + describe('filter confirmed is false', () => { + it('returns creations', async () => { await expect( query({ query: listContributions, @@ -233,6 +200,34 @@ describe('ContributionResolver', () => { ) }) }) + + describe('filter confirmed is true', () => { + it('returns only unconfirmed creations', async () => { + await expect( + query({ + query: listContributions, + variables: { + currentPage: 1, + pageSize: 25, + order: 'DESC', + filterConfirmed: true, + }, + }), + ).resolves.toEqual( + expect.objectContaining({ + data: { + listContributions: expect.arrayContaining([ + expect.objectContaining({ + id: expect.any(Number), + memo: 'Test env contribution', + amount: '100', + }), + ]), + }, + }), + ) + }) + }) }) }) }) From 0e13c7c2e12a66e6cbd41c1e6a167e6f5d32046c Mon Sep 17 00:00:00 2001 From: elweyn Date: Tue, 12 Jul 2022 08:47:15 +0200 Subject: [PATCH 072/137] Remove spaces. --- backend/src/graphql/resolver/ContributionResolver.test.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/backend/src/graphql/resolver/ContributionResolver.test.ts b/backend/src/graphql/resolver/ContributionResolver.test.ts index b3d6aeb3c..9b0f6a3bc 100644 --- a/backend/src/graphql/resolver/ContributionResolver.test.ts +++ b/backend/src/graphql/resolver/ContributionResolver.test.ts @@ -167,7 +167,7 @@ describe('ContributionResolver', () => { }, }) }) - + describe('filter confirmed is false', () => { it('returns creations', async () => { await expect( From 5369aced43ee60b6788c6a00ca492efaa6f0452e Mon Sep 17 00:00:00 2001 From: elweyn Date: Tue, 12 Jul 2022 09:37:06 +0200 Subject: [PATCH 073/137] Change mutation to include id in the result, write test to update contribution with inexistent id. --- .../resolver/ContributionResolver.test.ts | 53 +++++++++++++++++++ backend/src/seeds/graphql/mutations.ts | 1 + 2 files changed, 54 insertions(+) diff --git a/backend/src/graphql/resolver/ContributionResolver.test.ts b/backend/src/graphql/resolver/ContributionResolver.test.ts index c9302cf64..697c5ae43 100644 --- a/backend/src/graphql/resolver/ContributionResolver.test.ts +++ b/backend/src/graphql/resolver/ContributionResolver.test.ts @@ -13,6 +13,7 @@ import { peterLustig } from '@/seeds/users/peter-lustig' let mutate: any, query: any, con: any let testEnv: any +let result: any beforeAll(async () => { testEnv = await testEnvironment() @@ -159,6 +160,14 @@ describe('ContributionResolver', () => { 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 () => { @@ -233,5 +242,49 @@ describe('ContributionResolver', () => { ) }) }) + + describe('authenticated', () => { + beforeAll(async () => { + await userFactory(testEnv, peterLustig) + await userFactory(testEnv, bibiBloxberg) + // bibi needs GDDs + 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 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('wrong contribution id', () => { + it('throws an error', async () => { + await expect( + mutate({ + mutation: updateContribution, + variables: { + contributionId: -1, + amount: 100.0, + memo: 'Test env contribution', + creationDate: new Date().toString(), + }, + }), + ).resolves.toEqual( + expect.objectContaining({ + errors: [new GraphQLError('No contribution found to given id.')], + }), + ) + }) + }) + }) }) }) diff --git a/backend/src/seeds/graphql/mutations.ts b/backend/src/seeds/graphql/mutations.ts index 45adeacc8..bfa9847e0 100644 --- a/backend/src/seeds/graphql/mutations.ts +++ b/backend/src/seeds/graphql/mutations.ts @@ -234,6 +234,7 @@ export const deleteContributionLink = gql` export const createContribution = gql` mutation ($amount: Decimal!, $memo: String!, $creationDate: String!) { createContribution(amount: $amount, memo: $memo, creationDate: $creationDate) { + id amount memo } From 86433478ec24dd58de4f6dcbd6f8560836eabe30 Mon Sep 17 00:00:00 2001 From: elweyn Date: Tue, 12 Jul 2022 09:38:19 +0200 Subject: [PATCH 074/137] Test that only the user that created the contribution can update it with the updateContribution mutation. --- .../resolver/ContributionResolver.test.ts | 31 +++++++++++++++++++ 1 file changed, 31 insertions(+) diff --git a/backend/src/graphql/resolver/ContributionResolver.test.ts b/backend/src/graphql/resolver/ContributionResolver.test.ts index 697c5ae43..41b5808a1 100644 --- a/backend/src/graphql/resolver/ContributionResolver.test.ts +++ b/backend/src/graphql/resolver/ContributionResolver.test.ts @@ -285,6 +285,37 @@ describe('ContributionResolver', () => { ) }) }) + + describe('wrong user tries to update the contribution', () => { + beforeAll(async () => { + await query({ + query: login, + variables: { email: 'peter@lustig.de', password: 'Aa12345_' }, + }) + }) + + it('throws an error', async () => { + await expect( + mutate({ + mutation: updateContribution, + variables: { + contributionId: result.data.createContribution.id, + amount: 10.0, + memo: 'Test env contribution', + creationDate: new Date().toString(), + }, + }), + ).resolves.toEqual( + expect.objectContaining({ + errors: [ + new GraphQLError( + 'user of the pending contribution and send user does not correspond', + ), + ], + }), + ) + }) + }) }) }) }) From 6348756ab31a18fd1fcb7946918d8fc20a911487 Mon Sep 17 00:00:00 2001 From: elweyn Date: Tue, 12 Jul 2022 09:39:24 +0200 Subject: [PATCH 075/137] Test that the updateContribution mutation can not update more gdd's than allowed in the month. --- .../resolver/ContributionResolver.test.ts | 31 +++++++++++++++++++ 1 file changed, 31 insertions(+) diff --git a/backend/src/graphql/resolver/ContributionResolver.test.ts b/backend/src/graphql/resolver/ContributionResolver.test.ts index 41b5808a1..bdb8453da 100644 --- a/backend/src/graphql/resolver/ContributionResolver.test.ts +++ b/backend/src/graphql/resolver/ContributionResolver.test.ts @@ -316,6 +316,37 @@ describe('ContributionResolver', () => { ) }) }) + + describe('update to much so that the limit is exceeded', () => { + beforeAll(async () => { + await query({ + query: login, + variables: { email: 'bibi@bloxberg.de', password: 'Aa12345_' }, + }) + }) + + it('throws an error', async () => { + await expect( + mutate({ + mutation: updateContribution, + variables: { + contributionId: result.data.createContribution.id, + amount: 1019.0, + memo: 'Test env contribution', + creationDate: new Date().toString(), + }, + }), + ).resolves.toEqual( + expect.objectContaining({ + errors: [ + new GraphQLError( + 'The amount (1019 GDD) to be created exceeds the amount (1000 GDD) still available for this month.', + ), + ], + }), + ) + }) + }) }) }) }) From 9e355f9202d05e208dcaf36438bfae489d3c8521 Mon Sep 17 00:00:00 2001 From: elweyn Date: Tue, 12 Jul 2022 09:43:47 +0200 Subject: [PATCH 076/137] Test that the updateContribution mutation can not update contribution to a date that is older than 3 month. --- .../resolver/ContributionResolver.test.ts | 23 +++++++++++++++++++ 1 file changed, 23 insertions(+) diff --git a/backend/src/graphql/resolver/ContributionResolver.test.ts b/backend/src/graphql/resolver/ContributionResolver.test.ts index bdb8453da..d3d42be86 100644 --- a/backend/src/graphql/resolver/ContributionResolver.test.ts +++ b/backend/src/graphql/resolver/ContributionResolver.test.ts @@ -347,6 +347,29 @@ describe('ContributionResolver', () => { ) }) }) + + describe('update creation to a date that is older than 3 month', () => { + it('throws an error', async () => { + const date = new Date() // , + await expect( + mutate({ + mutation: updateContribution, + variables: { + contributionId: result.data.createContribution.id, + amount: 1019.0, + memo: 'Test env contribution', + creationDate: date.setMonth(date.getMonth() - 3).toString(), + }, + }), + ).resolves.toEqual( + expect.objectContaining({ + errors: [ + new GraphQLError('No information for available creations for the given date'), + ], + }), + ) + }) + }) }) }) }) From 9ee40767bbf019e5ed44ed732909d287b00c6fb0 Mon Sep 17 00:00:00 2001 From: elweyn Date: Tue, 12 Jul 2022 09:45:48 +0200 Subject: [PATCH 077/137] Change test so that only the date is to old and the amount could be right. --- backend/src/graphql/resolver/ContributionResolver.test.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/backend/src/graphql/resolver/ContributionResolver.test.ts b/backend/src/graphql/resolver/ContributionResolver.test.ts index d3d42be86..31d46e2ae 100644 --- a/backend/src/graphql/resolver/ContributionResolver.test.ts +++ b/backend/src/graphql/resolver/ContributionResolver.test.ts @@ -356,7 +356,7 @@ describe('ContributionResolver', () => { mutation: updateContribution, variables: { contributionId: result.data.createContribution.id, - amount: 1019.0, + amount: 10.0, memo: 'Test env contribution', creationDate: date.setMonth(date.getMonth() - 3).toString(), }, From c6ae5760c3072bb89d4d68f395062f1b7eff208a Mon Sep 17 00:00:00 2001 From: elweyn Date: Tue, 12 Jul 2022 09:55:03 +0200 Subject: [PATCH 078/137] Test that the updateContribution mutation updates the contribution with the right values. --- .../resolver/ContributionResolver.test.ts | 26 +++++++++++++++++++ backend/src/seeds/graphql/mutations.ts | 1 + 2 files changed, 27 insertions(+) diff --git a/backend/src/graphql/resolver/ContributionResolver.test.ts b/backend/src/graphql/resolver/ContributionResolver.test.ts index 31d46e2ae..3c8046bc2 100644 --- a/backend/src/graphql/resolver/ContributionResolver.test.ts +++ b/backend/src/graphql/resolver/ContributionResolver.test.ts @@ -370,6 +370,32 @@ describe('ContributionResolver', () => { ) }) }) + + describe('valid input', () => { + it('updates contribution', async () => { + await expect( + mutate({ + mutation: updateContribution, + variables: { + contributionId: result.data.createContribution.id, + amount: 10.0, + memo: 'Test contribution', + creationDate: new Date().toString(), + }, + }), + ).resolves.toEqual( + expect.objectContaining({ + data: { + updateContribution: { + id: result.data.createContribution.id, + amount: '10', + memo: 'Test contribution', + }, + }, + }), + ) + }) + }) }) }) }) diff --git a/backend/src/seeds/graphql/mutations.ts b/backend/src/seeds/graphql/mutations.ts index bfa9847e0..4e7fa8a90 100644 --- a/backend/src/seeds/graphql/mutations.ts +++ b/backend/src/seeds/graphql/mutations.ts @@ -249,6 +249,7 @@ export const updateContribution = gql` memo: $memo creationDate: $creationDate ) { + id amount memo } From b991bb0467035a5c18aa409ca99b93292fea41cd Mon Sep 17 00:00:00 2001 From: elweyn Date: Tue, 12 Jul 2022 10:11:28 +0200 Subject: [PATCH 079/137] Delete datas after all listContributions and updateContribution Tests. --- .../src/graphql/resolver/ContributionResolver.test.ts | 10 ++++++++++ 1 file changed, 10 insertions(+) diff --git a/backend/src/graphql/resolver/ContributionResolver.test.ts b/backend/src/graphql/resolver/ContributionResolver.test.ts index f690e10b1..a1f274fc6 100644 --- a/backend/src/graphql/resolver/ContributionResolver.test.ts +++ b/backend/src/graphql/resolver/ContributionResolver.test.ts @@ -169,6 +169,11 @@ describe('ContributionResolver', () => { }) }) + afterAll(async () => { + await cleanDB() + resetToken() + }) + describe('filter confirmed is false', () => { it('returns creations', async () => { await expect( @@ -276,6 +281,11 @@ describe('ContributionResolver', () => { }) }) + afterAll(async () => { + await cleanDB() + resetToken() + }) + describe('wrong contribution id', () => { it('throws an error', async () => { await expect( From 8a3c8253716d499fc8d0c6af421cc3dab6d02840 Mon Sep 17 00:00:00 2001 From: Moriz Wahl Date: Tue, 12 Jul 2022 10:27:52 +0200 Subject: [PATCH 080/137] feat: Login Returns Open Creations for User --- backend/src/graphql/model/User.ts | 8 +++++++- backend/src/graphql/resolver/UserResolver.ts | 5 +++-- 2 files changed, 10 insertions(+), 3 deletions(-) diff --git a/backend/src/graphql/model/User.ts b/backend/src/graphql/model/User.ts index 86c56312f..0642be630 100644 --- a/backend/src/graphql/model/User.ts +++ b/backend/src/graphql/model/User.ts @@ -1,10 +1,12 @@ import { ObjectType, Field } from 'type-graphql' import { KlickTipp } from './KlickTipp' import { User as dbUser } from '@entity/User' +import Decimal from 'decimal.js-light' +import { FULL_CREATION_AVAILABLE } from '../resolver/const/const' @ObjectType() export class User { - constructor(user: dbUser) { + constructor(user: dbUser, creation: Decimal[] = FULL_CREATION_AVAILABLE) { this.id = user.id this.email = user.email this.firstName = user.firstName @@ -17,6 +19,7 @@ export class User { this.isAdmin = user.isAdmin this.klickTipp = null this.hasElopage = null + this.creation = creation } @Field(() => Number) @@ -64,4 +67,7 @@ export class User { @Field(() => Boolean, { nullable: true }) hasElopage: boolean | null + + @Field(() => [Decimal]) + creation: Decimal[] } diff --git a/backend/src/graphql/resolver/UserResolver.ts b/backend/src/graphql/resolver/UserResolver.ts index 0bde22ae6..5b824b38f 100644 --- a/backend/src/graphql/resolver/UserResolver.ts +++ b/backend/src/graphql/resolver/UserResolver.ts @@ -23,6 +23,7 @@ import { sendAccountMultiRegistrationEmail } from '@/mailer/sendAccountMultiRegi import { klicktippSignIn } from '@/apis/KlicktippController' import { RIGHTS } from '@/auth/RIGHTS' import { hasElopageBuys } from '@/util/hasElopageBuys' +import { getUserCreation } from './util/creations' // eslint-disable-next-line @typescript-eslint/no-var-requires const sodium = require('sodium-native') @@ -224,7 +225,7 @@ export class UserResolver { logger.info('verifyLogin...') // TODO refactor and do not have duplicate code with login(see below) const userEntity = getUser(context) - const user = new User(userEntity) + const user = new User(userEntity, await getUserCreation(userEntity.id)) // user.pubkey = userEntity.pubKey.toString('hex') // Elopage Status & Stored PublisherId user.hasElopage = await this.hasElopage(context) @@ -274,7 +275,7 @@ export class UserResolver { logger.addContext('user', dbUser.id) logger.debug('login credentials valid...') - const user = new User(dbUser) + const user = new User(dbUser, await getUserCreation(dbUser.id)) logger.debug('user=' + user) // Elopage Status & Stored PublisherId From 0380609deeea78f4713205c3e0b217814ac2b018 Mon Sep 17 00:00:00 2001 From: Hannes Heine Date: Tue, 12 Jul 2022 12:54:46 +0200 Subject: [PATCH 081/137] Update backend/src/graphql/resolver/ContributionResolver.test.ts Co-authored-by: Moriz Wahl --- backend/src/graphql/resolver/ContributionResolver.test.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/backend/src/graphql/resolver/ContributionResolver.test.ts b/backend/src/graphql/resolver/ContributionResolver.test.ts index a1f274fc6..a5c9b2f55 100644 --- a/backend/src/graphql/resolver/ContributionResolver.test.ts +++ b/backend/src/graphql/resolver/ContributionResolver.test.ts @@ -368,7 +368,7 @@ describe('ContributionResolver', () => { }) }) - describe('update creation to a date that is older than 3 month', () => { + describe('update creation to a date that is older than 3 months', () => { it('throws an error', async () => { const date = new Date() // , await expect( From 90d2ffbff3bc91713510a1817dcb10f901197a66 Mon Sep 17 00:00:00 2001 From: Hannes Heine Date: Tue, 12 Jul 2022 12:54:55 +0200 Subject: [PATCH 082/137] Update backend/src/graphql/resolver/ContributionResolver.test.ts Co-authored-by: Moriz Wahl --- backend/src/graphql/resolver/ContributionResolver.test.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/backend/src/graphql/resolver/ContributionResolver.test.ts b/backend/src/graphql/resolver/ContributionResolver.test.ts index a5c9b2f55..731a897c1 100644 --- a/backend/src/graphql/resolver/ContributionResolver.test.ts +++ b/backend/src/graphql/resolver/ContributionResolver.test.ts @@ -370,7 +370,7 @@ describe('ContributionResolver', () => { describe('update creation to a date that is older than 3 months', () => { it('throws an error', async () => { - const date = new Date() // , + const date = new Date() await expect( mutate({ mutation: updateContribution, From 32d79bb61cdf19adee86e0403977e3f54255773f Mon Sep 17 00:00:00 2001 From: elweyn Date: Tue, 12 Jul 2022 13:01:46 +0200 Subject: [PATCH 083/137] Corrected the spelling errors and withdrew admin creation on update scenario. --- backend/src/graphql/resolver/ContributionResolver.test.ts | 7 +------ 1 file changed, 1 insertion(+), 6 deletions(-) diff --git a/backend/src/graphql/resolver/ContributionResolver.test.ts b/backend/src/graphql/resolver/ContributionResolver.test.ts index 731a897c1..394d9fc7d 100644 --- a/backend/src/graphql/resolver/ContributionResolver.test.ts +++ b/backend/src/graphql/resolver/ContributionResolver.test.ts @@ -262,11 +262,6 @@ describe('ContributionResolver', () => { beforeAll(async () => { await userFactory(testEnv, peterLustig) await userFactory(testEnv, bibiBloxberg) - // bibi needs GDDs - 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 userFactory(testEnv, bibiBloxberg) await query({ query: login, variables: { email: 'bibi@bloxberg.de', password: 'Aa12345_' }, @@ -337,7 +332,7 @@ describe('ContributionResolver', () => { }) }) - describe('update to much so that the limit is exceeded', () => { + describe('update too much so that the limit is exceeded', () => { beforeAll(async () => { await query({ query: login, From 3e471eb81ee0037e40c6d127e90ef546250378aa Mon Sep 17 00:00:00 2001 From: ogerly Date: Tue, 12 Jul 2022 16:54:37 +0200 Subject: [PATCH 084/137] 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 085/137] 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 086/137] 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 087/137] 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 c6bab99a2c96e8fcdf80e72c7878ec8e9f5502c2 Mon Sep 17 00:00:00 2001 From: elweyn Date: Wed, 13 Jul 2022 08:26:30 +0200 Subject: [PATCH 088/137] Add Test that adminUpdateContribution is not allowed on creation made by createContribution mutation. --- .../resolver/ContributionResolver.test.ts | 23 ++++++++++++++++++- 1 file changed, 22 insertions(+), 1 deletion(-) diff --git a/backend/src/graphql/resolver/ContributionResolver.test.ts b/backend/src/graphql/resolver/ContributionResolver.test.ts index 394d9fc7d..75d6d1128 100644 --- a/backend/src/graphql/resolver/ContributionResolver.test.ts +++ b/backend/src/graphql/resolver/ContributionResolver.test.ts @@ -2,7 +2,7 @@ /* eslint-disable @typescript-eslint/explicit-module-boundary-types */ import { bibiBloxberg } from '@/seeds/users/bibi-bloxberg' -import { createContribution, updateContribution } from '@/seeds/graphql/mutations' +import { adminUpdateContribution, createContribution, updateContribution } from '@/seeds/graphql/mutations' import { listContributions, login } from '@/seeds/graphql/queries' import { cleanDB, resetToken, testEnvironment } from '@test/helpers' import { GraphQLError } from 'graphql' @@ -332,6 +332,27 @@ describe('ContributionResolver', () => { }) }) + describe('admin tries to update a user contribution', () => { + it('throws an error', async () => { + await expect( + mutate({ + mutation: adminUpdateContribution, + variables: { + id: result.data.createContribution.id, + email: 'bibi@bloxberg.de', + amount: 10.0, + memo: 'Test env contribution', + creationDate: new Date().toString(), + }, + }), + ).resolves.toEqual( + expect.objectContaining({ + errors: [new GraphQLError('An admin is not allowed to update a user contribution.')], + }), + ) + }) + }) + describe('update too much so that the limit is exceeded', () => { beforeAll(async () => { await query({ From 801e223cfd29398004b267ced763eb9d530421f7 Mon Sep 17 00:00:00 2001 From: elweyn Date: Wed, 13 Jul 2022 08:27:05 +0200 Subject: [PATCH 089/137] Implement that adminUpdateContribution is not allowed when moderator is null. --- backend/src/graphql/resolver/AdminResolver.ts | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/backend/src/graphql/resolver/AdminResolver.ts b/backend/src/graphql/resolver/AdminResolver.ts index e3c61c300..12cad529c 100644 --- a/backend/src/graphql/resolver/AdminResolver.ts +++ b/backend/src/graphql/resolver/AdminResolver.ts @@ -321,6 +321,10 @@ export class AdminResolver { throw new Error('user of the pending contribution and send user does not correspond') } + if (contributionToUpdate.moderatorId === null) { + throw new Error('An admin is not allowed to update a user contribution.') + } + const creationDateObj = new Date(creationDate) let creations = await getUserCreation(user.id) if (contributionToUpdate.contributionDate.getMonth() === creationDateObj.getMonth()) { From e1d50cacb521b3fabec9eaae67cdf29987531139 Mon Sep 17 00:00:00 2001 From: elweyn Date: Wed, 13 Jul 2022 09:55:21 +0200 Subject: [PATCH 090/137] Fix linting. --- backend/src/graphql/resolver/ContributionResolver.test.ts | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/backend/src/graphql/resolver/ContributionResolver.test.ts b/backend/src/graphql/resolver/ContributionResolver.test.ts index 75d6d1128..7afae08f6 100644 --- a/backend/src/graphql/resolver/ContributionResolver.test.ts +++ b/backend/src/graphql/resolver/ContributionResolver.test.ts @@ -2,7 +2,11 @@ /* eslint-disable @typescript-eslint/explicit-module-boundary-types */ import { bibiBloxberg } from '@/seeds/users/bibi-bloxberg' -import { adminUpdateContribution, createContribution, updateContribution } from '@/seeds/graphql/mutations' +import { + adminUpdateContribution, + createContribution, + updateContribution, +} from '@/seeds/graphql/mutations' import { listContributions, login } from '@/seeds/graphql/queries' import { cleanDB, resetToken, testEnvironment } from '@test/helpers' import { GraphQLError } from 'graphql' From 9d9d1a78f18abda66333139ac1b4ffd66e631607 Mon Sep 17 00:00:00 2001 From: elweyn Date: Wed, 13 Jul 2022 11:01:44 +0200 Subject: [PATCH 091/137] 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 092/137] 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 093/137] 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 ed10d7d1a00b8cc8ae65d6efa1323921e800e649 Mon Sep 17 00:00:00 2001 From: mahula Date: Wed, 13 Jul 2022 14:54:17 +0200 Subject: [PATCH 094/137] set session timer to 0, if expiration is greater then 0 seconds --- frontend/src/components/SessionLogoutTimeout.vue | 8 ++++++-- 1 file changed, 6 insertions(+), 2 deletions(-) diff --git a/frontend/src/components/SessionLogoutTimeout.vue b/frontend/src/components/SessionLogoutTimeout.vue index 1e5a27998..113362abf 100644 --- a/frontend/src/components/SessionLogoutTimeout.vue +++ b/frontend/src/components/SessionLogoutTimeout.vue @@ -65,7 +65,7 @@ export default { this.$timer.restart('tokenExpires') this.$bvModal.show('modalSessionTimeOut') } - if (this.tokenExpiresInSeconds <= 0) { + if (this.tokenExpiresInSeconds === 0) { this.$timer.stop('tokenExpires') this.$emit('logout') } @@ -90,7 +90,11 @@ export default { }, computed: { tokenExpiresInSeconds() { - return Math.floor((new Date(this.$store.state.tokenTime * 1000).getTime() - this.now) / 1000) + const remainingSecs = Math.floor( + (new Date(this.$store.state.tokenTime * 1000).getTime() - this.now) / 1000, + ) + if (remainingSecs <= 0) return 0 + return remainingSecs }, }, beforeDestroy() { From b2164e6d1dc90fed257fcbb95601b5b5cc218e46 Mon Sep 17 00:00:00 2001 From: mahula Date: Wed, 13 Jul 2022 14:54:47 +0200 Subject: [PATCH 095/137] add unit test for this fix --- frontend/src/components/SessionLogoutTimeout.spec.js | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/frontend/src/components/SessionLogoutTimeout.spec.js b/frontend/src/components/SessionLogoutTimeout.spec.js index 0f5d21d36..94751f9cb 100644 --- a/frontend/src/components/SessionLogoutTimeout.spec.js +++ b/frontend/src/components/SessionLogoutTimeout.spec.js @@ -62,12 +62,16 @@ describe('SessionLogoutTimeout', () => { }) }) - describe('token is expired', () => { + describe('token is expired for several seconds', () => { beforeEach(() => { mocks.$store.state.tokenTime = setTokenTime(-60) wrapper = Wrapper() }) + it('value for remaining seconds is 0', () => { + expect(wrapper.tokenExpiresInSeconds === 0) + }) + it('emits logout', () => { expect(wrapper.emitted('logout')).toBeTruthy() }) From 1d1cc7e960aa845de7a659f6e5f4f25442c52e1b Mon Sep 17 00:00:00 2001 From: mahula Date: Wed, 13 Jul 2022 15:36:15 +0200 Subject: [PATCH 096/137] Update frontend/src/components/SessionLogoutTimeout.spec.js Co-authored-by: Moriz Wahl --- frontend/src/components/SessionLogoutTimeout.spec.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/frontend/src/components/SessionLogoutTimeout.spec.js b/frontend/src/components/SessionLogoutTimeout.spec.js index 94751f9cb..bd6911d13 100644 --- a/frontend/src/components/SessionLogoutTimeout.spec.js +++ b/frontend/src/components/SessionLogoutTimeout.spec.js @@ -68,7 +68,7 @@ describe('SessionLogoutTimeout', () => { wrapper = Wrapper() }) - it('value for remaining seconds is 0', () => { + it('has value for remaining seconds equal 0', () => { expect(wrapper.tokenExpiresInSeconds === 0) }) From 2302da9054785b8b4a7ca330fd1ddbdd42826ce0 Mon Sep 17 00:00:00 2001 From: mahula Date: Wed, 13 Jul 2022 15:36:40 +0200 Subject: [PATCH 097/137] Update frontend/src/components/SessionLogoutTimeout.vue Co-authored-by: Moriz Wahl --- frontend/src/components/SessionLogoutTimeout.vue | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/frontend/src/components/SessionLogoutTimeout.vue b/frontend/src/components/SessionLogoutTimeout.vue index 113362abf..f10b8114a 100644 --- a/frontend/src/components/SessionLogoutTimeout.vue +++ b/frontend/src/components/SessionLogoutTimeout.vue @@ -93,8 +93,7 @@ export default { const remainingSecs = Math.floor( (new Date(this.$store.state.tokenTime * 1000).getTime() - this.now) / 1000, ) - if (remainingSecs <= 0) return 0 - return remainingSecs + return remainingSecs <= 0 ? 0 : remainingSecs }, }, beforeDestroy() { 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 098/137] 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 90d90ca9bd9960457aa6a3267e73628d21675519 Mon Sep 17 00:00:00 2001 From: mahula Date: Wed, 13 Jul 2022 19:04:38 +0200 Subject: [PATCH 099/137] fix linting --- frontend/src/components/SessionLogoutTimeout.vue | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/frontend/src/components/SessionLogoutTimeout.vue b/frontend/src/components/SessionLogoutTimeout.vue index f10b8114a..1ebff752a 100644 --- a/frontend/src/components/SessionLogoutTimeout.vue +++ b/frontend/src/components/SessionLogoutTimeout.vue @@ -93,7 +93,7 @@ export default { const remainingSecs = Math.floor( (new Date(this.$store.state.tokenTime * 1000).getTime() - this.now) / 1000, ) - return remainingSecs <= 0 ? 0 : remainingSecs + return remainingSecs <= 0 ? 0 : remainingSecs }, }, beforeDestroy() { From 7c698de325294811d144f6ac7bac058d44200735 Mon Sep 17 00:00:00 2001 From: elweyn Date: Thu, 14 Jul 2022 12:25:45 +0200 Subject: [PATCH 100/137] 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 101/137] 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 102/137] 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 103/137] 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 104/137] 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 105/137] 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 106/137] 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 107/137] 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 108/137] 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 109/137] 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 110/137] 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 111/137] 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 112/137] 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 113/137] 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 114/137] 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 115/137] 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 116/137] 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 117/137] 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 118/137] 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 119/137] 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 120/137] 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 121/137] 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 93c2d6814ad1952105d1fbdc05f94ef174712c10 Mon Sep 17 00:00:00 2001 From: elweyn Date: Mon, 18 Jul 2022 11:27:44 +0200 Subject: [PATCH 122/137] Change the listContribution query to give back ContributionListResult object with linkCount. --- backend/src/graphql/resolver/ContributionResolver.ts | 12 ++++++++---- backend/src/seeds/graphql/queries.ts | 9 ++++++--- 2 files changed, 14 insertions(+), 7 deletions(-) diff --git a/backend/src/graphql/resolver/ContributionResolver.ts b/backend/src/graphql/resolver/ContributionResolver.ts index d71ecac59..c834904d6 100644 --- a/backend/src/graphql/resolver/ContributionResolver.ts +++ b/backend/src/graphql/resolver/ContributionResolver.ts @@ -2,6 +2,7 @@ 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' @@ -39,21 +40,21 @@ export class ContributionResolver { } @Authorized([RIGHTS.LIST_CONTRIBUTIONS]) - @Query(() => [Contribution]) + @Query(() => ContributionListResult) async listContributions( @Args() { currentPage = 1, pageSize = 5, order = Order.DESC }: Paginated, @Arg('filterConfirmed', () => Boolean) filterConfirmed: boolean | null, @Ctx() context: Context, - ): Promise { + ): Promise { const user = getUser(context) const where: { userId: number confirmedBy?: FindOperator | null } = { userId: user.id } if (filterConfirmed) where.confirmedBy = IsNull() - const contributions = await dbContribution.find({ + const [contributions, count] = await dbContribution.findAndCount({ where, order: { createdAt: order, @@ -62,7 +63,10 @@ export class ContributionResolver { skip: (currentPage - 1) * pageSize, take: pageSize, }) - return contributions.map((contribution) => new Contribution(contribution, new User(user))) + return new ContributionListResult( + count, + contributions.map((contribution) => new Contribution(contribution, new User(user))), + ) } @Authorized([RIGHTS.LIST_ALL_CONTRIBUTIONS]) diff --git a/backend/src/seeds/graphql/queries.ts b/backend/src/seeds/graphql/queries.ts index deae5f97b..e18d6b303 100644 --- a/backend/src/seeds/graphql/queries.ts +++ b/backend/src/seeds/graphql/queries.ts @@ -185,9 +185,12 @@ export const listContributions = gql` order: $order filterConfirmed: $filterConfirmed ) { - id - amount - memo + linkCount + linkList { + id + amount + memo + } } } ` From 495fbfd05ce3b16b3d081ed128854d0c32e014eb Mon Sep 17 00:00:00 2001 From: elweyn Date: Mon, 18 Jul 2022 11:31:04 +0200 Subject: [PATCH 123/137] Change linkCount to contributionCount and linkList to contributionList. --- backend/src/graphql/model/Contribution.ts | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/backend/src/graphql/model/Contribution.ts b/backend/src/graphql/model/Contribution.ts index 34bffd6d7..13c2d40d7 100644 --- a/backend/src/graphql/model/Contribution.ts +++ b/backend/src/graphql/model/Contribution.ts @@ -48,13 +48,13 @@ export class Contribution { @ObjectType() export class ContributionListResult { constructor(count: number, list: Contribution[]) { - this.linkCount = count - this.linkList = list + this.contributionCount = count + this.contributionList = list } @Field(() => Int) - linkCount: number + contributionCount: number @Field(() => [Contribution]) - linkList: Contribution[] + contributionList: Contribution[] } From 3a8fb6b353454452e344ae9eef76cfeea51ed8d4 Mon Sep 17 00:00:00 2001 From: elweyn Date: Mon, 18 Jul 2022 11:31:39 +0200 Subject: [PATCH 124/137] Change query of listContribution to get contributionCount and contributionList instead of link... --- backend/src/seeds/graphql/queries.ts | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/backend/src/seeds/graphql/queries.ts b/backend/src/seeds/graphql/queries.ts index e18d6b303..0d72c165d 100644 --- a/backend/src/seeds/graphql/queries.ts +++ b/backend/src/seeds/graphql/queries.ts @@ -185,8 +185,8 @@ export const listContributions = gql` order: $order filterConfirmed: $filterConfirmed ) { - linkCount - linkList { + contributionCount + contributionList { id amount memo From 11dacd40be4c9fec9000253d1898ee536a3eb0c1 Mon Sep 17 00:00:00 2001 From: elweyn Date: Mon, 18 Jul 2022 11:34:30 +0200 Subject: [PATCH 125/137] Change query listAllContributions now gets contributionCount and contributionList instead of linkCount and linkList. --- backend/src/seeds/graphql/queries.ts | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/backend/src/seeds/graphql/queries.ts b/backend/src/seeds/graphql/queries.ts index 0d72c165d..9f7a02e70 100644 --- a/backend/src/seeds/graphql/queries.ts +++ b/backend/src/seeds/graphql/queries.ts @@ -198,8 +198,8 @@ 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 { + contributionCount + contributionList { id firstName lastName 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 126/137] 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 42b8d625da34a908c5c3dd79254141f7bc5ee52f Mon Sep 17 00:00:00 2001 From: elweyn Date: Mon, 18 Jul 2022 11:38:58 +0200 Subject: [PATCH 127/137] Change query fields to new names. --- .../resolver/ContributionResolver.test.ts | 48 +++++++++++-------- 1 file changed, 27 insertions(+), 21 deletions(-) diff --git a/backend/src/graphql/resolver/ContributionResolver.test.ts b/backend/src/graphql/resolver/ContributionResolver.test.ts index e6478ffc2..37ff45f25 100644 --- a/backend/src/graphql/resolver/ContributionResolver.test.ts +++ b/backend/src/graphql/resolver/ContributionResolver.test.ts @@ -193,18 +193,21 @@ describe('ContributionResolver', () => { ).resolves.toEqual( expect.objectContaining({ data: { - listContributions: 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', - }), - ]), + listContributions: { + contributionCount: 2, + contributionList: 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', + }), + ]), + }, }, }), ) @@ -226,13 +229,16 @@ describe('ContributionResolver', () => { ).resolves.toEqual( expect.objectContaining({ data: { - listContributions: expect.arrayContaining([ - expect.objectContaining({ - id: expect.any(Number), - memo: 'Test env contribution', - amount: '100', - }), - ]), + listContributions: { + contributionCount: 1, + contributionList: expect.arrayContaining([ + expect.objectContaining({ + id: expect.any(Number), + memo: 'Test env contribution', + amount: '100', + }), + ]), + }, }, }), ) @@ -496,8 +502,8 @@ describe('ContributionResolver', () => { expect.objectContaining({ data: { listAllContributions: { - linkCount: 2, - linkList: expect.arrayContaining([ + contributionCount: 2, + contributionList: expect.arrayContaining([ expect.objectContaining({ id: expect.any(Number), memo: 'Herzlich Willkommen bei Gradido!', From ae04024dd38b56ed5e702fc7a9e37d183cf76066 Mon Sep 17 00:00:00 2001 From: elweyn Date: Mon, 18 Jul 2022 11:39:17 +0200 Subject: [PATCH 128/137] Remove unused import. --- backend/src/graphql/resolver/ContributionResolver.ts | 1 - 1 file changed, 1 deletion(-) diff --git a/backend/src/graphql/resolver/ContributionResolver.ts b/backend/src/graphql/resolver/ContributionResolver.ts index c834904d6..f21c65068 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' 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 129/137] 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 130/137] 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 131/137] 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 132/137] 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 133/137] 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 1691167582e94a8ee7b77269d9867713ebd4636f Mon Sep 17 00:00:00 2001 From: Moriz Wahl Date: Mon, 18 Jul 2022 23:47:24 +0200 Subject: [PATCH 134/137] explain nginx ports with docker --- README.md | 2 +- frontend/.env.old | 4 ++++ 2 files changed, 5 insertions(+), 1 deletion(-) create mode 100644 frontend/.env.old diff --git a/README.md b/README.md index 145ce4141..3d086018e 100644 --- a/README.md +++ b/README.md @@ -123,7 +123,7 @@ Note: The Changelog will be regenerated with all tags on release on the external ## How the different .env work on deploy -Each component (frontend, admin, backend and database) has its own `.env` file. When running in development you usually do not have to care about the `.env`. The defaults are set by the respective config file, found in the `src/config/` folder of each component. But if you have a local `.env`, the defaults set in the config are overwritten by the `.env`. +Each component (frontend, admin, backend and database) has its own `.env` file. When running in development with docker and nginx you usually do not have to care about the `.env`. The defaults are set by the respective config file, found in the `src/config/` folder of each component. But if you have a local `.env`, the defaults set in the config are overwritten by the `.env`. If you do not use docker, you need the `.env` in the frontend and admin interface because nginx is not running in order to find the backend. Each component has a `.env.dist` file. This file contains all environment variables used by the component and can be used as pattern. If you want to use a local `.env`, copy the `.env.dist` and adjust the variables accordingly. diff --git a/frontend/.env.old b/frontend/.env.old new file mode 100644 index 000000000..a22b31307 --- /dev/null +++ b/frontend/.env.old @@ -0,0 +1,4 @@ +LOGIN_API_URL=http://localhost/login_api/ +COMMUNITY_API_URL=http://localhost/api/ +ALLOW_REGISTER=true +GRAPHQL_URI=http://localhost:4000/graphql 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 135/137] 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 136/137] 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 From b31309f7ef76fb87e4b0ca7d75351d30b73b35ea Mon Sep 17 00:00:00 2001 From: Moriz Wahl Date: Tue, 19 Jul 2022 00:22:47 +0200 Subject: [PATCH 137/137] remove file artifact --- frontend/.env.old | 4 ---- 1 file changed, 4 deletions(-) delete mode 100644 frontend/.env.old diff --git a/frontend/.env.old b/frontend/.env.old deleted file mode 100644 index a22b31307..000000000 --- a/frontend/.env.old +++ /dev/null @@ -1,4 +0,0 @@ -LOGIN_API_URL=http://localhost/login_api/ -COMMUNITY_API_URL=http://localhost/api/ -ALLOW_REGISTER=true -GRAPHQL_URI=http://localhost:4000/graphql