diff --git a/backend/src/graphql/resolver/TransactionResolver.test.ts b/backend/src/graphql/resolver/TransactionResolver.test.ts index b0e9f34c2..6751aa6ad 100644 --- a/backend/src/graphql/resolver/TransactionResolver.test.ts +++ b/backend/src/graphql/resolver/TransactionResolver.test.ts @@ -1,6 +1,7 @@ /* eslint-disable @typescript-eslint/no-explicit-any */ /* eslint-disable @typescript-eslint/explicit-module-boundary-types */ +import Decimal from 'decimal.js-light' import { EventProtocolType } from '@/event/EventProtocolType' import { userFactory } from '@/seeds/factory/user' import { @@ -118,10 +119,8 @@ describe('send coins', () => { it('logs the error thrown', async () => { // find peter to check the log - const user = await findUserByEmail(peterData.email) - expect(logger.error).toBeCalledWith( - `The recipient account was deleted: recipientUser=${user}`, - ) + const user = await findUserByEmail('stephen@hawking.uk') + expect(logger.error).toBeCalledWith('The recipient account was deleted', user) }) }) @@ -151,10 +150,8 @@ describe('send coins', () => { it('logs the error thrown', async () => { // find peter to check the log - const user = await findUserByEmail(peterData.email) - expect(logger.error).toBeCalledWith( - `The recipient account is not activated: recipientUser=${user}`, - ) + const user = await findUserByEmail('garrick@ollivander.com') + expect(logger.error).toBeCalledWith('The recipient account is not activated', user) }) }) }) @@ -181,37 +178,13 @@ describe('send coins', () => { }), ).toEqual( expect.objectContaining({ - errors: [new GraphQLError('Sender and Recipient are the same.')], + errors: [new GraphQLError('Sender and Recipient are the same')], }), ) }) it('logs the error thrown', () => { - expect(logger.error).toBeCalledWith('Sender and Recipient are the same.') - }) - }) - - describe('memo text is too long', () => { - it('throws an error', async () => { - jest.clearAllMocks() - expect( - await mutate({ - mutation: sendCoins, - variables: { - email: 'peter@lustig.de', - amount: 100, - memo: 'test test test test test test test test test test test test test test test test test test test test test test test test test test test test test test test test test test test test test test test test test test test test test test test test test test test t', - }, - }), - ).toEqual( - expect.objectContaining({ - errors: [new GraphQLError('memo text is too long (255 characters maximum)')], - }), - ) - }) - - it('logs the error thrown', () => { - expect(logger.error).toBeCalledWith('memo text is too long: memo.length=256 > 255') + expect(logger.error).toBeCalledWith('Sender and Recipient are the same', expect.any(Number)) }) }) @@ -229,13 +202,37 @@ describe('send coins', () => { }), ).toEqual( expect.objectContaining({ - errors: [new GraphQLError('memo text is too short (5 characters minimum)')], + errors: [new GraphQLError('Memo text is too short')], }), ) }) it('logs the error thrown', () => { - expect(logger.error).toBeCalledWith('memo text is too short: memo.length=4 < 5') + expect(logger.error).toBeCalledWith('Memo text is too short', 4) + }) + }) + + describe('memo text is too long', () => { + it('throws an error', async () => { + jest.clearAllMocks() + expect( + await mutate({ + mutation: sendCoins, + variables: { + email: 'peter@lustig.de', + amount: 100, + memo: 'test test test test test test test test test test test test test test test test test test test test test test test test test test test test test test test test test test test test test test test test test test test test test test test test test test test t', + }, + }), + ).toEqual( + expect.objectContaining({ + errors: [new GraphQLError('Memo text is too long')], + }), + ) + }) + + it('logs the error thrown', () => { + expect(logger.error).toBeCalledWith('Memo text is too long', 256) }) }) @@ -253,15 +250,13 @@ describe('send coins', () => { }), ).toEqual( expect.objectContaining({ - errors: [new GraphQLError(`user hasn't enough GDD or amount is < 0`)], + errors: [new GraphQLError('User has not enough GDD or amount is < 0')], }), ) }) it('logs the error thrown', () => { - expect(logger.error).toBeCalledWith( - `user hasn't enough GDD or amount is < 0 : balance=null`, - ) + expect(logger.error).toBeCalledWith('User has not enough GDD or amount is < 0', null) }) }) }) @@ -293,6 +288,7 @@ describe('send coins', () => { describe('trying to send negative amount', () => { it('throws an error', async () => { + jest.clearAllMocks() expect( await mutate({ mutation: sendCoins, @@ -304,13 +300,13 @@ describe('send coins', () => { }), ).toEqual( expect.objectContaining({ - errors: [new GraphQLError(`Amount to send must be positive`)], + errors: [new GraphQLError('Amount to send must be positive')], }), ) }) it('logs the error thrown', () => { - expect(logger.error).toBeCalledWith(`Amount to send must be positive`) + expect(logger.error).toBeCalledWith('Amount to send must be positive', new Decimal(-50)) }) }) diff --git a/backend/src/graphql/resolver/TransactionResolver.ts b/backend/src/graphql/resolver/TransactionResolver.ts index 46fb812f7..9d5a1d38c 100644 --- a/backend/src/graphql/resolver/TransactionResolver.ts +++ b/backend/src/graphql/resolver/TransactionResolver.ts @@ -36,6 +36,7 @@ import { MEMO_MAX_CHARS, MEMO_MIN_CHARS } from './const/const' import { findUserByEmail } from './UserResolver' import { TRANSACTIONS_LOCK } from '@/util/TRANSACTIONS_LOCK' +import LogError from '@/server/LogError' import { getLastTransaction } from './util/getLastTransaction' @@ -54,18 +55,15 @@ export const executeTransaction = async ( ) if (sender.id === recipient.id) { - logger.error(`Sender and Recipient are the same.`) - throw new Error('Sender and Recipient are the same.') - } - - if (memo.length > MEMO_MAX_CHARS) { - logger.error(`memo text is too long: memo.length=${memo.length} > ${MEMO_MAX_CHARS}`) - throw new Error(`memo text is too long (${MEMO_MAX_CHARS} characters maximum)`) + throw new LogError('Sender and Recipient are the same', sender.id) } if (memo.length < MEMO_MIN_CHARS) { - logger.error(`memo text is too short: memo.length=${memo.length} < ${MEMO_MIN_CHARS}`) - throw new Error(`memo text is too short (${MEMO_MIN_CHARS} characters minimum)`) + throw new LogError('Memo text is too short', memo.length) + } + + if (memo.length > MEMO_MAX_CHARS) { + throw new LogError('Memo text is too long', memo.length) } // validate amount @@ -78,8 +76,7 @@ export const executeTransaction = async ( ) logger.debug(`calculated Balance=${sendBalance}`) if (!sendBalance) { - logger.error(`user hasn't enough GDD or amount is < 0 : balance=${sendBalance}`) - throw new Error("user hasn't enough GDD or amount is < 0") + throw new LogError('User has not enough GDD or amount is < 0', sendBalance) } const queryRunner = getConnection().createQueryRunner() @@ -155,8 +152,7 @@ export const executeTransaction = async ( ) } catch (e) { await queryRunner.rollbackTransaction() - logger.error(`Transaction was not successful: ${e}`) - throw new Error(`Transaction was not successful: ${e}`) + throw new LogError('Transaction was not successful', e) } finally { await queryRunner.release() } @@ -315,8 +311,7 @@ export class TransactionResolver { ): Promise { logger.info(`sendCoins(email=${email}, amount=${amount}, memo=${memo})`) if (amount.lte(0)) { - logger.error(`Amount to send must be positive`) - throw new Error('Amount to send must be positive') + throw new LogError('Amount to send must be positive', amount) } // TODO this is subject to replay attacks @@ -325,13 +320,11 @@ export class TransactionResolver { // validate recipient user const recipientUser = await findUserByEmail(email) if (recipientUser.deletedAt) { - logger.error(`The recipient account was deleted: recipientUser=${recipientUser}`) - throw new Error('The recipient account was deleted') + throw new LogError('The recipient account was deleted', recipientUser) } const emailContact = recipientUser.emailContact if (!emailContact.emailChecked) { - logger.error(`The recipient account is not activated: recipientUser=${recipientUser}`) - throw new Error('The recipient account is not activated') + throw new LogError('The recipient account is not activated', recipientUser) } await executeTransaction(amount, memo, senderUser, recipientUser) diff --git a/frontend/src/components/LinkInformations/RedeemLoggedOut.vue b/frontend/src/components/LinkInformations/RedeemLoggedOut.vue index bbad3f9fb..34c31af5a 100644 --- a/frontend/src/components/LinkInformations/RedeemLoggedOut.vue +++ b/frontend/src/components/LinkInformations/RedeemLoggedOut.vue @@ -3,20 +3,20 @@ -
+

{{ $t('gdd_per_link.redeem') }}

- +

{{ $t('gdd_per_link.no-account') }}

{{ $t('gdd_per_link.to-register') }}
- +

{{ $t('gdd_per_link.has-account') }}

- {{ $t('gdd_per_link.to-login') }} + {{ $t('gdd_per_link.to-login') }}
diff --git a/frontend/src/components/LinkInformations/RedeemValid.vue b/frontend/src/components/LinkInformations/RedeemValid.vue index c468a396a..39485b10e 100644 --- a/frontend/src/components/LinkInformations/RedeemValid.vue +++ b/frontend/src/components/LinkInformations/RedeemValid.vue @@ -3,7 +3,7 @@
- + {{ $t('gdd_per_link.redeem') }}
diff --git a/frontend/src/pages/Login.vue b/frontend/src/pages/Login.vue index bd07af3ef..c615d4d16 100755 --- a/frontend/src/pages/Login.vue +++ b/frontend/src/pages/Login.vue @@ -23,15 +23,17 @@ - - + + {{ $t('settings.password.forgot_pwd') }} -
- {{ $t('login') }} -
+ + + {{ $t('login') }} + + diff --git a/frontend/src/pages/Register.vue b/frontend/src/pages/Register.vue index eb68ee7c5..eaebb9ed1 100755 --- a/frontend/src/pages/Register.vue +++ b/frontend/src/pages/Register.vue @@ -68,25 +68,30 @@ > -
- - - - -
-
- - {{ $t('signup') }} - -
+ + + + + + + + + + + + {{ $t('signup') }} + + + diff --git a/frontend/src/pages/TransactionLink.vue b/frontend/src/pages/TransactionLink.vue index c3875d20e..764f48494 100644 --- a/frontend/src/pages/TransactionLink.vue +++ b/frontend/src/pages/TransactionLink.vue @@ -1,6 +1,6 @@