From e49892d69c5af288ebd3c1531e26806a1a43012d Mon Sep 17 00:00:00 2001 From: elweyn Date: Wed, 6 Apr 2022 10:56:27 +0200 Subject: [PATCH 001/106] Changed the value of code so that it get's the configured COMMUNITY_URL and redeem/ from the backend. --- backend/src/graphql/model/TransactionLink.ts | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/backend/src/graphql/model/TransactionLink.ts b/backend/src/graphql/model/TransactionLink.ts index 5081ffd7d..7d91a22ac 100644 --- a/backend/src/graphql/model/TransactionLink.ts +++ b/backend/src/graphql/model/TransactionLink.ts @@ -2,7 +2,7 @@ import { ObjectType, Field, Int } from 'type-graphql' import Decimal from 'decimal.js-light' import { TransactionLink as dbTransactionLink } from '@entity/TransactionLink' import { User } from './User' - +import CONFIG from '@/config' @ObjectType() export class TransactionLink { constructor(transactionLink: dbTransactionLink, user: User, redeemedBy: User | null = null) { @@ -11,7 +11,7 @@ export class TransactionLink { this.amount = transactionLink.amount this.holdAvailableAmount = transactionLink.holdAvailableAmount this.memo = transactionLink.memo - this.code = transactionLink.code + this.code = CONFIG.COMMUNITY_URL + 'redeem/' + transactionLink.code this.createdAt = transactionLink.createdAt this.validUntil = transactionLink.validUntil this.deletedAt = transactionLink.deletedAt From 54f5a0123f66500384ba4d983535fa0c7c603d33 Mon Sep 17 00:00:00 2001 From: elweyn Date: Wed, 6 Apr 2022 11:03:22 +0200 Subject: [PATCH 002/106] Remove the base url from the frontend. --- frontend/src/components/ClipboardCopy.vue | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/frontend/src/components/ClipboardCopy.vue b/frontend/src/components/ClipboardCopy.vue index b952dbd8c..67461cb0f 100644 --- a/frontend/src/components/ClipboardCopy.vue +++ b/frontend/src/components/ClipboardCopy.vue @@ -18,7 +18,7 @@ export default { }, data() { return { - url: `${window.location.origin}/redeem/${this.code}`, + url: `${this.code}`, } }, methods: { From ff24798767d87a7adbbd75a027dbcdb1ed364796 Mon Sep 17 00:00:00 2001 From: elweyn Date: Wed, 6 Apr 2022 11:10:09 +0200 Subject: [PATCH 003/106] Add free line after import. --- backend/src/graphql/model/TransactionLink.ts | 1 + 1 file changed, 1 insertion(+) diff --git a/backend/src/graphql/model/TransactionLink.ts b/backend/src/graphql/model/TransactionLink.ts index 7d91a22ac..f0134470a 100644 --- a/backend/src/graphql/model/TransactionLink.ts +++ b/backend/src/graphql/model/TransactionLink.ts @@ -3,6 +3,7 @@ import Decimal from 'decimal.js-light' import { TransactionLink as dbTransactionLink } from '@entity/TransactionLink' import { User } from './User' import CONFIG from '@/config' + @ObjectType() export class TransactionLink { constructor(transactionLink: dbTransactionLink, user: User, redeemedBy: User | null = null) { From d984ff25827aa84881dc7c74bd0b91fa2fb95e0a Mon Sep 17 00:00:00 2001 From: elweyn Date: Wed, 6 Apr 2022 18:44:19 +0200 Subject: [PATCH 004/106] Add COMMUNITY_REDEEM_LINK to the config. --- backend/.env.dist | 1 + backend/.env.template | 1 + backend/src/config/index.ts | 1 + 3 files changed, 3 insertions(+) diff --git a/backend/.env.dist b/backend/.env.dist index 0a95eda6c..2dc6f2b5f 100644 --- a/backend/.env.dist +++ b/backend/.env.dist @@ -27,6 +27,7 @@ KLICKTIPP_APIKEY_EN=SomeFakeKeyEN COMMUNITY_NAME=Gradido Entwicklung COMMUNITY_URL=http://localhost/ COMMUNITY_REGISTER_URL=http://localhost/register +COMMUNITY_REDEEM_URL=http://localhost/redeem/ COMMUNITY_DESCRIPTION=Die lokale Entwicklungsumgebung von Gradido. # Login Server diff --git a/backend/.env.template b/backend/.env.template index 66cac7a7c..f9a5f3e32 100644 --- a/backend/.env.template +++ b/backend/.env.template @@ -26,6 +26,7 @@ KLICKTIPP_APIKEY_EN=$KLICKTIPP_APIKEY_EN COMMUNITY_NAME=$COMMUNITY_NAME COMMUNITY_URL=$COMMUNITY_URL COMMUNITY_REGISTER_URL=$COMMUNITY_REGISTER_URL +COMMUNITY_REDEEM_URL=$COMMUNITY_REDEEM_URL COMMUNITY_DESCRIPTION=$COMMUNITY_DESCRIPTION # Login Server diff --git a/backend/src/config/index.ts b/backend/src/config/index.ts index 50388d29a..9c6e082c7 100644 --- a/backend/src/config/index.ts +++ b/backend/src/config/index.ts @@ -50,6 +50,7 @@ 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/', COMMUNITY_DESCRIPTION: process.env.COMMUNITY_DESCRIPTION || 'Die lokale Entwicklungsumgebung von Gradido.', } From 41b35f2c5e6674e1c5922d0ac25efa287cfa7693 Mon Sep 17 00:00:00 2001 From: elweyn Date: Wed, 6 Apr 2022 18:45:27 +0200 Subject: [PATCH 005/106] Add link to the TransactionLink and change code by link in frontend. --- backend/src/graphql/model/TransactionLink.ts | 6 +++++- frontend/src/components/ClipboardCopy.vue | 4 ++-- frontend/src/components/GddSend/TransactionResultLink.vue | 4 ++-- .../src/components/TransactionLinks/TransactionLink.vue | 3 ++- frontend/src/graphql/mutations.js | 1 + frontend/src/graphql/queries.js | 1 + frontend/src/pages/Send.vue | 4 +++- 7 files changed, 16 insertions(+), 7 deletions(-) diff --git a/backend/src/graphql/model/TransactionLink.ts b/backend/src/graphql/model/TransactionLink.ts index f0134470a..652545bbd 100644 --- a/backend/src/graphql/model/TransactionLink.ts +++ b/backend/src/graphql/model/TransactionLink.ts @@ -12,12 +12,13 @@ export class TransactionLink { this.amount = transactionLink.amount this.holdAvailableAmount = transactionLink.holdAvailableAmount this.memo = transactionLink.memo - this.code = CONFIG.COMMUNITY_URL + 'redeem/' + transactionLink.code + this.code = transactionLink.code this.createdAt = transactionLink.createdAt this.validUntil = transactionLink.validUntil this.deletedAt = transactionLink.deletedAt this.redeemedAt = transactionLink.redeemedAt this.redeemedBy = redeemedBy + this.link = CONFIG.COMMUNITY_REDEEM_URL + this.code } @Field(() => Number) @@ -52,6 +53,9 @@ export class TransactionLink { @Field(() => User, { nullable: true }) redeemedBy: User | null + + @Field(() => String) + link: string } @ObjectType() diff --git a/frontend/src/components/ClipboardCopy.vue b/frontend/src/components/ClipboardCopy.vue index 67461cb0f..ddc2cde8e 100644 --- a/frontend/src/components/ClipboardCopy.vue +++ b/frontend/src/components/ClipboardCopy.vue @@ -14,11 +14,11 @@ export default { name: 'ClipboardCopy', props: { - code: { type: String, required: true }, + link: { type: String, required: true }, }, data() { return { - url: `${this.code}`, + url: `${this.link}`, } }, methods: { diff --git a/frontend/src/components/GddSend/TransactionResultLink.vue b/frontend/src/components/GddSend/TransactionResultLink.vue index 66b5529d6..79369fc99 100644 --- a/frontend/src/components/GddSend/TransactionResultLink.vue +++ b/frontend/src/components/GddSend/TransactionResultLink.vue @@ -5,7 +5,7 @@
{{ $t('gdd_per_link.created') }}
- +

{{ $t('form.close') }} @@ -24,7 +24,7 @@ export default { ClipboardCopy, }, props: { - code: { + link: { type: String, required: true, }, diff --git a/frontend/src/components/TransactionLinks/TransactionLink.vue b/frontend/src/components/TransactionLinks/TransactionLink.vue index 9cbfdfb93..1c5ad690f 100644 --- a/frontend/src/components/TransactionLinks/TransactionLink.vue +++ b/frontend/src/components/TransactionLinks/TransactionLink.vue @@ -55,6 +55,7 @@ export default { props: { amount: { type: String, required: true }, code: { type: String, required: true }, + link: { type: String, required: true }, holdAvailableAmount: { type: String, required: true }, id: { type: Number, required: true }, memo: { type: String, required: true }, @@ -62,7 +63,7 @@ export default { }, methods: { copy() { - const link = `${window.location.origin}/redeem/${this.code}` + const link = `${this.link}` navigator.clipboard .writeText(link) .then(() => { diff --git a/frontend/src/graphql/mutations.js b/frontend/src/graphql/mutations.js index 3dbd8888e..754d8930a 100644 --- a/frontend/src/graphql/mutations.js +++ b/frontend/src/graphql/mutations.js @@ -76,6 +76,7 @@ export const createTransactionLink = gql` mutation($amount: Decimal!, $memo: String!) { createTransactionLink(amount: $amount, memo: $memo) { code + link } } ` diff --git a/frontend/src/graphql/queries.js b/frontend/src/graphql/queries.js index b8622ef2d..3452694d4 100644 --- a/frontend/src/graphql/queries.js +++ b/frontend/src/graphql/queries.js @@ -155,6 +155,7 @@ export const listTransactionLinks = gql` holdAvailableAmount memo code + link createdAt validUntil redeemedAt diff --git a/frontend/src/pages/Send.vue b/frontend/src/pages/Send.vue index 613342dba..533678a6e 100644 --- a/frontend/src/pages/Send.vue +++ b/frontend/src/pages/Send.vue @@ -41,7 +41,7 @@ >


@@ -88,6 +88,7 @@ export default { currentTransactionStep: TRANSACTION_STEPS.transactionForm, loading: false, code: null, + link: null, } }, props: { @@ -145,6 +146,7 @@ export default { .then((result) => { this.$emit('set-tunneled-email', null) this.code = result.data.createTransactionLink.code + this.link = result.data.createTransactionLink.link this.transactionData = { ...EMPTY_TRANSACTION_DATA } this.currentTransactionStep = TRANSACTION_STEPS.transactionResultLink this.updateTransactions({}) From 2cc7a6dee67e568e88a832b74ab647b08d6f0b34 Mon Sep 17 00:00:00 2001 From: elweyn Date: Wed, 6 Apr 2022 19:16:30 +0200 Subject: [PATCH 006/106] Fixing tests since we now use link and code. --- .../components/DecayInformations/CollapseLinksList.spec.js | 2 ++ .../src/components/TransactionLinks/TransactionLink.spec.js | 1 + .../components/Transactions/TransactionLinkSummary.spec.js | 4 ++++ frontend/src/pages/Send.spec.js | 2 +- 4 files changed, 8 insertions(+), 1 deletion(-) diff --git a/frontend/src/components/DecayInformations/CollapseLinksList.spec.js b/frontend/src/components/DecayInformations/CollapseLinksList.spec.js index b533c6aa1..b288f78d0 100644 --- a/frontend/src/components/DecayInformations/CollapseLinksList.spec.js +++ b/frontend/src/components/DecayInformations/CollapseLinksList.spec.js @@ -16,6 +16,7 @@ const propsData = { { amount: '5', code: 'ce28664b5308c17f931c0367', + link: 'http://localhost/redeem/ce28664b5308c17f931c0367', createdAt: '2022-03-16T14:22:40.000Z', holdAvailableAmount: '5.13109484759482747111', id: 87, @@ -26,6 +27,7 @@ const propsData = { { amount: '6', code: 'ce28664b5308c17f931c0367', + link: 'http://localhost/redeem/ce28664b5308c17f931c0367', createdAt: '2022-03-16T14:22:40.000Z', holdAvailableAmount: '5.13109484759482747111', id: 86, diff --git a/frontend/src/components/TransactionLinks/TransactionLink.spec.js b/frontend/src/components/TransactionLinks/TransactionLink.spec.js index f019a0ee1..8e455360b 100644 --- a/frontend/src/components/TransactionLinks/TransactionLink.spec.js +++ b/frontend/src/components/TransactionLinks/TransactionLink.spec.js @@ -22,6 +22,7 @@ const mocks = { const propsData = { amount: '75', code: 'c00000000c000000c0000', + link: 'http://localhost/redeem/c00000000c000000c0000', holdAvailableAmount: '5.13109484759482747111', id: 12, memo: 'Wie schön hier etwas Quatsch zu lesen!', diff --git a/frontend/src/components/Transactions/TransactionLinkSummary.spec.js b/frontend/src/components/Transactions/TransactionLinkSummary.spec.js index 1f2a4388c..7dfd0d41b 100644 --- a/frontend/src/components/Transactions/TransactionLinkSummary.spec.js +++ b/frontend/src/components/Transactions/TransactionLinkSummary.spec.js @@ -44,6 +44,7 @@ describe('TransactionLinkSummary', () => { { amount: '75', code: 'ce28664b5308c17f931c0367', + link: 'http://localhost/redeem/ce28664b5308c17f931c0367', createdAt: '2022-03-16T14:22:40.000Z', holdAvailableAmount: '5.13109484759482747111', id: 86, @@ -55,6 +56,7 @@ describe('TransactionLinkSummary', () => { { amount: '85', code: 'ce28664b5308c17f931c0367', + link: 'http://localhost/redeem/ce28664b5308c17f931c0367', createdAt: '2022-03-16T14:22:40.000Z', holdAvailableAmount: '5.13109484759482747111', id: 107, @@ -65,6 +67,7 @@ describe('TransactionLinkSummary', () => { { amount: '95', code: 'ce28664b5308c17f931c0367', + link: 'http://localhost/redeem/ce28664b5308c17f931c0367', createdAt: '2022-03-16T14:22:40.000Z', holdAvailableAmount: '5.13109484759482747111', id: 92, @@ -76,6 +79,7 @@ describe('TransactionLinkSummary', () => { { amount: '150', code: 'ce28664b5308c17f931c0367', + link: 'http://localhost/redeem/ce28664b5308c17f931c0367', createdAt: '2022-03-16T14:22:40.000Z', holdAvailableAmount: '5.13109484759482747111', id: 16, diff --git a/frontend/src/pages/Send.spec.js b/frontend/src/pages/Send.spec.js index 447fdde33..148d62168 100644 --- a/frontend/src/pages/Send.spec.js +++ b/frontend/src/pages/Send.spec.js @@ -162,7 +162,7 @@ describe('Send', () => { describe('transaction form link', () => { beforeEach(async () => { apolloMutationMock.mockResolvedValue({ - data: { createTransactionLink: { code: '0123456789' } }, + data: { createTransactionLink: { code: '0123456789', link: 'http://localhost/redeem/0123456789' } }, }) const transactionForm = wrapper.findComponent({ name: 'TransactionForm' }) await transactionForm.findAll('input[type="radio"]').at(1).setChecked() From f6b9b7664cb8071d02525340ea6b2e6bcecd1c3e Mon Sep 17 00:00:00 2001 From: elweyn Date: Thu, 7 Apr 2022 11:00:29 +0200 Subject: [PATCH 007/106] Add link to mocked return value. --- .../components/Transactions/TransactionLinkSummary.spec.js | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/frontend/src/components/Transactions/TransactionLinkSummary.spec.js b/frontend/src/components/Transactions/TransactionLinkSummary.spec.js index 7dfd0d41b..1d3d70527 100644 --- a/frontend/src/components/Transactions/TransactionLinkSummary.spec.js +++ b/frontend/src/components/Transactions/TransactionLinkSummary.spec.js @@ -155,6 +155,7 @@ describe('TransactionLinkSummary', () => { { amount: '76', code: 'ce28664b5308c17f931c0367', + link: 'http://localhost/redeem/ce28664b5308c17f931c0367', createdAt: '2022-03-16T14:22:40.000Z', holdAvailableAmount: '5.13109484759482747111', id: 87, @@ -166,6 +167,7 @@ describe('TransactionLinkSummary', () => { { amount: '86', code: 'ce28664b5308c17f931c0367', + link: 'http://localhost/redeem/ce28664b5308c17f931c0367', createdAt: '2022-03-16T14:22:40.000Z', holdAvailableAmount: '5.13109484759482747111', id: 108, @@ -177,6 +179,7 @@ describe('TransactionLinkSummary', () => { { amount: '96', code: 'ce28664b5308c17f931c0367', + link: 'http://localhost/redeem/ce28664b5308c17f931c0367', createdAt: '2022-03-16T14:22:40.000Z', holdAvailableAmount: '5.13109484759482747111', id: 93, @@ -188,6 +191,7 @@ describe('TransactionLinkSummary', () => { { amount: '150', code: 'ce28664b5308c17f931c0367', + link: 'http://localhost/redeem/ce28664b5308c17f931c0367', createdAt: '2022-03-16T14:22:40.000Z', holdAvailableAmount: '5.13109484759482747111', id: 17, From 2f2c00605f50e6bd192ef79208004fb6075f1275 Mon Sep 17 00:00:00 2001 From: elweyn Date: Fri, 8 Apr 2022 08:14:12 +0200 Subject: [PATCH 008/106] Change the config parameter community_redeem_url to a regex. --- backend/.env.dist | 2 +- backend/src/config/index.ts | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/backend/.env.dist b/backend/.env.dist index 2dc6f2b5f..929263107 100644 --- a/backend/.env.dist +++ b/backend/.env.dist @@ -27,7 +27,7 @@ KLICKTIPP_APIKEY_EN=SomeFakeKeyEN COMMUNITY_NAME=Gradido Entwicklung COMMUNITY_URL=http://localhost/ COMMUNITY_REGISTER_URL=http://localhost/register -COMMUNITY_REDEEM_URL=http://localhost/redeem/ +COMMUNITY_REDEEM_URL=http://localhost/redeem/{code} COMMUNITY_DESCRIPTION=Die lokale Entwicklungsumgebung von Gradido. # Login Server diff --git a/backend/src/config/index.ts b/backend/src/config/index.ts index 9c6e082c7..d0b693ad7 100644 --- a/backend/src/config/index.ts +++ b/backend/src/config/index.ts @@ -50,7 +50,7 @@ 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/', + COMMUNITY_REDEEM_URL: process.env.COMMUNITY_REDEEM_URL || 'http://localhost/redeem/{code}', COMMUNITY_DESCRIPTION: process.env.COMMUNITY_DESCRIPTION || 'Die lokale Entwicklungsumgebung von Gradido.', } From 6588a636dd39be354d78106698ece09334b45a4d Mon Sep 17 00:00:00 2001 From: elweyn Date: Fri, 8 Apr 2022 08:14:50 +0200 Subject: [PATCH 009/106] Change the composition of the link from addition to replace. --- backend/src/graphql/model/TransactionLink.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/backend/src/graphql/model/TransactionLink.ts b/backend/src/graphql/model/TransactionLink.ts index 652545bbd..18a601948 100644 --- a/backend/src/graphql/model/TransactionLink.ts +++ b/backend/src/graphql/model/TransactionLink.ts @@ -18,7 +18,7 @@ export class TransactionLink { this.deletedAt = transactionLink.deletedAt this.redeemedAt = transactionLink.redeemedAt this.redeemedBy = redeemedBy - this.link = CONFIG.COMMUNITY_REDEEM_URL + this.code + this.link = CONFIG.COMMUNITY_REDEEM_URL.replace(/{code}/g, this.code) } @Field(() => Number) From de7891f492abda1d7ca77bd451533315d7d3f242 Mon Sep 17 00:00:00 2001 From: elweyn Date: Fri, 8 Apr 2022 08:16:20 +0200 Subject: [PATCH 010/106] Fix linting. --- frontend/src/pages/Send.spec.js | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) diff --git a/frontend/src/pages/Send.spec.js b/frontend/src/pages/Send.spec.js index 148d62168..76757a247 100644 --- a/frontend/src/pages/Send.spec.js +++ b/frontend/src/pages/Send.spec.js @@ -162,7 +162,12 @@ describe('Send', () => { describe('transaction form link', () => { beforeEach(async () => { apolloMutationMock.mockResolvedValue({ - data: { createTransactionLink: { code: '0123456789', link: 'http://localhost/redeem/0123456789' } }, + data: { + createTransactionLink: { + code: '0123456789', + link: 'http://localhost/redeem/0123456789', + }, + }, }) const transactionForm = wrapper.findComponent({ name: 'TransactionForm' }) await transactionForm.findAll('input[type="radio"]').at(1).setChecked() From deb1d457e1a2f60815d713cfb5c7bf76cf843881 Mon Sep 17 00:00:00 2001 From: Moriz Wahl Date: Wed, 20 Apr 2022 10:32:33 +0200 Subject: [PATCH 011/106] migration adds is_admin column to users --- database/migrations/0034-drop_server_user_table.ts | 13 +++++++++++++ 1 file changed, 13 insertions(+) create mode 100644 database/migrations/0034-drop_server_user_table.ts diff --git a/database/migrations/0034-drop_server_user_table.ts b/database/migrations/0034-drop_server_user_table.ts new file mode 100644 index 000000000..2e0a789ac --- /dev/null +++ b/database/migrations/0034-drop_server_user_table.ts @@ -0,0 +1,13 @@ +/* MIGRATION DROP server_users TABLE +add isAdmin COLUMN to users TABLE */ + +/* eslint-disable @typescript-eslint/explicit-module-boundary-types */ +/* eslint-disable @typescript-eslint/no-explicit-any */ + +export async function upgrade(queryFn: (query: string, values?: any[]) => Promise>) { + await queryFn('ALTER TABLE `users` ADD COLUMN `is_admin` boolean DEFAULT false AFTER `language`;') +} + +export async function downgrade(queryFn: (query: string, values?: any[]) => Promise>) { + await queryFn('ALTER TABLE `users` DROP COLUMN `is_admin`;') +} From 58ab92ff63ba88071a02aaf807eff54044f096a1 Mon Sep 17 00:00:00 2001 From: Moriz Wahl Date: Wed, 20 Apr 2022 11:11:40 +0200 Subject: [PATCH 012/106] drop server users --- .../migrations/0034-drop_server_user_table.ts | 24 +++++++++++++++++++ 1 file changed, 24 insertions(+) diff --git a/database/migrations/0034-drop_server_user_table.ts b/database/migrations/0034-drop_server_user_table.ts index 2e0a789ac..914c75457 100644 --- a/database/migrations/0034-drop_server_user_table.ts +++ b/database/migrations/0034-drop_server_user_table.ts @@ -6,8 +6,32 @@ add isAdmin COLUMN to users TABLE */ export async function upgrade(queryFn: (query: string, values?: any[]) => Promise>) { await queryFn('ALTER TABLE `users` ADD COLUMN `is_admin` boolean DEFAULT false AFTER `language`;') + + await queryFn( + 'UPDATE `users` SET `is_admin` = true WHERE `email` IN (SELECT `email` FROM `server_users`);', + ) + + await queryFn('DROP TABLE `server_users`;') } export async function downgrade(queryFn: (query: string, values?: any[]) => Promise>) { + await queryFn(` + CREATE TABLE IF NOT EXISTS \`server_users\` ( + \`id\` int(10) unsigned NOT NULL AUTO_INCREMENT, + \`username\` varchar(50) COLLATE utf8mb4_unicode_ci NOT NULL, + \`password\` varchar(255) COLLATE utf8mb4_unicode_ci NOT NULL, + \`email\` varchar(50) COLLATE utf8mb4_unicode_ci NOT NULL, + \`role\` varchar(20) COLLATE utf8mb4_unicode_ci NOT NULL DEFAULT 'admin', + \`activated\` tinyint(4) NOT NULL DEFAULT '0', + \`last_login\` datetime DEFAULT NULL, + \`created\` datetime NOT NULL, + \`modified\` datetime NOT NULL, + PRIMARY KEY (\`id\`) + ) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_ci;`) + + await queryFn( + 'INSERT INTO `server_users` (`email`, `username`, `password`, `created`, `modified`) SELECT `email`, `first_name`, `password`, `created`, `created` FROM `users` WHERE `is_admin` = true;', + ) + await queryFn('ALTER TABLE `users` DROP COLUMN `is_admin`;') } From ca4a92d321d804dda4c8c4a79b0bea716616ff1b Mon Sep 17 00:00:00 2001 From: Moriz Wahl Date: Wed, 20 Apr 2022 11:19:02 +0200 Subject: [PATCH 013/106] add isAdmin entity to user db model --- .../0034-drop_server_user_table/User.ts | 81 +++++++++++++++++++ database/entity/User.ts | 2 +- 2 files changed, 82 insertions(+), 1 deletion(-) create mode 100644 database/entity/0034-drop_server_user_table/User.ts diff --git a/database/entity/0034-drop_server_user_table/User.ts b/database/entity/0034-drop_server_user_table/User.ts new file mode 100644 index 000000000..9192b92ff --- /dev/null +++ b/database/entity/0034-drop_server_user_table/User.ts @@ -0,0 +1,81 @@ +import { + BaseEntity, + Entity, + PrimaryGeneratedColumn, + Column, + OneToMany, + DeleteDateColumn, +} from 'typeorm' +import { UserSetting } from '../UserSetting' + +@Entity('users', { engine: 'InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_ci' }) +export class User extends BaseEntity { + @PrimaryGeneratedColumn('increment', { unsigned: true }) + id: number + + @Column({ name: 'public_key', type: 'binary', length: 32, default: null, nullable: true }) + pubKey: Buffer + + @Column({ name: 'privkey', type: 'binary', length: 80, default: null, nullable: true }) + privKey: Buffer + + @Column({ length: 255, unique: true, nullable: false, collation: 'utf8mb4_unicode_ci' }) + email: string + + @Column({ + name: 'first_name', + length: 255, + nullable: true, + default: null, + collation: 'utf8mb4_unicode_ci', + }) + firstName: string + + @Column({ + name: 'last_name', + length: 255, + nullable: true, + default: null, + collation: 'utf8mb4_unicode_ci', + }) + lastName: string + + @DeleteDateColumn() + deletedAt: Date | null + + @Column({ type: 'bigint', default: 0, unsigned: true }) + password: BigInt + + @Column({ name: 'email_hash', type: 'binary', length: 32, default: null, nullable: true }) + emailHash: Buffer + + @Column({ name: 'created', default: () => 'CURRENT_TIMESTAMP', nullable: false }) + createdAt: Date + + @Column({ name: 'email_checked', type: 'bool', nullable: false, default: false }) + emailChecked: boolean + + @Column({ length: 4, default: 'de', collation: 'utf8mb4_unicode_ci', nullable: false }) + language: string + + @Column({ name: 'is_admin', type: 'bool', nullable: false, default: false }) + isAdmin: boolean + + @Column({ name: 'referrer_id', type: 'int', unsigned: true, nullable: true, default: null }) + referrerId?: number | null + + @Column({ name: 'publisher_id', default: 0 }) + publisherId: number + + @Column({ + type: 'text', + name: 'passphrase', + collation: 'utf8mb4_unicode_ci', + nullable: true, + default: null, + }) + passphrase: string + + @OneToMany(() => UserSetting, (userSetting) => userSetting.user) + settings: UserSetting[] +} diff --git a/database/entity/User.ts b/database/entity/User.ts index 35dfb7bbe..4cd68174c 100644 --- a/database/entity/User.ts +++ b/database/entity/User.ts @@ -1 +1 @@ -export { User } from './0033-add_referrer_id/User' +export { User } from './0034-drop_server_user_table/User' From 5c6aa5d4ce715911dd60128ac6448b4c807e9c6e Mon Sep 17 00:00:00 2001 From: Moriz Wahl Date: Wed, 20 Apr 2022 11:20:28 +0200 Subject: [PATCH 014/106] new db version for isAdmin in user db model --- backend/src/config/index.ts | 2 +- backend/src/util/communityUser.ts | 1 + 2 files changed, 2 insertions(+), 1 deletion(-) diff --git a/backend/src/config/index.ts b/backend/src/config/index.ts index 91f450369..4bf550038 100644 --- a/backend/src/config/index.ts +++ b/backend/src/config/index.ts @@ -10,7 +10,7 @@ Decimal.set({ }) const constants = { - DB_VERSION: '0033-add_referrer_id', + DB_VERSION: '0034-drop_server_user_table', DECAY_START_TIME: new Date('2021-05-13 17:46:31'), // GMT+0 CONFIG_VERSION: { DEFAULT: 'DEFAULT', diff --git a/backend/src/util/communityUser.ts b/backend/src/util/communityUser.ts index 33ac2fad2..8b75b37a1 100644 --- a/backend/src/util/communityUser.ts +++ b/backend/src/util/communityUser.ts @@ -17,6 +17,7 @@ const communityDbUser: dbUser = { createdAt: new Date(), emailChecked: false, language: '', + isAdmin: false, publisherId: 0, passphrase: '', settings: [], From 64859a71f44457afc97b31f2fbe225451dedb90b Mon Sep 17 00:00:00 2001 From: Moriz Wahl Date: Wed, 20 Apr 2022 11:27:09 +0200 Subject: [PATCH 015/106] use isAdmin on user to determine if user is admin --- backend/src/graphql/model/User.ts | 8 ++++---- backend/src/graphql/resolver/UserResolver.ts | 10 ---------- 2 files changed, 4 insertions(+), 14 deletions(-) diff --git a/backend/src/graphql/model/User.ts b/backend/src/graphql/model/User.ts index 1a187a38f..1949592c0 100644 --- a/backend/src/graphql/model/User.ts +++ b/backend/src/graphql/model/User.ts @@ -14,8 +14,8 @@ export class User { this.emailChecked = user.emailChecked this.language = user.language this.publisherId = user.publisherId + this.isAdmin = user.isAdmin // TODO - this.isAdmin = null this.coinanimation = null this.klickTipp = null this.hasElopage = null @@ -58,11 +58,11 @@ export class User { // `passphrase` text COLLATE utf8mb4_unicode_ci DEFAULT NULL, + @Field(() => Boolean) + isAdmin: boolean + // TODO this is a bit inconsistent with what we query from the database // therefore all those fields are now nullable with default value null - @Field(() => Boolean, { nullable: true }) - isAdmin: boolean | null - @Field(() => Boolean, { nullable: true }) coinanimation: boolean | null diff --git a/backend/src/graphql/resolver/UserResolver.ts b/backend/src/graphql/resolver/UserResolver.ts index 137c09622..7685268b4 100644 --- a/backend/src/graphql/resolver/UserResolver.ts +++ b/backend/src/graphql/resolver/UserResolver.ts @@ -19,9 +19,7 @@ import { sendResetPasswordEmail as sendResetPasswordEmailMailer } from '@/mailer import { sendAccountActivationEmail } from '@/mailer/sendAccountActivationEmail' import { klicktippSignIn } from '@/apis/KlicktippController' import { RIGHTS } from '@/auth/RIGHTS' -import { ROLE_ADMIN } from '@/auth/ROLES' import { hasElopageBuys } from '@/util/hasElopageBuys' -import { ServerUser } from '@entity/ServerUser' // eslint-disable-next-line @typescript-eslint/no-var-requires const sodium = require('sodium-native') @@ -207,7 +205,6 @@ export class UserResolver { }) user.coinanimation = coinanimation - user.isAdmin = context.role === ROLE_ADMIN return user } @@ -243,9 +240,6 @@ export class UserResolver { } const user = new User(dbUser) - // user.email = email - // user.pubkey = dbUser.pubKey.toString('hex') - user.language = dbUser.language // Elopage Status & Stored PublisherId user.hasElopage = await this.hasElopage({ ...context, user: dbUser }) @@ -266,10 +260,6 @@ export class UserResolver { }) user.coinanimation = coinanimation - // context.role is not set to the actual role yet on login - const countServerUsers = await ServerUser.count({ email: user.email }) - user.isAdmin = countServerUsers > 0 - context.setHeaders.push({ key: 'token', value: encode(dbUser.pubKey), From 8ca72beac8cdbd5ebf112f90d09652e398ad41c5 Mon Sep 17 00:00:00 2001 From: Moriz Wahl Date: Wed, 20 Apr 2022 11:30:29 +0200 Subject: [PATCH 016/106] use isAdmin of user to determine user role --- backend/src/graphql/directive/isAuthorized.ts | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) diff --git a/backend/src/graphql/directive/isAuthorized.ts b/backend/src/graphql/directive/isAuthorized.ts index 84756c45a..065c01957 100644 --- a/backend/src/graphql/directive/isAuthorized.ts +++ b/backend/src/graphql/directive/isAuthorized.ts @@ -8,7 +8,6 @@ import { RIGHTS } from '@/auth/RIGHTS' import { getCustomRepository } from '@dbTools/typeorm' import { UserRepository } from '@repository/User' import { INALIENABLE_RIGHTS } from '@/auth/INALIENABLE_RIGHTS' -import { ServerUser } from '@entity/ServerUser' const isAuthorized: AuthChecker = async ({ context }, rights) => { context.role = ROLE_UNAUTHORIZED // unauthorized user @@ -36,8 +35,7 @@ const isAuthorized: AuthChecker = async ({ context }, rights) => { try { const user = await userRepository.findByPubkeyHex(context.pubKey) context.user = user - const countServerUsers = await ServerUser.count({ email: user.email }) - context.role = countServerUsers > 0 ? ROLE_ADMIN : ROLE_USER + context.role = user.isAdmin ? ROLE_ADMIN : ROLE_USER } catch { // in case the database query fails (user deleted) throw new Error('401 Unauthorized') From 9136c4596dad00460523b789718ede5871fa80ab Mon Sep 17 00:00:00 2001 From: Moriz Wahl Date: Wed, 20 Apr 2022 11:32:30 +0200 Subject: [PATCH 017/106] remove server user entity --- database/entity/ServerUser.ts | 1 - database/entity/index.ts | 2 -- 2 files changed, 3 deletions(-) delete mode 100644 database/entity/ServerUser.ts diff --git a/database/entity/ServerUser.ts b/database/entity/ServerUser.ts deleted file mode 100644 index 495513823..000000000 --- a/database/entity/ServerUser.ts +++ /dev/null @@ -1 +0,0 @@ -export { ServerUser } from './0001-init_db/ServerUser' diff --git a/database/entity/index.ts b/database/entity/index.ts index cb6f56ab0..542333755 100644 --- a/database/entity/index.ts +++ b/database/entity/index.ts @@ -1,7 +1,6 @@ import { LoginElopageBuys } from './LoginElopageBuys' import { LoginEmailOptIn } from './LoginEmailOptIn' import { Migration } from './Migration' -import { ServerUser } from './ServerUser' import { Transaction } from './Transaction' import { TransactionLink } from './TransactionLink' import { User } from './User' @@ -13,7 +12,6 @@ export const entities = [ LoginElopageBuys, LoginEmailOptIn, Migration, - ServerUser, Transaction, TransactionLink, User, From c9701574f38cf28d3ad26a3a37b02dd0bafa82df Mon Sep 17 00:00:00 2001 From: Moriz Wahl Date: Wed, 20 Apr 2022 11:44:34 +0200 Subject: [PATCH 018/106] seed with isAdmin, test user resolver with isAdmin --- .../src/graphql/resolver/UserResolver.test.ts | 1 + backend/src/seeds/factory/user.ts | 23 ++++--------------- 2 files changed, 5 insertions(+), 19 deletions(-) diff --git a/backend/src/graphql/resolver/UserResolver.test.ts b/backend/src/graphql/resolver/UserResolver.test.ts index 07b8e59e2..b9e230afe 100644 --- a/backend/src/graphql/resolver/UserResolver.test.ts +++ b/backend/src/graphql/resolver/UserResolver.test.ts @@ -100,6 +100,7 @@ describe('UserResolver', () => { emailChecked: false, passphrase: expect.any(String), language: 'de', + isAdmin: false, deletedAt: null, publisherId: 1234, referrerId: null, diff --git a/backend/src/seeds/factory/user.ts b/backend/src/seeds/factory/user.ts index ff4c1d6c9..373a3da4f 100644 --- a/backend/src/seeds/factory/user.ts +++ b/backend/src/seeds/factory/user.ts @@ -1,7 +1,6 @@ import { createUser, setPassword } from '@/seeds/graphql/mutations' import { User } from '@entity/User' import { LoginEmailOptIn } from '@entity/LoginEmailOptIn' -import { ServerUser } from '@entity/ServerUser' import { UserInterface } from '@/seeds/users/UserInterface' import { ApolloServerTestClient } from 'apollo-server-testing' @@ -29,23 +28,9 @@ export const userFactory = async ( // get user from database const dbUser = await User.findOneOrFail({ id }) - if (user.createdAt || user.deletedAt) { - if (user.createdAt) dbUser.createdAt = user.createdAt - if (user.deletedAt) dbUser.deletedAt = user.deletedAt - await dbUser.save() - } - - if (user.isAdmin) { - const admin = new ServerUser() - admin.username = dbUser.firstName - admin.password = 'please_refactor' - admin.email = dbUser.email - admin.role = 'admin' - admin.activated = 1 - admin.lastLogin = new Date() - admin.created = dbUser.createdAt - admin.modified = dbUser.createdAt - await admin.save() - } + if (user.createdAt) dbUser.createdAt = user.createdAt + if (user.deletedAt) dbUser.deletedAt = user.deletedAt + if (user.isAdmin) dbUser.isAdmin = user.isAdmin + await dbUser.save() } } From 863ecfa4746c4f4f3a0bf5127119e0cce7251520 Mon Sep 17 00:00:00 2001 From: Moriz Wahl Date: Thu, 21 Apr 2022 10:58:22 +0200 Subject: [PATCH 019/106] migrate is_admin column in users as datetime with default null --- database/migrations/0034-drop_server_user_table.ts | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/database/migrations/0034-drop_server_user_table.ts b/database/migrations/0034-drop_server_user_table.ts index 914c75457..fd5a9a682 100644 --- a/database/migrations/0034-drop_server_user_table.ts +++ b/database/migrations/0034-drop_server_user_table.ts @@ -5,10 +5,10 @@ add isAdmin COLUMN to users TABLE */ /* eslint-disable @typescript-eslint/no-explicit-any */ export async function upgrade(queryFn: (query: string, values?: any[]) => Promise>) { - await queryFn('ALTER TABLE `users` ADD COLUMN `is_admin` boolean DEFAULT false AFTER `language`;') + await queryFn('ALTER TABLE `users` ADD COLUMN `is_admin` datetime DEFAULT NULL AFTER `language`;') await queryFn( - 'UPDATE `users` SET `is_admin` = true WHERE `email` IN (SELECT `email` FROM `server_users`);', + 'UPDATE `users` AS `users`, (SELECT * FROM `server_users`) AS `server_users` SET users.`is_admin` = server_users.`modified` WHERE users.`email` IN (SELECT email from `server_users`);', ) await queryFn('DROP TABLE `server_users`;') @@ -30,7 +30,7 @@ export async function downgrade(queryFn: (query: string, values?: any[]) => Prom ) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_ci;`) await queryFn( - 'INSERT INTO `server_users` (`email`, `username`, `password`, `created`, `modified`) SELECT `email`, `first_name`, `password`, `created`, `created` FROM `users` WHERE `is_admin` = true;', + 'INSERT INTO `server_users` (`email`, `username`, `password`, `created`, `modified`) SELECT `email`, `first_name`, `password`, `is_admin`, `is_admin` FROM `users` WHERE `is_admin` IS NOT NULL;', ) await queryFn('ALTER TABLE `users` DROP COLUMN `is_admin`;') From ba648c67a98dd31c1bf07f494ae47529399a7364 Mon Sep 17 00:00:00 2001 From: Moriz Wahl Date: Thu, 21 Apr 2022 11:01:23 +0200 Subject: [PATCH 020/106] entity model users.isAdmin as nullable date --- database/entity/0034-drop_server_user_table/User.ts | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/database/entity/0034-drop_server_user_table/User.ts b/database/entity/0034-drop_server_user_table/User.ts index 9192b92ff..1f56d13d2 100644 --- a/database/entity/0034-drop_server_user_table/User.ts +++ b/database/entity/0034-drop_server_user_table/User.ts @@ -58,8 +58,8 @@ export class User extends BaseEntity { @Column({ length: 4, default: 'de', collation: 'utf8mb4_unicode_ci', nullable: false }) language: string - @Column({ name: 'is_admin', type: 'bool', nullable: false, default: false }) - isAdmin: boolean + @Column({ name: 'is_admin', type: 'datetime', nullable: true, default: null }) + isAdmin: Date | null @Column({ name: 'referrer_id', type: 'int', unsigned: true, nullable: true, default: null }) referrerId?: number | null From fa6fbe38c8e0ba1b44592146602cfb3938d9242d Mon Sep 17 00:00:00 2001 From: Moriz Wahl Date: Thu, 21 Apr 2022 11:05:51 +0200 Subject: [PATCH 021/106] User.isAdmin as nullable Date --- backend/src/graphql/model/User.ts | 4 ++-- backend/src/seeds/factory/user.ts | 2 +- backend/src/util/communityUser.ts | 2 +- 3 files changed, 4 insertions(+), 4 deletions(-) diff --git a/backend/src/graphql/model/User.ts b/backend/src/graphql/model/User.ts index 1949592c0..4f577f60a 100644 --- a/backend/src/graphql/model/User.ts +++ b/backend/src/graphql/model/User.ts @@ -58,8 +58,8 @@ export class User { // `passphrase` text COLLATE utf8mb4_unicode_ci DEFAULT NULL, - @Field(() => Boolean) - isAdmin: boolean + @Field(() => Date, { nullable: true }) + isAdmin: Date | null // TODO this is a bit inconsistent with what we query from the database // therefore all those fields are now nullable with default value null diff --git a/backend/src/seeds/factory/user.ts b/backend/src/seeds/factory/user.ts index 373a3da4f..4b5913d48 100644 --- a/backend/src/seeds/factory/user.ts +++ b/backend/src/seeds/factory/user.ts @@ -30,7 +30,7 @@ export const userFactory = async ( if (user.createdAt) dbUser.createdAt = user.createdAt if (user.deletedAt) dbUser.deletedAt = user.deletedAt - if (user.isAdmin) dbUser.isAdmin = user.isAdmin + if (user.isAdmin) dbUser.isAdmin = new Date() await dbUser.save() } } diff --git a/backend/src/util/communityUser.ts b/backend/src/util/communityUser.ts index 8b75b37a1..0d0d12f6c 100644 --- a/backend/src/util/communityUser.ts +++ b/backend/src/util/communityUser.ts @@ -17,7 +17,7 @@ const communityDbUser: dbUser = { createdAt: new Date(), emailChecked: false, language: '', - isAdmin: false, + isAdmin: null, publisherId: 0, passphrase: '', settings: [], From 50bddf49e4a1de785e5e413999c6c69186de2d84 Mon Sep 17 00:00:00 2001 From: Moriz Wahl Date: Thu, 21 Apr 2022 11:16:14 +0200 Subject: [PATCH 022/106] fix test for User.isAdmin as nullable date --- backend/src/graphql/resolver/UserResolver.test.ts | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/backend/src/graphql/resolver/UserResolver.test.ts b/backend/src/graphql/resolver/UserResolver.test.ts index b9e230afe..8e5cb299d 100644 --- a/backend/src/graphql/resolver/UserResolver.test.ts +++ b/backend/src/graphql/resolver/UserResolver.test.ts @@ -100,7 +100,7 @@ describe('UserResolver', () => { emailChecked: false, passphrase: expect.any(String), language: 'de', - isAdmin: false, + isAdmin: null, deletedAt: null, publisherId: 1234, referrerId: null, @@ -337,7 +337,7 @@ describe('UserResolver', () => { firstName: 'Bibi', hasElopage: false, id: expect.any(Number), - isAdmin: false, + isAdmin: null, klickTipp: { newsletterState: false, }, From 00e03af7f31090f339903047d1c1efcac6a57490 Mon Sep 17 00:00:00 2001 From: Ulf Gebhardt Date: Thu, 21 Apr 2022 13:19:01 +0200 Subject: [PATCH 023/106] increase backend config version v6 --- backend/.env.dist | 2 +- backend/src/config/index.ts | 2 +- deployment/bare_metal/.env.dist | 2 +- 3 files changed, 3 insertions(+), 3 deletions(-) diff --git a/backend/.env.dist b/backend/.env.dist index f4a17e81a..de33a7272 100644 --- a/backend/.env.dist +++ b/backend/.env.dist @@ -1,4 +1,4 @@ -CONFIG_VERSION=v5.2022-04-12 +CONFIG_VERSION=v6.2022-04-21 # Server PORT=4000 diff --git a/backend/src/config/index.ts b/backend/src/config/index.ts index 0cd0f408d..86cefe9e6 100644 --- a/backend/src/config/index.ts +++ b/backend/src/config/index.ts @@ -14,7 +14,7 @@ const constants = { DECAY_START_TIME: new Date('2021-05-13 17:46:31'), // GMT+0 CONFIG_VERSION: { DEFAULT: 'DEFAULT', - EXPECTED: 'v5.2022-04-12', + EXPECTED: 'v6.2022-04-21', CURRENT: '', }, } diff --git a/deployment/bare_metal/.env.dist b/deployment/bare_metal/.env.dist index efac0fc68..316fb60c2 100644 --- a/deployment/bare_metal/.env.dist +++ b/deployment/bare_metal/.env.dist @@ -24,7 +24,7 @@ COMMUNITY_REGISTER_URL=https://stage1.gradido.net/register COMMUNITY_DESCRIPTION="Gradido Development Stage1 Test Community" # backend -BACKEND_CONFIG_VERSION=v5.2022-04-12 +BACKEND_CONFIG_VERSION=v6.2022-04-21 JWT_EXPIRES_IN=30m GDT_API_URL=https://gdt.gradido.net From f9efc3fa06fdae058880d80dcc89d17ef661bbef Mon Sep 17 00:00:00 2001 From: Ulf Gebhardt Date: Thu, 21 Apr 2022 13:22:52 +0200 Subject: [PATCH 024/106] use link instead of url, do not use v-model, use value to not allow mutate prop --- frontend/src/components/ClipboardCopy.vue | 9 ++------- 1 file changed, 2 insertions(+), 7 deletions(-) diff --git a/frontend/src/components/ClipboardCopy.vue b/frontend/src/components/ClipboardCopy.vue index ddc2cde8e..ff8a3ae87 100644 --- a/frontend/src/components/ClipboardCopy.vue +++ b/frontend/src/components/ClipboardCopy.vue @@ -1,7 +1,7 @@ From 839d52748b1737ed5d8e6556760f09856a521929 Mon Sep 17 00:00:00 2001 From: Moriz Wahl Date: Thu, 21 Apr 2022 14:08:22 +0200 Subject: [PATCH 036/106] test reopening of transaction link details --- .../TransactionLinkSummary.spec.js | 21 +++ .../Transactions/TransactionLinkSummary.vue | 164 +++++++++--------- 2 files changed, 103 insertions(+), 82 deletions(-) diff --git a/frontend/src/components/Transactions/TransactionLinkSummary.spec.js b/frontend/src/components/Transactions/TransactionLinkSummary.spec.js index 3e57bceeb..79b453344 100644 --- a/frontend/src/components/Transactions/TransactionLinkSummary.spec.js +++ b/frontend/src/components/Transactions/TransactionLinkSummary.spec.js @@ -132,6 +132,27 @@ describe('TransactionLinkSummary', () => { it('has no component CollapseLinksList', () => { expect(wrapper.findComponent({ name: 'CollapseLinksList' }).isVisible()).toBe(false) }) + + describe('reopen transaction link details', () => { + beforeEach(() => { + jest.clearAllMocks() + wrapper.find('div.transaction-link-details').trigger('click') + }) + + it('calls the API to get the list transaction links', () => { + expect(apolloQueryMock).toBeCalledWith({ + query: listTransactionLinks, + variables: { + currentPage: 1, + }, + fetchPolicy: 'network-only', + }) + }) + + it('has four transactionLinks', () => { + expect(wrapper.vm.transactionLinks).toHaveLength(4) + }) + }) }) describe('load more transaction links', () => { diff --git a/frontend/src/components/Transactions/TransactionLinkSummary.vue b/frontend/src/components/Transactions/TransactionLinkSummary.vue index b1ba40c69..c24410924 100644 --- a/frontend/src/components/Transactions/TransactionLinkSummary.vue +++ b/frontend/src/components/Transactions/TransactionLinkSummary.vue @@ -37,87 +37,87 @@ From bbec1306d041e7661022660e27ada0f1746ec46d Mon Sep 17 00:00:00 2001 From: ogerly Date: Thu, 21 Apr 2022 16:38:14 +0200 Subject: [PATCH 037/106] change modal structure --- .../TransactionLinks/TransactionLink.vue | 15 ++++++++++----- 1 file changed, 10 insertions(+), 5 deletions(-) diff --git a/frontend/src/components/TransactionLinks/TransactionLink.vue b/frontend/src/components/TransactionLinks/TransactionLink.vue index 66f9f2f92..40d9296f1 100644 --- a/frontend/src/components/TransactionLinks/TransactionLink.vue +++ b/frontend/src/components/TransactionLinks/TransactionLink.vue @@ -45,11 +45,16 @@ - -
- -

{{ link }}

-
+ + + + + + From e154373694b3534c35b3b193a952ef0df2a60cb8 Mon Sep 17 00:00:00 2001 From: ogerly Date: Thu, 21 Apr 2022 16:39:19 +0200 Subject: [PATCH 038/106] add locales 'qrCode' --- frontend/src/locales/de.json | 1 + frontend/src/locales/en.json | 1 + 2 files changed, 2 insertions(+) diff --git a/frontend/src/locales/de.json b/frontend/src/locales/de.json index 20ce055d4..d7a6be144 100644 --- a/frontend/src/locales/de.json +++ b/frontend/src/locales/de.json @@ -164,6 +164,7 @@ "infoText": "Wenn dir dein Empfehlungsgeber seine Publisher-Id gegeben hat, trage sie hier ein, sonst lass das Feld bitte unverändert!", "publisherId": "Publisher-Id:" }, + "qrCode":"QR Code", "send_gdd": "GDD versenden", "send_per_link": "GDD versenden per Link", "settings": { diff --git a/frontend/src/locales/en.json b/frontend/src/locales/en.json index 201c44d93..a72a4ef25 100644 --- a/frontend/src/locales/en.json +++ b/frontend/src/locales/en.json @@ -164,6 +164,7 @@ "infoText": "If your referrer has given you his publisher id, enter it here, otherwise leave the field unchanged!", "publisherId": "PublisherID:" }, + "qrCode":"QR Code", "send_gdd": "GDD send", "send_per_link": "GDD send via link", "settings": { From 0e8ca5b410c016c76d7f11a16e2e8a29a88d723b Mon Sep 17 00:00:00 2001 From: ogerly Date: Thu, 21 Apr 2022 16:40:30 +0200 Subject: [PATCH 039/106] fixed yarn lint --- frontend/src/locales/de.json | 2 +- frontend/src/locales/en.json | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/frontend/src/locales/de.json b/frontend/src/locales/de.json index d7a6be144..6c891d4b2 100644 --- a/frontend/src/locales/de.json +++ b/frontend/src/locales/de.json @@ -164,7 +164,7 @@ "infoText": "Wenn dir dein Empfehlungsgeber seine Publisher-Id gegeben hat, trage sie hier ein, sonst lass das Feld bitte unverändert!", "publisherId": "Publisher-Id:" }, - "qrCode":"QR Code", + "qrCode": "QR Code", "send_gdd": "GDD versenden", "send_per_link": "GDD versenden per Link", "settings": { diff --git a/frontend/src/locales/en.json b/frontend/src/locales/en.json index a72a4ef25..759412019 100644 --- a/frontend/src/locales/en.json +++ b/frontend/src/locales/en.json @@ -164,7 +164,7 @@ "infoText": "If your referrer has given you his publisher id, enter it here, otherwise leave the field unchanged!", "publisherId": "PublisherID:" }, - "qrCode":"QR Code", + "qrCode": "QR Code", "send_gdd": "GDD send", "send_per_link": "GDD send via link", "settings": { From b2623cc83ea944ff643a3e25f4463919bcdcccec Mon Sep 17 00:00:00 2001 From: ogerly Date: Thu, 21 Apr 2022 17:46:43 +0200 Subject: [PATCH 040/106] add locales 'qrCode' --- frontend/src/locales/de.json | 1 + frontend/src/locales/en.json | 1 + 2 files changed, 2 insertions(+) diff --git a/frontend/src/locales/de.json b/frontend/src/locales/de.json index 20ce055d4..6c891d4b2 100644 --- a/frontend/src/locales/de.json +++ b/frontend/src/locales/de.json @@ -164,6 +164,7 @@ "infoText": "Wenn dir dein Empfehlungsgeber seine Publisher-Id gegeben hat, trage sie hier ein, sonst lass das Feld bitte unverändert!", "publisherId": "Publisher-Id:" }, + "qrCode": "QR Code", "send_gdd": "GDD versenden", "send_per_link": "GDD versenden per Link", "settings": { diff --git a/frontend/src/locales/en.json b/frontend/src/locales/en.json index 201c44d93..759412019 100644 --- a/frontend/src/locales/en.json +++ b/frontend/src/locales/en.json @@ -164,6 +164,7 @@ "infoText": "If your referrer has given you his publisher id, enter it here, otherwise leave the field unchanged!", "publisherId": "PublisherID:" }, + "qrCode": "QR Code", "send_gdd": "GDD send", "send_per_link": "GDD send via link", "settings": { From 1823bc3611293d2d7479eff67f60625044ca4bee Mon Sep 17 00:00:00 2001 From: ogerly Date: Thu, 21 Apr 2022 17:47:55 +0200 Subject: [PATCH 041/106] add methods 'showQrCodeButton', add data 'showQrcode' --- .../components/GddSend/TransactionResultLink.vue | 14 ++++++++++++-- 1 file changed, 12 insertions(+), 2 deletions(-) diff --git a/frontend/src/components/GddSend/TransactionResultLink.vue b/frontend/src/components/GddSend/TransactionResultLink.vue index ee65b159a..852f8b285 100644 --- a/frontend/src/components/GddSend/TransactionResultLink.vue +++ b/frontend/src/components/GddSend/TransactionResultLink.vue @@ -4,10 +4,10 @@
{{ $t('gdd_per_link.created') }}
- +
- + {{ $t('form.close') }} @@ -33,6 +33,16 @@ export default { required: true, }, }, + data() { + return { + showQrcode: false, + } + }, + methods: { + showQrCodeButton() { + this.showQrcode = !this.showQrcode + }, + }, computed: { link() { return `${window.location.origin}/redeem/${this.code}` From 8972c05e8ad6303fb190bb32df8f6ce74ea934f2 Mon Sep 17 00:00:00 2001 From: ogerly Date: Thu, 21 Apr 2022 17:48:17 +0200 Subject: [PATCH 042/106] add emit 'showQrCodeButton' --- frontend/src/components/ClipboardCopy.vue | 3 +++ 1 file changed, 3 insertions(+) diff --git a/frontend/src/components/ClipboardCopy.vue b/frontend/src/components/ClipboardCopy.vue index 810f73fe1..54dc67620 100644 --- a/frontend/src/components/ClipboardCopy.vue +++ b/frontend/src/components/ClipboardCopy.vue @@ -6,6 +6,9 @@ {{ $t('gdd_per_link.copy') }} + + {{ $t('qrCode') }} +
From e9767fc3dee7cc6f4dad8ebfd6e88af9295840a6 Mon Sep 17 00:00:00 2001 From: ogerly Date: Thu, 21 Apr 2022 18:02:44 +0200 Subject: [PATCH 043/106] add qr code svg in button --- frontend/src/components/ClipboardCopy.vue | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/frontend/src/components/ClipboardCopy.vue b/frontend/src/components/ClipboardCopy.vue index 54dc67620..1e76472a4 100644 --- a/frontend/src/components/ClipboardCopy.vue +++ b/frontend/src/components/ClipboardCopy.vue @@ -6,8 +6,8 @@ {{ $t('gdd_per_link.copy') }} - - {{ $t('qrCode') }} + + From 475af6b5f1ea983a68ba3ba28d8822fd20d06ef6 Mon Sep 17 00:00:00 2001 From: ogerly Date: Thu, 21 Apr 2022 18:03:26 +0200 Subject: [PATCH 044/106] remove unused code --- frontend/src/components/ClipboardCopy.vue | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/frontend/src/components/ClipboardCopy.vue b/frontend/src/components/ClipboardCopy.vue index 1e76472a4..753de32e0 100644 --- a/frontend/src/components/ClipboardCopy.vue +++ b/frontend/src/components/ClipboardCopy.vue @@ -7,7 +7,7 @@ {{ $t('gdd_per_link.copy') }} - + From 6360509cad72f4851c31c97677ef149a220ecd7c Mon Sep 17 00:00:00 2001 From: ogerly Date: Thu, 21 Apr 2022 18:05:04 +0200 Subject: [PATCH 045/106] fixed yarn lint --- frontend/src/locales/de.json | 1 - frontend/src/locales/en.json | 1 - 2 files changed, 2 deletions(-) diff --git a/frontend/src/locales/de.json b/frontend/src/locales/de.json index 6c891d4b2..20ce055d4 100644 --- a/frontend/src/locales/de.json +++ b/frontend/src/locales/de.json @@ -164,7 +164,6 @@ "infoText": "Wenn dir dein Empfehlungsgeber seine Publisher-Id gegeben hat, trage sie hier ein, sonst lass das Feld bitte unverändert!", "publisherId": "Publisher-Id:" }, - "qrCode": "QR Code", "send_gdd": "GDD versenden", "send_per_link": "GDD versenden per Link", "settings": { diff --git a/frontend/src/locales/en.json b/frontend/src/locales/en.json index 759412019..201c44d93 100644 --- a/frontend/src/locales/en.json +++ b/frontend/src/locales/en.json @@ -164,7 +164,6 @@ "infoText": "If your referrer has given you his publisher id, enter it here, otherwise leave the field unchanged!", "publisherId": "PublisherID:" }, - "qrCode": "QR Code", "send_gdd": "GDD send", "send_per_link": "GDD send via link", "settings": { From 459dc217b6397f7043b89e7537882979d7fdc187 Mon Sep 17 00:00:00 2001 From: ogerly Date: Thu, 21 Apr 2022 18:08:05 +0200 Subject: [PATCH 046/106] fixed yarn test --- frontend/src/pages/Send.spec.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/frontend/src/pages/Send.spec.js b/frontend/src/pages/Send.spec.js index 447fdde33..2b7d25ef5 100644 --- a/frontend/src/pages/Send.spec.js +++ b/frontend/src/pages/Send.spec.js @@ -249,7 +249,7 @@ describe('Send', () => { describe('close button click', () => { beforeEach(async () => { - await wrapper.findAll('button').at(1).trigger('click') + await wrapper.findAll('button').at(2).trigger('click') }) it('Shows the TransactionForm', () => { From afec1f7e59011fdb85723d2e7ae374e1d51c8339 Mon Sep 17 00:00:00 2001 From: ogerly Date: Thu, 21 Apr 2022 21:15:40 +0200 Subject: [PATCH 047/106] =?UTF-8?q?remove=20button,=20add=20dropdown=20men?= =?UTF-8?q?=C3=BC,=20change=20style?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../TransactionLinks/TransactionLink.vue | 59 ++++++++----------- 1 file changed, 26 insertions(+), 33 deletions(-) diff --git a/frontend/src/components/TransactionLinks/TransactionLink.vue b/frontend/src/components/TransactionLinks/TransactionLink.vue index 66f9f2f92..abb54f8f6 100644 --- a/frontend/src/components/TransactionLinks/TransactionLink.vue +++ b/frontend/src/components/TransactionLinks/TransactionLink.vue @@ -1,49 +1,39 @@ - + {{ $t('gdd_per_link.copy') }} Date: Fri, 22 Apr 2022 15:20:46 +0200 Subject: [PATCH 071/106] changed paddings from dropdown menu --- frontend/src/components/TransactionLinks/TransactionLink.vue | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/frontend/src/components/TransactionLinks/TransactionLink.vue b/frontend/src/components/TransactionLinks/TransactionLink.vue index e921135f8..5b8e15d5c 100644 --- a/frontend/src/components/TransactionLinks/TransactionLink.vue +++ b/frontend/src/components/TransactionLinks/TransactionLink.vue @@ -25,12 +25,12 @@ {{ $t('qrCode') }} - + {{ $t('delete') }} From fdb64071d6cff9a65198594e20b554ed01dc8616 Mon Sep 17 00:00:00 2001 From: Moriz Wahl Date: Mon, 25 Apr 2022 11:32:26 +0200 Subject: [PATCH 072/106] join tables to update is_admin --- database/migrations/0034-drop_server_user_table.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/database/migrations/0034-drop_server_user_table.ts b/database/migrations/0034-drop_server_user_table.ts index fd5a9a682..be6b44489 100644 --- a/database/migrations/0034-drop_server_user_table.ts +++ b/database/migrations/0034-drop_server_user_table.ts @@ -8,7 +8,7 @@ export async function upgrade(queryFn: (query: string, values?: any[]) => Promis await queryFn('ALTER TABLE `users` ADD COLUMN `is_admin` datetime DEFAULT NULL AFTER `language`;') await queryFn( - 'UPDATE `users` AS `users`, (SELECT * FROM `server_users`) AS `server_users` SET users.`is_admin` = server_users.`modified` WHERE users.`email` IN (SELECT email from `server_users`);', + 'UPDATE users AS users INNER JOIN server_users AS server_users ON users.email = server_users.email SET users.is_admin = server_users.modified WHERE users.email IN (SELECT email from server_users);', ) await queryFn('DROP TABLE `server_users`;') From d346a1d09dec91ca5981a85dc8ccb79e25c883fe Mon Sep 17 00:00:00 2001 From: Moriz Wahl Date: Mon, 25 Apr 2022 11:52:10 +0200 Subject: [PATCH 073/106] test verify login --- .../src/graphql/resolver/UserResolver.test.ts | 71 ++++++++++++++++++- 1 file changed, 70 insertions(+), 1 deletion(-) diff --git a/backend/src/graphql/resolver/UserResolver.test.ts b/backend/src/graphql/resolver/UserResolver.test.ts index 07b8e59e2..edd1ec7c5 100644 --- a/backend/src/graphql/resolver/UserResolver.test.ts +++ b/backend/src/graphql/resolver/UserResolver.test.ts @@ -5,7 +5,7 @@ import { testEnvironment, headerPushMock, resetToken, cleanDB } from '@test/help import { userFactory } from '@/seeds/factory/user' import { bibiBloxberg } from '@/seeds/users/bibi-bloxberg' import { createUser, setPassword } from '@/seeds/graphql/mutations' -import { login, logout } from '@/seeds/graphql/queries' +import { login, logout, verifyLogin } from '@/seeds/graphql/queries' import { GraphQLError } from 'graphql' import { LoginEmailOptIn } from '@entity/LoginEmailOptIn' import { User } from '@entity/User' @@ -412,6 +412,75 @@ describe('UserResolver', () => { }) }) }) + + describe('verifyLogin', () => { + describe('unauthenticated', () => { + it('throws an error', async () => { + resetToken() + await expect(query({ query: verifyLogin })).resolves.toEqual( + expect.objectContaining({ + errors: [new GraphQLError('401 Unauthorized')], + }), + ) + }) + }) + + describe('user exists but is not logged in', () => { + beforeAll(async () => { + await userFactory(testEnv, bibiBloxberg) + }) + + afterAll(async () => { + await cleanDB() + }) + + it('throws an error', async () => { + resetToken() + await expect(query({ query: verifyLogin })).resolves.toEqual( + expect.objectContaining({ + errors: [new GraphQLError('401 Unauthorized')], + }), + ) + }) + + describe('authenticated', () => { + const variables = { + email: 'bibi@bloxberg.de', + password: 'Aa12345_', + } + + beforeAll(async () => { + await query({ query: login, variables }) + }) + + afterAll(() => { + resetToken() + }) + + it('returns user object', async () => { + await expect(query({ query: verifyLogin })).resolves.toEqual( + expect.objectContaining({ + data: { + verifyLogin: { + email: 'bibi@bloxberg.de', + firstName: 'Bibi', + lastName: 'Bloxberg', + language: 'de', + coinanimation: true, + klickTipp: { + newsletterState: false, + }, + hasElopage: false, + publisherId: 1234, + isAdmin: false, + }, + }, + }), + ) + }) + }) + }) + }) }) describe('printTimeDuration', () => { From 276a1be889c51b6010a02562bad23ce09d697e8d Mon Sep 17 00:00:00 2001 From: Moriz Wahl Date: Mon, 25 Apr 2022 12:49:23 +0200 Subject: [PATCH 074/106] test forgot password mutation --- .../src/graphql/resolver/UserResolver.test.ts | 65 ++++++++++++++++++- backend/src/seeds/graphql/mutations.ts | 6 ++ 2 files changed, 68 insertions(+), 3 deletions(-) diff --git a/backend/src/graphql/resolver/UserResolver.test.ts b/backend/src/graphql/resolver/UserResolver.test.ts index edd1ec7c5..a2f5b2fdb 100644 --- a/backend/src/graphql/resolver/UserResolver.test.ts +++ b/backend/src/graphql/resolver/UserResolver.test.ts @@ -1,17 +1,18 @@ /* eslint-disable @typescript-eslint/no-explicit-any */ /* eslint-disable @typescript-eslint/explicit-module-boundary-types */ -import { testEnvironment, headerPushMock, resetToken, cleanDB } from '@test/helpers' +import { testEnvironment, headerPushMock, resetToken, cleanDB, resetEntity } from '@test/helpers' import { userFactory } from '@/seeds/factory/user' import { bibiBloxberg } from '@/seeds/users/bibi-bloxberg' -import { createUser, setPassword } from '@/seeds/graphql/mutations' +import { createUser, setPassword, forgotPassword } from '@/seeds/graphql/mutations' import { login, logout, verifyLogin } from '@/seeds/graphql/queries' import { GraphQLError } from 'graphql' import { LoginEmailOptIn } from '@entity/LoginEmailOptIn' import { User } from '@entity/User' import CONFIG from '@/config' import { sendAccountActivationEmail } from '@/mailer/sendAccountActivationEmail' -import { printTimeDuration } from './UserResolver' +import { sendResetPasswordEmail } from '@/mailer/sendResetPasswordEmail' +import { printTimeDuration, activationLink } from './UserResolver' // import { klicktippSignIn } from '@/apis/KlicktippController' @@ -22,6 +23,13 @@ jest.mock('@/mailer/sendAccountActivationEmail', () => { } }) +jest.mock('@/mailer/sendResetPasswordEmail', () => { + return { + __esModule: true, + sendResetPasswordEmail: jest.fn(), + } +}) + /* jest.mock('@/apis/KlicktippController', () => { return { @@ -481,6 +489,57 @@ describe('UserResolver', () => { }) }) }) + + describe('forgotPassword', () => { + const variables = { email: 'bibi@bloxberg.de' } + describe('user is not in DB', () => { + it('returns true', async () => { + await expect(mutate({ mutation: forgotPassword, variables })).resolves.toEqual( + expect.objectContaining({ + data: { + forgotPassword: true, + }, + }), + ) + }) + }) + + describe('user exists in DB', () => { + let result: any + let loginEmailOptIn: LoginEmailOptIn[] + + beforeAll(async () => { + await userFactory(testEnv, bibiBloxberg) + await resetEntity(LoginEmailOptIn) + result = await mutate({ mutation: forgotPassword, variables }) + loginEmailOptIn = await LoginEmailOptIn.find() + }) + + afterAll(async () => { + await cleanDB() + }) + + it('returns true', async () => { + await expect(result).toEqual( + expect.objectContaining({ + data: { + forgotPassword: true, + }, + }), + ) + }) + + it('sends reset password email', () => { + expect(sendResetPasswordEmail).toBeCalledWith({ + link: activationLink(loginEmailOptIn[0]), + firstName: 'Bibi', + lastName: 'Bloxberg', + email: 'bibi@bloxberg.de', + duration: expect.any(String), + }) + }) + }) + }) }) describe('printTimeDuration', () => { diff --git a/backend/src/seeds/graphql/mutations.ts b/backend/src/seeds/graphql/mutations.ts index 298d56bdb..fc662cf19 100644 --- a/backend/src/seeds/graphql/mutations.ts +++ b/backend/src/seeds/graphql/mutations.ts @@ -18,6 +18,12 @@ export const setPassword = gql` } ` +export const forgotPassword = gql` + mutation ($email: String!) { + forgotPassword(email: $email) + } +` + export const updateUserInfos = gql` mutation ( $firstName: String From e30d1f723fcfa7ca078de4fe0225761f08724119 Mon Sep 17 00:00:00 2001 From: Moriz Wahl Date: Mon, 25 Apr 2022 13:18:08 +0200 Subject: [PATCH 075/106] test queryOptIn --- .../src/graphql/resolver/UserResolver.test.ts | 59 ++++++++++++++++++- backend/src/seeds/graphql/queries.ts | 6 ++ 2 files changed, 64 insertions(+), 1 deletion(-) diff --git a/backend/src/graphql/resolver/UserResolver.test.ts b/backend/src/graphql/resolver/UserResolver.test.ts index a2f5b2fdb..0b62e0c99 100644 --- a/backend/src/graphql/resolver/UserResolver.test.ts +++ b/backend/src/graphql/resolver/UserResolver.test.ts @@ -5,7 +5,7 @@ import { testEnvironment, headerPushMock, resetToken, cleanDB, resetEntity } fro import { userFactory } from '@/seeds/factory/user' import { bibiBloxberg } from '@/seeds/users/bibi-bloxberg' import { createUser, setPassword, forgotPassword } from '@/seeds/graphql/mutations' -import { login, logout, verifyLogin } from '@/seeds/graphql/queries' +import { login, logout, verifyLogin, queryOptIn } from '@/seeds/graphql/queries' import { GraphQLError } from 'graphql' import { LoginEmailOptIn } from '@entity/LoginEmailOptIn' import { User } from '@entity/User' @@ -538,6 +538,63 @@ describe('UserResolver', () => { duration: expect.any(String), }) }) + + describe('request reset password again', () => { + it('thows an error', async () => { + await expect(mutate({ mutation: forgotPassword, variables })).resolves.toEqual( + expect.objectContaining({ + errors: [new GraphQLError('email already sent less than 10 minutes minutes ago')], + }), + ) + }) + }) + }) + }) + + describe('queryOptIn', () => { + let loginEmailOptIn: LoginEmailOptIn[] + + beforeAll(async () => { + await userFactory(testEnv, bibiBloxberg) + loginEmailOptIn = await LoginEmailOptIn.find() + }) + + afterAll(async () => { + await cleanDB() + }) + + describe('wrong optin code', () => { + it('throws an error', async () => { + await expect( + query({ query: queryOptIn, variables: { optIn: 'not-valid' } }), + ).resolves.toEqual( + expect.objectContaining({ + errors: [ + // keep Whitspace in error message! + new GraphQLError(`Could not find any entity of type "LoginEmailOptIn" matching: { + "verificationCode": "not-valid" +}`), + ], + }), + ) + }) + }) + + describe('correct optin code', () => { + it('returns true', async () => { + await expect( + query({ + query: queryOptIn, + variables: { optIn: loginEmailOptIn[0].verificationCode.toString() }, + }), + ).resolves.toEqual( + expect.objectContaining({ + data: { + queryOptIn: true, + }, + }), + ) + }) }) }) }) diff --git a/backend/src/seeds/graphql/queries.ts b/backend/src/seeds/graphql/queries.ts index 11a675eeb..76a386953 100644 --- a/backend/src/seeds/graphql/queries.ts +++ b/backend/src/seeds/graphql/queries.ts @@ -43,6 +43,12 @@ export const logout = gql` } ` +export const queryOptIn = gql` + query ($optIn: String!) { + queryOptIn(optIn: $optIn) + } +` + export const transactionsQuery = gql` query ( $currentPage: Int = 1 From 73fe46c39d80b5f867eb015d2072b9bc44357c25 Mon Sep 17 00:00:00 2001 From: Ulf Gebhardt Date: Mon, 25 Apr 2022 14:03:38 +0200 Subject: [PATCH 076/106] also change memo column --- .../AdminPendingCreation.ts | 2 +- .../0034-admin_pending_creations_decimal.ts | 11 ++++++++++- 2 files changed, 11 insertions(+), 2 deletions(-) diff --git a/database/entity/0034-admin_pending_creations_decimal/AdminPendingCreation.ts b/database/entity/0034-admin_pending_creations_decimal/AdminPendingCreation.ts index d204942b3..3cd83a3a5 100644 --- a/database/entity/0034-admin_pending_creations_decimal/AdminPendingCreation.ts +++ b/database/entity/0034-admin_pending_creations_decimal/AdminPendingCreation.ts @@ -16,7 +16,7 @@ export class AdminPendingCreation extends BaseEntity { @Column({ type: 'datetime', nullable: false }) date: Date - @Column({ length: 256, nullable: true, default: null }) + @Column({ length: 255, nullable: false, collation: 'utf8mb4_unicode_ci' }) memo: string @Column({ diff --git a/database/migrations/0034-admin_pending_creations_decimal.ts b/database/migrations/0034-admin_pending_creations_decimal.ts index 6df1e563b..d3648f376 100644 --- a/database/migrations/0034-admin_pending_creations_decimal.ts +++ b/database/migrations/0034-admin_pending_creations_decimal.ts @@ -1,4 +1,7 @@ -/* MIGRATION TO CHANGE `amount` FIELD TYPE TO `Decimal` ON `admin_pending_creations` */ +/* MIGRATION TO CHANGE SEVERAL FIELDS ON `admin_pending_creations` + * - `amount` FIELD TYPE TO `Decimal` + * - `memo` FIELD TYPE TO `varchar(255)`, collate `utf8mb4_unicode_ci` + */ /* eslint-disable @typescript-eslint/explicit-module-boundary-types */ /* eslint-disable @typescript-eslint/no-explicit-any */ @@ -18,9 +21,15 @@ export async function upgrade(queryFn: (query: string, values?: any[]) => Promis ) // drop `amount_bitint` column await queryFn('ALTER TABLE `admin_pending_creations` DROP COLUMN `amount_bigint`;') + + // change `memo` to varchar(255), collate utf8mb4_unicode_ci + await queryFn( + 'ALTER TABLE `admin_pending_creations` MODIFY COLUMN `memo` varchar(255) COLLATE utf8mb4_unicode_ci NOT NULL;', + ) } export async function downgrade(queryFn: (query: string, values?: any[]) => Promise>) { + await queryFn('ALTER TABLE `admin_pending_creations` MODIFY COLUMN `memo` text DEFAULT NULL;') await queryFn( 'ALTER TABLE `admin_pending_creations` ADD COLUMN `amount_bigint` bigint(20) DEFAULT NULL AFTER `amount`;', ) From 0264931e5824d4d8c087502d035bdb7b6057242c Mon Sep 17 00:00:00 2001 From: Moriz Wahl Date: Mon, 25 Apr 2022 14:07:31 +0200 Subject: [PATCH 077/106] test update user infos mutation. Remove publisher ID from update user infos as it is never used --- .../src/graphql/resolver/UserResolver.test.ts | 177 +++++++++++++++++- backend/src/graphql/resolver/UserResolver.ts | 15 +- 2 files changed, 176 insertions(+), 16 deletions(-) diff --git a/backend/src/graphql/resolver/UserResolver.test.ts b/backend/src/graphql/resolver/UserResolver.test.ts index 0b62e0c99..06924699a 100644 --- a/backend/src/graphql/resolver/UserResolver.test.ts +++ b/backend/src/graphql/resolver/UserResolver.test.ts @@ -4,7 +4,7 @@ import { testEnvironment, headerPushMock, resetToken, cleanDB, resetEntity } from '@test/helpers' import { userFactory } from '@/seeds/factory/user' import { bibiBloxberg } from '@/seeds/users/bibi-bloxberg' -import { createUser, setPassword, forgotPassword } from '@/seeds/graphql/mutations' +import { createUser, setPassword, forgotPassword, updateUserInfos } from '@/seeds/graphql/mutations' import { login, logout, verifyLogin, queryOptIn } from '@/seeds/graphql/queries' import { GraphQLError } from 'graphql' import { LoginEmailOptIn } from '@entity/LoginEmailOptIn' @@ -93,7 +93,7 @@ describe('UserResolver', () => { }) describe('filling all tables', () => { - it('saves the user in login_user table', () => { + it('saves the user in users table', () => { expect(user).toEqual([ { id: expect.any(Number), @@ -597,6 +597,179 @@ describe('UserResolver', () => { }) }) }) + + describe('updateUserInfos', () => { + describe('unauthenticated', () => { + it('throws an error', async () => { + resetToken() + await expect(mutate({ mutation: updateUserInfos })).resolves.toEqual( + expect.objectContaining({ + errors: [new GraphQLError('401 Unauthorized')], + }), + ) + }) + }) + + describe('authenticated', () => { + beforeAll(async () => { + await userFactory(testEnv, bibiBloxberg) + await query({ + query: login, + variables: { + email: 'bibi@bloxberg.de', + password: 'Aa12345_', + }, + }) + }) + + afterAll(async () => { + await cleanDB() + }) + + it('returns true', async () => { + await expect(mutate({ mutation: updateUserInfos })).resolves.toEqual( + expect.objectContaining({ + data: { + updateUserInfos: true, + }, + }), + ) + }) + + describe('first-name, last-name and language', () => { + it('updates the fields in DB', async () => { + await mutate({ + mutation: updateUserInfos, + variables: { + firstName: 'Benjamin', + lastName: 'Blümchen', + locale: 'en', + }, + }) + await expect(User.findOne()).resolves.toEqual( + expect.objectContaining({ + firstName: 'Benjamin', + lastName: 'Blümchen', + language: 'en', + }), + ) + }) + }) + + describe('language is not valid', () => { + it('thows an error', async () => { + await expect( + mutate({ + mutation: updateUserInfos, + variables: { + locale: 'not-valid', + }, + }), + ).resolves.toEqual( + expect.objectContaining({ + errors: [new GraphQLError(`"not-valid" isn't a valid language`)], + }), + ) + }) + }) + + describe('password', () => { + describe('wrong old password', () => { + it('throws an error', async () => { + await expect( + mutate({ + mutation: updateUserInfos, + variables: { + password: 'wrong password', + passwordNew: 'Aa12345_', + }, + }), + ).resolves.toEqual( + expect.objectContaining({ + errors: [new GraphQLError('Old password is invalid')], + }), + ) + }) + }) + + describe('invalid new password', () => { + it('throws an error', async () => { + await expect( + mutate({ + mutation: updateUserInfos, + variables: { + password: 'Aa12345_', + passwordNew: 'Aa12345', + }, + }), + ).resolves.toEqual( + expect.objectContaining({ + errors: [ + new GraphQLError( + 'Please enter a valid password with at least 8 characters, upper and lower case letters, at least one number and one special character!', + ), + ], + }), + ) + }) + }) + + describe('correct old and new password', () => { + it('returns true', async () => { + await expect( + mutate({ + mutation: updateUserInfos, + variables: { + password: 'Aa12345_', + passwordNew: 'Bb12345_', + }, + }), + ).resolves.toEqual( + expect.objectContaining({ + data: { updateUserInfos: true }, + }), + ) + }) + + it('can login wtih new password', async () => { + await expect( + query({ + query: login, + variables: { + email: 'bibi@bloxberg.de', + password: 'Bb12345_', + }, + }), + ).resolves.toEqual( + expect.objectContaining({ + data: { + login: expect.objectContaining({ + email: 'bibi@bloxberg.de', + }), + }, + }), + ) + }) + + it('cannot login wtih old password', async () => { + await expect( + query({ + query: login, + variables: { + email: 'bibi@bloxberg.de', + password: 'Aa12345_', + }, + }), + ).resolves.toEqual( + expect.objectContaining({ + errors: [new GraphQLError('No user with this credentials')], + }), + ) + }) + }) + }) + }) + }) }) describe('printTimeDuration', () => { diff --git a/backend/src/graphql/resolver/UserResolver.ts b/backend/src/graphql/resolver/UserResolver.ts index 137c09622..a4d4f9115 100644 --- a/backend/src/graphql/resolver/UserResolver.ts +++ b/backend/src/graphql/resolver/UserResolver.ts @@ -529,15 +529,7 @@ export class UserResolver { @Mutation(() => Boolean) async updateUserInfos( @Args() - { - firstName, - lastName, - language, - publisherId, - password, - passwordNew, - coinanimation, - }: UpdateUserInfosArgs, + { firstName, lastName, language, password, passwordNew, coinanimation }: UpdateUserInfosArgs, @Ctx() context: Context, ): Promise { const userEntity = getUser(context) @@ -581,11 +573,6 @@ export class UserResolver { userEntity.privKey = encryptedPrivkey } - // Save publisherId only if Elopage is not yet registered - if (publisherId && !(await this.hasElopage(context))) { - userEntity.publisherId = publisherId - } - const queryRunner = getConnection().createQueryRunner() await queryRunner.connect() await queryRunner.startTransaction('READ UNCOMMITTED') From 5cd2c045aa6f625a214a4f91fd9378f0740cc6bb Mon Sep 17 00:00:00 2001 From: Moriz Wahl Date: Mon, 25 Apr 2022 14:08:24 +0200 Subject: [PATCH 078/106] test coverage backend to 58% --- .github/workflows/test.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/test.yml b/.github/workflows/test.yml index ee602a343..3d046fcda 100644 --- a/.github/workflows/test.yml +++ b/.github/workflows/test.yml @@ -528,7 +528,7 @@ jobs: report_name: Coverage Backend type: lcov result_path: ./backend/coverage/lcov.info - min_coverage: 55 + min_coverage: 58 token: ${{ github.token }} ########################################################################## From e2957e0b345a1136ce1404a725ea7dc186a32682 Mon Sep 17 00:00:00 2001 From: Ulf Gebhardt Date: Mon, 25 Apr 2022 14:17:45 +0200 Subject: [PATCH 079/106] config value for the redeem URL was missing --- deployment/bare_metal/.env.dist | 1 + 1 file changed, 1 insertion(+) diff --git a/deployment/bare_metal/.env.dist b/deployment/bare_metal/.env.dist index 316fb60c2..a1751a859 100644 --- a/deployment/bare_metal/.env.dist +++ b/deployment/bare_metal/.env.dist @@ -21,6 +21,7 @@ WEBHOOK_GITHUB_BRANCH=master 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_DESCRIPTION="Gradido Development Stage1 Test Community" # backend From a4a92812bf3e21f9b0b6feb05cca3e84c1d0662d Mon Sep 17 00:00:00 2001 From: Ulf Gebhardt Date: Mon, 25 Apr 2022 15:14:55 +0200 Subject: [PATCH 080/106] adjusted migrtion number to 35 --- .../AdminPendingCreation.ts | 0 database/entity/AdminPendingCreation.ts | 2 +- ...tions_decimal.ts => 0035-admin_pending_creations_decimal.ts} | 0 3 files changed, 1 insertion(+), 1 deletion(-) rename database/entity/{0034-admin_pending_creations_decimal => 0035-admin_pending_creations_decimal}/AdminPendingCreation.ts (100%) rename database/migrations/{0034-admin_pending_creations_decimal.ts => 0035-admin_pending_creations_decimal.ts} (100%) diff --git a/database/entity/0034-admin_pending_creations_decimal/AdminPendingCreation.ts b/database/entity/0035-admin_pending_creations_decimal/AdminPendingCreation.ts similarity index 100% rename from database/entity/0034-admin_pending_creations_decimal/AdminPendingCreation.ts rename to database/entity/0035-admin_pending_creations_decimal/AdminPendingCreation.ts diff --git a/database/entity/AdminPendingCreation.ts b/database/entity/AdminPendingCreation.ts index a32590a22..b2b37d7c4 100644 --- a/database/entity/AdminPendingCreation.ts +++ b/database/entity/AdminPendingCreation.ts @@ -1 +1 @@ -export { AdminPendingCreation } from './0034-admin_pending_creations_decimal/AdminPendingCreation' +export { AdminPendingCreation } from './0035-admin_pending_creations_decimal/AdminPendingCreation' diff --git a/database/migrations/0034-admin_pending_creations_decimal.ts b/database/migrations/0035-admin_pending_creations_decimal.ts similarity index 100% rename from database/migrations/0034-admin_pending_creations_decimal.ts rename to database/migrations/0035-admin_pending_creations_decimal.ts From a4ae002693c2a6eced4f9e066ef9d60585ab7c36 Mon Sep 17 00:00:00 2001 From: Moriz Wahl Date: Mon, 25 Apr 2022 16:01:26 +0200 Subject: [PATCH 081/106] round balance down before subtracting hold available amount --- backend/src/util/virtualTransactions.ts | 1 + 1 file changed, 1 insertion(+) diff --git a/backend/src/util/virtualTransactions.ts b/backend/src/util/virtualTransactions.ts index 8c1aec65b..08d44b48d 100644 --- a/backend/src/util/virtualTransactions.ts +++ b/backend/src/util/virtualTransactions.ts @@ -70,6 +70,7 @@ const virtualDecayTransaction = ( typeId: TransactionTypeId.DECAY, amount: decay.decay ? decay.roundedDecay : new Decimal(0), balance: decay.balance + .toDecimalPlaces(2, Decimal.ROUND_DOWN) .minus(holdAvailabeAmount.toString()) .toDecimalPlaces(2, Decimal.ROUND_DOWN), balanceDate: time, From 22fcf28291f3641a1203128a4d1de353cb6458de Mon Sep 17 00:00:00 2001 From: Moriz Wahl Date: Mon, 25 Apr 2022 16:06:18 +0200 Subject: [PATCH 082/106] remove strange comments --- backend/src/graphql/resolver/UserResolver.ts | 2 -- 1 file changed, 2 deletions(-) diff --git a/backend/src/graphql/resolver/UserResolver.ts b/backend/src/graphql/resolver/UserResolver.ts index a4d4f9115..4fe2589ec 100644 --- a/backend/src/graphql/resolver/UserResolver.ts +++ b/backend/src/graphql/resolver/UserResolver.ts @@ -251,8 +251,6 @@ export class UserResolver { user.hasElopage = await this.hasElopage({ ...context, user: dbUser }) if (!user.hasElopage && publisherId) { user.publisherId = publisherId - // TODO: Check if we can use updateUserInfos - // await this.updateUserInfos({ publisherId }, { pubKey: loginUser.pubKey }) dbUser.publisherId = publisherId DbUser.save(dbUser) } From 54e119f88d1ad704393596058fc0029d61bb868d Mon Sep 17 00:00:00 2001 From: Moriz Wahl Date: Mon, 25 Apr 2022 16:20:00 +0200 Subject: [PATCH 083/106] fix test after alter is admin field --- backend/src/graphql/resolver/UserResolver.test.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/backend/src/graphql/resolver/UserResolver.test.ts b/backend/src/graphql/resolver/UserResolver.test.ts index 424c2051c..c658476a4 100644 --- a/backend/src/graphql/resolver/UserResolver.test.ts +++ b/backend/src/graphql/resolver/UserResolver.test.ts @@ -481,7 +481,7 @@ describe('UserResolver', () => { }, hasElopage: false, publisherId: 1234, - isAdmin: false, + isAdmin: null, }, }, }), From 6aad14024755ddbfedc1e3ee85ac9bff2faa9751 Mon Sep 17 00:00:00 2001 From: Ulf Gebhardt Date: Mon, 25 Apr 2022 16:36:33 +0200 Subject: [PATCH 084/106] fix database version requirement for backend --- backend/src/config/index.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/backend/src/config/index.ts b/backend/src/config/index.ts index 63968c235..1eee1b9a4 100644 --- a/backend/src/config/index.ts +++ b/backend/src/config/index.ts @@ -10,7 +10,7 @@ Decimal.set({ }) const constants = { - DB_VERSION: '0035-admin_pending_creations_decimal.ts', + DB_VERSION: '0035-admin_pending_creations_decimal', DECAY_START_TIME: new Date('2021-05-13 17:46:31'), // GMT+0 CONFIG_VERSION: { DEFAULT: 'DEFAULT', From 84d4d41f2233211c6d454da74ee95f5b00b2f3f1 Mon Sep 17 00:00:00 2001 From: Ulf Gebhardt Date: Mon, 25 Apr 2022 16:51:48 +0200 Subject: [PATCH 085/106] v1.8.0 --- CHANGELOG.md | 46 +++++++++++++++++++++++++++++++++++++++++++ admin/package.json | 2 +- backend/package.json | 2 +- database/package.json | 2 +- frontend/package.json | 2 +- package.json | 2 +- 6 files changed, 51 insertions(+), 5 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 53376946c..5d8b71dac 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -4,8 +4,54 @@ All notable changes to this project will be documented in this file. Dates are d Generated by [`auto-changelog`](https://github.com/CookPete/auto-changelog). +#### [1.8.0](https://github.com/gradido/gradido/compare/1.7.1...1.8.0) + +- Fix: database version requirement for backend corrected [`#1835`](https://github.com/gradido/gradido/pull/1835) +- feat: More User Resolver Tests [`#1827`](https://github.com/gradido/gradido/pull/1827) +- fix: Round Decay with Tranasction Links [`#1834`](https://github.com/gradido/gradido/pull/1834) +- Fix: config value for the redeem URL was missing [`#1828`](https://github.com/gradido/gradido/pull/1828) +- Refactor: Database admin pending creations use decimal [`#1748`](https://github.com/gradido/gradido/pull/1748) +- refactor: Drop Server User Table [`#1808`](https://github.com/gradido/gradido/pull/1808) +- 1816 expired link are not highlighted [`#1821`](https://github.com/gradido/gradido/pull/1821) +- 1812 put qr code into popup on generate [`#1820`](https://github.com/gradido/gradido/pull/1820) +- Docu: Federation image [`#1817`](https://github.com/gradido/gradido/pull/1817) +- 1813 qr code popup [`#1819`](https://github.com/gradido/gradido/pull/1819) +- Fix: cross-env for windows [`#1822`](https://github.com/gradido/gradido/pull/1822) +- fix: Double Load Transaction Links [`#1818`](https://github.com/gradido/gradido/pull/1818) +- Generated link in backend should also give back the base url [`#1745`](https://github.com/gradido/gradido/pull/1745) +- 1731 style startDecayStartblock, style Adapted across pages [`#1809`](https://github.com/gradido/gradido/pull/1809) +- Refactor: Frontend bake in community info [`#1750`](https://github.com/gradido/gradido/pull/1750) +- fix: Load Transaction Link Details on Click [`#1806`](https://github.com/gradido/gradido/pull/1806) +- devops: Deploy Seed in Backend [`#1790`](https://github.com/gradido/gradido/pull/1790) +- refactor: Balance Model and Decay Rounding [`#1780`](https://github.com/gradido/gradido/pull/1780) +- change config DECAY_START_TIME in UTC 0000 [`#1807`](https://github.com/gradido/gradido/pull/1807) +- 1751 make gdt visible only if explicitly clicked [`#1752`](https://github.com/gradido/gradido/pull/1752) +- add Tab system from bootstrap in SearchUserTable Userdata [`#1744`](https://github.com/gradido/gradido/pull/1744) +- Fix: Certbot renewal [`#1789`](https://github.com/gradido/gradido/pull/1789) +- 🍰 Add Wallet Link To Mails [`#1765`](https://github.com/gradido/gradido/pull/1765) +- 1633 display qr code on link in transaction list [`#1661`](https://github.com/gradido/gradido/pull/1661) +- 1755 insert additional text when redeeming [`#1756`](https://github.com/gradido/gradido/pull/1756) +- refactor: Define Context Interface [`#1762`](https://github.com/gradido/gradido/pull/1762) +- fix: Elopage Status [`#1742`](https://github.com/gradido/gradido/pull/1742) +- Refactor: Frontend decay start block as static config value [`#1749`](https://github.com/gradido/gradido/pull/1749) +- better date format for reddem valid date [`#1758`](https://github.com/gradido/gradido/pull/1758) +- add insert shadow in summary links transaction type [`#1754`](https://github.com/gradido/gradido/pull/1754) +- Feature: JWT duration is now 30min by default [`#1747`](https://github.com/gradido/gradido/pull/1747) +- Docu: Scope of Gradido [`#1746`](https://github.com/gradido/gradido/pull/1746) +- fix: Check That Recipient User Has Activated Account to Receive Coins [`#1743`](https://github.com/gradido/gradido/pull/1743) +- Fix: Fixed config dist version to properly reflect new password reset url [`#1737`](https://github.com/gradido/gradido/pull/1737) +- 503 transaction list pagination pages clickable [`#1677`](https://github.com/gradido/gradido/pull/1677) +- if no recipientEmail else form.email [`#1722`](https://github.com/gradido/gradido/pull/1722) +- 1727 change button text and observe spelling [`#1728`](https://github.com/gradido/gradido/pull/1728) +- 1729 load spinner if pending balance [`#1730`](https://github.com/gradido/gradido/pull/1730) +- transaction type remains when jumping from the verification back [`#1724`](https://github.com/gradido/gradido/pull/1724) +- text for toast expand link copied [`#1726`](https://github.com/gradido/gradido/pull/1726) + #### [1.7.1](https://github.com/gradido/gradido/compare/1.7.0...1.7.1) +> 1 April 2022 + +- v1.7.1 [`#1721`](https://github.com/gradido/gradido/pull/1721) - fix: Localize Dates on Redeem Transaction Link Page [`#1720`](https://github.com/gradido/gradido/pull/1720) - fix: Round Virtual Transaction Link Transaction [`#1718`](https://github.com/gradido/gradido/pull/1718) - larger icon and deacy information if center [`#1719`](https://github.com/gradido/gradido/pull/1719) diff --git a/admin/package.json b/admin/package.json index 3d3919954..c5b2e60f5 100644 --- a/admin/package.json +++ b/admin/package.json @@ -3,7 +3,7 @@ "description": "Administraion Interface for Gradido", "main": "index.js", "author": "Moriz Wahl", - "version": "1.7.1", + "version": "1.8.0", "license": "MIT", "private": false, "scripts": { diff --git a/backend/package.json b/backend/package.json index 8654f4cc7..c5318d674 100644 --- a/backend/package.json +++ b/backend/package.json @@ -1,6 +1,6 @@ { "name": "gradido-backend", - "version": "1.7.1", + "version": "1.8.0", "description": "Gradido unified backend providing an API-Service for Gradido Transactions", "main": "src/index.ts", "repository": "https://github.com/gradido/gradido/backend", diff --git a/database/package.json b/database/package.json index a1fffa882..13c638c79 100644 --- a/database/package.json +++ b/database/package.json @@ -1,6 +1,6 @@ { "name": "gradido-database", - "version": "1.7.1", + "version": "1.8.0", "description": "Gradido Database Tool to execute database migrations", "main": "src/index.ts", "repository": "https://github.com/gradido/gradido/database", diff --git a/frontend/package.json b/frontend/package.json index b3091d4b4..18021e705 100755 --- a/frontend/package.json +++ b/frontend/package.json @@ -1,6 +1,6 @@ { "name": "bootstrap-vue-gradido-wallet", - "version": "1.7.1", + "version": "1.8.0", "private": true, "scripts": { "start": "node run/server.js", diff --git a/package.json b/package.json index 2ff37c71a..c8abef594 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "gradido", - "version": "1.7.1", + "version": "1.8.0", "description": "Gradido", "main": "index.js", "repository": "git@github.com:gradido/gradido.git", From 6d48b6f4e39f97ddf05e4fe5241156db8c43d5f4 Mon Sep 17 00:00:00 2001 From: Moriz Wahl Date: Tue, 26 Apr 2022 09:27:55 +0200 Subject: [PATCH 086/106] fix: Confirm Creation with Decimal --- backend/src/graphql/resolver/AdminResolver.ts | 5 ++--- backend/src/seeds/graphql/mutations.ts | 2 +- 2 files changed, 3 insertions(+), 4 deletions(-) diff --git a/backend/src/graphql/resolver/AdminResolver.ts b/backend/src/graphql/resolver/AdminResolver.ts index 379412cdc..2009af3b0 100644 --- a/backend/src/graphql/resolver/AdminResolver.ts +++ b/backend/src/graphql/resolver/AdminResolver.ts @@ -333,8 +333,7 @@ export class AdminResolver { decay = calculateDecay(lastTransaction.balance, lastTransaction.balanceDate, receivedCallDate) newBalance = decay.balance } - // TODO pending creations decimal - newBalance = newBalance.add(new Decimal(Number(pendingCreation.amount)).toString()) + newBalance = newBalance.add(pendingCreation.amount.toString()) const transaction = new DbTransaction() transaction.typeId = TransactionTypeId.CREATION @@ -516,7 +515,7 @@ function isCreationValid(creations: Decimal[], amount: Decimal, creationDate: Da throw new Error(`No Creation found!`) } - if (amount.greaterThan(creations[index])) { + if (amount.greaterThan(creations[index].toString())) { throw new Error( `The amount (${amount} GDD) to be created exceeds the available amount (${creations[index]} GDD) for this month.`, ) diff --git a/backend/src/seeds/graphql/mutations.ts b/backend/src/seeds/graphql/mutations.ts index fc662cf19..601b1fbbf 100644 --- a/backend/src/seeds/graphql/mutations.ts +++ b/backend/src/seeds/graphql/mutations.ts @@ -86,7 +86,7 @@ export const createTransactionLink = gql` export const createPendingCreation = gql` mutation ( $email: String! - $amount: Float! + $amount: Decimal! $memo: String! $creationDate: String! $moderator: Int! From 3c9a12d29311182140cb399e447b70bfd93e5c35 Mon Sep 17 00:00:00 2001 From: ogerly Date: Tue, 26 Apr 2022 11:05:30 +0200 Subject: [PATCH 087/106] open modal only for id --- frontend/src/components/ClipboardCopy.vue | 12 +++++++++++- .../TransactionLinks/TransactionLink.vue | 14 ++++++++++++++ frontend/src/locales/de.json | 2 +- frontend/src/locales/en.json | 2 +- 4 files changed, 27 insertions(+), 3 deletions(-) diff --git a/frontend/src/components/ClipboardCopy.vue b/frontend/src/components/ClipboardCopy.vue index 936f6db1a..e8fb6e084 100644 --- a/frontend/src/components/ClipboardCopy.vue +++ b/frontend/src/components/ClipboardCopy.vue @@ -1,6 +1,6 @@