From 07a80b2df76c91a588b2ce17c5e5a5626a5c4fc1 Mon Sep 17 00:00:00 2001 From: einhornimmond Date: Thu, 4 Dec 2025 13:01:01 +0100 Subject: [PATCH 1/2] linting --- backend/src/apis/HttpRequest.ts | 3 +- backend/src/apis/KlicktippController.ts | 4 +- .../dltConnector/DltConnectorClient.test.ts | 2 - .../apis/dltConnector/DltConnectorClient.ts | 22 +- .../__mocks__/DltConnectorClient.ts | 7 +- backend/src/apis/dltConnector/index.ts | 100 ++++--- .../dltConnector/model/TransactionDraft.ts | 92 +++++-- backend/src/apis/gms/ExportUsers.ts | 7 +- backend/src/apis/gms/GmsClient.ts | 9 +- backend/src/apis/humhub/ExportUsers.ts | 3 +- backend/src/apis/humhub/HumHubClient.ts | 5 +- backend/src/apis/humhub/syncUser.ts | 6 +- backend/src/apis/openai/OpenaiClient.ts | 24 +- backend/src/auth/JWT.ts | 2 +- backend/src/config/const.ts | 2 +- backend/src/config/schema.ts | 6 +- backend/src/data/UserLogic.ts | 3 +- backend/src/event/Events.ts | 16 +- .../src/federation/authenticateCommunities.ts | 62 +++-- .../client/1_0/AuthenticationClient.ts | 7 +- .../client/1_0/DisbursementClient.ts | 10 +- .../federation/client/1_0/FederationClient.ts | 5 +- .../client/AuthenticationClientFactory.ts | 8 +- .../client/DisbursementClientFactory.ts | 3 +- .../client/FederationClientFactory.ts | 3 +- .../federation/validateCommunities.test.ts | 8 +- backend/src/federation/validateCommunities.ts | 63 +++-- .../graphql/arg/ContributionMessageArgs.ts | 3 +- backend/src/graphql/arg/Paginated.ts | 3 +- .../arg/SearchContributionsFilterArgs.ts | 3 +- backend/src/graphql/arg/SetUserRoleArgs.ts | 3 +- .../src/graphql/arg/UpdateUserInfosArgs.ts | 5 +- backend/src/graphql/arg/UserArgs.ts | 2 +- backend/src/graphql/directive/isAuthorized.ts | 5 +- .../src/graphql/enum/ContributionCycleType.ts | 2 +- .../src/graphql/enum/ContributionStatus.ts | 2 +- backend/src/graphql/enum/ContributionType.ts | 2 +- .../graphql/enum/PendingTransactionState.ts | 2 +- backend/src/graphql/enum/RoleNames.ts | 2 +- .../src/graphql/input/EditCommunityInput.ts | 2 +- .../src/graphql/model/ContributionLinkList.ts | 3 +- .../src/graphql/model/FederatedCommunity.ts | 3 +- backend/src/graphql/model/GdtEntry.ts | 3 +- backend/src/graphql/model/RedeemJwtLink.ts | 3 +- backend/src/graphql/model/Transaction.ts | 3 +- backend/src/graphql/model/User.ts | 5 +- .../src/graphql/resolver/AiChatResolver.ts | 22 +- .../src/graphql/resolver/BalanceResolver.ts | 21 +- .../resolver/CommunityResolver.test.ts | 38 +-- .../src/graphql/resolver/CommunityResolver.ts | 31 +-- .../resolver/ContributionLinkResolver.test.ts | 9 +- .../resolver/ContributionLinkResolver.ts | 9 +- .../ContributionMessageResolver.test.ts | 19 +- .../resolver/ContributionMessageResolver.ts | 23 +- .../resolver/ContributionResolver.test.ts | 27 +- .../graphql/resolver/ContributionResolver.ts | 92 ++++--- .../graphql/resolver/EmailOptinCodes.test.ts | 9 +- backend/src/graphql/resolver/GdtResolver.ts | 10 +- .../resolver/KlicktippResolver.test.ts | 9 +- .../resolver/ProjectBrandingResolver.ts | 10 +- .../graphql/resolver/StatisticsResolver.ts | 8 +- .../resolver/TransactionLinkResolver.test.ts | 16 +- .../resolver/TransactionLinkResolver.ts | 189 ++++++++----- .../resolver/TransactionResolver.test.ts | 14 +- .../graphql/resolver/TransactionResolver.ts | 69 +++-- .../src/graphql/resolver/UserResolver.test.ts | 58 ++-- backend/src/graphql/resolver/UserResolver.ts | 145 +++++----- backend/src/graphql/resolver/const/const.ts | 2 +- .../src/graphql/resolver/semaphore.test.ts | 23 +- .../graphql/resolver/util/Location2Point.ts | 3 +- .../util/authenticateGmsUserPlayground.ts | 7 +- .../src/graphql/resolver/util/communities.ts | 3 +- .../util/compareGmsRelevantUserSettings.ts | 6 +- .../graphql/resolver/util/contributions.ts | 6 +- .../graphql/resolver/util/creations.test.ts | 8 +- .../src/graphql/resolver/util/creations.ts | 13 +- .../resolver/util/extractGraphQLFields.ts | 2 +- .../resolver/util/findContributionMessages.ts | 5 +- .../resolver/util/findContributions.ts | 5 +- .../src/graphql/resolver/util/findUsers.ts | 5 +- .../resolver/util/getKlicktippState.ts | 3 +- .../resolver/util/getTransactionList.ts | 3 +- .../graphql/resolver/util/sendUserToGms.ts | 3 +- .../graphql/resolver/util/syncHumhub.test.ts | 6 +- .../src/graphql/resolver/util/syncHumhub.ts | 8 +- .../resolver/util/transactionLinkList.ts | 5 +- backend/src/graphql/scalar/Location.ts | 3 +- backend/src/graphql/schema.ts | 3 +- backend/src/graphql/union/QueryLinkResult.ts | 3 +- .../validator/ContributionStatusArray.ts | 3 +- backend/src/graphql/validator/DateString.ts | 2 +- backend/src/graphql/validator/Decimal.ts | 2 +- backend/src/graphql/validator/HieroId.ts | 2 +- backend/src/graphql/validator/Location.ts | 3 +- backend/src/index.ts | 6 +- .../AbstractUnconfirmedContribution.role.ts | 11 +- .../UpdateUnconfirmedContribution.context.ts | 7 +- backend/src/openIDConnect/index.ts | 21 +- backend/src/password/EncryptorUtils.ts | 10 +- backend/src/password/PasswordEncryptor.ts | 2 +- .../src/password/__mocks__/EncryptorUtils.ts | 14 +- backend/src/seeds/contributionLink/index.ts | 2 +- .../src/seeds/creation/CreationInterface.ts | 4 +- backend/src/seeds/creation/index.ts | 3 +- backend/src/seeds/factory/contributionLink.ts | 11 +- backend/src/seeds/factory/creation.ts | 8 +- backend/src/seeds/factory/transactionLink.ts | 8 +- backend/src/seeds/factory/user.ts | 17 +- backend/src/seeds/index.ts | 22 +- .../TransactionLinkInterface.ts | 2 +- backend/src/seeds/transactionLink/index.ts | 2 +- backend/src/seeds/users/UserInterface.ts | 2 +- backend/src/seeds/users/bibi-bloxberg.ts | 2 +- backend/src/seeds/users/bob-baumeister.ts | 2 +- backend/src/seeds/users/garrick-ollivander.ts | 3 +- backend/src/seeds/users/peter-lustig.ts | 2 +- .../src/seeds/users/raeuber-hotzenplotz.ts | 3 +- backend/src/seeds/users/stephen-hawking.ts | 2 +- backend/src/server/LogError.test.ts | 2 +- backend/src/server/LogError.ts | 2 +- backend/src/server/createServer.ts | 17 +- backend/src/server/logger.ts | 2 +- backend/src/util/Monitor.ts | 3 +- backend/src/util/communityUser.ts | 6 +- backend/src/util/executeKlicktipp.ts | 3 +- backend/src/util/klicktipp.test.ts | 8 +- backend/src/util/validate.ts | 16 +- backend/src/util/virtualTransactions.ts | 10 +- backend/src/webhook/elopage.ts | 5 +- backend/src/webhook/gms.ts | 3 +- biome.json | 10 +- config-schema/src/index.ts | 9 +- .../src/log4js-config/coloredContext.ts | 4 +- config-schema/src/log4js-config/index.ts | 2 +- .../src/log4js-config/types/index.ts | 2 +- config-schema/src/validate.ts | 18 +- core/src/config/index.ts | 3 - core/src/config/schema.ts | 5 +- core/src/emails/index.ts | 2 +- core/src/emails/sendEmailTranslated.test.ts | 8 +- core/src/emails/sendEmailTranslated.ts | 14 +- core/src/emails/sendEmailVariants.test.ts | 7 +- core/src/emails/sendEmailVariants.ts | 79 +++--- .../federation/client/1_0/SendCoinsClient.ts | 11 +- .../client/1_0/query/voteForSendCoins.ts | 1 - .../client/SendCoinsClientFactory.ts | 3 +- core/src/graphql/enum/TransactionTypeId.ts | 2 +- core/src/graphql/logging/DecayLogging.view.ts | 3 +- .../logic/interpretEncryptedTransferArgs.ts | 24 +- .../src/graphql/logic/processXComSendCoins.ts | 185 +++++++------ .../logic/settlePendingSenderTransaction.ts | 22 +- core/src/graphql/logic/storeForeignUser.ts | 10 +- core/src/graphql/logic/storeLinkAsRedeemed.ts | 26 +- core/src/graphql/model/Decay.ts | 2 +- core/src/index.ts | 11 +- core/src/locales/localization.test.ts | 2 +- core/src/locales/localization.ts | 5 +- .../logic/CommunityHandshakeState.logic.ts | 2 +- .../CommunityHandshakeStateLogic.test.ts | 7 +- core/src/logic/community.logic.ts | 2 +- core/src/logic/index.ts | 2 +- core/src/types/images.d.ts | 4 +- core/src/util/calculateSenderBalance.ts | 11 +- core/src/util/utilities.ts | 11 +- core/src/validation/user.test.ts | 16 +- core/src/validation/user.ts | 6 +- .../0094-openai_threads_add_updated_at.ts | 3 +- ...95-add_community_handshake_states_table.ts | 2 +- database/src/AppDatabase.ts | 9 +- database/src/entity/Community.ts | 2 +- .../src/entity/CommunityHandshakeState.ts | 11 +- database/src/entity/Contribution.ts | 2 +- database/src/entity/Event.ts | 2 +- database/src/entity/OpenaiThreads.ts | 9 +- database/src/entity/User.ts | 2 +- database/src/entity/index.ts | 4 +- .../src/enum/CommunityHandshakeStateType.ts | 8 +- database/src/enum/RoleNames.ts | 2 +- database/src/enum/index.ts | 8 +- database/src/index.ts | 6 +- database/src/logging/AbstractLogging.view.ts | 3 +- .../CommunityHandshakeStateLogging.view.ts | 6 +- database/src/logging/CommunityLogging.view.ts | 4 +- .../logging/PendingTransactionLogging.view.ts | 2 +- database/src/logging/index.ts | 2 +- database/src/queries/communities.test.ts | 20 +- database/src/queries/communities.ts | 36 +-- .../src/queries/communityHandshakes.test.ts | 35 +-- database/src/queries/communityHandshakes.ts | 29 +- database/src/queries/index.ts | 6 +- .../src/queries/pendingTransactions.test.ts | 79 +++--- database/src/queries/pendingTransactions.ts | 6 +- database/src/queries/transactionLinks.ts | 2 +- database/src/queries/user.test.ts | 37 +-- database/src/queries/user.ts | 17 +- database/src/seeds/community.ts | 74 ++--- .../src/seeds/factory/contributionLink.ts | 16 +- database/src/seeds/factory/creation.ts | 58 ++-- .../src/seeds/factory/pendingTransaction.ts | 8 +- database/src/seeds/factory/transaction.ts | 18 +- database/src/seeds/factory/transactionLink.ts | 31 ++- database/src/seeds/factory/user.ts | 75 ++++-- database/src/seeds/users/index.ts | 16 +- database/src/seeds/users/peter-lustig.ts | 2 +- dht-node/src/config/index.ts | 2 +- dht-node/src/config/schema.ts | 2 +- dht-node/src/dht_node/index.test.ts | 7 +- dht-node/src/dht_node/index.ts | 4 +- dht-node/src/index.ts | 7 +- .../src/client/1_0/AuthenticationClient.ts | 25 +- .../src/client/AuthenticationClientFactory.ts | 8 +- federation/src/config/index.ts | 6 +- federation/src/config/schema.ts | 2 +- .../api/1_0/enum/PendingTransactionState.ts | 2 +- ...etPublicCommunityInfoResultLogging.view.ts | 2 +- .../1_0/logger/SendCoinsArgsLogging.view.ts | 2 +- federation/src/graphql/api/1_0/model/Decay.ts | 2 +- .../1_0/resolver/AuthenticationResolver.ts | 119 ++++++--- .../api/1_0/resolver/DisbursementResolver.ts | 55 ++-- .../PublicCommunityInfoResolver.test.ts | 4 +- .../resolver/PublicCommunityInfoResolver.ts | 4 +- .../1_0/resolver/PublicKeyResolver.test.ts | 6 +- .../1_0/resolver/SendCoinsResolver.test.ts | 248 ++++++++++++----- .../api/1_0/resolver/SendCoinsResolver.ts | 124 +++++---- federation/src/graphql/api/1_0/schema.ts | 8 +- .../api/1_0/util/authenticateCommunity.ts | 109 +++++--- .../api/1_0/util/calculateRecipientBalance.ts | 6 +- .../util/revertSettledReceiveTransaction.ts | 16 +- .../util/settlePendingReceiveTransaction.ts | 16 +- .../1_1/resolver/PublicKeyResolver.test.ts | 6 +- federation/src/graphql/schema.ts | 3 +- .../src/graphql/util/checkTradingLevel.ts | 2 +- federation/src/index.ts | 10 +- federation/src/server/LogError.ts | 2 +- federation/src/server/createServer.ts | 17 +- shared/src/const/index.ts | 2 +- shared/src/enum/OptInType.ts | 2 +- shared/src/enum/PasswordEncryptionType.ts | 1 - shared/src/enum/index.ts | 6 +- shared/src/helper/BinaryData.ts | 4 +- shared/src/helper/index.ts | 4 +- shared/src/helper/onShutdown.ts | 17 +- shared/src/helper/updateField.test.ts | 5 +- shared/src/helper/updateField.ts | 27 +- shared/src/index.ts | 12 +- shared/src/jwt/JWT.test.ts | 252 +++++++++++------- shared/src/jwt/JWT.ts | 81 ++++-- .../AuthenticationJwtPayloadType.ts | 6 +- .../AuthenticationResponseJwtPayloadType.ts | 5 +- .../EncryptedJWEJwtPayloadType.ts | 5 +- .../OpenConnectionCallbackJwtPayloadType.ts | 6 +- .../OpenConnectionJwtPayloadType.ts | 5 +- .../payloadtypes/SendCoinsJwtPayloadType.ts | 2 +- .../payloadtypes/SignedTransferPayloadType.ts | 6 +- shared/src/logic/decay.test.ts | 17 +- shared/src/logic/decay.ts | 20 +- shared/src/schema/base.schema.test.ts | 2 +- shared/src/schema/base.schema.ts | 7 +- shared/src/schema/community.schema.test.ts | 3 +- shared/src/schema/community.schema.ts | 2 +- shared/src/schema/index.ts | 4 +- shared/src/schema/user.schema.test.ts | 138 +++++----- shared/src/schema/user.schema.ts | 6 +- shared/src/util/index.ts | 2 +- 264 files changed, 2465 insertions(+), 1939 deletions(-) diff --git a/backend/src/apis/HttpRequest.ts b/backend/src/apis/HttpRequest.ts index 9a775ee28..8ac73880c 100644 --- a/backend/src/apis/HttpRequest.ts +++ b/backend/src/apis/HttpRequest.ts @@ -1,8 +1,7 @@ import axios from 'axios' - +import { getLogger } from 'log4js' import { LOG4JS_BASE_CATEGORY_NAME } from '@/config/const' import { LogError } from '@/server/LogError' -import { getLogger } from 'log4js' const logger = getLogger(`${LOG4JS_BASE_CATEGORY_NAME}.apis.HttpRequest`) diff --git a/backend/src/apis/KlicktippController.ts b/backend/src/apis/KlicktippController.ts index 5a33df9ae..bb3b2fa88 100644 --- a/backend/src/apis/KlicktippController.ts +++ b/backend/src/apis/KlicktippController.ts @@ -1,7 +1,7 @@ -import { LOG4JS_BASE_CATEGORY_NAME } from '@/config/const' -import { CONFIG } from '@/config' import KlicktippConnector from 'klicktipp-api' import { getLogger } from 'log4js' +import { CONFIG } from '@/config' +import { LOG4JS_BASE_CATEGORY_NAME } from '@/config/const' const klicktippConnector = new KlicktippConnector() const logger = getLogger(`${LOG4JS_BASE_CATEGORY_NAME}.apis.KlicktippController`) diff --git a/backend/src/apis/dltConnector/DltConnectorClient.test.ts b/backend/src/apis/dltConnector/DltConnectorClient.test.ts index 55acb6e04..bbaba5b98 100644 --- a/backend/src/apis/dltConnector/DltConnectorClient.test.ts +++ b/backend/src/apis/dltConnector/DltConnectorClient.test.ts @@ -18,5 +18,3 @@ describe('undefined DltConnectorClient', () => { CONFIG.DLT_ACTIVE = true }) }) - - diff --git a/backend/src/apis/dltConnector/DltConnectorClient.ts b/backend/src/apis/dltConnector/DltConnectorClient.ts index 2a1ced85d..52d0e6594 100644 --- a/backend/src/apis/dltConnector/DltConnectorClient.ts +++ b/backend/src/apis/dltConnector/DltConnectorClient.ts @@ -1,9 +1,8 @@ +import { getLogger } from 'log4js' +import { IRestResponse, RestClient } from 'typed-rest-client' import { CONFIG } from '@/config' import { LOG4JS_BASE_CATEGORY_NAME } from '@/config/const' -import { getLogger } from 'log4js' - import { TransactionDraft } from './model/TransactionDraft' -import { IRestResponse, RestClient } from 'typed-rest-client' const logger = getLogger(`${LOG4JS_BASE_CATEGORY_NAME}.apis.dltConnector`) @@ -41,10 +40,10 @@ export class DltConnectorClient { if (!DltConnectorClient.instance.client) { try { DltConnectorClient.instance.client = new RestClient( - 'gradido-backend', - CONFIG.DLT_CONNECTOR_URL, - undefined, - { keepAlive: true } + 'gradido-backend', + CONFIG.DLT_CONNECTOR_URL, + undefined, + { keepAlive: true }, ) } catch (e) { logger.error("couldn't connect to dlt-connector: ", e) @@ -58,11 +57,10 @@ export class DltConnectorClient { * transmit transaction via dlt-connector to hiero * and update dltTransactionId of transaction in db with hiero transaction id */ - public async sendTransaction(input: TransactionDraft): Promise> { + public async sendTransaction( + input: TransactionDraft, + ): Promise> { logger.debug('transmit transaction or user to dlt connector', input) - return await this.client.create<{ transactionId: string }>( - '/sendTransaction', - input - ) + return await this.client.create<{ transactionId: string }>('/sendTransaction', input) } } diff --git a/backend/src/apis/dltConnector/__mocks__/DltConnectorClient.ts b/backend/src/apis/dltConnector/__mocks__/DltConnectorClient.ts index 5a2c96d79..5bde24108 100644 --- a/backend/src/apis/dltConnector/__mocks__/DltConnectorClient.ts +++ b/backend/src/apis/dltConnector/__mocks__/DltConnectorClient.ts @@ -1,9 +1,8 @@ +import { getLogger } from 'log4js' +import { IRestResponse } from 'typed-rest-client' +import { TransactionDraft } from '@/apis/dltConnector/model/TransactionDraft' import { CONFIG } from '@/config' import { LOG4JS_BASE_CATEGORY_NAME } from '@/config/const' -import { getLogger } from 'log4js' - -import { TransactionDraft } from '@/apis/dltConnector/model/TransactionDraft' -import { IRestResponse } from 'typed-rest-client' const logger = getLogger(`${LOG4JS_BASE_CATEGORY_NAME}.apis.dltConnector`) diff --git a/backend/src/apis/dltConnector/index.ts b/backend/src/apis/dltConnector/index.ts index ae7d138ef..bd4016bdf 100644 --- a/backend/src/apis/dltConnector/index.ts +++ b/backend/src/apis/dltConnector/index.ts @@ -1,28 +1,30 @@ -import { IRestResponse } from 'typed-rest-client' -import { DltTransactionType } from './enum/DltTransactionType' -import { getLogger } from 'log4js' -import { LOG4JS_BASE_CATEGORY_NAME } from '@/config/const' -import { DltConnectorClient } from './DltConnectorClient' -import { - Community as DbCommunity, +import { + Community as DbCommunity, Contribution as DbContribution, - DltTransaction as DbDltTransaction, + DltTransaction as DbDltTransaction, TransactionLink as DbTransactionLink, User as DbUser, getCommunityByUuid, getHomeCommunity, getUserById, - UserLoggingView, + UserLoggingView, } from 'database' -import { TransactionDraft } from './model/TransactionDraft' +import { getLogger } from 'log4js' +import { IRestResponse } from 'typed-rest-client' import { CONFIG } from '@/config' +import { LOG4JS_BASE_CATEGORY_NAME } from '@/config/const' +import { DltConnectorClient } from './DltConnectorClient' +import { DltTransactionType } from './enum/DltTransactionType' +import { TransactionDraft } from './model/TransactionDraft' const logger = getLogger(`${LOG4JS_BASE_CATEGORY_NAME}.dltConnector`) // will be undefined if dlt connect is disabled const dltConnectorClient = DltConnectorClient.getInstance() -async function checkDltConnectorResult(dltTransaction: DbDltTransaction, clientResponse: Promise>) - : Promise { +async function checkDltConnectorResult( + dltTransaction: DbDltTransaction, + clientResponse: Promise>, +): Promise { // check result from dlt connector try { const response = await clientResponse @@ -31,7 +33,7 @@ async function checkDltConnectorResult(dltTransaction: DbDltTransaction, clientR } else { dltTransaction.error = `empty result with status code ${response.statusCode}` logger.error('error from dlt-connector', response) - } + } } catch (e) { logger.debug(e) if (e instanceof Error) { @@ -47,8 +49,12 @@ async function checkDltConnectorResult(dltTransaction: DbDltTransaction, clientR return dltTransaction } -async function executeDltTransaction(draft: TransactionDraft | null, typeId: DltTransactionType, persist = true): Promise { - if (draft && dltConnectorClient) { +async function executeDltTransaction( + draft: TransactionDraft | null, + typeId: DltTransactionType, + persist = true, +): Promise { + if (draft && dltConnectorClient) { const clientResponse = dltConnectorClient.sendTransaction(draft) let dltTransaction = new DbDltTransaction() dltTransaction.typeId = typeId @@ -63,30 +69,39 @@ async function executeDltTransaction(draft: TransactionDraft | null, typeId: Dlt /** * send register address transaction via dlt-connector to hiero - * and update dltTransactionId of transaction in db with hiero transaction id + * and update dltTransactionId of transaction in db with hiero transaction id */ -export async function registerAddressTransaction(user: DbUser, community: DbCommunity): Promise { +export async function registerAddressTransaction( + user: DbUser, + community: DbCommunity, +): Promise { if (!CONFIG.DLT_ACTIVE) { return Promise.resolve(null) } if (!user.id) { - logger.error(`missing id for user: ${user.gradidoID}, please call registerAddressTransaction after user.save()`) + logger.error( + `missing id for user: ${user.gradidoID}, please call registerAddressTransaction after user.save()`, + ) return null } // return null if some data where missing and log error const draft = TransactionDraft.createRegisterAddress(user, community) - const dltTransaction = await executeDltTransaction(draft, DltTransactionType.REGISTER_ADDRESS, false) + const dltTransaction = await executeDltTransaction( + draft, + DltTransactionType.REGISTER_ADDRESS, + false, + ) if (dltTransaction) { if (user.id) { dltTransaction.userId = user.id } return await dltTransaction.save() - } - return null + } + return null } export async function contributionTransaction( - contribution: DbContribution, + contribution: DbContribution, signingUser: DbUser, createdAt: Date, ): Promise { @@ -98,16 +113,21 @@ export async function contributionTransaction( logger.error('home community not found') return null } - const draft = TransactionDraft.createContribution(contribution, createdAt, signingUser, homeCommunity) + const draft = TransactionDraft.createContribution( + contribution, + createdAt, + signingUser, + homeCommunity, + ) return await executeDltTransaction(draft, DltTransactionType.CREATION) } export async function transferTransaction( - senderUser: DbUser, - recipientUser: DbUser, - amount: string, - memo: string, - createdAt: Date + senderUser: DbUser, + recipientUser: DbUser, + amount: string, + memo: string, + createdAt: Date, ): Promise { if (!CONFIG.DLT_ACTIVE) { return Promise.resolve(null) @@ -125,8 +145,10 @@ export async function transferTransaction( return await executeDltTransaction(draft, DltTransactionType.TRANSFER) } -export async function deferredTransferTransaction(senderUser: DbUser, transactionLink: DbTransactionLink) -: Promise { +export async function deferredTransferTransaction( + senderUser: DbUser, + transactionLink: DbTransactionLink, +): Promise { if (!CONFIG.DLT_ACTIVE) { return Promise.resolve(null) } @@ -138,8 +160,12 @@ export async function deferredTransferTransaction(senderUser: DbUser, transactio return await executeDltTransaction(draft, DltTransactionType.DEFERRED_TRANSFER) } -export async function redeemDeferredTransferTransaction(transactionLink: DbTransactionLink, amount: string, createdAt: Date, recipientUser: DbUser) -: Promise { +export async function redeemDeferredTransferTransaction( + transactionLink: DbTransactionLink, + amount: string, + createdAt: Date, + recipientUser: DbUser, +): Promise { if (!CONFIG.DLT_ACTIVE) { return Promise.resolve(null) } @@ -158,9 +184,11 @@ export async function redeemDeferredTransferTransaction(transactionLink: DbTrans } logger.debug(`sender: ${new UserLoggingView(transactionLink.user)}`) logger.debug(`recipient: ${new UserLoggingView(recipientUser)}`) - const draft = TransactionDraft.redeemDeferredTransfer(transactionLink, amount, createdAt, recipientUser) + const draft = TransactionDraft.redeemDeferredTransfer( + transactionLink, + amount, + createdAt, + recipientUser, + ) return await executeDltTransaction(draft, DltTransactionType.REDEEM_DEFERRED_TRANSFER) } - - - diff --git a/backend/src/apis/dltConnector/model/TransactionDraft.ts b/backend/src/apis/dltConnector/model/TransactionDraft.ts index 0fae08297..1727c7fd8 100755 --- a/backend/src/apis/dltConnector/model/TransactionDraft.ts +++ b/backend/src/apis/dltConnector/model/TransactionDraft.ts @@ -1,18 +1,17 @@ // https://www.npmjs.com/package/@apollo/protobufjs import { AccountType } from '@dltConnector/enum/AccountType' import { TransactionType } from '@dltConnector/enum/TransactionType' - -import { AccountIdentifier } from './AccountIdentifier' -import { - Community as DbCommunity, - Contribution as DbContribution, - TransactionLink as DbTransactionLink, - User as DbUser +import { + Community as DbCommunity, + Contribution as DbContribution, + TransactionLink as DbTransactionLink, + User as DbUser, } from 'database' -import { CommunityAccountIdentifier } from './CommunityAccountIdentifier' import { getLogger } from 'log4js' import { LOG4JS_BASE_CATEGORY_NAME } from '@/config/const' import { CODE_VALID_DAYS_DURATION } from '@/graphql/resolver/const/const' +import { AccountIdentifier } from './AccountIdentifier' +import { CommunityAccountIdentifier } from './CommunityAccountIdentifier' const logger = getLogger(`${LOG4JS_BASE_CATEGORY_NAME}.dltConnector.model.TransactionDraft`) @@ -35,22 +34,36 @@ export class TransactionDraft { static createRegisterAddress(user: DbUser, community: DbCommunity): TransactionDraft | null { if (community.hieroTopicId) { const draft = new TransactionDraft() - draft.user = new AccountIdentifier(community.hieroTopicId, new CommunityAccountIdentifier(user.gradidoID)) + draft.user = new AccountIdentifier( + community.hieroTopicId, + new CommunityAccountIdentifier(user.gradidoID), + ) draft.type = TransactionType.REGISTER_ADDRESS draft.createdAt = user.createdAt.toISOString() draft.accountType = AccountType.COMMUNITY_HUMAN return draft } else { - logger.warn(`missing topicId for community ${community.id}`) + logger.warn(`missing topicId for community ${community.id}`) } return null } - static createContribution(contribution: DbContribution, createdAt: Date, signingUser: DbUser, community: DbCommunity): TransactionDraft | null { + static createContribution( + contribution: DbContribution, + createdAt: Date, + signingUser: DbUser, + community: DbCommunity, + ): TransactionDraft | null { if (community.hieroTopicId) { const draft = new TransactionDraft() - draft.user = new AccountIdentifier(community.hieroTopicId, new CommunityAccountIdentifier(contribution.user.gradidoID)) - draft.linkedUser = new AccountIdentifier(community.hieroTopicId, new CommunityAccountIdentifier(signingUser.gradidoID)) + draft.user = new AccountIdentifier( + community.hieroTopicId, + new CommunityAccountIdentifier(contribution.user.gradidoID), + ) + draft.linkedUser = new AccountIdentifier( + community.hieroTopicId, + new CommunityAccountIdentifier(signingUser.gradidoID), + ) draft.type = TransactionType.GRADIDO_CREATION draft.createdAt = createdAt.toISOString() draft.amount = contribution.amount.toString() @@ -58,23 +71,37 @@ export class TransactionDraft { draft.targetDate = contribution.contributionDate.toISOString() return draft } else { - logger.warn(`missing topicId for community ${community.id}`) + logger.warn(`missing topicId for community ${community.id}`) } return null } - static createTransfer(sendingUser: DbUser, receivingUser: DbUser, amount: string, memo: string, createdAt: Date): TransactionDraft | null { - if (!sendingUser.community || !receivingUser.community) { + static createTransfer( + sendingUser: DbUser, + receivingUser: DbUser, + amount: string, + memo: string, + createdAt: Date, + ): TransactionDraft | null { + if (!sendingUser.community || !receivingUser.community) { throw new Error(`missing community for user ${sendingUser.id} and/or ${receivingUser.id}`) } const senderUserTopic = sendingUser.community.hieroTopicId const receiverUserTopic = receivingUser.community.hieroTopicId if (!senderUserTopic || !receiverUserTopic) { - throw new Error(`missing topicId for community ${sendingUser.community.id} and/or ${receivingUser.community.id}`) + throw new Error( + `missing topicId for community ${sendingUser.community.id} and/or ${receivingUser.community.id}`, + ) } const draft = new TransactionDraft() - draft.user = new AccountIdentifier(senderUserTopic, new CommunityAccountIdentifier(sendingUser.gradidoID)) - draft.linkedUser = new AccountIdentifier(receiverUserTopic, new CommunityAccountIdentifier(receivingUser.gradidoID)) + draft.user = new AccountIdentifier( + senderUserTopic, + new CommunityAccountIdentifier(sendingUser.gradidoID), + ) + draft.linkedUser = new AccountIdentifier( + receiverUserTopic, + new CommunityAccountIdentifier(receivingUser.gradidoID), + ) draft.type = TransactionType.GRADIDO_TRANSFER draft.createdAt = createdAt.toISOString() draft.amount = amount @@ -82,8 +109,10 @@ export class TransactionDraft { return draft } - static createDeferredTransfer(sendingUser: DbUser, transactionLink: DbTransactionLink) - : TransactionDraft | null { + static createDeferredTransfer( + sendingUser: DbUser, + transactionLink: DbTransactionLink, + ): TransactionDraft | null { if (!sendingUser.community) { throw new Error(`missing community for user ${sendingUser.id}`) } @@ -94,7 +123,10 @@ export class TransactionDraft { const createdAtOnlySeconds = transactionLink.createdAt createdAtOnlySeconds.setMilliseconds(0) const draft = new TransactionDraft() - draft.user = new AccountIdentifier(senderUserTopic, new CommunityAccountIdentifier(sendingUser.gradidoID)) + draft.user = new AccountIdentifier( + senderUserTopic, + new CommunityAccountIdentifier(sendingUser.gradidoID), + ) draft.linkedUser = new AccountIdentifier(senderUserTopic, transactionLink.code) draft.type = TransactionType.GRADIDO_DEFERRED_TRANSFER draft.createdAt = createdAtOnlySeconds.toISOString() @@ -104,13 +136,18 @@ export class TransactionDraft { return draft } - static redeemDeferredTransfer(transactionLink: DbTransactionLink, amount: string, createdAt: Date, recipientUser: DbUser): TransactionDraft | null { + static redeemDeferredTransfer( + transactionLink: DbTransactionLink, + amount: string, + createdAt: Date, + recipientUser: DbUser, + ): TransactionDraft | null { if (!transactionLink.user.community) { throw new Error(`missing community for user ${transactionLink.user.id}`) } if (!recipientUser.community) { throw new Error(`missing community for user ${recipientUser.id}`) - } + } const senderUserTopic = transactionLink.user.community.hieroTopicId if (!senderUserTopic) { throw new Error(`missing topicId for community ${transactionLink.user.community.id}`) @@ -123,10 +160,13 @@ export class TransactionDraft { createdAtOnlySeconds.setMilliseconds(0) const draft = new TransactionDraft() draft.user = new AccountIdentifier(senderUserTopic, transactionLink.code) - draft.linkedUser = new AccountIdentifier(recipientUserTopic, new CommunityAccountIdentifier(recipientUser.gradidoID)) + draft.linkedUser = new AccountIdentifier( + recipientUserTopic, + new CommunityAccountIdentifier(recipientUser.gradidoID), + ) draft.type = TransactionType.GRADIDO_REDEEM_DEFERRED_TRANSFER draft.createdAt = createdAtOnlySeconds.toISOString() draft.amount = amount return draft } -} \ No newline at end of file +} diff --git a/backend/src/apis/gms/ExportUsers.ts b/backend/src/apis/gms/ExportUsers.ts index 5c5cb72d8..e6494776a 100644 --- a/backend/src/apis/gms/ExportUsers.ts +++ b/backend/src/apis/gms/ExportUsers.ts @@ -1,15 +1,16 @@ import { User as DbUser } from 'database' + // import { createTestClient } from 'apollo-server-testing' -import { LOG4JS_BASE_CATEGORY_NAME } from '@/config/const' // import { createGmsUser } from '@/apis/gms/GmsClient' // import { GmsUser } from '@/apis/gms/model/GmsUser' import { CONFIG as CORE_CONFIG } from 'core' +import { AppDatabase, getHomeCommunity } from 'database' +import { getLogger } from 'log4js' +import { LOG4JS_BASE_CATEGORY_NAME } from '@/config/const' import { sendUserToGms } from '@/graphql/resolver/util/sendUserToGms' import { LogError } from '@/server/LogError' import { initLogging } from '@/server/logger' -import { AppDatabase, getHomeCommunity } from 'database' -import { getLogger } from 'log4js' const logger = getLogger(`${LOG4JS_BASE_CATEGORY_NAME}.apis.gms.ExportUsers`) diff --git a/backend/src/apis/gms/GmsClient.ts b/backend/src/apis/gms/GmsClient.ts index 7ed1df89d..2f73d3248 100644 --- a/backend/src/apis/gms/GmsClient.ts +++ b/backend/src/apis/gms/GmsClient.ts @@ -1,11 +1,10 @@ import axios from 'axios' - -import { httpAgent, httpsAgent } from '@/apis/ConnectionAgents' -import { LOG4JS_BASE_CATEGORY_NAME } from '@/config/const' -import { CONFIG } from '@/config' -import { LogError } from '@/server/LogError' import { ensureUrlEndsWithSlash } from 'core' import { getLogger } from 'log4js' +import { httpAgent, httpsAgent } from '@/apis/ConnectionAgents' +import { CONFIG } from '@/config' +import { LOG4JS_BASE_CATEGORY_NAME } from '@/config/const' +import { LogError } from '@/server/LogError' import { GmsUser } from './model/GmsUser' diff --git a/backend/src/apis/humhub/ExportUsers.ts b/backend/src/apis/humhub/ExportUsers.ts index 99ae859eb..4990b1381 100644 --- a/backend/src/apis/humhub/ExportUsers.ts +++ b/backend/src/apis/humhub/ExportUsers.ts @@ -1,9 +1,8 @@ import { AppDatabase, User } from 'database' +import { getLogger } from 'log4js' import { IsNull, Not } from 'typeorm' - import { LOG4JS_BASE_CATEGORY_NAME } from '@/config/const' import { initLogging } from '@/server/logger' -import { getLogger } from 'log4js' import { HumHubClient } from './HumHubClient' import { GetUser } from './model/GetUser' import { UsersResponse } from './model/UsersResponse' diff --git a/backend/src/apis/humhub/HumHubClient.ts b/backend/src/apis/humhub/HumHubClient.ts index 0cdc683c5..3c6b2536f 100644 --- a/backend/src/apis/humhub/HumHubClient.ts +++ b/backend/src/apis/humhub/HumHubClient.ts @@ -1,12 +1,11 @@ import { ProjectBranding } from 'database' import { SignJWT } from 'jose' +import { getLogger } from 'log4js' import { IRequestOptions, IRestResponse, RestClient } from 'typed-rest-client' - import { CONFIG } from '@/config' -import { LogError } from '@/server/LogError' import { LOG4JS_BASE_CATEGORY_NAME } from '@/config/const' -import { getLogger } from 'log4js' +import { LogError } from '@/server/LogError' import { PostUserLoggingView } from './logging/PostUserLogging.view' import { GetUser } from './model/GetUser' import { PostUser } from './model/PostUser' diff --git a/backend/src/apis/humhub/syncUser.ts b/backend/src/apis/humhub/syncUser.ts index 22ecde87c..dbd04e543 100644 --- a/backend/src/apis/humhub/syncUser.ts +++ b/backend/src/apis/humhub/syncUser.ts @@ -1,11 +1,9 @@ import { User } from 'database' - +import { getLogger } from 'log4js' import { LOG4JS_BASE_CATEGORY_NAME } from '@/config/const' import { LogError } from '@/server/LogError' -import { getLogger } from 'log4js' - -import { HumHubClient } from './HumHubClient' import { isHumhubUserIdenticalToDbUser } from './compareHumhubUserDbUser' +import { HumHubClient } from './HumHubClient' import { GetUser } from './model/GetUser' import { PostUser } from './model/PostUser' diff --git a/backend/src/apis/openai/OpenaiClient.ts b/backend/src/apis/openai/OpenaiClient.ts index 5655020aa..527a3a90c 100644 --- a/backend/src/apis/openai/OpenaiClient.ts +++ b/backend/src/apis/openai/OpenaiClient.ts @@ -1,14 +1,12 @@ import { OpenaiThreads, User } from 'database' +import { getLogger } from 'log4js' import { OpenAI } from 'openai' import { Message } from 'openai/resources/beta/threads/messages' - import { httpsAgent } from '@/apis/ConnectionAgents' import { CONFIG } from '@/config' -import { Message as MessageModel } from './model/Message' - import { LOG4JS_BASE_CATEGORY_NAME } from '@/config/const' -import { getLogger } from 'log4js' +import { Message as MessageModel } from './model/Message' const logger = getLogger(`${LOG4JS_BASE_CATEGORY_NAME}.apis.openai.OpenaiClient`) // this is the time after when openai is deleting an inactive thread @@ -89,8 +87,13 @@ export class OpenaiClient { logger.warn(`No openai thread found for user: ${user.id}`) return [] } - if (openaiThreadEntity.updatedAt < new Date(Date.now() - OPENAI_AI_THREAD_DEFAULT_TIMEOUT_DAYS * 24 * 60 * 60 * 1000)) { - logger.info(`Openai thread for user: ${user.id} is older than ${OPENAI_AI_THREAD_DEFAULT_TIMEOUT_DAYS} days, deleting...`) + if ( + openaiThreadEntity.updatedAt < + new Date(Date.now() - OPENAI_AI_THREAD_DEFAULT_TIMEOUT_DAYS * 24 * 60 * 60 * 1000) + ) { + logger.info( + `Openai thread for user: ${user.id} is older than ${OPENAI_AI_THREAD_DEFAULT_TIMEOUT_DAYS} days, deleting...`, + ) // let run async, because it could need some time, but we don't need to wait, because we create a new one nevertheless // biome-ignore lint/complexity/noVoid: start it intentionally async without waiting for result void this.deleteThread(openaiThreadEntity.id) @@ -113,10 +116,10 @@ export class OpenaiClient { ) .reverse() } catch (e) { - if(e instanceof Error && e.toString().includes('No thread found with id')) { + if (e instanceof Error && e.toString().includes('No thread found with id')) { logger.info(`Thread not found: ${openaiThreadEntity.id}`) return [] - } + } throw e } } @@ -141,7 +144,10 @@ export class OpenaiClient { } public async runAndGetLastNewMessage(threadId: string): Promise { - const updateOpenAiThreadResolver = OpenaiThreads.update({ id: threadId }, { updatedAt: new Date() }) + const updateOpenAiThreadResolver = OpenaiThreads.update( + { id: threadId }, + { updatedAt: new Date() }, + ) const run = await this.openai.beta.threads.runs.createAndPoll(threadId, { assistant_id: CONFIG.OPENAI_ASSISTANT_ID, }) diff --git a/backend/src/auth/JWT.ts b/backend/src/auth/JWT.ts index 870ec2871..cc9b4bad6 100644 --- a/backend/src/auth/JWT.ts +++ b/backend/src/auth/JWT.ts @@ -1,4 +1,4 @@ -import { SignJWT, jwtVerify } from 'jose' +import { jwtVerify, SignJWT } from 'jose' import { CONFIG } from '@/config/' import { LogError } from '@/server/LogError' diff --git a/backend/src/config/const.ts b/backend/src/config/const.ts index 05d413da4..d4b0805fe 100644 --- a/backend/src/config/const.ts +++ b/backend/src/config/const.ts @@ -1,3 +1,3 @@ export const LOG4JS_BASE_CATEGORY_NAME = 'backend' export const FRONTEND_LOGIN_ROUTE = 'login' -export const GRADIDO_REALM = 'gradido' \ No newline at end of file +export const GRADIDO_REALM = 'gradido' diff --git a/backend/src/config/schema.ts b/backend/src/config/schema.ts index 2f65435cc..7523f47ee 100644 --- a/backend/src/config/schema.ts +++ b/backend/src/config/schema.ts @@ -11,11 +11,11 @@ import { GRAPHIQL, HUMHUB_ACTIVE, HUMHUB_API_URL, + LOG_FILES_BASE_PATH, + LOG_LEVEL, LOG4JS_CONFIG, LOGIN_APP_SECRET, LOGIN_SERVER_KEY, - LOG_FILES_BASE_PATH, - LOG_LEVEL, NODE_ENV, OPENAI_ACTIVE, PRODUCTION, @@ -44,7 +44,7 @@ export const schema = Joi.object({ OPENAI_ACTIVE, PRODUCTION, - COMMUNITY_REDEEM_URL: Joi.string() + COMMUNITY_REDEEM_URL: Joi.string() .uri({ scheme: ['http', 'https'] }) .description('The url for redeeming link transactions, must start with frontend base url') .default('http://0.0.0.0/redeem/') diff --git a/backend/src/data/UserLogic.ts b/backend/src/data/UserLogic.ts index 68fb538d3..b2bca2c9e 100644 --- a/backend/src/data/UserLogic.ts +++ b/backend/src/data/UserLogic.ts @@ -1,6 +1,5 @@ -import { User, UserRole } from 'database' - import { RoleNames } from '@enum/RoleNames' +import { User, UserRole } from 'database' export class UserLogic { public constructor(private self: User) {} diff --git a/backend/src/event/Events.ts b/backend/src/event/Events.ts index 4f10afbce..5db84de51 100644 --- a/backend/src/event/Events.ts +++ b/backend/src/event/Events.ts @@ -1,35 +1,35 @@ -export { EventType } from './EventType' -export { Event } from './Event' export { EVENT_ADMIN_CONTRIBUTION_CONFIRM } from './EVENT_ADMIN_CONTRIBUTION_CONFIRM' export { EVENT_ADMIN_CONTRIBUTION_CREATE } from './EVENT_ADMIN_CONTRIBUTION_CREATE' export { EVENT_ADMIN_CONTRIBUTION_DELETE } from './EVENT_ADMIN_CONTRIBUTION_DELETE' export { EVENT_ADMIN_CONTRIBUTION_DENY } from './EVENT_ADMIN_CONTRIBUTION_DENY' -export { EVENT_ADMIN_CONTRIBUTION_UPDATE } from './EVENT_ADMIN_CONTRIBUTION_UPDATE' export { EVENT_ADMIN_CONTRIBUTION_LINK_CREATE } from './EVENT_ADMIN_CONTRIBUTION_LINK_CREATE' export { EVENT_ADMIN_CONTRIBUTION_LINK_DELETE } from './EVENT_ADMIN_CONTRIBUTION_LINK_DELETE' export { EVENT_ADMIN_CONTRIBUTION_LINK_UPDATE } from './EVENT_ADMIN_CONTRIBUTION_LINK_UPDATE' export { EVENT_ADMIN_CONTRIBUTION_MESSAGE_CREATE } from './EVENT_ADMIN_CONTRIBUTION_MESSAGE_CREATE' +export { EVENT_ADMIN_CONTRIBUTION_UPDATE } from './EVENT_ADMIN_CONTRIBUTION_UPDATE' export { EVENT_ADMIN_USER_DELETE } from './EVENT_ADMIN_USER_DELETE' -export { EVENT_ADMIN_USER_UNDELETE } from './EVENT_ADMIN_USER_UNDELETE' export { EVENT_ADMIN_USER_ROLE_SET } from './EVENT_ADMIN_USER_ROLE_SET' +export { EVENT_ADMIN_USER_UNDELETE } from './EVENT_ADMIN_USER_UNDELETE' export { EVENT_CONTRIBUTION_CREATE } from './EVENT_CONTRIBUTION_CREATE' export { EVENT_CONTRIBUTION_DELETE } from './EVENT_CONTRIBUTION_DELETE' -export { EVENT_CONTRIBUTION_UPDATE } from './EVENT_CONTRIBUTION_UPDATE' -export { EVENT_CONTRIBUTION_MESSAGE_CREATE } from './EVENT_CONTRIBUTION_MESSAGE_CREATE' export { EVENT_CONTRIBUTION_LINK_REDEEM } from './EVENT_CONTRIBUTION_LINK_REDEEM' +export { EVENT_CONTRIBUTION_MESSAGE_CREATE } from './EVENT_CONTRIBUTION_MESSAGE_CREATE' +export { EVENT_CONTRIBUTION_UPDATE } from './EVENT_CONTRIBUTION_UPDATE' export { EVENT_EMAIL_ACCOUNT_MULTIREGISTRATION } from './EVENT_EMAIL_ACCOUNT_MULTIREGISTRATION' export { EVENT_EMAIL_ADMIN_CONFIRMATION } from './EVENT_EMAIL_ADMIN_CONFIRMATION' export { EVENT_EMAIL_CONFIRMATION } from './EVENT_EMAIL_CONFIRMATION' export { EVENT_EMAIL_FORGOT_PASSWORD } from './EVENT_EMAIL_FORGOT_PASSWORD' export { EVENT_NEWSLETTER_SUBSCRIBE } from './EVENT_NEWSLETTER_SUBSCRIBE' export { EVENT_NEWSLETTER_UNSUBSCRIBE } from './EVENT_NEWSLETTER_UNSUBSCRIBE' -export { EVENT_TRANSACTION_SEND } from './EVENT_TRANSACTION_SEND' -export { EVENT_TRANSACTION_RECEIVE } from './EVENT_TRANSACTION_RECEIVE' export { EVENT_TRANSACTION_LINK_CREATE } from './EVENT_TRANSACTION_LINK_CREATE' export { EVENT_TRANSACTION_LINK_DELETE } from './EVENT_TRANSACTION_LINK_DELETE' export { EVENT_TRANSACTION_LINK_REDEEM } from './EVENT_TRANSACTION_LINK_REDEEM' +export { EVENT_TRANSACTION_RECEIVE } from './EVENT_TRANSACTION_RECEIVE' +export { EVENT_TRANSACTION_SEND } from './EVENT_TRANSACTION_SEND' export { EVENT_USER_ACTIVATE_ACCOUNT } from './EVENT_USER_ACTIVATE_ACCOUNT' export { EVENT_USER_INFO_UPDATE } from './EVENT_USER_INFO_UPDATE' export { EVENT_USER_LOGIN } from './EVENT_USER_LOGIN' export { EVENT_USER_LOGOUT } from './EVENT_USER_LOGOUT' export { EVENT_USER_REGISTER } from './EVENT_USER_REGISTER' +export { Event } from './Event' +export { EventType } from './EventType' diff --git a/backend/src/federation/authenticateCommunities.ts b/backend/src/federation/authenticateCommunities.ts index 9c87da3c0..a08382395 100644 --- a/backend/src/federation/authenticateCommunities.ts +++ b/backend/src/federation/authenticateCommunities.ts @@ -1,26 +1,32 @@ -import { - CommunityHandshakeState as DbCommunityHandshakeState, - CommunityHandshakeStateLoggingView, - FederatedCommunity as DbFederatedCommunity, - findPendingCommunityHandshake, - getHomeCommunityWithFederatedCommunityOrFail, +import { + CommunityHandshakeStateLogic, + EncryptedTransferArgs, + ensureUrlEndsWithSlash, + getFederatedCommunityWithApiOrFail, +} from 'core' +import { + CommunityHandshakeStateLoggingView, CommunityHandshakeStateType, + CommunityHandshakeState as DbCommunityHandshakeState, + FederatedCommunity as DbFederatedCommunity, + findPendingCommunityHandshake, getCommunityByPublicKeyOrFail, + getHomeCommunityWithFederatedCommunityOrFail, } from 'database' -import { randombytes_random } from 'sodium-native' - -import { AuthenticationClient as V1_0_AuthenticationClient } from '@/federation/client/1_0/AuthenticationClient' -import { ensureUrlEndsWithSlash, getFederatedCommunityWithApiOrFail } from 'core' - -import { LOG4JS_BASE_CATEGORY_NAME } from '@/config/const' -import { communityAuthenticatedSchema, encryptAndSign, OpenConnectionJwtPayloadType } from 'shared' import { getLogger } from 'log4js' +import { + communityAuthenticatedSchema, + Ed25519PublicKey, + encryptAndSign, + OpenConnectionJwtPayloadType, +} from 'shared' +import { randombytes_random } from 'sodium-native' +import { LOG4JS_BASE_CATEGORY_NAME } from '@/config/const' +import { AuthenticationClient as V1_0_AuthenticationClient } from '@/federation/client/1_0/AuthenticationClient' import { AuthenticationClientFactory } from './client/AuthenticationClientFactory' -import { EncryptedTransferArgs } from 'core' -import { CommunityHandshakeStateLogic } from 'core' -import { Ed25519PublicKey } from 'shared' -const createLogger = (functionName: string) => getLogger(`${LOG4JS_BASE_CATEGORY_NAME}.federation.authenticateCommunities.${functionName}`) +const createLogger = (functionName: string) => + getLogger(`${LOG4JS_BASE_CATEGORY_NAME}.federation.authenticateCommunities.${functionName}`) export enum StartCommunityAuthenticationResult { ALREADY_AUTHENTICATED = 'already authenticated', @@ -39,16 +45,18 @@ export async function startCommunityAuthentication( const homeComA = await getHomeCommunityWithFederatedCommunityOrFail(fedComB.apiVersion) // methodLogger.debug('homeComA', new CommunityLoggingView(homeComA)) const homeFedComA = getFederatedCommunityWithApiOrFail(homeComA, fedComB.apiVersion) - + const comB = await getCommunityByPublicKeyOrFail(fedComBPublicKey) // methodLogger.debug('started with comB:', new CommunityLoggingView(comB)) // check if communityUuid is not a valid v4Uuid - - // communityAuthenticatedSchema.safeParse return true - // - if communityUuid is a valid v4Uuid and + + // communityAuthenticatedSchema.safeParse return true + // - if communityUuid is a valid v4Uuid and // - if authenticatedAt is a valid date if (communityAuthenticatedSchema.safeParse(comB).success) { - methodLogger.debug(`comB.communityUuid is already a valid v4Uuid ${ comB.communityUuid || 'null' } and was authenticated at ${ comB.authenticatedAt || 'null'}`) + methodLogger.debug( + `comB.communityUuid is already a valid v4Uuid ${comB.communityUuid || 'null'} and was authenticated at ${comB.authenticatedAt || 'null'}`, + ) return StartCommunityAuthenticationResult.ALREADY_AUTHENTICATED } /*methodLogger.debug('comB.uuid is null or is a not valid v4Uuid...', @@ -62,11 +70,14 @@ export async function startCommunityAuthentication( // retry on timeout or failure if (!(await stateLogic.isTimeoutUpdate())) { // authentication with community and api version is still in progress and it is not timeout yet - methodLogger.debug('existingState, so we exit here', new CommunityHandshakeStateLoggingView(existingState)) + methodLogger.debug( + 'existingState, so we exit here', + new CommunityHandshakeStateLoggingView(existingState), + ) return StartCommunityAuthenticationResult.ALREADY_IN_PROGRESS } } - + const client = AuthenticationClientFactory.getInstance(fedComB) if (client instanceof V1_0_AuthenticationClient) { @@ -82,7 +93,8 @@ export async function startCommunityAuthentication( methodLogger.debug('[START_COMMUNITY_AUTHENTICATION] community handshake state created') //create JWT with url in payload encrypted by foreignCom.publicJwtKey and signed with homeCom.privateJwtKey - const payload = new OpenConnectionJwtPayloadType(handshakeID, + const payload = new OpenConnectionJwtPayloadType( + handshakeID, ensureUrlEndsWithSlash(homeFedComA.endPoint).concat(homeFedComA.apiVersion), ) // methodLogger.debug('payload', payload) diff --git a/backend/src/federation/client/1_0/AuthenticationClient.ts b/backend/src/federation/client/1_0/AuthenticationClient.ts index 5d897093e..95bcc6726 100644 --- a/backend/src/federation/client/1_0/AuthenticationClient.ts +++ b/backend/src/federation/client/1_0/AuthenticationClient.ts @@ -1,11 +1,8 @@ +import { EncryptedTransferArgs, ensureUrlEndsWithSlash } from 'core' import { FederatedCommunity as DbFederatedCommunity } from 'database' import { GraphQLClient } from 'graphql-request' - -import { ensureUrlEndsWithSlash } from 'core' - -import { LOG4JS_BASE_CATEGORY_NAME } from '@/config/const' -import { EncryptedTransferArgs } from 'core' import { getLogger } from 'log4js' +import { LOG4JS_BASE_CATEGORY_NAME } from '@/config/const' import { openConnection } from './query/openConnection' const logger = getLogger(`${LOG4JS_BASE_CATEGORY_NAME}.federation.client.1_0.AuthenticationClient`) diff --git a/backend/src/federation/client/1_0/DisbursementClient.ts b/backend/src/federation/client/1_0/DisbursementClient.ts index 8ca859070..664f8b353 100644 --- a/backend/src/federation/client/1_0/DisbursementClient.ts +++ b/backend/src/federation/client/1_0/DisbursementClient.ts @@ -1,11 +1,8 @@ +import { EncryptedTransferArgs, ensureUrlEndsWithSlash } from 'core' import { FederatedCommunity as DbFederatedCommunity } from 'database' import { GraphQLClient } from 'graphql-request' - -import { ensureUrlEndsWithSlash } from 'core' import { getLogger } from 'log4js' - import { LOG4JS_BASE_CATEGORY_NAME } from '@/config/const' -import { EncryptedTransferArgs } from 'core' import { processDisburseJwtOnSenderCommunity as processDisburseJwtOnSenderCommunityQuery } from './query/processDisburseJwtOnSenderCommunity' const logger = getLogger(`${LOG4JS_BASE_CATEGORY_NAME}.federation.client.1_0.DisbursementClient`) @@ -30,7 +27,9 @@ export class DisbursementClient { async sendDisburseJwtToSenderCommunity(args: EncryptedTransferArgs): Promise { logger.debug('sendDisburseJwtToSenderCommunity against endpoint=', this.endpoint) try { - const { data } = await this.client.rawRequest<{ processDisburseJwtOnSenderCommunity: string }>(processDisburseJwtOnSenderCommunityQuery, { args }) + const { data } = await this.client.rawRequest<{ + processDisburseJwtOnSenderCommunity: string + }>(processDisburseJwtOnSenderCommunityQuery, { args }) const response = data?.processDisburseJwtOnSenderCommunity if (response) { logger.debug('received response:', response) @@ -43,5 +42,4 @@ export class DisbursementClient { } return null } - } diff --git a/backend/src/federation/client/1_0/FederationClient.ts b/backend/src/federation/client/1_0/FederationClient.ts index c437ad085..741a341ac 100644 --- a/backend/src/federation/client/1_0/FederationClient.ts +++ b/backend/src/federation/client/1_0/FederationClient.ts @@ -1,11 +1,10 @@ +import { ensureUrlEndsWithSlash } from 'core' import { FederatedCommunity as DbFederatedCommunity } from 'database' import { GraphQLClient } from 'graphql-request' - +import { getLogger } from 'log4js' import { LOG4JS_BASE_CATEGORY_NAME } from '@/config/const' import { getPublicCommunityInfo } from '@/federation/client/1_0/query/getPublicCommunityInfo' import { getPublicKey } from '@/federation/client/1_0/query/getPublicKey' -import { ensureUrlEndsWithSlash } from 'core' -import { getLogger } from 'log4js' import { PublicCommunityInfoLoggingView } from './logging/PublicCommunityInfoLogging.view' import { GetPublicKeyResult } from './model/GetPublicKeyResult' diff --git a/backend/src/federation/client/AuthenticationClientFactory.ts b/backend/src/federation/client/AuthenticationClientFactory.ts index 344753a48..9c94f285a 100644 --- a/backend/src/federation/client/AuthenticationClientFactory.ts +++ b/backend/src/federation/client/AuthenticationClientFactory.ts @@ -1,9 +1,7 @@ -import { FederatedCommunity as DbFederatedCommunity } from 'database' - -import { AuthenticationClient as V1_0_AuthenticationClient } from '@/federation/client/1_0/AuthenticationClient' - -import { AuthenticationClient as V1_1_AuthenticationClient } from '@/federation/client/1_1/AuthenticationClient' import { ApiVersionType } from 'core' +import { FederatedCommunity as DbFederatedCommunity } from 'database' +import { AuthenticationClient as V1_0_AuthenticationClient } from '@/federation/client/1_0/AuthenticationClient' +import { AuthenticationClient as V1_1_AuthenticationClient } from '@/federation/client/1_1/AuthenticationClient' type AuthenticationClient = V1_0_AuthenticationClient | V1_1_AuthenticationClient diff --git a/backend/src/federation/client/DisbursementClientFactory.ts b/backend/src/federation/client/DisbursementClientFactory.ts index 01c911e92..7dc0da587 100644 --- a/backend/src/federation/client/DisbursementClientFactory.ts +++ b/backend/src/federation/client/DisbursementClientFactory.ts @@ -1,8 +1,7 @@ +import { ApiVersionType } from 'core' import { FederatedCommunity as DbFederatedCommunity } from 'database' - import { DisbursementClient as V1_0_DisbursementClient } from '@/federation/client/1_0/DisbursementClient' import { DisbursementClient as V1_1_DisbursementClient } from '@/federation/client/1_1/DisbursementClient' -import { ApiVersionType } from 'core' type DisbursementClient = V1_0_DisbursementClient | V1_1_DisbursementClient diff --git a/backend/src/federation/client/FederationClientFactory.ts b/backend/src/federation/client/FederationClientFactory.ts index 926c3c180..90807d091 100644 --- a/backend/src/federation/client/FederationClientFactory.ts +++ b/backend/src/federation/client/FederationClientFactory.ts @@ -1,8 +1,7 @@ +import { ApiVersionType, ensureUrlEndsWithSlash } from 'core' import { FederatedCommunity as DbFederatedCommunity } from 'database' - import { FederationClient as V1_0_FederationClient } from '@/federation/client/1_0/FederationClient' import { FederationClient as V1_1_FederationClient } from '@/federation/client/1_1/FederationClient' -import { ApiVersionType, ensureUrlEndsWithSlash } from 'core' type FederationClient = V1_0_FederationClient | V1_1_FederationClient diff --git a/backend/src/federation/validateCommunities.test.ts b/backend/src/federation/validateCommunities.test.ts index 0506f33be..3d226a2f5 100644 --- a/backend/src/federation/validateCommunities.test.ts +++ b/backend/src/federation/validateCommunities.test.ts @@ -1,13 +1,11 @@ +import { cleanDB, testEnvironment } from '@test/helpers' import { ApolloServerTestClient } from 'apollo-server-testing' -import { FederatedCommunity as DbFederatedCommunity } from 'database' +import { getLogger } from 'config-schema/test/testSetup' +import { AppDatabase, FederatedCommunity as DbFederatedCommunity } from 'database' import { GraphQLClient } from 'graphql-request' import { Response } from 'graphql-request/dist/types' import { DataSource, Not } from 'typeorm' - -import { cleanDB, testEnvironment } from '@test/helpers' -import { getLogger } from 'config-schema/test/testSetup' import { LOG4JS_BASE_CATEGORY_NAME } from '@/config/const' -import { AppDatabase } from 'database' import { validateCommunities } from './validateCommunities' const logger = getLogger(`${LOG4JS_BASE_CATEGORY_NAME}.federation.validateCommunities`) diff --git a/backend/src/federation/validateCommunities.ts b/backend/src/federation/validateCommunities.ts index ac9334977..a5035ea79 100644 --- a/backend/src/federation/validateCommunities.ts +++ b/backend/src/federation/validateCommunities.ts @@ -1,20 +1,19 @@ +import { ApiVersionType } from 'core' import { Community as DbCommunity, FederatedCommunity as DbFederatedCommunity, getHomeCommunity, } from 'database' +import { getLogger } from 'log4js' +import { createKeyPair, Ed25519PublicKey } from 'shared' import { IsNull } from 'typeorm' - import { LOG4JS_BASE_CATEGORY_NAME } from '@/config/const' import { FederationClient as V1_0_FederationClient } from '@/federation/client/1_0/FederationClient' import { PublicCommunityInfo } from '@/federation/client/1_0/model/PublicCommunityInfo' import { FederationClientFactory } from '@/federation/client/FederationClientFactory' import { LogError } from '@/server/LogError' -import { createKeyPair, Ed25519PublicKey } from 'shared' -import { getLogger } from 'log4js' import { startCommunityAuthentication } from './authenticateCommunities' import { PublicCommunityInfoLoggingView } from './client/1_0/logging/PublicCommunityInfoLogging.view' -import { ApiVersionType } from 'core' const logger = getLogger(`${LOG4JS_BASE_CATEGORY_NAME}.federation.validateCommunities`) @@ -47,7 +46,11 @@ export async function validateCommunities(): Promise { logger.debug(`verify federation community: ${dbFedComB.endPoint}${dbFedComB.apiVersion}`) const apiValueStrings: string[] = Object.values(ApiVersionType) if (!apiValueStrings.includes(dbFedComB.apiVersion)) { - logger.debug('dbFedComB with unsupported apiVersion', dbFedComB.endPoint, dbFedComB.apiVersion) + logger.debug( + 'dbFedComB with unsupported apiVersion', + dbFedComB.endPoint, + dbFedComB.apiVersion, + ) logger.debug(`supported ApiVersions=`, apiValueStrings) continue } @@ -65,18 +68,29 @@ export async function validateCommunities(): Promise { const pubComInfo = await client.getPublicCommunityInfo() if (pubComInfo) { await writeForeignCommunity(dbFedComB, pubComInfo) - logger.debug(`wrote response of getPublicCommunityInfo in dbFedComB ${dbFedComB.endPoint}`) + logger.debug( + `wrote response of getPublicCommunityInfo in dbFedComB ${dbFedComB.endPoint}`, + ) try { const result = await startCommunityAuthentication(dbFedComB) - logger.info(`${dbFedComB.endPoint}${dbFedComB.apiVersion} verified, authentication state: ${result}`) + logger.info( + `${dbFedComB.endPoint}${dbFedComB.apiVersion} verified, authentication state: ${result}`, + ) } catch (err) { - logger.warn(`Warning: Authentication of community ${dbFedComB.endPoint} still ongoing:`, err) + logger.warn( + `Warning: Authentication of community ${dbFedComB.endPoint} still ongoing:`, + err, + ) } } else { logger.debug('missing result of getPublicCommunityInfo') } } else { - logger.debug('received not matching publicKey:', clientPublicKey.asHex(), fedComBPublicKey.asHex()) + logger.debug( + 'received not matching publicKey:', + clientPublicKey.asHex(), + fedComBPublicKey.asHex(), + ) } } } catch (err) { @@ -89,25 +103,36 @@ export async function writeJwtKeyPairInHomeCommunity(): Promise { logger.debug(`Federation: writeJwtKeyPairInHomeCommunity`) try { // check for existing homeCommunity entry - let homeCom = await getHomeCommunity() + const homeCom = await getHomeCommunity() if (homeCom) { if (!homeCom.publicJwtKey && !homeCom.privateJwtKey) { // Generate key pair using jose library - const { publicKey, privateKey } = await createKeyPair(); - logger.debug(`Federation: writeJwtKeyPairInHomeCommunity publicKey=`, publicKey); - logger.debug(`Federation: writeJwtKeyPairInHomeCommunity privateKey=`, privateKey.slice(0, 20)); - - homeCom.publicJwtKey = publicKey; - logger.debug(`Federation: writeJwtKeyPairInHomeCommunity publicJwtKey.length=`, homeCom.publicJwtKey.length); - homeCom.privateJwtKey = privateKey; - logger.debug(`Federation: writeJwtKeyPairInHomeCommunity privateJwtKey.length=`, homeCom.privateJwtKey.length); + const { publicKey, privateKey } = await createKeyPair() + logger.debug(`Federation: writeJwtKeyPairInHomeCommunity publicKey=`, publicKey) + logger.debug( + `Federation: writeJwtKeyPairInHomeCommunity privateKey=`, + privateKey.slice(0, 20), + ) + + homeCom.publicJwtKey = publicKey + logger.debug( + `Federation: writeJwtKeyPairInHomeCommunity publicJwtKey.length=`, + homeCom.publicJwtKey.length, + ) + homeCom.privateJwtKey = privateKey + logger.debug( + `Federation: writeJwtKeyPairInHomeCommunity privateJwtKey.length=`, + homeCom.privateJwtKey.length, + ) await DbCommunity.save(homeCom) logger.debug(`Federation: writeJwtKeyPairInHomeCommunity done`) } else { logger.debug(`Federation: writeJwtKeyPairInHomeCommunity: keypair already exists`) } } else { - throw new Error(`Error! A HomeCommunity-Entry still not exist! Please start the DHT-Modul first.`) + throw new Error( + `Error! A HomeCommunity-Entry still not exist! Please start the DHT-Modul first.`, + ) } return homeCom } catch (err) { diff --git a/backend/src/graphql/arg/ContributionMessageArgs.ts b/backend/src/graphql/arg/ContributionMessageArgs.ts index 8c95fadbd..1b4a7d14d 100644 --- a/backend/src/graphql/arg/ContributionMessageArgs.ts +++ b/backend/src/graphql/arg/ContributionMessageArgs.ts @@ -1,8 +1,7 @@ +import { ContributionMessageType } from '@enum/ContributionMessageType' import { IsEnum, IsInt, IsString } from 'class-validator' import { ArgsType, Field, InputType, Int } from 'type-graphql' -import { ContributionMessageType } from '@enum/ContributionMessageType' - import { isValidDateString } from '@/graphql/validator/DateString' @InputType() diff --git a/backend/src/graphql/arg/Paginated.ts b/backend/src/graphql/arg/Paginated.ts index 235c7c158..3663b8724 100644 --- a/backend/src/graphql/arg/Paginated.ts +++ b/backend/src/graphql/arg/Paginated.ts @@ -1,8 +1,7 @@ +import { Order } from '@enum/Order' import { IsEnum, IsPositive } from 'class-validator' import { ArgsType, Field, InputType, Int } from 'type-graphql' -import { Order } from '@enum/Order' - @ArgsType() @InputType() export class Paginated { diff --git a/backend/src/graphql/arg/SearchContributionsFilterArgs.ts b/backend/src/graphql/arg/SearchContributionsFilterArgs.ts index ad8b7747e..e6763e1c7 100644 --- a/backend/src/graphql/arg/SearchContributionsFilterArgs.ts +++ b/backend/src/graphql/arg/SearchContributionsFilterArgs.ts @@ -1,8 +1,7 @@ +import { ContributionStatus } from '@enum/ContributionStatus' import { IsBoolean, IsPositive, IsString } from 'class-validator' import { ArgsType, Field, InputType, Int } from 'type-graphql' -import { ContributionStatus } from '@enum/ContributionStatus' - import { isContributionStatusArray } from '@/graphql/validator/ContributionStatusArray' @ArgsType() diff --git a/backend/src/graphql/arg/SetUserRoleArgs.ts b/backend/src/graphql/arg/SetUserRoleArgs.ts index 48d8086ab..df7e3ab01 100644 --- a/backend/src/graphql/arg/SetUserRoleArgs.ts +++ b/backend/src/graphql/arg/SetUserRoleArgs.ts @@ -1,8 +1,7 @@ +import { RoleNames } from '@enum/RoleNames' import { IsEnum, IsPositive } from 'class-validator' import { ArgsType, Field, InputType, Int } from 'type-graphql' -import { RoleNames } from '@enum/RoleNames' - @InputType() @ArgsType() export class SetUserRoleArgs { diff --git a/backend/src/graphql/arg/UpdateUserInfosArgs.ts b/backend/src/graphql/arg/UpdateUserInfosArgs.ts index c368bbd8b..2f4a85344 100644 --- a/backend/src/graphql/arg/UpdateUserInfosArgs.ts +++ b/backend/src/graphql/arg/UpdateUserInfosArgs.ts @@ -1,9 +1,8 @@ -import { IsBoolean, IsEnum, IsInt, IsString } from 'class-validator' -import { ArgsType, Field, InputType, Int } from 'type-graphql' - import { GmsPublishLocationType } from '@enum/GmsPublishLocationType' import { PublishNameType } from '@enum/PublishNameType' import { Location } from '@model/Location' +import { IsBoolean, IsEnum, IsInt, IsString } from 'class-validator' +import { ArgsType, Field, InputType, Int } from 'type-graphql' import { isValidLocation } from '@/graphql/validator/Location' diff --git a/backend/src/graphql/arg/UserArgs.ts b/backend/src/graphql/arg/UserArgs.ts index 681d3ce51..d22b0a881 100644 --- a/backend/src/graphql/arg/UserArgs.ts +++ b/backend/src/graphql/arg/UserArgs.ts @@ -9,5 +9,5 @@ export class UserArgs { @Field({ nullable: true }) @IsString() - communityIdentifier?: string + communityIdentifier?: string } diff --git a/backend/src/graphql/directive/isAuthorized.ts b/backend/src/graphql/directive/isAuthorized.ts index 6f4d08d54..fdb528330 100644 --- a/backend/src/graphql/directive/isAuthorized.ts +++ b/backend/src/graphql/directive/isAuthorized.ts @@ -1,8 +1,7 @@ +import { RoleNames } from '@enum/RoleNames' import { User } from 'database' import { AuthChecker } from 'type-graphql' -import { RoleNames } from '@enum/RoleNames' - import { INALIENABLE_RIGHTS } from '@/auth/INALIENABLE_RIGHTS' import { decode, encode } from '@/auth/JWT' import { RIGHTS } from '@/auth/RIGHTS' @@ -14,8 +13,8 @@ import { ROLE_UNAUTHORIZED, ROLE_USER, } from '@/auth/ROLES' -import { LogError } from '@/server/LogError' import { Context } from '@/server/context' +import { LogError } from '@/server/LogError' export const isAuthorized: AuthChecker = async ({ context }, rights) => { context.role = ROLE_UNAUTHORIZED // unauthorized user diff --git a/backend/src/graphql/enum/ContributionCycleType.ts b/backend/src/graphql/enum/ContributionCycleType.ts index 050a6ac0d..ab0439f7b 100644 --- a/backend/src/graphql/enum/ContributionCycleType.ts +++ b/backend/src/graphql/enum/ContributionCycleType.ts @@ -1,5 +1,5 @@ -import { registerEnumType } from 'type-graphql' import { ContributionCycleType } from 'database' +import { registerEnumType } from 'type-graphql' export { ContributionCycleType } diff --git a/backend/src/graphql/enum/ContributionStatus.ts b/backend/src/graphql/enum/ContributionStatus.ts index 69d2e1171..00acf4ba7 100644 --- a/backend/src/graphql/enum/ContributionStatus.ts +++ b/backend/src/graphql/enum/ContributionStatus.ts @@ -1,5 +1,5 @@ -import { registerEnumType } from 'type-graphql' import { ContributionStatus } from 'database' +import { registerEnumType } from 'type-graphql' export { ContributionStatus } diff --git a/backend/src/graphql/enum/ContributionType.ts b/backend/src/graphql/enum/ContributionType.ts index 28fae333a..9ae364a63 100644 --- a/backend/src/graphql/enum/ContributionType.ts +++ b/backend/src/graphql/enum/ContributionType.ts @@ -1,5 +1,5 @@ -import { registerEnumType } from 'type-graphql' import { ContributionType } from 'database' +import { registerEnumType } from 'type-graphql' export { ContributionType } diff --git a/backend/src/graphql/enum/PendingTransactionState.ts b/backend/src/graphql/enum/PendingTransactionState.ts index cf1a17291..38ccc3898 100644 --- a/backend/src/graphql/enum/PendingTransactionState.ts +++ b/backend/src/graphql/enum/PendingTransactionState.ts @@ -1,5 +1,5 @@ -import { registerEnumType } from 'type-graphql' import { PendingTransactionState } from 'shared' +import { registerEnumType } from 'type-graphql' export { PendingTransactionState } diff --git a/backend/src/graphql/enum/RoleNames.ts b/backend/src/graphql/enum/RoleNames.ts index 872b4937f..ba1483974 100644 --- a/backend/src/graphql/enum/RoleNames.ts +++ b/backend/src/graphql/enum/RoleNames.ts @@ -1,5 +1,5 @@ -import { registerEnumType } from 'type-graphql' import { RoleNames } from 'database' +import { registerEnumType } from 'type-graphql' export { RoleNames } diff --git a/backend/src/graphql/input/EditCommunityInput.ts b/backend/src/graphql/input/EditCommunityInput.ts index 93d867d88..4cffc1467 100644 --- a/backend/src/graphql/input/EditCommunityInput.ts +++ b/backend/src/graphql/input/EditCommunityInput.ts @@ -2,8 +2,8 @@ import { IsString, IsUUID } from 'class-validator' import { ArgsType, Field, InputType } from 'type-graphql' import { Location } from '@/graphql/model/Location' -import { isValidLocation } from '@/graphql/validator/Location' import { isValidHieroId } from '@/graphql/validator/HieroId' +import { isValidLocation } from '@/graphql/validator/Location' @ArgsType() @InputType() diff --git a/backend/src/graphql/model/ContributionLinkList.ts b/backend/src/graphql/model/ContributionLinkList.ts index 7f7c3b56f..6036a6469 100644 --- a/backend/src/graphql/model/ContributionLinkList.ts +++ b/backend/src/graphql/model/ContributionLinkList.ts @@ -1,6 +1,5 @@ -import { Field, Int, ObjectType } from 'type-graphql' - import { ContributionLink } from '@model/ContributionLink' +import { Field, Int, ObjectType } from 'type-graphql' @ObjectType() export class ContributionLinkList { diff --git a/backend/src/graphql/model/FederatedCommunity.ts b/backend/src/graphql/model/FederatedCommunity.ts index cee430dba..ad5eef8a6 100644 --- a/backend/src/graphql/model/FederatedCommunity.ts +++ b/backend/src/graphql/model/FederatedCommunity.ts @@ -1,8 +1,7 @@ +import { ensureUrlEndsWithSlash } from 'core' import { FederatedCommunity as DbFederatedCommunity } from 'database' import { Field, Int, ObjectType } from 'type-graphql' -import { ensureUrlEndsWithSlash } from 'core' - @ObjectType() export class FederatedCommunity { constructor(dbCom: DbFederatedCommunity) { diff --git a/backend/src/graphql/model/GdtEntry.ts b/backend/src/graphql/model/GdtEntry.ts index 1ef756cb6..c1654c32b 100644 --- a/backend/src/graphql/model/GdtEntry.ts +++ b/backend/src/graphql/model/GdtEntry.ts @@ -1,6 +1,5 @@ -import { Field, Float, Int, ObjectType } from 'type-graphql' - import { GdtEntryType } from '@enum/GdtEntryType' +import { Field, Float, Int, ObjectType } from 'type-graphql' @ObjectType() export class GdtEntry { diff --git a/backend/src/graphql/model/RedeemJwtLink.ts b/backend/src/graphql/model/RedeemJwtLink.ts index 64544ad0e..9b8989c28 100644 --- a/backend/src/graphql/model/RedeemJwtLink.ts +++ b/backend/src/graphql/model/RedeemJwtLink.ts @@ -1,7 +1,6 @@ import { Decimal } from 'decimal.js-light' -import { Field, ObjectType } from 'type-graphql' - import { RedeemJwtPayloadType } from 'shared' +import { Field, ObjectType } from 'type-graphql' import { Community } from './Community' import { User } from './User' diff --git a/backend/src/graphql/model/Transaction.ts b/backend/src/graphql/model/Transaction.ts index 0560cef54..a865ac832 100644 --- a/backend/src/graphql/model/Transaction.ts +++ b/backend/src/graphql/model/Transaction.ts @@ -1,9 +1,8 @@ +import { Decay, TransactionTypeId } from 'core' import { Transaction as dbTransaction } from 'database' import { Decimal } from 'decimal.js-light' import { Field, Int, ObjectType } from 'type-graphql' -import { Decay, TransactionTypeId } from 'core' - import { User } from './User' @ObjectType() diff --git a/backend/src/graphql/model/User.ts b/backend/src/graphql/model/User.ts index ffc6aae31..963df0a21 100644 --- a/backend/src/graphql/model/User.ts +++ b/backend/src/graphql/model/User.ts @@ -1,10 +1,9 @@ +import { GmsPublishLocationType } from '@enum/GmsPublishLocationType' +import { PublishNameType } from '@enum/PublishNameType' import { User as DbUser } from 'database' import { Field, Int, ObjectType } from 'type-graphql' import { Point } from 'typeorm' -import { GmsPublishLocationType } from '@enum/GmsPublishLocationType' -import { PublishNameType } from '@enum/PublishNameType' - import { PublishNameLogic } from '@/data/PublishName.logic' import { Point2Location } from '@/graphql/resolver/util/Location2Point' diff --git a/backend/src/graphql/resolver/AiChatResolver.ts b/backend/src/graphql/resolver/AiChatResolver.ts index c8f6bb4f9..41ede6e01 100644 --- a/backend/src/graphql/resolver/AiChatResolver.ts +++ b/backend/src/graphql/resolver/AiChatResolver.ts @@ -1,10 +1,8 @@ -import { Arg, Authorized, Ctx, Mutation, Query, Resolver } from 'type-graphql' - import { OpenaiMessage } from '@input/OpenaiMessage' import { ChatGptMessage } from '@model/ChatGptMessage' - -import { OpenaiClient } from '@/apis/openai/OpenaiClient' +import { Arg, Authorized, Ctx, Mutation, Query, Resolver } from 'type-graphql' import { Message } from '@/apis/openai/model/Message' +import { OpenaiClient } from '@/apis/openai/OpenaiClient' import { RIGHTS } from '@/auth/RIGHTS' import { Context } from '@/server/context' @@ -15,10 +13,14 @@ export class AiChatResolver { async resumeChat(@Ctx() context: Context): Promise { const openaiClient = OpenaiClient.getInstance() if (!openaiClient) { - return Promise.resolve([new ChatGptMessage({ content: 'OpenAI API is not enabled', role: 'assistant' }, true)]) + return Promise.resolve([ + new ChatGptMessage({ content: 'OpenAI API is not enabled', role: 'assistant' }, true), + ]) } if (!context.user) { - return Promise.resolve([new ChatGptMessage({ content: 'User not found', role: 'assistant' }, true)]) + return Promise.resolve([ + new ChatGptMessage({ content: 'User not found', role: 'assistant' }, true), + ]) } const messages = await openaiClient.resumeThread(context.user) return messages.map((message) => new ChatGptMessage(message)) @@ -42,10 +44,14 @@ export class AiChatResolver { ): Promise { const openaiClient = OpenaiClient.getInstance() if (!openaiClient) { - return Promise.resolve(new ChatGptMessage({ content: 'OpenAI API is not enabled', role: 'assistant' }, true)) + return Promise.resolve( + new ChatGptMessage({ content: 'OpenAI API is not enabled', role: 'assistant' }, true), + ) } if (!context.user) { - return Promise.resolve(new ChatGptMessage({ content: 'User not found', role: 'assistant' }, true)) + return Promise.resolve( + new ChatGptMessage({ content: 'User not found', role: 'assistant' }, true), + ) } const messageObj = new Message(message) if (!threadId || threadId.length === 0) { diff --git a/backend/src/graphql/resolver/BalanceResolver.ts b/backend/src/graphql/resolver/BalanceResolver.ts index 0e88382ff..58937803a 100644 --- a/backend/src/graphql/resolver/BalanceResolver.ts +++ b/backend/src/graphql/resolver/BalanceResolver.ts @@ -1,19 +1,20 @@ -import { Transaction as dbTransaction, TransactionLink as dbTransactionLink } from 'database' +import { Balance } from '@model/Balance' +import { DecayLoggingView } from 'core' +import { + Transaction as dbTransaction, + TransactionLink as dbTransactionLink, + getLastTransaction, +} from 'database' import { Decimal } from 'decimal.js-light' +import { getLogger } from 'log4js' +import { calculateDecay } from 'shared' import { Authorized, Ctx, Query, Resolver } from 'type-graphql' import { IsNull } from 'typeorm' - -import { Balance } from '@model/Balance' - import { RIGHTS } from '@/auth/RIGHTS' -import { BalanceLoggingView } from '@/logging/BalanceLogging.view' -import { Context, getUser } from '@/server/context' -import { DecayLoggingView } from 'core' -import { calculateDecay } from 'shared' import { LOG4JS_BASE_CATEGORY_NAME } from '@/config/const' -import { getLastTransaction } from 'database' -import { getLogger } from 'log4js' +import { BalanceLoggingView } from '@/logging/BalanceLogging.view' +import { Context, getUser } from '@/server/context' import { GdtResolver } from './GdtResolver' import { transactionLinkSummary } from './util/transactionLinkSummary' diff --git a/backend/src/graphql/resolver/CommunityResolver.test.ts b/backend/src/graphql/resolver/CommunityResolver.test.ts index e36caf691..d83d57d9e 100644 --- a/backend/src/graphql/resolver/CommunityResolver.test.ts +++ b/backend/src/graphql/resolver/CommunityResolver.test.ts @@ -1,25 +1,26 @@ +import { cleanDB, testEnvironment } from '@test/helpers' import { ApolloServerTestClient } from 'apollo-server-testing' -import { Community as DbCommunity, FederatedCommunity as DbFederatedCommunity, getHomeCommunity } from 'database' +import { getLogger } from 'config-schema/test/testSetup' +import { + AppDatabase, + Community as DbCommunity, + FederatedCommunity as DbFederatedCommunity, + getHomeCommunity, +} from 'database' +import { createCommunity, createVerifiedFederatedCommunity } from 'database/src/seeds/community' import { GraphQLError } from 'graphql/error/GraphQLError' import { DataSource } from 'typeorm' import { v4 as uuidv4 } from 'uuid' - -import { cleanDB, testEnvironment } from '@test/helpers' - +import { CONFIG } from '@/config' import { userFactory } from '@/seeds/factory/user' import { login, updateHomeCommunityQuery } from '@/seeds/graphql/mutations' import { - allCommunities, + allCommunities, getCommunityByIdentifierQuery, getHomeCommunityQuery, reachableCommunities, } from '@/seeds/graphql/queries' import { peterLustig } from '@/seeds/users/peter-lustig' -import { createCommunity, createVerifiedFederatedCommunity } from 'database/src/seeds/community' - -import { getLogger } from 'config-schema/test/testSetup' -import { CONFIG } from '@/config' -import { AppDatabase } from 'database' jest.mock('@/password/EncryptorUtils') @@ -121,11 +122,11 @@ describe('CommunityResolver', () => { let homeCom3: DbFederatedCommunity let foreignCom1: DbFederatedCommunity let foreignCom2: DbFederatedCommunity - let foreignCom3: DbFederatedCommunity + let foreignCom3: DbFederatedCommunity beforeAll(async () => { // create admin and login as admin - await userFactory(testEnv, peterLustig) + await userFactory(testEnv, peterLustig) await mutate({ mutation: login, variables: peterLoginData }) }) @@ -498,7 +499,7 @@ describe('CommunityResolver', () => { DbCommunity.insert(foreignCom2), DbFederatedCommunity.insert(com1FedCom), DbFederatedCommunity.insert(com1FedCom2), - DbFederatedCommunity.insert(com2FedCom) + DbFederatedCommunity.insert(com2FedCom), ]) }) @@ -512,13 +513,14 @@ describe('CommunityResolver', () => { description: homeCom1.description, url: homeCom1.url, uuid: homeCom1.communityUuid, - }, { + }, + { foreign: foreignCom1.foreign, name: foreignCom1.name, description: foreignCom1.description, url: foreignCom1.url, uuid: foreignCom1.communityUuid, - } + }, ]) }) }) @@ -574,7 +576,7 @@ describe('CommunityResolver', () => { description: homeCom?.description, url: homeCom?.url, creationDate: homeCom?.creationDate?.toISOString(), - uuid: homeCom?.communityUuid + uuid: homeCom?.communityUuid, }, }, }) @@ -591,7 +593,7 @@ describe('CommunityResolver', () => { await DbCommunity.clear() // create admin and login as admin - await userFactory(testEnv, peterLustig) + await userFactory(testEnv, peterLustig) homeCom = (await getHomeCommunity())! foreignCom1 = await createCommunity(true, false) foreignCom2 = await createCommunity(true, false) @@ -599,7 +601,7 @@ describe('CommunityResolver', () => { await Promise.all([ DbCommunity.insert(foreignCom1), DbCommunity.insert(foreignCom2), - mutate({ mutation: login, variables: peterLoginData }) + mutate({ mutation: login, variables: peterLoginData }), ]) }) diff --git a/backend/src/graphql/resolver/CommunityResolver.ts b/backend/src/graphql/resolver/CommunityResolver.ts index d75541929..0209c284d 100644 --- a/backend/src/graphql/resolver/CommunityResolver.ts +++ b/backend/src/graphql/resolver/CommunityResolver.ts @@ -1,26 +1,15 @@ -import { - Community as DbCommunity, - getReachableCommunities, - getHomeCommunity -} from 'database' -import { Arg, Args, Authorized, Mutation, Query, Resolver } from 'type-graphql' import { Paginated } from '@arg/Paginated' import { EditCommunityInput } from '@input/EditCommunityInput' import { AdminCommunityView } from '@model/AdminCommunityView' import { Community } from '@model/Community' - -import { RIGHTS } from '@/auth/RIGHTS' -import { LogError } from '@/server/LogError' - -import { Location2Point } from './util/Location2Point' -import { - getAllCommunities, - getCommunityByIdentifier, - getCommunityByUuid, -} from './util/communities' +import { Community as DbCommunity, getHomeCommunity, getReachableCommunities } from 'database' import { updateAllDefinedAndChanged } from 'shared' - +import { Arg, Args, Authorized, Mutation, Query, Resolver } from 'type-graphql' +import { RIGHTS } from '@/auth/RIGHTS' import { CONFIG } from '@/config' +import { LogError } from '@/server/LogError' +import { getAllCommunities, getCommunityByIdentifier, getCommunityByUuid } from './util/communities' +import { Location2Point } from './util/Location2Point' @Resolver() export class CommunityResolver { @@ -35,11 +24,13 @@ export class CommunityResolver { @Query(() => [Community]) async reachableCommunities(): Promise { const dbCommunities: DbCommunity[] = await getReachableCommunities( - CONFIG.FEDERATION_VALIDATE_COMMUNITY_TIMER * 2, { - // order by + CONFIG.FEDERATION_VALIDATE_COMMUNITY_TIMER * 2, + { + // order by foreign: 'ASC', // home community first name: 'ASC', // sort foreign communities by name - }) + }, + ) return dbCommunities.map((dbCom: DbCommunity) => new Community(dbCom)) } diff --git a/backend/src/graphql/resolver/ContributionLinkResolver.test.ts b/backend/src/graphql/resolver/ContributionLinkResolver.test.ts index c67b900f8..3318b285f 100644 --- a/backend/src/graphql/resolver/ContributionLinkResolver.test.ts +++ b/backend/src/graphql/resolver/ContributionLinkResolver.test.ts @@ -1,11 +1,10 @@ +import { cleanDB, resetToken, testEnvironment } from '@test/helpers' import { ApolloServerTestClient } from 'apollo-server-testing' -import { ContributionLink as DbContributionLink, Event as DbEvent } from 'database' +import { getLogger } from 'config-schema/test/testSetup' +import { AppDatabase, ContributionLink as DbContributionLink, Event as DbEvent } from 'database' import { Decimal } from 'decimal.js-light' import { GraphQLError } from 'graphql' import { DataSource } from 'typeorm' - -import { cleanDB, resetToken, testEnvironment } from '@test/helpers' - import { LOG4JS_BASE_CATEGORY_NAME } from '@/config/const' import { EventType } from '@/event/Events' import { userFactory } from '@/seeds/factory/user' @@ -18,8 +17,6 @@ import { import { listContributionLinks } from '@/seeds/graphql/queries' import { bibiBloxberg } from '@/seeds/users/bibi-bloxberg' import { peterLustig } from '@/seeds/users/peter-lustig' -import { getLogger } from 'config-schema/test/testSetup' -import { AppDatabase } from 'database' jest.mock('@/password/EncryptorUtils') diff --git a/backend/src/graphql/resolver/ContributionLinkResolver.ts b/backend/src/graphql/resolver/ContributionLinkResolver.ts index 456cfafb1..20ba3064c 100644 --- a/backend/src/graphql/resolver/ContributionLinkResolver.ts +++ b/backend/src/graphql/resolver/ContributionLinkResolver.ts @@ -1,12 +1,11 @@ -import { ContributionLink as DbContributionLink } from 'database' -import { Arg, Args, Authorized, Ctx, Int, Mutation, Query, Resolver } from 'type-graphql' -import { IsNull, MoreThan } from 'typeorm' - import { ContributionLinkArgs } from '@arg/ContributionLinkArgs' import { Paginated } from '@arg/Paginated' import { Order } from '@enum/Order' import { ContributionLink } from '@model/ContributionLink' import { ContributionLinkList } from '@model/ContributionLinkList' +import { ContributionLink as DbContributionLink } from 'database' +import { Arg, Args, Authorized, Ctx, Int, Mutation, Query, Resolver } from 'type-graphql' +import { IsNull, MoreThan } from 'typeorm' import { RIGHTS } from '@/auth/RIGHTS' import { @@ -14,8 +13,8 @@ import { EVENT_ADMIN_CONTRIBUTION_LINK_DELETE, EVENT_ADMIN_CONTRIBUTION_LINK_UPDATE, } from '@/event/Events' -import { LogError } from '@/server/LogError' import { Context, getUser } from '@/server/context' +import { LogError } from '@/server/LogError' import { transactionLinkCode as contributionLinkCode } from './TransactionLinkResolver' import { isStartEndDateValid } from './util/creations' diff --git a/backend/src/graphql/resolver/ContributionMessageResolver.test.ts b/backend/src/graphql/resolver/ContributionMessageResolver.test.ts index cde631f9d..65d1b02df 100644 --- a/backend/src/graphql/resolver/ContributionMessageResolver.test.ts +++ b/backend/src/graphql/resolver/ContributionMessageResolver.test.ts @@ -1,13 +1,12 @@ -import { ApolloServerTestClient } from 'apollo-server-testing' -import { Contribution as DbContribution, Event as DbEvent } from 'database' -import { GraphQLError } from 'graphql' -import { DataSource } from 'typeorm' - import { ContributionStatus } from '@enum/ContributionStatus' import { cleanDB, resetToken, testEnvironment } from '@test/helpers' - -import { LOG4JS_BASE_CATEGORY_NAME } from '@/config/const' +import { ApolloServerTestClient } from 'apollo-server-testing' +import { getLogger } from 'config-schema/test/testSetup' import { sendAddedContributionMessageEmail } from 'core' +import { AppDatabase, Contribution as DbContribution, Event as DbEvent } from 'database' +import { GraphQLError } from 'graphql' +import { DataSource } from 'typeorm' +import { LOG4JS_BASE_CATEGORY_NAME } from '@/config/const' import { EventType } from '@/event/Events' import { userFactory } from '@/seeds/factory/user' import { @@ -20,10 +19,10 @@ import { adminListContributionMessages, listContributionMessages } from '@/seeds import { bibiBloxberg } from '@/seeds/users/bibi-bloxberg' import { bobBaumeister } from '@/seeds/users/bob-baumeister' import { peterLustig } from '@/seeds/users/peter-lustig' -import { getLogger} from 'config-schema/test/testSetup' -import { AppDatabase } from 'database' -const logger = getLogger(`${LOG4JS_BASE_CATEGORY_NAME}.graphql.resolver.ContributionMessageResolver`) +const logger = getLogger( + `${LOG4JS_BASE_CATEGORY_NAME}.graphql.resolver.ContributionMessageResolver`, +) const logErrorLogger = getLogger(`${LOG4JS_BASE_CATEGORY_NAME}.server.LogError`) const interactionLogger = getLogger( `${LOG4JS_BASE_CATEGORY_NAME}.interactions.updateUnconfirmedContribution`, diff --git a/backend/src/graphql/resolver/ContributionMessageResolver.ts b/backend/src/graphql/resolver/ContributionMessageResolver.ts index 5926a1bc4..cf987d8a6 100644 --- a/backend/src/graphql/resolver/ContributionMessageResolver.ts +++ b/backend/src/graphql/resolver/ContributionMessageResolver.ts @@ -1,35 +1,34 @@ +import { ContributionMessageArgs } from '@arg/ContributionMessageArgs' +import { Paginated } from '@arg/Paginated' +import { ContributionMessageType } from '@enum/ContributionMessageType' +import { Order } from '@enum/Order' +import { ContributionMessage, ContributionMessageListResult } from '@model/ContributionMessage' +import { sendAddedContributionMessageEmail } from 'core' import { AppDatabase, Contribution as DbContribution, ContributionMessage as DbContributionMessage, User as DbUser, } from 'database' +import { getLogger } from 'log4js' import { Arg, Args, Authorized, Ctx, Int, Mutation, Query, Resolver } from 'type-graphql' import { EntityManager, FindOptionsRelations } from 'typeorm' - -import { ContributionMessageArgs } from '@arg/ContributionMessageArgs' -import { Paginated } from '@arg/Paginated' -import { ContributionMessageType } from '@enum/ContributionMessageType' -import { Order } from '@enum/Order' -import { ContributionMessage, ContributionMessageListResult } from '@model/ContributionMessage' - import { RIGHTS } from '@/auth/RIGHTS' -import { sendAddedContributionMessageEmail } from 'core' +import { LOG4JS_BASE_CATEGORY_NAME } from '@/config/const' import { EVENT_ADMIN_CONTRIBUTION_MESSAGE_CREATE, EVENT_CONTRIBUTION_MESSAGE_CREATE, } from '@/event/Events' import { UpdateUnconfirmedContributionContext } from '@/interactions/updateUnconfirmedContribution/UpdateUnconfirmedContribution.context' -import { LogError } from '@/server/LogError' import { Context, getUser } from '@/server/context' -import { getLogger } from 'log4js' -import { LOG4JS_BASE_CATEGORY_NAME } from '@/config/const' +import { LogError } from '@/server/LogError' import { contributionFrontendLink } from './util/contributions' import { findContributionMessages } from './util/findContributionMessages' const db = AppDatabase.getInstance() -const createLogger = () => getLogger(`${LOG4JS_BASE_CATEGORY_NAME}.graphql.resolver.ContributionMessageResolver`) +const createLogger = () => + getLogger(`${LOG4JS_BASE_CATEGORY_NAME}.graphql.resolver.ContributionMessageResolver`) @Resolver() export class ContributionMessageResolver { diff --git a/backend/src/graphql/resolver/ContributionResolver.test.ts b/backend/src/graphql/resolver/ContributionResolver.test.ts index e036a230d..e750f7185 100644 --- a/backend/src/graphql/resolver/ContributionResolver.test.ts +++ b/backend/src/graphql/resolver/ContributionResolver.test.ts @@ -1,9 +1,3 @@ -import { ApolloServerTestClient } from 'apollo-server-testing' -import { Contribution, Event as DbEvent, Transaction as DbTransaction, User } from 'database' -import { Decimal } from 'decimal.js-light' -import { GraphQLError } from 'graphql' -import { DataSource, Equal } from 'typeorm' - import { ContributionMessageType } from '@enum/ContributionMessageType' import { ContributionStatus } from '@enum/ContributionStatus' import { Order } from '@enum/Order' @@ -14,13 +8,26 @@ import { resetToken, testEnvironment, } from '@test/helpers' - -import { LOG4JS_BASE_CATEGORY_NAME } from '@/config/const' +import { ApolloServerTestClient } from 'apollo-server-testing' +import { getLogger } from 'config-schema/test/testSetup' import { + getFirstDayOfPreviousNMonth, sendContributionConfirmedEmail, sendContributionDeletedEmail, sendContributionDeniedEmail, } from 'core' +import { + AppDatabase, + Contribution, + Event as DbEvent, + Transaction as DbTransaction, + User, +} from 'database' +import { Decimal } from 'decimal.js-light' +import { GraphQLError } from 'graphql' +import { getLogger as originalGetLogger } from 'log4js' +import { DataSource, Equal } from 'typeorm' +import { LOG4JS_BASE_CATEGORY_NAME } from '@/config/const' import { EventType } from '@/event/Events' import { creations } from '@/seeds/creation/index' import { creationFactory } from '@/seeds/factory/creation' @@ -49,10 +56,6 @@ import { garrickOllivander } from '@/seeds/users/garrick-ollivander' import { peterLustig } from '@/seeds/users/peter-lustig' import { raeuberHotzenplotz } from '@/seeds/users/raeuber-hotzenplotz' import { stephenHawking } from '@/seeds/users/stephen-hawking' -import { getFirstDayOfPreviousNMonth } from 'core' -import { getLogger } from 'config-schema/test/testSetup' -import { getLogger as originalGetLogger } from 'log4js' -import { AppDatabase } from 'database' jest.mock('core', () => { const originalModule = jest.requireActual('core') diff --git a/backend/src/graphql/resolver/ContributionResolver.ts b/backend/src/graphql/resolver/ContributionResolver.ts index 167677152..b18af5c39 100644 --- a/backend/src/graphql/resolver/ContributionResolver.ts +++ b/backend/src/graphql/resolver/ContributionResolver.ts @@ -1,35 +1,9 @@ -import { - AppDatabase, - Contribution as DbContribution, - Transaction as DbTransaction, - User as DbUser, - getLastTransaction, - UserContact, -} from 'database' -import { Decimal } from 'decimal.js-light' -import { GraphQLResolveInfo } from 'graphql' -import { Arg, Args, Authorized, Ctx, Info, Int, Mutation, Query, Resolver } from 'type-graphql' -import { EntityManager, IsNull } from 'typeorm' - -import { RIGHTS } from '@/auth/RIGHTS' -import { - EVENT_ADMIN_CONTRIBUTION_CONFIRM, - EVENT_ADMIN_CONTRIBUTION_CREATE, - EVENT_ADMIN_CONTRIBUTION_DELETE, - EVENT_ADMIN_CONTRIBUTION_DENY, - EVENT_ADMIN_CONTRIBUTION_UPDATE, - EVENT_CONTRIBUTION_CREATE, - EVENT_CONTRIBUTION_DELETE, - EVENT_CONTRIBUTION_UPDATE, -} from '@/event/Events' -import { UpdateUnconfirmedContributionContext } from '@/interactions/updateUnconfirmedContribution/UpdateUnconfirmedContribution.context' -import { LogError } from '@/server/LogError' -import { Context, getClientTimezoneOffset, getUser } from '@/server/context' import { AdminCreateContributionArgs } from '@arg/AdminCreateContributionArgs' import { AdminUpdateContributionArgs } from '@arg/AdminUpdateContributionArgs' import { ContributionArgs } from '@arg/ContributionArgs' import { Paginated } from '@arg/Paginated' import { SearchContributionsFilterArgs } from '@arg/SearchContributionsFilterArgs' +import { ContributionMessageType } from '@enum/ContributionMessageType' import { ContributionStatus } from '@enum/ContributionStatus' import { ContributionType } from '@enum/ContributionType' import { AdminUpdateContribution } from '@model/AdminUpdateContribution' @@ -42,15 +16,39 @@ import { sendContributionConfirmedEmail, sendContributionDeletedEmail, sendContributionDeniedEmail, - TransactionTypeId + TransactionTypeId, } from 'core' -import { calculateDecay, Decay } from 'shared' - -import { contributionTransaction } from '@/apis/dltConnector' -import { LOG4JS_BASE_CATEGORY_NAME } from '@/config/const' -import { ContributionMessageType } from '@enum/ContributionMessageType' +import { + AppDatabase, + Contribution as DbContribution, + Transaction as DbTransaction, + User as DbUser, + getLastTransaction, + UserContact, +} from 'database' +import { Decimal } from 'decimal.js-light' +import { GraphQLResolveInfo } from 'graphql' import { getLogger } from 'log4js' import { Mutex } from 'redis-semaphore' +import { calculateDecay, Decay } from 'shared' +import { Arg, Args, Authorized, Ctx, Info, Int, Mutation, Query, Resolver } from 'type-graphql' +import { EntityManager, IsNull } from 'typeorm' +import { contributionTransaction } from '@/apis/dltConnector' +import { RIGHTS } from '@/auth/RIGHTS' +import { LOG4JS_BASE_CATEGORY_NAME } from '@/config/const' +import { + EVENT_ADMIN_CONTRIBUTION_CONFIRM, + EVENT_ADMIN_CONTRIBUTION_CREATE, + EVENT_ADMIN_CONTRIBUTION_DELETE, + EVENT_ADMIN_CONTRIBUTION_DENY, + EVENT_ADMIN_CONTRIBUTION_UPDATE, + EVENT_CONTRIBUTION_CREATE, + EVENT_CONTRIBUTION_DELETE, + EVENT_CONTRIBUTION_UPDATE, +} from '@/event/Events' +import { UpdateUnconfirmedContributionContext } from '@/interactions/updateUnconfirmedContribution/UpdateUnconfirmedContribution.context' +import { Context, getClientTimezoneOffset, getUser } from '@/server/context' +import { LogError } from '@/server/LogError' import { contributionFrontendLink, loadAllContributions, @@ -61,7 +59,8 @@ import { extractGraphQLFields } from './util/extractGraphQLFields' import { findContributions } from './util/findContributions' const db = AppDatabase.getInstance() -const createLogger = () => getLogger(`${LOG4JS_BASE_CATEGORY_NAME}.graphql.resolver.ContributionResolver`) +const createLogger = () => + getLogger(`${LOG4JS_BASE_CATEGORY_NAME}.graphql.resolver.ContributionResolver`) @Resolver(() => Contribution) export class ContributionResolver { @@ -435,12 +434,15 @@ export class ContributionResolver { const logger = createLogger() logger.addContext('contribution', id) // acquire lock - const mutex = new Mutex (db.getRedisClient(), 'TRANSACTIONS_LOCK') + const mutex = new Mutex(db.getRedisClient(), 'TRANSACTIONS_LOCK') await mutex.acquire() try { const clientTimezoneOffset = getClientTimezoneOffset(context) - const contribution = await DbContribution.findOne({ where: { id }, relations: {user: {emailContact: true}} }) + const contribution = await DbContribution.findOne({ + where: { id }, + relations: { user: { emailContact: true } }, + }) if (!contribution) { throw new LogError('Contribution not found', id) } @@ -450,7 +452,7 @@ export class ContributionResolver { if (contribution.contributionStatus === 'DENIED') { throw new LogError('Contribution already denied', id) } - + const moderatorUser = getUser(context) if (moderatorUser.id === contribution.userId) { throw new LogError('Moderator can not confirm own contribution') @@ -460,7 +462,11 @@ export class ContributionResolver { throw new LogError('Can not confirm contribution since the user was deleted') } const receivedCallDate = new Date() - const dltTransactionPromise = contributionTransaction(contribution, moderatorUser, receivedCallDate) + const dltTransactionPromise = contributionTransaction( + contribution, + moderatorUser, + receivedCallDate, + ) const creations = await getUserCreation(contribution.userId, clientTimezoneOffset, false) validateContribution( creations, @@ -468,7 +474,7 @@ export class ContributionResolver { contribution.contributionDate, clientTimezoneOffset, ) - + const queryRunner = db.getDataSource().createQueryRunner() await queryRunner.connect() await queryRunner.startTransaction('REPEATABLE READ') // 'READ COMMITTED') @@ -515,7 +521,7 @@ export class ContributionResolver { await queryRunner.manager.update(DbContribution, { id: contribution.id }, contribution) await queryRunner.commitTransaction() - + logger.info('creation commited successfuly.') await sendContributionConfirmedEmail({ firstName: user.firstName, @@ -536,12 +542,14 @@ export class ContributionResolver { // wait for finishing transaction by dlt-connector/hiero const dltStartTime = new Date() const dltTransaction = await dltTransactionPromise - if(dltTransaction) { + if (dltTransaction) { dltTransaction.transactionId = transaction.id await dltTransaction.save() } const dltEndTime = new Date() - logger.debug(`dlt-connector contribution finished in ${dltEndTime.getTime() - dltStartTime.getTime()} ms`) + logger.debug( + `dlt-connector contribution finished in ${dltEndTime.getTime() - dltStartTime.getTime()} ms`, + ) } catch (e) { await queryRunner.rollbackTransaction() throw new LogError('Creation was not successful', e) diff --git a/backend/src/graphql/resolver/EmailOptinCodes.test.ts b/backend/src/graphql/resolver/EmailOptinCodes.test.ts index 20a5b834e..da2181230 100644 --- a/backend/src/graphql/resolver/EmailOptinCodes.test.ts +++ b/backend/src/graphql/resolver/EmailOptinCodes.test.ts @@ -1,16 +1,13 @@ +import { cleanDB, testEnvironment } from '@test/helpers' import { ApolloServerTestClient } from 'apollo-server-testing' -import { User as DbUser } from 'database' +import { CONFIG as CORE_CONFIG } from 'core' +import { AppDatabase, User as DbUser } from 'database' import { GraphQLError } from 'graphql' import { DataSource } from 'typeorm' - -import { cleanDB, testEnvironment } from '@test/helpers' - -import { CONFIG as CORE_CONFIG } from 'core' import { CONFIG } from '@/config' import { writeHomeCommunityEntry } from '@/seeds/community' import { createUser, forgotPassword, setPassword } from '@/seeds/graphql/mutations' import { queryOptIn } from '@/seeds/graphql/queries' -import { AppDatabase } from 'database' let mutate: ApolloServerTestClient['mutate'] let query: ApolloServerTestClient['query'] diff --git a/backend/src/graphql/resolver/GdtResolver.ts b/backend/src/graphql/resolver/GdtResolver.ts index c689cf9c2..62d8eb732 100644 --- a/backend/src/graphql/resolver/GdtResolver.ts +++ b/backend/src/graphql/resolver/GdtResolver.ts @@ -1,17 +1,15 @@ -import { Arg, Args, Authorized, Ctx, Float, Int, Query, Resolver } from 'type-graphql' - import { Paginated } from '@arg/Paginated' import { Order } from '@enum/Order' import { GdtEntry } from '@model/GdtEntry' import { GdtEntryList } from '@model/GdtEntryList' - +import { getLogger } from 'log4js' +import { Arg, Args, Authorized, Ctx, Float, Int, Query, Resolver } from 'type-graphql' import { apiGet, apiPost } from '@/apis/HttpRequest' import { RIGHTS } from '@/auth/RIGHTS' import { CONFIG } from '@/config' -import { LogError } from '@/server/LogError' -import { Context, getUser } from '@/server/context' -import { getLogger } from 'log4js' import { LOG4JS_BASE_CATEGORY_NAME } from '@/config/const' +import { Context, getUser } from '@/server/context' +import { LogError } from '@/server/LogError' const logger = getLogger(`${LOG4JS_BASE_CATEGORY_NAME}.graphql.resolver.GdtResolver`) diff --git a/backend/src/graphql/resolver/KlicktippResolver.test.ts b/backend/src/graphql/resolver/KlicktippResolver.test.ts index c13da22d2..8ad4e2447 100644 --- a/backend/src/graphql/resolver/KlicktippResolver.test.ts +++ b/backend/src/graphql/resolver/KlicktippResolver.test.ts @@ -1,15 +1,12 @@ -import { Event as DbEvent, UserContact } from 'database' -import { GraphQLError } from 'graphql' - import { cleanDB, resetToken, testEnvironment } from '@test/helpers' import { getLogger } from 'config-schema/test/testSetup' - +import { AppDatabase, Event as DbEvent, UserContact } from 'database' +import { GraphQLError } from 'graphql' +import { LOG4JS_BASE_CATEGORY_NAME } from '@/config/const' import { EventType } from '@/event/Events' import { userFactory } from '@/seeds/factory/user' import { login, subscribeNewsletter, unsubscribeNewsletter } from '@/seeds/graphql/mutations' import { bibiBloxberg } from '@/seeds/users/bibi-bloxberg' -import { LOG4JS_BASE_CATEGORY_NAME } from '@/config/const' -import { AppDatabase } from 'database' jest.mock('@/password/EncryptorUtils') diff --git a/backend/src/graphql/resolver/ProjectBrandingResolver.ts b/backend/src/graphql/resolver/ProjectBrandingResolver.ts index 9e59dbbaa..610afa630 100644 --- a/backend/src/graphql/resolver/ProjectBrandingResolver.ts +++ b/backend/src/graphql/resolver/ProjectBrandingResolver.ts @@ -1,16 +1,14 @@ -import { ProjectBranding as DbProjectBranding } from 'database' -import { Arg, Authorized, ID, Int, Mutation, Query, Resolver } from 'type-graphql' - import { ProjectBrandingInput } from '@input/ProjectBrandingInput' import { ProjectBranding } from '@model/ProjectBranding' import { Space } from '@model/Space' import { SpaceList } from '@model/SpaceList' - +import { ProjectBranding as DbProjectBranding } from 'database' +import { getLogger } from 'log4js' +import { Arg, Authorized, ID, Int, Mutation, Query, Resolver } from 'type-graphql' import { HumHubClient } from '@/apis/humhub/HumHubClient' import { RIGHTS } from '@/auth/RIGHTS' -import { LogError } from '@/server/LogError' -import { getLogger } from 'log4js' import { LOG4JS_BASE_CATEGORY_NAME } from '@/config/const' +import { LogError } from '@/server/LogError' const logger = getLogger(`${LOG4JS_BASE_CATEGORY_NAME}.graphql.resolver.ProjectBrandingResolver`) diff --git a/backend/src/graphql/resolver/StatisticsResolver.ts b/backend/src/graphql/resolver/StatisticsResolver.ts index 7ba54fafb..1e435c2a7 100644 --- a/backend/src/graphql/resolver/StatisticsResolver.ts +++ b/backend/src/graphql/resolver/StatisticsResolver.ts @@ -1,11 +1,9 @@ +import { CommunityStatistics, DynamicStatisticsFields } from '@model/CommunityStatistics' import { AppDatabase, Transaction as DbTransaction, User as DbUser } from 'database' import { Decimal } from 'decimal.js-light' -import { Authorized, FieldResolver, Query, Resolver } from 'type-graphql' - -import { CommunityStatistics, DynamicStatisticsFields } from '@model/CommunityStatistics' - -import { RIGHTS } from '@/auth/RIGHTS' import { calculateDecay } from 'shared' +import { Authorized, FieldResolver, Query, Resolver } from 'type-graphql' +import { RIGHTS } from '@/auth/RIGHTS' const db = AppDatabase.getInstance() diff --git a/backend/src/graphql/resolver/TransactionLinkResolver.test.ts b/backend/src/graphql/resolver/TransactionLinkResolver.test.ts index bb5787378..6538dd89e 100644 --- a/backend/src/graphql/resolver/TransactionLinkResolver.test.ts +++ b/backend/src/graphql/resolver/TransactionLinkResolver.test.ts @@ -1,5 +1,9 @@ +import { UnconfirmedContribution } from '@model/UnconfirmedContribution' +import { cleanDB, resetEntity, resetToken, testEnvironment } from '@test/helpers' import { ApolloServerTestClient } from 'apollo-server-testing' +import { getLogger } from 'config-schema/test/testSetup' import { + AppDatabase, ContributionLink as DbContributionLink, Event as DbEvent, Transaction, @@ -9,10 +13,8 @@ import { import { Decimal } from 'decimal.js-light' import { GraphQLError } from 'graphql' import { DataSource } from 'typeorm' - -import { UnconfirmedContribution } from '@model/UnconfirmedContribution' -import { cleanDB, resetEntity, resetToken, testEnvironment } from '@test/helpers' - +import { CONFIG } from '@/config' +import { LOG4JS_BASE_CATEGORY_NAME } from '@/config/const' import { EventType } from '@/event/Events' import { creations } from '@/seeds/creation/index' import { creationFactory } from '@/seeds/factory/creation' @@ -32,11 +34,7 @@ import { listTransactionLinksAdmin } from '@/seeds/graphql/queries' import { transactionLinks } from '@/seeds/transactionLink/index' import { bibiBloxberg } from '@/seeds/users/bibi-bloxberg' import { peterLustig } from '@/seeds/users/peter-lustig' -import { LOG4JS_BASE_CATEGORY_NAME } from '@/config/const' -import { getLogger } from 'config-schema/test/testSetup' import { transactionLinkCode } from './TransactionLinkResolver' -import { CONFIG } from '@/config' -import { AppDatabase } from 'database' const logErrorLogger = getLogger(`${LOG4JS_BASE_CATEGORY_NAME}.server.LogError`) @@ -967,7 +965,7 @@ describe('TransactionLinkResolver', () => { createdAt: expect.any(String), }), expect.objectContaining({ - memo: "Kein Trick, keine Zauberrei,\n bei Gradidio sei dabei!", + memo: 'Kein Trick, keine Zauberrei,\n bei Gradidio sei dabei!', deletedAt: expect.any(String), }), ]), diff --git a/backend/src/graphql/resolver/TransactionLinkResolver.ts b/backend/src/graphql/resolver/TransactionLinkResolver.ts index e834ae305..82fd1ca2e 100644 --- a/backend/src/graphql/resolver/TransactionLinkResolver.ts +++ b/backend/src/graphql/resolver/TransactionLinkResolver.ts @@ -1,5 +1,3 @@ -import { randomBytes } from 'crypto' - import { Paginated } from '@arg/Paginated' import { TransactionLinkArgs } from '@arg/TransactionLinkArgs' import { TransactionLinkFilters } from '@arg/TransactionLinkFilters' @@ -12,51 +10,65 @@ import { RedeemJwtLink } from '@model/RedeemJwtLink' import { TransactionLink, TransactionLinkResult } from '@model/TransactionLink' import { User } from '@model/User' import { QueryLinkResult } from '@union/QueryLinkResult' -import { Decay, interpretEncryptedTransferArgs, TransactionTypeId } from 'core' import { - AppDatabase, Contribution as DbContribution, - ContributionLink as DbContributionLink, - FederatedCommunity as DbFederatedCommunity, + Decay, + EncryptedTransferArgs, + fullName, + interpretEncryptedTransferArgs, + TransactionTypeId, +} from 'core' +import { randomBytes } from 'crypto' +import { + AppDatabase, + Contribution as DbContribution, + ContributionLink as DbContributionLink, DltTransaction as DbDltTransaction, + FederatedCommunity as DbFederatedCommunity, Transaction as DbTransaction, TransactionLink as DbTransactionLink, User as DbUser, findModeratorCreatingContributionLink, findTransactionLinkByCode, - getHomeCommunity + getHomeCommunity, + getLastTransaction, } from 'database' import { Decimal } from 'decimal.js-light' +import { Redis } from 'ioredis' +import { getLogger, Logger } from 'log4js' +import { Mutex } from 'redis-semaphore' +// import { TRANSACTION_LINK_LOCK, TRANSACTIONS_LOCK } from 'database' +import { + calculateDecay, + compoundInterest, + DisburseJwtPayloadType, + decode, + encode, + encryptAndSign, + RedeemJwtPayloadType, + SignedTransferPayloadType, + verify, +} from 'shared' +import { randombytes_random } from 'sodium-native' import { Arg, Args, Authorized, Ctx, Int, Mutation, Query, Resolver } from 'type-graphql' - +import { + contributionTransaction, + deferredTransferTransaction, + redeemDeferredTransferTransaction, +} from '@/apis/dltConnector' import { RIGHTS } from '@/auth/RIGHTS' +import { LOG4JS_BASE_CATEGORY_NAME } from '@/config/const' import { EVENT_CONTRIBUTION_LINK_REDEEM, EVENT_TRANSACTION_LINK_CREATE, EVENT_TRANSACTION_LINK_DELETE, EVENT_TRANSACTION_LINK_REDEEM, } from '@/event/Events' -import { LogError } from '@/server/LogError' -import { Context, getClientTimezoneOffset, getUser } from '@/server/context' -import { calculateBalance } from '@/util/validate' -import { fullName } from 'core' -// import { TRANSACTION_LINK_LOCK, TRANSACTIONS_LOCK } from 'database' -import { - calculateDecay, - compoundInterest, - decode, - DisburseJwtPayloadType, - encode, - encryptAndSign, - RedeemJwtPayloadType, - verify -} from 'shared' -import { LOG4JS_BASE_CATEGORY_NAME } from '@/config/const' import { DisbursementClient as V1_0_DisbursementClient } from '@/federation/client/1_0/DisbursementClient' import { DisbursementClientFactory } from '@/federation/client/DisbursementClientFactory' -import { EncryptedTransferArgs } from 'core' -import { getLastTransaction } from 'database' -import { getLogger, Logger } from 'log4js' -import { randombytes_random } from 'sodium-native' +import { Context, getClientTimezoneOffset, getUser } from '@/server/context' +import { LogError } from '@/server/LogError' +import { calculateBalance } from '@/util/validate' +import { CODE_VALID_DAYS_DURATION } from './const/const' import { executeTransaction } from './TransactionResolver' import { getAuthenticatedCommunities, @@ -65,13 +77,9 @@ import { } from './util/communities' import { getUserCreation, validateContribution } from './util/creations' import { transactionLinkList } from './util/transactionLinkList' -import { SignedTransferPayloadType } from 'shared' -import { contributionTransaction, deferredTransferTransaction, redeemDeferredTransferTransaction } from '@/apis/dltConnector' -import { CODE_VALID_DAYS_DURATION } from './const/const' -import { Redis } from 'ioredis' -import { Mutex } from 'redis-semaphore' -const createLogger = (method: string) => getLogger(`${LOG4JS_BASE_CATEGORY_NAME}.graphql.resolver.TransactionLinkResolver.${method}`) +const createLogger = (method: string) => + getLogger(`${LOG4JS_BASE_CATEGORY_NAME}.graphql.resolver.TransactionLinkResolver.${method}`) // TODO: do not export, test it inside the resolver export const transactionLinkCode = (date: Date): string => { @@ -83,7 +91,6 @@ export const transactionLinkCode = (date: Date): string => { ) } - const db = AppDatabase.getInstance() export const transactionLinkExpireDate = (date: Date): Date => { @@ -130,7 +137,9 @@ export class TransactionLinkResolver { const startTime = Date.now() const dltTransaction = await dltTransactionPromise const endTime = Date.now() - createLogger('createTransactionLink').debug(`dlt transaction created in ${endTime - startTime} ms`) + createLogger('createTransactionLink').debug( + `dlt transaction created in ${endTime - startTime} ms`, + ) if (dltTransaction) { dltTransaction.transactionLinkId = transactionLink.id await DbDltTransaction.save(dltTransaction) @@ -167,14 +176,21 @@ export class TransactionLinkResolver { }) transactionLink.user = user - const dltTransactionPromise = redeemDeferredTransferTransaction(transactionLink, transactionLink.amount.toString(), transactionLink.deletedAt!, user) + const dltTransactionPromise = redeemDeferredTransferTransaction( + transactionLink, + transactionLink.amount.toString(), + transactionLink.deletedAt!, + user, + ) await EVENT_TRANSACTION_LINK_DELETE(user, transactionLink) // wait for dlt transaction to be created const startTime = Date.now() const dltTransaction = await dltTransactionPromise const endTime = Date.now() - createLogger('deleteTransactionLink').debug(`dlt transaction created in ${endTime - startTime} ms`) + createLogger('deleteTransactionLink').debug( + `dlt transaction created in ${endTime - startTime} ms`, + ) if (dltTransaction) { dltTransaction.transactionLinkId = transactionLink.id await DbDltTransaction.save(dltTransaction) @@ -382,12 +398,13 @@ export class TransactionLinkResolver { const startTime = new Date() const dltTransaction = await dltTransactionPromise const endTime = new Date() - methodLogger.info(`dlt-connector transaction finished in ${endTime.getTime() - startTime.getTime()} ms`) + methodLogger.info( + `dlt-connector transaction finished in ${endTime.getTime() - startTime.getTime()} ms`, + ) if (dltTransaction) { dltTransaction.transactionId = transaction.id await dltTransaction.save() } - } } catch (e) { await queryRunner.rollbackTransaction() @@ -398,10 +415,10 @@ export class TransactionLinkResolver { } finally { // releaseLock() await mutex.release() - } + } return true } else { - // const releaseLinkLock = await TRANSACTION_LINK_LOCK.acquire() + // const releaseLinkLock = await TRANSACTION_LINK_LOCK.acquire() const mutex = new Mutex(db.getRedisClient(), 'TRANSACTION_LINK_LOCK') await mutex.acquire() const now = new Date() @@ -508,7 +525,11 @@ export class TransactionLinkResolver { if (!recipientCom.publicJwtKey) { throw new LogError('Recipient community publicJwtKey is not set') } - const redeemJwt = await encryptAndSign(redeemJwtPayloadType, senderCom.privateJwtKey!, recipientCom.publicJwtKey!) + const redeemJwt = await encryptAndSign( + redeemJwtPayloadType, + senderCom.privateJwtKey!, + recipientCom.publicJwtKey!, + ) if (!redeemJwt) { throw new LogError('Redeem JWT was not created successfully') } @@ -517,7 +538,7 @@ export class TransactionLinkResolver { args.publicKey = senderCom.publicKey.toString('hex') args.jwt = redeemJwt args.handshakeID = randombytes_random().toString() - if(methodLogger.isDebugEnabled()) { + if (methodLogger.isDebugEnabled()) { methodLogger.debug('successfully created RedeemJWT-Response with args:', args) } const signedTransferPayload = new SignedTransferPayloadType( @@ -525,15 +546,21 @@ export class TransactionLinkResolver { args.jwt, args.handshakeID, ) - if(methodLogger.isDebugEnabled()) { - methodLogger.debug('successfully created RedeemJWT-Response with signedTransferPayload:', signedTransferPayload) + if (methodLogger.isDebugEnabled()) { + methodLogger.debug( + 'successfully created RedeemJWT-Response with signedTransferPayload:', + signedTransferPayload, + ) } const signedTransferJwt = await encode(signedTransferPayload, senderCom.privateJwtKey!) if (!signedTransferJwt) { throw new LogError('SignedTransfer JWT was not created successfully') } - if(methodLogger.isDebugEnabled()) { - methodLogger.debug('successfully created RedeemJWT-Response with signedTransferJwt:', signedTransferJwt) + if (methodLogger.isDebugEnabled()) { + methodLogger.debug( + 'successfully created RedeemJWT-Response with signedTransferJwt:', + signedTransferJwt, + ) } return signedTransferJwt @@ -563,7 +590,7 @@ export class TransactionLinkResolver { const handshakeID = randombytes_random().toString() const methodLogger = createLogger(`disburseTransactionLink`) methodLogger.addContext('handshakeID', handshakeID) - if(methodLogger.isDebugEnabled()) { + if (methodLogger.isDebugEnabled()) { methodLogger.debug('args=', { senderGradidoId, senderCommunityUuid, @@ -575,10 +602,10 @@ export class TransactionLinkResolver { amount, memo, validUntil, - recipientAlias, + recipientAlias, }) } - const senderCom = await getCommunityByUuid(senderCommunityUuid) + const senderCom = await getCommunityByUuid(senderCommunityUuid) if (!senderCom) { const errmsg = `Sender community not found with uuid=${senderCommunityUuid}` methodLogger.error(errmsg) @@ -612,11 +639,15 @@ export class TransactionLinkResolver { validUntil!, recipientAlias!, ) - if(methodLogger.isDebugEnabled()) { + if (methodLogger.isDebugEnabled()) { methodLogger.debug('disburseJwtPayload=', disburseJwtPayload) } - const jws = await encryptAndSign(disburseJwtPayload, recipientCom.privateJwtKey!, senderCom.publicJwtKey!) - if(methodLogger.isDebugEnabled()) { + const jws = await encryptAndSign( + disburseJwtPayload, + recipientCom.privateJwtKey!, + senderCom.publicJwtKey!, + ) + if (methodLogger.isDebugEnabled()) { methodLogger.debug('jws=', jws) } const args = new EncryptedTransferArgs() @@ -626,7 +657,7 @@ export class TransactionLinkResolver { try { // now send the disburseJwt to the sender community to invoke a x-community-tx to disbures the redeemLink const result = await client.sendDisburseJwtToSenderCommunity(args) - if(methodLogger.isDebugEnabled()) { + if (methodLogger.isDebugEnabled()) { methodLogger.debug('Disburse JWT was sent successfully with result=', result) } } catch (e) { @@ -675,26 +706,38 @@ export class TransactionLinkResolver { async queryRedeemJwtLink(code: string, logger: Logger): Promise { logger.debug('queryRedeemJwtLink... redeem jwt-token found') - + // decode token first to get the EncryptedTransferArgs with the senderCommunity.publicKey as input to verify token const decodedPayload = decode(code) as SignedTransferPayloadType logger.debug('queryRedeemJwtLink... decodedPayload=', decodedPayload) - logger.debug('switch logger-context to received token-handshakeID:' + decodedPayload.handshakeID) + logger.debug( + 'switch logger-context to received token-handshakeID:' + decodedPayload.handshakeID, + ) logger.addContext('handshakeID', decodedPayload.handshakeID) - if(decodedPayload !== null && decodedPayload.tokentype === SignedTransferPayloadType.SIGNED_TRANSFER_TYPE) { + if ( + decodedPayload !== null && + decodedPayload.tokentype === SignedTransferPayloadType.SIGNED_TRANSFER_TYPE + ) { const signedTransferPayload = new SignedTransferPayloadType( decodedPayload.publicKey, decodedPayload.jwt, - decodedPayload.handshakeID) + decodedPayload.handshakeID, + ) logger.debug('queryRedeemJwtLink... signedTransferPayload=', signedTransferPayload) - const senderCom = await getCommunityByPublicKey(Buffer.from(signedTransferPayload.publicKey, 'hex')) + const senderCom = await getCommunityByPublicKey( + Buffer.from(signedTransferPayload.publicKey, 'hex'), + ) if (!senderCom) { const errmsg = `Sender community not found with publicKey=${signedTransferPayload.publicKey}` logger.error(errmsg) throw new Error(errmsg) } logger.debug('queryRedeemJwtLink... senderCom=', senderCom) - const jweVerifyResult = await verify(signedTransferPayload.handshakeID, signedTransferPayload.jwt, senderCom.publicJwtKey!) + const jweVerifyResult = await verify( + signedTransferPayload.handshakeID, + signedTransferPayload.jwt, + senderCom.publicJwtKey!, + ) logger.debug('queryRedeemJwtLink... jweVerifyResult=', jweVerifyResult) let verifiedRedeemJwtPayload: RedeemJwtPayloadType | null = null if (jweVerifyResult === null) { @@ -707,22 +750,34 @@ export class TransactionLinkResolver { encryptedTransferArgs.jwt = signedTransferPayload.jwt encryptedTransferArgs.handshakeID = signedTransferPayload.handshakeID - verifiedRedeemJwtPayload = await interpretEncryptedTransferArgs(encryptedTransferArgs) as RedeemJwtPayloadType - if(logger.isDebugEnabled()) { + verifiedRedeemJwtPayload = (await interpretEncryptedTransferArgs( + encryptedTransferArgs, + )) as RedeemJwtPayloadType + if (logger.isDebugEnabled()) { logger.debug(`queryRedeemJwtLink() ...`, verifiedRedeemJwtPayload) } if (!verifiedRedeemJwtPayload) { - const errmsg = `invalid authentication payload of requesting community with publicKey` + signedTransferPayload.publicKey + const errmsg = + `invalid authentication payload of requesting community with publicKey` + + signedTransferPayload.publicKey logger.error(errmsg) throw new Error(errmsg) } if (verifiedRedeemJwtPayload.tokentype !== RedeemJwtPayloadType.REDEEM_ACTIVATION_TYPE) { - const errmsg = `Wrong tokentype in redeem JWT: type=` + verifiedRedeemJwtPayload.tokentype + ' vs expected ' + RedeemJwtPayloadType.REDEEM_ACTIVATION_TYPE + const errmsg = + `Wrong tokentype in redeem JWT: type=` + + verifiedRedeemJwtPayload.tokentype + + ' vs expected ' + + RedeemJwtPayloadType.REDEEM_ACTIVATION_TYPE logger.error(errmsg) throw new Error(errmsg) } - if(senderCom?.communityUuid !== verifiedRedeemJwtPayload.sendercommunityuuid) { - const errmsg = `Mismatch of sender community UUID in redeem JWT against transfer JWT: uuid=` + senderCom.communityUuid + ' vs ' + verifiedRedeemJwtPayload.sendercommunityuuid + if (senderCom?.communityUuid !== verifiedRedeemJwtPayload.sendercommunityuuid) { + const errmsg = + `Mismatch of sender community UUID in redeem JWT against transfer JWT: uuid=` + + senderCom.communityUuid + + ' vs ' + + verifiedRedeemJwtPayload.sendercommunityuuid logger.error(errmsg) throw new Error(errmsg) } diff --git a/backend/src/graphql/resolver/TransactionResolver.test.ts b/backend/src/graphql/resolver/TransactionResolver.test.ts index 523620177..3f6bb5047 100644 --- a/backend/src/graphql/resolver/TransactionResolver.test.ts +++ b/backend/src/graphql/resolver/TransactionResolver.test.ts @@ -1,5 +1,9 @@ +import { cleanDB, testEnvironment } from '@test/helpers' import { ApolloServerTestClient } from 'apollo-server-testing' +import { getLogger } from 'config-schema/test/testSetup' +import { CONFIG as CORE_CONFIG } from 'core' import { + AppDatabase, Community as DbCommunity, Event as DbEvent, FederatedCommunity as DbFederatedCommunity, @@ -10,9 +14,7 @@ import { import { GraphQLError } from 'graphql' import { DataSource, In } from 'typeorm' import { v4 as uuidv4 } from 'uuid' - -import { cleanDB, testEnvironment } from '@test/helpers' - +import { CONFIG } from '@/config' // import { CONFIG } from '@/config' import { LOG4JS_BASE_CATEGORY_NAME } from '@/config/const' import { EventType } from '@/event/Events' @@ -32,10 +34,6 @@ import { bobBaumeister } from '@/seeds/users/bob-baumeister' import { garrickOllivander } from '@/seeds/users/garrick-ollivander' import { peterLustig } from '@/seeds/users/peter-lustig' import { stephenHawking } from '@/seeds/users/stephen-hawking' -import { getLogger } from 'config-schema/test/testSetup' -import { CONFIG } from '@/config' -import { CONFIG as CORE_CONFIG} from 'core' -import { AppDatabase } from 'database' jest.mock('@/password/EncryptorUtils') @@ -552,7 +550,7 @@ describe('send coins', () => { }) }) }) -/* + /* describe.skip('X-Com send coins via gradido ID', () => { beforeAll(async () => { CONFIG.FEDERATION_XCOM_SENDCOINS_ENABLED = true diff --git a/backend/src/graphql/resolver/TransactionResolver.ts b/backend/src/graphql/resolver/TransactionResolver.ts index b53ce4e61..8741eef06 100644 --- a/backend/src/graphql/resolver/TransactionResolver.ts +++ b/backend/src/graphql/resolver/TransactionResolver.ts @@ -1,3 +1,16 @@ +import { Paginated } from '@arg/Paginated' +import { TransactionSendArgs } from '@arg/TransactionSendArgs' +import { Order } from '@enum/Order' +import { Transaction } from '@model/Transaction' +import { TransactionList } from '@model/TransactionList' +import { User } from '@model/User' +import { + fullName, + processXComCompleteTransaction, + sendTransactionLinkRedeemedEmail, + sendTransactionReceivedEmail, + TransactionTypeId, +} from 'core' import { AppDatabase, countOpenPendingTransactions, @@ -10,45 +23,32 @@ import { import { Decimal } from 'decimal.js-light' import { Args, Authorized, Ctx, Mutation, Query, Resolver } from 'type-graphql' import { In, IsNull } from 'typeorm' - -import { Paginated } from '@arg/Paginated' -import { TransactionSendArgs } from '@arg/TransactionSendArgs' -import { Order } from '@enum/Order' -import { Transaction } from '@model/Transaction' -import { TransactionList } from '@model/TransactionList' -import { User } from '@model/User' -import { - fullName, - processXComCompleteTransaction, - sendTransactionLinkRedeemedEmail, - sendTransactionReceivedEmail, - TransactionTypeId -} from 'core' import { RIGHTS } from '@/auth/RIGHTS' import { CONFIG } from '@/config' -import { - EVENT_TRANSACTION_RECEIVE, EVENT_TRANSACTION_SEND } from '@/event/Events' -import { LogError } from '@/server/LogError' +import { EVENT_TRANSACTION_RECEIVE, EVENT_TRANSACTION_SEND } from '@/event/Events' import { Context, getUser } from '@/server/context' +import { LogError } from '@/server/LogError' import { communityUser } from '@/util/communityUser' import { calculateBalance } from '@/util/validate' import { virtualDecayTransaction, virtualLinkTransaction } from '@/util/virtualTransactions' + // import { TRANSACTIONS_LOCK } from 'database' -import { LOG4JS_BASE_CATEGORY_NAME } from '@/config/const' import { getLastTransaction } from 'database' +import { Redis } from 'ioredis' import { getLogger, Logger } from 'log4js' +import { Mutex } from 'redis-semaphore' +import { redeemDeferredTransferTransaction, transferTransaction } from '@/apis/dltConnector' +import { LOG4JS_BASE_CATEGORY_NAME } from '@/config/const' import { BalanceResolver } from './BalanceResolver' import { GdtResolver } from './GdtResolver' import { getCommunityName, isHomeCommunity } from './util/communities' import { getTransactionList } from './util/getTransactionList' import { transactionLinkSummary } from './util/transactionLinkSummary' -import { transferTransaction, redeemDeferredTransferTransaction } from '@/apis/dltConnector' -import { Redis } from 'ioredis' -import { Mutex } from 'redis-semaphore' const db = AppDatabase.getInstance() -const createLogger = () => getLogger(`${LOG4JS_BASE_CATEGORY_NAME}.graphql.resolver.TransactionResolver`) +const createLogger = () => + getLogger(`${LOG4JS_BASE_CATEGORY_NAME}.graphql.resolver.TransactionResolver`) export const executeTransaction = async ( amount: Decimal, @@ -66,15 +66,26 @@ export const executeTransaction = async ( const receivedCallDate = new Date() let dltTransactionPromise: Promise = Promise.resolve(null) if (!transactionLink) { - dltTransactionPromise = transferTransaction(sender, recipient, amount.toString(), memo, receivedCallDate) + dltTransactionPromise = transferTransaction( + sender, + recipient, + amount.toString(), + memo, + receivedCallDate, + ) } else { - dltTransactionPromise = redeemDeferredTransferTransaction(transactionLink, amount.toString(), receivedCallDate, recipient) + dltTransactionPromise = redeemDeferredTransferTransaction( + transactionLink, + amount.toString(), + receivedCallDate, + recipient, + ) } try { logger.info('executeTransaction', amount, memo, sender, recipient) - if (await countOpenPendingTransactions([sender.gradidoID, recipient.gradidoID]) > 0) { + if ((await countOpenPendingTransactions([sender.gradidoID, recipient.gradidoID])) > 0) { throw new LogError( `There exist still ongoing 'Pending-Transactions' for the involved users on sender-side!`, ) @@ -84,7 +95,7 @@ export const executeTransaction = async ( throw new LogError('Sender and Recipient are the same', sender.id) } - // validate amount + // validate amount const sendBalance = await calculateBalance( sender.id, amount.mul(-1), @@ -178,11 +189,13 @@ export const executeTransaction = async ( const startTime = new Date() const dltTransaction = await dltTransactionPromise const endTime = new Date() - logger.debug(`dlt-connector transaction finished in ${endTime.getTime() - startTime.getTime()} ms`) + logger.debug( + `dlt-connector transaction finished in ${endTime.getTime() - startTime.getTime()} ms`, + ) if (dltTransaction) { dltTransaction.transactionId = transactionSend.id await dltTransaction.save() - } + } } catch (e) { await queryRunner.rollbackTransaction() throw new LogError('Transaction was not successful', e) diff --git a/backend/src/graphql/resolver/UserResolver.test.ts b/backend/src/graphql/resolver/UserResolver.test.ts index b055c7975..792f8591b 100644 --- a/backend/src/graphql/resolver/UserResolver.test.ts +++ b/backend/src/graphql/resolver/UserResolver.test.ts @@ -1,5 +1,20 @@ +import { GmsPublishLocationType } from '@enum/GmsPublishLocationType' +import { OptInType } from '@enum/OptInType' +import { PasswordEncryptionType } from '@enum/PasswordEncryptionType' +import { RoleNames } from '@enum/RoleNames' +import { UserContactType } from '@enum/UserContactType' +import { ContributionLink } from '@model/ContributionLink' +import { Location } from '@model/Location' +import { cleanDB, headerPushMock, resetToken, testEnvironment } from '@test/helpers' import { UserInputError } from 'apollo-server-express' import { ApolloServerTestClient } from 'apollo-server-testing' +import { getLogger } from 'config-schema/test/testSetup' +import { + objectValuesToArray, + sendAccountActivationEmail, + sendAccountMultiRegistrationEmail, + sendResetPasswordEmail, +} from 'core' import { AppDatabase, Community as DbCommunity, @@ -12,23 +27,9 @@ import { import { GraphQLError } from 'graphql' import { DataSource } from 'typeorm' import { v4 as uuidv4, validate as validateUUID, version as versionUUID } from 'uuid' - -import { GmsPublishLocationType } from '@enum/GmsPublishLocationType' -import { OptInType } from '@enum/OptInType' -import { PasswordEncryptionType } from '@enum/PasswordEncryptionType' -import { RoleNames } from '@enum/RoleNames' -import { UserContactType } from '@enum/UserContactType' -import { ContributionLink } from '@model/ContributionLink' -import { Location } from '@model/Location' -import { cleanDB, headerPushMock, resetToken, testEnvironment } from '@test/helpers' - import { subscribe } from '@/apis/KlicktippController' import { CONFIG } from '@/config' -import { - sendAccountActivationEmail, - sendAccountMultiRegistrationEmail, - sendResetPasswordEmail, -} from 'core' +import { LOG4JS_BASE_CATEGORY_NAME } from '@/config/const' import { EventType } from '@/event/Events' import { PublishNameType } from '@/graphql/enum/PublishNameType' import { SecretKeyCryptographyCreateKey } from '@/password/EncryptorUtils' @@ -65,10 +66,6 @@ import { garrickOllivander } from '@/seeds/users/garrick-ollivander' import { peterLustig } from '@/seeds/users/peter-lustig' import { stephenHawking } from '@/seeds/users/stephen-hawking' import { printTimeDuration } from '@/util/time' -import { objectValuesToArray } from 'core' - -import { LOG4JS_BASE_CATEGORY_NAME } from '@/config/const' -import { getLogger } from 'config-schema/test/testSetup' import { Location2Point } from './util/Location2Point' jest.mock('@/apis/humhub/HumHubClient') @@ -158,7 +155,6 @@ describe('UserResolver', () => { expect(result).toEqual( expect.objectContaining({ data: { createUser: { id: expect.any(Number) } } }), ) - }) describe('valid input data', () => { @@ -1054,7 +1050,9 @@ describe('UserResolver', () => { describe('duration not expired', () => { it('throws an error', async () => { - await expect(mutate({ mutation: forgotPassword, variables: { email: 'bob@baumeister.de' } })).resolves.toEqual( + await expect( + mutate({ mutation: forgotPassword, variables: { email: 'bob@baumeister.de' } }), + ).resolves.toEqual( expect.objectContaining({ errors: [ new GraphQLError( @@ -1071,7 +1069,9 @@ describe('UserResolver', () => { describe('duration reset to 0', () => { it('returns true', async () => { CONFIG.EMAIL_CODE_REQUEST_TIME = 0 - await expect(mutate({ mutation: forgotPassword, variables: { email: 'bob@baumeister.de' } })).resolves.toEqual( + await expect( + mutate({ mutation: forgotPassword, variables: { email: 'bob@baumeister.de' } }), + ).resolves.toEqual( expect.objectContaining({ data: { forgotPassword: true, @@ -1112,7 +1112,9 @@ describe('UserResolver', () => { describe('request reset password again', () => { it('throws an error', async () => { CONFIG.EMAIL_CODE_REQUEST_TIME = emailCodeRequestTime - await expect(mutate({ mutation: forgotPassword, variables: { email: 'bob@baumeister.de' } })).resolves.toEqual( + await expect( + mutate({ mutation: forgotPassword, variables: { email: 'bob@baumeister.de' } }), + ).resolves.toEqual( expect.objectContaining({ errors: [new GraphQLError('Email already sent less than 10 minutes ago')], }), @@ -1144,7 +1146,10 @@ describe('UserResolver', () => { it('throws an error', async () => { jest.clearAllMocks() await expect( - query({ query: queryOptIn, variables: { email: 'bob@baumeister.de', optIn: 'not-valid' } }), + query({ + query: queryOptIn, + variables: { email: 'bob@baumeister.de', optIn: 'not-valid' }, + }), ).resolves.toEqual( expect.objectContaining({ errors: [ @@ -1165,7 +1170,10 @@ describe('UserResolver', () => { await expect( query({ query: queryOptIn, - variables: { email: 'bob@baumeister.de', optIn: emailContact.emailVerificationCode.toString() }, + variables: { + email: 'bob@baumeister.de', + optIn: emailContact.emailVerificationCode.toString(), + }, }), ).resolves.toEqual( expect.objectContaining({ diff --git a/backend/src/graphql/resolver/UserResolver.ts b/backend/src/graphql/resolver/UserResolver.ts index ea68934c6..061498207 100644 --- a/backend/src/graphql/resolver/UserResolver.ts +++ b/backend/src/graphql/resolver/UserResolver.ts @@ -1,32 +1,3 @@ -import { - AppDatabase, - ContributionLink as DbContributionLink, - TransactionLink as DbTransactionLink, - User as DbUser, - UserContact as DbUserContact, - ProjectBranding, - UserLoggingView, - getHomeCommunity, - findUserByIdentifier -} from 'database' -import { GraphQLResolveInfo } from 'graphql' -import { - Arg, - Args, - Authorized, - Ctx, - FieldResolver, - Info, - Int, - Mutation, - Query, - Resolver, - Root, -} from 'type-graphql' -import { IRestResponse } from 'typed-rest-client' -import { EntityManager, EntityNotFoundError, In, Point } from 'typeorm' -import { v4 as uuidv4 } from 'uuid' - import { UserArgs } from '@arg//UserArgs' import { CreateUserArgs } from '@arg/CreateUserArgs' import { Paginated } from '@arg/Paginated' @@ -46,15 +17,55 @@ import { User } from '@model/User' import { SearchUsersResult, UserAdmin } from '@model/UserAdmin' import { UserContact } from '@model/UserContact' import { UserLocationResult } from '@model/UserLocationResult' - -import { subscribe } from '@/apis/KlicktippController' +import { + delay, + sendAccountActivationEmail, + sendAccountMultiRegistrationEmail, + sendResetPasswordEmail, + validateAlias, +} from 'core' +import { + AppDatabase, + ContributionLink as DbContributionLink, + TransactionLink as DbTransactionLink, + User as DbUser, + UserContact as DbUserContact, + findUserByIdentifier, + getHomeCommunity, + ProjectBranding, + UserLoggingView, +} from 'database' +import { GraphQLResolveInfo } from 'graphql' +import { getLogger, Logger } from 'log4js' +import random from 'random-bigint' +import { updateAllDefinedAndChanged } from 'shared' +import { randombytes_random } from 'sodium-native' +import { + Arg, + Args, + Authorized, + Ctx, + FieldResolver, + Info, + Int, + Mutation, + Query, + Resolver, + Root, +} from 'type-graphql' +import { IRestResponse } from 'typed-rest-client' +import { EntityManager, EntityNotFoundError, In, Point } from 'typeorm' +import { v4 as uuidv4 } from 'uuid' +import { registerAddressTransaction } from '@/apis/dltConnector' import { HumHubClient } from '@/apis/humhub/HumHubClient' import { Account as HumhubAccount } from '@/apis/humhub/model/Account' import { GetUser } from '@/apis/humhub/model/GetUser' import { PostUser } from '@/apis/humhub/model/PostUser' +import { subscribe } from '@/apis/KlicktippController' import { encode } from '@/auth/JWT' import { RIGHTS } from '@/auth/RIGHTS' import { CONFIG } from '@/config' +import { LOG4JS_BASE_CATEGORY_NAME } from '@/config/const' import { PublishNameLogic } from '@/data/PublishName.logic' import { EVENT_ADMIN_USER_DELETE, @@ -74,36 +85,22 @@ import { } from '@/event/Events' import { isValidPassword } from '@/password/EncryptorUtils' import { encryptPassword, verifyPassword } from '@/password/PasswordEncryptor' -import { LogError } from '@/server/LogError' import { Context, getClientTimezoneOffset, getUser } from '@/server/context' +import { LogError } from '@/server/LogError' import { communityDbUser } from '@/util/communityUser' import { hasElopageBuys } from '@/util/hasElopageBuys' import { durationInMinutesFromDates, getTimeDurationObject, printTimeDuration } from '@/util/time' -import { - delay, - sendAccountActivationEmail, - sendAccountMultiRegistrationEmail, - sendResetPasswordEmail, -} from 'core' -import random from 'random-bigint' -import { randombytes_random } from 'sodium-native' - -import { LOG4JS_BASE_CATEGORY_NAME } from '@/config/const' -import { Logger, getLogger } from 'log4js' import { FULL_CREATION_AVAILABLE } from './const/const' -import { Location2Point, Point2Location } from './util/Location2Point' import { authenticateGmsUserPlayground } from './util/authenticateGmsUserPlayground' import { compareGmsRelevantUserSettings } from './util/compareGmsRelevantUserSettings' import { getUserCreations } from './util/creations' import { extractGraphQLFieldsForSelect } from './util/extractGraphQLFields' import { findUsers } from './util/findUsers' import { getKlicktippState } from './util/getKlicktippState' +import { Location2Point, Point2Location } from './util/Location2Point' import { deleteUserRole, setUserRole } from './util/modifyUserRole' import { sendUserToGms } from './util/sendUserToGms' import { syncHumhub } from './util/syncHumhub' -import { validateAlias } from 'core' -import { registerAddressTransaction } from '@/apis/dltConnector' -import { updateAllDefinedAndChanged } from 'shared' const LANGUAGES = ['de', 'en', 'es', 'fr', 'nl'] const DEFAULT_LANGUAGE = 'de' @@ -380,12 +377,14 @@ export class UserResolver { const homeCom = await getHomeCommunity() if (!homeCom) { logger.error('no home community found, please start the dht-node first') - throw new Error(`Error creating user, please write the support team: ${CONFIG.COMMUNITY_SUPPORT_MAIL}`) + throw new Error( + `Error creating user, please write the support team: ${CONFIG.COMMUNITY_SUPPORT_MAIL}`, + ) } if (homeCom.communityUuid) { dbUser.communityUuid = homeCom.communityUuid } - + dbUser.gradidoID = gradidoID dbUser.firstName = firstName dbUser.lastName = lastName @@ -396,9 +395,9 @@ export class UserResolver { dbUser.alias = alias } dbUser.publisherId = publisherId ?? 0 - dbUser.passwordEncryptionType = PasswordEncryptionType.NO_PASSWORD + dbUser.passwordEncryptionType = PasswordEncryptionType.NO_PASSWORD - if(logger.isDebugEnabled()) { + if (logger.isDebugEnabled()) { logger.debug('new dbUser', new UserLoggingView(dbUser)) } if (redeemCode) { @@ -510,7 +509,9 @@ export class UserResolver { const startTime = new Date() await dltTransactionPromise const endTime = new Date() - logger.info(`dlt-connector register address finished in ${endTime.getTime() - startTime.getTime()} ms`) + logger.info( + `dlt-connector register address finished in ${endTime.getTime() - startTime.getTime()} ms`, + ) return new User(dbUser) } @@ -736,13 +737,13 @@ export class UserResolver { user.humhubPublishName as PublishNameType, ) - let updated = updateAllDefinedAndChanged(user, { - firstName, - lastName, - hideAmountGDD, - hideAmountGDT, - humhubAllowed, - gmsAllowed, + let updated = updateAllDefinedAndChanged(user, { + firstName, + lastName, + hideAmountGDD, + hideAmountGDT, + humhubAllowed, + gmsAllowed, gmsPublishName: gmsPublishName?.valueOf(), humhubPublishName: humhubPublishName?.valueOf(), gmsPublishLocation: gmsPublishLocation?.valueOf(), @@ -813,7 +814,7 @@ export class UserResolver { if (!homeCom) { logger.error('no home community found, please start the dht-node first') throw new Error( - `Error updating user, please write the support team: ${CONFIG.COMMUNITY_SUPPORT_MAIL}` + `Error updating user, please write the support team: ${CONFIG.COMMUNITY_SUPPORT_MAIL}`, ) } if (homeCom.gmsApiKey !== null) { @@ -859,9 +860,11 @@ export class UserResolver { if (context.token) { const homeCom = await getHomeCommunity() if (!homeCom) { - logger.error("couldn't authenticate for gms, no home community found, please start the dht-node first") + logger.error( + "couldn't authenticate for gms, no home community found, please start the dht-node first", + ) throw new Error( - `Error authenticating for gms, please write the support team: ${CONFIG.COMMUNITY_SUPPORT_MAIL}` + `Error authenticating for gms, please write the support team: ${CONFIG.COMMUNITY_SUPPORT_MAIL}`, ) } if (!homeCom.gmsApiKey) { @@ -888,9 +891,11 @@ export class UserResolver { if (context.token) { const homeCom = await getHomeCommunity() if (!homeCom) { - logger.error("couldn't load home community location, no home community found, please start the dht-node first") + logger.error( + "couldn't load home community location, no home community found, please start the dht-node first", + ) throw new Error( - `Error loading user location, please write the support team: ${CONFIG.COMMUNITY_SUPPORT_MAIL}` + `Error loading user location, please write the support team: ${CONFIG.COMMUNITY_SUPPORT_MAIL}`, ) } result.communityLocation = Point2Location(homeCom.location as Point) @@ -976,7 +981,15 @@ export class UserResolver { @Ctx() context: Context, ): Promise { const clientTimezoneOffset = getClientTimezoneOffset(context) - const userFields = ['id', 'firstName', 'lastName', 'emailId', 'emailContact', 'deletedAt', 'createdAt'] + const userFields = [ + 'id', + 'firstName', + 'lastName', + 'emailId', + 'emailContact', + 'deletedAt', + 'createdAt', + ] const [users, count] = await findUsers( userFields, query, @@ -1141,7 +1154,7 @@ export class UserResolver { if (identifier.includes('/')) { const parts = identifier.split('/') communityIdentifier = parts[0] - identifier = parts[1] + identifier = parts[1] } const foundDbUser = await findUserByIdentifier(identifier, communityIdentifier) if (!foundDbUser) { diff --git a/backend/src/graphql/resolver/const/const.ts b/backend/src/graphql/resolver/const/const.ts index 8e0a0722e..e67aad1f8 100644 --- a/backend/src/graphql/resolver/const/const.ts +++ b/backend/src/graphql/resolver/const/const.ts @@ -12,4 +12,4 @@ export const MEMO_MAX_CHARS = 512 export const MEMO_MIN_CHARS = 5 export const DEFAULT_PAGINATION_PAGE_SIZE = 25 export const FRONTEND_CONTRIBUTIONS_ITEM_ANCHOR_PREFIX = 'contributionListItem-' -export const CODE_VALID_DAYS_DURATION = 14 \ No newline at end of file +export const CODE_VALID_DAYS_DURATION = 14 diff --git a/backend/src/graphql/resolver/semaphore.test.ts b/backend/src/graphql/resolver/semaphore.test.ts index f104507e7..c2bdee9f8 100644 --- a/backend/src/graphql/resolver/semaphore.test.ts +++ b/backend/src/graphql/resolver/semaphore.test.ts @@ -1,12 +1,14 @@ +import { cleanDB, contributionDateFormatter, testEnvironment } from '@test/helpers' import { ApolloServerTestClient } from 'apollo-server-testing' -import { Community as DbCommunity } from 'database' +import { CONFIG as CORE_CONFIG } from 'core' +import { AppDatabase, Community as DbCommunity } from 'database' import { Decimal } from 'decimal.js-light' import { GraphQLError } from 'graphql' +// import { TRANSACTIONS_LOCK } from 'database' +import { Mutex } from 'redis-semaphore' import { DataSource } from 'typeorm' import { v4 as uuidv4 } from 'uuid' - -import { cleanDB, contributionDateFormatter, testEnvironment } from '@test/helpers' - +import { CONFIG } from '@/config' import { creationFactory, nMonthsBefore } from '@/seeds/factory/creation' import { userFactory } from '@/seeds/factory/user' import { @@ -21,11 +23,6 @@ import { import { bibiBloxberg } from '@/seeds/users/bibi-bloxberg' import { bobBaumeister } from '@/seeds/users/bob-baumeister' import { peterLustig } from '@/seeds/users/peter-lustig' -import { CONFIG } from '@/config' -import { CONFIG as CORE_CONFIG } from 'core' -// import { TRANSACTIONS_LOCK } from 'database' -import { Mutex } from 'redis-semaphore' -import { AppDatabase } from 'database' jest.mock('@/password/EncryptorUtils') @@ -53,7 +50,7 @@ afterAll(async () => { await testEnv.db.getRedisClient().quit() }) -type WorkData = { start: number, end: number } +type WorkData = { start: number; end: number } async function fakeWork(workData: WorkData[], index: number) { // const releaseLock = await TRANSACTIONS_LOCK.acquire() // create a new mutex for every function call, like in production code @@ -71,16 +68,16 @@ async function fakeWork(workData: WorkData[], index: number) { describe('semaphore', () => { it("didn't should run in parallel", async () => { const workData: WorkData[] = [] - + const promises: Promise[] = [] - for(let i = 0; i < 20; i++) { + for (let i = 0; i < 20; i++) { promises.push(fakeWork(workData, i)) } await Promise.all(promises) workData.sort((a, b) => a.start - b.start) workData.forEach((work, index) => { expect(work.start).toBeLessThan(work.end) - if(index < workData.length - 1) { + if (index < workData.length - 1) { expect(work.start).toBeLessThan(workData[index + 1].start) expect(work.end).toBeLessThanOrEqual(workData[index + 1].start) } diff --git a/backend/src/graphql/resolver/util/Location2Point.ts b/backend/src/graphql/resolver/util/Location2Point.ts index 40fb0b19b..142a15e82 100644 --- a/backend/src/graphql/resolver/util/Location2Point.ts +++ b/backend/src/graphql/resolver/util/Location2Point.ts @@ -1,6 +1,5 @@ -import { Point } from 'typeorm' - import { Location } from '@model/Location' +import { Point } from 'typeorm' export function Location2Point(location: Location): Point { let pointStr: string diff --git a/backend/src/graphql/resolver/util/authenticateGmsUserPlayground.ts b/backend/src/graphql/resolver/util/authenticateGmsUserPlayground.ts index dfa775bde..0d946eb42 100644 --- a/backend/src/graphql/resolver/util/authenticateGmsUserPlayground.ts +++ b/backend/src/graphql/resolver/util/authenticateGmsUserPlayground.ts @@ -1,11 +1,10 @@ +import { ensureUrlEndsWithSlash } from 'core' import { User as DbUser } from 'database' - +import { getLogger } from 'log4js' import { verifyAuthToken } from '@/apis/gms/GmsClient' import { CONFIG } from '@/config' -import { GmsUserAuthenticationResult } from '@/graphql/model/GmsUserAuthenticationResult' import { LOG4JS_BASE_CATEGORY_NAME } from '@/config/const' -import { ensureUrlEndsWithSlash } from 'core' -import { getLogger } from 'log4js' +import { GmsUserAuthenticationResult } from '@/graphql/model/GmsUserAuthenticationResult' const logger = getLogger( `${LOG4JS_BASE_CATEGORY_NAME}.graphql.resolver.util.authenticateGmsUserPlayground`, diff --git a/backend/src/graphql/resolver/util/communities.ts b/backend/src/graphql/resolver/util/communities.ts index d1288a1ea..54546d1b4 100644 --- a/backend/src/graphql/resolver/util/communities.ts +++ b/backend/src/graphql/resolver/util/communities.ts @@ -1,3 +1,4 @@ +import { Paginated } from '@arg/Paginated' import { AppDatabase, Community as DbCommunity, @@ -5,8 +6,6 @@ import { } from 'database' import { FindOneOptions, IsNull, Not } from 'typeorm' -import { Paginated } from '@arg/Paginated' - import { LogError } from '@/server/LogError' function findWithCommunityIdentifier(communityIdentifier: string): FindOneOptions { diff --git a/backend/src/graphql/resolver/util/compareGmsRelevantUserSettings.ts b/backend/src/graphql/resolver/util/compareGmsRelevantUserSettings.ts index 1928374a4..3ce7b6fb6 100644 --- a/backend/src/graphql/resolver/util/compareGmsRelevantUserSettings.ts +++ b/backend/src/graphql/resolver/util/compareGmsRelevantUserSettings.ts @@ -1,13 +1,11 @@ import { User as DbUser, UserLoggingView } from 'database' +import { getLogger } from 'log4js' import { Point } from 'typeorm' - +import { LOG4JS_BASE_CATEGORY_NAME } from '@/config/const' import { UpdateUserInfosArgs } from '@/graphql/arg/UpdateUserInfosArgs' import { GmsPublishLocationType } from '@/graphql/enum/GmsPublishLocationType' import { PublishNameType } from '@/graphql/enum/PublishNameType' import { LogError } from '@/server/LogError' - -import { getLogger } from 'log4js' -import { LOG4JS_BASE_CATEGORY_NAME } from '@/config/const' import { Point2Location } from './Location2Point' const logger = getLogger( diff --git a/backend/src/graphql/resolver/util/contributions.ts b/backend/src/graphql/resolver/util/contributions.ts index adf9da800..7d3c78993 100644 --- a/backend/src/graphql/resolver/util/contributions.ts +++ b/backend/src/graphql/resolver/util/contributions.ts @@ -1,12 +1,12 @@ +import { Paginated } from '@arg/Paginated' +import { Contribution as DbContribution } from 'database' +import { FindManyOptions, In, MoreThan } from 'typeorm' import { CONFIG } from '@/config' import { Order } from '@/graphql/enum/Order' import { DEFAULT_PAGINATION_PAGE_SIZE, FRONTEND_CONTRIBUTIONS_ITEM_ANCHOR_PREFIX, } from '@/graphql/resolver/const/const' -import { Paginated } from '@arg/Paginated' -import { Contribution as DbContribution } from 'database' -import { FindManyOptions, In, MoreThan } from 'typeorm' // TODO: combine with Pagination class for all queries to use function buildPaginationOptions(paginated: Paginated): FindManyOptions { diff --git a/backend/src/graphql/resolver/util/creations.test.ts b/backend/src/graphql/resolver/util/creations.test.ts index e490ab20a..0f5cc9fcb 100644 --- a/backend/src/graphql/resolver/util/creations.test.ts +++ b/backend/src/graphql/resolver/util/creations.test.ts @@ -1,9 +1,7 @@ -import { ApolloServerTestClient } from 'apollo-server-testing' -import { Contribution, User } from 'database' -import { DataSource } from 'typeorm' -import { AppDatabase } from 'database' - import { cleanDB, contributionDateFormatter, testEnvironment } from '@test/helpers' +import { ApolloServerTestClient } from 'apollo-server-testing' +import { AppDatabase, Contribution, User } from 'database' +import { DataSource } from 'typeorm' import { CONFIG } from '@/config' import { userFactory } from '@/seeds/factory/user' diff --git a/backend/src/graphql/resolver/util/creations.ts b/backend/src/graphql/resolver/util/creations.ts index 486e7cc99..833baced2 100644 --- a/backend/src/graphql/resolver/util/creations.ts +++ b/backend/src/graphql/resolver/util/creations.ts @@ -1,14 +1,11 @@ -import { Contribution } from 'database' -import { Decimal } from 'decimal.js-light' - import { OpenCreation } from '@model/OpenCreation' - -import { FULL_CREATION_AVAILABLE, MAX_CREATION_AMOUNT } from '@/graphql/resolver/const/const' -import { LOG4JS_BASE_CATEGORY_NAME } from '@/config/const' -import { LogError } from '@/server/LogError' import { getFirstDayOfPreviousNMonth } from 'core' -import { AppDatabase } from 'database' +import { AppDatabase, Contribution } from 'database' +import { Decimal } from 'decimal.js-light' import { getLogger } from 'log4js' +import { LOG4JS_BASE_CATEGORY_NAME } from '@/config/const' +import { FULL_CREATION_AVAILABLE, MAX_CREATION_AMOUNT } from '@/graphql/resolver/const/const' +import { LogError } from '@/server/LogError' const db = AppDatabase.getInstance() const logger = getLogger(`${LOG4JS_BASE_CATEGORY_NAME}.graphql.resolver.util.creations`) diff --git a/backend/src/graphql/resolver/util/extractGraphQLFields.ts b/backend/src/graphql/resolver/util/extractGraphQLFields.ts index 2920f8180..e6cba554c 100644 --- a/backend/src/graphql/resolver/util/extractGraphQLFields.ts +++ b/backend/src/graphql/resolver/util/extractGraphQLFields.ts @@ -1,7 +1,7 @@ import { GraphQLResolveInfo } from 'graphql' import { - ResolveTree, parseResolveInfo, + ResolveTree, simplifyParsedResolveInfoFragmentWithType, } from 'graphql-parse-resolve-info' import { ObjectLiteral, SelectQueryBuilder } from 'typeorm' diff --git a/backend/src/graphql/resolver/util/findContributionMessages.ts b/backend/src/graphql/resolver/util/findContributionMessages.ts index bee06b4bf..e33a80e9a 100644 --- a/backend/src/graphql/resolver/util/findContributionMessages.ts +++ b/backend/src/graphql/resolver/util/findContributionMessages.ts @@ -1,8 +1,7 @@ -import { ContributionMessage as DbContributionMessage } from 'database' -import { In } from 'typeorm' - import { Paginated } from '@arg/Paginated' import { ContributionMessageType } from '@enum/ContributionMessageType' +import { ContributionMessage as DbContributionMessage } from 'database' +import { In } from 'typeorm' interface FindContributionMessagesOptions { contributionId: number diff --git a/backend/src/graphql/resolver/util/findContributions.ts b/backend/src/graphql/resolver/util/findContributions.ts index dd89b2199..5fad940f5 100644 --- a/backend/src/graphql/resolver/util/findContributions.ts +++ b/backend/src/graphql/resolver/util/findContributions.ts @@ -1,8 +1,7 @@ -import { AppDatabase, Contribution as DbContribution } from 'database' -import { Brackets, In, IsNull, LessThanOrEqual, Like, Not, SelectQueryBuilder } from 'typeorm' - import { Paginated } from '@arg/Paginated' import { SearchContributionsFilterArgs } from '@arg/SearchContributionsFilterArgs' +import { AppDatabase, Contribution as DbContribution } from 'database' +import { Brackets, In, IsNull, LessThanOrEqual, Like, Not, SelectQueryBuilder } from 'typeorm' import { LogError } from '@/server/LogError' diff --git a/backend/src/graphql/resolver/util/findUsers.ts b/backend/src/graphql/resolver/util/findUsers.ts index 83ed30484..f90c09165 100644 --- a/backend/src/graphql/resolver/util/findUsers.ts +++ b/backend/src/graphql/resolver/util/findUsers.ts @@ -1,8 +1,7 @@ -import { User as DbUser } from 'database' -import { IsNull, Like, Not } from 'typeorm' - import { SearchUsersFilters } from '@arg/SearchUsersFilters' import { Order } from '@enum/Order' +import { User as DbUser } from 'database' +import { IsNull, Like, Not } from 'typeorm' function likeQuery(searchCriteria: string) { return Like(`%${searchCriteria}%`) diff --git a/backend/src/graphql/resolver/util/getKlicktippState.ts b/backend/src/graphql/resolver/util/getKlicktippState.ts index 7cfdb6d51..224889a74 100644 --- a/backend/src/graphql/resolver/util/getKlicktippState.ts +++ b/backend/src/graphql/resolver/util/getKlicktippState.ts @@ -1,8 +1,7 @@ import { KlickTipp } from '@model/KlickTipp' - +import { getLogger } from 'log4js' import { getKlickTippUser } from '@/apis/KlicktippController' import { LOG4JS_BASE_CATEGORY_NAME } from '@/config/const' -import { getLogger } from 'log4js' const logger = getLogger(`${LOG4JS_BASE_CATEGORY_NAME}.graphql.resolver.util.getKlicktippState`) diff --git a/backend/src/graphql/resolver/util/getTransactionList.ts b/backend/src/graphql/resolver/util/getTransactionList.ts index 08ddbc71e..81af12598 100644 --- a/backend/src/graphql/resolver/util/getTransactionList.ts +++ b/backend/src/graphql/resolver/util/getTransactionList.ts @@ -1,6 +1,5 @@ -import { Transaction as DbTransaction } from 'database' - import { Order } from '@enum/Order' +import { Transaction as DbTransaction } from 'database' export const getTransactionList = async ( userId: number, diff --git a/backend/src/graphql/resolver/util/sendUserToGms.ts b/backend/src/graphql/resolver/util/sendUserToGms.ts index a0edfd35a..5772b4e23 100644 --- a/backend/src/graphql/resolver/util/sendUserToGms.ts +++ b/backend/src/graphql/resolver/util/sendUserToGms.ts @@ -1,11 +1,10 @@ import { Community as DbCommunity, User as DbUser } from 'database' - +import { getLogger } from 'log4js' import { createGmsUser, updateGmsUser } from '@/apis/gms/GmsClient' import { GmsUser } from '@/apis/gms/model/GmsUser' import { CONFIG } from '@/config' import { LOG4JS_BASE_CATEGORY_NAME } from '@/config/const' import { LogError } from '@/server/LogError' -import { getLogger } from 'log4js' const logger = getLogger(`${LOG4JS_BASE_CATEGORY_NAME}.graphql.resolver.util.sendUserToGms`) diff --git a/backend/src/graphql/resolver/util/syncHumhub.test.ts b/backend/src/graphql/resolver/util/syncHumhub.test.ts index 5d31f036b..db320b7cc 100644 --- a/backend/src/graphql/resolver/util/syncHumhub.test.ts +++ b/backend/src/graphql/resolver/util/syncHumhub.test.ts @@ -1,12 +1,10 @@ +import { getLogger } from 'config-schema/test/testSetup' import { User, UserContact } from 'database' - import { HumHubClient } from '@/apis/humhub/HumHubClient' import { GetUser } from '@/apis/humhub/model/GetUser' +import { LOG4JS_BASE_CATEGORY_NAME } from '@/config/const' import { UpdateUserInfosArgs } from '@/graphql/arg/UpdateUserInfosArgs' import { PublishNameType } from '@/graphql/enum/PublishNameType' - -import { LOG4JS_BASE_CATEGORY_NAME } from '@/config/const' -import { getLogger } from 'config-schema/test/testSetup' import { syncHumhub } from './syncHumhub' jest.mock('@/apis/humhub/HumHubClient') diff --git a/backend/src/graphql/resolver/util/syncHumhub.ts b/backend/src/graphql/resolver/util/syncHumhub.ts index 9cc53d1e9..7fbca18ce 100644 --- a/backend/src/graphql/resolver/util/syncHumhub.ts +++ b/backend/src/graphql/resolver/util/syncHumhub.ts @@ -1,16 +1,16 @@ import { User } from 'database' - +import { getLogger } from 'log4js' import { HumHubClient } from '@/apis/humhub/HumHubClient' import { GetUser } from '@/apis/humhub/model/GetUser' import { PostUser } from '@/apis/humhub/model/PostUser' import { ExecutedHumhubAction, syncUser } from '@/apis/humhub/syncUser' +import { LOG4JS_BASE_CATEGORY_NAME } from '@/config/const' import { PublishNameLogic } from '@/data/PublishName.logic' import { UpdateUserInfosArgs } from '@/graphql/arg/UpdateUserInfosArgs' import { PublishNameType } from '@/graphql/enum/PublishNameType' -import { LOG4JS_BASE_CATEGORY_NAME } from '@/config/const' -import { getLogger } from 'log4js' -const createLogger = () => getLogger(`${LOG4JS_BASE_CATEGORY_NAME}.graphql.resolver.util.syncHumhub`) +const createLogger = () => + getLogger(`${LOG4JS_BASE_CATEGORY_NAME}.graphql.resolver.util.syncHumhub`) /** * Syncs the user with humhub diff --git a/backend/src/graphql/resolver/util/transactionLinkList.ts b/backend/src/graphql/resolver/util/transactionLinkList.ts index f8bf33da0..7fcd2949c 100644 --- a/backend/src/graphql/resolver/util/transactionLinkList.ts +++ b/backend/src/graphql/resolver/util/transactionLinkList.ts @@ -1,10 +1,9 @@ -import { TransactionLink as DbTransactionLink, User as DbUser } from 'database' -import { IsNull, MoreThan } from 'typeorm' - import { Paginated } from '@arg/Paginated' import { TransactionLinkFilters } from '@arg/TransactionLinkFilters' import { Order } from '@enum/Order' import { TransactionLink, TransactionLinkResult } from '@model/TransactionLink' +import { TransactionLink as DbTransactionLink, User as DbUser } from 'database' +import { IsNull, MoreThan } from 'typeorm' import { User } from '@/graphql/model/User' diff --git a/backend/src/graphql/scalar/Location.ts b/backend/src/graphql/scalar/Location.ts index cd171c8e7..1ffaec47f 100644 --- a/backend/src/graphql/scalar/Location.ts +++ b/backend/src/graphql/scalar/Location.ts @@ -1,6 +1,5 @@ -import { GraphQLScalarType, Kind } from 'graphql' - import { Location } from '@model/Location' +import { GraphQLScalarType, Kind } from 'graphql' import { LogError } from '@/server/LogError' diff --git a/backend/src/graphql/schema.ts b/backend/src/graphql/schema.ts index 6a0e3db5e..bebc3dbda 100644 --- a/backend/src/graphql/schema.ts +++ b/backend/src/graphql/schema.ts @@ -1,9 +1,8 @@ +import { Location } from '@model/Location' import { Decimal } from 'decimal.js-light' import { GraphQLSchema } from 'graphql' import { buildSchema } from 'type-graphql' -import { Location } from '@model/Location' - import { isAuthorized } from './directive/isAuthorized' import { AiChatResolver } from './resolver/AiChatResolver' import { BalanceResolver } from './resolver/BalanceResolver' diff --git a/backend/src/graphql/union/QueryLinkResult.ts b/backend/src/graphql/union/QueryLinkResult.ts index e506efdc6..47fd7b622 100644 --- a/backend/src/graphql/union/QueryLinkResult.ts +++ b/backend/src/graphql/union/QueryLinkResult.ts @@ -1,8 +1,7 @@ -import { createUnionType } from 'type-graphql' - import { ContributionLink } from '@model/ContributionLink' import { RedeemJwtLink } from '@model/RedeemJwtLink' import { TransactionLink } from '@model/TransactionLink' +import { createUnionType } from 'type-graphql' export const QueryLinkResult = createUnionType({ name: 'QueryLinkResult', // the name of the GraphQL union diff --git a/backend/src/graphql/validator/ContributionStatusArray.ts b/backend/src/graphql/validator/ContributionStatusArray.ts index dd7c93277..63f372355 100644 --- a/backend/src/graphql/validator/ContributionStatusArray.ts +++ b/backend/src/graphql/validator/ContributionStatusArray.ts @@ -1,6 +1,5 @@ -import { ValidationOptions, registerDecorator } from 'class-validator' - import { ContributionStatus } from '@enum/ContributionStatus' +import { registerDecorator, ValidationOptions } from 'class-validator' export function isContributionStatusArray(validationOptions?: ValidationOptions) { return function (object: Object, propertyName: string) { diff --git a/backend/src/graphql/validator/DateString.ts b/backend/src/graphql/validator/DateString.ts index 3502b8c84..d0757e941 100644 --- a/backend/src/graphql/validator/DateString.ts +++ b/backend/src/graphql/validator/DateString.ts @@ -1,4 +1,4 @@ -import { ValidationArguments, ValidationOptions, registerDecorator } from 'class-validator' +import { registerDecorator, ValidationArguments, ValidationOptions } from 'class-validator' export function isValidDateString(validationOptions?: ValidationOptions) { return function (object: Object, propertyName: string) { diff --git a/backend/src/graphql/validator/Decimal.ts b/backend/src/graphql/validator/Decimal.ts index 0300c6d9c..74b1cb950 100644 --- a/backend/src/graphql/validator/Decimal.ts +++ b/backend/src/graphql/validator/Decimal.ts @@ -1,4 +1,4 @@ -import { ValidationArguments, ValidationOptions, registerDecorator } from 'class-validator' +import { registerDecorator, ValidationArguments, ValidationOptions } from 'class-validator' import { Decimal } from 'decimal.js-light' export function IsPositiveDecimal(validationOptions?: ValidationOptions) { diff --git a/backend/src/graphql/validator/HieroId.ts b/backend/src/graphql/validator/HieroId.ts index a7627ec78..62eb41f87 100644 --- a/backend/src/graphql/validator/HieroId.ts +++ b/backend/src/graphql/validator/HieroId.ts @@ -1,4 +1,4 @@ -import { ValidationArguments, ValidationOptions, registerDecorator } from 'class-validator' +import { registerDecorator, ValidationArguments, ValidationOptions } from 'class-validator' export function isValidHieroId(validationOptions?: ValidationOptions) { return function (object: Object, propertyName: string) { diff --git a/backend/src/graphql/validator/Location.ts b/backend/src/graphql/validator/Location.ts index 0bbf9fb92..edc5ede03 100644 --- a/backend/src/graphql/validator/Location.ts +++ b/backend/src/graphql/validator/Location.ts @@ -1,6 +1,5 @@ -import { ValidationArguments, ValidationOptions, registerDecorator } from 'class-validator' - import { Location } from '@model/Location' +import { registerDecorator, ValidationArguments, ValidationOptions } from 'class-validator' import { Location2Point } from '@/graphql/resolver/util/Location2Point' diff --git a/backend/src/index.ts b/backend/src/index.ts index db4bf76b5..104b1a698 100644 --- a/backend/src/index.ts +++ b/backend/src/index.ts @@ -2,9 +2,11 @@ import 'reflect-metadata' import 'source-map-support/register' import { getLogger } from 'log4js' import { CONFIG } from './config' -import { startValidateCommunities } from './federation/validateCommunities' +import { + startValidateCommunities, + writeJwtKeyPairInHomeCommunity, +} from './federation/validateCommunities' import { createServer } from './server/createServer' -import { writeJwtKeyPairInHomeCommunity } from './federation/validateCommunities' import { initLogging } from './server/logger' async function main() { diff --git a/backend/src/interactions/updateUnconfirmedContribution/AbstractUnconfirmedContribution.role.ts b/backend/src/interactions/updateUnconfirmedContribution/AbstractUnconfirmedContribution.role.ts index dd85e3fb6..95971833f 100644 --- a/backend/src/interactions/updateUnconfirmedContribution/AbstractUnconfirmedContribution.role.ts +++ b/backend/src/interactions/updateUnconfirmedContribution/AbstractUnconfirmedContribution.role.ts @@ -1,14 +1,13 @@ import { Contribution, User } from 'database' import { Decimal } from 'decimal.js-light' - +import { getLogger, Logger } from 'log4js' import { Role } from '@/auth/Role' +import { LOG4JS_BASE_CATEGORY_NAME } from '@/config/const' import { ContributionLogic } from '@/data/Contribution.logic' import { ContributionMessageBuilder } from '@/data/ContributionMessage.builder' import { ContributionStatus } from '@/graphql/enum/ContributionStatus' -import { LogError } from '@/server/LogError' import { Context, getClientTimezoneOffset } from '@/server/context' -import { Logger, getLogger } from 'log4js' -import { LOG4JS_BASE_CATEGORY_NAME } from '@/config/const' +import { LogError } from '@/server/LogError' export abstract class AbstractUnconfirmedContributionRole { private availableCreationSums?: Decimal[] @@ -24,7 +23,9 @@ export abstract class AbstractUnconfirmedContributionRole { if (self.confirmedAt || self.deniedAt) { throw new LogError("this contribution isn't unconfirmed!") } - this.logger = getLogger(`${LOG4JS_BASE_CATEGORY_NAME}.interactions.updateUnconfirmedContribution`) + this.logger = getLogger( + `${LOG4JS_BASE_CATEGORY_NAME}.interactions.updateUnconfirmedContribution`, + ) this.logger.addContext('contribution', this.self.id) } diff --git a/backend/src/interactions/updateUnconfirmedContribution/UpdateUnconfirmedContribution.context.ts b/backend/src/interactions/updateUnconfirmedContribution/UpdateUnconfirmedContribution.context.ts index 4e36b66c4..9765a0578 100644 --- a/backend/src/interactions/updateUnconfirmedContribution/UpdateUnconfirmedContribution.context.ts +++ b/backend/src/interactions/updateUnconfirmedContribution/UpdateUnconfirmedContribution.context.ts @@ -1,13 +1,12 @@ +import { AdminUpdateContributionArgs } from '@arg/AdminUpdateContributionArgs' +import { ContributionArgs } from '@arg/ContributionArgs' import { Contribution, ContributionMessage } from 'database' import { Decimal } from 'decimal.js-light' import { EntityManager, FindOneOptions, FindOptionsRelations } from 'typeorm' -import { AdminUpdateContributionArgs } from '@arg/AdminUpdateContributionArgs' -import { ContributionArgs } from '@arg/ContributionArgs' - import { ContributionMessageArgs } from '@/graphql/arg/ContributionMessageArgs' -import { LogError } from '@/server/LogError' import { Context } from '@/server/context' +import { LogError } from '@/server/LogError' import { AbstractUnconfirmedContributionRole } from './AbstractUnconfirmedContribution.role' import { UnconfirmedContributionAdminRole } from './UnconfirmedContributionAdmin.role' diff --git a/backend/src/openIDConnect/index.ts b/backend/src/openIDConnect/index.ts index f6ef5a88d..2084aceb1 100644 --- a/backend/src/openIDConnect/index.ts +++ b/backend/src/openIDConnect/index.ts @@ -1,9 +1,9 @@ +import { createHash } from 'crypto' +import { getHomeCommunity } from 'database' +import { exportJWK, importSPKI } from 'jose' +import { getLogger } from 'log4js' import { CONFIG } from '@/config' import { FRONTEND_LOGIN_ROUTE, GRADIDO_REALM, LOG4JS_BASE_CATEGORY_NAME } from '@/config/const' -import { getHomeCommunity } from 'database' -import { importSPKI, exportJWK } from 'jose' -import { createHash } from 'crypto' -import { getLogger } from 'log4js' const logger = getLogger(`${LOG4JS_BASE_CATEGORY_NAME}.openIDConnect`) const defaultErrorForCaller = 'Internal Server Error' @@ -12,7 +12,10 @@ export const openidConfiguration = async (req: any, res: any): Promise => res.setHeader('Content-Type', 'application/json') res.status(200).json({ issuer: new URL(FRONTEND_LOGIN_ROUTE, CONFIG.COMMUNITY_URL).toString(), - jwks_uri: new URL(`/realms/${GRADIDO_REALM}/protocol/openid-connect/certs`, CONFIG.COMMUNITY_URL).toString(), + jwks_uri: new URL( + `/realms/${GRADIDO_REALM}/protocol/openid-connect/certs`, + CONFIG.COMMUNITY_URL, + ).toString(), }) } @@ -33,9 +36,7 @@ export const jwks = async (req: any, res: any): Promise => { const jwkRsa = await exportJWK(rsaKey) // Optional: calculate Key ID (z.B. SHA-256 Fingerprint) - const kid = createHash('sha256') - .update(homeCommunity.publicJwtKey) - .digest('base64url') + const kid = createHash('sha256').update(homeCommunity.publicJwtKey).digest('base64url') const jwks = { keys: [ @@ -59,5 +60,5 @@ export const jwks = async (req: any, res: any): Promise => { } catch (err) { logger.error('Failed to convert publicJwtKey to JWK', err) res.status(500).json({ error: 'Failed to generate JWKS' }) - } -} \ No newline at end of file + } +} diff --git a/backend/src/password/EncryptorUtils.ts b/backend/src/password/EncryptorUtils.ts index 20ff202b7..30c536d16 100644 --- a/backend/src/password/EncryptorUtils.ts +++ b/backend/src/password/EncryptorUtils.ts @@ -1,16 +1,12 @@ import { cpus } from 'node:os' import path from 'node:path' - -import { User } from 'database' -import { Pool, pool } from 'workerpool' - import { PasswordEncryptionType } from '@enum/PasswordEncryptionType' - +import { User } from 'database' +import { crypto_shorthash_KEYBYTES } from 'sodium-native' +import { Pool, pool } from 'workerpool' import { CONFIG } from '@/config' import { LogError } from '@/server/LogError' -import { crypto_shorthash_KEYBYTES } from 'sodium-native' - import { SecretKeyCryptographyCreateKeyFunc } from './EncryptionWorker.js' const configLoginAppSecret = Buffer.from(CONFIG.LOGIN_APP_SECRET, 'hex') diff --git a/backend/src/password/PasswordEncryptor.ts b/backend/src/password/PasswordEncryptor.ts index 9efe4e60e..188cb4bd3 100644 --- a/backend/src/password/PasswordEncryptor.ts +++ b/backend/src/password/PasswordEncryptor.ts @@ -1,6 +1,6 @@ import { User } from 'database' -import { SecretKeyCryptographyCreateKey, getUserCryptographicSalt } from './EncryptorUtils' +import { getUserCryptographicSalt, SecretKeyCryptographyCreateKey } from './EncryptorUtils' export const encryptPassword = async (dbUser: User, password: string): Promise => { const salt = getUserCryptographicSalt(dbUser) diff --git a/backend/src/password/__mocks__/EncryptorUtils.ts b/backend/src/password/__mocks__/EncryptorUtils.ts index 1bac06239..4697688a2 100644 --- a/backend/src/password/__mocks__/EncryptorUtils.ts +++ b/backend/src/password/__mocks__/EncryptorUtils.ts @@ -1,18 +1,12 @@ -import { User } from 'database' - import { PasswordEncryptionType } from '@enum/PasswordEncryptionType' - -import { CONFIG } from '@/config' -import { LogError } from '@/server/LogError' +import { User } from 'database' import { getLogger } from 'log4js' - -import { LOG4JS_BASE_CATEGORY_NAME } from '@/config/const' import { crypto_box_SEEDBYTES, crypto_hash_sha512_BYTES, - crypto_hash_sha512_STATEBYTES, crypto_hash_sha512_final, crypto_hash_sha512_init, + crypto_hash_sha512_STATEBYTES, crypto_hash_sha512_update, crypto_pwhash, crypto_pwhash_MEMLIMIT_MIN, @@ -22,6 +16,10 @@ import { crypto_shorthash_BYTES, crypto_shorthash_KEYBYTES, } from 'sodium-native' +import { CONFIG } from '@/config' + +import { LOG4JS_BASE_CATEGORY_NAME } from '@/config/const' +import { LogError } from '@/server/LogError' const logger = getLogger(`${LOG4JS_BASE_CATEGORY_NAME}.password.EncryptorUtils`) diff --git a/backend/src/seeds/contributionLink/index.ts b/backend/src/seeds/contributionLink/index.ts index 5be34e171..d2591356c 100644 --- a/backend/src/seeds/contributionLink/index.ts +++ b/backend/src/seeds/contributionLink/index.ts @@ -17,4 +17,4 @@ export const contributionLinks: ContributionLinkInterface[] = [ validTo: new Date(2022, 8, 25), }, ] -*/ \ No newline at end of file +*/ diff --git a/backend/src/seeds/creation/CreationInterface.ts b/backend/src/seeds/creation/CreationInterface.ts index a05276a3d..ad466fba9 100644 --- a/backend/src/seeds/creation/CreationInterface.ts +++ b/backend/src/seeds/creation/CreationInterface.ts @@ -1,4 +1,4 @@ -export { CreationInterface } from 'database' +export { CreationInterface } from 'database' /* export interface CreationInterface { email: string @@ -9,4 +9,4 @@ export interface CreationInterface { // number of months to move the confirmed creation to the past moveCreationDate?: number } -*/ \ No newline at end of file +*/ diff --git a/backend/src/seeds/creation/index.ts b/backend/src/seeds/creation/index.ts index f95bc6fa4..5d87cadec 100644 --- a/backend/src/seeds/creation/index.ts +++ b/backend/src/seeds/creation/index.ts @@ -1,4 +1,3 @@ - export { creations } from 'database' /* @@ -157,4 +156,4 @@ export const creations: CreationInterface[] = [ confirmed: true, }, ] -*/ \ No newline at end of file +*/ diff --git a/backend/src/seeds/factory/contributionLink.ts b/backend/src/seeds/factory/contributionLink.ts index e29d7a635..97eeada1e 100644 --- a/backend/src/seeds/factory/contributionLink.ts +++ b/backend/src/seeds/factory/contributionLink.ts @@ -1,13 +1,12 @@ -import { - contributionLinkFactory as contributionLinkFactoryDb, - ContributionLinkInterface -} from 'database' - import { ContributionLink } from '@model/ContributionLink' +import { + ContributionLinkInterface, + contributionLinkFactory as contributionLinkFactoryDb, +} from 'database' export { ContributionLinkInterface } -export async function contributionLinkFactory ( +export async function contributionLinkFactory( _client: any, contributionLink: ContributionLinkInterface, ): Promise { diff --git a/backend/src/seeds/factory/creation.ts b/backend/src/seeds/factory/creation.ts index 2d57dc782..a8d7a351c 100644 --- a/backend/src/seeds/factory/creation.ts +++ b/backend/src/seeds/factory/creation.ts @@ -1,8 +1,8 @@ -import { +import { Contribution, - creationFactory as creationFactoryDb, - CreationInterface, - nMonthsBefore + CreationInterface, + creationFactory as creationFactoryDb, + nMonthsBefore, } from 'database' export { CreationInterface, nMonthsBefore } diff --git a/backend/src/seeds/factory/transactionLink.ts b/backend/src/seeds/factory/transactionLink.ts index 02911bd32..7ebd8a0cf 100644 --- a/backend/src/seeds/factory/transactionLink.ts +++ b/backend/src/seeds/factory/transactionLink.ts @@ -1,11 +1,11 @@ -import { - transactionLinkFactory as transactionLinkFactoryDb, - TransactionLinkInterface +import { + TransactionLinkInterface, + transactionLinkFactory as transactionLinkFactoryDb, } from 'database' export { TransactionLinkInterface } -export async function transactionLinkFactory ( +export async function transactionLinkFactory( _client: any, transactionLink: TransactionLinkInterface, ): Promise { diff --git a/backend/src/seeds/factory/user.ts b/backend/src/seeds/factory/user.ts index 5308518cb..ed2556e86 100644 --- a/backend/src/seeds/factory/user.ts +++ b/backend/src/seeds/factory/user.ts @@ -1,13 +1,14 @@ -import { User, userFactory as userFactoryDb, userFactoryBulk as userFactoryBulkDb, Community } from 'database' - +import { + Community, + User, + userFactoryBulk as userFactoryBulkDb, + userFactory as userFactoryDb, +} from 'database' +import { encryptPassword } from '@/password/PasswordEncryptor' import { writeHomeCommunityEntry } from '@/seeds/community' import { UserInterface } from '@/seeds/users/UserInterface' -import { encryptPassword } from '@/password/PasswordEncryptor' -export const userFactory = async ( - _client: any, - user: UserInterface, -): Promise => { +export const userFactory = async (_client: any, user: UserInterface): Promise => { const homeCom = await writeHomeCommunityEntry() const dbUser = await userFactoryDb(user, homeCom) @@ -32,4 +33,4 @@ export async function userFactoryBulk(users: UserInterface[], homeCommunity?: Co } } return dbUsers -} \ No newline at end of file +} diff --git a/backend/src/seeds/index.ts b/backend/src/seeds/index.ts index 4cc352ec7..59cd5e5d5 100644 --- a/backend/src/seeds/index.ts +++ b/backend/src/seeds/index.ts @@ -1,16 +1,14 @@ -import { - AppDatabase, - User, - UserInterface, - creationFactoryBulk, - transactionLinkFactoryBulk +import { + AppDatabase, + creationFactoryBulk, + transactionLinkFactoryBulk, + User, + UserInterface, } from 'database' import { internet, name } from 'faker' - -import { CONFIG } from '@/config' - -import { initLogging } from '@/server/logger' import { getLogger } from 'log4js' +import { CONFIG } from '@/config' +import { initLogging } from '@/server/logger' import { writeHomeCommunityEntry } from './community' import { contributionLinks } from './contributionLink/index' import { creations } from './creation/index' @@ -61,7 +59,7 @@ const run = async () => { logger.info('seeding all creations successful...') // create Transaction Links - const movedTransactionLinks = transactionLinks.map(transactionLink => { + const movedTransactionLinks = transactionLinks.map((transactionLink) => { let createdAt = new Date(new Date().getTime() + 1000) if (transactionLink.createdAt) { createdAt = transactionLink.createdAt @@ -84,7 +82,7 @@ const run = async () => { } async function clearDatabase(db: AppDatabase) { - await db.getDataSource().transaction(async trx => { + await db.getDataSource().transaction(async (trx) => { await trx.query(`SET FOREIGN_KEY_CHECKS = 0`) await trx.query(`TRUNCATE TABLE contributions`) await trx.query(`TRUNCATE TABLE contribution_links`) diff --git a/backend/src/seeds/transactionLink/TransactionLinkInterface.ts b/backend/src/seeds/transactionLink/TransactionLinkInterface.ts index 4b2e57fa3..be2fc2060 100644 --- a/backend/src/seeds/transactionLink/TransactionLinkInterface.ts +++ b/backend/src/seeds/transactionLink/TransactionLinkInterface.ts @@ -10,4 +10,4 @@ export interface TransactionLinkInterface { // redeemedBy?: number deletedAt?: boolean } -*/ \ No newline at end of file +*/ diff --git a/backend/src/seeds/transactionLink/index.ts b/backend/src/seeds/transactionLink/index.ts index c5d46b146..b0693c1e7 100644 --- a/backend/src/seeds/transactionLink/index.ts +++ b/backend/src/seeds/transactionLink/index.ts @@ -55,4 +55,4 @@ bei Gradidio sei dabei!`, deletedAt: true, }, ] -*/ \ No newline at end of file +*/ diff --git a/backend/src/seeds/users/UserInterface.ts b/backend/src/seeds/users/UserInterface.ts index abbecb254..7aaecc739 100644 --- a/backend/src/seeds/users/UserInterface.ts +++ b/backend/src/seeds/users/UserInterface.ts @@ -13,4 +13,4 @@ export interface UserInterface { publisherId?: number role?: string } -*/ \ No newline at end of file +*/ diff --git a/backend/src/seeds/users/bibi-bloxberg.ts b/backend/src/seeds/users/bibi-bloxberg.ts index dda6b1525..4a49584ae 100644 --- a/backend/src/seeds/users/bibi-bloxberg.ts +++ b/backend/src/seeds/users/bibi-bloxberg.ts @@ -14,4 +14,4 @@ export const bibiBloxberg: UserInterface = { // move user createdAt before transaction link createdAt: new Date(2021, 9, 17), } -*/ \ No newline at end of file +*/ diff --git a/backend/src/seeds/users/bob-baumeister.ts b/backend/src/seeds/users/bob-baumeister.ts index 61df64759..fab508e7a 100644 --- a/backend/src/seeds/users/bob-baumeister.ts +++ b/backend/src/seeds/users/bob-baumeister.ts @@ -11,4 +11,4 @@ export const bobBaumeister: UserInterface = { emailChecked: true, language: 'de', } -*/ \ No newline at end of file +*/ diff --git a/backend/src/seeds/users/garrick-ollivander.ts b/backend/src/seeds/users/garrick-ollivander.ts index 332f06157..b0fbee70a 100644 --- a/backend/src/seeds/users/garrick-ollivander.ts +++ b/backend/src/seeds/users/garrick-ollivander.ts @@ -1,4 +1,3 @@ - export { garrickOllivander } from 'database' /* import { UserInterface } from './UserInterface' @@ -13,4 +12,4 @@ export const garrickOllivander: UserInterface = { emailChecked: false, language: 'en', } -*/ \ No newline at end of file +*/ diff --git a/backend/src/seeds/users/peter-lustig.ts b/backend/src/seeds/users/peter-lustig.ts index 6c86ef800..59fdb279a 100644 --- a/backend/src/seeds/users/peter-lustig.ts +++ b/backend/src/seeds/users/peter-lustig.ts @@ -14,4 +14,4 @@ export const peterLustig: UserInterface = { language: 'de', role: RoleNames.ADMIN, } -*/ \ No newline at end of file +*/ diff --git a/backend/src/seeds/users/raeuber-hotzenplotz.ts b/backend/src/seeds/users/raeuber-hotzenplotz.ts index dc52f10b4..639f2da5e 100644 --- a/backend/src/seeds/users/raeuber-hotzenplotz.ts +++ b/backend/src/seeds/users/raeuber-hotzenplotz.ts @@ -1,4 +1,3 @@ - export { raeuberHotzenplotz } from 'database' /* import { UserInterface } from './UserInterface' @@ -11,4 +10,4 @@ export const raeuberHotzenplotz: UserInterface = { emailChecked: true, language: 'de', } -*/ \ No newline at end of file +*/ diff --git a/backend/src/seeds/users/stephen-hawking.ts b/backend/src/seeds/users/stephen-hawking.ts index a9a2085e6..f1feeb5ab 100644 --- a/backend/src/seeds/users/stephen-hawking.ts +++ b/backend/src/seeds/users/stephen-hawking.ts @@ -12,4 +12,4 @@ export const stephenHawking: UserInterface = { deletedAt: new Date('2018-03-14T09:17:52'), language: 'en', } -*/ \ No newline at end of file +*/ diff --git a/backend/src/server/LogError.test.ts b/backend/src/server/LogError.test.ts index 3b98aea89..b028b0e9a 100644 --- a/backend/src/server/LogError.test.ts +++ b/backend/src/server/LogError.test.ts @@ -1,5 +1,5 @@ -import { LOG4JS_BASE_CATEGORY_NAME } from '@/config/const' import { getLogger } from 'config-schema/test/testSetup' +import { LOG4JS_BASE_CATEGORY_NAME } from '@/config/const' import { LogError } from './LogError' diff --git a/backend/src/server/LogError.ts b/backend/src/server/LogError.ts index c455eaa15..deb638ace 100644 --- a/backend/src/server/LogError.ts +++ b/backend/src/server/LogError.ts @@ -1,5 +1,5 @@ -import { LOG4JS_BASE_CATEGORY_NAME } from '@/config/const' import { getLogger } from 'log4js' +import { LOG4JS_BASE_CATEGORY_NAME } from '@/config/const' const logger = getLogger(`${LOG4JS_BASE_CATEGORY_NAME}.server.LogError`) diff --git a/backend/src/server/createServer.ts b/backend/src/server/createServer.ts index 29d985b32..a464ddba7 100644 --- a/backend/src/server/createServer.ts +++ b/backend/src/server/createServer.ts @@ -1,20 +1,21 @@ -import { CONFIG } from '@/config' -import { CONFIG as CORE_CONFIG } from 'core' -import { schema } from '@/graphql/schema' -import { elopageWebhook } from '@/webhook/elopage' -import { gmsWebhook } from '@/webhook/gms' import { ApolloServer } from 'apollo-server-express' +import { CONFIG as CORE_CONFIG } from 'core' +import { AppDatabase } from 'database' import express, { Express, json, urlencoded } from 'express' import { slowDown } from 'express-slow-down' import helmet from 'helmet' -import { Logger, getLogger } from 'log4js' +import { getLogger, Logger } from 'log4js' import { DataSource } from 'typeorm' +import { CONFIG } from '@/config' import { GRADIDO_REALM, LOG4JS_BASE_CATEGORY_NAME } from '@/config/const' -import { AppDatabase } from 'database' +import { schema } from '@/graphql/schema' +import { jwks, openidConfiguration } from '@/openIDConnect' +import { elopageWebhook } from '@/webhook/elopage' +import { gmsWebhook } from '@/webhook/gms' import { context as serverContext } from './context' import { cors } from './cors' import { plugins } from './plugins' -import { jwks, openidConfiguration } from '@/openIDConnect' + // TODO implement // import queryComplexity, { simpleEstimator, fieldConfigEstimator } from "graphql-query-complexity"; diff --git a/backend/src/server/logger.ts b/backend/src/server/logger.ts index be9cababe..4abfc782e 100644 --- a/backend/src/server/logger.ts +++ b/backend/src/server/logger.ts @@ -1,5 +1,5 @@ -import { CONFIG } from '@/config' import { defaultCategory, initLogger } from 'config-schema' +import { CONFIG } from '@/config' export function initLogging() { // init logger diff --git a/backend/src/util/Monitor.ts b/backend/src/util/Monitor.ts index 31d6d8938..416e02119 100644 --- a/backend/src/util/Monitor.ts +++ b/backend/src/util/Monitor.ts @@ -1,8 +1,7 @@ +import { getLogger } from 'log4js' import { registerEnumType } from 'type-graphql' - import { LOG4JS_BASE_CATEGORY_NAME } from '@/config/const' import { LogError } from '@/server/LogError' -import { getLogger } from 'log4js' export enum MonitorNames { SEND_DLT_TRANSACTIONS = 1, diff --git a/backend/src/util/communityUser.ts b/backend/src/util/communityUser.ts index 9ae664667..2fae042d0 100644 --- a/backend/src/util/communityUser.ts +++ b/backend/src/util/communityUser.ts @@ -1,9 +1,9 @@ -import { UserContact, User as dbUser } from 'database' +import { User } from '@model/User' +import { User as dbUser, UserContact } from 'database' import { RemoveOptions, SaveOptions } from 'typeorm' -import { User } from '@model/User' - import { PasswordEncryptionType } from '@/graphql/enum/PasswordEncryptionType' + // import { UserContact as EmailContact } from 'database' const communityDbUser: dbUser = { diff --git a/backend/src/util/executeKlicktipp.ts b/backend/src/util/executeKlicktipp.ts index 47db2c735..b5b1e8b58 100644 --- a/backend/src/util/executeKlicktipp.ts +++ b/backend/src/util/executeKlicktipp.ts @@ -1,7 +1,6 @@ import { AppDatabase } from 'database' - -import { exportEventDataToKlickTipp } from './klicktipp' import { initLogging } from '@/server/logger' +import { exportEventDataToKlickTipp } from './klicktipp' async function executeKlicktipp(): Promise { initLogging() diff --git a/backend/src/util/klicktipp.test.ts b/backend/src/util/klicktipp.test.ts index 50fe4a1f7..0368a58b3 100644 --- a/backend/src/util/klicktipp.test.ts +++ b/backend/src/util/klicktipp.test.ts @@ -1,9 +1,7 @@ -import { ApolloServerTestClient } from 'apollo-server-testing' -import { Event as DbEvent } from 'database' -import { DataSource } from 'typeorm' -import { AppDatabase } from 'database' - import { cleanDB, resetToken, testEnvironment } from '@test/helpers' +import { ApolloServerTestClient } from 'apollo-server-testing' +import { AppDatabase, Event as DbEvent } from 'database' +import { DataSource } from 'typeorm' import { addFieldsToSubscriber } from '@/apis/KlicktippController' import { creations } from '@/seeds/creation' diff --git a/backend/src/util/validate.ts b/backend/src/util/validate.ts index 1190e32aa..26dfa18f5 100644 --- a/backend/src/util/validate.ts +++ b/backend/src/util/validate.ts @@ -1,13 +1,9 @@ -import { TransactionLink as dbTransactionLink } from 'database' -import { Decimal } from 'decimal.js-light' -import { validate, version } from 'uuid' - import { Decay } from 'core' - -import { getLastTransaction } from 'database' -import { transactionLinkSummary } from '@/graphql/resolver/util/transactionLinkSummary' - +import { TransactionLink as dbTransactionLink, getLastTransaction } from 'database' +import { Decimal } from 'decimal.js-light' import { calculateDecay } from 'shared' +import { validate, version } from 'uuid' +import { transactionLinkSummary } from '@/graphql/resolver/util/transactionLinkSummary' function isStringBoolean(value: string): boolean { const lowerValue = value.toLowerCase() @@ -36,7 +32,9 @@ async function calculateBalance( return null } - const decay = new Decay(calculateDecay(lastTransaction.balance, lastTransaction.balanceDate, time)) + const decay = new Decay( + calculateDecay(lastTransaction.balance, lastTransaction.balanceDate, time), + ) const balance = decay.balance.add(amount.toString()) const { sumHoldAvailableAmount } = await transactionLinkSummary(userId, time) diff --git a/backend/src/util/virtualTransactions.ts b/backend/src/util/virtualTransactions.ts index a3bbbe042..65bcbb2f3 100644 --- a/backend/src/util/virtualTransactions.ts +++ b/backend/src/util/virtualTransactions.ts @@ -1,12 +1,10 @@ -import { Transaction as dbTransaction } from 'database' -import { Decimal } from 'decimal.js-light' -import { RemoveOptions, SaveOptions } from 'typeorm' - -import { TransactionTypeId } from 'core' import { Transaction } from '@model/Transaction' import { User } from '@model/User' - +import { TransactionTypeId } from 'core' +import { Transaction as dbTransaction } from 'database' +import { Decimal } from 'decimal.js-light' import { calculateDecay } from 'shared' +import { RemoveOptions, SaveOptions } from 'typeorm' const defaultModelFunctions = { hasId: function (): boolean { diff --git a/backend/src/webhook/elopage.ts b/backend/src/webhook/elopage.ts index 64113062f..637f53b6e 100644 --- a/backend/src/webhook/elopage.ts +++ b/backend/src/webhook/elopage.ts @@ -25,11 +25,10 @@ I assume that the webhook arrives via POST and transmits a string as shown above */ -import { LoginElopageBuys, UserContact as dbUserContact } from 'database' - +import { UserContact as dbUserContact, LoginElopageBuys } from 'database' +import { getLogger } from 'log4js' import { LOG4JS_BASE_CATEGORY_NAME } from '@/config/const' import { UserResolver } from '@/graphql/resolver/UserResolver' -import { getLogger } from 'log4js' const logger = getLogger(`${LOG4JS_BASE_CATEGORY_NAME}.webhook.elopage`) diff --git a/backend/src/webhook/gms.ts b/backend/src/webhook/gms.ts index 038804366..e8123143c 100644 --- a/backend/src/webhook/gms.ts +++ b/backend/src/webhook/gms.ts @@ -1,7 +1,6 @@ import { User as DbUser } from 'database' - -import { decode } from '@/auth/JWT' import { getLogger } from 'log4js' +import { decode } from '@/auth/JWT' import { LOG4JS_BASE_CATEGORY_NAME } from '@/config/const' const logger = getLogger(`${LOG4JS_BASE_CATEGORY_NAME}.webhook.gms`) diff --git a/biome.json b/biome.json index 13ccfdbe9..4f60baebc 100644 --- a/biome.json +++ b/biome.json @@ -5,11 +5,11 @@ "ignoreUnknown": false, "includes": [ "**/package.json", - "src/**/*.js", - "src/**/*.ts", - "entity/**/*.ts", - "logging/**/*.ts", - "migrations/**/*.ts", + "**/src/**/*.js", + "**/src/**/*.ts", + "**/entity/**/*.ts", + "**/logging/**/*.ts", + "**/migrations/**/*.ts", "!**/build", "!**/node_modules", "!**/coverage" diff --git a/config-schema/src/index.ts b/config-schema/src/index.ts index 9c7c32653..ceff49b0b 100644 --- a/config-schema/src/index.ts +++ b/config-schema/src/index.ts @@ -1,7 +1,8 @@ import 'source-map-support/register' + export * from './commonSchema' -export { DatabaseConfigSchema } from './DatabaseConfigSchema' -export { validate } from './validate' -export type { LogLevel, Category } from './log4js-config' -export { createLog4jsConfig, initLogger, defaultCategory } from './log4js-config' export { DECAY_START_TIME } from './const' +export { DatabaseConfigSchema } from './DatabaseConfigSchema' +export type { Category, LogLevel } from './log4js-config' +export { createLog4jsConfig, defaultCategory, initLogger } from './log4js-config' +export { validate } from './validate' diff --git a/config-schema/src/log4js-config/coloredContext.ts b/config-schema/src/log4js-config/coloredContext.ts index 1f238fcdb..f7dc74dd5 100644 --- a/config-schema/src/log4js-config/coloredContext.ts +++ b/config-schema/src/log4js-config/coloredContext.ts @@ -1,7 +1,7 @@ +import { inspect } from 'node:util' import { Level, LoggingEvent } from 'log4js' import colors from 'yoctocolors-cjs' import { ColoredContextLayoutConfig, LogLevel } from './types' -import { inspect } from 'node:util' function colorize(str: string, level: Level): string { switch (level.colour) { @@ -34,7 +34,7 @@ function composeDataString(data: (string | Object)[]): string { .map((d) => { // if it is a object and his toString function return only garbage if (d && typeof d === 'object' && d.toString() === '[object Object]') { - return inspect(d, ) + return inspect(d) } if (d) { return d.toString() diff --git a/config-schema/src/log4js-config/index.ts b/config-schema/src/log4js-config/index.ts index 94721d384..85f362775 100644 --- a/config-schema/src/log4js-config/index.ts +++ b/config-schema/src/log4js-config/index.ts @@ -1,5 +1,5 @@ import { readFileSync, writeFileSync } from 'node:fs' -import { Configuration, LoggingEvent, addLayout, configure } from 'log4js' +import { addLayout, Configuration, configure, LoggingEvent } from 'log4js' import { createAppenderConfig } from './appenders' import { createColoredContextLayout } from './coloredContext' import type { Category, CustomFileAppender, LogLevel } from './types' diff --git a/config-schema/src/log4js-config/types/index.ts b/config-schema/src/log4js-config/types/index.ts index 67279ff57..f2387e1ca 100644 --- a/config-schema/src/log4js-config/types/index.ts +++ b/config-schema/src/log4js-config/types/index.ts @@ -1,4 +1,4 @@ export * from './Category' +export * from './ColoredContextLayoutConfig' export * from './CustomFileAppender' export * from './LogLevel' -export * from './ColoredContextLayoutConfig' diff --git a/config-schema/src/validate.ts b/config-schema/src/validate.ts index 17ccea483..baa7cf132 100644 --- a/config-schema/src/validate.ts +++ b/config-schema/src/validate.ts @@ -21,15 +21,15 @@ export function validate(schema: ObjectSchema, data: any) { const description = schemaJson.keys[key] ? schema.describe().keys[key].flags.description : 'No description available' - if (data[key] === undefined) { - throw new Error( - `Environment Variable '${key}' is missing. ${description}, details: ${details}`, - ) - } else { - throw new Error( - `Error on Environment Variable ${key} with value = ${value}: ${err.message}. ${description}`, - ) - } + if (data[key] === undefined) { + throw new Error( + `Environment Variable '${key}' is missing. ${description}, details: ${details}`, + ) + } else { + throw new Error( + `Error on Environment Variable ${key} with value = ${value}: ${err.message}. ${description}`, + ) + } } catch (e) { // biome-ignore lint/suspicious/noConsole: schema validation may be run before logger is initialized console.error('Error getting description for key ' + key + ': ' + e) diff --git a/core/src/config/index.ts b/core/src/config/index.ts index be3179236..8a7150016 100644 --- a/core/src/config/index.ts +++ b/core/src/config/index.ts @@ -7,7 +7,6 @@ import { schema } from './schema' dotenv.config() - const federation = { FEDERATION_BACKEND_SEND_ON_API: process.env.FEDERATION_BACKEND_SEND_ON_API ?? '1_0', FEDERATION_XCOM_SENDCOINS_ENABLED: @@ -29,7 +28,6 @@ const community = { COMMUNITY_URL, } - const email = { EMAIL: process.env.EMAIL === 'true', EMAIL_LINK_FORGOTPASSWORD: @@ -44,7 +42,6 @@ const email = { EMAIL_SMTP_PORT: Number(process.env.EMAIL_SMTP_PORT) || 1025, } - export const CONFIG = { ...federation, ...community, diff --git a/core/src/config/schema.ts b/core/src/config/schema.ts index 6f8e2d6a8..ba3c31941 100644 --- a/core/src/config/schema.ts +++ b/core/src/config/schema.ts @@ -1,12 +1,11 @@ - -import Joi from 'joi' import { COMMUNITY_SUPPORT_MAIL, COMMUNITY_URL, NODE_ENV } from 'config-schema' +import Joi from 'joi' export const schema = Joi.object({ COMMUNITY_SUPPORT_MAIL, COMMUNITY_URL, NODE_ENV, - + EMAIL: Joi.boolean() .default(false) .description('Enable or disable email functionality') diff --git a/core/src/emails/index.ts b/core/src/emails/index.ts index e7b39331a..ecf610bc5 100644 --- a/core/src/emails/index.ts +++ b/core/src/emails/index.ts @@ -1 +1 @@ -export * from './sendEmailVariants' \ No newline at end of file +export * from './sendEmailVariants' diff --git a/core/src/emails/sendEmailTranslated.test.ts b/core/src/emails/sendEmailTranslated.test.ts index 8d77637ff..3c196d760 100644 --- a/core/src/emails/sendEmailTranslated.test.ts +++ b/core/src/emails/sendEmailTranslated.test.ts @@ -1,10 +1,10 @@ +import { afterAll, beforeEach, describe, expect, it, jest, mock } from 'bun:test' import { createTransport } from 'nodemailer' -import { CONFIG } from '../config' -import { i18n } from '../locales/localization' import { getLogger } from '../../../config-schema/test/testSetup.bun' +import { CONFIG } from '../config' import { LOG4JS_BASE_CATEGORY_NAME } from '../config/const' +import { i18n } from '../locales/localization' import { sendEmailTranslated } from './sendEmailTranslated' -import { mock, jest, describe, it, expect, beforeEach, afterAll } from 'bun:test' const logger = getLogger(`${LOG4JS_BASE_CATEGORY_NAME}.emails.sendEmailTranslated`) @@ -109,7 +109,7 @@ describe('sendEmailTranslated', () => { }) }) }) - + it('calls "i18n.setLocale" with "en"', async () => { expect(spySetLocale).toBeCalledWith('en') }) diff --git a/core/src/emails/sendEmailTranslated.ts b/core/src/emails/sendEmailTranslated.ts index c73650fb5..104bbe85f 100644 --- a/core/src/emails/sendEmailTranslated.ts +++ b/core/src/emails/sendEmailTranslated.ts @@ -1,16 +1,16 @@ -import path from 'path' import Email from 'email-templates' -import { i18n } from '../locales/localization' +import { getLogger } from 'log4js' import { createTransport } from 'nodemailer' +import path from 'path' import { CONFIG } from '../config' import { LOG4JS_BASE_CATEGORY_NAME } from '../config/const' -import { getLogger } from 'log4js' -import gradidoHeader from './templates/includes/gradido-header.jpeg' +import { i18n } from '../locales/localization' +import chatboxIcon from './templates/includes/chatbox-icon.png' import facebookIcon from './templates/includes/facebook-icon.png' +import gradidoHeader from './templates/includes/gradido-header.jpeg' import telegramIcon from './templates/includes/telegram-icon.png' import twitterIcon from './templates/includes/twitter-icon.png' import youtubeIcon from './templates/includes/youtube-icon.png' -import chatboxIcon from './templates/includes/chatbox-icon.png' const logger = getLogger(`${LOG4JS_BASE_CATEGORY_NAME}.emails.sendEmailTranslated`) @@ -48,7 +48,7 @@ export const sendEmailTranslated = async ({ ) receiver.to = CONFIG.EMAIL_TEST_RECEIVER } - + const transport = createTransport({ host: CONFIG.EMAIL_SMTP_HOST, port: CONFIG.EMAIL_SMTP_PORT, @@ -102,7 +102,7 @@ export const sendEmailTranslated = async ({ cid: 'youtubeicon', }, { - // filename: 'chatbox-icon.png', + // filename: 'chatbox-icon.png', content: chatboxIcon, cid: 'chatboxicon', }, diff --git a/core/src/emails/sendEmailVariants.test.ts b/core/src/emails/sendEmailVariants.test.ts index da07c83f4..1fbbbce8f 100644 --- a/core/src/emails/sendEmailVariants.test.ts +++ b/core/src/emails/sendEmailVariants.test.ts @@ -1,6 +1,6 @@ +import { afterEach, beforeAll, describe, expect, it, jest, mock } from 'bun:test' import { Decimal } from 'decimal.js-light' import { CONFIG } from '../config' -import { mock, jest, describe, it, expect, beforeAll, afterEach } from 'bun:test' import * as sendEmailTranslatedApi from './sendEmailTranslated' import { @@ -64,7 +64,7 @@ describe('sendEmailVariants', () => { contributionMemo: 'My contribution.', contributionFrontendLink, message: 'My message.', - }) + }) }) describe('calls "sendEmailTranslated"', () => { @@ -144,7 +144,6 @@ describe('sendEmailVariants', () => { }) }) - describe('result', () => { it('is the expected object', () => { // bun testrunner bug, toMatchObject mess with 'result' @@ -167,8 +166,6 @@ describe('sendEmailVariants', () => { }) }) - - describe('sendAccountMultiRegistrationEmail', () => { beforeAll(async () => { result = await sendAccountMultiRegistrationEmail({ diff --git a/core/src/emails/sendEmailVariants.ts b/core/src/emails/sendEmailVariants.ts index 8a4b6f9af..f50f88181 100644 --- a/core/src/emails/sendEmailVariants.ts +++ b/core/src/emails/sendEmailVariants.ts @@ -28,9 +28,10 @@ function getEmailCommonLocales(): Record { } export const sendAddedContributionMessageEmail = ( - data: EmailCommonData & ContributionEmailCommonData & { - message: string - }, + data: EmailCommonData & + ContributionEmailCommonData & { + message: string + }, ): Promise | boolean | null | Error> => { return sendEmailTranslated({ receiver: { @@ -44,11 +45,13 @@ export const sendAddedContributionMessageEmail = ( }) } -export const sendAccountActivationEmail = (data: EmailCommonData & { - activationLink: string - timeDurationObject: Record - logoUrl?: string | null -}): Promise | boolean | null | Error> => { +export const sendAccountActivationEmail = ( + data: EmailCommonData & { + activationLink: string + timeDurationObject: Record + logoUrl?: string | null + }, +): Promise | boolean | null | Error> => { return sendEmailTranslated({ receiver: { to: `${data.firstName} ${data.lastName} <${data.email}>` }, template: 'accountActivation', @@ -59,7 +62,9 @@ export const sendAccountActivationEmail = (data: EmailCommonData & { }) } -export const sendAccountMultiRegistrationEmail = (data: EmailCommonData): Promise | boolean | null | Error> => { +export const sendAccountMultiRegistrationEmail = ( + data: EmailCommonData, +): Promise | boolean | null | Error> => { return sendEmailTranslated({ receiver: { to: `${data.firstName} ${data.lastName} <${data.email}>` }, template: 'accountMultiRegistration', @@ -71,9 +76,10 @@ export const sendAccountMultiRegistrationEmail = (data: EmailCommonData): Promis } export const sendContributionConfirmedEmail = ( - data: EmailCommonData & ContributionEmailCommonData & { - contributionAmount: Decimal - }, + data: EmailCommonData & + ContributionEmailCommonData & { + contributionAmount: Decimal + }, ): Promise | boolean | null | Error> => { return sendEmailTranslated({ receiver: { to: `${data.firstName} ${data.lastName} <${data.email}>` }, @@ -87,9 +93,10 @@ export const sendContributionConfirmedEmail = ( } export const sendContributionChangedByModeratorEmail = ( - data: EmailCommonData & ContributionEmailCommonData & { - contributionMemoUpdated: string - }, + data: EmailCommonData & + ContributionEmailCommonData & { + contributionMemoUpdated: string + }, ): Promise | boolean | null | Error> => { return sendEmailTranslated({ receiver: { to: `${data.firstName} ${data.lastName} <${data.email}>` }, @@ -128,10 +135,12 @@ export const sendContributionDeniedEmail = ( }) } -export const sendResetPasswordEmail = (data: EmailCommonData & { - resetLink: string - timeDurationObject: Record -}): Promise | boolean | null | Error> => { +export const sendResetPasswordEmail = ( + data: EmailCommonData & { + resetLink: string + timeDurationObject: Record + }, +): Promise | boolean | null | Error> => { return sendEmailTranslated({ receiver: { to: `${data.firstName} ${data.lastName} <${data.email}>` }, template: 'resetPassword', @@ -142,13 +151,15 @@ export const sendResetPasswordEmail = (data: EmailCommonData & { }) } -export const sendTransactionLinkRedeemedEmail = (data: EmailCommonData & { - senderFirstName: string - senderLastName: string - senderEmail: string - transactionMemo: string - transactionAmount: Decimal -}): Promise | boolean | null | Error> => { +export const sendTransactionLinkRedeemedEmail = ( + data: EmailCommonData & { + senderFirstName: string + senderLastName: string + senderEmail: string + transactionMemo: string + transactionAmount: Decimal + }, +): Promise | boolean | null | Error> => { return sendEmailTranslated({ receiver: { to: `${data.firstName} ${data.lastName} <${data.email}>` }, template: 'transactionLinkRedeemed', @@ -160,13 +171,15 @@ export const sendTransactionLinkRedeemedEmail = (data: EmailCommonData & { }) } -export const sendTransactionReceivedEmail = (data: EmailCommonData & { - senderFirstName: string - senderLastName: string - senderEmail: string - memo: string - transactionAmount: Decimal -}): Promise | boolean | null | Error> => { +export const sendTransactionReceivedEmail = ( + data: EmailCommonData & { + senderFirstName: string + senderLastName: string + senderEmail: string + memo: string + transactionAmount: Decimal + }, +): Promise | boolean | null | Error> => { return sendEmailTranslated({ receiver: { to: `${data.firstName} ${data.lastName} <${data.email}>` }, template: 'transactionReceived', diff --git a/core/src/federation/client/1_0/SendCoinsClient.ts b/core/src/federation/client/1_0/SendCoinsClient.ts index a872c438d..785eb5c10 100644 --- a/core/src/federation/client/1_0/SendCoinsClient.ts +++ b/core/src/federation/client/1_0/SendCoinsClient.ts @@ -1,15 +1,13 @@ import { FederatedCommunity as DbFederatedCommunity } from 'database' import { GraphQLClient } from 'graphql-request' - -import { ensureUrlEndsWithSlash } from '../../../util/utilities' import { getLogger } from 'log4js' - import { LOG4JS_BASE_CATEGORY_NAME } from '../../../config/const' +import { EncryptedTransferArgs } from '../../../graphql/model/EncryptedTransferArgs' +import { ensureUrlEndsWithSlash } from '../../../util/utilities' import { revertSendCoins as revertSendCoinsQuery } from './query/revertSendCoins' import { revertSettledSendCoins as revertSettledSendCoinsQuery } from './query/revertSettledSendCoins' import { settleSendCoins as settleSendCoinsQuery } from './query/settleSendCoins' import { voteForSendCoins as voteForSendCoinsQuery } from './query/voteForSendCoins' -import { EncryptedTransferArgs } from '../../../graphql/model/EncryptedTransferArgs' const logger = getLogger(`${LOG4JS_BASE_CATEGORY_NAME}.federation.client.1_0.SendCoinsClient`) @@ -33,7 +31,10 @@ export class SendCoinsClient { async voteForSendCoins(args: EncryptedTransferArgs): Promise { logger.debug('voteForSendCoins against endpoint=', this.endpoint) try { - const { data } = await this.client.rawRequest<{ voteForSendCoins: string }>(voteForSendCoinsQuery, { args }) + const { data } = await this.client.rawRequest<{ voteForSendCoins: string }>( + voteForSendCoinsQuery, + { args }, + ) const responseJwt = data?.voteForSendCoins if (responseJwt) { logger.debug('received response jwt', responseJwt) diff --git a/core/src/federation/client/1_0/query/voteForSendCoins.ts b/core/src/federation/client/1_0/query/voteForSendCoins.ts index 9b987657c..adf8dd1d0 100644 --- a/core/src/federation/client/1_0/query/voteForSendCoins.ts +++ b/core/src/federation/client/1_0/query/voteForSendCoins.ts @@ -5,4 +5,3 @@ export const voteForSendCoins = gql` voteForSendCoins(data: $args) } ` - diff --git a/core/src/federation/client/SendCoinsClientFactory.ts b/core/src/federation/client/SendCoinsClientFactory.ts index 4a2772175..fcabfe514 100644 --- a/core/src/federation/client/SendCoinsClientFactory.ts +++ b/core/src/federation/client/SendCoinsClientFactory.ts @@ -1,8 +1,7 @@ import { FederatedCommunity as DbFederatedCommunity } from 'database' - +import { ApiVersionType } from '../enum/apiVersionType' import { SendCoinsClient as V1_0_SendCoinsClient } from './1_0/SendCoinsClient' import { SendCoinsClient as V1_1_SendCoinsClient } from './1_1/SendCoinsClient' -import { ApiVersionType } from '../enum/apiVersionType' type SendCoinsClient = V1_0_SendCoinsClient | V1_1_SendCoinsClient diff --git a/core/src/graphql/enum/TransactionTypeId.ts b/core/src/graphql/enum/TransactionTypeId.ts index c6c188c5f..d2a909cb7 100644 --- a/core/src/graphql/enum/TransactionTypeId.ts +++ b/core/src/graphql/enum/TransactionTypeId.ts @@ -1,5 +1,5 @@ -import { registerEnumType } from 'type-graphql' import { TransactionTypeId } from 'database' +import { registerEnumType } from 'type-graphql' export { TransactionTypeId } registerEnumType(TransactionTypeId, { diff --git a/core/src/graphql/logging/DecayLogging.view.ts b/core/src/graphql/logging/DecayLogging.view.ts index 2c485447a..d3917ace4 100644 --- a/core/src/graphql/logging/DecayLogging.view.ts +++ b/core/src/graphql/logging/DecayLogging.view.ts @@ -1,7 +1,6 @@ import { AbstractLoggingView } from 'database' - -import { Decay } from '../model/Decay' import type { Decay as DecayInterface } from 'shared' +import { Decay } from '../model/Decay' export class DecayLoggingView extends AbstractLoggingView { public constructor(private self: Decay | DecayInterface) { diff --git a/core/src/graphql/logic/interpretEncryptedTransferArgs.ts b/core/src/graphql/logic/interpretEncryptedTransferArgs.ts index 576a2b3b8..53faa7416 100644 --- a/core/src/graphql/logic/interpretEncryptedTransferArgs.ts +++ b/core/src/graphql/logic/interpretEncryptedTransferArgs.ts @@ -1,14 +1,17 @@ -import { EncryptedTransferArgs } from '../model/EncryptedTransferArgs' -import { Ed25519PublicKey, JwtPayloadType } from 'shared' -import { Community as DbCommunity } from 'database' +import { CommunityLoggingView, Community as DbCommunity, getHomeCommunity } from 'database' import { getLogger } from 'log4js' -import { CommunityLoggingView, getHomeCommunity } from 'database' -import { verifyAndDecrypt } from 'shared' +import { Ed25519PublicKey, JwtPayloadType, verifyAndDecrypt } from 'shared' import { LOG4JS_BASE_CATEGORY_NAME } from '../../config/const' +import { EncryptedTransferArgs } from '../model/EncryptedTransferArgs' -const createLogger = (functionName: string) => getLogger(`${LOG4JS_BASE_CATEGORY_NAME}.graphql.logic.interpretEncryptedTransferArgs.${functionName}`) +const createLogger = (functionName: string) => + getLogger( + `${LOG4JS_BASE_CATEGORY_NAME}.graphql.logic.interpretEncryptedTransferArgs.${functionName}`, + ) -export const interpretEncryptedTransferArgs = async (args: EncryptedTransferArgs): Promise => { +export const interpretEncryptedTransferArgs = async ( + args: EncryptedTransferArgs, +): Promise => { const methodLogger = createLogger('interpretEncryptedTransferArgs') methodLogger.addContext('handshakeID', args.handshakeID) methodLogger.debug('interpretEncryptedTransferArgs()... args:', args) @@ -30,7 +33,12 @@ export const interpretEncryptedTransferArgs = async (args: EncryptedTransferArgs // verify the signing of args.jwt with homeCom.privateJwtKey and decrypt args.jwt with requestingCom.publicJwtKey // TODO: maybe use community from caller instead of loading it separately const homeCom = await getHomeCommunity() - const jwtPayload = await verifyAndDecrypt(args.handshakeID, args.jwt, homeCom!.privateJwtKey!, requestingCom.publicJwtKey) as JwtPayloadType + const jwtPayload = (await verifyAndDecrypt( + args.handshakeID, + args.jwt, + homeCom!.privateJwtKey!, + requestingCom.publicJwtKey, + )) as JwtPayloadType if (!jwtPayload) { const errmsg = `invalid payload of community with publicKey ${argsPublicKey.asHex()}` methodLogger.error(errmsg) diff --git a/core/src/graphql/logic/processXComSendCoins.ts b/core/src/graphql/logic/processXComSendCoins.ts index bdbf24928..ceb33a378 100644 --- a/core/src/graphql/logic/processXComSendCoins.ts +++ b/core/src/graphql/logic/processXComSendCoins.ts @@ -10,31 +10,35 @@ import { findUserByIdentifier, getCommunityByUuid, PendingTransactionLoggingView, - UserLoggingView + UserLoggingView, } from 'database' import { Decimal } from 'decimal.js-light' - -import { CONFIG as CONFIG_CORE } from '../../config' -import { LOG4JS_BASE_CATEGORY_NAME } from '../../config/const' - -import { encryptAndSign, PendingTransactionState, SendCoinsJwtPayloadType, SendCoinsResponseJwtPayloadType, verifyAndDecrypt } from 'shared' -import { SendCoinsClient as V1_0_SendCoinsClient } from '../../federation/client/1_0/SendCoinsClient' -import { SendCoinsResult } from '../../federation/client/1_0/model/SendCoinsResult' -import { SendCoinsClientFactory } from '../../federation/client/SendCoinsClientFactory' -import { TransactionTypeId } from '../../graphql/enum/TransactionTypeId' // import { LogError } from '@server/LogError' import { getLogger } from 'log4js' +import { + encryptAndSign, + PendingTransactionState, + SendCoinsJwtPayloadType, + SendCoinsResponseJwtPayloadType, + verifyAndDecrypt, +} from 'shared' +import { randombytes_random } from 'sodium-native' +import { CONFIG as CONFIG_CORE } from '../../config' +import { LOG4JS_BASE_CATEGORY_NAME } from '../../config/const' +import { SendCoinsResultLoggingView } from '../../federation/client/1_0/logging/SendCoinsResultLogging.view' +import { SendCoinsResult } from '../../federation/client/1_0/model/SendCoinsResult' +import { SendCoinsClient as V1_0_SendCoinsClient } from '../../federation/client/1_0/SendCoinsClient' +import { SendCoinsClientFactory } from '../../federation/client/SendCoinsClientFactory' +import { TransactionTypeId } from '../../graphql/enum/TransactionTypeId' +import { EncryptedTransferArgs } from '../../graphql/model/EncryptedTransferArgs' import { calculateSenderBalance } from '../../util/calculateSenderBalance' import { fullName } from '../../util/utilities' - -import { randombytes_random } from 'sodium-native' -import { SendCoinsResultLoggingView } from '../../federation/client/1_0/logging/SendCoinsResultLogging.view' -import { EncryptedTransferArgs } from '../../graphql/model/EncryptedTransferArgs' import { settlePendingSenderTransaction } from './settlePendingSenderTransaction' import { storeForeignUser } from './storeForeignUser' import { storeLinkAsRedeemed } from './storeLinkAsRedeemed' -const createLogger = (method: string) => getLogger(`${LOG4JS_BASE_CATEGORY_NAME}.graphql.resolver.util.processXComSendCoins.${method}`) +const createLogger = (method: string) => + getLogger(`${LOG4JS_BASE_CATEGORY_NAME}.graphql.resolver.util.processXComSendCoins.${method}`) export async function processXComCompleteTransaction( senderCommunityUuid: string, @@ -82,7 +86,7 @@ export async function processXComCompleteTransaction( throw new Error(errmsg) } let dbTransactionLink: DbTransactionLink | null = null - if(code !== undefined) { + if (code !== undefined) { try { dbTransactionLink = await findTransactionLinkByCode(code) if (dbTransactionLink && dbTransactionLink.validUntil < new Date()) { @@ -96,12 +100,12 @@ export async function processXComCompleteTransaction( throw new Error(errmsg) } } - if(creationDate === undefined) { + if (creationDate === undefined) { creationDate = new Date() } let pendingResult: SendCoinsResponseJwtPayloadType | null = null let committingResult: SendCoinsResult - + try { pendingResult = await processXComPendingSendCoins( recipientCom, @@ -131,10 +135,10 @@ export async function processXComCompleteTransaction( methodLogger.fatal('FATAL ERROR: on processXComCommittingSendCoins for', committingResult) throw new Error( 'FATAL ERROR: on processXComCommittingSendCoins with ' + - recipientCom.communityUuid + - recipientGradidoId + - amount.toString() + - memo, + recipientCom.communityUuid + + recipientGradidoId + + amount.toString() + + memo, ) } // after successful x-com-tx store the recipient as foreign user @@ -151,7 +155,7 @@ export async function processXComCompleteTransaction( methodLogger.error(errmsg) throw new Error(errmsg) } - if(dbTransactionLink !== null) { + if (dbTransactionLink !== null) { // after successful x-com-tx per link store the link as redeemed methodLogger.debug('store link as redeemed...') if (await storeLinkAsRedeemed(dbTransactionLink, foreignUser!, creationDate)) { @@ -163,9 +167,10 @@ export async function processXComCompleteTransaction( ) } } - } + } } catch (err) { - const errmsg = `ERROR: on processXComCommittingSendCoins with ` + + const errmsg = + `ERROR: on processXComCommittingSendCoins with ` + recipientCommunityUuid + recipientGradidoId + amount.toString() + @@ -191,20 +196,18 @@ export async function processXComPendingSendCoins( const methodLogger = createLogger(`processXComPendingSendCoins`) try { // even if debug is not enabled, attributes are processed so we skip the entire call for performance reasons - if(methodLogger.isDebugEnabled()) { - methodLogger.debug( - 'XCom: processXComPendingSendCoins...', { - receiverCom: new CommunityLoggingView(receiverCom), - senderCom: new CommunityLoggingView(senderCom), - amount: amount.toString(), - memo: memo.substring(0, 5), - sender: new UserLoggingView(sender), - recipientIdentifier, - transactionLinkId - } - ) + if (methodLogger.isDebugEnabled()) { + methodLogger.debug('XCom: processXComPendingSendCoins...', { + receiverCom: new CommunityLoggingView(receiverCom), + senderCom: new CommunityLoggingView(senderCom), + amount: amount.toString(), + memo: memo.substring(0, 5), + sender: new UserLoggingView(sender), + recipientIdentifier, + transactionLinkId, + }) } - if (await countOpenPendingTransactions([sender.gradidoID, recipientIdentifier]) > 0) { + if ((await countOpenPendingTransactions([sender.gradidoID, recipientIdentifier])) > 0) { const errmsg = `There exist still ongoing 'Pending-Transactions' for the involved users on sender-side!` methodLogger.error(errmsg) throw new Error(errmsg) @@ -218,7 +221,7 @@ export async function processXComPendingSendCoins( methodLogger.error(errmsg) throw new Error(errmsg) } - if(methodLogger.isDebugEnabled()) { + if (methodLogger.isDebugEnabled()) { methodLogger.debug(`calculated senderBalance = ${JSON.stringify(senderBalance, null, 2)}`) } @@ -231,7 +234,8 @@ export async function processXComPendingSendCoins( const client = SendCoinsClientFactory.getInstance(receiverFCom) if (client instanceof V1_0_SendCoinsClient) { - const payload = new SendCoinsJwtPayloadType(handshakeID, + const payload = new SendCoinsJwtPayloadType( + handshakeID, receiverCom.communityUuid!, recipientIdentifier, creationDate.toISOString(), @@ -241,13 +245,13 @@ export async function processXComPendingSendCoins( sender.gradidoID, fullName(sender.firstName, sender.lastName), sender.alias, - transactionLinkId + transactionLinkId, ) - if(methodLogger.isDebugEnabled()) { + if (methodLogger.isDebugEnabled()) { methodLogger.debug(`ready for voteForSendCoins with payload=${payload}`) } const jws = await encryptAndSign(payload, senderCom.privateJwtKey!, receiverCom.publicJwtKey!) - if(methodLogger.isDebugEnabled()) { + if (methodLogger.isDebugEnabled()) { methodLogger.debug('jws', jws) } // prepare the args for the client invocation @@ -255,21 +259,31 @@ export async function processXComPendingSendCoins( args.publicKey = senderCom.publicKey.toString('hex') args.jwt = jws args.handshakeID = handshakeID - if(methodLogger.isDebugEnabled()) { + if (methodLogger.isDebugEnabled()) { methodLogger.debug('before client.voteForSendCoins() args:', args) } const responseJwt = await client.voteForSendCoins(args) - if(methodLogger.isDebugEnabled()) { + if (methodLogger.isDebugEnabled()) { methodLogger.debug(`response of voteForSendCoins():`, responseJwt) } if (responseJwt !== null) { - voteResult = await verifyAndDecrypt(handshakeID, responseJwt, senderCom.privateJwtKey!, receiverCom.publicJwtKey!) as SendCoinsResponseJwtPayloadType - if(methodLogger.isDebugEnabled()) { + voteResult = (await verifyAndDecrypt( + handshakeID, + responseJwt, + senderCom.privateJwtKey!, + receiverCom.publicJwtKey!, + )) as SendCoinsResponseJwtPayloadType + if (methodLogger.isDebugEnabled()) { methodLogger.debug(`received payload from voteForSendCoins():`, voteResult) } - if (voteResult && voteResult.tokentype !== SendCoinsResponseJwtPayloadType.SEND_COINS_RESPONSE_TYPE) { - const errmsg = `Invalid tokentype in voteForSendCoins-response of community with publicKey` + receiverCom.publicKey + if ( + voteResult && + voteResult.tokentype !== SendCoinsResponseJwtPayloadType.SEND_COINS_RESPONSE_TYPE + ) { + const errmsg = + `Invalid tokentype in voteForSendCoins-response of community with publicKey` + + receiverCom.publicKey methodLogger.error(errmsg) throw new Error('Error in X-Com-TX protocol...') } @@ -290,7 +304,10 @@ export async function processXComPendingSendCoins( pendingTx.linkedUserGradidoID = voteResult.recipGradidoID } if (voteResult.recipFirstName && voteResult.recipLastName) { - pendingTx.linkedUserName = fullName(voteResult.recipFirstName, voteResult.recipLastName) + pendingTx.linkedUserName = fullName( + voteResult.recipFirstName, + voteResult.recipLastName, + ) } pendingTx.memo = memo pendingTx.previous = senderBalance ? senderBalance.lastTransactionId : null @@ -303,40 +320,50 @@ export async function processXComPendingSendCoins( pendingTx.userGradidoID = sender.gradidoID pendingTx.userName = fullName(sender.firstName, sender.lastName) pendingTx.transactionLinkId = transactionLinkId - if(methodLogger.isDebugEnabled()) { - methodLogger.debug(`initialized sender pendingTX=${new PendingTransactionLoggingView(pendingTx)}`) + if (methodLogger.isDebugEnabled()) { + methodLogger.debug( + `initialized sender pendingTX=${new PendingTransactionLoggingView(pendingTx)}`, + ) } await DbPendingTransaction.insert(pendingTx) methodLogger.debug('sender pendingTx successfully inserted...') } catch (err) { - methodLogger.error(`Error in writing sender pending transaction: ${JSON.stringify(err, null, 2)}`) + methodLogger.error( + `Error in writing sender pending transaction: ${JSON.stringify(err, null, 2)}`, + ) // revert the existing pending transaction on receiver side let revertCount = 0 methodLogger.debug('first try to revertSendCoins of receiver') do { if (await client.revertSendCoins(args)) { - methodLogger.debug(`revertSendCoins()-1_0... successfull after revertCount=${revertCount}`) + methodLogger.debug( + `revertSendCoins()-1_0... successfull after revertCount=${revertCount}`, + ) // treat revertingSendCoins as an error of the whole sendCoins-process const errmsg = `Error in writing sender pending transaction: ${JSON.stringify(err, null, 2)}` methodLogger.error(errmsg) throw new Error(errmsg) } } while (CONFIG_CORE.FEDERATION_XCOM_MAXREPEAT_REVERTSENDCOINS > revertCount++) - const errmsg = `Error in reverting receiver pending transaction even after revertCount=${revertCount}` + JSON.stringify(err, null, 2) + const errmsg = + `Error in reverting receiver pending transaction even after revertCount=${revertCount}` + + JSON.stringify(err, null, 2) methodLogger.error(errmsg) throw new Error(errmsg) } methodLogger.debug('voteForSendCoins()-1_0... successfull') return voteResult } else { - methodLogger.error(`break with error on writing pendingTransaction for recipient... ${voteResult}`) + methodLogger.error( + `break with error on writing pendingTransaction for recipient... ${voteResult}`, + ) } } else { methodLogger.error(`break with no response from voteForSendCoins()-1_0...`) } } - } catch (err: any) { + } catch (err: any) { const errmsg = `Error: ${err.message}` + JSON.stringify(err, null, 2) methodLogger.error(errmsg) throw new Error(errmsg) @@ -359,19 +386,17 @@ export async function processXComCommittingSendCoins( methodLogger.addContext('handshakeID', handshakeID) const sendCoinsResult = new SendCoinsResult() try { - if(methodLogger.isDebugEnabled()) { - methodLogger.debug( - 'XCom: processXComCommittingSendCoins...', { - receiverCom: new CommunityLoggingView(receiverCom), - senderCom: new CommunityLoggingView(senderCom), - creationDate: creationDate.toISOString(), - amount: amount.toString(), - memo: memo.substring(0, 5), - sender: new UserLoggingView(sender), - recipient: new SendCoinsResultLoggingView(recipient), - transactionLinkId, - } - ) + if (methodLogger.isDebugEnabled()) { + methodLogger.debug('XCom: processXComCommittingSendCoins...', { + receiverCom: new CommunityLoggingView(receiverCom), + senderCom: new CommunityLoggingView(senderCom), + creationDate: creationDate.toISOString(), + amount: amount.toString(), + memo: memo.substring(0, 5), + sender: new UserLoggingView(sender), + recipient: new SendCoinsResultLoggingView(recipient), + transactionLinkId, + }) } // first find pending Tx with given parameters const pendingTx = await DbPendingTransaction.findOneBy({ @@ -387,8 +412,10 @@ export async function processXComCommittingSendCoins( memo, }) if (pendingTx) { - if(methodLogger.isDebugEnabled()) { - methodLogger.debug(`find pending Tx for settlement: ${new PendingTransactionLoggingView(pendingTx)}`) + if (methodLogger.isDebugEnabled()) { + methodLogger.debug( + `find pending Tx for settlement: ${new PendingTransactionLoggingView(pendingTx)}`, + ) } const receiverFCom = await DbFederatedCommunity.findOneOrFail({ where: { @@ -420,10 +447,14 @@ export async function processXComCommittingSendCoins( if (pendingTx.linkedUserGradidoID) { payload.recipientUserIdentifier = pendingTx.linkedUserGradidoID } - if(methodLogger.isDebugEnabled()) { - methodLogger.debug(`ready for settleSendCoins with payload=${ JSON.stringify(payload)}`) + if (methodLogger.isDebugEnabled()) { + methodLogger.debug(`ready for settleSendCoins with payload=${JSON.stringify(payload)}`) } - const jws = await encryptAndSign(payload, senderCom.privateJwtKey!, receiverCom.publicJwtKey!) + const jws = await encryptAndSign( + payload, + senderCom.privateJwtKey!, + receiverCom.publicJwtKey!, + ) // prepare the args for the client invocation const args = new EncryptedTransferArgs() args.publicKey = senderCom.publicKey.toString('hex') @@ -454,7 +485,9 @@ export async function processXComCommittingSendCoins( sendCoinsResult.recipAlias = recipient.recipAlias } } catch (err) { - methodLogger.error(`Error in writing sender pending transaction: ${JSON.stringify(err, null, 2)}`) + methodLogger.error( + `Error in writing sender pending transaction: ${JSON.stringify(err, null, 2)}`, + ) // revert the existing pending transaction on receiver side let revertCount = 0 methodLogger.debug('first try to revertSettledSendCoins of receiver') diff --git a/core/src/graphql/logic/settlePendingSenderTransaction.ts b/core/src/graphql/logic/settlePendingSenderTransaction.ts index 2069892fb..3336f2abd 100644 --- a/core/src/graphql/logic/settlePendingSenderTransaction.ts +++ b/core/src/graphql/logic/settlePendingSenderTransaction.ts @@ -1,23 +1,22 @@ +// import { TRANSACTIONS_LOCK, getLastTransaction } from 'database' import { AppDatabase, CommunityLoggingView, Community as DbCommunity, PendingTransaction as DbPendingTransaction, User as DbUser, + Transaction as dbTransaction, + getLastTransaction, PendingTransactionLoggingView, UserLoggingView, - Transaction as dbTransaction, } from 'database' import { Decimal } from 'decimal.js-light' - -import { LOG4JS_BASE_CATEGORY_NAME } from '../../config/const' -import { PendingTransactionState } from 'shared' -// import { LogError } from '@/server/LogError' -import { calculateSenderBalance } from '../../util/calculateSenderBalance' -// import { TRANSACTIONS_LOCK, getLastTransaction } from 'database' -import { getLastTransaction } from 'database' import { getLogger } from 'log4js' import { Mutex } from 'redis-semaphore' +import { PendingTransactionState } from 'shared' +import { LOG4JS_BASE_CATEGORY_NAME } from '../../config/const' +// import { LogError } from '@/server/LogError' +import { calculateSenderBalance } from '../../util/calculateSenderBalance' const db = AppDatabase.getInstance() const logger = getLogger( @@ -41,7 +40,12 @@ export async function settlePendingSenderTransaction( logger.debug(`start Transaction for write-access...`) try { - logger.info('settlePendingSenderTransaction:', new CommunityLoggingView(homeCom), new UserLoggingView(senderUser), new PendingTransactionLoggingView(pendingTx)) + logger.info( + 'settlePendingSenderTransaction:', + new CommunityLoggingView(homeCom), + new UserLoggingView(senderUser), + new PendingTransactionLoggingView(pendingTx), + ) // ensure that no other pendingTx with the same sender or recipient exists const openSenderPendingTx = await DbPendingTransaction.count({ diff --git a/core/src/graphql/logic/storeForeignUser.ts b/core/src/graphql/logic/storeForeignUser.ts index 95a1d106c..a367ee8e3 100644 --- a/core/src/graphql/logic/storeForeignUser.ts +++ b/core/src/graphql/logic/storeForeignUser.ts @@ -1,8 +1,7 @@ import { Community as DbCommunity, User as DbUser, findForeignUserByUuids } from 'database' - -import { SendCoinsResult } from '../../federation/client/1_0/model/SendCoinsResult' -import { LOG4JS_BASE_CATEGORY_NAME } from '../../config/const' import { getLogger } from 'log4js' +import { LOG4JS_BASE_CATEGORY_NAME } from '../../config/const' +import { SendCoinsResult } from '../../federation/client/1_0/model/SendCoinsResult' const logger = getLogger(`${LOG4JS_BASE_CATEGORY_NAME}.graphql.logic.storeForeignUser`) @@ -12,7 +11,10 @@ export async function storeForeignUser( ): Promise { if (recipCom.communityUuid !== null && committingResult.recipGradidoID !== null) { try { - const user = await findForeignUserByUuids(recipCom.communityUuid, committingResult.recipGradidoID) + const user = await findForeignUserByUuids( + recipCom.communityUuid, + committingResult.recipGradidoID, + ) if (!user) { logger.debug( 'no foreignUser found for:', diff --git a/core/src/graphql/logic/storeLinkAsRedeemed.ts b/core/src/graphql/logic/storeLinkAsRedeemed.ts index efc3589de..1461e1f25 100644 --- a/core/src/graphql/logic/storeLinkAsRedeemed.ts +++ b/core/src/graphql/logic/storeLinkAsRedeemed.ts @@ -5,17 +5,17 @@ import { LOG4JS_BASE_CATEGORY_NAME } from '../../config/const' const logger = getLogger(`${LOG4JS_BASE_CATEGORY_NAME}.graphql.logic.storeLinkAsRedeemed`) export async function storeLinkAsRedeemed( - dbTransactionLink: DbTransactionLink, - foreignUser: DbUser, - creationDate: Date, + dbTransactionLink: DbTransactionLink, + foreignUser: DbUser, + creationDate: Date, ): Promise { - try { - dbTransactionLink.redeemedBy = foreignUser.id - dbTransactionLink.redeemedAt = creationDate - await DbTransactionLink.save(dbTransactionLink) - return true - } catch (err) { - logger.error('error: ', err) - return false - } -} \ No newline at end of file + try { + dbTransactionLink.redeemedBy = foreignUser.id + dbTransactionLink.redeemedAt = creationDate + await DbTransactionLink.save(dbTransactionLink) + return true + } catch (err) { + logger.error('error: ', err) + return false + } +} diff --git a/core/src/graphql/model/Decay.ts b/core/src/graphql/model/Decay.ts index 838e442f7..f18acdb3d 100644 --- a/core/src/graphql/model/Decay.ts +++ b/core/src/graphql/model/Decay.ts @@ -1,6 +1,6 @@ import { Decimal } from 'decimal.js-light' -import { Field, Int, ObjectType } from 'type-graphql' import { Decay as DecayInterface } from 'shared' +import { Field, Int, ObjectType } from 'type-graphql' @ObjectType() export class Decay { diff --git a/core/src/index.ts b/core/src/index.ts index a429bdc3b..ddc204f5b 100644 --- a/core/src/index.ts +++ b/core/src/index.ts @@ -1,4 +1,5 @@ -export {SendCoinsClient as V1_0_SendCoinsClient} from './federation/client/1_0/SendCoinsClient' +export * from './config/index' +export * from './emails' export * from './federation/client/1_0/logging/SendCoinsArgsLogging.view' export * from './federation/client/1_0/logging/SendCoinsResultLogging.view' export * from './federation/client/1_0/model/SendCoinsArgs' @@ -7,7 +8,8 @@ export * from './federation/client/1_0/query/revertSendCoins' export * from './federation/client/1_0/query/revertSettledSendCoins' export * from './federation/client/1_0/query/settleSendCoins' export * from './federation/client/1_0/query/voteForSendCoins' -export {SendCoinsClient as V1_1_SendCoinsClient} from './federation/client/1_1/SendCoinsClient' +export { SendCoinsClient as V1_0_SendCoinsClient } from './federation/client/1_0/SendCoinsClient' +export { SendCoinsClient as V1_1_SendCoinsClient } from './federation/client/1_1/SendCoinsClient' export * from './federation/client/SendCoinsClientFactory' export * from './federation/enum/apiVersionType' export * from './graphql/enum/TransactionTypeId' @@ -18,10 +20,7 @@ export * from './graphql/logic/settlePendingSenderTransaction' export * from './graphql/logic/storeForeignUser' export * from './graphql/model/Decay' export * from './graphql/model/EncryptedTransferArgs' -export * from './emails' +export * from './logic' export * from './util/calculateSenderBalance' export * from './util/utilities' export * from './validation/user' -export * from './config/index' -export * from './logic' - diff --git a/core/src/locales/localization.test.ts b/core/src/locales/localization.test.ts index 77651c4e4..b91e0a201 100644 --- a/core/src/locales/localization.test.ts +++ b/core/src/locales/localization.test.ts @@ -4,4 +4,4 @@ describe('localization', () => { it('translate emails.accountMultiRegistration.contactSupport with Contact support', () => { expect(i18n.__('emails.accountMultiRegistration.contactSupport')).toBe('Contact support') }) -}) \ No newline at end of file +}) diff --git a/core/src/locales/localization.ts b/core/src/locales/localization.ts index df604cf5a..cb19e7ae9 100644 --- a/core/src/locales/localization.ts +++ b/core/src/locales/localization.ts @@ -1,8 +1,8 @@ -import en from './en.json' -import de from './de.json' import { I18n } from 'i18n' import { getLogger } from 'log4js' import { LOG4JS_BASE_CATEGORY_NAME } from '../config/const' +import de from './de.json' +import en from './en.json' const logger = getLogger(`${LOG4JS_BASE_CATEGORY_NAME}.emails.localization`) @@ -35,4 +35,3 @@ export const i18n = new I18n({ disable: false, }, }) - diff --git a/core/src/logic/CommunityHandshakeState.logic.ts b/core/src/logic/CommunityHandshakeState.logic.ts index 52422be15..e9cb23d5c 100644 --- a/core/src/logic/CommunityHandshakeState.logic.ts +++ b/core/src/logic/CommunityHandshakeState.logic.ts @@ -21,7 +21,7 @@ export class CommunityHandshakeStateLogic { if (this.self.status === CommunityHandshakeStateType.EXPIRED) { return true } - if ((Date.now() - this.self.updatedAt.getTime()) > FEDERATION_AUTHENTICATION_TIMEOUT_MS) { + if (Date.now() - this.self.updatedAt.getTime() > FEDERATION_AUTHENTICATION_TIMEOUT_MS) { return true } return false diff --git a/core/src/logic/CommunityHandshakeStateLogic.test.ts b/core/src/logic/CommunityHandshakeStateLogic.test.ts index 52d11d8fb..8d322e254 100644 --- a/core/src/logic/CommunityHandshakeStateLogic.test.ts +++ b/core/src/logic/CommunityHandshakeStateLogic.test.ts @@ -1,7 +1,6 @@ -import { CommunityHandshakeState } from 'database' -import { CommunityHandshakeStateLogic } from './CommunityHandshakeState.logic' -import { CommunityHandshakeStateType } from 'database' +import { CommunityHandshakeState, CommunityHandshakeStateType } from 'database' import { FEDERATION_AUTHENTICATION_TIMEOUT_MS } from 'shared' +import { CommunityHandshakeStateLogic } from './CommunityHandshakeState.logic' describe('CommunityHandshakeStateLogic', () => { it('isTimeout', () => { @@ -19,4 +18,4 @@ describe('CommunityHandshakeStateLogic', () => { const logic = new CommunityHandshakeStateLogic(state) expect(logic.isTimeout()).toEqual(false) }) -}) \ No newline at end of file +}) diff --git a/core/src/logic/community.logic.ts b/core/src/logic/community.logic.ts index 8fb9cd59b..885878e73 100644 --- a/core/src/logic/community.logic.ts +++ b/core/src/logic/community.logic.ts @@ -2,7 +2,7 @@ import { Community as DbCommunity, FederatedCommunity as DbFederatedCommunity } export function getFederatedCommunityWithApiOrFail( community: DbCommunity, - apiVersion: string + apiVersion: string, ): DbFederatedCommunity { const fedCom = community.federatedCommunities?.find((fedCom) => fedCom.apiVersion === apiVersion) if (!fedCom) { diff --git a/core/src/logic/index.ts b/core/src/logic/index.ts index 7d7a943bf..2c431a7c6 100644 --- a/core/src/logic/index.ts +++ b/core/src/logic/index.ts @@ -1,2 +1,2 @@ export * from './CommunityHandshakeState.logic' -export * from './community.logic' \ No newline at end of file +export * from './community.logic' diff --git a/core/src/types/images.d.ts b/core/src/types/images.d.ts index 91c6fd6f9..80a0a953a 100644 --- a/core/src/types/images.d.ts +++ b/core/src/types/images.d.ts @@ -1,4 +1,4 @@ -// biome-ignore lint/style/noDefaultExport: Asset modules use default export by convention +// biome-ignore-all lint/style/noDefaultExport: Asset modules use default export by convention declare module '*.jpg' { const value: string export default value @@ -11,5 +11,3 @@ declare module '*.png' { const value: string export default value } - - \ No newline at end of file diff --git a/core/src/util/calculateSenderBalance.ts b/core/src/util/calculateSenderBalance.ts index 7fe5ae19f..00c67a885 100644 --- a/core/src/util/calculateSenderBalance.ts +++ b/core/src/util/calculateSenderBalance.ts @@ -1,10 +1,7 @@ -import { Decimal } from 'decimal.js-light' - -import { Decay } from '../graphql/model/Decay' - import { getLastTransaction } from 'database' - +import { Decimal } from 'decimal.js-light' import { calculateDecay } from 'shared' +import { Decay } from '../graphql/model/Decay' export async function calculateSenderBalance( userId: number, @@ -16,7 +13,9 @@ export async function calculateSenderBalance( return null } - const decay = new Decay(calculateDecay(lastTransaction.balance, lastTransaction.balanceDate, time)) + const decay = new Decay( + calculateDecay(lastTransaction.balance, lastTransaction.balanceDate, time), + ) const balance = decay.balance.add(amount.toString()) return { balance, lastTransactionId: lastTransaction.id, decay } diff --git a/core/src/util/utilities.ts b/core/src/util/utilities.ts index cfec3d37a..7278f5c9e 100644 --- a/core/src/util/utilities.ts +++ b/core/src/util/utilities.ts @@ -1,7 +1,7 @@ -import { promisify } from 'util' - import { Decimal } from 'decimal.js-light' +import { promisify } from 'util' import { i18n } from '../locales/localization' + export { fullName } from 'shared' export const objectValuesToArray = (obj: Record): string[] => @@ -19,7 +19,7 @@ export const decimalSeparatorByLanguage = (a: Decimal, language: string): string export function resetInterface>(obj: T): T { // Iterate over all properties of the object for (const key in obj) { - if (Object.prototype.hasOwnProperty.call(obj, key)) { + if (Object.hasOwn(obj, key)) { // Set all optional properties to undefined obj[key] = undefined as T[Extract] @@ -33,7 +33,10 @@ export const delay = promisify(setTimeout) export const ensureUrlEndsWithSlash = (url: string): string => { return url.endsWith('/') ? url : url.concat('/') } -export function splitUrlInEndPointAndApiVersion(url: string): { endPoint: string, apiVersion: string } { +export function splitUrlInEndPointAndApiVersion(url: string): { + endPoint: string + apiVersion: string +} { const endPoint = url.slice(0, url.lastIndexOf('/') + 1) const apiVersion = url.slice(url.lastIndexOf('/') + 1, url.length) return { endPoint, apiVersion } diff --git a/core/src/validation/user.test.ts b/core/src/validation/user.test.ts index fb9cf7b94..33a9f5e66 100644 --- a/core/src/validation/user.test.ts +++ b/core/src/validation/user.test.ts @@ -1,8 +1,8 @@ -import { validateAlias } from './user' +import { afterAll, beforeEach, describe, expect, it, jest, mock } from 'bun:test' +import { AbstractLoggingView, AppDatabase, aliasExists } from 'database' import { getLogger } from '../../../config-schema/test/testSetup.bun' -import { describe, it, expect, mock, jest, afterAll, beforeEach } from 'bun:test' import { LOG4JS_BASE_CATEGORY_NAME } from '../config/const' -import { aliasExists, AbstractLoggingView, AppDatabase } from 'database' +import { validateAlias } from './user' const logger = getLogger(`${LOG4JS_BASE_CATEGORY_NAME}.validation.user`) @@ -19,13 +19,12 @@ mock.module('database', () => ({ AppDatabase, })) - afterAll(() => { mock.restore() }) -describe('validate alias', () => { - beforeEach(() => { +describe('validate alias', () => { + beforeEach(() => { jest.clearAllMocks() }) @@ -57,11 +56,10 @@ describe('validate alias', () => { }) }) - describe('test against existing alias in database', () => { describe('alias exists in database', () => { it('throws and logs an error', () => { - (aliasExists as jest.Mock).mockReturnValue(true) + ;(aliasExists as jest.Mock).mockReturnValue(true) expect(validateAlias('b-b')).rejects.toEqual(new Error('Given alias is already in use')) expect(logger.warn.mock.calls[0]).toEqual(['alias already in use', 'b-b']) }) @@ -69,7 +67,7 @@ describe('validate alias', () => { describe('valid alias', () => { it('resolves to true', async () => { - (aliasExists as jest.Mock).mockReturnValue(false) + ;(aliasExists as jest.Mock).mockReturnValue(false) expect(validateAlias('bibi')).resolves.toEqual(true) }) }) diff --git a/core/src/validation/user.ts b/core/src/validation/user.ts index eebc34442..808f67e64 100644 --- a/core/src/validation/user.ts +++ b/core/src/validation/user.ts @@ -1,8 +1,8 @@ -import { ZodError } from 'zod' -import { getLogger } from 'log4js' -import { LOG4JS_BASE_CATEGORY_NAME } from '../config/const' import { aliasExists } from 'database' +import { getLogger } from 'log4js' import { aliasSchema } from 'shared' +import { ZodError } from 'zod' +import { LOG4JS_BASE_CATEGORY_NAME } from '../config/const' const logger = getLogger(`${LOG4JS_BASE_CATEGORY_NAME}.validation.user`) diff --git a/database/migration/migrations/0094-openai_threads_add_updated_at.ts b/database/migration/migrations/0094-openai_threads_add_updated_at.ts index 8505bf21c..9175e2580 100644 --- a/database/migration/migrations/0094-openai_threads_add_updated_at.ts +++ b/database/migration/migrations/0094-openai_threads_add_updated_at.ts @@ -1,7 +1,6 @@ - export async function upgrade(queryFn: (query: string, values?: any[]) => Promise>) { await queryFn( - 'ALTER TABLE `openai_threads` ADD COLUMN `updatedAt` timestamp NULL DEFAULT CURRENT_TIMESTAMP AFTER `createdAt`;' + 'ALTER TABLE `openai_threads` ADD COLUMN `updatedAt` timestamp NULL DEFAULT CURRENT_TIMESTAMP AFTER `createdAt`;', ) } diff --git a/database/migration/migrations/0095-add_community_handshake_states_table.ts b/database/migration/migrations/0095-add_community_handshake_states_table.ts index 45e5b29a8..20ae775d5 100644 --- a/database/migration/migrations/0095-add_community_handshake_states_table.ts +++ b/database/migration/migrations/0095-add_community_handshake_states_table.ts @@ -17,4 +17,4 @@ export async function upgrade(queryFn: (query: string, values?: any[]) => Promis export async function downgrade(queryFn: (query: string, values?: any[]) => Promise>) { await queryFn(`DROP TABLE community_handshake_states;`) -} +} diff --git a/database/src/AppDatabase.ts b/database/src/AppDatabase.ts index e0ca68527..6357b8a3c 100644 --- a/database/src/AppDatabase.ts +++ b/database/src/AppDatabase.ts @@ -1,11 +1,10 @@ -import { DataSource as DBDataSource, FileLogger } from 'typeorm' -import { Migration, entities } from './entity' - +import Redis from 'ioredis' import { getLogger } from 'log4js' +import { DataSource as DBDataSource, FileLogger } from 'typeorm' import { latestDbVersion } from '.' import { CONFIG } from './config' import { LOG4JS_BASE_CATEGORY_NAME } from './config/const' -import Redis from 'ioredis' +import { entities, Migration } from './entity' const logger = getLogger(`${LOG4JS_BASE_CATEGORY_NAME}.AppDatabase`) @@ -109,7 +108,7 @@ export class AppDatabase { } return this.redisClient } - + // ###################################### // private methods // ###################################### diff --git a/database/src/entity/Community.ts b/database/src/entity/Community.ts index e21226d44..d8dbfa4a2 100644 --- a/database/src/entity/Community.ts +++ b/database/src/entity/Community.ts @@ -10,8 +10,8 @@ import { UpdateDateColumn, } from 'typeorm' import { type FederatedCommunity as FederatedCommunityType } from './FederatedCommunity' -import { type User as UserType } from './User' import { GeometryTransformer } from './transformer/GeometryTransformer' +import { type User as UserType } from './User' @Entity('communities') export class Community extends BaseEntity { diff --git a/database/src/entity/CommunityHandshakeState.ts b/database/src/entity/CommunityHandshakeState.ts index eca9c07e7..c24c22968 100644 --- a/database/src/entity/CommunityHandshakeState.ts +++ b/database/src/entity/CommunityHandshakeState.ts @@ -1,5 +1,12 @@ +import { + BaseEntity, + Column, + CreateDateColumn, + Entity, + PrimaryGeneratedColumn, + UpdateDateColumn, +} from 'typeorm' import { CommunityHandshakeStateType } from '../enum' -import { BaseEntity, Column, CreateDateColumn, Entity, PrimaryGeneratedColumn, UpdateDateColumn } from 'typeorm' @Entity('community_handshake_states') export class CommunityHandshakeState extends BaseEntity { @@ -34,4 +41,4 @@ export class CommunityHandshakeState extends BaseEntity { @UpdateDateColumn({ name: 'updated_at', type: 'datetime', precision: 3 }) updatedAt: Date -} \ No newline at end of file +} diff --git a/database/src/entity/Contribution.ts b/database/src/entity/Contribution.ts index 242eae06f..19a592452 100644 --- a/database/src/entity/Contribution.ts +++ b/database/src/entity/Contribution.ts @@ -12,8 +12,8 @@ import { } from 'typeorm' import { type ContributionMessage as ContributionMessageType } from './ContributionMessage' import { type Transaction as TransactionType } from './Transaction' -import { type User as UserType } from './User' import { DecimalTransformer } from './transformer/DecimalTransformer' +import { type User as UserType } from './User' @Entity('contributions') export class Contribution extends BaseEntity { diff --git a/database/src/entity/Event.ts b/database/src/entity/Event.ts index 4adbe6e51..41209edb8 100644 --- a/database/src/entity/Event.ts +++ b/database/src/entity/Event.ts @@ -13,8 +13,8 @@ import { type ContributionLink as ContributionLinkType } from './ContributionLin import { type ContributionMessage as ContributionMessageType } from './ContributionMessage' import { type Transaction as TransactionType } from './Transaction' import { type TransactionLink as TransactionLinkType } from './TransactionLink' -import { type User as UserType } from './User' import { DecimalTransformer } from './transformer/DecimalTransformer' +import { type User as UserType } from './User' @Entity('events') export class Event extends BaseEntity { diff --git a/database/src/entity/OpenaiThreads.ts b/database/src/entity/OpenaiThreads.ts index 03c216921..09eb26908 100644 --- a/database/src/entity/OpenaiThreads.ts +++ b/database/src/entity/OpenaiThreads.ts @@ -1,4 +1,11 @@ -import { BaseEntity, Column, CreateDateColumn, Entity, PrimaryColumn, UpdateDateColumn } from 'typeorm' +import { + BaseEntity, + Column, + CreateDateColumn, + Entity, + PrimaryColumn, + UpdateDateColumn, +} from 'typeorm' @Entity('openai_threads') export class OpenaiThreads extends BaseEntity { diff --git a/database/src/entity/User.ts b/database/src/entity/User.ts index 20219e4f7..d4c5091f2 100644 --- a/database/src/entity/User.ts +++ b/database/src/entity/User.ts @@ -15,9 +15,9 @@ import { type Contribution as ContributionType } from './Contribution' import { type ContributionMessage as ContributionMessageType } from './ContributionMessage' import { type DltTransaction as DltTransactionType } from './DltTransaction' import { type TransactionLink as TransactionLinkType } from './TransactionLink' +import { GeometryTransformer } from './transformer/GeometryTransformer' import { type UserContact as UserContactType } from './UserContact' import { type UserRole as UserRoleType } from './UserRole' -import { GeometryTransformer } from './transformer/GeometryTransformer' @Entity('users', { engine: 'InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_ci' }) export class User extends BaseEntity { diff --git a/database/src/entity/index.ts b/database/src/entity/index.ts index 32bbe239b..f700e64d3 100644 --- a/database/src/entity/index.ts +++ b/database/src/entity/index.ts @@ -1,4 +1,5 @@ import { Community } from './Community' +import { CommunityHandshakeState } from './CommunityHandshakeState' import { Contribution } from './Contribution' import { ContributionLink } from './ContributionLink' import { ContributionMessage } from './ContributionMessage' @@ -7,7 +8,6 @@ import { Event } from './Event' import { FederatedCommunity } from './FederatedCommunity' import { LoginElopageBuys } from './LoginElopageBuys' import { Migration } from './Migration' -import { CommunityHandshakeState } from './CommunityHandshakeState' import { OpenaiThreads } from './OpenaiThreads' import { PendingTransaction } from './PendingTransaction' import { ProjectBranding } from './ProjectBranding' @@ -27,7 +27,7 @@ export { Event, FederatedCommunity, LoginElopageBuys, - Migration, + Migration, ProjectBranding, OpenaiThreads, PendingTransaction, diff --git a/database/src/enum/CommunityHandshakeStateType.ts b/database/src/enum/CommunityHandshakeStateType.ts index e41913cc0..6a60669b5 100644 --- a/database/src/enum/CommunityHandshakeStateType.ts +++ b/database/src/enum/CommunityHandshakeStateType.ts @@ -1,9 +1,9 @@ -export enum CommunityHandshakeStateType { +export enum CommunityHandshakeStateType { START_COMMUNITY_AUTHENTICATION = 'START_COMMUNITY_AUTHENTICATION', START_OPEN_CONNECTION_CALLBACK = 'START_OPEN_CONNECTION_CALLBACK', START_AUTHENTICATION = 'START_AUTHENTICATION', - + SUCCESS = 'SUCCESS', FAILED = 'FAILED', - EXPIRED = 'EXPIRED' -} \ No newline at end of file + EXPIRED = 'EXPIRED', +} diff --git a/database/src/enum/RoleNames.ts b/database/src/enum/RoleNames.ts index dda8eaa8a..19deed4d4 100644 --- a/database/src/enum/RoleNames.ts +++ b/database/src/enum/RoleNames.ts @@ -5,4 +5,4 @@ export enum RoleNames { MODERATOR_AI = 'MODERATOR_AI', ADMIN = 'ADMIN', DLT_CONNECTOR = 'DLT_CONNECTOR_ROLE', -} \ No newline at end of file +} diff --git a/database/src/enum/index.ts b/database/src/enum/index.ts index df243acf3..1c304e22d 100644 --- a/database/src/enum/index.ts +++ b/database/src/enum/index.ts @@ -1,6 +1,6 @@ export * from './CommunityHandshakeStateType' -export * from './ContributionType' -export * from './ContributionStatus' -export * from './TransactionTypeId' export * from './ContributionCycleType' -export * from './RoleNames' \ No newline at end of file +export * from './ContributionStatus' +export * from './ContributionType' +export * from './RoleNames' +export * from './TransactionTypeId' diff --git a/database/src/index.ts b/database/src/index.ts index b062add6d..5276b6ac8 100644 --- a/database/src/index.ts +++ b/database/src/index.ts @@ -1,9 +1,9 @@ import { latestDbVersion } from './detectLastDBVersion' export { latestDbVersion } +export { AppDatabase } from './AppDatabase' export * from './entity' +export * from './enum' export * from './logging' export * from './queries' -export * from './seeds' -export * from './enum' -export { AppDatabase } from './AppDatabase' +export * from './seeds' diff --git a/database/src/logging/AbstractLogging.view.ts b/database/src/logging/AbstractLogging.view.ts index 00fdd4703..7e1616c65 100644 --- a/database/src/logging/AbstractLogging.view.ts +++ b/database/src/logging/AbstractLogging.view.ts @@ -1,6 +1,5 @@ -import util from 'util' - import { Decimal } from 'decimal.js-light' +import util from 'util' export abstract class AbstractLoggingView { protected bufferStringFormat: BufferEncoding = 'hex' diff --git a/database/src/logging/CommunityHandshakeStateLogging.view.ts b/database/src/logging/CommunityHandshakeStateLogging.view.ts index b7df2452d..0edbe851e 100644 --- a/database/src/logging/CommunityHandshakeStateLogging.view.ts +++ b/database/src/logging/CommunityHandshakeStateLogging.view.ts @@ -11,11 +11,11 @@ export class CommunityHandshakeStateLoggingView extends AbstractLoggingView { id: this.self.id, handshakeId: this.self.handshakeId, oneTimeCode: this.self.oneTimeCode, - publicKey: this.self.publicKey.toString(this.bufferStringFormat), + publicKey: this.self.publicKey.toString(this.bufferStringFormat), status: this.self.status, lastError: this.self.lastError, createdAt: this.dateToString(this.self.createdAt), - updatedAt: this.dateToString(this.self.updatedAt), + updatedAt: this.dateToString(this.self.updatedAt), } } -} \ No newline at end of file +} diff --git a/database/src/logging/CommunityLogging.view.ts b/database/src/logging/CommunityLogging.view.ts index 1d675828c..3bb36d205 100644 --- a/database/src/logging/CommunityLogging.view.ts +++ b/database/src/logging/CommunityLogging.view.ts @@ -1,6 +1,6 @@ import { Community } from '../entity' -import { FederatedCommunityLoggingView } from './FederatedCommunityLogging.view' import { AbstractLoggingView } from './AbstractLogging.view' +import { FederatedCommunityLoggingView } from './FederatedCommunityLogging.view' export class CommunityLoggingView extends AbstractLoggingView { public constructor(private self: Community) { @@ -22,7 +22,7 @@ export class CommunityLoggingView extends AbstractLoggingView { createdAt: this.dateToString(this.self.createdAt), updatedAt: this.dateToString(this.self.updatedAt), federatedCommunities: this.self.federatedCommunities?.map( - (federatedCommunity) => new FederatedCommunityLoggingView(federatedCommunity) + (federatedCommunity) => new FederatedCommunityLoggingView(federatedCommunity), ), } } diff --git a/database/src/logging/PendingTransactionLogging.view.ts b/database/src/logging/PendingTransactionLogging.view.ts index fad2d8f56..20e08e662 100644 --- a/database/src/logging/PendingTransactionLogging.view.ts +++ b/database/src/logging/PendingTransactionLogging.view.ts @@ -1,7 +1,7 @@ +import { PendingTransactionState } from 'shared' import { PendingTransaction, Transaction } from '../entity' import { AbstractLoggingView } from './AbstractLogging.view' import { TransactionLoggingView } from './TransactionLogging.view' -import { PendingTransactionState } from 'shared' export class PendingTransactionLoggingView extends AbstractLoggingView { public constructor(private self: PendingTransaction) { diff --git a/database/src/logging/index.ts b/database/src/logging/index.ts index 522fc3b56..f3aa4a8ce 100644 --- a/database/src/logging/index.ts +++ b/database/src/logging/index.ts @@ -1,6 +1,7 @@ import { getLogger } from 'log4js' import { LOG4JS_BASE_CATEGORY_NAME } from '../config/const' import { AbstractLoggingView } from './AbstractLogging.view' +import { CommunityHandshakeStateLoggingView } from './CommunityHandshakeStateLogging.view' import { CommunityLoggingView } from './CommunityLogging.view' import { ContributionLoggingView } from './ContributionLogging.view' import { ContributionMessageLoggingView } from './ContributionMessageLogging.view' @@ -11,7 +12,6 @@ import { TransactionLoggingView } from './TransactionLogging.view' import { UserContactLoggingView } from './UserContactLogging.view' import { UserLoggingView } from './UserLogging.view' import { UserRoleLoggingView } from './UserRoleLogging.view' -import { CommunityHandshakeStateLoggingView } from './CommunityHandshakeStateLogging.view' export { AbstractLoggingView, diff --git a/database/src/queries/communities.test.ts b/database/src/queries/communities.test.ts index 1f5135994..4e8440490 100644 --- a/database/src/queries/communities.test.ts +++ b/database/src/queries/communities.test.ts @@ -1,13 +1,13 @@ +import { Ed25519PublicKey } from 'shared' import { Community as DbCommunity, FederatedCommunity as DbFederatedCommunity } from '..' import { AppDatabase } from '../AppDatabase' -import { - getCommunityByPublicKeyOrFail, - getHomeCommunity, - getHomeCommunityWithFederatedCommunityOrFail, - getReachableCommunities -} from './communities' import { createCommunity, createVerifiedFederatedCommunity } from '../seeds/community' -import { Ed25519PublicKey } from 'shared' +import { + getCommunityByPublicKeyOrFail, + getHomeCommunity, + getHomeCommunityWithFederatedCommunityOrFail, + getReachableCommunities, +} from './communities' const db = AppDatabase.getInstance() @@ -48,7 +48,7 @@ describe('community.queries', () => { it('should return the home community with federated communities', async () => { const homeCom = await createCommunity(false) await createVerifiedFederatedCommunity('1_0', 100, homeCom) - const community = await getHomeCommunityWithFederatedCommunityOrFail('1_0') + const community = await getHomeCommunityWithFederatedCommunityOrFail('1_0') expect(community).toBeDefined() expect(community?.federatedCommunities).toHaveLength(1) }) @@ -74,7 +74,7 @@ describe('community.queries', () => { expect(communityByPublicKey?.communityUuid).toBe(homeCom.communityUuid) }) }) - describe('getReachableCommunities', () => { + describe('getReachableCommunities', () => { it('home community counts also to reachable communities', async () => { await createCommunity(false) expect(await getReachableCommunities(1000)).toHaveLength(1) @@ -121,4 +121,4 @@ describe('community.queries', () => { expect(await getReachableCommunities(1000)).toHaveLength(0) }) }) -}) \ No newline at end of file +}) diff --git a/database/src/queries/communities.ts b/database/src/queries/communities.ts index fee69b27e..83e8933d0 100644 --- a/database/src/queries/communities.ts +++ b/database/src/queries/communities.ts @@ -1,6 +1,6 @@ +import { Ed25519PublicKey, urlSchema, uuidv4Schema } from 'shared' import { FindOptionsOrder, FindOptionsWhere, IsNull, MoreThanOrEqual, Not } from 'typeorm' import { Community as DbCommunity } from '../entity' -import { Ed25519PublicKey, urlSchema, uuidv4Schema } from 'shared' /** * Retrieves the home community, i.e., a community that is not foreign. @@ -10,11 +10,13 @@ export async function getHomeCommunity(): Promise { // TODO: Put in Cache, it is needed nearly always // TODO: return only DbCommunity or throw to reduce unnecessary checks, because there should be always a home community return await DbCommunity.findOne({ - where: { foreign: false } + where: { foreign: false }, }) } -export async function getHomeCommunityWithFederatedCommunityOrFail(apiVersion: string): Promise { +export async function getHomeCommunityWithFederatedCommunityOrFail( + apiVersion: string, +): Promise { return await DbCommunity.findOneOrFail({ where: { foreign: false, federatedCommunities: { apiVersion } }, relations: { federatedCommunities: true }, @@ -27,7 +29,9 @@ export async function getCommunityByUuid(communityUuid: string): Promise { +export function findWithCommunityIdentifier( + communityIdentifier: string, +): FindOptionsWhere { const where: FindOptionsWhere = {} // pre filter identifier type to reduce db query complexity if (urlSchema.safeParse(communityIdentifier).success) { @@ -51,7 +55,7 @@ export async function getCommunityWithFederatedCommunityByIdentifier( export async function getCommunityWithFederatedCommunityWithApiOrFail( publicKey: Ed25519PublicKey, - apiVersion: string + apiVersion: string, ): Promise { return await DbCommunity.findOneOrFail({ where: { foreign: true, publicKey: publicKey.asBuffer(), federatedCommunities: { apiVersion } }, @@ -59,25 +63,27 @@ export async function getCommunityWithFederatedCommunityWithApiOrFail( }) } -export async function getCommunityByPublicKeyOrFail(publicKey: Ed25519PublicKey): Promise { +export async function getCommunityByPublicKeyOrFail( + publicKey: Ed25519PublicKey, +): Promise { return await DbCommunity.findOneOrFail({ where: { publicKey: publicKey.asBuffer() }, }) } -// returns all reachable communities +// returns all reachable communities // home community and all federated communities which have been verified within the last authenticationTimeoutMs export async function getReachableCommunities( authenticationTimeoutMs: number, - order?: FindOptionsOrder + order?: FindOptionsOrder, ): Promise { return await DbCommunity.find({ - where: [ - { - authenticatedAt: Not(IsNull()), - federatedCommunities: { + where: [ + { + authenticatedAt: Not(IsNull()), + federatedCommunities: { verifiedAt: MoreThanOrEqual(new Date(Date.now() - authenticationTimeoutMs)), - } + }, }, { foreign: false }, ], @@ -86,10 +92,10 @@ export async function getReachableCommunities( } export async function getNotReachableCommunities( - order?: FindOptionsOrder + order?: FindOptionsOrder, ): Promise { return await DbCommunity.find({ where: { authenticatedAt: IsNull(), foreign: true }, order, }) -} \ No newline at end of file +} diff --git a/database/src/queries/communityHandshakes.test.ts b/database/src/queries/communityHandshakes.test.ts index c1b665bab..02750cbd9 100644 --- a/database/src/queries/communityHandshakes.test.ts +++ b/database/src/queries/communityHandshakes.test.ts @@ -1,14 +1,14 @@ -import { AppDatabase } from '../AppDatabase' -import { - CommunityHandshakeState as DbCommunityHandshakeState, - Community as DbCommunity, - FederatedCommunity as DbFederatedCommunity, - findPendingCommunityHandshake, - CommunityHandshakeStateType -} from '..' -import { createCommunity, createVerifiedFederatedCommunity } from '../seeds/community' -import { Ed25519PublicKey } from 'shared' import { randomBytes } from 'node:crypto' +import { Ed25519PublicKey } from 'shared' +import { + CommunityHandshakeStateType, + Community as DbCommunity, + CommunityHandshakeState as DbCommunityHandshakeState, + FederatedCommunity as DbFederatedCommunity, + findPendingCommunityHandshake, +} from '..' +import { AppDatabase } from '../AppDatabase' +import { createCommunity, createVerifiedFederatedCommunity } from '../seeds/community' const db = AppDatabase.getInstance() @@ -40,14 +40,17 @@ describe('communityHandshakes', () => { const com1 = await createCommunity(false) await createVerifiedFederatedCommunity('1_0', 100, com1) await createCommunityHandshakeState(com1.publicKey) - const communityHandshakeState = await findPendingCommunityHandshake(new Ed25519PublicKey(com1.publicKey), '1_0') + const communityHandshakeState = await findPendingCommunityHandshake( + new Ed25519PublicKey(com1.publicKey), + '1_0', + ) expect(communityHandshakeState).toBeDefined() expect(communityHandshakeState).toMatchObject({ publicKey: com1.publicKey, apiVersion: '1_0', status: CommunityHandshakeStateType.START_COMMUNITY_AUTHENTICATION, - handshakeId: 1 - }) + handshakeId: 1, + }) }) it('update state', async () => { @@ -55,7 +58,7 @@ describe('communityHandshakes', () => { await createCommunityHandshakeState(publicKey.asBuffer()) const communityHandshakeState = await findPendingCommunityHandshake(publicKey, '1_0') expect(communityHandshakeState).toBeDefined() - communityHandshakeState!.status = CommunityHandshakeStateType.START_OPEN_CONNECTION_CALLBACK + communityHandshakeState!.status = CommunityHandshakeStateType.START_OPEN_CONNECTION_CALLBACK await communityHandshakeState!.save() const communityHandshakeState2 = await findPendingCommunityHandshake(publicKey, '1_0') expect(communityHandshakeState2).toBeDefined() @@ -63,7 +66,7 @@ describe('communityHandshakes', () => { publicKey: publicKey.asBuffer(), apiVersion: '1_0', status: CommunityHandshakeStateType.START_OPEN_CONNECTION_CALLBACK, - handshakeId: 1 + handshakeId: 1, }) }) -}) \ No newline at end of file +}) diff --git a/database/src/queries/communityHandshakes.ts b/database/src/queries/communityHandshakes.ts index 9dc83118b..2ac8e32c1 100644 --- a/database/src/queries/communityHandshakes.ts +++ b/database/src/queries/communityHandshakes.ts @@ -1,6 +1,6 @@ -import { Not, In } from 'typeorm' -import { CommunityHandshakeState, CommunityHandshakeStateType} from '..' import { Ed25519PublicKey } from 'shared' +import { In, Not } from 'typeorm' +import { CommunityHandshakeState, CommunityHandshakeStateType } from '..' /** * Find a pending community handshake by public key. @@ -10,26 +10,31 @@ import { Ed25519PublicKey } from 'shared' * @returns The CommunityHandshakeState with associated federated community and community. */ export function findPendingCommunityHandshake( - publicKey: Ed25519PublicKey, apiVersion: string, status?: CommunityHandshakeStateType + publicKey: Ed25519PublicKey, + apiVersion: string, + status?: CommunityHandshakeStateType, ): Promise { return CommunityHandshakeState.findOne({ - where: { - publicKey: publicKey.asBuffer(), + where: { + publicKey: publicKey.asBuffer(), apiVersion, - status: status || Not(In([ - CommunityHandshakeStateType.EXPIRED, - CommunityHandshakeStateType.FAILED, - CommunityHandshakeStateType.SUCCESS - ])) + status: + status || + Not( + In([ + CommunityHandshakeStateType.EXPIRED, + CommunityHandshakeStateType.FAILED, + CommunityHandshakeStateType.SUCCESS, + ]), + ), }, }) } export function findPendingCommunityHandshakeOrFailByOneTimeCode( - oneTimeCode: number + oneTimeCode: number, ): Promise { return CommunityHandshakeState.findOneOrFail({ where: { oneTimeCode }, }) } - \ No newline at end of file diff --git a/database/src/queries/index.ts b/database/src/queries/index.ts index 2cd0164ce..112f82466 100644 --- a/database/src/queries/index.ts +++ b/database/src/queries/index.ts @@ -1,11 +1,11 @@ import { LOG4JS_BASE_CATEGORY_NAME } from '../config/const' -export * from './user' export * from './communities' +export * from './communityHandshakes' export * from './events' export * from './pendingTransactions' -export * from './transactions' export * from './transactionLinks' -export * from './communityHandshakes' +export * from './transactions' +export * from './user' export const LOG4JS_QUERIES_CATEGORY_NAME = `${LOG4JS_BASE_CATEGORY_NAME}.queries` diff --git a/database/src/queries/pendingTransactions.test.ts b/database/src/queries/pendingTransactions.test.ts index a4765dcee..d8215db33 100644 --- a/database/src/queries/pendingTransactions.test.ts +++ b/database/src/queries/pendingTransactions.test.ts @@ -1,21 +1,21 @@ -import { - PendingTransaction as DbPendingTransaction, - User as DbUser, - UserContact as DbUserContact, - Community as DbCommunity -} from '..' -import { countOpenPendingTransactions } from './pendingTransactions' +import Decimal from 'decimal.js-light' import { PendingTransactionState } from 'shared' +import { v4 as uuidv4 } from 'uuid' +import { + Community as DbCommunity, + PendingTransaction as DbPendingTransaction, + User as DbUser, + UserContact as DbUserContact, +} from '..' import { AppDatabase } from '../AppDatabase' -import { userFactory } from '../seeds/factory/user' +import { createCommunity } from '../seeds/community' import { pendingTransactionFactory } from '../seeds/factory/pendingTransaction' +import { userFactory } from '../seeds/factory/user' import { bibiBloxberg } from '../seeds/users/bibi-bloxberg' -import { peterLustig } from '../seeds/users/peter-lustig' import { bobBaumeister } from '../seeds/users/bob-baumeister' import { garrickOllivander } from '../seeds/users/garrick-ollivander' -import { createCommunity } from '../seeds/community' -import { v4 as uuidv4 } from 'uuid' -import Decimal from 'decimal.js-light' +import { peterLustig } from '../seeds/users/peter-lustig' +import { countOpenPendingTransactions } from './pendingTransactions' const db = AppDatabase.getInstance() @@ -26,7 +26,6 @@ afterAll(async () => { await db.destroy() }) - describe('countOpenPendingTransactions', () => { let bibi: DbUser let peter: DbUser @@ -40,45 +39,44 @@ describe('countOpenPendingTransactions', () => { await createCommunity(false) - bibi = await userFactory(bibiBloxberg) + bibi = await userFactory(bibiBloxberg) peter = await userFactory(peterLustig) bob = await userFactory(bobBaumeister) garrick = await userFactory(garrickOllivander) // Bibi -> Peter await pendingTransactionFactory( - bibi, - peter, - new Decimal(10), - 'Bibi -> Peter new', - PendingTransactionState.NEW + bibi, + peter, + new Decimal(10), + 'Bibi -> Peter new', + PendingTransactionState.NEW, ) await pendingTransactionFactory( - bibi, - peter, - new Decimal(100.01), - 'Bibi -> Peter settled', - PendingTransactionState.SETTLED + bibi, + peter, + new Decimal(100.01), + 'Bibi -> Peter settled', + PendingTransactionState.SETTLED, ) // Peter -> Bibi await pendingTransactionFactory( - peter, - bibi, - new Decimal(12), - 'Peter -> Bibi new', - PendingTransactionState.NEW + peter, + bibi, + new Decimal(12), + 'Peter -> Bibi new', + PendingTransactionState.NEW, ) // Bob -> Peter await pendingTransactionFactory( - bob, - peter, - new Decimal(17.1), - 'Bob -> Peter new', - PendingTransactionState.NEW + bob, + peter, + new Decimal(17.1), + 'Bob -> Peter new', + PendingTransactionState.NEW, ) - }) it('should return 0 if called with empty array', async () => { const count = await countOpenPendingTransactions([]) @@ -103,21 +101,20 @@ describe('countOpenPendingTransactions', () => { it('peter and bob have one transaction together, peter two additional, should return 3', async () => { const count = await countOpenPendingTransactions([peter.gradidoID, bob.gradidoID]) expect(count).toBe(3) - }) - + }) + it('peter has three transactions, should return 3', async () => { const count = await countOpenPendingTransactions([peter.gradidoID]) expect(count).toBe(3) - }) - + }) it('bibi has two transactions, should return 2', async () => { const count = await countOpenPendingTransactions([bibi.gradidoID]) expect(count).toBe(2) - }) + }) it('bob has one transaction, should return 1', async () => { const count = await countOpenPendingTransactions([bob.gradidoID]) expect(count).toBe(1) - }) + }) }) diff --git a/database/src/queries/pendingTransactions.ts b/database/src/queries/pendingTransactions.ts index 44bf63f82..b6481af33 100644 --- a/database/src/queries/pendingTransactions.ts +++ b/database/src/queries/pendingTransactions.ts @@ -1,6 +1,6 @@ -import { PendingTransaction as DbPendingTransaction } from '../entity' -import { In } from 'typeorm' import { PendingTransactionState } from 'shared' +import { In } from 'typeorm' +import { PendingTransaction as DbPendingTransaction } from '../entity' /** * Counts the number of open pending transactions for the given users. @@ -15,4 +15,4 @@ export async function countOpenPendingTransactions(users: string[]): Promise { return await DbTransactionLink.findOneOrFail({ diff --git a/database/src/queries/user.test.ts b/database/src/queries/user.test.ts index 6348c01d8..163cbaaea 100644 --- a/database/src/queries/user.test.ts +++ b/database/src/queries/user.test.ts @@ -1,13 +1,13 @@ -import { User as DbUser, UserContact as DbUserContact, Community as DbCommunity } from '..' +import { clearLogs, getLogger, printLogs } from '../../../config-schema/test/testSetup.bun' +import { Community as DbCommunity, User as DbUser, UserContact as DbUserContact } from '..' import { AppDatabase } from '../AppDatabase' -import { aliasExists, findUserByIdentifier } from './user' +import { createCommunity } from '../seeds/community' import { userFactory } from '../seeds/factory/user' import { bibiBloxberg } from '../seeds/users/bibi-bloxberg' -import { createCommunity } from '../seeds/community' -import { peterLustig } from '../seeds/users/peter-lustig' import { bobBaumeister } from '../seeds/users/bob-baumeister' -import { getLogger, printLogs, clearLogs } from '../../../config-schema/test/testSetup.bun' +import { peterLustig } from '../seeds/users/peter-lustig' import { LOG4JS_QUERIES_CATEGORY_NAME } from '.' +import { aliasExists, findUserByIdentifier } from './user' const db = AppDatabase.getInstance() const userIdentifierLoggerName = `${LOG4JS_QUERIES_CATEGORY_NAME}.user.findUserByIdentifier` @@ -25,9 +25,9 @@ describe('user.queries', () => { await DbUser.clear() await DbUserContact.clear() - const bibi = bibiBloxberg + const bibi = bibiBloxberg bibi.alias = 'b-b' - await userFactory(bibi) + await userFactory(bibi) }) it('should return true if alias exists', async () => { @@ -69,12 +69,12 @@ describe('user.queries', () => { const user = await findUserByIdentifier(userBibi.gradidoID, communityUuid) expect(user).toMatchObject(userBibi) }) - + it('userIdentifier is alias', async () => { const user = await findUserByIdentifier(userBibi.alias, communityUuid) expect(user).toMatchObject(userBibi) }) - + it('userIdentifier is email', async () => { const user = await findUserByIdentifier(userBibi.emailContact.email, communityUuid) expect(user).toMatchObject(userBibi) @@ -84,18 +84,18 @@ describe('user.queries', () => { expect(user).toBeNull() }) }) - + describe('communityIdentifier is community name', () => { it('userIdentifier is gradido id', async () => { const user = await findUserByIdentifier(userBibi.gradidoID, communityName) expect(user).toMatchObject(userBibi) }) - + it('userIdentifier is alias', async () => { const user = await findUserByIdentifier(userBibi.alias, communityName) expect(user).toMatchObject(userBibi) }) - + it('userIdentifier is email', async () => { const user = await findUserByIdentifier(userBibi.emailContact.email, communityName) expect(user).toMatchObject(userBibi) @@ -116,12 +116,12 @@ describe('user.queries', () => { const user = await findUserByIdentifier(userBibi.gradidoID) expect(user).toMatchObject(userBibi) }) - + it('userIdentifier is alias', async () => { const user = await findUserByIdentifier(userBibi.alias) expect(user).toMatchObject(userBibi) }) - + it('userIdentifier is email', async () => { const user = await findUserByIdentifier(userBibi.emailContact.email) expect(user).toMatchObject(userBibi) @@ -129,11 +129,12 @@ describe('user.queries', () => { it('userIdentifier is unknown type', async () => { const user = await findUserByIdentifier('sa') printLogs() - expect(getLogger(userIdentifierLoggerName).warn).toHaveBeenCalledWith('Unknown identifier type', 'sa') + expect(getLogger(userIdentifierLoggerName).warn).toHaveBeenCalledWith( + 'Unknown identifier type', + 'sa', + ) expect(user).toBeNull() }) - }) + }) }) }) - - diff --git a/database/src/queries/user.ts b/database/src/queries/user.ts index c117c9ff8..9e7d84c27 100644 --- a/database/src/queries/user.ts +++ b/database/src/queries/user.ts @@ -1,7 +1,7 @@ +import { getLogger } from 'log4js' +import { aliasSchema, emailSchema, uuidv4Schema } from 'shared' import { Raw } from 'typeorm' import { User as DbUser, UserContact as DbUserContact } from '../entity' -import { aliasSchema, emailSchema, uuidv4Schema } from 'shared' -import { getLogger } from 'log4js' import { findWithCommunityIdentifier, LOG4JS_QUERIES_CATEGORY_NAME } from './index' export async function aliasExists(alias: string): Promise { @@ -32,8 +32,8 @@ export const findUserByIdentifier = async ( identifier: string, communityIdentifier?: string, ): Promise => { - const communityWhere = communityIdentifier - ? findWithCommunityIdentifier(communityIdentifier) + const communityWhere = communityIdentifier + ? findWithCommunityIdentifier(communityIdentifier) : undefined if (uuidv4Schema.safeParse(identifier).success) { @@ -52,12 +52,12 @@ export const findUserByIdentifier = async ( }, relations: { user: { community: true } }, }) - if (userContact) { + if (userContact) { // TODO: remove circular reference const user = userContact.user user.emailContact = userContact return user - } + } } else if (aliasSchema.safeParse(identifier).success) { return await DbUser.findOne({ where: { alias: identifier, community: communityWhere }, @@ -65,7 +65,10 @@ export const findUserByIdentifier = async ( }) } else { // should don't happen often, so we create only in the rare case a logger for it - getLogger(`${LOG4JS_QUERIES_CATEGORY_NAME}.user.findUserByIdentifier`).warn('Unknown identifier type', identifier) + getLogger(`${LOG4JS_QUERIES_CATEGORY_NAME}.user.findUserByIdentifier`).warn( + 'Unknown identifier type', + identifier, + ) } return null } diff --git a/database/src/seeds/community.ts b/database/src/seeds/community.ts index 12a5bd67f..32591eba3 100644 --- a/database/src/seeds/community.ts +++ b/database/src/seeds/community.ts @@ -1,56 +1,56 @@ -import { Community, FederatedCommunity } from '../entity' import { randomBytes } from 'node:crypto' import { v4 as uuidv4 } from 'uuid' +import { Community, FederatedCommunity } from '../entity' /** * Creates a community. - * @param foreign + * @param foreign * @param store if true, write to db, default: true - * @returns + * @returns */ export async function createCommunity(foreign: boolean, store: boolean = true): Promise { - const community = new Community() - community.publicKey = randomBytes(32) - community.communityUuid = uuidv4() - community.name = 'HomeCommunity-name' - community.creationDate = new Date() + const community = new Community() + community.publicKey = randomBytes(32) + community.communityUuid = uuidv4() + community.name = 'HomeCommunity-name' + community.creationDate = new Date() - if(foreign) { - community.foreign = true - community.name = 'ForeignCommunity-name' - community.description = 'ForeignCommunity-description' - community.url = `http://foreign-${Math.random()}/api` - community.authenticatedAt = new Date() - } else { - community.foreign = false - // todo: generate valid public/private key pair (ed25519) - community.privateKey = randomBytes(64) - community.name = 'HomeCommunity-name' - community.description = 'HomeCommunity-description' - community.url = 'http://localhost/api' - } - return store ? await community.save() : community + if (foreign) { + community.foreign = true + community.name = 'ForeignCommunity-name' + community.description = 'ForeignCommunity-description' + community.url = `http://foreign-${Math.random()}/api` + community.authenticatedAt = new Date() + } else { + community.foreign = false + // todo: generate valid public/private key pair (ed25519) + community.privateKey = randomBytes(64) + community.name = 'HomeCommunity-name' + community.description = 'HomeCommunity-description' + community.url = 'http://localhost/api' + } + return store ? await community.save() : community } /** * Creates a verified federated community. - * @param apiVersion + * @param apiVersion * @param verifiedBeforeMs time in ms before the current time - * @param community + * @param community * @param store if true, write to db, default: true - * @returns + * @returns */ export async function createVerifiedFederatedCommunity( - apiVersion: string, - verifiedBeforeMs: number, - community: Community, - store: boolean = true + apiVersion: string, + verifiedBeforeMs: number, + community: Community, + store: boolean = true, ): Promise { - const federatedCommunity = new FederatedCommunity() - federatedCommunity.apiVersion = apiVersion - federatedCommunity.endPoint = community.url - federatedCommunity.publicKey = community.publicKey - federatedCommunity.community = community - federatedCommunity.verifiedAt = new Date(Date.now() - verifiedBeforeMs) - return store ? await federatedCommunity.save() : federatedCommunity + const federatedCommunity = new FederatedCommunity() + federatedCommunity.apiVersion = apiVersion + federatedCommunity.endPoint = community.url + federatedCommunity.publicKey = community.publicKey + federatedCommunity.community = community + federatedCommunity.verifiedAt = new Date(Date.now() - verifiedBeforeMs) + return store ? await federatedCommunity.save() : federatedCommunity } diff --git a/database/src/seeds/factory/contributionLink.ts b/database/src/seeds/factory/contributionLink.ts index c05888568..27d301a93 100644 --- a/database/src/seeds/factory/contributionLink.ts +++ b/database/src/seeds/factory/contributionLink.ts @@ -1,20 +1,23 @@ import Decimal from 'decimal.js-light' import { ContributionLink } from '../../entity' - +import { ContributionCycleType } from '../../enum' import { ContributionLinkInterface } from '../contributionLink/ContributionLinkInterface' import { transactionLinkCode } from './transactionLink' -import { ContributionCycleType } from '../../enum' -export function contributionLinkFactory(contributionLink: ContributionLinkInterface): Promise { +export function contributionLinkFactory( + contributionLink: ContributionLinkInterface, +): Promise { return createContributionLink(contributionLink) } -export function createContributionLink(contributionLinkData: ContributionLinkInterface): Promise { +export function createContributionLink( + contributionLinkData: ContributionLinkInterface, +): Promise { const contributionLink = new ContributionLink() contributionLink.amount = new Decimal(contributionLinkData.amount) contributionLink.name = contributionLinkData.name contributionLink.memo = contributionLinkData.memo - contributionLink.createdAt = new Date() + contributionLink.createdAt = new Date() contributionLink.code = transactionLinkCode(new Date()) contributionLink.cycle = ContributionCycleType.ONCE if (contributionLinkData.validFrom) { @@ -25,7 +28,6 @@ export function createContributionLink(contributionLinkData: ContributionLinkInt } contributionLink.maxAmountPerMonth = new Decimal(200) contributionLink.maxPerCycle = 1 - + return contributionLink.save() } - \ No newline at end of file diff --git a/database/src/seeds/factory/creation.ts b/database/src/seeds/factory/creation.ts index 8870a717f..f8a45be4f 100644 --- a/database/src/seeds/factory/creation.ts +++ b/database/src/seeds/factory/creation.ts @@ -1,10 +1,10 @@ -import { Contribution, Transaction, User } from '../../entity' import { Decimal } from 'decimal.js-light' -import { CreationInterface } from '../creation/CreationInterface' -import { ContributionType, ContributionStatus, TransactionTypeId } from '../../enum' -import { findUserByIdentifier } from '../../queries' -import { createTransaction } from './transaction' import { AppDatabase } from '../../AppDatabase' +import { Contribution, Transaction, User } from '../../entity' +import { ContributionStatus, ContributionType, TransactionTypeId } from '../../enum' +import { findUserByIdentifier } from '../../queries' +import { CreationInterface } from '../creation/CreationInterface' +import { createTransaction } from './transaction' export function nMonthsBefore(date: Date, months = 1): string { return new Date(date.getFullYear(), date.getMonth() - months, 1).toISOString() @@ -21,7 +21,7 @@ export async function creationFactory( if (!user) { throw new Error(`User ${creation.email} not found`) } - let contribution = await createContribution(creation, user) + const contribution = await createContribution(creation, user) if (creation.confirmed) { if (!moderatorUser) { moderatorUser = await findUserByIdentifier('peter@lustig.de') @@ -39,7 +39,11 @@ export async function creationFactoryBulk( userCreationIndexedByEmail: Map, moderatorUser: User, ): Promise { - const lastTransaction = await Transaction.findOne({ order: { id: 'DESC' }, select: ['id'], where: {} }) + const lastTransaction = await Transaction.findOne({ + order: { id: 'DESC' }, + select: ['id'], + where: {}, + }) let transactionId = lastTransaction ? lastTransaction.id + 1 : 1 const dbContributions: Contribution[] = [] const dbTransactions: Transaction[] = [] @@ -49,14 +53,14 @@ export async function creationFactoryBulk( if (!user) { throw new Error(`User ${creation.email} not found`) } - let contribution = await createContribution(creation, user, false) + const contribution = await createContribution(creation, user, false) if (creation.confirmed) { const { contribution: _, transaction } = await confirmTransaction( - creation, - contribution, - moderatorUser, - transactionId, - false + creation, + contribution, + moderatorUser, + transactionId, + false, ) dbTransactions.push(transaction) transactionId++ @@ -66,12 +70,16 @@ export async function creationFactoryBulk( const dataSource = AppDatabase.getInstance().getDataSource() await dataSource.transaction(async (transaction) => { await dataSource.getRepository(Contribution).insert(dbContributions) - await dataSource.getRepository(Transaction).insert(dbTransactions) + await dataSource.getRepository(Transaction).insert(dbTransactions) }) return dbContributions } -export async function createContribution(creation: CreationInterface, user: User, store: boolean = true): Promise { +export async function createContribution( + creation: CreationInterface, + user: User, + store: boolean = true, +): Promise { const contribution = new Contribution() contribution.user = user contribution.userId = user.id @@ -81,17 +89,17 @@ export async function createContribution(creation: CreationInterface, user: User contribution.memo = creation.memo contribution.contributionType = ContributionType.USER contribution.contributionStatus = ContributionStatus.PENDING - + return store ? contribution.save() : contribution } export async function confirmTransaction( creation: CreationInterface, - contribution: Contribution, - moderatorUser: User, - transactionId?: number, - store: boolean = true -): Promise<{ contribution: Contribution, transaction: Transaction }> { + contribution: Contribution, + moderatorUser: User, + transactionId?: number, + store: boolean = true, +): Promise<{ contribution: Contribution; transaction: Transaction }> { const balanceDate = getBalanceDate(creation) const transaction = await createTransaction( contribution.amount, @@ -117,10 +125,10 @@ export async function confirmTransaction( return { contribution, transaction } } - + function getContributionDate(creation: CreationInterface): Date { if (creation.moveCreationDate) { - return new Date(nMonthsBefore(new Date(creation.contributionDate), creation.moveCreationDate)) + return new Date(nMonthsBefore(new Date(creation.contributionDate), creation.moveCreationDate)) } return new Date(creation.contributionDate) } @@ -128,7 +136,7 @@ function getContributionDate(creation: CreationInterface): Date { function getBalanceDate(creation: CreationInterface): Date { const now = new Date() if (creation.moveCreationDate) { - return new Date(nMonthsBefore(now, creation.moveCreationDate)) + return new Date(nMonthsBefore(now, creation.moveCreationDate)) } return now -} \ No newline at end of file +} diff --git a/database/src/seeds/factory/pendingTransaction.ts b/database/src/seeds/factory/pendingTransaction.ts index 2e8c7d256..75cb7c70e 100644 --- a/database/src/seeds/factory/pendingTransaction.ts +++ b/database/src/seeds/factory/pendingTransaction.ts @@ -1,6 +1,6 @@ -import { User as DbUser, PendingTransaction as DbPendingTransaction } from '../..' -import { PendingTransactionState } from 'shared' import { Decimal } from 'decimal.js-light' +import { PendingTransactionState } from 'shared' +import { PendingTransaction as DbPendingTransaction, User as DbUser } from '../..' export async function pendingTransactionFactory( sender: DbUser, @@ -17,7 +17,7 @@ export async function pendingTransactionFactory( pendingTransaction.userGradidoID = sender.gradidoID pendingTransaction.userCommunityUuid = sender.communityUuid! pendingTransaction.linkedUserId = receiver.id - pendingTransaction.linkedUserGradidoID = receiver.gradidoID - pendingTransaction.linkedUserCommunityUuid = receiver.communityUuid! + pendingTransaction.linkedUserGradidoID = receiver.gradidoID + pendingTransaction.linkedUserCommunityUuid = receiver.communityUuid! await pendingTransaction.save() } diff --git a/database/src/seeds/factory/transaction.ts b/database/src/seeds/factory/transaction.ts index 02a56723e..ed6292e9f 100644 --- a/database/src/seeds/factory/transaction.ts +++ b/database/src/seeds/factory/transaction.ts @@ -1,9 +1,8 @@ import Decimal from 'decimal.js-light' -import { User, Transaction } from '../../entity' +import { calculateDecay, Decay, fullName } from 'shared' +import { Transaction, User } from '../../entity' import { TransactionTypeId } from '../../enum' -import { fullName } from 'shared' import { getLastTransaction } from '../../queries' -import { calculateDecay, Decay } from 'shared' export async function createTransaction( amount: Decimal, @@ -13,20 +12,15 @@ export async function createTransaction( type: TransactionTypeId, balanceDate: Date, creationDate?: Date, - id?: number, + id?: number, store: boolean = true, ): Promise { - const lastTransaction = await getLastTransaction(user.id) // balance and decay calculation let newBalance = new Decimal(0) let decay: Decay | null = null if (lastTransaction) { - decay = calculateDecay( - lastTransaction.balance, - lastTransaction.balanceDate, - balanceDate, - ) + decay = calculateDecay(lastTransaction.balance, lastTransaction.balanceDate, balanceDate) newBalance = decay.balance } newBalance = newBalance.add(amount.toString()) @@ -54,6 +48,6 @@ export async function createTransaction( transaction.balanceDate = balanceDate transaction.decay = decay ? decay.decay : new Decimal(0) transaction.decayStart = decay ? decay.start : null - + return store ? transaction.save() : transaction -} \ No newline at end of file +} diff --git a/database/src/seeds/factory/transactionLink.ts b/database/src/seeds/factory/transactionLink.ts index 956e33fb5..b657ead58 100644 --- a/database/src/seeds/factory/transactionLink.ts +++ b/database/src/seeds/factory/transactionLink.ts @@ -1,10 +1,10 @@ -import { TransactionLinkInterface } from '../transactionLink/TransactionLinkInterface' -import { TransactionLink, User } from '../../entity' -import { Decimal } from 'decimal.js-light' -import { findUserByIdentifier } from '../../queries' -import { compoundInterest } from 'shared' import { randomBytes } from 'node:crypto' +import { Decimal } from 'decimal.js-light' +import { compoundInterest } from 'shared' import { AppDatabase } from '../../AppDatabase' +import { TransactionLink, User } from '../../entity' +import { findUserByIdentifier } from '../../queries' +import { TransactionLinkInterface } from '../transactionLink/TransactionLinkInterface' export async function transactionLinkFactory( transactionLinkData: TransactionLinkInterface, @@ -21,8 +21,8 @@ export async function transactionLinkFactory( } export async function transactionLinkFactoryBulk( - transactionLinks: TransactionLinkInterface[], - userCreationIndexedByEmail: Map + transactionLinks: TransactionLinkInterface[], + userCreationIndexedByEmail: Map, ): Promise { const dbTransactionLinks: TransactionLink[] = [] for (const transactionLink of transactionLinks) { @@ -37,9 +37,16 @@ export async function transactionLinkFactoryBulk( return dbTransactionLinks } -export async function createTransactionLink(transactionLinkData: TransactionLinkInterface, userId: number, store: boolean = true): Promise { - const holdAvailableAmount = compoundInterest(new Decimal(transactionLinkData.amount.toString()), CODE_VALID_DAYS_DURATION * 24 * 60 * 60) - let createdAt = transactionLinkData.createdAt || new Date() +export async function createTransactionLink( + transactionLinkData: TransactionLinkInterface, + userId: number, + store: boolean = true, +): Promise { + const holdAvailableAmount = compoundInterest( + new Decimal(transactionLinkData.amount.toString()), + CODE_VALID_DAYS_DURATION * 24 * 60 * 60, + ) + const createdAt = transactionLinkData.createdAt || new Date() const validUntil = transactionLinkExpireDate(createdAt) const transactionLink = new TransactionLink() @@ -52,7 +59,7 @@ export async function createTransactionLink(transactionLinkData: TransactionLink transactionLink.validUntil = validUntil if (transactionLinkData.deletedAt) { - transactionLink.deletedAt = new Date(createdAt.getTime() + 1000) + transactionLink.deletedAt = new Date(createdAt.getTime() + 1000) } return store ? transactionLink.save() : transactionLink @@ -74,4 +81,4 @@ export const transactionLinkCode = (date: Date): string => { .toString('hex') .substring(0, 24 - time.length) + time ) -} \ No newline at end of file +} diff --git a/database/src/seeds/factory/user.ts b/database/src/seeds/factory/user.ts index 4d16c009e..df033c716 100644 --- a/database/src/seeds/factory/user.ts +++ b/database/src/seeds/factory/user.ts @@ -1,17 +1,19 @@ -import { UserInterface } from '../users/UserInterface' -import { User, UserContact, UserRole } from '../../entity' -import { v4 } from 'uuid' -import { UserContactType, OptInType, PasswordEncryptionType } from 'shared' -import { getHomeCommunity } from '../../queries/communities' import random from 'random-bigint' -import { Community } from '../../entity' +import { OptInType, PasswordEncryptionType, UserContactType } from 'shared' +import { v4 } from 'uuid' import { AppDatabase } from '../..' +import { Community, User, UserContact, UserRole } from '../../entity' import { RoleNames } from '../../enum/RoleNames' +import { getHomeCommunity } from '../../queries/communities' +import { UserInterface } from '../users/UserInterface' -export async function userFactory(user: UserInterface, homeCommunity?: Community | null): Promise { - // TODO: improve with cascade +export async function userFactory( + user: UserInterface, + homeCommunity?: Community | null, +): Promise { + // TODO: improve with cascade let dbUser = await createUser(user, homeCommunity) - let dbUserContact = await createUserContact(user, dbUser.id) + const dbUserContact = await createUserContact(user, dbUser.id) dbUser.emailId = dbUserContact.id dbUser.emailContact = dbUserContact dbUser = await dbUser.save() @@ -20,21 +22,28 @@ export async function userFactory(user: UserInterface, homeCommunity?: Community if (userRole && (userRole === RoleNames.ADMIN || userRole === RoleNames.MODERATOR)) { dbUser.userRoles = [await createUserRole(dbUser.id, userRole)] } - + return dbUser } // only use in non-parallel environment (seeding for example) -export async function userFactoryBulk(users: UserInterface[], homeCommunity?: Community | null): Promise { +export async function userFactoryBulk( + users: UserInterface[], + homeCommunity?: Community | null, +): Promise { const dbUsers: User[] = [] const dbUserContacts: UserContact[] = [] const dbUserRoles: UserRole[] = [] const lastUser = await User.findOne({ order: { id: 'DESC' }, select: ['id'], where: {} }) - const lastUserContact = await UserContact.findOne({ order: { id: 'DESC' }, select: ['id'], where: {} }) + const lastUserContact = await UserContact.findOne({ + order: { id: 'DESC' }, + select: ['id'], + where: {}, + }) let userId = lastUser ? lastUser.id + 1 : 1 let emailId = lastUserContact ? lastUserContact.id + 1 : 1 // console.log(`start with userId: ${userId} and emailId: ${emailId}`) - for(const user of users) { + for (const user of users) { const dbUser = await createUser(user, homeCommunity, false) dbUser.id = userId dbUser.emailId = emailId @@ -51,28 +60,32 @@ export async function userFactoryBulk(users: UserInterface[], homeCommunity?: Co if (userRole && (userRole === RoleNames.ADMIN || userRole === RoleNames.MODERATOR)) { dbUserRoles.push(await createUserRole(dbUser.id, userRole, false)) } - + userId++ emailId++ } const dataSource = AppDatabase.getInstance().getDataSource() - await dataSource.transaction(async transaction => { + await dataSource.transaction(async (transaction) => { // typeorm change my data what I don't want // because of manuel id assignment - const dbUsersCopy = dbUsers.map(user => ({ ...user })) - const dbUserContactsCopy = dbUserContacts.map(userContact => ({ ...userContact })) - const dbUserRolesCopy = dbUserRoles.map(userRole => ({ ...userRole })) + const dbUsersCopy = dbUsers.map((user) => ({ ...user })) + const dbUserContactsCopy = dbUserContacts.map((userContact) => ({ ...userContact })) + const dbUserRolesCopy = dbUserRoles.map((userRole) => ({ ...userRole })) await Promise.all([ transaction.getRepository(User).insert(dbUsersCopy), transaction.getRepository(UserContact).insert(dbUserContactsCopy), - transaction.getRepository(UserRole).insert(dbUserRolesCopy) + transaction.getRepository(UserRole).insert(dbUserRolesCopy), ]) }) return dbUsers } -export async function createUser(user: UserInterface, homeCommunity?: Community | null, store: boolean = true): Promise { - let dbUser = new User() +export async function createUser( + user: UserInterface, + homeCommunity?: Community | null, + store: boolean = true, +): Promise { + const dbUser = new User() dbUser.firstName = user.firstName ?? '' dbUser.lastName = user.lastName ?? '' if (user.alias) { @@ -86,7 +99,7 @@ export async function createUser(user: UserInterface, homeCommunity?: Community dbUser.gradidoID = v4() if (user.emailChecked) { - // dbUser.password = + // dbUser.password = dbUser.passwordEncryptionType = PasswordEncryptionType.GRADIDO_ID } if (!homeCommunity) { @@ -100,8 +113,12 @@ export async function createUser(user: UserInterface, homeCommunity?: Community return store ? dbUser.save() : dbUser } -export async function createUserContact(user: UserInterface, userId?: number, store: boolean = true): Promise { - let dbUserContact = new UserContact() +export async function createUserContact( + user: UserInterface, + userId?: number, + store: boolean = true, +): Promise { + const dbUserContact = new UserContact() dbUserContact.email = user.email ?? '' dbUserContact.type = UserContactType.USER_CONTACT_EMAIL @@ -123,9 +140,13 @@ export async function createUserContact(user: UserInterface, userId?: number, st return store ? dbUserContact.save() : dbUserContact } -export async function createUserRole(userId: number, role: RoleNames, store: boolean = true): Promise { - let dbUserRole = new UserRole() +export async function createUserRole( + userId: number, + role: RoleNames, + store: boolean = true, +): Promise { + const dbUserRole = new UserRole() dbUserRole.userId = userId dbUserRole.role = role return store ? dbUserRole.save() : dbUserRole -} \ No newline at end of file +} diff --git a/database/src/seeds/users/index.ts b/database/src/seeds/users/index.ts index 8149ffd4c..bab220a7c 100644 --- a/database/src/seeds/users/index.ts +++ b/database/src/seeds/users/index.ts @@ -6,14 +6,14 @@ import { raeuberHotzenplotz } from './raeuber-hotzenplotz' import { stephenHawking } from './stephen-hawking' import { UserInterface } from './UserInterface' -export { - type UserInterface, - bibiBloxberg, - bobBaumeister, - garrickOllivander, - peterLustig, - raeuberHotzenplotz, - stephenHawking +export { + type UserInterface, + bibiBloxberg, + bobBaumeister, + garrickOllivander, + peterLustig, + raeuberHotzenplotz, + stephenHawking, } export const users: UserInterface[] = [ diff --git a/database/src/seeds/users/peter-lustig.ts b/database/src/seeds/users/peter-lustig.ts index e20bac5fe..233724ba6 100644 --- a/database/src/seeds/users/peter-lustig.ts +++ b/database/src/seeds/users/peter-lustig.ts @@ -1,5 +1,5 @@ -import { UserInterface } from './UserInterface' import { RoleNames } from '../../enum' +import { UserInterface } from './UserInterface' export const peterLustig: UserInterface = { email: 'peter@lustig.de', diff --git a/dht-node/src/config/index.ts b/dht-node/src/config/index.ts index 7f403ef26..c4e9c8aba 100644 --- a/dht-node/src/config/index.ts +++ b/dht-node/src/config/index.ts @@ -1,5 +1,5 @@ -import { validate } from 'config-schema' import type { LogLevel } from 'config-schema' +import { validate } from 'config-schema' import dotenv from 'dotenv' import { schema } from './schema' diff --git a/dht-node/src/config/schema.ts b/dht-node/src/config/schema.ts index a205a51f3..bb6da9e08 100644 --- a/dht-node/src/config/schema.ts +++ b/dht-node/src/config/schema.ts @@ -1,9 +1,9 @@ import { COMMUNITY_DESCRIPTION, COMMUNITY_NAME, - LOG4JS_CONFIG, LOG_FILES_BASE_PATH, LOG_LEVEL, + LOG4JS_CONFIG, NODE_ENV, PRODUCTION, } from 'config-schema' diff --git a/dht-node/src/dht_node/index.test.ts b/dht-node/src/dht_node/index.test.ts index 25ccd4638..36a941dbf 100644 --- a/dht-node/src/dht_node/index.test.ts +++ b/dht-node/src/dht_node/index.test.ts @@ -1,11 +1,10 @@ import DHT from '@hyperswarm/dht' -import { Community as DbCommunity, FederatedCommunity as DbFederatedCommunity } from 'database' -import { validate as validateUUID, version as versionUUID } from 'uuid' - import { cleanDB, testEnvironment } from '@test/helpers' import { getLogger } from 'config-schema/test/testSetup' -import { LOG4JS_BASE_CATEGORY_NAME } from '@/config/const' +import { Community as DbCommunity, FederatedCommunity as DbFederatedCommunity } from 'database' +import { validate as validateUUID, version as versionUUID } from 'uuid' import { CONFIG } from '@/config' +import { LOG4JS_BASE_CATEGORY_NAME } from '@/config/const' import { startDHT } from './index' diff --git a/dht-node/src/dht_node/index.ts b/dht-node/src/dht_node/index.ts index 162814f09..c1fbc420e 100644 --- a/dht-node/src/dht_node/index.ts +++ b/dht-node/src/dht_node/index.ts @@ -5,12 +5,10 @@ import { FederatedCommunity as DbFederatedCommunity, getHomeCommunity, } from 'database' +import { getLogger } from 'log4js' import { v4 as uuidv4 } from 'uuid' - import { CONFIG } from '@/config' import { LOG4JS_BASE_CATEGORY_NAME } from '@/config/const' - -import { getLogger } from 'log4js' import { ApiVersionType } from './ApiVersionType' const KEY_SECRET_SEEDBYTES = 32 diff --git a/dht-node/src/index.ts b/dht-node/src/index.ts index 36c866eaa..13d2a4366 100644 --- a/dht-node/src/index.ts +++ b/dht-node/src/index.ts @@ -1,11 +1,10 @@ import 'source-map-support/register' -import { startDHT } from '@/dht_node/index' - -import { CONFIG } from '@/config' -import { LOG4JS_BASE_CATEGORY_NAME } from '@/config/const' import { defaultCategory, initLogger } from 'config-schema' import { AppDatabase } from 'database' import { getLogger } from 'log4js' +import { CONFIG } from '@/config' +import { LOG4JS_BASE_CATEGORY_NAME } from '@/config/const' +import { startDHT } from '@/dht_node/index' async function main() { // init logger diff --git a/federation/src/client/1_0/AuthenticationClient.ts b/federation/src/client/1_0/AuthenticationClient.ts index ac14bcb84..e83397720 100644 --- a/federation/src/client/1_0/AuthenticationClient.ts +++ b/federation/src/client/1_0/AuthenticationClient.ts @@ -1,9 +1,8 @@ +import { EncryptedTransferArgs } from 'core' import { FederatedCommunity as DbFederatedCommunity } from 'database' import { GraphQLClient } from 'graphql-request' import { getLogger, Logger } from 'log4js' import { LOG4JS_BASE_CATEGORY_NAME } from '@/config/const' - -import { EncryptedTransferArgs } from 'core' import { authenticate } from './query/authenticate' import { openConnectionCallback } from './query/openConnectionCallback' @@ -27,15 +26,23 @@ export class AuthenticationClient { } async openConnectionCallback(args: EncryptedTransferArgs): Promise { - const methodLogger = getLogger(`${LOG4JS_BASE_CATEGORY_NAME}.client.1_0.AuthenticationClient.openConnectionCallback`) + const methodLogger = getLogger( + `${LOG4JS_BASE_CATEGORY_NAME}.client.1_0.AuthenticationClient.openConnectionCallback`, + ) methodLogger.addContext('handshakeID', args.handshakeID) methodLogger.debug('openConnectionCallback with endpoint', this.endpoint, args) try { - const { data } = await this.client.rawRequest<{ openConnectionCallback: boolean }>(openConnectionCallback, { args }) + const { data } = await this.client.rawRequest<{ openConnectionCallback: boolean }>( + openConnectionCallback, + { args }, + ) methodLogger.debug('after openConnectionCallback: data:', data) if (!data || !data.openConnectionCallback) { - methodLogger.warn('openConnectionCallback without response data from endpoint', this.endpoint) + methodLogger.warn( + 'openConnectionCallback without response data from endpoint', + this.endpoint, + ) return false } methodLogger.debug('openConnectionCallback successfully started with endpoint', this.endpoint) @@ -47,11 +54,15 @@ export class AuthenticationClient { } async authenticate(args: EncryptedTransferArgs): Promise { - const methodLogger = getLogger(`${LOG4JS_BASE_CATEGORY_NAME}.client.1_0.AuthenticationClient.authenticate`) + const methodLogger = getLogger( + `${LOG4JS_BASE_CATEGORY_NAME}.client.1_0.AuthenticationClient.authenticate`, + ) methodLogger.addContext('handshakeID', args.handshakeID) methodLogger.debug('authenticate with endpoint=', this.endpoint) try { - const { data } = await this.client.rawRequest<{ authenticate: string }>(authenticate, { args }) + const { data } = await this.client.rawRequest<{ authenticate: string }>(authenticate, { + args, + }) methodLogger.debug('after authenticate: data:', data) const responseJwt = data?.authenticate diff --git a/federation/src/client/AuthenticationClientFactory.ts b/federation/src/client/AuthenticationClientFactory.ts index 94a74581a..ab231e29a 100644 --- a/federation/src/client/AuthenticationClientFactory.ts +++ b/federation/src/client/AuthenticationClientFactory.ts @@ -1,9 +1,7 @@ -import { FederatedCommunity as DbFederatedCommunity } from 'database' - -import { AuthenticationClient as V1_0_AuthenticationClient } from './1_0/AuthenticationClient' - -import { AuthenticationClient as V1_1_AuthenticationClient } from './1_1/AuthenticationClient' import { ApiVersionType } from 'core' +import { FederatedCommunity as DbFederatedCommunity } from 'database' +import { AuthenticationClient as V1_0_AuthenticationClient } from './1_0/AuthenticationClient' +import { AuthenticationClient as V1_1_AuthenticationClient } from './1_1/AuthenticationClient' type AuthenticationClient = V1_0_AuthenticationClient | V1_1_AuthenticationClient diff --git a/federation/src/config/index.ts b/federation/src/config/index.ts index 6e9d5437e..5947b0899 100644 --- a/federation/src/config/index.ts +++ b/federation/src/config/index.ts @@ -1,10 +1,10 @@ // ATTENTION: DO NOT PUT ANY SECRETS IN HERE (or the .env) + +import type { LogLevel } from 'config-schema' +import { validate } from 'config-schema' import { Decimal } from 'decimal.js-light' import dotenv from 'dotenv' -import { validate } from 'config-schema' -import type { LogLevel } from 'config-schema' - import { schema } from './schema' dotenv.config() diff --git a/federation/src/config/schema.ts b/federation/src/config/schema.ts index 07f5ed48f..b87eb8373 100644 --- a/federation/src/config/schema.ts +++ b/federation/src/config/schema.ts @@ -1,8 +1,8 @@ import { GRAPHIQL, - LOG4JS_CONFIG_PLACEHOLDER, LOG_FILES_BASE_PATH, LOG_LEVEL, + LOG4JS_CONFIG_PLACEHOLDER, NODE_ENV, PRODUCTION, } from 'config-schema' diff --git a/federation/src/graphql/api/1_0/enum/PendingTransactionState.ts b/federation/src/graphql/api/1_0/enum/PendingTransactionState.ts index e59f3fd7d..a70a776c5 100644 --- a/federation/src/graphql/api/1_0/enum/PendingTransactionState.ts +++ b/federation/src/graphql/api/1_0/enum/PendingTransactionState.ts @@ -1,5 +1,5 @@ -import { registerEnumType } from 'type-graphql' import { PendingTransactionState } from 'shared' +import { registerEnumType } from 'type-graphql' registerEnumType(PendingTransactionState, { name: 'PendingTransactionState', // this one is mandatory diff --git a/federation/src/graphql/api/1_0/logger/GetPublicCommunityInfoResultLogging.view.ts b/federation/src/graphql/api/1_0/logger/GetPublicCommunityInfoResultLogging.view.ts index 3eb7fd208..472b62c7d 100644 --- a/federation/src/graphql/api/1_0/logger/GetPublicCommunityInfoResultLogging.view.ts +++ b/federation/src/graphql/api/1_0/logger/GetPublicCommunityInfoResultLogging.view.ts @@ -1,5 +1,5 @@ -import { GetPublicCommunityInfoResult } from '@/graphql/api/1_0/model/GetPublicCommunityInfoResult' import { AbstractLoggingView } from 'database' +import { GetPublicCommunityInfoResult } from '@/graphql/api/1_0/model/GetPublicCommunityInfoResult' export class GetPublicCommunityInfoResultLoggingView extends AbstractLoggingView { public constructor(private self: GetPublicCommunityInfoResult) { diff --git a/federation/src/graphql/api/1_0/logger/SendCoinsArgsLogging.view.ts b/federation/src/graphql/api/1_0/logger/SendCoinsArgsLogging.view.ts index 4b5698995..1ad47a5a2 100644 --- a/federation/src/graphql/api/1_0/logger/SendCoinsArgsLogging.view.ts +++ b/federation/src/graphql/api/1_0/logger/SendCoinsArgsLogging.view.ts @@ -1,5 +1,5 @@ -import { SendCoinsArgs } from '@/graphql/api/1_0/model/SendCoinsArgs' import { AbstractLoggingView } from 'database' +import { SendCoinsArgs } from '@/graphql/api/1_0/model/SendCoinsArgs' export class SendCoinsArgsLoggingView extends AbstractLoggingView { public constructor(private self: SendCoinsArgs) { diff --git a/federation/src/graphql/api/1_0/model/Decay.ts b/federation/src/graphql/api/1_0/model/Decay.ts index f72fade3a..f18acdb3d 100644 --- a/federation/src/graphql/api/1_0/model/Decay.ts +++ b/federation/src/graphql/api/1_0/model/Decay.ts @@ -1,6 +1,6 @@ import { Decimal } from 'decimal.js-light' +import { Decay as DecayInterface } from 'shared' import { Field, Int, ObjectType } from 'type-graphql' -import { Decay as DecayInterface} from 'shared' @ObjectType() export class Decay { diff --git a/federation/src/graphql/api/1_0/resolver/AuthenticationResolver.ts b/federation/src/graphql/api/1_0/resolver/AuthenticationResolver.ts index 3bee91e3e..686f22768 100644 --- a/federation/src/graphql/api/1_0/resolver/AuthenticationResolver.ts +++ b/federation/src/graphql/api/1_0/resolver/AuthenticationResolver.ts @@ -1,31 +1,39 @@ -import { LOG4JS_BASE_CATEGORY_NAME } from '@/config/const' -import { CommunityHandshakeStateLogic, EncryptedTransferArgs, interpretEncryptedTransferArgs, splitUrlInEndPointAndApiVersion } from 'core' +import { + CommunityHandshakeStateLogic, + EncryptedTransferArgs, + interpretEncryptedTransferArgs, + splitUrlInEndPointAndApiVersion, +} from 'core' import { CommunityHandshakeStateLoggingView, - CommunityHandshakeState as DbCommunityHandshakeState, CommunityHandshakeStateType, + CommunityHandshakeState as DbCommunityHandshakeState, FederatedCommunity as DbFedCommunity, - getHomeCommunity, findPendingCommunityHandshakeOrFailByOneTimeCode, getCommunityByPublicKeyOrFail, + getHomeCommunity, } from 'database' import { getLogger } from 'log4js' -import { - AuthenticationJwtPayloadType, - AuthenticationResponseJwtPayloadType, - Ed25519PublicKey, - encryptAndSign, - OpenConnectionCallbackJwtPayloadType, - OpenConnectionJwtPayloadType, - uint32Schema, - uuidv4Schema +import { + AuthenticationJwtPayloadType, + AuthenticationResponseJwtPayloadType, + Ed25519PublicKey, + encryptAndSign, + OpenConnectionCallbackJwtPayloadType, + OpenConnectionJwtPayloadType, + uint32Schema, + uuidv4Schema, } from 'shared' import { Arg, Mutation, Resolver } from 'type-graphql' +import { LOG4JS_BASE_CATEGORY_NAME } from '@/config/const' import { startAuthentication, startOpenConnectionCallback } from '../util/authenticateCommunity' // TODO: think about the case, when we have a higher api version, which still use this resolver const apiVersion = '1_0' -const createLogger = (method: string ) => getLogger(`${LOG4JS_BASE_CATEGORY_NAME}.graphql.api.${apiVersion}.resolver.AuthenticationResolver.${method}`) +const createLogger = (method: string) => + getLogger( + `${LOG4JS_BASE_CATEGORY_NAME}.graphql.api.${apiVersion}.resolver.AuthenticationResolver.${method}`, + ) @Resolver() export class AuthenticationResolver { @@ -37,15 +45,23 @@ export class AuthenticationResolver { const methodLogger = createLogger('openConnection') methodLogger.addContext('handshakeID', args.handshakeID) const argsPublicKey = new Ed25519PublicKey(args.publicKey) - methodLogger.debug(`start via apiVersion=${apiVersion}, public key: ${argsPublicKey.asHex()}`) + methodLogger.debug(`start via apiVersion=${apiVersion}, public key: ${argsPublicKey.asHex()}`) try { - const openConnectionJwtPayload = await interpretEncryptedTransferArgs(args) as OpenConnectionJwtPayloadType + const openConnectionJwtPayload = (await interpretEncryptedTransferArgs( + args, + )) as OpenConnectionJwtPayloadType methodLogger.debug(`openConnectionJwtPayload url: ${openConnectionJwtPayload.url}`) if (!openConnectionJwtPayload) { - throw new Error(`invalid OpenConnection payload of requesting community with publicKey ${argsPublicKey.asHex()}`) + throw new Error( + `invalid OpenConnection payload of requesting community with publicKey ${argsPublicKey.asHex()}`, + ) } - if (openConnectionJwtPayload.tokentype !== OpenConnectionJwtPayloadType.OPEN_CONNECTION_TYPE) { - throw new Error(`invalid tokentype: ${openConnectionJwtPayload.tokentype} of community with publicKey ${argsPublicKey.asHex()}`) + if ( + openConnectionJwtPayload.tokentype !== OpenConnectionJwtPayloadType.OPEN_CONNECTION_TYPE + ) { + throw new Error( + `invalid tokentype: ${openConnectionJwtPayload.tokentype} of community with publicKey ${argsPublicKey.asHex()}`, + ) } if (!openConnectionJwtPayload.url) { throw new Error(`invalid url of community with publicKey ${argsPublicKey.asHex()}`) @@ -57,14 +73,18 @@ export class AuthenticationResolver { throw new Error(`invalid url of community with publicKey ${argsPublicKey.asHex()}`) } if (fedComA.apiVersion !== apiVersion) { - throw new Error(`invalid apiVersion: ${fedComA.apiVersion} of community with publicKey ${argsPublicKey.asHex()}`) + throw new Error( + `invalid apiVersion: ${fedComA.apiVersion} of community with publicKey ${argsPublicKey.asHex()}`, + ) } // no await to respond immediately and invoke callback-request asynchronously // important: startOpenConnectionCallback must catch all exceptions them self, or server will crash! // biome-ignore lint/complexity/noVoid: start it intentionally async without waiting for result void startOpenConnectionCallback(args.handshakeID, argsPublicKey, fedComA) - methodLogger.debug('openConnection() successfully initiated callback and returns true immediately...') + methodLogger.debug( + 'openConnection() successfully initiated callback and returns true immediately...', + ) return true } catch (err) { methodLogger.error('invalid jwt token:', err) @@ -82,12 +102,18 @@ export class AuthenticationResolver { methodLogger.addContext('handshakeID', args.handshakeID) methodLogger.debug(`start via apiVersion=${apiVersion}, public key: ${args.publicKey}`) try { - // decrypt args.url with homeCom.privateJwtKey and verify signing with callbackFedCom.publicKey - const openConnectionCallbackJwtPayload = await interpretEncryptedTransferArgs(args) as OpenConnectionCallbackJwtPayloadType + // decrypt args.url with homeCom.privateJwtKey and verify signing with callbackFedCom.publicKey + const openConnectionCallbackJwtPayload = (await interpretEncryptedTransferArgs( + args, + )) as OpenConnectionCallbackJwtPayloadType if (!openConnectionCallbackJwtPayload) { - throw new Error(`invalid OpenConnectionCallback payload of requesting community with publicKey ${args.publicKey}`) + throw new Error( + `invalid OpenConnectionCallback payload of requesting community with publicKey ${args.publicKey}`, + ) } - const { endPoint, apiVersion } = splitUrlInEndPointAndApiVersion(openConnectionCallbackJwtPayload.url) + const { endPoint, apiVersion } = splitUrlInEndPointAndApiVersion( + openConnectionCallbackJwtPayload.url, + ) // methodLogger.debug(`search fedComB per:`, endPoint, apiVersion) const fedComB = await DbFedCommunity.findOneBy({ endPoint, apiVersion }) if (!fedComB) { @@ -98,7 +124,11 @@ export class AuthenticationResolver { ) // no await to respond immediately and invoke authenticate-request asynchronously // biome-ignore lint/complexity/noVoid: start it intentionally async without waiting for result - void startAuthentication(args.handshakeID, openConnectionCallbackJwtPayload.oneTimeCode, fedComB) + void startAuthentication( + args.handshakeID, + openConnectionCallbackJwtPayload.oneTimeCode, + fedComB, + ) // methodLogger.debug('openConnectionCallback() successfully initiated authentication and returns true immediately...') return true } catch (err) { @@ -119,23 +149,25 @@ export class AuthenticationResolver { let state: DbCommunityHandshakeState | null = null const argsPublicKey = new Ed25519PublicKey(args.publicKey) try { - const authArgs = await interpretEncryptedTransferArgs(args) as AuthenticationJwtPayloadType + const authArgs = (await interpretEncryptedTransferArgs(args)) as AuthenticationJwtPayloadType // methodLogger.debug(`interpreted authentication payload...authArgs:`, authArgs) if (!authArgs) { methodLogger.debug(`interpretEncryptedTransferArgs was called with`, args) - throw new Error(`invalid authentication payload of requesting community with publicKey ${argsPublicKey.asHex()}`) + throw new Error( + `invalid authentication payload of requesting community with publicKey ${argsPublicKey.asHex()}`, + ) } const validOneTimeCode = uint32Schema.safeParse(Number(authArgs.oneTimeCode)) if (!validOneTimeCode.success) { throw new Error( - `invalid oneTimeCode: ${authArgs.oneTimeCode} for community with publicKey ${argsPublicKey.asHex()}, expect uint32` + `invalid oneTimeCode: ${authArgs.oneTimeCode} for community with publicKey ${argsPublicKey.asHex()}, expect uint32`, ) } state = await findPendingCommunityHandshakeOrFailByOneTimeCode(validOneTimeCode.data) const stateLogic = new CommunityHandshakeStateLogic(state) if ( - (await stateLogic.isTimeoutUpdate()) || + (await stateLogic.isTimeoutUpdate()) || state.status !== CommunityHandshakeStateType.START_OPEN_CONNECTION_CALLBACK ) { throw new Error('No valid pending community handshake found') @@ -143,7 +175,7 @@ export class AuthenticationResolver { state.status = CommunityHandshakeStateType.SUCCESS await state.save() methodLogger.debug('[SUCCESS] community handshake state updated') - + // methodLogger.debug(`search community per oneTimeCode:`, authArgs.oneTimeCode) const authCom = await getCommunityByPublicKeyOrFail(argsPublicKey) if (authCom) { @@ -153,24 +185,33 @@ export class AuthenticationResolver { // methodLogger.debug('args.publicKey', argsPublicKey.asHex()) if (!authComPublicKey.isSame(argsPublicKey)) { throw new Error( - `corrupt authentication call detected, oneTimeCode: ${authArgs.oneTimeCode} doesn't belong to caller: ${argsPublicKey.asHex()}` + `corrupt authentication call detected, oneTimeCode: ${authArgs.oneTimeCode} doesn't belong to caller: ${argsPublicKey.asHex()}`, ) } const communityUuid = uuidv4Schema.safeParse(authArgs.uuid) if (!communityUuid.success) { throw new Error( - `invalid uuid: ${authArgs.uuid} for community with publicKey ${authComPublicKey.asHex()}` + `invalid uuid: ${authArgs.uuid} for community with publicKey ${authComPublicKey.asHex()}`, ) } authCom.communityUuid = communityUuid.data authCom.authenticatedAt = new Date() await authCom.save() - methodLogger.debug(`update authCom.uuid successfully with ${authCom.communityUuid} at ${authCom.authenticatedAt}`) + methodLogger.debug( + `update authCom.uuid successfully with ${authCom.communityUuid} at ${authCom.authenticatedAt}`, + ) const homeComB = await getHomeCommunity() if (homeComB?.communityUuid) { - const responseArgs = new AuthenticationResponseJwtPayloadType(args.handshakeID,homeComB.communityUuid) - const responseJwt = await encryptAndSign(responseArgs, homeComB.privateJwtKey!, authCom.publicJwtKey!) + const responseArgs = new AuthenticationResponseJwtPayloadType( + args.handshakeID, + homeComB.communityUuid, + ) + const responseJwt = await encryptAndSign( + responseArgs, + homeComB.privateJwtKey!, + authCom.publicJwtKey!, + ) return responseJwt } } else { @@ -184,7 +225,11 @@ export class AuthenticationResolver { state.lastError = String(err) await state.save() } catch (err) { - methodLogger.error(`failed to save state`, new CommunityHandshakeStateLoggingView(state), err) + methodLogger.error( + `failed to save state`, + new CommunityHandshakeStateLoggingView(state), + err, + ) } } methodLogger.error(`failed`, err) diff --git a/federation/src/graphql/api/1_0/resolver/DisbursementResolver.ts b/federation/src/graphql/api/1_0/resolver/DisbursementResolver.ts index 2388aaec0..3f0aa85cf 100644 --- a/federation/src/graphql/api/1_0/resolver/DisbursementResolver.ts +++ b/federation/src/graphql/api/1_0/resolver/DisbursementResolver.ts @@ -1,13 +1,15 @@ -import { getLogger } from "log4js" -import { Arg, Mutation, Resolver } from "type-graphql" +import { + EncryptedTransferArgs, + interpretEncryptedTransferArgs, + processXComCompleteTransaction, +} from 'core' +import { getLogger } from 'log4js' +import { DisburseJwtPayloadType } from 'shared' +import { Arg, Mutation, Resolver } from 'type-graphql' +import { LOG4JS_BASE_CATEGORY_NAME } from '@/config/const' -import { LOG4JS_BASE_CATEGORY_NAME } from "@/config/const" -import { interpretEncryptedTransferArgs } from "core" -import { EncryptedTransferArgs } from "core" -import { DisburseJwtPayloadType } from "shared" -import { processXComCompleteTransaction } from "core" - -const createLogger = (method: string) => getLogger(`${LOG4JS_BASE_CATEGORY_NAME}.graphql.api.1_0.resolver.DisbursementResolver.${method}`) +const createLogger = (method: string) => + getLogger(`${LOG4JS_BASE_CATEGORY_NAME}.graphql.api.1_0.resolver.DisbursementResolver.${method}`) @Resolver() export class DisbursementResolver { @@ -18,31 +20,34 @@ export class DisbursementResolver { ): Promise { const methodLogger = createLogger(`processDisburseJwtOnSenderCommunity`) methodLogger.addContext('handshakeID', args.handshakeID) - if(methodLogger.isDebugEnabled()) { + if (methodLogger.isDebugEnabled()) { methodLogger.debug(`processDisburseJwtOnSenderCommunity() via apiVersion=1_0 ...`, args) } - const authArgs = await interpretEncryptedTransferArgs(args) as DisburseJwtPayloadType + const authArgs = (await interpretEncryptedTransferArgs(args)) as DisburseJwtPayloadType if (!authArgs) { - const errmsg = `invalid disbursement payload of requesting community with publicKey` + args.publicKey + const errmsg = + `invalid disbursement payload of requesting community with publicKey` + args.publicKey methodLogger.error(errmsg) throw new Error(errmsg) } - if(methodLogger.isDebugEnabled()) { + if (methodLogger.isDebugEnabled()) { methodLogger.debug(`processDisburseJwtOnSenderCommunity() via apiVersion=1_0 ...`, authArgs) } let result = 'Disbursement of Redeem-Link failed!' try { - if(await processXComCompleteTransaction( - authArgs.sendercommunityuuid, - authArgs.sendergradidoid, - authArgs.recipientcommunityuuid, - authArgs.recipientgradidoid, - authArgs.amount, - authArgs.memo, - authArgs.code, - authArgs.recipientfirstname, - authArgs.recipientalias, - )) { + if ( + await processXComCompleteTransaction( + authArgs.sendercommunityuuid, + authArgs.sendergradidoid, + authArgs.recipientcommunityuuid, + authArgs.recipientgradidoid, + authArgs.amount, + authArgs.memo, + authArgs.code, + authArgs.recipientfirstname, + authArgs.recipientalias, + ) + ) { result = 'Disbursement of Redeem-Link successfull!' } } catch (err) { @@ -51,4 +56,4 @@ export class DisbursementResolver { } return result } -} \ No newline at end of file +} diff --git a/federation/src/graphql/api/1_0/resolver/PublicCommunityInfoResolver.test.ts b/federation/src/graphql/api/1_0/resolver/PublicCommunityInfoResolver.test.ts index 174c3735f..c2e0b5c26 100644 --- a/federation/src/graphql/api/1_0/resolver/PublicCommunityInfoResolver.test.ts +++ b/federation/src/graphql/api/1_0/resolver/PublicCommunityInfoResolver.test.ts @@ -1,9 +1,9 @@ -import { CONFIG } from '@/config' -import { createServer } from '@/server/createServer' import { createTestClient } from 'apollo-server-testing' import { Community as DbCommunity } from 'database' import { getLogger } from 'log4js' import { DataSource } from 'typeorm' +import { CONFIG } from '@/config' +import { createServer } from '@/server/createServer' let query: any diff --git a/federation/src/graphql/api/1_0/resolver/PublicCommunityInfoResolver.ts b/federation/src/graphql/api/1_0/resolver/PublicCommunityInfoResolver.ts index 1cdb43a31..455c0368e 100644 --- a/federation/src/graphql/api/1_0/resolver/PublicCommunityInfoResolver.ts +++ b/federation/src/graphql/api/1_0/resolver/PublicCommunityInfoResolver.ts @@ -5,7 +5,9 @@ import { LOG4JS_BASE_CATEGORY_NAME } from '@/config/const' import { GetPublicCommunityInfoResultLoggingView } from '../logger/GetPublicCommunityInfoResultLogging.view' import { GetPublicCommunityInfoResult } from '../model/GetPublicCommunityInfoResult' -const logger = getLogger(`${LOG4JS_BASE_CATEGORY_NAME}.graphql.api.1_0.resolver.PublicCommunityInfoResolver`) +const logger = getLogger( + `${LOG4JS_BASE_CATEGORY_NAME}.graphql.api.1_0.resolver.PublicCommunityInfoResolver`, +) @Resolver() export class PublicCommunityInfoResolver { diff --git a/federation/src/graphql/api/1_0/resolver/PublicKeyResolver.test.ts b/federation/src/graphql/api/1_0/resolver/PublicKeyResolver.test.ts index 023a11a19..b72051b9e 100644 --- a/federation/src/graphql/api/1_0/resolver/PublicKeyResolver.test.ts +++ b/federation/src/graphql/api/1_0/resolver/PublicKeyResolver.test.ts @@ -1,9 +1,9 @@ -import { CONFIG } from '@/config' -import { LOG4JS_BASE_CATEGORY_NAME } from '@/config/const' -import { createServer } from '@/server/createServer' import { createTestClient } from 'apollo-server-testing' import { FederatedCommunity as DbFederatedCommunity } from 'database' import { getLogger } from 'log4js' +import { CONFIG } from '@/config' +import { LOG4JS_BASE_CATEGORY_NAME } from '@/config/const' +import { createServer } from '@/server/createServer' let query: any diff --git a/federation/src/graphql/api/1_0/resolver/SendCoinsResolver.test.ts b/federation/src/graphql/api/1_0/resolver/SendCoinsResolver.test.ts index d0417cb40..bdea0ec9a 100644 --- a/federation/src/graphql/api/1_0/resolver/SendCoinsResolver.test.ts +++ b/federation/src/graphql/api/1_0/resolver/SendCoinsResolver.test.ts @@ -1,15 +1,22 @@ -import { CONFIG } from '@/config' -import { LOG4JS_BASE_CATEGORY_NAME } from '@/config/const' -import { fullName } from '@/graphql/util/fullName' import { cleanDB, testEnvironment } from '@test/helpers' import { ApolloServerTestClient } from 'apollo-server-testing' +import { EncryptedTransferArgs } from 'core' import { Community as DbCommunity, User as DbUser, UserContact as DbUserContact } from 'database' import Decimal from 'decimal.js-light' import { GraphQLError } from 'graphql' import { getLogger } from 'log4js' +import { + createKeyPair, + encryptAndSign, + SendCoinsJwtPayloadType, + SendCoinsResponseJwtPayloadType, + verifyAndDecrypt, +} from 'shared' import { DataSource } from 'typeorm' -import { EncryptedTransferArgs } from 'core' -import { createKeyPair, encryptAndSign, SendCoinsJwtPayloadType, SendCoinsResponseJwtPayloadType, verifyAndDecrypt } from 'shared' +import { CONFIG } from '@/config' +import { LOG4JS_BASE_CATEGORY_NAME } from '@/config/const' +import { fullName } from '@/graphql/util/fullName' + let mutate: ApolloServerTestClient['mutate'] // , con: Connection // let query: ApolloServerTestClient['query'] @@ -64,29 +71,37 @@ describe('SendCoinsResolver', () => { beforeEach(async () => { await cleanDB() // Generate key pair using jose library - const { publicKey: homePublicKey, privateKey: homePrivateKey } = await createKeyPair(); + const { publicKey: homePublicKey, privateKey: homePrivateKey } = await createKeyPair() recipientCom = DbCommunity.create() recipientCom.foreign = false recipientCom.url = 'homeCom-url' recipientCom.name = 'homeCom-Name' recipientCom.description = 'homeCom-Description' recipientCom.creationDate = new Date() - recipientCom.publicKey = Buffer.alloc(32, '15F92F8EC2EA685D5FD51EE3588F5B4805EBD330EF9EDD16043F3BA9C35C0D91', 'hex') // 'homeCom-publicKey', 'hex') - recipientCom.publicJwtKey = homePublicKey; - recipientCom.privateJwtKey = homePrivateKey; + recipientCom.publicKey = Buffer.alloc( + 32, + '15F92F8EC2EA685D5FD51EE3588F5B4805EBD330EF9EDD16043F3BA9C35C0D91', + 'hex', + ) // 'homeCom-publicKey', 'hex') + recipientCom.publicJwtKey = homePublicKey + recipientCom.privateJwtKey = homePrivateKey recipientCom.communityUuid = '56a55482-909e-46a4-bfa2-cd025e894eba' await DbCommunity.insert(recipientCom) - const { publicKey: foreignPublicKey, privateKey: foreignPrivateKey } = await createKeyPair(); + const { publicKey: foreignPublicKey, privateKey: foreignPrivateKey } = await createKeyPair() senderCom = DbCommunity.create() senderCom.foreign = true senderCom.url = 'foreignCom-url' senderCom.name = 'foreignCom-Name' senderCom.description = 'foreignCom-Description' senderCom.creationDate = new Date() - senderCom.publicKey = Buffer.alloc(32, '15F92F8EC2EA685D5FD51EE3588F5B4805EBD330EF9EDD16043F3BA9C35C0D92', 'hex') // 'foreignCom-publicKey', 'hex') - senderCom.publicJwtKey = foreignPublicKey; - senderCom.privateJwtKey = foreignPrivateKey; + senderCom.publicKey = Buffer.alloc( + 32, + '15F92F8EC2EA685D5FD51EE3588F5B4805EBD330EF9EDD16043F3BA9C35C0D92', + 'hex', + ) // 'foreignCom-publicKey', 'hex') + senderCom.publicJwtKey = foreignPublicKey + senderCom.privateJwtKey = foreignPrivateKey senderCom.communityUuid = '56a55482-909e-46a4-bfa2-cd025e894ebb' await DbCommunity.insert(senderCom) @@ -121,7 +136,7 @@ describe('SendCoinsResolver', () => { await DbUser.save(recipUser) }) - describe('voteForSendCoins', () => { + describe('voteForSendCoins', () => { describe('unknown recipient community', () => { it('throws an error', async () => { jest.clearAllMocks() @@ -135,10 +150,14 @@ describe('SendCoinsResolver', () => { senderCom.communityUuid!, sendUser.gradidoID, fullName(sendUser.firstName, sendUser.lastName), - sendUser.alias + sendUser.alias, ) // invoke encryption as beeing on the foreignCom side to find in voteForSendCoins the correct homeCom - const jws = await encryptAndSign(payload, senderCom.privateJwtKey!, recipientCom.publicJwtKey!) + const jws = await encryptAndSign( + payload, + senderCom.privateJwtKey!, + recipientCom.publicJwtKey!, + ) const args = new EncryptedTransferArgs() args.publicKey = senderCom.publicKey.toString('hex') args.jwt = jws @@ -147,11 +166,13 @@ describe('SendCoinsResolver', () => { mutation: voteForSendCoinsMutation, variables: { args }, }) - expect( - graphQLResponse, - ).toEqual( + expect(graphQLResponse).toEqual( expect.objectContaining({ - errors: [new GraphQLError('voteForSendCoins with wrong recipientCommunityUuid: invalid recipientCom')], + errors: [ + new GraphQLError( + 'voteForSendCoins with wrong recipientCommunityUuid: invalid recipientCom', + ), + ], }), ) }) @@ -171,10 +192,14 @@ describe('SendCoinsResolver', () => { senderCom.communityUuid!, sendUser.gradidoID, fullName(sendUser.firstName, sendUser.lastName), - sendUser.alias + sendUser.alias, ) // invoke encryption as beeing on the foreignCom side to find in voteForSendCoins the correct homeCom - const jws = await encryptAndSign(payload, senderCom.privateJwtKey!, recipientCom.publicJwtKey!) + const jws = await encryptAndSign( + payload, + senderCom.privateJwtKey!, + recipientCom.publicJwtKey!, + ) const args = new EncryptedTransferArgs() args.publicKey = senderCom.publicKey.toString('hex') args.jwt = jws @@ -210,10 +235,14 @@ describe('SendCoinsResolver', () => { senderCom.communityUuid!, sendUser.gradidoID, fullName(sendUser.firstName, sendUser.lastName), - sendUser.alias + sendUser.alias, ) // invoke encryption as beeing on the foreignCom side to find in voteForSendCoins the correct homeCom - const jws = await encryptAndSign(payload, senderCom.privateJwtKey!, recipientCom.publicJwtKey!) + const jws = await encryptAndSign( + payload, + senderCom.privateJwtKey!, + recipientCom.publicJwtKey!, + ) const args = new EncryptedTransferArgs() args.publicKey = senderCom.publicKey.toString('hex') args.jwt = jws @@ -222,10 +251,13 @@ describe('SendCoinsResolver', () => { mutation: voteForSendCoinsMutation, variables: { args }, }) - const voteResult = await verifyAndDecrypt('handshakeID', responseJwt.data.voteForSendCoins, senderCom.privateJwtKey!, recipientCom.publicJwtKey!) as SendCoinsResponseJwtPayloadType - expect( - voteResult, - ).toEqual( + const voteResult = (await verifyAndDecrypt( + 'handshakeID', + responseJwt.data.voteForSendCoins, + senderCom.privateJwtKey!, + recipientCom.publicJwtKey!, + )) as SendCoinsResponseJwtPayloadType + expect(voteResult).toEqual( expect.objectContaining({ expiration: '10m', handshakeID: 'handshakeID', @@ -254,10 +286,14 @@ describe('SendCoinsResolver', () => { senderCom.communityUuid!, sendUser.gradidoID, fullName(sendUser.firstName, sendUser.lastName), - sendUser.alias + sendUser.alias, ) // invoke encryption as beeing on the foreignCom side to find in voteForSendCoins the correct homeCom - const jws = await encryptAndSign(payload, senderCom.privateJwtKey!, recipientCom.publicJwtKey!) + const jws = await encryptAndSign( + payload, + senderCom.privateJwtKey!, + recipientCom.publicJwtKey!, + ) const args = new EncryptedTransferArgs() args.publicKey = senderCom.publicKey.toString('hex') args.jwt = jws @@ -266,10 +302,13 @@ describe('SendCoinsResolver', () => { mutation: voteForSendCoinsMutation, variables: { args }, }) - const voteResult = await verifyAndDecrypt('handshakeID', responseJwt.data.voteForSendCoins, senderCom.privateJwtKey!, recipientCom.publicJwtKey!) as SendCoinsResponseJwtPayloadType - expect( - voteResult, - ).toEqual( + const voteResult = (await verifyAndDecrypt( + 'handshakeID', + responseJwt.data.voteForSendCoins, + senderCom.privateJwtKey!, + recipientCom.publicJwtKey!, + )) as SendCoinsResponseJwtPayloadType + expect(voteResult).toEqual( expect.objectContaining({ recipGradidoID: '56a55482-909e-46a4-bfa2-cd025e894ebd', recipFirstName: 'recipUser-FirstName', @@ -285,7 +324,6 @@ describe('SendCoinsResolver', () => { it('throws an error', async () => { jest.clearAllMocks() - const payload = new SendCoinsJwtPayloadType( 'handshakeID', recipientCom.communityUuid!, @@ -296,10 +334,14 @@ describe('SendCoinsResolver', () => { senderCom.communityUuid!, sendUser.gradidoID, fullName(sendUser.firstName, sendUser.lastName), - sendUser.alias + sendUser.alias, ) // invoke encryption as beeing on the foreignCom side to find in voteForSendCoins the correct homeCom - const jws = await encryptAndSign(payload, senderCom.privateJwtKey!, recipientCom.publicJwtKey!) + const jws = await encryptAndSign( + payload, + senderCom.privateJwtKey!, + recipientCom.publicJwtKey!, + ) const args = new EncryptedTransferArgs() args.publicKey = senderCom.publicKey.toString('hex') args.jwt = jws @@ -308,10 +350,13 @@ describe('SendCoinsResolver', () => { mutation: voteForSendCoinsMutation, variables: { args }, }) - const voteResult = await verifyAndDecrypt('handshakeID', responseJwt.data.voteForSendCoins, senderCom.privateJwtKey!, recipientCom.publicJwtKey!) as SendCoinsResponseJwtPayloadType - expect( - voteResult, - ).toEqual( + const voteResult = (await verifyAndDecrypt( + 'handshakeID', + responseJwt.data.voteForSendCoins, + senderCom.privateJwtKey!, + recipientCom.publicJwtKey!, + )) as SendCoinsResponseJwtPayloadType + expect(voteResult).toEqual( expect.objectContaining({ recipGradidoID: '56a55482-909e-46a4-bfa2-cd025e894ebd', recipFirstName: 'recipUser-FirstName', @@ -328,7 +373,6 @@ describe('SendCoinsResolver', () => { const creationDate = new Date() beforeEach(async () => { - const payload = new SendCoinsJwtPayloadType( 'handshakeID', recipientCom.communityUuid!, @@ -339,10 +383,14 @@ describe('SendCoinsResolver', () => { senderCom.communityUuid!, sendUser.gradidoID, fullName(sendUser.firstName, sendUser.lastName), - sendUser.alias + sendUser.alias, ) // invoke encryption as beeing on the foreignCom side to find in voteForSendCoins the correct homeCom - const jws = await encryptAndSign(payload, senderCom.privateJwtKey!, recipientCom.publicJwtKey!) + const jws = await encryptAndSign( + payload, + senderCom.privateJwtKey!, + recipientCom.publicJwtKey!, + ) const args = new EncryptedTransferArgs() args.publicKey = senderCom.publicKey.toString('hex') args.jwt = jws @@ -367,10 +415,14 @@ describe('SendCoinsResolver', () => { senderCom.communityUuid!, sendUser.gradidoID, fullName(sendUser.firstName, sendUser.lastName), - sendUser.alias + sendUser.alias, ) // invoke encryption as beeing on the foreignCom side to find in voteForSendCoins the correct homeCom - const jws = await encryptAndSign(payload, senderCom.privateJwtKey!, recipientCom.publicJwtKey!) + const jws = await encryptAndSign( + payload, + senderCom.privateJwtKey!, + recipientCom.publicJwtKey!, + ) const args = new EncryptedTransferArgs() args.publicKey = senderCom.publicKey.toString('hex') args.jwt = jws @@ -382,7 +434,11 @@ describe('SendCoinsResolver', () => { }), ).toEqual( expect.objectContaining({ - errors: [new GraphQLError('revertSendCoins with wrong recipientCommunityUuid=invalid recipientCom')], + errors: [ + new GraphQLError( + 'revertSendCoins with wrong recipientCommunityUuid=invalid recipientCom', + ), + ], }), ) }) @@ -402,10 +458,14 @@ describe('SendCoinsResolver', () => { senderCom.communityUuid!, sendUser.gradidoID, fullName(sendUser.firstName, sendUser.lastName), - sendUser.alias + sendUser.alias, ) // invoke encryption as beeing on the foreignCom side to find in voteForSendCoins the correct homeCom - const jws = await encryptAndSign(payload, senderCom.privateJwtKey!, recipientCom.publicJwtKey!) + const jws = await encryptAndSign( + payload, + senderCom.privateJwtKey!, + recipientCom.publicJwtKey!, + ) const args = new EncryptedTransferArgs() args.publicKey = senderCom.publicKey.toString('hex') args.jwt = jws @@ -441,10 +501,14 @@ describe('SendCoinsResolver', () => { senderCom.communityUuid!, sendUser.gradidoID, fullName(sendUser.firstName, sendUser.lastName), - sendUser.alias + sendUser.alias, ) // invoke encryption as beeing on the foreignCom side to find in voteForSendCoins the correct homeCom - const jws = await encryptAndSign(payload, senderCom.privateJwtKey!, recipientCom.publicJwtKey!) + const jws = await encryptAndSign( + payload, + senderCom.privateJwtKey!, + recipientCom.publicJwtKey!, + ) const args = new EncryptedTransferArgs() args.publicKey = senderCom.publicKey.toString('hex') args.jwt = jws @@ -480,10 +544,14 @@ describe('SendCoinsResolver', () => { senderCom.communityUuid!, sendUser.gradidoID, fullName(sendUser.firstName, sendUser.lastName), - sendUser.alias + sendUser.alias, ) // invoke encryption as beeing on the foreignCom side to find in voteForSendCoins the correct homeCom - const jws = await encryptAndSign(payload, senderCom.privateJwtKey!, recipientCom.publicJwtKey!) + const jws = await encryptAndSign( + payload, + senderCom.privateJwtKey!, + recipientCom.publicJwtKey!, + ) const args = new EncryptedTransferArgs() args.publicKey = senderCom.publicKey.toString('hex') args.jwt = jws @@ -508,10 +576,14 @@ describe('SendCoinsResolver', () => { senderCom.communityUuid!, sendUser.gradidoID, fullName(sendUser.firstName, sendUser.lastName), - sendUser.alias + sendUser.alias, ) // invoke encryption as beeing on the foreignCom side to find in voteForSendCoins the correct homeCom - const jws = await encryptAndSign(payload, senderCom.privateJwtKey!, recipientCom.publicJwtKey!) + const jws = await encryptAndSign( + payload, + senderCom.privateJwtKey!, + recipientCom.publicJwtKey!, + ) const args = new EncryptedTransferArgs() args.publicKey = senderCom.publicKey.toString('hex') args.jwt = jws @@ -523,7 +595,11 @@ describe('SendCoinsResolver', () => { }), ).toEqual( expect.objectContaining({ - errors: [new GraphQLError('settleSendCoins with wrong recipientCommunityUuid=invalid recipientCom')], + errors: [ + new GraphQLError( + 'settleSendCoins with wrong recipientCommunityUuid=invalid recipientCom', + ), + ], }), ) }) @@ -542,10 +618,14 @@ describe('SendCoinsResolver', () => { senderCom.communityUuid!, sendUser.gradidoID, fullName(sendUser.firstName, sendUser.lastName), - sendUser.alias + sendUser.alias, ) // invoke encryption as beeing on the foreignCom side to find in voteForSendCoins the correct homeCom - const jws = await encryptAndSign(payload, senderCom.privateJwtKey!, recipientCom.publicJwtKey!) + const jws = await encryptAndSign( + payload, + senderCom.privateJwtKey!, + recipientCom.publicJwtKey!, + ) const args = new EncryptedTransferArgs() args.publicKey = senderCom.publicKey.toString('hex') args.jwt = jws @@ -559,7 +639,8 @@ describe('SendCoinsResolver', () => { expect.objectContaining({ errors: [ new GraphQLError( - 'settleSendCoins with unknown recipientUserIdentifier in the community=' + recipientCom.name, + 'settleSendCoins with unknown recipientUserIdentifier in the community=' + + recipientCom.name, ), ], }), @@ -580,10 +661,14 @@ describe('SendCoinsResolver', () => { senderCom.communityUuid!, sendUser.gradidoID, fullName(sendUser.firstName, sendUser.lastName), - sendUser.alias + sendUser.alias, ) // invoke encryption as beeing on the foreignCom side to find in voteForSendCoins the correct homeCom - const jws = await encryptAndSign(payload, senderCom.privateJwtKey!, recipientCom.publicJwtKey!) + const jws = await encryptAndSign( + payload, + senderCom.privateJwtKey!, + recipientCom.publicJwtKey!, + ) const args = new EncryptedTransferArgs() args.publicKey = senderCom.publicKey.toString('hex') args.jwt = jws @@ -618,10 +703,14 @@ describe('SendCoinsResolver', () => { senderCom.communityUuid!, sendUser.gradidoID, fullName(sendUser.firstName, sendUser.lastName), - sendUser.alias + sendUser.alias, ) // invoke encryption as beeing on the foreignCom side to find in voteForSendCoins the correct homeCom - const jws = await encryptAndSign(payload, senderCom.privateJwtKey!, recipientCom.publicJwtKey!) + const jws = await encryptAndSign( + payload, + senderCom.privateJwtKey!, + recipientCom.publicJwtKey!, + ) const args = new EncryptedTransferArgs() args.publicKey = senderCom.publicKey.toString('hex') args.jwt = jws @@ -649,10 +738,14 @@ describe('SendCoinsResolver', () => { senderCom.communityUuid!, sendUser.gradidoID, fullName(sendUser.firstName, sendUser.lastName), - sendUser.alias + sendUser.alias, ) // invoke encryption as beeing on the foreignCom side to find in voteForSendCoins the correct homeCom - const jws = await encryptAndSign(payload, senderCom.privateJwtKey!, recipientCom.publicJwtKey!) + const jws = await encryptAndSign( + payload, + senderCom.privateJwtKey!, + recipientCom.publicJwtKey!, + ) const args = new EncryptedTransferArgs() args.publicKey = senderCom.publicKey.toString('hex') args.jwt = jws @@ -664,7 +757,11 @@ describe('SendCoinsResolver', () => { }), ).toEqual( expect.objectContaining({ - errors: [new GraphQLError('revertSettledSendCoins with wrong recipientCommunityUuid=invalid recipientCom')], + errors: [ + new GraphQLError( + 'revertSettledSendCoins with wrong recipientCommunityUuid=invalid recipientCom', + ), + ], }), ) }) @@ -683,10 +780,14 @@ describe('SendCoinsResolver', () => { senderCom.communityUuid!, sendUser.gradidoID, fullName(sendUser.firstName, sendUser.lastName), - sendUser.alias + sendUser.alias, ) // invoke encryption as beeing on the foreignCom side to find in voteForSendCoins the correct homeCom - const jws = await encryptAndSign(payload, senderCom.privateJwtKey!, recipientCom.publicJwtKey!) + const jws = await encryptAndSign( + payload, + senderCom.privateJwtKey!, + recipientCom.publicJwtKey!, + ) const args = new EncryptedTransferArgs() args.publicKey = senderCom.publicKey.toString('hex') args.jwt = jws @@ -700,7 +801,8 @@ describe('SendCoinsResolver', () => { expect.objectContaining({ errors: [ new GraphQLError( - 'revertSettledSendCoins with unknown recipientUserIdentifier in the community=' + recipientCom.name, + 'revertSettledSendCoins with unknown recipientUserIdentifier in the community=' + + recipientCom.name, ), ], }), @@ -721,10 +823,14 @@ describe('SendCoinsResolver', () => { senderCom.communityUuid!, sendUser.gradidoID, fullName(sendUser.firstName, sendUser.lastName), - sendUser.alias + sendUser.alias, ) // invoke encryption as beeing on the foreignCom side to find in voteForSendCoins the correct homeCom - const jws = await encryptAndSign(payload, senderCom.privateJwtKey!, recipientCom.publicJwtKey!) + const jws = await encryptAndSign( + payload, + senderCom.privateJwtKey!, + recipientCom.publicJwtKey!, + ) const args = new EncryptedTransferArgs() args.publicKey = senderCom.publicKey.toString('hex') args.jwt = jws diff --git a/federation/src/graphql/api/1_0/resolver/SendCoinsResolver.ts b/federation/src/graphql/api/1_0/resolver/SendCoinsResolver.ts index baaa376c5..4e6dc71d2 100644 --- a/federation/src/graphql/api/1_0/resolver/SendCoinsResolver.ts +++ b/federation/src/graphql/api/1_0/resolver/SendCoinsResolver.ts @@ -1,30 +1,35 @@ -import { fullName } from '@/graphql/util/fullName' -import { LogError } from '@/server/LogError' +import { EncryptedTransferArgs, interpretEncryptedTransferArgs } from 'core' import { + countOpenPendingTransactions, Community as DbCommunity, PendingTransaction as DbPendingTransaction, + findUserByIdentifier, PendingTransactionLoggingView, - findUserByIdentifier } from 'database' import Decimal from 'decimal.js-light' import { getLogger } from 'log4js' +import { + encryptAndSign, + PendingTransactionState, + SendCoinsJwtPayloadType, + SendCoinsResponseJwtPayloadType, + verifyAndDecrypt, +} from 'shared' import { Arg, Mutation, Resolver } from 'type-graphql' import { LOG4JS_BASE_CATEGORY_NAME } from '@/config/const' -import { encryptAndSign, PendingTransactionState, verifyAndDecrypt } from 'shared' +import { fullName } from '@/graphql/util/fullName' +import { LogError } from '@/server/LogError' import { TransactionTypeId } from '../enum/TransactionTypeId' import { SendCoinsArgsLoggingView } from '../logger/SendCoinsArgsLogging.view' import { SendCoinsArgs } from '../model/SendCoinsArgs' -import { SendCoinsResponseJwtPayloadType } from 'shared' import { calculateRecipientBalance } from '../util/calculateRecipientBalance' // import { checkTradingLevel } from '@/graphql/util/checkTradingLevel' import { revertSettledReceiveTransaction } from '../util/revertSettledReceiveTransaction' import { settlePendingReceiveTransaction } from '../util/settlePendingReceiveTransaction' import { storeForeignUser } from '../util/storeForeignUser' -import { countOpenPendingTransactions } from 'database' -import { EncryptedTransferArgs } from 'core' -import { interpretEncryptedTransferArgs } from 'core' -import { SendCoinsJwtPayloadType } from 'shared' -const createLogger = (method: string) => getLogger(`${LOG4JS_BASE_CATEGORY_NAME}.graphql.api.1_0.resolver.SendCoinsResolver.${method}`) + +const createLogger = (method: string) => + getLogger(`${LOG4JS_BASE_CATEGORY_NAME}.graphql.api.1_0.resolver.SendCoinsResolver.${method}`) @Resolver() export class SendCoinsResolver { @@ -35,16 +40,17 @@ export class SendCoinsResolver { ): Promise { const methodLogger = createLogger(`voteForSendCoins`) methodLogger.addContext('handshakeID', args.handshakeID) - if(methodLogger.isDebugEnabled()) { + if (methodLogger.isDebugEnabled()) { methodLogger.debug(`voteForSendCoins() via apiVersion=1_0 ...`, args) } - const authArgs = await interpretEncryptedTransferArgs(args) as SendCoinsJwtPayloadType + const authArgs = (await interpretEncryptedTransferArgs(args)) as SendCoinsJwtPayloadType if (!authArgs) { - const errmsg = `invalid authentication payload of requesting community with publicKey` + args.publicKey + const errmsg = + `invalid authentication payload of requesting community with publicKey` + args.publicKey methodLogger.error(errmsg) throw new Error(errmsg) } - if(methodLogger.isDebugEnabled()) { + if (methodLogger.isDebugEnabled()) { methodLogger.debug(`voteForSendCoins() via apiVersion=1_0 ...`, authArgs) } // first check if receiver community is correct @@ -65,19 +71,23 @@ export class SendCoinsResolver { throw new Error(errmsg) } let receiverUser - + // second check if receiver user exists in this community receiverUser = await findUserByIdentifier( authArgs.recipientUserIdentifier, authArgs.recipientCommunityUuid, ) if (!receiverUser) { - const errmsg = `voteForSendCoins with unknown recipientUserIdentifier in the community=` + recipientCom.name + const errmsg = + `voteForSendCoins with unknown recipientUserIdentifier in the community=` + + recipientCom.name methodLogger.error(errmsg) throw new Error(errmsg) } - - if (await countOpenPendingTransactions([authArgs.senderUserUuid, receiverUser.gradidoID]) > 0) { + + if ( + (await countOpenPendingTransactions([authArgs.senderUserUuid, receiverUser.gradidoID])) > 0 + ) { const errmsg = `There exist still ongoing 'Pending-Transactions' for the involved users on receiver-side!` methodLogger.error(errmsg) throw new Error(errmsg) @@ -85,7 +95,11 @@ export class SendCoinsResolver { try { const txDate = new Date(authArgs.creationDate) - const receiveBalance = await calculateRecipientBalance(receiverUser.id, authArgs.amount, txDate) + const receiveBalance = await calculateRecipientBalance( + receiverUser.id, + authArgs.amount, + txDate, + ) const pendingTx = DbPendingTransaction.create() pendingTx.amount = authArgs.amount pendingTx.balance = receiveBalance ? receiveBalance.balance : authArgs.amount @@ -115,7 +129,11 @@ export class SendCoinsResolver { receiverUser.lastName, receiverUser.alias, ) - const responseJwt = await encryptAndSign(responseArgs, recipientCom.privateJwtKey!, senderCom.publicJwtKey!) + const responseJwt = await encryptAndSign( + responseArgs, + recipientCom.privateJwtKey!, + senderCom.publicJwtKey!, + ) methodLogger.debug(`voteForSendCoins()-1_0... successfull`) return responseJwt } catch (err) { @@ -132,16 +150,16 @@ export class SendCoinsResolver { ): Promise { const methodLogger = createLogger(`revertSendCoins`) methodLogger.addContext('handshakeID', args.handshakeID) - if(methodLogger.isDebugEnabled()) { + if (methodLogger.isDebugEnabled()) { methodLogger.debug(`revertSendCoins() via apiVersion=1_0 ...`) } - const authArgs = await interpretEncryptedTransferArgs(args) as SendCoinsJwtPayloadType + const authArgs = (await interpretEncryptedTransferArgs(args)) as SendCoinsJwtPayloadType if (!authArgs) { const errmsg = `invalid revertSendCoins payload of requesting community with publicKey=${args.publicKey}` methodLogger.error(errmsg) throw new Error(errmsg) } - if(methodLogger.isDebugEnabled()) { + if (methodLogger.isDebugEnabled()) { methodLogger.debug(`revertSendCoins() via apiVersion=1_0 ...`, authArgs) } // first check if receiver community is correct @@ -154,7 +172,7 @@ export class SendCoinsResolver { throw new Error(errmsg) } let receiverUser - + // second check if receiver user exists in this community receiverUser = await findUserByIdentifier(authArgs.recipientUserIdentifier) if (!receiverUser) { @@ -172,7 +190,7 @@ export class SendCoinsResolver { linkedUserCommunityUuid: authArgs.senderCommunityUuid, linkedUserGradidoID: authArgs.senderUserUuid, }) - if(methodLogger.isDebugEnabled()) { + if (methodLogger.isDebugEnabled()) { methodLogger.debug( 'XCom: revertSendCoins found pendingTX=', pendingTx ? new PendingTransactionLoggingView(pendingTx) : 'null', @@ -194,11 +212,13 @@ export class SendCoinsResolver { pendingTx?.amount.toString(), authArgs.amount.toString(), ) - const errmsg = `Can't find in revertSendCoins the pending receiver TX for ` + { - args: new SendCoinsArgsLoggingView(authArgs), - pendingTransactionState: PendingTransactionState.NEW, - transactionType: TransactionTypeId.RECEIVE, - } + const errmsg = + `Can't find in revertSendCoins the pending receiver TX for ` + + { + args: new SendCoinsArgsLoggingView(authArgs), + pendingTransactionState: PendingTransactionState.NEW, + transactionType: TransactionTypeId.RECEIVE, + } methodLogger.error(errmsg) throw new Error(errmsg) } @@ -218,16 +238,16 @@ export class SendCoinsResolver { ): Promise { const methodLogger = createLogger(`settleSendCoins`) methodLogger.addContext('handshakeID', args.handshakeID) - if(methodLogger.isDebugEnabled()) { + if (methodLogger.isDebugEnabled()) { methodLogger.debug(`settleSendCoins() via apiVersion=1_0 ...`, args) } - const authArgs = await interpretEncryptedTransferArgs(args) as SendCoinsJwtPayloadType + const authArgs = (await interpretEncryptedTransferArgs(args)) as SendCoinsJwtPayloadType if (!authArgs) { const errmsg = `invalid settleSendCoins payload of requesting community with publicKey=${args.publicKey}` methodLogger.error(errmsg) throw new Error(errmsg) } - if(methodLogger.isDebugEnabled()) { + if (methodLogger.isDebugEnabled()) { methodLogger.debug(`settleSendCoins() via apiVersion=1_0 ...`, authArgs) } // first check if receiver community is correct @@ -239,7 +259,7 @@ export class SendCoinsResolver { methodLogger.error(errmsg) throw new Error(errmsg) } - + // second check if receiver user exists in this community const receiverUser = await findUserByIdentifier(authArgs.recipientUserIdentifier) if (!receiverUser) { @@ -256,7 +276,7 @@ export class SendCoinsResolver { linkedUserCommunityUuid: authArgs.senderCommunityUuid, linkedUserGradidoID: authArgs.senderUserUuid, }) - if(methodLogger.isDebugEnabled()) { + if (methodLogger.isDebugEnabled()) { methodLogger.debug( 'XCom: settleSendCoins found pendingTX=', pendingTx ? new PendingTransactionLoggingView(pendingTx) : 'null', @@ -283,10 +303,14 @@ export class SendCoinsResolver { methodLogger.debug(`XCom: settlePendingReceiveTransaction()-1_0... successful`) return true } else { - methodLogger.debug('XCom: settlePendingReceiveTransaction NOT matching pendingTX for settlement...') - const errmsg = `Can't find in settlePendingReceiveTransaction the pending receiver TX for ` + { - args: new SendCoinsArgsLoggingView(authArgs), - pendingTransactionState: PendingTransactionState.NEW, + methodLogger.debug( + 'XCom: settlePendingReceiveTransaction NOT matching pendingTX for settlement...', + ) + const errmsg = + `Can't find in settlePendingReceiveTransaction the pending receiver TX for ` + + { + args: new SendCoinsArgsLoggingView(authArgs), + pendingTransactionState: PendingTransactionState.NEW, transactionTypeId: TransactionTypeId.RECEIVE, } methodLogger.error(errmsg) @@ -301,16 +325,16 @@ export class SendCoinsResolver { ): Promise { const methodLogger = createLogger(`revertSettledSendCoins`) methodLogger.addContext('handshakeID', args.handshakeID) - if(methodLogger.isDebugEnabled()) { + if (methodLogger.isDebugEnabled()) { methodLogger.debug(`revertSettledSendCoins() via apiVersion=1_0 ...`) } - const authArgs = await interpretEncryptedTransferArgs(args) as SendCoinsJwtPayloadType + const authArgs = (await interpretEncryptedTransferArgs(args)) as SendCoinsJwtPayloadType if (!authArgs) { const errmsg = `invalid revertSettledSendCoins payload of requesting community with publicKey=${args.publicKey}` methodLogger.error(errmsg) throw new Error(errmsg) } - if(methodLogger.isDebugEnabled()) { + if (methodLogger.isDebugEnabled()) { methodLogger.debug(`revertSettledSendCoins() via apiVersion=1_0 ...`, authArgs) } // first check if receiver community is correct @@ -321,8 +345,8 @@ export class SendCoinsResolver { const errmsg = `revertSettledSendCoins with wrong recipientCommunityUuid=${authArgs.recipientCommunityUuid}` methodLogger.error(errmsg) throw new Error(errmsg) - } - + } + // second check if receiver user exists in this community const receiverUser = await findUserByIdentifier(authArgs.recipientUserIdentifier) if (!receiverUser) { @@ -359,11 +383,13 @@ export class SendCoinsResolver { } } else { methodLogger.debug('XCom: revertSettledSendCoins NOT matching pendingTX...') - const errmsg = `Can't find in revertSettledSendCoins the pending receiver TX for ` + { - args: new SendCoinsArgsLoggingView(authArgs), - pendingTransactionState: PendingTransactionState.SETTLED, - transactionTypeId: TransactionTypeId.RECEIVE, - } + const errmsg = + `Can't find in revertSettledSendCoins the pending receiver TX for ` + + { + args: new SendCoinsArgsLoggingView(authArgs), + pendingTransactionState: PendingTransactionState.SETTLED, + transactionTypeId: TransactionTypeId.RECEIVE, + } methodLogger.error(errmsg) throw new Error(errmsg) } diff --git a/federation/src/graphql/api/1_0/schema.ts b/federation/src/graphql/api/1_0/schema.ts index fcb05c803..90ed13cb1 100644 --- a/federation/src/graphql/api/1_0/schema.ts +++ b/federation/src/graphql/api/1_0/schema.ts @@ -6,5 +6,11 @@ import { PublicKeyResolver } from './resolver/PublicKeyResolver' import { SendCoinsResolver } from './resolver/SendCoinsResolver' export const getApiResolvers = (): NonEmptyArray => { - return [AuthenticationResolver, DisbursementResolver, PublicCommunityInfoResolver, PublicKeyResolver, SendCoinsResolver] + return [ + AuthenticationResolver, + DisbursementResolver, + PublicCommunityInfoResolver, + PublicKeyResolver, + SendCoinsResolver, + ] } diff --git a/federation/src/graphql/api/1_0/util/authenticateCommunity.ts b/federation/src/graphql/api/1_0/util/authenticateCommunity.ts index 4b95898ba..a57aebd3b 100644 --- a/federation/src/graphql/api/1_0/util/authenticateCommunity.ts +++ b/federation/src/graphql/api/1_0/util/authenticateCommunity.ts @@ -1,7 +1,14 @@ -import { CommunityHandshakeStateLogic, EncryptedTransferArgs, ensureUrlEndsWithSlash } from 'core' +import { + CommunityHandshakeStateLogic, + EncryptedTransferArgs, + ensureUrlEndsWithSlash, + getFederatedCommunityWithApiOrFail, +} from 'core' import { CommunityHandshakeStateLoggingView, + CommunityHandshakeStateType, Community as DbCommunity, + CommunityHandshakeState as DbCommunityHandshakeState, FederatedCommunity as DbFedCommunity, findPendingCommunityHandshake, getCommunityByPublicKeyOrFail, @@ -9,25 +16,22 @@ import { getHomeCommunityWithFederatedCommunityOrFail, } from 'database' import { getLogger } from 'log4js' - -import { AuthenticationClientFactory } from '@/client/AuthenticationClientFactory' -import { randombytes_random } from 'sodium-native' - -import { AuthenticationClient as V1_0_AuthenticationClient } from '@/client/1_0/AuthenticationClient' -import { LOG4JS_BASE_CATEGORY_NAME } from '@/config/const' -import { - AuthenticationJwtPayloadType, - AuthenticationResponseJwtPayloadType, - Ed25519PublicKey, - encryptAndSign, - OpenConnectionCallbackJwtPayloadType, - uuidv4Schema, - verifyAndDecrypt +import { + AuthenticationJwtPayloadType, + AuthenticationResponseJwtPayloadType, + Ed25519PublicKey, + encryptAndSign, + OpenConnectionCallbackJwtPayloadType, + uuidv4Schema, + verifyAndDecrypt, } from 'shared' -import { CommunityHandshakeState as DbCommunityHandshakeState, CommunityHandshakeStateType } from 'database' -import { getFederatedCommunityWithApiOrFail } from 'core' +import { randombytes_random } from 'sodium-native' +import { AuthenticationClient as V1_0_AuthenticationClient } from '@/client/1_0/AuthenticationClient' +import { AuthenticationClientFactory } from '@/client/AuthenticationClientFactory' +import { LOG4JS_BASE_CATEGORY_NAME } from '@/config/const' -const createLogger = (method: string ) => getLogger(`${LOG4JS_BASE_CATEGORY_NAME}.graphql.api.1_0.util.authenticateCommunity.${method}`) +const createLogger = (method: string) => + getLogger(`${LOG4JS_BASE_CATEGORY_NAME}.graphql.api.1_0.util.authenticateCommunity.${method}`) export async function startOpenConnectionCallback( handshakeID: string, @@ -41,13 +45,20 @@ export async function startOpenConnectionCallback( let state: DbCommunityHandshakeState | null = null try { - const pendingState = await findPendingCommunityHandshake(publicKey, api, CommunityHandshakeStateType.START_OPEN_CONNECTION_CALLBACK) + const pendingState = await findPendingCommunityHandshake( + publicKey, + api, + CommunityHandshakeStateType.START_OPEN_CONNECTION_CALLBACK, + ) if (pendingState) { const stateLogic = new CommunityHandshakeStateLogic(pendingState) // retry on timeout or failure if (!(await stateLogic.isTimeoutUpdate())) { // authentication with community and api version is still in progress and it is not timeout yet - methodLogger.debug('existingState, so we exit here', new CommunityHandshakeStateLoggingView(pendingState)) + methodLogger.debug( + 'existingState, so we exit here', + new CommunityHandshakeStateLoggingView(pendingState), + ) return } } @@ -59,12 +70,12 @@ export async function startOpenConnectionCallback( ]) // get federated communities with correct api version // simply check and extract federated community from community of given api version or throw error if not found - const homeFedComB = getFederatedCommunityWithApiOrFail(homeComB, api) - + const homeFedComB = getFederatedCommunityWithApiOrFail(homeComB, api) + // TODO: make sure it is unique const oneTimeCode = randombytes_random() const oneTimeCodeString = oneTimeCode.toString() - + // Create new community handshake state state = new DbCommunityHandshakeState() state.publicKey = publicKey.asBuffer() @@ -80,7 +91,11 @@ export async function startOpenConnectionCallback( if (client instanceof V1_0_AuthenticationClient) { const url = ensureUrlEndsWithSlash(homeFedComB.endPoint) + homeFedComB.apiVersion - const callbackArgs = new OpenConnectionCallbackJwtPayloadType(handshakeID, oneTimeCodeString, url) + const callbackArgs = new OpenConnectionCallbackJwtPayloadType( + handshakeID, + oneTimeCodeString, + url, + ) // methodLogger.debug(`Authentication: start openConnectionCallback with args:`, callbackArgs) // encrypt callbackArgs with requestedCom.publicJwtKey and sign it with homeCom.privateJwtKey const jwt = await encryptAndSign(callbackArgs, homeComB.privateJwtKey!, comA.publicJwtKey!) @@ -108,7 +123,7 @@ export async function startOpenConnectionCallback( state.status = CommunityHandshakeStateType.FAILED state.lastError = String(err) state = await state.save() - } catch(e) { + } catch (e) { methodLogger.error('error on saving CommunityHandshakeState', e) } } @@ -134,12 +149,16 @@ export async function startAuthentication( if (!comB.publicJwtKey) { throw new Error('Public JWT key still not exist for foreign community') } - state = await findPendingCommunityHandshake(fedComBPublicKey, fedComB.apiVersion, CommunityHandshakeStateType.START_COMMUNITY_AUTHENTICATION) + state = await findPendingCommunityHandshake( + fedComBPublicKey, + fedComB.apiVersion, + CommunityHandshakeStateType.START_COMMUNITY_AUTHENTICATION, + ) if (!state) { throw new Error('No pending community handshake found') } const stateLogic = new CommunityHandshakeStateLogic(state) - if ((await stateLogic.isTimeoutUpdate())) { + if (await stateLogic.isTimeoutUpdate()) { methodLogger.debug('invalid state', new CommunityHandshakeStateLoggingView(state)) throw new Error('No valid pending community handshake found') } @@ -149,9 +168,17 @@ export async function startAuthentication( const client = AuthenticationClientFactory.getInstance(fedComB) if (client instanceof V1_0_AuthenticationClient) { - const authenticationArgs = new AuthenticationJwtPayloadType(handshakeID, oneTimeCode, homeComA!.communityUuid!) + const authenticationArgs = new AuthenticationJwtPayloadType( + handshakeID, + oneTimeCode, + homeComA!.communityUuid!, + ) // encrypt authenticationArgs.uuid with fedComB.publicJwtKey and sign it with homeCom.privateJwtKey - const jwt = await encryptAndSign(authenticationArgs, homeComA!.privateJwtKey!, comB.publicJwtKey!) + const jwt = await encryptAndSign( + authenticationArgs, + homeComA!.privateJwtKey!, + comB.publicJwtKey!, + ) const args = new EncryptedTransferArgs() args.publicKey = new Ed25519PublicKey(homeComA!.publicKey).asHex() args.jwt = jwt @@ -161,23 +188,34 @@ export async function startAuthentication( // methodLogger.debug(`response of authenticate():`, responseJwt) if (responseJwt !== null) { - const payload = await verifyAndDecrypt(handshakeID, responseJwt, homeComA!.privateJwtKey!, comB.publicJwtKey!) as AuthenticationResponseJwtPayloadType + const payload = (await verifyAndDecrypt( + handshakeID, + responseJwt, + homeComA!.privateJwtKey!, + comB.publicJwtKey!, + )) as AuthenticationResponseJwtPayloadType /*methodLogger.debug( `received payload from authenticate ComB:`, payload, new FederatedCommunityLoggingView(fedComB), )*/ - if (payload.tokentype !== AuthenticationResponseJwtPayloadType.AUTHENTICATION_RESPONSE_TYPE) { - throw new Error(`Invalid tokentype in authenticate-response of community with publicKey ${fedComBPublicKey.asHex()}`) + if ( + payload.tokentype !== AuthenticationResponseJwtPayloadType.AUTHENTICATION_RESPONSE_TYPE + ) { + throw new Error( + `Invalid tokentype in authenticate-response of community with publicKey ${fedComBPublicKey.asHex()}`, + ) } const parsedUuidv4 = uuidv4Schema.safeParse(payload.uuid) if (!parsedUuidv4.success) { - throw new Error(`Invalid uuid in authenticate-response of community with publicKey ${fedComBPublicKey.asHex()}`) + throw new Error( + `Invalid uuid in authenticate-response of community with publicKey ${fedComBPublicKey.asHex()}`, + ) } methodLogger.debug('received uuid from authenticate ComB:', parsedUuidv4.data) comB.communityUuid = parsedUuidv4.data comB.authenticatedAt = new Date() - await DbCommunity.save(comB) + await DbCommunity.save(comB) state.status = CommunityHandshakeStateType.SUCCESS await state.save() methodLogger.debug('[SUCCESS] community handshake state updated') @@ -198,10 +236,9 @@ export async function startAuthentication( state.status = CommunityHandshakeStateType.FAILED state.lastError = String(err) await state.save() - } catch(e) { + } catch (e) { methodLogger.error('error on saving CommunityHandshakeState', e) } } - } } diff --git a/federation/src/graphql/api/1_0/util/calculateRecipientBalance.ts b/federation/src/graphql/api/1_0/util/calculateRecipientBalance.ts index ead2cc641..f07a0c4d6 100644 --- a/federation/src/graphql/api/1_0/util/calculateRecipientBalance.ts +++ b/federation/src/graphql/api/1_0/util/calculateRecipientBalance.ts @@ -1,6 +1,6 @@ +import { Decimal } from 'decimal.js-light' import { calculateDecay } from 'shared' import { getLastTransaction } from '@/graphql/util/getLastTransaction' -import { Decimal } from 'decimal.js-light' import { Decay } from '../model/Decay' export async function calculateRecipientBalance( @@ -13,7 +13,9 @@ export async function calculateRecipientBalance( return null } - const decay = new Decay(calculateDecay(lastTransaction.balance, lastTransaction.balanceDate, time)) + const decay = new Decay( + calculateDecay(lastTransaction.balance, lastTransaction.balanceDate, time), + ) const balance = decay.balance.add(amount.toString()) diff --git a/federation/src/graphql/api/1_0/util/revertSettledReceiveTransaction.ts b/federation/src/graphql/api/1_0/util/revertSettledReceiveTransaction.ts index 9b311be30..8b6710d97 100644 --- a/federation/src/graphql/api/1_0/util/revertSettledReceiveTransaction.ts +++ b/federation/src/graphql/api/1_0/util/revertSettledReceiveTransaction.ts @@ -4,23 +4,23 @@ import { Community as DbCommunity, PendingTransaction as DbPendingTransaction, User as DbUser, + Transaction as dbTransaction, PendingTransactionLoggingView, TransactionLoggingView, UserLoggingView, - Transaction as dbTransaction, } from 'database' - -import { PendingTransactionState } from 'shared' - -import { LogError } from '@/server/LogError' import { getLogger } from 'log4js' +import { PendingTransactionState } from 'shared' import { LOG4JS_BASE_CATEGORY_NAME } from '@/config/const' - -import { TRANSACTIONS_LOCK } from '@/graphql/util/TRANSACTIONS_LOCK' import { getLastTransaction } from '@/graphql/util/getLastTransaction' +import { TRANSACTIONS_LOCK } from '@/graphql/util/TRANSACTIONS_LOCK' +import { LogError } from '@/server/LogError' + const db = AppDatabase.getInstance() -const logger = getLogger(`${LOG4JS_BASE_CATEGORY_NAME}.graphql.api.1_0.util.revertSettledReceiveTransaction`) +const logger = getLogger( + `${LOG4JS_BASE_CATEGORY_NAME}.graphql.api.1_0.util.revertSettledReceiveTransaction`, +) export async function revertSettledReceiveTransaction( homeCom: DbCommunity, diff --git a/federation/src/graphql/api/1_0/util/settlePendingReceiveTransaction.ts b/federation/src/graphql/api/1_0/util/settlePendingReceiveTransaction.ts index 6035aa442..89592f129 100644 --- a/federation/src/graphql/api/1_0/util/settlePendingReceiveTransaction.ts +++ b/federation/src/graphql/api/1_0/util/settlePendingReceiveTransaction.ts @@ -4,24 +4,24 @@ import { Community as DbCommunity, PendingTransaction as DbPendingTransaction, User as DbUser, + Transaction as dbTransaction, PendingTransactionLoggingView, TransactionLoggingView, UserLoggingView, - Transaction as dbTransaction, } from 'database' -import { PendingTransactionState } from 'shared' - -import { LogError } from '@/server/LogError' - -import { TRANSACTIONS_LOCK } from '@/graphql/util/TRANSACTIONS_LOCK' -import { getLastTransaction } from '@/graphql/util/getLastTransaction' import Decimal from 'decimal.js-light' import { getLogger } from 'log4js' +import { PendingTransactionState } from 'shared' import { LOG4JS_BASE_CATEGORY_NAME } from '@/config/const' +import { getLastTransaction } from '@/graphql/util/getLastTransaction' +import { TRANSACTIONS_LOCK } from '@/graphql/util/TRANSACTIONS_LOCK' +import { LogError } from '@/server/LogError' import { calculateRecipientBalance } from './calculateRecipientBalance' const db = AppDatabase.getInstance() -const logger = getLogger(`${LOG4JS_BASE_CATEGORY_NAME}.graphql.api.1_0.util.settlePendingReceiveTransaction`) +const logger = getLogger( + `${LOG4JS_BASE_CATEGORY_NAME}.graphql.api.1_0.util.settlePendingReceiveTransaction`, +) export async function settlePendingReceiveTransaction( homeCom: DbCommunity, diff --git a/federation/src/graphql/api/1_1/resolver/PublicKeyResolver.test.ts b/federation/src/graphql/api/1_1/resolver/PublicKeyResolver.test.ts index 40db6db76..f28e297b9 100644 --- a/federation/src/graphql/api/1_1/resolver/PublicKeyResolver.test.ts +++ b/federation/src/graphql/api/1_1/resolver/PublicKeyResolver.test.ts @@ -1,9 +1,9 @@ -import { CONFIG } from '@/config' -import { LOG4JS_BASE_CATEGORY_NAME } from '@/config/const' -import { createServer } from '@/server/createServer' import { createTestClient } from 'apollo-server-testing' import { FederatedCommunity as DbFederatedCommunity } from 'database' import { getLogger } from 'log4js' +import { CONFIG } from '@/config' +import { LOG4JS_BASE_CATEGORY_NAME } from '@/config/const' +import { createServer } from '@/server/createServer' let query: any diff --git a/federation/src/graphql/schema.ts b/federation/src/graphql/schema.ts index a5d498048..a1aa3cac2 100644 --- a/federation/src/graphql/schema.ts +++ b/federation/src/graphql/schema.ts @@ -1,7 +1,6 @@ +import { Decimal } from 'decimal.js-light' import { GraphQLSchema } from 'graphql' import { buildSchema } from 'type-graphql' - -import { Decimal } from 'decimal.js-light' import { getApiResolvers } from './api/schema' // import isAuthorized from './directive/isAuthorized' import { DecimalScalar } from './scalar/Decimal' diff --git a/federation/src/graphql/util/checkTradingLevel.ts b/federation/src/graphql/util/checkTradingLevel.ts index 2a96f34f9..6867ce127 100644 --- a/federation/src/graphql/util/checkTradingLevel.ts +++ b/federation/src/graphql/util/checkTradingLevel.ts @@ -1,7 +1,7 @@ -import { CONFIG } from '@/config' import { Community as DbCommunity } from 'database' import { Decimal } from 'decimal.js-light' import { getLogger } from 'log4js' +import { CONFIG } from '@/config' import { LOG4JS_BASE_CATEGORY_NAME } from '@/config/const' export async function checkTradingLevel(homeCom: DbCommunity, amount: Decimal): Promise { diff --git a/federation/src/index.ts b/federation/src/index.ts index c9f58b0e5..421934c58 100644 --- a/federation/src/index.ts +++ b/federation/src/index.ts @@ -1,12 +1,12 @@ import 'source-map-support/register' -import { createServer } from './server/createServer' import { defaultCategory, initLogger } from 'config-schema' import { getLogger } from 'log4js' +import { onShutdown, printServerCrashAsciiArt, ShutdownReason } from 'shared' // config import { CONFIG } from './config' import { LOG4JS_BASE_CATEGORY_NAME } from './config/const' -import { onShutdown, printServerCrashAsciiArt, ShutdownReason } from 'shared' +import { createServer } from './server/createServer' async function main() { const startTime = new Date() @@ -35,7 +35,11 @@ async function main() { } else { const endTime = new Date() const duration = endTime.getTime() - startTime.getTime() - printServerCrashAsciiArt('Server Crash', `reason: ${reason}`, `server was ${duration}ms online`) + printServerCrashAsciiArt( + 'Server Crash', + `reason: ${reason}`, + `server was ${duration}ms online`, + ) logger.error(error) } }) diff --git a/federation/src/server/LogError.ts b/federation/src/server/LogError.ts index 0a91b17c6..0a0b89b41 100644 --- a/federation/src/server/LogError.ts +++ b/federation/src/server/LogError.ts @@ -1,5 +1,5 @@ -import { LOG4JS_BASE_CATEGORY_NAME } from '@/config/const' import { getLogger } from 'log4js' +import { LOG4JS_BASE_CATEGORY_NAME } from '@/config/const' /** * A custom Error that logs itself immediately upon instantiation. diff --git a/federation/src/server/createServer.ts b/federation/src/server/createServer.ts index d8cb0f473..fc25d722b 100644 --- a/federation/src/server/createServer.ts +++ b/federation/src/server/createServer.ts @@ -1,21 +1,18 @@ import 'reflect-metadata' import { ApolloServer } from 'apollo-server-express' -import express, { Express } from 'express' - -// server -import { cors } from './cors' -// import serverContext from './context' -import { plugins } from './plugins' - -// graphql -import { schema } from '@/graphql/schema' - import { AppDatabase } from 'database' +import express, { Express } from 'express' import { slowDown } from 'express-slow-down' import helmet from 'helmet' import { Logger } from 'log4js' import { DataSource } from 'typeorm' +// graphql +import { schema } from '@/graphql/schema' +// server +import { cors } from './cors' +// import serverContext from './context' +import { plugins } from './plugins' // i18n // import { i18n } from './localization' diff --git a/shared/src/const/index.ts b/shared/src/const/index.ts index 97fe8f306..76990ffc8 100644 --- a/shared/src/const/index.ts +++ b/shared/src/const/index.ts @@ -3,4 +3,4 @@ export const SECONDS_PER_YEAR_GREGORIAN_CALENDER = 31556952.0 export const LOG4JS_BASE_CATEGORY_NAME = 'shared' export const REDEEM_JWT_TOKEN_EXPIRATION = '10m' // 10 minutes -export const FEDERATION_AUTHENTICATION_TIMEOUT_MS = 60 * 1000 * 10 \ No newline at end of file +export const FEDERATION_AUTHENTICATION_TIMEOUT_MS = 60 * 1000 * 10 diff --git a/shared/src/enum/OptInType.ts b/shared/src/enum/OptInType.ts index 1f6300b39..9d6121980 100644 --- a/shared/src/enum/OptInType.ts +++ b/shared/src/enum/OptInType.ts @@ -5,4 +5,4 @@ export enum OptInType { EMAIL_OPT_IN_RESET_PASSWORD = 2, } -// export const OptInTypeSchema = zEnum(OptInType) \ No newline at end of file +// export const OptInTypeSchema = zEnum(OptInType) diff --git a/shared/src/enum/PasswordEncryptionType.ts b/shared/src/enum/PasswordEncryptionType.ts index 13b72be0c..ab8f23d7d 100644 --- a/shared/src/enum/PasswordEncryptionType.ts +++ b/shared/src/enum/PasswordEncryptionType.ts @@ -8,4 +8,3 @@ export enum PasswordEncryptionType { } // export const PasswordEncryptionTypeSchema = zEnum(PasswordEncryptionType) - diff --git a/shared/src/enum/index.ts b/shared/src/enum/index.ts index adadf38ce..9ea1fa0aa 100644 --- a/shared/src/enum/index.ts +++ b/shared/src/enum/index.ts @@ -1,5 +1,5 @@ +export * from './OptInType' +export * from './PasswordEncryptionType' +export * from './PendingTransactionState' export * from './RoleNames' export * from './UserContactType' -export * from './PasswordEncryptionType' -export * from './OptInType' -export * from './PendingTransactionState' diff --git a/shared/src/helper/BinaryData.ts b/shared/src/helper/BinaryData.ts index 37d63b156..ba6c2dd32 100644 --- a/shared/src/helper/BinaryData.ts +++ b/shared/src/helper/BinaryData.ts @@ -4,7 +4,7 @@ import { LOG4JS_BASE_CATEGORY_NAME } from '../const' const logging = getLogger(`${LOG4JS_BASE_CATEGORY_NAME}.helper.BinaryData`) /** - * Class mainly for handling ed25519 public keys, + * Class mainly for handling ed25519 public keys, * to make sure we have always the correct Format (Buffer or Hex String) */ export class BinaryData { @@ -48,4 +48,4 @@ export class Ed25519PublicKey extends BinaryData { throw new Error('Invalid ed25519 public key length') } } -} \ No newline at end of file +} diff --git a/shared/src/helper/index.ts b/shared/src/helper/index.ts index 9170aad49..85de0555b 100644 --- a/shared/src/helper/index.ts +++ b/shared/src/helper/index.ts @@ -1,3 +1,3 @@ -export * from './updateField' export * from './BinaryData' -export * from './onShutdown' \ No newline at end of file +export * from './onShutdown' +export * from './updateField' diff --git a/shared/src/helper/onShutdown.ts b/shared/src/helper/onShutdown.ts index ea24bf2fc..baba43b6a 100644 --- a/shared/src/helper/onShutdown.ts +++ b/shared/src/helper/onShutdown.ts @@ -7,14 +7,15 @@ export enum ShutdownReason { UNCAUGHT_REJECTION = 'UNCAUGHT_REJECTION', } - /** * Setup graceful shutdown for the process * @param gracefulShutdown will be called if process is terminated */ -export function onShutdown(shutdownHandler: (reason: ShutdownReason, error?: Error | any) => Promise) { +export function onShutdown( + shutdownHandler: (reason: ShutdownReason, error?: Error | any) => Promise, +) { const signals: NodeJS.Signals[] = ['SIGINT', 'SIGTERM'] - signals.forEach(sig => { + signals.forEach((sig) => { process.on(sig, async () => { await shutdownHandler(sig as ShutdownReason) process.exit(0) @@ -31,13 +32,13 @@ export function onShutdown(shutdownHandler: (reason: ShutdownReason, error?: Err process.exit(1) }) - if (process.platform === "win32") { - const rl = require("readline").createInterface({ + if (process.platform === 'win32') { + const rl = require('readline').createInterface({ input: process.stdin, output: process.stdout, }) - rl.on("SIGINT", () => { - process.emit("SIGINT" as any) + rl.on('SIGINT', () => { + process.emit('SIGINT' as any) }) } } @@ -49,4 +50,4 @@ export function printServerCrashAsciiArt(msg1: string, msg2: string, msg3: strin console.error(colors.redBright(` > < ${msg3}`)) console.error(colors.redBright('')) // biome-ignore-end lint/suspicious/noConsole: Server Crash Ascii Art is for console and stdout -} \ No newline at end of file +} diff --git a/shared/src/helper/updateField.test.ts b/shared/src/helper/updateField.test.ts index 4eb6d84e4..1675b2241 100644 --- a/shared/src/helper/updateField.test.ts +++ b/shared/src/helper/updateField.test.ts @@ -34,7 +34,7 @@ describe('updateIfDefinedAndChanged', () => { describe('updateAllDefinedAndChanged', () => { it('should update all fields if incoming is different from current', () => { - type TestEntity = { field1: string | null, field2: string | null, field3: string | null } + type TestEntity = { field1: string | null; field2: string | null; field3: string | null } const current: TestEntity = { field1: 'current', field2: 'current', field3: 'current' } const incoming = { field1: 'incoming', field2: 'incoming', otherField: 'incoming' } const result = updateAllDefinedAndChanged(current, incoming) @@ -56,7 +56,7 @@ describe('updateAllDefinedAndChanged', () => { expect(current).toEqual({ field1: 'current', field2: 'current' }) }) it('should update field if incoming is null', () => { - type TestEntity = { field1: string | null, field2: string | null } + type TestEntity = { field1: string | null; field2: string | null } type TestInput = { field1: string | null } const current: TestEntity = { field1: 'current', field2: 'current' } const incoming: TestInput = { field1: null } @@ -65,4 +65,3 @@ describe('updateAllDefinedAndChanged', () => { expect(current).toEqual({ field1: null, field2: 'current' }) }) }) - diff --git a/shared/src/helper/updateField.ts b/shared/src/helper/updateField.ts index 0f7008628..d143d61e3 100644 --- a/shared/src/helper/updateField.ts +++ b/shared/src/helper/updateField.ts @@ -8,10 +8,10 @@ export function updateIfDefinedAndChanged( entity: T, key: K, - incoming: T[K] | undefined + incoming: T[K] | undefined, ): boolean { if (typeof incoming === 'undefined') { - return false + return false } // Object.is compare actual values and return true if they are identical if (Object.is(entity[key], incoming)) { @@ -22,18 +22,21 @@ export function updateIfDefinedAndChanged( } /** - * Check all keys of incoming and if exist on entity, call {@link updateIfDefinedAndChanged} + * Check all keys of incoming and if exist on entity, call {@link updateIfDefinedAndChanged} * to update entity if value isn't undefined and not equal to current value. * @param entity The entity to update. * @param incoming The incoming values to update the entity with. * @returns True if at least one field was updated, false otherwise. */ -export function updateAllDefinedAndChanged(entity: T, incoming: Partial): boolean { - let updated = false - for (const [key, value] of Object.entries(incoming)) { - if (key in entity && updateIfDefinedAndChanged(entity, key as keyof T, value as T[keyof T])) { - updated = true - } - } - return updated -} \ No newline at end of file +export function updateAllDefinedAndChanged( + entity: T, + incoming: Partial, +): boolean { + let updated = false + for (const [key, value] of Object.entries(incoming)) { + if (key in entity && updateIfDefinedAndChanged(entity, key as keyof T, value as T[keyof T])) { + updated = true + } + } + return updated +} diff --git a/shared/src/index.ts b/shared/src/index.ts index 9eb6655c5..aff9f4ea9 100644 --- a/shared/src/index.ts +++ b/shared/src/index.ts @@ -1,20 +1,18 @@ -export * from './schema' -export * from './enum' export * from './const' +export * from './enum' export * from './helper' -export * from './logic/decay' -export * from './util' export * from './jwt/JWT' export * from './jwt/payloadtypes/AuthenticationJwtPayloadType' export * from './jwt/payloadtypes/AuthenticationResponseJwtPayloadType' export * from './jwt/payloadtypes/DisburseJwtPayloadType' export * from './jwt/payloadtypes/EncryptedJWEJwtPayloadType' export * from './jwt/payloadtypes/JwtPayloadType' -export * from './jwt/payloadtypes/OpenConnectionJwtPayloadType' export * from './jwt/payloadtypes/OpenConnectionCallbackJwtPayloadType' +export * from './jwt/payloadtypes/OpenConnectionJwtPayloadType' export * from './jwt/payloadtypes/RedeemJwtPayloadType' export * from './jwt/payloadtypes/SendCoinsJwtPayloadType' export * from './jwt/payloadtypes/SendCoinsResponseJwtPayloadType' export * from './jwt/payloadtypes/SignedTransferPayloadType' - - +export * from './logic/decay' +export * from './schema' +export * from './util' diff --git a/shared/src/jwt/JWT.test.ts b/shared/src/jwt/JWT.test.ts index 05a143298..b6eec4940 100644 --- a/shared/src/jwt/JWT.test.ts +++ b/shared/src/jwt/JWT.test.ts @@ -1,8 +1,16 @@ - // import { testEnvironment } from '@test/helpers' // import { logger } from '@test/testSetup' -import { createKeyPair, decode, decrypt, encode, encrypt, encryptAndSign, verify, verifyAndDecrypt } from './JWT' +import { + createKeyPair, + decode, + decrypt, + encode, + encrypt, + encryptAndSign, + verify, + verifyAndDecrypt, +} from './JWT' import { EncryptedJWEJwtPayloadType } from './payloadtypes/EncryptedJWEJwtPayloadType' import { OpenConnectionJwtPayloadType } from './payloadtypes/OpenConnectionJwtPayloadType' @@ -16,9 +24,9 @@ let keypairComA: { publicKey: string; privateKey: string } let keypairComB: { publicKey: string; privateKey: string } beforeAll(async () => { -// testEnv = await testEnvironment(logger) -// con = testEnv.con -// await cleanDB() + // testEnv = await testEnvironment(logger) + // con = testEnv.con + // await cleanDB() keypairComA = await createKeyPair() keypairComB = await createKeyPair() @@ -30,138 +38,188 @@ afterAll(async () => { }) describe('test JWS creation and verification', () => { - let jwsComA: string - let jwsComB: string - beforeEach(async () => { - jest.clearAllMocks() - jwsComA = await encode(new OpenConnectionJwtPayloadType('handshakeID', 'http://localhost:5001/api/'), keypairComA.privateKey) - jwsComB = await encode(new OpenConnectionJwtPayloadType('handshakeID', 'http://localhost:5002/api/'), keypairComB.privateKey) + let jwsComA: string + let jwsComB: string + beforeEach(async () => { + jest.clearAllMocks() + jwsComA = await encode( + new OpenConnectionJwtPayloadType('handshakeID', 'http://localhost:5001/api/'), + keypairComA.privateKey, + ) + jwsComB = await encode( + new OpenConnectionJwtPayloadType('handshakeID', 'http://localhost:5002/api/'), + keypairComB.privateKey, + ) + }) + it('decode jwsComA', async () => { + const decodedJwsComA = await decode(jwsComA) + expect(decodedJwsComA).toEqual({ + expiration: '10m', + handshakeID: 'handshakeID', + tokentype: OpenConnectionJwtPayloadType.OPEN_CONNECTION_TYPE, + url: 'http://localhost:5001/api/', }) - it('decode jwsComA', async () => { - const decodedJwsComA = await decode(jwsComA) - expect(decodedJwsComA).toEqual({ - expiration: '10m', - handshakeID: 'handshakeID', - tokentype: OpenConnectionJwtPayloadType.OPEN_CONNECTION_TYPE, - url: 'http://localhost:5001/api/', - }) + }) + it('decode jwsComB', async () => { + const decodedJwsComB = await decode(jwsComB) + expect(decodedJwsComB).toEqual({ + expiration: '10m', + handshakeID: 'handshakeID', + tokentype: OpenConnectionJwtPayloadType.OPEN_CONNECTION_TYPE, + url: 'http://localhost:5002/api/', }) - it('decode jwsComB', async () => { - const decodedJwsComB = await decode(jwsComB) - expect(decodedJwsComB).toEqual({ - expiration: '10m', - handshakeID: 'handshakeID', - tokentype: OpenConnectionJwtPayloadType.OPEN_CONNECTION_TYPE, - url: 'http://localhost:5002/api/', - }) - }) - it('verify jwsComA', async () => { - const verifiedJwsComA = await verify('handshakeID', jwsComA, keypairComA.publicKey) - expect(verifiedJwsComA).toEqual(expect.objectContaining({ + }) + it('verify jwsComA', async () => { + const verifiedJwsComA = await verify('handshakeID', jwsComA, keypairComA.publicKey) + expect(verifiedJwsComA).toEqual( + expect.objectContaining({ payload: expect.objectContaining({ tokentype: OpenConnectionJwtPayloadType.OPEN_CONNECTION_TYPE, url: 'http://localhost:5001/api/', - }) - })) - }) - it('verify jwsComB', async () => { - const verifiedJwsComB = await verify('handshakeID', jwsComB, keypairComB.publicKey) - expect(verifiedJwsComB).toEqual(expect.objectContaining({ + }), + }), + ) + }) + it('verify jwsComB', async () => { + const verifiedJwsComB = await verify('handshakeID', jwsComB, keypairComB.publicKey) + expect(verifiedJwsComB).toEqual( + expect.objectContaining({ payload: expect.objectContaining({ tokentype: OpenConnectionJwtPayloadType.OPEN_CONNECTION_TYPE, url: 'http://localhost:5002/api/', - }) - })) - }) + }), + }), + ) + }) }) describe('test JWE encryption and decryption', () => { - let jweComA: string - let jweComB: string - beforeEach(async () => { - jest.clearAllMocks() - jweComA = await encrypt(new OpenConnectionJwtPayloadType('handshakeID', 'http://localhost:5001/api/'), keypairComB.publicKey) - jweComB = await encrypt(new OpenConnectionJwtPayloadType('handshakeID', 'http://localhost:5002/api/'), keypairComA.publicKey) - }) - it('decrypt jweComA', async () => { - const decryptedAJwT = await decrypt('handshakeID', jweComA, keypairComB.privateKey) - expect(JSON.parse(decryptedAJwT)).toEqual(expect.objectContaining({ + let jweComA: string + let jweComB: string + beforeEach(async () => { + jest.clearAllMocks() + jweComA = await encrypt( + new OpenConnectionJwtPayloadType('handshakeID', 'http://localhost:5001/api/'), + keypairComB.publicKey, + ) + jweComB = await encrypt( + new OpenConnectionJwtPayloadType('handshakeID', 'http://localhost:5002/api/'), + keypairComA.publicKey, + ) + }) + it('decrypt jweComA', async () => { + const decryptedAJwT = await decrypt('handshakeID', jweComA, keypairComB.privateKey) + expect(JSON.parse(decryptedAJwT)).toEqual( + expect.objectContaining({ tokentype: OpenConnectionJwtPayloadType.OPEN_CONNECTION_TYPE, url: 'http://localhost:5001/api/', handshakeID: 'handshakeID', - })) - }) - it('decrypt jweComB', async () => { - const decryptedBJwT = await decrypt('handshakeID', jweComB, keypairComA.privateKey) - expect(JSON.parse(decryptedBJwT)).toEqual(expect.objectContaining({ + }), + ) + }) + it('decrypt jweComB', async () => { + const decryptedBJwT = await decrypt('handshakeID', jweComB, keypairComA.privateKey) + expect(JSON.parse(decryptedBJwT)).toEqual( + expect.objectContaining({ tokentype: OpenConnectionJwtPayloadType.OPEN_CONNECTION_TYPE, url: 'http://localhost:5002/api/', handshakeID: 'handshakeID', - })) - }) + }), + ) + }) }) describe('test encrypted and signed JWT', () => { - let jweComA: string - let jwsComA: string - let jweComB: string - let jwsComB: string - beforeEach(async () => { - jest.clearAllMocks() - jweComA = await encrypt(new OpenConnectionJwtPayloadType('handshakeID', 'http://localhost:5001/api/'), keypairComB.publicKey) - jwsComA = await encode(new EncryptedJWEJwtPayloadType('handshakeID', jweComA), keypairComA.privateKey) - jweComB = await encrypt(new OpenConnectionJwtPayloadType('handshakeID', 'http://localhost:5002/api/'), keypairComA.publicKey) - jwsComB = await encode(new EncryptedJWEJwtPayloadType('handshakeID', jweComB), keypairComB.privateKey) - }) - it('verify jwsComA', async () => { - const verifiedJwsComA = await verify('handshakeID', jwsComA, keypairComA.publicKey) - expect(verifiedJwsComA).toEqual(expect.objectContaining({ + let jweComA: string + let jwsComA: string + let jweComB: string + let jwsComB: string + beforeEach(async () => { + jest.clearAllMocks() + jweComA = await encrypt( + new OpenConnectionJwtPayloadType('handshakeID', 'http://localhost:5001/api/'), + keypairComB.publicKey, + ) + jwsComA = await encode( + new EncryptedJWEJwtPayloadType('handshakeID', jweComA), + keypairComA.privateKey, + ) + jweComB = await encrypt( + new OpenConnectionJwtPayloadType('handshakeID', 'http://localhost:5002/api/'), + keypairComA.publicKey, + ) + jwsComB = await encode( + new EncryptedJWEJwtPayloadType('handshakeID', jweComB), + keypairComB.privateKey, + ) + }) + it('verify jwsComA', async () => { + const verifiedJwsComA = await verify('handshakeID', jwsComA, keypairComA.publicKey) + expect(verifiedJwsComA).toEqual( + expect.objectContaining({ payload: expect.objectContaining({ jwe: jweComA, tokentype: EncryptedJWEJwtPayloadType.ENCRYPTED_JWE_TYPE, handshakeID: 'handshakeID', - }) - })) - }) - it('verify jwsComB', async () => { - const verifiedJwsComB = await verify('handshakeID', jwsComB, keypairComB.publicKey) - expect(verifiedJwsComB).toEqual(expect.objectContaining({ + }), + }), + ) + }) + it('verify jwsComB', async () => { + const verifiedJwsComB = await verify('handshakeID', jwsComB, keypairComB.publicKey) + expect(verifiedJwsComB).toEqual( + expect.objectContaining({ payload: expect.objectContaining({ jwe: jweComB, tokentype: EncryptedJWEJwtPayloadType.ENCRYPTED_JWE_TYPE, handshakeID: 'handshakeID', - }) - })) - }) - it('decrypt jweComA', async () => { - expect(JSON.parse(await decrypt('handshakeID', jweComA, keypairComB.privateKey))).toEqual(expect.objectContaining({ + }), + }), + ) + }) + it('decrypt jweComA', async () => { + expect(JSON.parse(await decrypt('handshakeID', jweComA, keypairComB.privateKey))).toEqual( + expect.objectContaining({ tokentype: OpenConnectionJwtPayloadType.OPEN_CONNECTION_TYPE, url: 'http://localhost:5001/api/', handshakeID: 'handshakeID', - })) - }) - it('decrypt jweComB', async () => { - expect(JSON.parse(await decrypt('handshakeID', jweComB, keypairComA.privateKey))).toEqual(expect.objectContaining({ + }), + ) + }) + it('decrypt jweComB', async () => { + expect(JSON.parse(await decrypt('handshakeID', jweComB, keypairComA.privateKey))).toEqual( + expect.objectContaining({ tokentype: OpenConnectionJwtPayloadType.OPEN_CONNECTION_TYPE, url: 'http://localhost:5002/api/', handshakeID: 'handshakeID', - })) - }) + }), + ) + }) }) - describe('test encryptAndSign and verifyAndDecrypt', () => { let jwtComA: string beforeEach(async () => { jest.clearAllMocks() - jwtComA = await encryptAndSign(new OpenConnectionJwtPayloadType('handshakeID', 'http://localhost:5001/api/'), keypairComA.privateKey, keypairComB.publicKey) + jwtComA = await encryptAndSign( + new OpenConnectionJwtPayloadType('handshakeID', 'http://localhost:5001/api/'), + keypairComA.privateKey, + keypairComB.publicKey, + ) }) it('verifyAndDecrypt jwtComA', async () => { - const verifiedAndDecryptedPayload = await verifyAndDecrypt('handshakeID', jwtComA, keypairComB.privateKey, keypairComA.publicKey) - expect(verifiedAndDecryptedPayload).toEqual(expect.objectContaining({ - tokentype: OpenConnectionJwtPayloadType.OPEN_CONNECTION_TYPE, - url: 'http://localhost:5001/api/', - handshakeID: 'handshakeID', - })) + const verifiedAndDecryptedPayload = await verifyAndDecrypt( + 'handshakeID', + jwtComA, + keypairComB.privateKey, + keypairComA.publicKey, + ) + expect(verifiedAndDecryptedPayload).toEqual( + expect.objectContaining({ + tokentype: OpenConnectionJwtPayloadType.OPEN_CONNECTION_TYPE, + url: 'http://localhost:5001/api/', + handshakeID: 'handshakeID', + }), + ) }) -}) \ No newline at end of file +}) diff --git a/shared/src/jwt/JWT.ts b/shared/src/jwt/JWT.ts index 7c8fd799d..190b4c380 100644 --- a/shared/src/jwt/JWT.ts +++ b/shared/src/jwt/JWT.ts @@ -1,27 +1,42 @@ -import { generateKeyPair, exportSPKI, exportPKCS8, SignJWT, decodeJwt, importPKCS8, importSPKI, jwtVerify, CompactEncrypt, compactDecrypt } from 'jose' -import { LOG4JS_BASE_CATEGORY_NAME } from '../const' +import { + CompactEncrypt, + compactDecrypt, + decodeJwt, + exportPKCS8, + exportSPKI, + generateKeyPair, + importPKCS8, + importSPKI, + jwtVerify, + SignJWT, +} from 'jose' import { getLogger } from 'log4js' +import { LOG4JS_BASE_CATEGORY_NAME } from '../const' const logger = getLogger(`${LOG4JS_BASE_CATEGORY_NAME}.auth.jwt.JWT`) -import { JwtPayloadType } from './payloadtypes/JwtPayloadType' import { EncryptedJWEJwtPayloadType } from './payloadtypes/EncryptedJWEJwtPayloadType' +import { JwtPayloadType } from './payloadtypes/JwtPayloadType' export const createKeyPair = async (): Promise<{ publicKey: string; privateKey: string }> => { // Generate key pair using jose library const keyPair = await generateKeyPair('RS256', { modulusLength: 2048, // recommended key size extractable: true, - }); - logger.debug(`Federation: writeJwtKeyPairInHomeCommunity generated keypair...`); - + }) + logger.debug(`Federation: writeJwtKeyPairInHomeCommunity generated keypair...`) + // Convert keys to PEM format for storage in database - const publicKeyPem = await exportSPKI(keyPair.publicKey); - const privateKeyPem = await exportPKCS8(keyPair.privateKey); - return { publicKey: publicKeyPem, privateKey: privateKeyPem }; + const publicKeyPem = await exportSPKI(keyPair.publicKey) + const privateKeyPem = await exportPKCS8(keyPair.privateKey) + return { publicKey: publicKeyPem, privateKey: privateKeyPem } } -export const verify = async (handshakeID: string, token: string, publicKey: string): Promise => { +export const verify = async ( + handshakeID: string, + token: string, + publicKey: string, +): Promise => { const methodLogger = getLogger(`${LOG4JS_BASE_CATEGORY_NAME}.auth.jwt.JWT.verify`) methodLogger.addContext('handshakeID', handshakeID) if (!token) { @@ -33,9 +48,7 @@ export const verify = async (handshakeID: string, token: string, publicKey: stri try { const importedKey = await importSPKI(publicKey, 'RS256') // Convert the key to JWK format if needed - const secret = typeof importedKey === 'string' - ? JSON.parse(importedKey) - : importedKey; + const secret = typeof importedKey === 'string' ? JSON.parse(importedKey) : importedKey // const secret = new TextEncoder().encode(publicKey) const { payload } = await jwtVerify(token, secret, { issuer: JwtPayloadType.ISSUER, @@ -57,9 +70,7 @@ export const encode = async (payload: JwtPayloadType, privatekey: string): Promi methodLogger.debug('encode... privatekey=', privatekey.substring(0, 20)) try { const importedKey = await importPKCS8(privatekey, 'RS256') - const secret = typeof importedKey === 'string' - ? JSON.parse(importedKey) - : importedKey; + const secret = typeof importedKey === 'string' ? JSON.parse(importedKey) : importedKey // const secret = new TextEncoder().encode(privatekey) const token = await new SignJWT({ payload, 'urn:gradido:claim': true }) @@ -79,7 +90,11 @@ export const encode = async (payload: JwtPayloadType, privatekey: string): Promi } } -export const verifyJwtType = async (handshakeID: string, token: string, publicKey: string): Promise => { +export const verifyJwtType = async ( + handshakeID: string, + token: string, + publicKey: string, +): Promise => { const payload = await verify(handshakeID, token, publicKey) return payload ? payload.tokentype : 'unknown token type' } @@ -97,13 +112,9 @@ export const encrypt = async (payload: JwtPayloadType, publicKey: string): Promi try { const encryptKey = await importSPKI(publicKey, 'RSA-OAEP-256') // Convert the key to JWK format if needed - const recipientKey = typeof encryptKey === 'string' - ? JSON.parse(encryptKey) - : encryptKey; - - const jwe = await new CompactEncrypt( - new TextEncoder().encode(JSON.stringify(payload)), - ) + const recipientKey = typeof encryptKey === 'string' ? JSON.parse(encryptKey) : encryptKey + + const jwe = await new CompactEncrypt(new TextEncoder().encode(JSON.stringify(payload))) .setProtectedHeader({ alg: 'RSA-OAEP-256', enc: 'A256GCM' }) .encrypt(recipientKey) methodLogger.debug('encrypt... jwe=', jwe) @@ -114,15 +125,18 @@ export const encrypt = async (payload: JwtPayloadType, publicKey: string): Promi } } -export const decrypt = async(handshakeID: string, jwe: string, privateKey: string): Promise => { +export const decrypt = async ( + handshakeID: string, + jwe: string, + privateKey: string, +): Promise => { const methodLogger = getLogger(`${LOG4JS_BASE_CATEGORY_NAME}.auth.jwt.JWT.decrypt`) methodLogger.addContext('handshakeID', handshakeID) methodLogger.debug('decrypt... jwe=', jwe) methodLogger.debug('decrypt... privateKey=', privateKey.substring(0, 10)) try { const decryptKey = await importPKCS8(privateKey, 'RSA-OAEP-256') - const { plaintext, protectedHeader } = - await compactDecrypt(jwe, decryptKey) + const { plaintext, protectedHeader } = await compactDecrypt(jwe, decryptKey) methodLogger.debug('decrypt... plaintext=', plaintext) methodLogger.debug('decrypt... protectedHeader=', protectedHeader) return new TextDecoder().decode(plaintext) @@ -132,7 +146,11 @@ export const decrypt = async(handshakeID: string, jwe: string, privateKey: strin } } -export const encryptAndSign = async (payload: JwtPayloadType, privateKey: string, publicKey: string): Promise => { +export const encryptAndSign = async ( + payload: JwtPayloadType, + privateKey: string, + publicKey: string, +): Promise => { const methodLogger = getLogger(`${LOG4JS_BASE_CATEGORY_NAME}.auth.jwt.JWT.encryptAndSign`) methodLogger.addContext('handshakeID', payload.handshakeID) const jwe = await encrypt(payload, publicKey) @@ -142,7 +160,12 @@ export const encryptAndSign = async (payload: JwtPayloadType, privateKey: string return jws } -export const verifyAndDecrypt = async (handshakeID: string, token: string, privateKey: string, publicKey: string): Promise => { +export const verifyAndDecrypt = async ( + handshakeID: string, + token: string, + privateKey: string, + publicKey: string, +): Promise => { const methodLogger = getLogger(`${LOG4JS_BASE_CATEGORY_NAME}.auth.jwt.JWT.verifyAndDecrypt`) methodLogger.addContext('handshakeID', handshakeID) const jweVerifyResult = await verify(handshakeID, token, publicKey) diff --git a/shared/src/jwt/payloadtypes/AuthenticationJwtPayloadType.ts b/shared/src/jwt/payloadtypes/AuthenticationJwtPayloadType.ts index bd7aef013..6b11ad1f4 100644 --- a/shared/src/jwt/payloadtypes/AuthenticationJwtPayloadType.ts +++ b/shared/src/jwt/payloadtypes/AuthenticationJwtPayloadType.ts @@ -6,11 +6,7 @@ export class AuthenticationJwtPayloadType extends JwtPayloadType { oneTimeCode: string uuid: string - constructor( - handshakeID: string, - oneTimeCode: string, - uuid: string, - ) { + constructor(handshakeID: string, oneTimeCode: string, uuid: string) { super(handshakeID) this.tokentype = AuthenticationJwtPayloadType.AUTHENTICATION_TYPE this.oneTimeCode = oneTimeCode diff --git a/shared/src/jwt/payloadtypes/AuthenticationResponseJwtPayloadType.ts b/shared/src/jwt/payloadtypes/AuthenticationResponseJwtPayloadType.ts index ea220a713..fa5f8f9de 100644 --- a/shared/src/jwt/payloadtypes/AuthenticationResponseJwtPayloadType.ts +++ b/shared/src/jwt/payloadtypes/AuthenticationResponseJwtPayloadType.ts @@ -5,10 +5,7 @@ export class AuthenticationResponseJwtPayloadType extends JwtPayloadType { uuid: string - constructor( - handshakeID: string, - uuid: string, - ) { + constructor(handshakeID: string, uuid: string) { super(handshakeID) this.tokentype = AuthenticationResponseJwtPayloadType.AUTHENTICATION_RESPONSE_TYPE this.uuid = uuid diff --git a/shared/src/jwt/payloadtypes/EncryptedJWEJwtPayloadType.ts b/shared/src/jwt/payloadtypes/EncryptedJWEJwtPayloadType.ts index 0d6d86476..06319d82c 100644 --- a/shared/src/jwt/payloadtypes/EncryptedJWEJwtPayloadType.ts +++ b/shared/src/jwt/payloadtypes/EncryptedJWEJwtPayloadType.ts @@ -5,10 +5,7 @@ export class EncryptedJWEJwtPayloadType extends JwtPayloadType { jwe: string - constructor( - handshakeID: string, - jwe: string, - ) { + constructor(handshakeID: string, jwe: string) { super(handshakeID) this.tokentype = EncryptedJWEJwtPayloadType.ENCRYPTED_JWE_TYPE this.jwe = jwe diff --git a/shared/src/jwt/payloadtypes/OpenConnectionCallbackJwtPayloadType.ts b/shared/src/jwt/payloadtypes/OpenConnectionCallbackJwtPayloadType.ts index 544e23800..bc0bdeeb7 100644 --- a/shared/src/jwt/payloadtypes/OpenConnectionCallbackJwtPayloadType.ts +++ b/shared/src/jwt/payloadtypes/OpenConnectionCallbackJwtPayloadType.ts @@ -6,11 +6,7 @@ export class OpenConnectionCallbackJwtPayloadType extends JwtPayloadType { oneTimeCode: string url: string - constructor( - handshakeID: string, - oneTimeCode: string, - url: string, - ) { + constructor(handshakeID: string, oneTimeCode: string, url: string) { super(handshakeID) this.tokentype = OpenConnectionCallbackJwtPayloadType.OPEN_CONNECTION_CALLBACK_TYPE this.oneTimeCode = oneTimeCode diff --git a/shared/src/jwt/payloadtypes/OpenConnectionJwtPayloadType.ts b/shared/src/jwt/payloadtypes/OpenConnectionJwtPayloadType.ts index a9e7e0a5a..4ae014ae0 100644 --- a/shared/src/jwt/payloadtypes/OpenConnectionJwtPayloadType.ts +++ b/shared/src/jwt/payloadtypes/OpenConnectionJwtPayloadType.ts @@ -5,10 +5,7 @@ export class OpenConnectionJwtPayloadType extends JwtPayloadType { url: string - constructor( - handshakeID: string, - url: string, - ) { + constructor(handshakeID: string, url: string) { super(handshakeID) this.tokentype = OpenConnectionJwtPayloadType.OPEN_CONNECTION_TYPE this.url = url diff --git a/shared/src/jwt/payloadtypes/SendCoinsJwtPayloadType.ts b/shared/src/jwt/payloadtypes/SendCoinsJwtPayloadType.ts index b49086467..194284843 100644 --- a/shared/src/jwt/payloadtypes/SendCoinsJwtPayloadType.ts +++ b/shared/src/jwt/payloadtypes/SendCoinsJwtPayloadType.ts @@ -1,5 +1,5 @@ -import { JwtPayloadType } from './JwtPayloadType' import { Decimal } from 'decimal.js-light' +import { JwtPayloadType } from './JwtPayloadType' export class SendCoinsJwtPayloadType extends JwtPayloadType { static SEND_COINS_TYPE = 'send-coins' diff --git a/shared/src/jwt/payloadtypes/SignedTransferPayloadType.ts b/shared/src/jwt/payloadtypes/SignedTransferPayloadType.ts index 1b3f3a468..8412058c3 100644 --- a/shared/src/jwt/payloadtypes/SignedTransferPayloadType.ts +++ b/shared/src/jwt/payloadtypes/SignedTransferPayloadType.ts @@ -6,11 +6,7 @@ export class SignedTransferPayloadType extends JwtPayloadType { publicKey: string jwt: string - constructor( - publicKey: string, - jwt: string, - handshakeID: string, - ) { + constructor(publicKey: string, jwt: string, handshakeID: string) { super(handshakeID) this.tokentype = SignedTransferPayloadType.SIGNED_TRANSFER_TYPE this.publicKey = publicKey diff --git a/shared/src/logic/decay.test.ts b/shared/src/logic/decay.test.ts index a3deedaa4..b34568d0c 100644 --- a/shared/src/logic/decay.test.ts +++ b/shared/src/logic/decay.test.ts @@ -22,7 +22,7 @@ describe('utils/decay', () => { const seconds = 31556952 expect(decayFormula(amount, seconds).toString()).toBe('49.99999999999999999999999') }) - + it('has correct backward calculation', () => { const amount = new Decimal(1.0) const seconds = -1 @@ -63,16 +63,19 @@ describe('utils/decay', () => { const seconds = 1209600 expect(compoundInterest(amount, seconds).toString()).toBe('102.6924912992003635568199') // if I lock 102.6924912992003635568199 GDD, I will have 99.99999999999999999999998 GDD after 14 days, not 100% but near enough - expect(decayFormulaFast(compoundInterest(amount, seconds), seconds).toString()).toBe('99.99999999999999999999998') + expect(decayFormulaFast(compoundInterest(amount, seconds), seconds).toString()).toBe( + '99.99999999999999999999998', + ) expect(compoundInterest(amount, seconds).toDecimalPlaces(4).toString()).toBe('102.6925') // rounded to 4 decimal places it is working like a charm - expect(decayFormulaFast(new Decimal( - compoundInterest(amount, seconds).toDecimalPlaces(4)), - seconds - ).toDecimalPlaces(4).toString()).toBe('100') + expect( + decayFormulaFast(new Decimal(compoundInterest(amount, seconds).toDecimalPlaces(4)), seconds) + .toDecimalPlaces(4) + .toString(), + ).toBe('100') }) }) - + it('has base 0.99999997802044727', () => { const now = new Date() now.setSeconds(1) diff --git a/shared/src/logic/decay.ts b/shared/src/logic/decay.ts index c3b8cf3b2..eec9f0cff 100644 --- a/shared/src/logic/decay.ts +++ b/shared/src/logic/decay.ts @@ -15,11 +15,11 @@ export interface Decay { end: Date | null duration: number | null } - + export function decayFormula(value: Decimal, seconds: number): Decimal { // TODO why do we need to convert this here to a string to work properly? - // chatgpt: We convert to string here to avoid precision loss: - // .pow(seconds) can internally round the result, especially for large values of `seconds`. + // chatgpt: We convert to string here to avoid precision loss: + // .pow(seconds) can internally round the result, especially for large values of `seconds`. // Using .toString() ensures full precision is preserved in the multiplication. return value.mul( new Decimal('0.99999997803504048973201202316767079413460520837376').pow(seconds).toString(), @@ -27,17 +27,17 @@ export function decayFormula(value: Decimal, seconds: number): Decimal { } export function decayFormulaFast(value: Decimal, seconds: number): Decimal { - return value.mul(new Decimal(2).pow(new Decimal(-seconds).div(new Decimal(SECONDS_PER_YEAR_GREGORIAN_CALENDER)))) + return value.mul( + new Decimal(2).pow(new Decimal(-seconds).div(new Decimal(SECONDS_PER_YEAR_GREGORIAN_CALENDER))), + ) } export function compoundInterest(value: Decimal, seconds: number): Decimal { - return value.mul(new Decimal(2).pow(new Decimal(seconds).div(new Decimal(SECONDS_PER_YEAR_GREGORIAN_CALENDER)))) + return value.mul( + new Decimal(2).pow(new Decimal(seconds).div(new Decimal(SECONDS_PER_YEAR_GREGORIAN_CALENDER))), + ) } -export function calculateDecay( - amount: Decimal, - from: Date, - to: Date -): Decay { +export function calculateDecay(amount: Decimal, from: Date, to: Date): Decay { const fromMs = from.getTime() const toMs = to.getTime() const startBlockMs = DECAY_START_TIME.getTime() diff --git a/shared/src/schema/base.schema.test.ts b/shared/src/schema/base.schema.test.ts index d12f2a3b4..375078d14 100644 --- a/shared/src/schema/base.schema.test.ts +++ b/shared/src/schema/base.schema.test.ts @@ -1,6 +1,6 @@ import { describe, expect, it } from 'bun:test' -import { uuidv4Schema, uint32Schema } from './base.schema' import { v4 as uuidv4 } from 'uuid' +import { uint32Schema, uuidv4Schema } from './base.schema' describe('uuidv4 schema', () => { it('should validate uuidv4 (40x)', () => { diff --git a/shared/src/schema/base.schema.ts b/shared/src/schema/base.schema.ts index 2f158b1b0..cf88aa1e5 100644 --- a/shared/src/schema/base.schema.ts +++ b/shared/src/schema/base.schema.ts @@ -1,7 +1,10 @@ -import { string, number } from 'zod' import { validate, version } from 'uuid' +import { number, string } from 'zod' -export const uuidv4Schema = string().refine((val: string) => validate(val) && version(val) === 4, 'Invalid uuid') +export const uuidv4Schema = string().refine( + (val: string) => validate(val) && version(val) === 4, + 'Invalid uuid', +) export const emailSchema = string().email() export const urlSchema = string().url() export const uint32Schema = number().positive().lte(4294967295) diff --git a/shared/src/schema/community.schema.test.ts b/shared/src/schema/community.schema.test.ts index a46ea9c94..5a3faa863 100644 --- a/shared/src/schema/community.schema.test.ts +++ b/shared/src/schema/community.schema.test.ts @@ -1,7 +1,6 @@ +import { describe, expect, it } from 'bun:test' import { v4 as uuidv4 } from 'uuid' import { communityAuthenticatedSchema } from './community.schema' -import { describe, it, expect } from 'bun:test' - describe('communityAuthenticatedSchema', () => { it('should return an error if communityUuid is not a uuidv4', () => { diff --git a/shared/src/schema/community.schema.ts b/shared/src/schema/community.schema.ts index 6957b16b0..ab8796036 100644 --- a/shared/src/schema/community.schema.ts +++ b/shared/src/schema/community.schema.ts @@ -1,4 +1,4 @@ -import { object, date, array, string } from 'zod' +import { array, date, object, string } from 'zod' import { uuidv4Schema } from './base.schema' export const communityAuthenticatedSchema = object({ diff --git a/shared/src/schema/index.ts b/shared/src/schema/index.ts index 83455fb73..8d1f75b22 100644 --- a/shared/src/schema/index.ts +++ b/shared/src/schema/index.ts @@ -1,3 +1,3 @@ -export * from './user.schema' export * from './base.schema' -export * from './community.schema' \ No newline at end of file +export * from './community.schema' +export * from './user.schema' diff --git a/shared/src/schema/user.schema.test.ts b/shared/src/schema/user.schema.test.ts index 015309dfd..d32fb7f6c 100644 --- a/shared/src/schema/user.schema.test.ts +++ b/shared/src/schema/user.schema.test.ts @@ -1,34 +1,38 @@ +import { describe, expect, it } from 'bun:test' import { aliasSchema, firstNameSchema } from './user.schema' -import { describe, it, expect } from 'bun:test' describe('validate alias', () => { describe('alias contains invalid characters', () => { it('throws and logs an error', () => { - expect(() => aliasSchema.parse('Bibi.Bloxberg')).toThrowError(expect.objectContaining( - expect.arrayContaining([ - expect.objectContaining({ - origin: 'string', - code: 'invalid_format', - format: 'regex', - message: 'Invalid characters in alias', - path: [], - }) - ]) - )) + expect(() => aliasSchema.parse('Bibi.Bloxberg')).toThrowError( + expect.objectContaining( + expect.arrayContaining([ + expect.objectContaining({ + origin: 'string', + code: 'invalid_format', + format: 'regex', + message: 'Invalid characters in alias', + path: [], + }), + ]), + ), + ) }) }) describe('alias is a reserved word', () => { it('throws and logs an error', () => { - expect(() => aliasSchema.parse('admin')).toThrowError(expect.objectContaining( - expect.arrayContaining([ - expect.objectContaining({ - code: 'custom', - message: 'Given alias is not allowed', - path: [], - }), - ]), - )) + expect(() => aliasSchema.parse('admin')).toThrowError( + expect.objectContaining( + expect.arrayContaining([ + expect.objectContaining({ + code: 'custom', + message: 'Given alias is not allowed', + path: [], + }), + ]), + ), + ) }) }) @@ -49,48 +53,54 @@ describe('validate alias', () => { describe('alias is a reserved word with uppercase characters', () => { it('throws and logs an error', () => { - expect(() => aliasSchema.parse('Admin')).toThrowError(expect.objectContaining( - expect.arrayContaining([ - expect.objectContaining({ - code: 'custom', - message: 'Given alias is not allowed', - path: [], - }), - ]), - )) + expect(() => aliasSchema.parse('Admin')).toThrowError( + expect.objectContaining( + expect.arrayContaining([ + expect.objectContaining({ + code: 'custom', + message: 'Given alias is not allowed', + path: [], + }), + ]), + ), + ) }) }) describe('hyphens and underscore', () => { describe('alias starts with underscore', () => { it('throws and logs an error', () => { - expect(() => aliasSchema.parse('_bibi')).toThrowError(expect.objectContaining( - expect.arrayContaining([ - expect.objectContaining({ - origin: 'string', - code: 'invalid_format', - format: 'regex', - message: 'Invalid characters in alias', - path: [], - }) - ]) - )) + expect(() => aliasSchema.parse('_bibi')).toThrowError( + expect.objectContaining( + expect.arrayContaining([ + expect.objectContaining({ + origin: 'string', + code: 'invalid_format', + format: 'regex', + message: 'Invalid characters in alias', + path: [], + }), + ]), + ), + ) }) }) describe('alias contains two following hyphens', () => { it('throws and logs an error', () => { - expect(() => aliasSchema.parse('bi--bi')).toThrowError(expect.objectContaining( - expect.arrayContaining([ - expect.objectContaining({ - origin: 'string', - code: 'invalid_format', - format: 'regex', - message: 'Invalid characters in alias', - path: [], - }) - ]) - )) + expect(() => aliasSchema.parse('bi--bi')).toThrowError( + expect.objectContaining( + expect.arrayContaining([ + expect.objectContaining({ + origin: 'string', + code: 'invalid_format', + format: 'regex', + message: 'Invalid characters in alias', + path: [], + }), + ]), + ), + ) }) }) }) @@ -99,17 +109,19 @@ describe('validate alias', () => { describe('validate first name', () => { describe('first name contains invalid characters', () => { it('throws and logs an error', () => { - expect(() => firstNameSchema.parse('')).toThrowError(expect.objectContaining( - expect.arrayContaining([ - expect.objectContaining({ - origin: 'string', - code: 'invalid_format', - format: 'regex', - message: 'Invalid characters in first name', - path: [], - }) - ]) - )) + expect(() => firstNameSchema.parse('')).toThrowError( + expect.objectContaining( + expect.arrayContaining([ + expect.objectContaining({ + origin: 'string', + code: 'invalid_format', + format: 'regex', + message: 'Invalid characters in first name', + path: [], + }), + ]), + ), + ) }) }) it('use greek symbols', () => { diff --git a/shared/src/schema/user.schema.ts b/shared/src/schema/user.schema.ts index 4e15ca9fa..b96a8aa46 100644 --- a/shared/src/schema/user.schema.ts +++ b/shared/src/schema/user.schema.ts @@ -5,7 +5,7 @@ export const VALID_ALIAS_REGEX = /^(?=.{3,20}$)[a-zA-Z0-9]+(?:[_-][a-zA-Z0-9]+?) // first a character or ' is expected // then all without the last a character, space, apostrophe or hyphen is expected // last a character is expected -export const VALID_NAME_REGEX = /^[\p{L}'][ \p{L}'-_]*[\p{L}]$/u +export const VALID_NAME_REGEX = /^[\p{L}'][ \p{L}'-_]*[\p{L}]$/u const RESERVED_ALIAS = [ 'admin', @@ -23,7 +23,7 @@ const RESERVED_ALIAS = [ 'usr', 'var', 'reserved', - 'undefined' + 'undefined', ] export const aliasSchema = string() @@ -44,4 +44,4 @@ export const firstNameSchema = string() export const lastNameSchema = string() .min(2, 'Last name is too short') .max(255, 'Last name is too long') - .regex(VALID_NAME_REGEX) \ No newline at end of file + .regex(VALID_NAME_REGEX) diff --git a/shared/src/util/index.ts b/shared/src/util/index.ts index c2a905916..f23cbdbf2 100644 --- a/shared/src/util/index.ts +++ b/shared/src/util/index.ts @@ -1 +1 @@ -export * from './utilities' \ No newline at end of file +export * from './utilities' From 05e275edcfd616375eb359b1d6ddadb64fe38790 Mon Sep 17 00:00:00 2001 From: einhornimmond Date: Thu, 4 Dec 2025 13:07:05 +0100 Subject: [PATCH 2/2] disable rule because changed code isn't compatible with current build target --- biome.json | 2 +- core/src/util/utilities.ts | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/biome.json b/biome.json index 4f60baebc..19c068854 100644 --- a/biome.json +++ b/biome.json @@ -103,7 +103,7 @@ "noGlobalAssign": "error", "noImportAssign": "error", "noMisleadingCharacterClass": "error", - "noPrototypeBuiltins": "error", + "noPrototypeBuiltins": "off", "noRedeclare": "error", "noSelfCompare": "error", "noShadowRestrictedNames": "error", diff --git a/core/src/util/utilities.ts b/core/src/util/utilities.ts index 7278f5c9e..6c5a0eb93 100644 --- a/core/src/util/utilities.ts +++ b/core/src/util/utilities.ts @@ -19,7 +19,7 @@ export const decimalSeparatorByLanguage = (a: Decimal, language: string): string export function resetInterface>(obj: T): T { // Iterate over all properties of the object for (const key in obj) { - if (Object.hasOwn(obj, key)) { + if (Object.prototype.hasOwnProperty.call(obj, key)) { // Set all optional properties to undefined obj[key] = undefined as T[Extract]