From 23e70c5f1c42e9a9f4b2413adf2409a8c09ba60d Mon Sep 17 00:00:00 2001
From: clauspeterhuebner
Date: Wed, 6 Aug 2025 16:42:19 +0200
Subject: [PATCH 01/48] only for save current work
---
backend/src/graphql/resolver/TransactionLinkResolver.ts | 9 ++++++---
shared/src/jwt/payloadtypes/DisburseJwtPayloadType.ts | 5 ++---
2 files changed, 8 insertions(+), 6 deletions(-)
diff --git a/backend/src/graphql/resolver/TransactionLinkResolver.ts b/backend/src/graphql/resolver/TransactionLinkResolver.ts
index 32464cc82..65c2d5df6 100644
--- a/backend/src/graphql/resolver/TransactionLinkResolver.ts
+++ b/backend/src/graphql/resolver/TransactionLinkResolver.ts
@@ -39,7 +39,7 @@ import { TRANSACTIONS_LOCK } from '@/util/TRANSACTIONS_LOCK'
import { TRANSACTION_LINK_LOCK } from '@/util/TRANSACTION_LINK_LOCK'
import { fullName } from '@/util/utilities'
import { calculateBalance } from '@/util/validate'
-import { calculateDecay, decode, DisburseJwtPayloadType, encode, RedeemJwtPayloadType, verify } from 'shared'
+import { calculateDecay, decode, DisburseJwtPayloadType, encode, encryptAndSign, RedeemJwtPayloadType, verify } from 'shared'
import { LOG4JS_BASE_CATEGORY_NAME } from '@/config/const'
import { getLogger, Logger } from 'log4js'
@@ -655,6 +655,7 @@ export class TransactionLinkResolver {
}
async createDisburseJwt(
+ handshakeId: string,
senderCommunityUuid: string,
senderGradidoId: string,
recipientCommunityUuid: string,
@@ -670,6 +671,7 @@ export class TransactionLinkResolver {
const logger = createLogger()
logger.addContext('code', code.substring(0, 6))
logger.debug('TransactionLinkResolver.createDisburseJwt... args=', {
+ handshakeId,
senderCommunityUuid,
senderGradidoId,
recipientCommunityUuid,
@@ -683,7 +685,8 @@ export class TransactionLinkResolver {
recipientAlias,
})
- const disburseJwtPayloadType = new DisburseJwtPayloadType(
+ const disburseJwtPayload = new DisburseJwtPayloadType(
+ handshakeId,
senderCommunityUuid,
senderGradidoId,
recipientCommunityUuid,
@@ -696,8 +699,8 @@ export class TransactionLinkResolver {
validUntil,
recipientAlias,
)
+ const disburseJwt = await encryptAndSign(disburseJwtPayload, homeComB.privateJwtKey!, authCom.publicJwtKey!)
// TODO:encode/sign the jwt normally with the private key of the recipient community, but interims with uuid
- const disburseJwt = await encode(disburseJwtPayloadType, recipientCommunityUuid)
logger.debug('TransactionLinkResolver.createDisburseJwt... disburseJwt=', disburseJwt)
// TODO: encrypt the payload with the public key of the target/sender community
return disburseJwt
diff --git a/shared/src/jwt/payloadtypes/DisburseJwtPayloadType.ts b/shared/src/jwt/payloadtypes/DisburseJwtPayloadType.ts
index 2940161df..426e3f58a 100644
--- a/shared/src/jwt/payloadtypes/DisburseJwtPayloadType.ts
+++ b/shared/src/jwt/payloadtypes/DisburseJwtPayloadType.ts
@@ -17,6 +17,7 @@ export class DisburseJwtPayloadType extends JwtPayloadType {
recipientalias: string
constructor(
+ handshakeID: string,
senderCommunityUuid: string,
senderGradidoId: string,
recipientCommunityUuid: string,
@@ -29,9 +30,7 @@ export class DisburseJwtPayloadType extends JwtPayloadType {
validUntil: string,
recipientAlias: string,
) {
- // eslint-disable-next-line @typescript-eslint/no-unsafe-call
- super('handshakeID')
- // eslint-disable-next-line @typescript-eslint/no-unsafe-assignment
+ super(handshakeID)
this.tokentype = DisburseJwtPayloadType.DISBURSE_ACTIVATION_TYPE
this.sendercommunityuuid = senderCommunityUuid
this.sendergradidoid = senderGradidoId
From 6e5fb223d655d22bd9bedaa41518ee002f17ed76 Mon Sep 17 00:00:00 2001
From: clauspeterhuebner
Date: Wed, 20 Aug 2025 16:26:02 +0200
Subject: [PATCH 02/48] safe current work
---
.../apis/dltConnector/DltConnectorClient.ts | 2 +-
.../src/federation/authenticateCommunities.ts | 2 +-
.../client/1_0/DisbursementClient.ts | 48 ++++
.../federation/client/1_0/FederationClient.ts | 2 +-
.../processDisburseJwtOnSenderCommunity.ts | 7 +
.../client/1_1/DisbursementClient.ts | 3 +
.../federation/client/1_1/SendCoinsClient.ts | 3 -
.../client/AuthenticationClientFactory.ts | 2 +-
.../client/DisbursementClientFactory.ts | 58 +++++
.../client/FederationClientFactory.ts | 4 +-
backend/src/federation/validateCommunities.ts | 2 +-
backend/src/graphql/model/Transaction.ts | 2 +-
.../graphql/resolver/ContributionResolver.ts | 4 +-
.../resolver/TransactionLinkResolver.ts | 205 +++++++++---------
.../resolver/TransactionResolver.test.ts | 6 +-
.../graphql/resolver/TransactionResolver.ts | 18 +-
.../sendTransactionsToDltConnector.test.ts | 2 +-
.../graphql/resolver/util/storeForeignUser.ts | 2 +-
backend/src/util/virtualTransactions.ts | 2 +-
bun.lock | 1 +
core/package.json | 1 +
.../federation/client/1_0/SendCoinsClient.ts | 9 +-
.../1_0/logging/SendCoinsArgsLogging.view.ts | 2 +-
.../logging/SendCoinsResultLogging.view.ts | 2 +-
.../client/1_0/model/SendCoinsArgs.ts | 0
.../client/1_0/model/SendCoinsResult.ts | 0
.../client/1_0/query/revertSendCoins.ts | 0
.../1_0/query/revertSettledSendCoins.ts | 0
.../client/1_0/query/settleSendCoins.ts | 0
.../client/1_0/query/voteForSendCoins.ts | 0
.../federation/client/1_1/SendCoinsClient.ts | 3 +
.../client/SendCoinsClientFactory.ts | 7 +-
.../src/federation/enum/apiVersionType.ts | 0
.../src/graphql/enum/TransactionTypeId.ts | 0
.../graphql/logic}/processXComSendCoins.ts | 25 +--
core/src/index.ts | 16 +-
{backend => core}/src/util/utilities.test.ts | 0
{backend => core}/src/util/utilities.ts | 0
core/tsconfig.json | 11 +-
.../src/client/AuthenticationClientFactory.ts | 2 +-
federation/src/client/enum/ApiVersionType.ts | 4 -
.../api/1_0/resolver/DisbursementResolver.ts | 33 +++
42 files changed, 322 insertions(+), 168 deletions(-)
create mode 100644 backend/src/federation/client/1_0/DisbursementClient.ts
create mode 100644 backend/src/federation/client/1_0/query/processDisburseJwtOnSenderCommunity.ts
create mode 100644 backend/src/federation/client/1_1/DisbursementClient.ts
delete mode 100644 backend/src/federation/client/1_1/SendCoinsClient.ts
create mode 100644 backend/src/federation/client/DisbursementClientFactory.ts
rename {backend => core}/src/federation/client/1_0/SendCoinsClient.ts (92%)
rename {backend => core}/src/federation/client/1_0/logging/SendCoinsArgsLogging.view.ts (89%)
rename {backend => core}/src/federation/client/1_0/logging/SendCoinsResultLogging.view.ts (85%)
rename {backend => core}/src/federation/client/1_0/model/SendCoinsArgs.ts (100%)
rename {backend => core}/src/federation/client/1_0/model/SendCoinsResult.ts (100%)
rename {backend => core}/src/federation/client/1_0/query/revertSendCoins.ts (100%)
rename {backend => core}/src/federation/client/1_0/query/revertSettledSendCoins.ts (100%)
rename {backend => core}/src/federation/client/1_0/query/settleSendCoins.ts (100%)
rename {backend => core}/src/federation/client/1_0/query/voteForSendCoins.ts (100%)
create mode 100644 core/src/federation/client/1_1/SendCoinsClient.ts
rename {backend => core}/src/federation/client/SendCoinsClientFactory.ts (85%)
rename {backend => core}/src/federation/enum/apiVersionType.ts (100%)
rename {backend => core}/src/graphql/enum/TransactionTypeId.ts (100%)
rename {backend/src/graphql/resolver/util => core/src/graphql/logic}/processXComSendCoins.ts (93%)
rename {backend => core}/src/util/utilities.test.ts (100%)
rename {backend => core}/src/util/utilities.ts (100%)
delete mode 100644 federation/src/client/enum/ApiVersionType.ts
create mode 100644 federation/src/graphql/api/1_0/resolver/DisbursementResolver.ts
diff --git a/backend/src/apis/dltConnector/DltConnectorClient.ts b/backend/src/apis/dltConnector/DltConnectorClient.ts
index 6f5b437de..bec2990d0 100644
--- a/backend/src/apis/dltConnector/DltConnectorClient.ts
+++ b/backend/src/apis/dltConnector/DltConnectorClient.ts
@@ -3,7 +3,7 @@ import { GraphQLClient, gql } from 'graphql-request'
import { CONFIG } from '@/config'
import { LOG4JS_BASE_CATEGORY_NAME } from '@/config/const'
-import { TransactionTypeId } from '@/graphql/enum/TransactionTypeId'
+import { TransactionTypeId } from 'core/src/graphql/enum/TransactionTypeId'
import { LogError } from '@/server/LogError'
import { getLogger } from 'log4js'
diff --git a/backend/src/federation/authenticateCommunities.ts b/backend/src/federation/authenticateCommunities.ts
index d8946eb47..179c7e996 100644
--- a/backend/src/federation/authenticateCommunities.ts
+++ b/backend/src/federation/authenticateCommunities.ts
@@ -4,7 +4,7 @@ import { randombytes_random } from 'sodium-native'
import { CONFIG } from '@/config'
import { AuthenticationClient as V1_0_AuthenticationClient } from '@/federation/client/1_0/AuthenticationClient'
-import { ensureUrlEndsWithSlash } from '@/util/utilities'
+import { ensureUrlEndsWithSlash } from 'core'
import { LOG4JS_BASE_CATEGORY_NAME } from '@/config/const'
import { encryptAndSign, OpenConnectionJwtPayloadType } from 'shared'
diff --git a/backend/src/federation/client/1_0/DisbursementClient.ts b/backend/src/federation/client/1_0/DisbursementClient.ts
new file mode 100644
index 000000000..bf466feef
--- /dev/null
+++ b/backend/src/federation/client/1_0/DisbursementClient.ts
@@ -0,0 +1,48 @@
+import { FederatedCommunity as DbFederatedCommunity } from 'database'
+import { GraphQLClient } from 'graphql-request'
+
+import { LogError } from '@/server/LogError'
+import { ensureUrlEndsWithSlash } from 'core/src/util/utilities'
+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`)
+
+export class DisbursementClient {
+ dbCom: DbFederatedCommunity
+ endpoint: string
+ client: GraphQLClient
+
+ constructor(dbCom: DbFederatedCommunity) {
+ this.dbCom = dbCom
+ this.endpoint = ensureUrlEndsWithSlash(dbCom.endPoint).concat(dbCom.apiVersion).concat('/')
+ this.client = new GraphQLClient(this.endpoint, {
+ method: 'POST',
+ jsonSerializer: {
+ parse: JSON.parse,
+ stringify: JSON.stringify,
+ },
+ })
+ }
+
+ async sendDisburseJwtToSenderCommunity(args: EncryptedTransferArgs): Promise {
+ logger.debug('sendDisburseJwtToSenderCommunity against endpoint=', this.endpoint)
+ try {
+ const { data } = await this.client.rawRequest<{ processDisburseJwtOnSenderCommunity: string }>(processDisburseJwtOnSenderCommunityQuery, { args })
+ const responseJwt = data?.processDisburseJwtOnSenderCommunity
+ if (responseJwt) {
+ logger.debug('received response jwt', responseJwt)
+ return responseJwt
+ }
+ } catch (err) {
+ const errmsg = `sendDisburseJwtToSenderCommunity failed for endpoint=${this.endpoint}, err=${err}`
+ logger.error(errmsg)
+ throw new Error(errmsg)
+ }
+ return null
+ }
+
+}
diff --git a/backend/src/federation/client/1_0/FederationClient.ts b/backend/src/federation/client/1_0/FederationClient.ts
index df1140f9c..525765803 100644
--- a/backend/src/federation/client/1_0/FederationClient.ts
+++ b/backend/src/federation/client/1_0/FederationClient.ts
@@ -4,7 +4,7 @@ import { GraphQLClient } from 'graphql-request'
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 '@/util/utilities'
+import { ensureUrlEndsWithSlash } from 'core/src/util/utilities'
import { getLogger } from 'log4js'
import { PublicCommunityInfoLoggingView } from './logging/PublicCommunityInfoLogging.view'
diff --git a/backend/src/federation/client/1_0/query/processDisburseJwtOnSenderCommunity.ts b/backend/src/federation/client/1_0/query/processDisburseJwtOnSenderCommunity.ts
new file mode 100644
index 000000000..e2d0f49d9
--- /dev/null
+++ b/backend/src/federation/client/1_0/query/processDisburseJwtOnSenderCommunity.ts
@@ -0,0 +1,7 @@
+import { gql } from 'graphql-request'
+
+export const processDisburseJwtOnSenderCommunity = gql`
+ mutation ($args: EncryptedTransferArgs!) {
+ processDisburseJwtOnSenderCommunity(data: $args)
+ }
+`
diff --git a/backend/src/federation/client/1_1/DisbursementClient.ts b/backend/src/federation/client/1_1/DisbursementClient.ts
new file mode 100644
index 000000000..411befe19
--- /dev/null
+++ b/backend/src/federation/client/1_1/DisbursementClient.ts
@@ -0,0 +1,3 @@
+import { DisbursementClient as V1_0_DisbursementClient } from '@/federation/client/1_0/DisbursementClient'
+
+export class DisbursementClient extends V1_0_DisbursementClient {}
diff --git a/backend/src/federation/client/1_1/SendCoinsClient.ts b/backend/src/federation/client/1_1/SendCoinsClient.ts
deleted file mode 100644
index cc804d0dc..000000000
--- a/backend/src/federation/client/1_1/SendCoinsClient.ts
+++ /dev/null
@@ -1,3 +0,0 @@
-import { SendCoinsClient as V1_0_SendCoinsClient } from '@/federation/client/1_0/SendCoinsClient'
-
-export class SendCoinsClient extends V1_0_SendCoinsClient {}
diff --git a/backend/src/federation/client/AuthenticationClientFactory.ts b/backend/src/federation/client/AuthenticationClientFactory.ts
index 0ae0cd1b8..344753a48 100644
--- a/backend/src/federation/client/AuthenticationClientFactory.ts
+++ b/backend/src/federation/client/AuthenticationClientFactory.ts
@@ -3,7 +3,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 '@/federation/enum/apiVersionType'
+import { ApiVersionType } from 'core'
type AuthenticationClient = V1_0_AuthenticationClient | V1_1_AuthenticationClient
diff --git a/backend/src/federation/client/DisbursementClientFactory.ts b/backend/src/federation/client/DisbursementClientFactory.ts
new file mode 100644
index 000000000..01c911e92
--- /dev/null
+++ b/backend/src/federation/client/DisbursementClientFactory.ts
@@ -0,0 +1,58 @@
+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
+
+interface DisbursementClientInstance {
+ id: number
+
+ client: DisbursementClient
+}
+
+export class DisbursementClientFactory {
+ private static instanceArray: DisbursementClientInstance[] = []
+
+ /**
+ * The Singleton's constructor should always be private to prevent direct
+ * construction calls with the `new` operator.
+ */
+
+ private constructor() {}
+
+ private static createDisbursementClient = (dbCom: DbFederatedCommunity) => {
+ switch (dbCom.apiVersion) {
+ case ApiVersionType.V1_0:
+ return new V1_0_DisbursementClient(dbCom)
+ case ApiVersionType.V1_1:
+ return new V1_1_DisbursementClient(dbCom)
+ default:
+ return null
+ }
+ }
+
+ /**
+ * The static method that controls the access to the singleton instance.
+ *
+ * This implementation let you subclass the Singleton class while keeping
+ * just one instance of each subclass around.
+ */
+ public static getInstance(dbCom: DbFederatedCommunity): DisbursementClient | null {
+ const instance = DisbursementClientFactory.instanceArray.find(
+ (instance) => instance.id === dbCom.id,
+ )
+ if (instance) {
+ return instance.client
+ }
+ const client = DisbursementClientFactory.createDisbursementClient(dbCom)
+ if (client) {
+ DisbursementClientFactory.instanceArray.push({
+ id: dbCom.id,
+ client,
+ } as DisbursementClientInstance)
+ }
+ return client
+ }
+}
diff --git a/backend/src/federation/client/FederationClientFactory.ts b/backend/src/federation/client/FederationClientFactory.ts
index 3660934f4..926c3c180 100644
--- a/backend/src/federation/client/FederationClientFactory.ts
+++ b/backend/src/federation/client/FederationClientFactory.ts
@@ -1,10 +1,8 @@
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 } from '@/federation/enum/apiVersionType'
-import { ensureUrlEndsWithSlash } from '@/util/utilities'
+import { ApiVersionType, ensureUrlEndsWithSlash } from 'core'
type FederationClient = V1_0_FederationClient | V1_1_FederationClient
diff --git a/backend/src/federation/validateCommunities.ts b/backend/src/federation/validateCommunities.ts
index 478261386..36c9985c9 100644
--- a/backend/src/federation/validateCommunities.ts
+++ b/backend/src/federation/validateCommunities.ts
@@ -15,7 +15,7 @@ import { createKeyPair } from 'shared'
import { getLogger } from 'log4js'
import { startCommunityAuthentication } from './authenticateCommunities'
import { PublicCommunityInfoLoggingView } from './client/1_0/logging/PublicCommunityInfoLogging.view'
-import { ApiVersionType } from './enum/apiVersionType'
+import { ApiVersionType } from 'core'
const logger = getLogger(`${LOG4JS_BASE_CATEGORY_NAME}.federation.validateCommunities`)
diff --git a/backend/src/graphql/model/Transaction.ts b/backend/src/graphql/model/Transaction.ts
index dc0849a53..ee7250271 100644
--- a/backend/src/graphql/model/Transaction.ts
+++ b/backend/src/graphql/model/Transaction.ts
@@ -2,7 +2,7 @@ import { Transaction as dbTransaction } from 'database'
import { Decimal } from 'decimal.js-light'
import { Field, Int, ObjectType } from 'type-graphql'
-import { TransactionTypeId } from '@enum/TransactionTypeId'
+import { TransactionTypeId } from 'core/src/graphql/enum/TransactionTypeId'
import { Decay } from './Decay'
import { User } from './User'
diff --git a/backend/src/graphql/resolver/ContributionResolver.ts b/backend/src/graphql/resolver/ContributionResolver.ts
index c6f7b33c1..6e2a302ba 100644
--- a/backend/src/graphql/resolver/ContributionResolver.ts
+++ b/backend/src/graphql/resolver/ContributionResolver.ts
@@ -16,11 +16,11 @@ import { Paginated } from '@arg/Paginated'
import { SearchContributionsFilterArgs } from '@arg/SearchContributionsFilterArgs'
import { ContributionStatus } from '@enum/ContributionStatus'
import { ContributionType } from '@enum/ContributionType'
-import { TransactionTypeId } from '@enum/TransactionTypeId'
import { AdminUpdateContribution } from '@model/AdminUpdateContribution'
import { Contribution, ContributionListResult } from '@model/Contribution'
import { OpenCreation } from '@model/OpenCreation'
import { UnconfirmedContribution } from '@model/UnconfirmedContribution'
+import { TransactionTypeId } from 'core'
import { RIGHTS } from '@/auth/RIGHTS'
import {
@@ -43,8 +43,8 @@ import { UpdateUnconfirmedContributionContext } from '@/interactions/updateUncon
import { LogError } from '@/server/LogError'
import { Context, getClientTimezoneOffset, getUser } from '@/server/context'
import { TRANSACTIONS_LOCK } from '@/util/TRANSACTIONS_LOCK'
+import { fullName } from 'core'
import { calculateDecay, Decay } from 'shared'
-import { fullName } from '@/util/utilities'
import { LOG4JS_BASE_CATEGORY_NAME } from '@/config/const'
import { ContributionMessageType } from '@enum/ContributionMessageType'
diff --git a/backend/src/graphql/resolver/TransactionLinkResolver.ts b/backend/src/graphql/resolver/TransactionLinkResolver.ts
index 65c2d5df6..546d11124 100644
--- a/backend/src/graphql/resolver/TransactionLinkResolver.ts
+++ b/backend/src/graphql/resolver/TransactionLinkResolver.ts
@@ -6,22 +6,19 @@ import { TransactionLinkFilters } from '@arg/TransactionLinkFilters'
import { ContributionCycleType } from '@enum/ContributionCycleType'
import { ContributionStatus } from '@enum/ContributionStatus'
import { ContributionType } from '@enum/ContributionType'
-import { TransactionTypeId } from '@enum/TransactionTypeId'
-import { Community } from '@model/Community'
import { ContributionLink } from '@model/ContributionLink'
import { Decay } from '@model/Decay'
import { RedeemJwtLink } from '@model/RedeemJwtLink'
import { TransactionLink, TransactionLinkResult } from '@model/TransactionLink'
import { User } from '@model/User'
import { QueryLinkResult } from '@union/QueryLinkResult'
+import { TransactionTypeId } from 'core'
import {
- AppDatabase,
- Contribution as DbContribution,
- ContributionLink as DbContributionLink,
- Transaction as DbTransaction,
+ AppDatabase, Community as DbCommunity, Contribution as DbContribution,
+ ContributionLink as DbContributionLink, FederatedCommunity as DbFederatedCommunity, Transaction as DbTransaction,
TransactionLink as DbTransactionLink,
User as DbUser,
- getHomeCommunity,
+ getHomeCommunity
} from 'database'
import { Decimal } from 'decimal.js-light'
import { Arg, Args, Authorized, Ctx, Int, Mutation, Query, Resolver } from 'type-graphql'
@@ -37,12 +34,16 @@ import { LogError } from '@/server/LogError'
import { Context, getClientTimezoneOffset, getUser } from '@/server/context'
import { TRANSACTIONS_LOCK } from '@/util/TRANSACTIONS_LOCK'
import { TRANSACTION_LINK_LOCK } from '@/util/TRANSACTION_LINK_LOCK'
-import { fullName } from '@/util/utilities'
import { calculateBalance } from '@/util/validate'
+import { fullName } from 'core'
import { calculateDecay, 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 { getLogger, Logger } from 'log4js'
+import { randombytes_random } from 'sodium-native'
import { executeTransaction } from './TransactionResolver'
import {
getAuthenticatedCommunities,
@@ -53,7 +54,7 @@ import { getLastTransaction } from './util/getLastTransaction'
import { sendTransactionsToDltConnector } from './util/sendTransactionsToDltConnector'
import { transactionLinkList } from './util/transactionLinkList'
-const createLogger = () => getLogger(`${LOG4JS_BASE_CATEGORY_NAME}.graphql.resolver.TransactionLinkResolver`)
+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 => {
@@ -148,9 +149,9 @@ export class TransactionLinkResolver {
@Authorized([RIGHTS.QUERY_TRANSACTION_LINK])
@Query(() => QueryLinkResult)
async queryTransactionLink(@Arg('code') code: string): Promise {
- const logger = createLogger()
- logger.addContext('code', code.substring(0, 6))
- logger.debug('TransactionLinkResolver.queryTransactionLink...')
+ const methodLogger = createLogger('queryTransactionLink')
+ methodLogger.addContext('code', code.substring(0, 6))
+ methodLogger.debug('queryTransactionLink...')
if (code.match(/^CL-/)) {
const contributionLink = await DbContributionLink.findOneOrFail({
where: { code: code.replace('CL-', '') },
@@ -171,7 +172,7 @@ export class TransactionLinkResolver {
}
// normal redeem code
if (txLinkFound) {
- logger.debug(
+ methodLogger.debug(
'TransactionLinkResolver.queryTransactionLink... normal redeem code found=',
txLinkFound,
)
@@ -186,7 +187,7 @@ export class TransactionLinkResolver {
return new TransactionLink(dbTransactionLink, new User(user), redeemedBy, communities)
} else {
// redeem jwt-token
- return await this.queryRedeemJwtLink(code, logger)
+ return await this.queryRedeemJwtLink(code, methodLogger)
}
}
}
@@ -197,8 +198,8 @@ export class TransactionLinkResolver {
@Arg('code', () => String) code: string,
@Ctx() context: Context,
): Promise {
- const logger = createLogger()
- logger.addContext('code', code.substring(0, 6))
+ const methodLogger = createLogger('redeemTransactionLink')
+ methodLogger.addContext('code', code.substring(0, 6))
const clientTimezoneOffset = getClientTimezoneOffset(context)
// const homeCom = await DbCommunity.findOneOrFail({ where: { foreign: false } })
const user = getUser(context)
@@ -206,7 +207,7 @@ export class TransactionLinkResolver {
// acquire lock
const releaseLock = await TRANSACTIONS_LOCK.acquire()
try {
- logger.info('redeem contribution link...')
+ methodLogger.info('redeem contribution link...')
const now = new Date()
const queryRunner = db.getDataSource().createQueryRunner()
await queryRunner.connect()
@@ -221,7 +222,7 @@ export class TransactionLinkResolver {
if (!contributionLink) {
throw new LogError('No contribution link found to given code', code)
}
- logger.info('...contribution link found with id', contributionLink.id)
+ methodLogger.info('...contribution link found with id', contributionLink.id)
if (new Date(contributionLink.validFrom).getTime() > now.getTime()) {
throw new LogError('Contribution link is not valid yet', contributionLink.validFrom)
}
@@ -278,7 +279,7 @@ export class TransactionLinkResolver {
}
const creations = await getUserCreation(user.id, clientTimezoneOffset)
- logger.info('open creations', creations)
+ methodLogger.info('open creations', creations)
validateContribution(creations, contributionLink.amount, now, clientTimezoneOffset)
const contribution = new DbContribution()
contribution.userId = user.id
@@ -383,7 +384,7 @@ export class TransactionLinkResolver {
transactionLink.memo,
linkedUser,
user,
- logger,
+ methodLogger,
transactionLink,
)
await EVENT_TRANSACTION_LINK_REDEEM(
@@ -413,9 +414,9 @@ export class TransactionLinkResolver {
@Arg('alias', { nullable: true }) alias?: string,
@Arg('validUntil', { nullable: true }) validUntil?: string,
): Promise {
- const logger = createLogger()
- logger.addContext('code', code.substring(0, 6))
- logger.debug('TransactionLinkResolver.queryRedeemJwt... args=', {
+ const methodLogger = createLogger('createRedeemJwt')
+ methodLogger.addContext('code', code.substring(0, 6))
+ methodLogger.debug('args=', {
gradidoId,
senderCommunityUuid,
senderCommunityName,
@@ -466,40 +467,80 @@ export class TransactionLinkResolver {
@Arg('validUntil', { nullable: true }) validUntil?: string,
@Arg('recipientAlias', { nullable: true }) recipientAlias?: string,
): Promise {
- const logger = createLogger()
- logger.addContext('code', code.substring(0, 6))
- logger.debug('TransactionLinkResolver.disburseTransactionLink... args=', {
- senderGradidoId,
- senderCommunityUuid,
- recipientCommunityUuid,
- recipientCommunityName,
- recipientGradidoId,
- recipientFirstName,
- code,
- amount,
- memo,
- validUntil,
+ const handshakeID = randombytes_random().toString()
+ const methodLogger = createLogger(`disburseTransactionLink`)
+ methodLogger.addContext('handshakeID', handshakeID)
+ if(methodLogger.isDebugEnabled()) {
+ methodLogger.debug('args=', {
+ senderGradidoId,
+ senderCommunityUuid,
+ recipientCommunityUuid,
+ recipientCommunityName,
+ recipientGradidoId,
+ recipientFirstName,
+ code,
+ amount,
+ memo,
+ validUntil,
recipientAlias,
- })
- const disburseJwt = await this.createDisburseJwt(
- senderCommunityUuid,
- senderGradidoId,
- recipientCommunityUuid,
- recipientCommunityName,
- recipientGradidoId,
- recipientFirstName,
- code,
- amount,
- memo,
- validUntil ?? '',
- recipientAlias ?? '',
- )
- try {
- logger.debug('TransactionLinkResolver.disburseTransactionLink... disburseJwt=', disburseJwt)
- // now send the disburseJwt to the sender community to invoke a x-community-tx to disbures the redeemLink
- // await sendDisburseJwtToSenderCommunity(context, disburseJwt)
- } catch (e) {
- throw new LogError('Disburse JWT was not sent successfully', e)
+ })
+ }
+ const senderCom = await DbCommunity.findOneBy({ communityUuid: senderCommunityUuid })
+ if (!senderCom) {
+ const errmsg = `Sender community not found with uuid=${senderCommunityUuid}`
+ methodLogger.error(errmsg)
+ throw new LogError(errmsg)
+ }
+ const senderFedCom = await DbFederatedCommunity.findOneBy({ publicKey: senderCom.publicKey })
+ if (!senderFedCom) {
+ const errmsg = `Sender federated community not found with publicKey=${senderCom.publicKey}`
+ methodLogger.error(errmsg)
+ throw new LogError(errmsg)
+ }
+ const recipientCom = await DbCommunity.findOneBy({ communityUuid: recipientCommunityUuid })
+ if (!recipientCom) {
+ const errmsg = `Recipient community not found with uuid=${recipientCommunityUuid}`
+ methodLogger.error(errmsg)
+ throw new LogError(errmsg)
+ }
+ const client = DisbursementClientFactory.getInstance(senderFedCom)
+ if (client instanceof V1_0_DisbursementClient) {
+ const disburseJwtPayload = new DisburseJwtPayloadType(
+ handshakeID,
+ senderCommunityUuid,
+ senderGradidoId,
+ recipientCommunityUuid,
+ recipientCommunityName,
+ recipientGradidoId,
+ recipientFirstName,
+ code,
+ amount,
+ memo,
+ validUntil!,
+ recipientAlias!,
+ )
+ if(methodLogger.isDebugEnabled()) {
+ methodLogger.debug('disburseJwtPayload=', disburseJwtPayload)
+ }
+ const jws = await encryptAndSign(disburseJwtPayload, recipientCom.privateJwtKey!, senderCom.publicJwtKey!)
+ if(methodLogger.isDebugEnabled()) {
+ methodLogger.debug('jws=', jws)
+ }
+ const args = new EncryptedTransferArgs()
+ args.publicKey = senderCom.publicKey.toString('hex')
+ args.jwt = jws
+ args.handshakeID = handshakeID
+ 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()) {
+ methodLogger.debug('Disburse JWT was sent successfully with result=', result)
+ }
+ } catch (e) {
+ const errmsg = `Disburse JWT was not sent successfully with error=${e}`
+ methodLogger.error(errmsg)
+ throw new Error(errmsg)
+ }
}
return true
}
@@ -653,56 +694,4 @@ export class TransactionLinkResolver {
)
}
}
-
- async createDisburseJwt(
- handshakeId: string,
- senderCommunityUuid: string,
- senderGradidoId: string,
- recipientCommunityUuid: string,
- recipientCommunityName: string,
- recipientGradidoId: string,
- recipientFirstName: string,
- code: string,
- amount: string,
- memo: string,
- validUntil: string,
- recipientAlias: string,
- ): Promise {
- const logger = createLogger()
- logger.addContext('code', code.substring(0, 6))
- logger.debug('TransactionLinkResolver.createDisburseJwt... args=', {
- handshakeId,
- senderCommunityUuid,
- senderGradidoId,
- recipientCommunityUuid,
- recipientCommunityName,
- recipientGradidoId,
- recipientFirstName,
- code,
- amount,
- memo,
- validUntil,
- recipientAlias,
- })
-
- const disburseJwtPayload = new DisburseJwtPayloadType(
- handshakeId,
- senderCommunityUuid,
- senderGradidoId,
- recipientCommunityUuid,
- recipientCommunityName,
- recipientGradidoId,
- recipientFirstName,
- code,
- amount,
- memo,
- validUntil,
- recipientAlias,
- )
- const disburseJwt = await encryptAndSign(disburseJwtPayload, homeComB.privateJwtKey!, authCom.publicJwtKey!)
- // TODO:encode/sign the jwt normally with the private key of the recipient community, but interims with uuid
- logger.debug('TransactionLinkResolver.createDisburseJwt... disburseJwt=', disburseJwt)
- // TODO: encrypt the payload with the public key of the target/sender community
- return disburseJwt
- }
}
diff --git a/backend/src/graphql/resolver/TransactionResolver.test.ts b/backend/src/graphql/resolver/TransactionResolver.test.ts
index 275ae77fd..e39fcefc4 100644
--- a/backend/src/graphql/resolver/TransactionResolver.test.ts
+++ b/backend/src/graphql/resolver/TransactionResolver.test.ts
@@ -16,9 +16,9 @@ import { cleanDB, testEnvironment } from '@test/helpers'
import { CONFIG } from '@/config'
import { LOG4JS_BASE_CATEGORY_NAME } from '@/config/const'
import { EventType } from '@/event/Events'
-import { SendCoinsClient } from '@/federation/client/1_0/SendCoinsClient'
-import { SendCoinsArgs } from '@/federation/client/1_0/model/SendCoinsArgs'
-import { SendCoinsResult } from '@/federation/client/1_0/model/SendCoinsResult'
+import { SendCoinsClient } from 'core/src/federation/client/1_0/SendCoinsClient'
+import { SendCoinsArgs } from 'core/src/federation/client/1_0/model/SendCoinsArgs'
+import { SendCoinsResult } from 'core/src/federation/client/1_0/model/SendCoinsResult'
import { userFactory } from '@/seeds/factory/user'
import {
confirmContribution,
diff --git a/backend/src/graphql/resolver/TransactionResolver.ts b/backend/src/graphql/resolver/TransactionResolver.ts
index 06ddf6bbf..5ceef0836 100644
--- a/backend/src/graphql/resolver/TransactionResolver.ts
+++ b/backend/src/graphql/resolver/TransactionResolver.ts
@@ -2,7 +2,6 @@ import {
AppDatabase,
countOpenPendingTransactions,
Community as DbCommunity,
- PendingTransaction as DbPendingTransaction,
Transaction as dbTransaction,
TransactionLink as dbTransactionLink,
User as dbUser,
@@ -15,11 +14,11 @@ import { In, IsNull } from 'typeorm'
import { Paginated } from '@arg/Paginated'
import { TransactionSendArgs } from '@arg/TransactionSendArgs'
import { Order } from '@enum/Order'
-import { PendingTransactionState, SendCoinsResponseJwtPayloadType } from 'shared'
-import { TransactionTypeId } from '@enum/TransactionTypeId'
import { Transaction } from '@model/Transaction'
import { TransactionList } from '@model/TransactionList'
import { User } from '@model/User'
+import { TransactionTypeId } from 'core/src/graphql/enum/TransactionTypeId'
+import { SendCoinsResponseJwtPayloadType } from 'shared'
import { RIGHTS } from '@/auth/RIGHTS'
import { CONFIG } from '@/config'
@@ -28,26 +27,25 @@ import {
sendTransactionReceivedEmail,
} from '@/emails/sendEmailVariants'
import { EVENT_TRANSACTION_RECEIVE, EVENT_TRANSACTION_SEND } from '@/event/Events'
-import { SendCoinsResult } from '@/federation/client/1_0/model/SendCoinsResult'
import { LogError } from '@/server/LogError'
import { Context, getUser } from '@/server/context'
import { TRANSACTIONS_LOCK } from '@/util/TRANSACTIONS_LOCK'
import { communityUser } from '@/util/communityUser'
-import { fullName } from '@/util/utilities'
import { calculateBalance } from '@/util/validate'
import { virtualDecayTransaction, virtualLinkTransaction } from '@/util/virtualTransactions'
+import { fullName, SendCoinsResult } from 'core'
-import { Logger, getLogger } from 'log4js'
import { LOG4JS_BASE_CATEGORY_NAME } from '@/config/const'
+import {
+ processXComCommittingSendCoins,
+ processXComPendingSendCoins,
+} from 'core'
+import { getLogger, Logger } from 'log4js'
import { BalanceResolver } from './BalanceResolver'
import { GdtResolver } from './GdtResolver'
import { getCommunityByIdentifier, getCommunityName, isHomeCommunity } from './util/communities'
import { getLastTransaction } from './util/getLastTransaction'
import { getTransactionList } from './util/getTransactionList'
-import {
- processXComCommittingSendCoins,
- processXComPendingSendCoins,
-} from './util/processXComSendCoins'
import { sendTransactionsToDltConnector } from './util/sendTransactionsToDltConnector'
import { storeForeignUser } from './util/storeForeignUser'
import { transactionLinkSummary } from './util/transactionLinkSummary'
diff --git a/backend/src/graphql/resolver/util/sendTransactionsToDltConnector.test.ts b/backend/src/graphql/resolver/util/sendTransactionsToDltConnector.test.ts
index b5ec0a08a..769730544 100644
--- a/backend/src/graphql/resolver/util/sendTransactionsToDltConnector.test.ts
+++ b/backend/src/graphql/resolver/util/sendTransactionsToDltConnector.test.ts
@@ -12,7 +12,7 @@ import { cleanDB, testEnvironment } from '@test/helpers'
import { i18n as localization } from '@test/testSetup'
import { CONFIG } from '@/config'
-import { TransactionTypeId } from '@/graphql/enum/TransactionTypeId'
+import { TransactionTypeId } from 'core'
import { creations } from '@/seeds/creation'
import { creationFactory } from '@/seeds/factory/creation'
import { userFactory } from '@/seeds/factory/user'
diff --git a/backend/src/graphql/resolver/util/storeForeignUser.ts b/backend/src/graphql/resolver/util/storeForeignUser.ts
index adceb155e..8c33c8923 100644
--- a/backend/src/graphql/resolver/util/storeForeignUser.ts
+++ b/backend/src/graphql/resolver/util/storeForeignUser.ts
@@ -1,6 +1,6 @@
import { Community as DbCommunity, User as DbUser } from 'database'
-import { SendCoinsResult } from '@/federation/client/1_0/model/SendCoinsResult'
+import { SendCoinsResult } from 'core/src/federation/client/1_0/model/SendCoinsResult'
import { LOG4JS_BASE_CATEGORY_NAME } from '@/config/const'
import { getLogger } from 'log4js'
diff --git a/backend/src/util/virtualTransactions.ts b/backend/src/util/virtualTransactions.ts
index dabaee264..0811eaf1b 100644
--- a/backend/src/util/virtualTransactions.ts
+++ b/backend/src/util/virtualTransactions.ts
@@ -2,7 +2,7 @@ import { Transaction as dbTransaction } from 'database'
import { Decimal } from 'decimal.js-light'
import { RemoveOptions, SaveOptions } from 'typeorm'
-import { TransactionTypeId } from '@enum/TransactionTypeId'
+import { TransactionTypeId } from 'core/src/graphql/enum/TransactionTypeId'
import { Transaction } from '@model/Transaction'
import { User } from '@model/User'
diff --git a/bun.lock b/bun.lock
index b49609f5c..30a87f9af 100644
--- a/bun.lock
+++ b/bun.lock
@@ -192,6 +192,7 @@
"devDependencies": {
"@biomejs/biome": "2.0.0",
"@types/node": "^17.0.21",
+ "jest": "27.2.4",
"type-graphql": "^1.1.1",
"typescript": "^4.9.5",
},
diff --git a/core/package.json b/core/package.json
index a1f7a5603..0044d263f 100644
--- a/core/package.json
+++ b/core/package.json
@@ -27,6 +27,7 @@
"devDependencies": {
"@biomejs/biome": "2.0.0",
"@types/node": "^17.0.21",
+ "jest": "27.2.4",
"type-graphql": "^1.1.1",
"typescript": "^4.9.5"
},
diff --git a/backend/src/federation/client/1_0/SendCoinsClient.ts b/core/src/federation/client/1_0/SendCoinsClient.ts
similarity index 92%
rename from backend/src/federation/client/1_0/SendCoinsClient.ts
rename to core/src/federation/client/1_0/SendCoinsClient.ts
index 13c2b8697..f4b6d49d8 100644
--- a/backend/src/federation/client/1_0/SendCoinsClient.ts
+++ b/core/src/federation/client/1_0/SendCoinsClient.ts
@@ -1,7 +1,6 @@
import { FederatedCommunity as DbFederatedCommunity } from 'database'
import { GraphQLClient } from 'graphql-request'
-import { LogError } from '@/server/LogError'
import { ensureUrlEndsWithSlash } from '@/util/utilities'
import { getLogger } from 'log4js'
@@ -83,7 +82,9 @@ export class SendCoinsClient {
logger.debug(`settleSendCoins successful from endpoint=${this.endpoint}`)
return true
} catch (err) {
- throw new LogError(`settleSendCoins failed for endpoint=${this.endpoint}`, err)
+ const errmsg = `settleSendCoins failed for endpoint=${this.endpoint}, err=${err}`
+ logger.error(errmsg)
+ throw new Error(errmsg)
}
}
@@ -103,7 +104,9 @@ export class SendCoinsClient {
logger.debug(`revertSettledSendCoins successful from endpoint=${this.endpoint}`)
return true
} catch (err) {
- throw new LogError(`revertSettledSendCoins failed for endpoint=${this.endpoint}`, err)
+ const errmsg = `revertSettledSendCoins failed for endpoint=${this.endpoint}, err=${err}`
+ logger.error(errmsg)
+ throw new Error(errmsg)
}
}
}
diff --git a/backend/src/federation/client/1_0/logging/SendCoinsArgsLogging.view.ts b/core/src/federation/client/1_0/logging/SendCoinsArgsLogging.view.ts
similarity index 89%
rename from backend/src/federation/client/1_0/logging/SendCoinsArgsLogging.view.ts
rename to core/src/federation/client/1_0/logging/SendCoinsArgsLogging.view.ts
index 9bd8fee69..4057a2971 100644
--- a/backend/src/federation/client/1_0/logging/SendCoinsArgsLogging.view.ts
+++ b/core/src/federation/client/1_0/logging/SendCoinsArgsLogging.view.ts
@@ -1,6 +1,6 @@
import { AbstractLoggingView } from 'database'
-import { SendCoinsArgs } from '@/federation/client/1_0/model/SendCoinsArgs'
+import { SendCoinsArgs } from 'core/src/federation/client/1_0/model/SendCoinsArgs'
export class SendCoinsArgsLoggingView extends AbstractLoggingView {
public constructor(private self: SendCoinsArgs) {
diff --git a/backend/src/federation/client/1_0/logging/SendCoinsResultLogging.view.ts b/core/src/federation/client/1_0/logging/SendCoinsResultLogging.view.ts
similarity index 85%
rename from backend/src/federation/client/1_0/logging/SendCoinsResultLogging.view.ts
rename to core/src/federation/client/1_0/logging/SendCoinsResultLogging.view.ts
index 2f2ec355e..a83e211e8 100644
--- a/backend/src/federation/client/1_0/logging/SendCoinsResultLogging.view.ts
+++ b/core/src/federation/client/1_0/logging/SendCoinsResultLogging.view.ts
@@ -1,6 +1,6 @@
import { AbstractLoggingView } from 'database'
-import { SendCoinsResult } from '@/federation/client/1_0/model/SendCoinsResult'
+import { SendCoinsResult } from 'core/src/federation/client/1_0/model/SendCoinsResult'
export class SendCoinsResultLoggingView extends AbstractLoggingView {
public constructor(private self: SendCoinsResult) {
diff --git a/backend/src/federation/client/1_0/model/SendCoinsArgs.ts b/core/src/federation/client/1_0/model/SendCoinsArgs.ts
similarity index 100%
rename from backend/src/federation/client/1_0/model/SendCoinsArgs.ts
rename to core/src/federation/client/1_0/model/SendCoinsArgs.ts
diff --git a/backend/src/federation/client/1_0/model/SendCoinsResult.ts b/core/src/federation/client/1_0/model/SendCoinsResult.ts
similarity index 100%
rename from backend/src/federation/client/1_0/model/SendCoinsResult.ts
rename to core/src/federation/client/1_0/model/SendCoinsResult.ts
diff --git a/backend/src/federation/client/1_0/query/revertSendCoins.ts b/core/src/federation/client/1_0/query/revertSendCoins.ts
similarity index 100%
rename from backend/src/federation/client/1_0/query/revertSendCoins.ts
rename to core/src/federation/client/1_0/query/revertSendCoins.ts
diff --git a/backend/src/federation/client/1_0/query/revertSettledSendCoins.ts b/core/src/federation/client/1_0/query/revertSettledSendCoins.ts
similarity index 100%
rename from backend/src/federation/client/1_0/query/revertSettledSendCoins.ts
rename to core/src/federation/client/1_0/query/revertSettledSendCoins.ts
diff --git a/backend/src/federation/client/1_0/query/settleSendCoins.ts b/core/src/federation/client/1_0/query/settleSendCoins.ts
similarity index 100%
rename from backend/src/federation/client/1_0/query/settleSendCoins.ts
rename to core/src/federation/client/1_0/query/settleSendCoins.ts
diff --git a/backend/src/federation/client/1_0/query/voteForSendCoins.ts b/core/src/federation/client/1_0/query/voteForSendCoins.ts
similarity index 100%
rename from backend/src/federation/client/1_0/query/voteForSendCoins.ts
rename to core/src/federation/client/1_0/query/voteForSendCoins.ts
diff --git a/core/src/federation/client/1_1/SendCoinsClient.ts b/core/src/federation/client/1_1/SendCoinsClient.ts
new file mode 100644
index 000000000..b37f08b29
--- /dev/null
+++ b/core/src/federation/client/1_1/SendCoinsClient.ts
@@ -0,0 +1,3 @@
+import { SendCoinsClient as V1_0_SendCoinsClient } from 'core/src/federation/client/1_0/SendCoinsClient'
+
+export class SendCoinsClient extends V1_0_SendCoinsClient {}
diff --git a/backend/src/federation/client/SendCoinsClientFactory.ts b/core/src/federation/client/SendCoinsClientFactory.ts
similarity index 85%
rename from backend/src/federation/client/SendCoinsClientFactory.ts
rename to core/src/federation/client/SendCoinsClientFactory.ts
index 2fd15f739..8251da3cb 100644
--- a/backend/src/federation/client/SendCoinsClientFactory.ts
+++ b/core/src/federation/client/SendCoinsClientFactory.ts
@@ -1,9 +1,8 @@
import { FederatedCommunity as DbFederatedCommunity } from 'database'
-import { SendCoinsClient as V1_0_SendCoinsClient } from '@/federation/client/1_0/SendCoinsClient'
-
-import { SendCoinsClient as V1_1_SendCoinsClient } from '@/federation/client/1_1/SendCoinsClient'
-import { ApiVersionType } from '@/federation/enum/apiVersionType'
+import { SendCoinsClient as V1_0_SendCoinsClient } from '@federation/client/1_0/SendCoinsClient'
+import { SendCoinsClient as V1_1_SendCoinsClient } from '@federation/client/1_1/SendCoinsClient'
+import { ApiVersionType } from '@federation/enum/apiVersionType'
type SendCoinsClient = V1_0_SendCoinsClient | V1_1_SendCoinsClient
diff --git a/backend/src/federation/enum/apiVersionType.ts b/core/src/federation/enum/apiVersionType.ts
similarity index 100%
rename from backend/src/federation/enum/apiVersionType.ts
rename to core/src/federation/enum/apiVersionType.ts
diff --git a/backend/src/graphql/enum/TransactionTypeId.ts b/core/src/graphql/enum/TransactionTypeId.ts
similarity index 100%
rename from backend/src/graphql/enum/TransactionTypeId.ts
rename to core/src/graphql/enum/TransactionTypeId.ts
diff --git a/backend/src/graphql/resolver/util/processXComSendCoins.ts b/core/src/graphql/logic/processXComSendCoins.ts
similarity index 93%
rename from backend/src/graphql/resolver/util/processXComSendCoins.ts
rename to core/src/graphql/logic/processXComSendCoins.ts
index 91eb61a1e..3b17939d5 100644
--- a/backend/src/graphql/resolver/util/processXComSendCoins.ts
+++ b/core/src/graphql/logic/processXComSendCoins.ts
@@ -10,23 +10,22 @@ import {
} from 'database'
import { Decimal } from 'decimal.js-light'
-import { CONFIG } from '@/config'
+import { LOG4JS_BASE_CATEGORY_NAME } from '@config/const'
-import { SendCoinsClient as V1_0_SendCoinsClient } from '@/federation/client/1_0/SendCoinsClient'
-import { SendCoinsArgs } from '@/federation/client/1_0/model/SendCoinsArgs'
-import { SendCoinsResult } from '@/federation/client/1_0/model/SendCoinsResult'
-import { SendCoinsClientFactory } from '@/federation/client/SendCoinsClientFactory'
+import { SendCoinsClient as V1_0_SendCoinsClient } from '@federation/client/1_0/SendCoinsClient'
+import { SendCoinsArgs } from '@federation/client/1_0/model/SendCoinsArgs'
+import { SendCoinsResult } from '@federation/client/1_0/model/SendCoinsResult'
+import { SendCoinsClientFactory } from '@federation/client/SendCoinsClientFactory'
import { encryptAndSign, PendingTransactionState, SendCoinsJwtPayloadType, SendCoinsResponseJwtPayloadType, verifyAndDecrypt } from 'shared'
-import { TransactionTypeId } from '@/graphql/enum/TransactionTypeId'
-import { LOG4JS_BASE_CATEGORY_NAME } from '@/config/const'
-import { LogError } from '@/server/LogError'
-import { calculateSenderBalance } from '@/util/calculateSenderBalance'
-import { fullName } from '@/util/utilities'
+import { TransactionTypeId } from '@graphql/enum/TransactionTypeId'
+import { LogError } from '@server/LogError'
+import { calculateSenderBalance } from '@util/calculateSenderBalance'
+import { fullName } from '@util/utilities'
import { getLogger } from 'log4js'
-import { settlePendingSenderTransaction } from './settlePendingSenderTransaction'
-import { SendCoinsArgsLoggingView } from '@/federation/client/1_0/logging/SendCoinsArgsLogging.view'
-import { SendCoinsResultLoggingView } from '@/federation/client/1_0/logging/SendCoinsResultLogging.view'
+import { settlePendingSenderTransaction } from '@graphql/resolver/util/settlePendingSenderTransaction'
+import { SendCoinsArgsLoggingView } from '@federation/client/1_0/logging/SendCoinsArgsLogging.view'
+import { SendCoinsResultLoggingView } from '@federation/client/1_0/logging/SendCoinsResultLogging.view'
import { EncryptedTransferArgs } from 'core'
import { randombytes_random } from 'sodium-native'
diff --git a/core/src/index.ts b/core/src/index.ts
index 28aae758a..3aa4a63d8 100644
--- a/core/src/index.ts
+++ b/core/src/index.ts
@@ -1,3 +1,17 @@
-export * from './validation/user'
+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'
+export * from './federation/client/1_0/model/SendCoinsResult'
+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 * from './federation/client/SendCoinsClientFactory'
+export * from './federation/enum/apiVersionType'
+export * from './graphql/enum/TransactionTypeId'
export * from './graphql/logic/interpretEncryptedTransferArgs'
+export * from './graphql/logic/processXComSendCoins'
export * from './graphql/model/EncryptedTransferArgs'
+export * from './util/utilities'
+export * from './validation/user'
+
diff --git a/backend/src/util/utilities.test.ts b/core/src/util/utilities.test.ts
similarity index 100%
rename from backend/src/util/utilities.test.ts
rename to core/src/util/utilities.test.ts
diff --git a/backend/src/util/utilities.ts b/core/src/util/utilities.ts
similarity index 100%
rename from backend/src/util/utilities.ts
rename to core/src/util/utilities.ts
diff --git a/core/tsconfig.json b/core/tsconfig.json
index 75b686340..660381127 100644
--- a/core/tsconfig.json
+++ b/core/tsconfig.json
@@ -44,8 +44,15 @@
/* Module Resolution Options */
// "moduleResolution": "node", /* Specify module resolution strategy: 'node' (Node.js) or 'classic' (TypeScript pre-1.6). */
- // "baseUrl": ".", /* Base directory to resolve non-absolute module names. */
- // "paths": {}, /* A series of entries which re-map imports to lookup locations relative to the 'baseUrl'. */
+ "baseUrl": ".", /* Base directory to resolve non-absolute module names. */
+ "paths": { /* A series of entries which re-map imports to lookup locations relative to the 'baseUrl'. */
+ "@/*": ["src/*"],
+ "@config/*": ["src/config/*"],
+ "@federation/*": ["src/federation/*"],
+ "@graphql/*": ["src/graphql/*"],
+ "@util/*": ["src/util/*"],
+ "@validation/*": ["src/validation/*"],
+ },
// "rootDirs": [".", "../database"], /* List of root folders whose combined content represents the structure of the project at runtime. */
// "typeRoots": [], /* List of folders to include type definitions from. */
// "types": ["bun-types"], /* Type declaration files to be included in compilation. */
diff --git a/federation/src/client/AuthenticationClientFactory.ts b/federation/src/client/AuthenticationClientFactory.ts
index 29e55279d..94a74581a 100644
--- a/federation/src/client/AuthenticationClientFactory.ts
+++ b/federation/src/client/AuthenticationClientFactory.ts
@@ -3,7 +3,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 './enum/ApiVersionType'
+import { ApiVersionType } from 'core'
type AuthenticationClient = V1_0_AuthenticationClient | V1_1_AuthenticationClient
diff --git a/federation/src/client/enum/ApiVersionType.ts b/federation/src/client/enum/ApiVersionType.ts
deleted file mode 100644
index 60da9de57..000000000
--- a/federation/src/client/enum/ApiVersionType.ts
+++ /dev/null
@@ -1,4 +0,0 @@
-export enum ApiVersionType {
- V1_0 = '1_0',
- V1_1 = '1_1',
-}
diff --git a/federation/src/graphql/api/1_0/resolver/DisbursementResolver.ts b/federation/src/graphql/api/1_0/resolver/DisbursementResolver.ts
new file mode 100644
index 000000000..629da9e54
--- /dev/null
+++ b/federation/src/graphql/api/1_0/resolver/DisbursementResolver.ts
@@ -0,0 +1,33 @@
+import { getLogger } from "log4js"
+import { Arg, Mutation, Resolver } from "type-graphql"
+
+import { LOG4JS_BASE_CATEGORY_NAME } from "@/config/const"
+import { interpretEncryptedTransferArgs } from "core"
+import { EncryptedTransferArgs } from "core"
+import { DisburseJwtPayloadType } from "shared"
+
+const createLogger = (method: string) => getLogger(`${LOG4JS_BASE_CATEGORY_NAME}.graphql.api.1_0.resolver.DisbursementResolver.${method}`)
+
+@Resolver()
+export class DisbursementResolver {
+ @Mutation(() => String)
+ async processDisburseJwtOnSenderCommunity(
+ @Arg('data')
+ args: EncryptedTransferArgs,
+ ): Promise {
+ const methodLogger = createLogger(`processDisburseJwtOnSenderCommunity`)
+ methodLogger.addContext('handshakeID', args.handshakeID)
+ if(methodLogger.isDebugEnabled()) {
+ methodLogger.debug(`processDisburseJwtOnSenderCommunity() via apiVersion=1_0 ...`, args)
+ }
+ const authArgs = await interpretEncryptedTransferArgs(args) as DisburseJwtPayloadType
+ if (!authArgs) {
+ const errmsg = `invalid disbursement payload of requesting community with publicKey` + args.publicKey
+ methodLogger.error(errmsg)
+ throw new Error(errmsg)
+ }
+ if(methodLogger.isDebugEnabled()) {
+ methodLogger.debug(`processDisburseJwtOnSenderCommunity() via apiVersion=1_0 ...`, authArgs)
+ }
+ }
+}
\ No newline at end of file
From 0c6d8b4ba18aa3cdbaa139931e6712956253f3f2 Mon Sep 17 00:00:00 2001
From: clauspeterhuebner
Date: Wed, 20 Aug 2025 19:01:56 +0200
Subject: [PATCH 03/48] save current work
---
.../client/1_0/AuthenticationClient.ts | 4 +-
.../client/1_0/DisbursementClient.ts | 3 +-
.../federation/client/1_0/FederationClient.ts | 2 +-
backend/src/graphql/model/Transaction.ts | 3 +-
.../src/graphql/resolver/BalanceResolver.ts | 4 +-
.../graphql/resolver/ContributionResolver.ts | 4 +-
.../resolver/TransactionLinkResolver.test.ts | 2 +-
.../resolver/TransactionLinkResolver.ts | 8 +-
.../resolver/TransactionResolver.test.ts | 8 +-
.../graphql/resolver/TransactionResolver.ts | 6 +-
backend/src/util/validate.ts | 4 +-
.../federation/client/1_0/SendCoinsClient.ts | 2 +-
.../1_0/logging/SendCoinsArgsLogging.view.ts | 2 +-
.../logging/SendCoinsResultLogging.view.ts | 2 +-
.../client/1_0/query/voteForSendCoins.ts | 11 +-
.../federation/client/1_1/SendCoinsClient.ts | 2 +-
.../src/graphql}/logging/DecayLogging.view.ts | 2 +-
.../src/graphql/logic/processXComSendCoins.ts | 235 +++++++++++++++++-
.../logic}/settlePendingSenderTransaction.ts | 28 ++-
{backend => core}/src/graphql/model/Decay.ts | 0
core/src/index.ts | 5 +
.../src/util/calculateSenderBalance.ts | 4 +-
database/package.json | 1 +
database/src/index.ts | 1 +
database/src/queries/index.ts | 1 +
.../src/queries/transactions.ts | 0
.../src/util/TRANSACTIONS_LOCK.ts | 0
.../src/util/TRANSACTION_LINK_LOCK.ts | 0
database/src/util/index.ts | 2 +
.../src/client/1_0/AuthenticationClient.ts | 2 +-
30 files changed, 289 insertions(+), 59 deletions(-)
rename {backend/src => core/src/graphql}/logging/DecayLogging.view.ts (92%)
rename {backend/src/graphql/resolver/util => core/src/graphql/logic}/settlePendingSenderTransaction.ts (85%)
rename {backend => core}/src/graphql/model/Decay.ts (100%)
rename {backend => core}/src/util/calculateSenderBalance.ts (83%)
rename backend/src/graphql/resolver/util/getLastTransaction.ts => database/src/queries/transactions.ts (100%)
rename {backend => database}/src/util/TRANSACTIONS_LOCK.ts (100%)
rename {backend => database}/src/util/TRANSACTION_LINK_LOCK.ts (100%)
create mode 100644 database/src/util/index.ts
diff --git a/backend/src/federation/client/1_0/AuthenticationClient.ts b/backend/src/federation/client/1_0/AuthenticationClient.ts
index b504c0030..5d897093e 100644
--- a/backend/src/federation/client/1_0/AuthenticationClient.ts
+++ b/backend/src/federation/client/1_0/AuthenticationClient.ts
@@ -1,11 +1,11 @@
import { FederatedCommunity as DbFederatedCommunity } from 'database'
import { GraphQLClient } from 'graphql-request'
-import { ensureUrlEndsWithSlash } from '@/util/utilities'
+import { ensureUrlEndsWithSlash } from 'core'
import { LOG4JS_BASE_CATEGORY_NAME } from '@/config/const'
+import { EncryptedTransferArgs } from 'core'
import { getLogger } from 'log4js'
-import { EncryptedTransferArgs } from 'core/src/graphql/model/EncryptedTransferArgs'
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 bf466feef..abaf1818b 100644
--- a/backend/src/federation/client/1_0/DisbursementClient.ts
+++ b/backend/src/federation/client/1_0/DisbursementClient.ts
@@ -1,8 +1,7 @@
import { FederatedCommunity as DbFederatedCommunity } from 'database'
import { GraphQLClient } from 'graphql-request'
-import { LogError } from '@/server/LogError'
-import { ensureUrlEndsWithSlash } from 'core/src/util/utilities'
+import { ensureUrlEndsWithSlash } from 'core'
import { getLogger } from 'log4js'
import { LOG4JS_BASE_CATEGORY_NAME } from '@/config/const'
diff --git a/backend/src/federation/client/1_0/FederationClient.ts b/backend/src/federation/client/1_0/FederationClient.ts
index 525765803..c437ad085 100644
--- a/backend/src/federation/client/1_0/FederationClient.ts
+++ b/backend/src/federation/client/1_0/FederationClient.ts
@@ -4,7 +4,7 @@ import { GraphQLClient } from 'graphql-request'
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/src/util/utilities'
+import { ensureUrlEndsWithSlash } from 'core'
import { getLogger } from 'log4js'
import { PublicCommunityInfoLoggingView } from './logging/PublicCommunityInfoLogging.view'
diff --git a/backend/src/graphql/model/Transaction.ts b/backend/src/graphql/model/Transaction.ts
index ee7250271..0560cef54 100644
--- a/backend/src/graphql/model/Transaction.ts
+++ b/backend/src/graphql/model/Transaction.ts
@@ -2,9 +2,8 @@ import { Transaction as dbTransaction } from 'database'
import { Decimal } from 'decimal.js-light'
import { Field, Int, ObjectType } from 'type-graphql'
-import { TransactionTypeId } from 'core/src/graphql/enum/TransactionTypeId'
+import { Decay, TransactionTypeId } from 'core'
-import { Decay } from './Decay'
import { User } from './User'
@ObjectType()
diff --git a/backend/src/graphql/resolver/BalanceResolver.ts b/backend/src/graphql/resolver/BalanceResolver.ts
index f7388c027..d49c73c39 100644
--- a/backend/src/graphql/resolver/BalanceResolver.ts
+++ b/backend/src/graphql/resolver/BalanceResolver.ts
@@ -7,14 +7,14 @@ import { Balance } from '@model/Balance'
import { RIGHTS } from '@/auth/RIGHTS'
import { BalanceLoggingView } from '@/logging/BalanceLogging.view'
-import { DecayLoggingView } from '@/logging/DecayLogging.view'
+import { DecayLoggingView } from 'core/src/graphql/logging/DecayLogging.view'
import { Context, getUser } from '@/server/context'
import { calculateDecay } from 'shared'
import { getLogger } from 'log4js'
import { LOG4JS_BASE_CATEGORY_NAME } from '@/config/const'
import { GdtResolver } from './GdtResolver'
-import { getLastTransaction } from './util/getLastTransaction'
+import { getLastTransaction } from 'database'
import { transactionLinkSummary } from './util/transactionLinkSummary'
@Resolver()
diff --git a/backend/src/graphql/resolver/ContributionResolver.ts b/backend/src/graphql/resolver/ContributionResolver.ts
index 6e2a302ba..263c5c4aa 100644
--- a/backend/src/graphql/resolver/ContributionResolver.ts
+++ b/backend/src/graphql/resolver/ContributionResolver.ts
@@ -42,7 +42,7 @@ import {
import { UpdateUnconfirmedContributionContext } from '@/interactions/updateUnconfirmedContribution/UpdateUnconfirmedContribution.context'
import { LogError } from '@/server/LogError'
import { Context, getClientTimezoneOffset, getUser } from '@/server/context'
-import { TRANSACTIONS_LOCK } from '@/util/TRANSACTIONS_LOCK'
+import { TRANSACTIONS_LOCK } from 'database'
import { fullName } from 'core'
import { calculateDecay, Decay } from 'shared'
@@ -58,7 +58,7 @@ import {
import { getOpenCreations, getUserCreation, validateContribution } from './util/creations'
import { extractGraphQLFields } from './util/extractGraphQLFields'
import { findContributions } from './util/findContributions'
-import { getLastTransaction } from './util/getLastTransaction'
+import { getLastTransaction } from 'database'
import { sendTransactionsToDltConnector } from './util/sendTransactionsToDltConnector'
const db = AppDatabase.getInstance()
diff --git a/backend/src/graphql/resolver/TransactionLinkResolver.test.ts b/backend/src/graphql/resolver/TransactionLinkResolver.test.ts
index 7862f71f0..658d74186 100644
--- a/backend/src/graphql/resolver/TransactionLinkResolver.test.ts
+++ b/backend/src/graphql/resolver/TransactionLinkResolver.test.ts
@@ -32,7 +32,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 { TRANSACTIONS_LOCK } from '@/util/TRANSACTIONS_LOCK'
+import { TRANSACTIONS_LOCK } from 'database'
import { LOG4JS_BASE_CATEGORY_NAME } from '@/config/const'
import { getLogger } from 'config-schema/test/testSetup'
diff --git a/backend/src/graphql/resolver/TransactionLinkResolver.ts b/backend/src/graphql/resolver/TransactionLinkResolver.ts
index 546d11124..cf601a300 100644
--- a/backend/src/graphql/resolver/TransactionLinkResolver.ts
+++ b/backend/src/graphql/resolver/TransactionLinkResolver.ts
@@ -7,12 +7,11 @@ import { ContributionCycleType } from '@enum/ContributionCycleType'
import { ContributionStatus } from '@enum/ContributionStatus'
import { ContributionType } from '@enum/ContributionType'
import { ContributionLink } from '@model/ContributionLink'
-import { Decay } from '@model/Decay'
import { RedeemJwtLink } from '@model/RedeemJwtLink'
import { TransactionLink, TransactionLinkResult } from '@model/TransactionLink'
import { User } from '@model/User'
import { QueryLinkResult } from '@union/QueryLinkResult'
-import { TransactionTypeId } from 'core'
+import { Decay, TransactionTypeId } from 'core'
import {
AppDatabase, Community as DbCommunity, Contribution as DbContribution,
ContributionLink as DbContributionLink, FederatedCommunity as DbFederatedCommunity, Transaction as DbTransaction,
@@ -32,16 +31,16 @@ import {
} from '@/event/Events'
import { LogError } from '@/server/LogError'
import { Context, getClientTimezoneOffset, getUser } from '@/server/context'
-import { TRANSACTIONS_LOCK } from '@/util/TRANSACTIONS_LOCK'
-import { TRANSACTION_LINK_LOCK } from '@/util/TRANSACTION_LINK_LOCK'
import { calculateBalance } from '@/util/validate'
import { fullName } from 'core'
+import { TRANSACTION_LINK_LOCK, TRANSACTIONS_LOCK } from 'database'
import { calculateDecay, 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 { executeTransaction } from './TransactionResolver'
@@ -50,7 +49,6 @@ import {
getCommunityByUuid,
} from './util/communities'
import { getUserCreation, validateContribution } from './util/creations'
-import { getLastTransaction } from './util/getLastTransaction'
import { sendTransactionsToDltConnector } from './util/sendTransactionsToDltConnector'
import { transactionLinkList } from './util/transactionLinkList'
diff --git a/backend/src/graphql/resolver/TransactionResolver.test.ts b/backend/src/graphql/resolver/TransactionResolver.test.ts
index e39fcefc4..e844ed0a5 100644
--- a/backend/src/graphql/resolver/TransactionResolver.test.ts
+++ b/backend/src/graphql/resolver/TransactionResolver.test.ts
@@ -13,12 +13,12 @@ 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'
-import { SendCoinsClient } from 'core/src/federation/client/1_0/SendCoinsClient'
-import { SendCoinsArgs } from 'core/src/federation/client/1_0/model/SendCoinsArgs'
-import { SendCoinsResult } from 'core/src/federation/client/1_0/model/SendCoinsResult'
+// import { V1_0_SendCoinsClient } from 'core'
+// import { SendCoinsArgs } from 'core'
+// import { SendCoinsResult } from 'core'
import { userFactory } from '@/seeds/factory/user'
import {
confirmContribution,
diff --git a/backend/src/graphql/resolver/TransactionResolver.ts b/backend/src/graphql/resolver/TransactionResolver.ts
index 5ceef0836..23e9f415f 100644
--- a/backend/src/graphql/resolver/TransactionResolver.ts
+++ b/backend/src/graphql/resolver/TransactionResolver.ts
@@ -17,7 +17,7 @@ import { Order } from '@enum/Order'
import { Transaction } from '@model/Transaction'
import { TransactionList } from '@model/TransactionList'
import { User } from '@model/User'
-import { TransactionTypeId } from 'core/src/graphql/enum/TransactionTypeId'
+import { TransactionTypeId } from 'core'
import { SendCoinsResponseJwtPayloadType } from 'shared'
import { RIGHTS } from '@/auth/RIGHTS'
@@ -29,7 +29,7 @@ import {
import { EVENT_TRANSACTION_RECEIVE, EVENT_TRANSACTION_SEND } from '@/event/Events'
import { LogError } from '@/server/LogError'
import { Context, getUser } from '@/server/context'
-import { TRANSACTIONS_LOCK } from '@/util/TRANSACTIONS_LOCK'
+import { TRANSACTIONS_LOCK } from 'database'
import { communityUser } from '@/util/communityUser'
import { calculateBalance } from '@/util/validate'
import { virtualDecayTransaction, virtualLinkTransaction } from '@/util/virtualTransactions'
@@ -44,7 +44,7 @@ import { getLogger, Logger } from 'log4js'
import { BalanceResolver } from './BalanceResolver'
import { GdtResolver } from './GdtResolver'
import { getCommunityByIdentifier, getCommunityName, isHomeCommunity } from './util/communities'
-import { getLastTransaction } from './util/getLastTransaction'
+import { getLastTransaction } from 'database'
import { getTransactionList } from './util/getTransactionList'
import { sendTransactionsToDltConnector } from './util/sendTransactionsToDltConnector'
import { storeForeignUser } from './util/storeForeignUser'
diff --git a/backend/src/util/validate.ts b/backend/src/util/validate.ts
index 1dd8a4529..1190e32aa 100644
--- a/backend/src/util/validate.ts
+++ b/backend/src/util/validate.ts
@@ -2,9 +2,9 @@ import { TransactionLink as dbTransactionLink } from 'database'
import { Decimal } from 'decimal.js-light'
import { validate, version } from 'uuid'
-import { Decay } from '@model/Decay'
+import { Decay } from 'core'
-import { getLastTransaction } from '@/graphql/resolver/util/getLastTransaction'
+import { getLastTransaction } from 'database'
import { transactionLinkSummary } from '@/graphql/resolver/util/transactionLinkSummary'
import { calculateDecay } from 'shared'
diff --git a/core/src/federation/client/1_0/SendCoinsClient.ts b/core/src/federation/client/1_0/SendCoinsClient.ts
index f4b6d49d8..bb8d2c858 100644
--- a/core/src/federation/client/1_0/SendCoinsClient.ts
+++ b/core/src/federation/client/1_0/SendCoinsClient.ts
@@ -9,7 +9,7 @@ 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 'core'
+import { EncryptedTransferArgs } from '@graphql/model/EncryptedTransferArgs'
const logger = getLogger(`${LOG4JS_BASE_CATEGORY_NAME}.federation.client.1_0.SendCoinsClient`)
diff --git a/core/src/federation/client/1_0/logging/SendCoinsArgsLogging.view.ts b/core/src/federation/client/1_0/logging/SendCoinsArgsLogging.view.ts
index 4057a2971..1db8c2887 100644
--- a/core/src/federation/client/1_0/logging/SendCoinsArgsLogging.view.ts
+++ b/core/src/federation/client/1_0/logging/SendCoinsArgsLogging.view.ts
@@ -1,6 +1,6 @@
import { AbstractLoggingView } from 'database'
-import { SendCoinsArgs } from 'core/src/federation/client/1_0/model/SendCoinsArgs'
+import { SendCoinsArgs } from '@federation/client/1_0/model/SendCoinsArgs'
export class SendCoinsArgsLoggingView extends AbstractLoggingView {
public constructor(private self: SendCoinsArgs) {
diff --git a/core/src/federation/client/1_0/logging/SendCoinsResultLogging.view.ts b/core/src/federation/client/1_0/logging/SendCoinsResultLogging.view.ts
index a83e211e8..383f4fd37 100644
--- a/core/src/federation/client/1_0/logging/SendCoinsResultLogging.view.ts
+++ b/core/src/federation/client/1_0/logging/SendCoinsResultLogging.view.ts
@@ -1,6 +1,6 @@
import { AbstractLoggingView } from 'database'
-import { SendCoinsResult } from 'core/src/federation/client/1_0/model/SendCoinsResult'
+import { SendCoinsResult } from '@federation/client/1_0/model/SendCoinsResult'
export class SendCoinsResultLoggingView extends AbstractLoggingView {
public constructor(private self: SendCoinsResult) {
diff --git a/core/src/federation/client/1_0/query/voteForSendCoins.ts b/core/src/federation/client/1_0/query/voteForSendCoins.ts
index 6fc9a11ae..9b987657c 100644
--- a/core/src/federation/client/1_0/query/voteForSendCoins.ts
+++ b/core/src/federation/client/1_0/query/voteForSendCoins.ts
@@ -5,13 +5,4 @@ export const voteForSendCoins = gql`
voteForSendCoins(data: $args)
}
`
-/*
- {
- vote
- recipGradidoID
- recipFirstName
- recipLastName
- recipAlias
- }
- }
-*/
+
diff --git a/core/src/federation/client/1_1/SendCoinsClient.ts b/core/src/federation/client/1_1/SendCoinsClient.ts
index b37f08b29..8c7f9caec 100644
--- a/core/src/federation/client/1_1/SendCoinsClient.ts
+++ b/core/src/federation/client/1_1/SendCoinsClient.ts
@@ -1,3 +1,3 @@
-import { SendCoinsClient as V1_0_SendCoinsClient } from 'core/src/federation/client/1_0/SendCoinsClient'
+import { SendCoinsClient as V1_0_SendCoinsClient } from '@federation/client/1_0/SendCoinsClient'
export class SendCoinsClient extends V1_0_SendCoinsClient {}
diff --git a/backend/src/logging/DecayLogging.view.ts b/core/src/graphql/logging/DecayLogging.view.ts
similarity index 92%
rename from backend/src/logging/DecayLogging.view.ts
rename to core/src/graphql/logging/DecayLogging.view.ts
index 538beecd5..f4f20ab6f 100644
--- a/backend/src/logging/DecayLogging.view.ts
+++ b/core/src/graphql/logging/DecayLogging.view.ts
@@ -1,6 +1,6 @@
import { AbstractLoggingView } from 'database'
-import { Decay } from '@/graphql/model/Decay'
+import { Decay } from '@graphql/model/Decay'
import type { Decay as DecayInterface } from 'shared'
export class DecayLoggingView extends AbstractLoggingView {
diff --git a/core/src/graphql/logic/processXComSendCoins.ts b/core/src/graphql/logic/processXComSendCoins.ts
index 3b17939d5..a50fa2f8d 100644
--- a/core/src/graphql/logic/processXComSendCoins.ts
+++ b/core/src/graphql/logic/processXComSendCoins.ts
@@ -18,19 +18,105 @@ import { SendCoinsResult } from '@federation/client/1_0/model/SendCoinsResult'
import { SendCoinsClientFactory } from '@federation/client/SendCoinsClientFactory'
import { encryptAndSign, PendingTransactionState, SendCoinsJwtPayloadType, SendCoinsResponseJwtPayloadType, verifyAndDecrypt } from 'shared'
import { TransactionTypeId } from '@graphql/enum/TransactionTypeId'
-import { LogError } from '@server/LogError'
+// import { LogError } from '@server/LogError'
import { calculateSenderBalance } from '@util/calculateSenderBalance'
import { fullName } from '@util/utilities'
import { getLogger } from 'log4js'
-import { settlePendingSenderTransaction } from '@graphql/resolver/util/settlePendingSenderTransaction'
+import { settlePendingSenderTransaction } from './settlePendingSenderTransaction'
import { SendCoinsArgsLoggingView } from '@federation/client/1_0/logging/SendCoinsArgsLogging.view'
import { SendCoinsResultLoggingView } from '@federation/client/1_0/logging/SendCoinsResultLogging.view'
-import { EncryptedTransferArgs } from 'core'
+import { EncryptedTransferArgs } from '@graphql/model/EncryptedTransferArgs'
import { randombytes_random } from 'sodium-native'
const createLogger = (method: string) => getLogger(`${LOG4JS_BASE_CATEGORY_NAME}.graphql.resolver.util.processXComSendCoins.${method}`)
+/*
+export async function processXComTransaction(
+ receiverCom: DbCommunity,
+ senderCom: DbCommunity,
+ creationDate: Date,
+ amount: Decimal,
+ memo: string,
+ sender: dbUser,
+ recipientIdentifier: string,
+): Promise {
+ const methodLogger = createLogger(`processXComTransaction`)
+ // processing a x-community sendCoins
+ methodLogger.info('X-Com: processing a x-community transaction...')
+ if (!CONFIG.FEDERATION_XCOM_SENDCOINS_ENABLED) {
+ throw new LogError('X-Community sendCoins disabled per configuration!')
+ }
+ const recipCom = await getCommunityByIdentifier(recipientCommunityIdentifier)
+ methodLogger.debug('recipient community: ', recipCom?.id)
+ if (recipCom === null) {
+ throw new LogError(
+ `no recipient community found for identifier: ${recipientCommunityIdentifier}`,
+ )
+ }
+ if (recipCom !== null && recipCom.authenticatedAt === null) {
+ throw new LogError('recipient community is connected, but still not authenticated yet!')
+ }
+ let pendingResult: SendCoinsResponseJwtPayloadType | null = null
+ let committingResult: SendCoinsResult
+ const creationDate = new Date()
+ try {
+ pendingResult = await processXComPendingSendCoins(
+ recipCom,
+ homeCom,
+ creationDate,
+ amount,
+ memo,
+ senderUser,
+ recipientIdentifier,
+ )
+ methodLogger.debug('processXComPendingSendCoins result: ', pendingResult)
+ if (pendingResult && pendingResult.vote && pendingResult.recipGradidoID) {
+ methodLogger.debug('vor processXComCommittingSendCoins... ')
+ committingResult = await processXComCommittingSendCoins(
+ recipCom,
+ homeCom,
+ creationDate,
+ amount,
+ memo,
+ senderUser,
+ pendingResult,
+ )
+ methodLogger.debug('processXComCommittingSendCoins result: ', committingResult)
+ if (!committingResult.vote) {
+ methodLogger.fatal('FATAL ERROR: on processXComCommittingSendCoins for', committingResult)
+ throw new LogError(
+ 'FATAL ERROR: on processXComCommittingSendCoins with ',
+ recipientCommunityIdentifier,
+ recipientIdentifier,
+ amount.toString(),
+ memo,
+ )
+ }
+ // after successful x-com-tx store the recipient as foreign user
+ methodLogger.debug('store recipient as foreign user...')
+ if (await storeForeignUser(recipCom, committingResult)) {
+ methodLogger.info(
+ 'X-Com: new foreign user inserted successfully...',
+ recipCom.communityUuid,
+ committingResult.recipGradidoID,
+ )
+ }
+ }
+ } catch (err) {
+ const errmsg = `ERROR: on processXComCommittingSendCoins with ` +
+ recipientCommunityIdentifier +
+ recipientIdentifier +
+ amount.toString() +
+ memo +
+ err
+ methodLogger.error(errmsg)
+ throw new Error(errmsg)
+ }
+ return true
+}
+*/
+/*
export async function processXComPendingSendCoins(
receiverCom: DbCommunity,
senderCom: DbCommunity,
@@ -82,6 +168,149 @@ export async function processXComPendingSendCoins(
})
const client = SendCoinsClientFactory.getInstance(receiverFCom)
+ if (client instanceof V1_0_SendCoinsClient) {
+ const payload = new SendCoinsJwtPayloadType(handshakeID,
+ receiverCom.communityUuid!,
+ recipientIdentifier,
+ creationDate.toISOString(),
+ amount,
+ memo,
+ senderCom.communityUuid!,
+ sender.gradidoID,
+ fullName(sender.firstName, sender.lastName),
+ sender.alias
+ )
+ if(methodLogger.isDebugEnabled()) {
+ methodLogger.debug(`ready for voteForSendCoins with payload=${payload}`)
+ }
+ const jws = await encryptAndSign(payload, senderCom.privateJwtKey!, receiverCom.publicJwtKey!)
+ if(methodLogger.isDebugEnabled()) {
+ methodLogger.debug('jws', jws)
+ }
+ // prepare the args for the client invocation
+ const args = new EncryptedTransferArgs()
+ args.publicKey = senderCom.publicKey.toString('hex')
+ args.jwt = jws
+ args.handshakeID = handshakeID
+ if(methodLogger.isDebugEnabled()) {
+ methodLogger.debug('before client.voteForSendCoins() args:', args)
+ }
+
+ const responseJwt = await client.voteForSendCoins(args)
+ 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()) {
+ methodLogger.debug(`calculated voteResult = ${JSON.stringify(voteResult, null, 2)}`)
+ }
+ if (voteResult && voteResult.vote && voteResult.recipGradidoID) {
+ methodLogger.debug('vor processXComCommittingSendCoins... ')
+ const committingResult = await processXComCommittingSendCoins(
+ receiverCom,
+ senderCom,
+ creationDate,
+ amount,
+ memo,
+ sender,
+ voteResult,
+ )
+ methodLogger.debug('processXComCommittingSendCoins result: ', committingResult)
+ if (!committingResult.vote) {
+ methodLogger.fatal('FATAL ERROR: on processXComCommittingSendCoins for', committingResult)
+ throw new LogError(
+ 'FATAL ERROR: on processXComCommittingSendCoins with ',
+ recipientCommunityIdentifier,
+ recipientIdentifier,
+ amount.toString(),
+ memo,
+ )
+ }
+ // after successful x-com-tx store the recipient as foreign user
+ methodLogger.debug('store recipient as foreign user...')
+ if (await storeForeignUser(receiverCom, committingResult)) {
+ methodLogger.info(
+ 'X-Com: new foreign user inserted successfully...',
+ receiverCom.communityUuid,
+ committingResult.recipGradidoID,
+ )
+ }
+ }
+ }
+ } else {
+ const errmsg = `Client is not instance of V1_0_SendCoinsClient`
+ methodLogger.error(errmsg)
+ throw new LogError(errmsg)
+ }
+ } catch (err) {
+ const errmsg = `ERROR: on processXComCommittingSendCoins with ` +
+ recipientCommunityIdentifier +
+ recipientIdentifier +
+ amount.toString() +
+ memo +
+ err
+ throw new LogError(errmsg)
+ }
+}
+ memo,
+ err,
+ )
+ }
+ }
+}
+*/
+export async function processXComPendingSendCoins(
+ receiverCom: DbCommunity,
+ senderCom: DbCommunity,
+ creationDate: Date,
+ amount: Decimal,
+ memo: string,
+ sender: dbUser,
+ recipientIdentifier: string,
+): Promise {
+ let voteResult: SendCoinsResponseJwtPayloadType
+ 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
+ }
+ )
+ }
+ 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)
+ }
+ const handshakeID = randombytes_random().toString()
+ methodLogger.addContext('handshakeID', handshakeID)
+ // first calculate the sender balance and check if the transaction is allowed
+ const senderBalance = await calculateSenderBalance(sender.id, amount.mul(-1), creationDate)
+ if (!senderBalance) {
+ const errmsg = `User has not enough GDD or amount is < 0`
+ methodLogger.error(errmsg)
+ throw new Error(errmsg)
+ }
+ if(methodLogger.isDebugEnabled()) {
+ methodLogger.debug(`calculated senderBalance = ${JSON.stringify(senderBalance, null, 2)}`)
+ }
+
+ const receiverFCom = await DbFederatedCommunity.findOneOrFail({
+ where: {
+ publicKey: Buffer.from(receiverCom.publicKey),
+ apiVersion: CONFIG.FEDERATION_BACKEND_SEND_ON_API,
+ },
+ })
+ const client = SendCoinsClientFactory.getInstance(receiverFCom)
+
if (client instanceof V1_0_SendCoinsClient) {
const payload = new SendCoinsJwtPayloadType(handshakeID,
receiverCom.communityUuid!,
diff --git a/backend/src/graphql/resolver/util/settlePendingSenderTransaction.ts b/core/src/graphql/logic/settlePendingSenderTransaction.ts
similarity index 85%
rename from backend/src/graphql/resolver/util/settlePendingSenderTransaction.ts
rename to core/src/graphql/logic/settlePendingSenderTransaction.ts
index c528b0ca7..8abd511c1 100644
--- a/backend/src/graphql/resolver/util/settlePendingSenderTransaction.ts
+++ b/core/src/graphql/logic/settlePendingSenderTransaction.ts
@@ -10,17 +10,16 @@ import {
} from 'database'
import { Decimal } from 'decimal.js-light'
-import { PendingTransactionState } from 'shared'
import { LOG4JS_BASE_CATEGORY_NAME } from '@/config/const'
-import { LogError } from '@/server/LogError'
-import { TRANSACTIONS_LOCK } from '@/util/TRANSACTIONS_LOCK'
-import { calculateSenderBalance } from '@/util/calculateSenderBalance'
+import { PendingTransactionState } from 'shared'
+// import { LogError } from '@/server/LogError'
+import { calculateSenderBalance } from 'core'
+import { TRANSACTIONS_LOCK, getLastTransaction } from 'database'
import { getLogger } from 'log4js'
-import { getLastTransaction } from './getLastTransaction'
const db = AppDatabase.getInstance()
const logger = getLogger(
- `${LOG4JS_BASE_CATEGORY_NAME}.graphql.resolver.util.settlePendingSenderTransaction`,
+ `${LOG4JS_BASE_CATEGORY_NAME}.graphql.logic.settlePendingSenderTransaction`,
)
export async function settlePendingSenderTransaction(
@@ -53,15 +52,17 @@ export async function settlePendingSenderTransaction(
],
})
if (openSenderPendingTx > 1 || openReceiverPendingTx > 1) {
- throw new LogError('There are more than 1 pending Transactions for Sender and/or Recipient')
+ const errmsg = `There are more than 1 pending Transactions for Sender and/or Recipient`
+ logger.error(errmsg)
+ throw new Error(errmsg)
}
const lastTransaction = await getLastTransaction(senderUser.id)
if (lastTransaction?.id !== pendingTx.previous) {
- throw new LogError(
- `X-Com: missmatching transaction order! lastTransationId=${lastTransaction?.id} != pendingTx.previous=${pendingTx.previous}`,
- )
+ const errmsg = `X-Com: missmatching transaction order! lastTransationId=${lastTransaction?.id} != pendingTx.previous=${pendingTx.previous}`
+ logger.error(errmsg)
+ throw new Error(errmsg)
}
// transfer the pendingTx to the transactions table
@@ -82,7 +83,9 @@ export async function settlePendingSenderTransaction(
pendingTx.balanceDate,
)
if (!sendBalance) {
- throw new LogError(`Sender has not enough GDD or amount is < 0', sendBalance`)
+ const errmsg = 'Sender has not enough GDD or amount is < 0'
+ logger.error(errmsg)
+ throw new Error(errmsg)
}
transactionSend.balance = sendBalance?.balance ?? new Decimal(0)
transactionSend.balanceDate = pendingTx.balanceDate
@@ -114,7 +117,8 @@ export async function settlePendingSenderTransaction(
// void sendTransactionsToDltConnector()
} catch (e) {
await queryRunner.rollbackTransaction()
- throw new LogError('X-Com: send Transaction was not successful', e)
+ logger.error('X-Com: send Transaction was not successful', e)
+ throw new Error('X-Com: send Transaction was not successful')
} finally {
await queryRunner.release()
releaseLock()
diff --git a/backend/src/graphql/model/Decay.ts b/core/src/graphql/model/Decay.ts
similarity index 100%
rename from backend/src/graphql/model/Decay.ts
rename to core/src/graphql/model/Decay.ts
diff --git a/core/src/index.ts b/core/src/index.ts
index 3aa4a63d8..9ee34cc19 100644
--- a/core/src/index.ts
+++ b/core/src/index.ts
@@ -1,3 +1,4 @@
+export {SendCoinsClient as V1_0_SendCoinsClient} from './federation/client/1_0/SendCoinsClient'
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'
@@ -6,12 +7,16 @@ 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 * from './federation/client/SendCoinsClientFactory'
export * from './federation/enum/apiVersionType'
export * from './graphql/enum/TransactionTypeId'
+export * from './graphql/logging/DecayLogging.view'
export * from './graphql/logic/interpretEncryptedTransferArgs'
export * from './graphql/logic/processXComSendCoins'
+export * from './graphql/model/Decay'
export * from './graphql/model/EncryptedTransferArgs'
+export * from './util/calculateSenderBalance'
export * from './util/utilities'
export * from './validation/user'
diff --git a/backend/src/util/calculateSenderBalance.ts b/core/src/util/calculateSenderBalance.ts
similarity index 83%
rename from backend/src/util/calculateSenderBalance.ts
rename to core/src/util/calculateSenderBalance.ts
index a01b1f15e..ce7609895 100644
--- a/backend/src/util/calculateSenderBalance.ts
+++ b/core/src/util/calculateSenderBalance.ts
@@ -1,8 +1,8 @@
import { Decimal } from 'decimal.js-light'
-import { Decay } from '@model/Decay'
+import { Decay } from '@graphql/model/Decay'
-import { getLastTransaction } from '@/graphql/resolver/util/getLastTransaction'
+import { getLastTransaction } from 'database'
import { calculateDecay } from 'shared'
diff --git a/database/package.json b/database/package.json
index 6a6240fa1..26aa6b9e1 100644
--- a/database/package.json
+++ b/database/package.json
@@ -41,6 +41,7 @@
"@types/geojson": "^7946.0.13",
"@types/jest": "27.0.2",
"@types/node": "^18.7.14",
+ "await-semaphore": "^0.1.3",
"crypto-random-bigint": "^2.1.1",
"jest": "27.2.4",
"ts-jest": "27.0.5",
diff --git a/database/src/index.ts b/database/src/index.ts
index 3ff4efa17..56dec24ee 100644
--- a/database/src/index.ts
+++ b/database/src/index.ts
@@ -60,4 +60,5 @@ export const entities = [
export { latestDbVersion }
export * from './logging'
export * from './queries'
+export * from './util'
export { AppDatabase } from './AppDatabase'
diff --git a/database/src/queries/index.ts b/database/src/queries/index.ts
index 9acf80871..b8ca12b86 100644
--- a/database/src/queries/index.ts
+++ b/database/src/queries/index.ts
@@ -3,5 +3,6 @@ import { LOG4JS_BASE_CATEGORY_NAME } from '../config/const'
export * from './user'
export * from './communities'
export * from './pendingTransactions'
+export * from './transactions'
export const LOG4JS_QUERIES_CATEGORY_NAME = `${LOG4JS_BASE_CATEGORY_NAME}.queries`
diff --git a/backend/src/graphql/resolver/util/getLastTransaction.ts b/database/src/queries/transactions.ts
similarity index 100%
rename from backend/src/graphql/resolver/util/getLastTransaction.ts
rename to database/src/queries/transactions.ts
diff --git a/backend/src/util/TRANSACTIONS_LOCK.ts b/database/src/util/TRANSACTIONS_LOCK.ts
similarity index 100%
rename from backend/src/util/TRANSACTIONS_LOCK.ts
rename to database/src/util/TRANSACTIONS_LOCK.ts
diff --git a/backend/src/util/TRANSACTION_LINK_LOCK.ts b/database/src/util/TRANSACTION_LINK_LOCK.ts
similarity index 100%
rename from backend/src/util/TRANSACTION_LINK_LOCK.ts
rename to database/src/util/TRANSACTION_LINK_LOCK.ts
diff --git a/database/src/util/index.ts b/database/src/util/index.ts
new file mode 100644
index 000000000..b16b20d19
--- /dev/null
+++ b/database/src/util/index.ts
@@ -0,0 +1,2 @@
+export * from './TRANSACTIONS_LOCK'
+export * from './TRANSACTION_LINK_LOCK'
\ No newline at end of file
diff --git a/federation/src/client/1_0/AuthenticationClient.ts b/federation/src/client/1_0/AuthenticationClient.ts
index 60a205aa7..ac14bcb84 100644
--- a/federation/src/client/1_0/AuthenticationClient.ts
+++ b/federation/src/client/1_0/AuthenticationClient.ts
@@ -3,7 +3,7 @@ import { GraphQLClient } from 'graphql-request'
import { getLogger, Logger } from 'log4js'
import { LOG4JS_BASE_CATEGORY_NAME } from '@/config/const'
-import { EncryptedTransferArgs } from 'core/src/graphql/model/EncryptedTransferArgs'
+import { EncryptedTransferArgs } from 'core'
import { authenticate } from './query/authenticate'
import { openConnectionCallback } from './query/openConnectionCallback'
From d4b2f5494c4961fb684a33ce54832371f02378a9 Mon Sep 17 00:00:00 2001
From: clauspeterhuebner
Date: Wed, 20 Aug 2025 23:58:29 +0200
Subject: [PATCH 04/48] correct imports after shifting code to core modul
---
backend/src/apis/dltConnector/DltConnectorClient.ts | 2 +-
backend/src/apis/gms/GmsClient.ts | 2 +-
backend/src/emails/sendEmailVariants.ts | 2 +-
backend/src/graphql/model/FederatedCommunity.ts | 2 +-
backend/src/graphql/resolver/BalanceResolver.ts | 6 +++---
backend/src/graphql/resolver/UserResolver.ts | 2 +-
.../graphql/resolver/util/authenticateGmsUserPlayground.ts | 2 +-
backend/src/graphql/resolver/util/creations.ts | 2 +-
backend/src/util/virtualTransactions.ts | 2 +-
9 files changed, 11 insertions(+), 11 deletions(-)
diff --git a/backend/src/apis/dltConnector/DltConnectorClient.ts b/backend/src/apis/dltConnector/DltConnectorClient.ts
index bec2990d0..17d6a3a9d 100644
--- a/backend/src/apis/dltConnector/DltConnectorClient.ts
+++ b/backend/src/apis/dltConnector/DltConnectorClient.ts
@@ -3,7 +3,7 @@ import { GraphQLClient, gql } from 'graphql-request'
import { CONFIG } from '@/config'
import { LOG4JS_BASE_CATEGORY_NAME } from '@/config/const'
-import { TransactionTypeId } from 'core/src/graphql/enum/TransactionTypeId'
+import { TransactionTypeId } from 'core'
import { LogError } from '@/server/LogError'
import { getLogger } from 'log4js'
diff --git a/backend/src/apis/gms/GmsClient.ts b/backend/src/apis/gms/GmsClient.ts
index bb4fce2e7..7ed1df89d 100644
--- a/backend/src/apis/gms/GmsClient.ts
+++ b/backend/src/apis/gms/GmsClient.ts
@@ -4,7 +4,7 @@ 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 '@/util/utilities'
+import { ensureUrlEndsWithSlash } from 'core'
import { getLogger } from 'log4js'
import { GmsUser } from './model/GmsUser'
diff --git a/backend/src/emails/sendEmailVariants.ts b/backend/src/emails/sendEmailVariants.ts
index 642f87387..aac726002 100644
--- a/backend/src/emails/sendEmailVariants.ts
+++ b/backend/src/emails/sendEmailVariants.ts
@@ -1,7 +1,7 @@
import { Decimal } from 'decimal.js-light'
import { CONFIG } from '@/config'
-import { decimalSeparatorByLanguage } from '@/util/utilities'
+import { decimalSeparatorByLanguage } from 'core'
import { sendEmailTranslated } from './sendEmailTranslated'
diff --git a/backend/src/graphql/model/FederatedCommunity.ts b/backend/src/graphql/model/FederatedCommunity.ts
index 7029013eb..cee430dba 100644
--- a/backend/src/graphql/model/FederatedCommunity.ts
+++ b/backend/src/graphql/model/FederatedCommunity.ts
@@ -1,7 +1,7 @@
import { FederatedCommunity as DbFederatedCommunity } from 'database'
import { Field, Int, ObjectType } from 'type-graphql'
-import { ensureUrlEndsWithSlash } from '@/util/utilities'
+import { ensureUrlEndsWithSlash } from 'core'
@ObjectType()
export class FederatedCommunity {
diff --git a/backend/src/graphql/resolver/BalanceResolver.ts b/backend/src/graphql/resolver/BalanceResolver.ts
index d49c73c39..0e88382ff 100644
--- a/backend/src/graphql/resolver/BalanceResolver.ts
+++ b/backend/src/graphql/resolver/BalanceResolver.ts
@@ -7,14 +7,14 @@ import { Balance } from '@model/Balance'
import { RIGHTS } from '@/auth/RIGHTS'
import { BalanceLoggingView } from '@/logging/BalanceLogging.view'
-import { DecayLoggingView } from 'core/src/graphql/logging/DecayLogging.view'
import { Context, getUser } from '@/server/context'
+import { DecayLoggingView } from 'core'
import { calculateDecay } from 'shared'
-import { getLogger } from 'log4js'
import { LOG4JS_BASE_CATEGORY_NAME } from '@/config/const'
-import { GdtResolver } from './GdtResolver'
import { getLastTransaction } from 'database'
+import { getLogger } from 'log4js'
+import { GdtResolver } from './GdtResolver'
import { transactionLinkSummary } from './util/transactionLinkSummary'
@Resolver()
diff --git a/backend/src/graphql/resolver/UserResolver.ts b/backend/src/graphql/resolver/UserResolver.ts
index dbfad91ef..045ca7756 100644
--- a/backend/src/graphql/resolver/UserResolver.ts
+++ b/backend/src/graphql/resolver/UserResolver.ts
@@ -85,7 +85,7 @@ import { Context, getClientTimezoneOffset, getUser } from '@/server/context'
import { communityDbUser } from '@/util/communityUser'
import { hasElopageBuys } from '@/util/hasElopageBuys'
import { durationInMinutesFromDates, getTimeDurationObject, printTimeDuration } from '@/util/time'
-import { delay } from '@/util/utilities'
+import { delay } from 'core'
import random from 'random-bigint'
import { randombytes_random } from 'sodium-native'
diff --git a/backend/src/graphql/resolver/util/authenticateGmsUserPlayground.ts b/backend/src/graphql/resolver/util/authenticateGmsUserPlayground.ts
index 74593f1c7..dfa775bde 100644
--- a/backend/src/graphql/resolver/util/authenticateGmsUserPlayground.ts
+++ b/backend/src/graphql/resolver/util/authenticateGmsUserPlayground.ts
@@ -4,7 +4,7 @@ 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 '@/util/utilities'
+import { ensureUrlEndsWithSlash } from 'core'
import { getLogger } from 'log4js'
const logger = getLogger(
diff --git a/backend/src/graphql/resolver/util/creations.ts b/backend/src/graphql/resolver/util/creations.ts
index a0c930579..486e7cc99 100644
--- a/backend/src/graphql/resolver/util/creations.ts
+++ b/backend/src/graphql/resolver/util/creations.ts
@@ -6,7 +6,7 @@ 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 '@/util/utilities'
+import { getFirstDayOfPreviousNMonth } from 'core'
import { AppDatabase } from 'database'
import { getLogger } from 'log4js'
diff --git a/backend/src/util/virtualTransactions.ts b/backend/src/util/virtualTransactions.ts
index 0811eaf1b..a3bbbe042 100644
--- a/backend/src/util/virtualTransactions.ts
+++ b/backend/src/util/virtualTransactions.ts
@@ -2,7 +2,7 @@ import { Transaction as dbTransaction } from 'database'
import { Decimal } from 'decimal.js-light'
import { RemoveOptions, SaveOptions } from 'typeorm'
-import { TransactionTypeId } from 'core/src/graphql/enum/TransactionTypeId'
+import { TransactionTypeId } from 'core'
import { Transaction } from '@model/Transaction'
import { User } from '@model/User'
From f6db4b633d78d983674bd63f956d75d5633a69be Mon Sep 17 00:00:00 2001
From: clauspeterhuebner
Date: Thu, 21 Aug 2025 22:10:16 +0200
Subject: [PATCH 05/48] introduce config_core
---
.../resolver/TransactionLinkResolver.ts | 6 +-
.../graphql/resolver/TransactionResolver.ts | 26 +-
core/package.json | 1 +
core/src/config/index.ts | 27 ++
core/src/config/schema.ts | 29 ++
.../src/graphql/logic/processXComSendCoins.ts | 289 ++++++------------
.../src/graphql/logic}/storeForeignUser.ts | 14 +-
core/src/index.ts | 3 +-
database/src/queries/communities.ts | 8 +-
database/src/queries/index.ts | 1 +
database/src/queries/transactionLinks.ts | 8 +
database/src/queries/user.ts | 9 +
12 files changed, 199 insertions(+), 222 deletions(-)
create mode 100644 core/src/config/index.ts
create mode 100644 core/src/config/schema.ts
rename {backend/src/graphql/resolver/util => core/src/graphql/logic}/storeForeignUser.ts (83%)
create mode 100644 database/src/queries/transactionLinks.ts
diff --git a/backend/src/graphql/resolver/TransactionLinkResolver.ts b/backend/src/graphql/resolver/TransactionLinkResolver.ts
index cf601a300..28375bcab 100644
--- a/backend/src/graphql/resolver/TransactionLinkResolver.ts
+++ b/backend/src/graphql/resolver/TransactionLinkResolver.ts
@@ -17,6 +17,7 @@ import {
ContributionLink as DbContributionLink, FederatedCommunity as DbFederatedCommunity, Transaction as DbTransaction,
TransactionLink as DbTransactionLink,
User as DbUser,
+ findTransactionLinkByCode,
getHomeCommunity
} from 'database'
import { Decimal } from 'decimal.js-light'
@@ -160,10 +161,7 @@ export class TransactionLinkResolver {
let txLinkFound = false
let dbTransactionLink!: DbTransactionLink
try {
- dbTransactionLink = await DbTransactionLink.findOneOrFail({
- where: { code },
- withDeleted: true,
- })
+ dbTransactionLink = await findTransactionLinkByCode(code)
txLinkFound = true
} catch (_err) {
txLinkFound = false
diff --git a/backend/src/graphql/resolver/TransactionResolver.ts b/backend/src/graphql/resolver/TransactionResolver.ts
index 23e9f415f..2ef7b69ff 100644
--- a/backend/src/graphql/resolver/TransactionResolver.ts
+++ b/backend/src/graphql/resolver/TransactionResolver.ts
@@ -17,8 +17,7 @@ import { Order } from '@enum/Order'
import { Transaction } from '@model/Transaction'
import { TransactionList } from '@model/TransactionList'
import { User } from '@model/User'
-import { TransactionTypeId } from 'core'
-import { SendCoinsResponseJwtPayloadType } from 'shared'
+import { processXComCompleteTransaction, TransactionTypeId } from 'core'
import { RIGHTS } from '@/auth/RIGHTS'
import { CONFIG } from '@/config'
@@ -29,25 +28,20 @@ import {
import { EVENT_TRANSACTION_RECEIVE, EVENT_TRANSACTION_SEND } from '@/event/Events'
import { LogError } from '@/server/LogError'
import { Context, getUser } from '@/server/context'
-import { TRANSACTIONS_LOCK } from 'database'
import { communityUser } from '@/util/communityUser'
import { calculateBalance } from '@/util/validate'
import { virtualDecayTransaction, virtualLinkTransaction } from '@/util/virtualTransactions'
-import { fullName, SendCoinsResult } from 'core'
+import { fullName } from 'core'
+import { TRANSACTIONS_LOCK } from 'database'
import { LOG4JS_BASE_CATEGORY_NAME } from '@/config/const'
-import {
- processXComCommittingSendCoins,
- processXComPendingSendCoins,
-} from 'core'
+import { getLastTransaction } from 'database'
import { getLogger, Logger } from 'log4js'
import { BalanceResolver } from './BalanceResolver'
import { GdtResolver } from './GdtResolver'
-import { getCommunityByIdentifier, getCommunityName, isHomeCommunity } from './util/communities'
-import { getLastTransaction } from 'database'
+import { getCommunityName, isHomeCommunity } from './util/communities'
import { getTransactionList } from './util/getTransactionList'
import { sendTransactionsToDltConnector } from './util/sendTransactionsToDltConnector'
-import { storeForeignUser } from './util/storeForeignUser'
import { transactionLinkSummary } from './util/transactionLinkSummary'
const db = AppDatabase.getInstance()
@@ -465,6 +459,15 @@ export class TransactionResolver {
await executeTransaction(amount, memo, senderUser, recipientUser, logger)
logger.info('successful executeTransaction')
} else {
+ await processXComCompleteTransaction(
+ senderUser.communityUuid,
+ senderUser.gradidoID,
+ recipientCommunityIdentifier,
+ recipientIdentifier,
+ amount.valueOf(),
+ memo,
+ )
+ /*
// processing a x-community sendCoins
logger.info('X-Com: processing a x-community transaction...')
if (!CONFIG.FEDERATION_XCOM_SENDCOINS_ENABLED) {
@@ -537,6 +540,7 @@ export class TransactionResolver {
err,
)
}
+ */
}
return true
}
diff --git a/core/package.json b/core/package.json
index 0044d263f..c85b5e504 100644
--- a/core/package.json
+++ b/core/package.json
@@ -27,6 +27,7 @@
"devDependencies": {
"@biomejs/biome": "2.0.0",
"@types/node": "^17.0.21",
+ "decimal.js-light": "^2.5.1",
"jest": "27.2.4",
"type-graphql": "^1.1.1",
"typescript": "^4.9.5"
diff --git a/core/src/config/index.ts b/core/src/config/index.ts
new file mode 100644
index 000000000..31b8cf033
--- /dev/null
+++ b/core/src/config/index.ts
@@ -0,0 +1,27 @@
+// ATTENTION: DO NOT PUT ANY SECRETS IN HERE (or the .env)
+
+import { LogLevel, validate } from 'config-schema'
+import dotenv from 'dotenv'
+
+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:
+ process.env.FEDERATION_XCOM_SENDCOINS_ENABLED === 'true' || false,
+ // default value for community-uuid is equal uuid of stage-3
+ FEDERATION_XCOM_RECEIVER_COMMUNITY_UUID:
+ process.env.FEDERATION_XCOM_RECEIVER_COMMUNITY_UUID ?? '56a55482-909e-46a4-bfa2-cd025e894ebc',
+ FEDERATION_XCOM_MAXREPEAT_REVERTSENDCOINS: parseInt(
+ process.env.FEDERATION_XCOM_MAXREPEAT_REVERTSENDCOINS ?? '3',
+ ),
+}
+
+
+export const CONFIG = {
+ ...federation,
+}
+validate(schema, CONFIG)
diff --git a/core/src/config/schema.ts b/core/src/config/schema.ts
new file mode 100644
index 000000000..dbf6478de
--- /dev/null
+++ b/core/src/config/schema.ts
@@ -0,0 +1,29 @@
+import Joi from 'joi'
+
+export const schema = Joi.object({
+ FEDERATION_BACKEND_SEND_ON_API: Joi.string()
+ .pattern(/^\d+_\d+$/)
+ .default('1_0')
+ .description('API Version of sending requests to another communities, e.g., "1_0"')
+ .required(),
+
+ FEDERATION_XCOM_SENDCOINS_ENABLED: Joi.boolean()
+ .default(false)
+ .description('Enable or disable the federation send coins feature')
+ .optional(),
+
+ FEDERATION_XCOM_RECEIVER_COMMUNITY_UUID: Joi.string()
+ .uuid()
+ .default('56a55482-909e-46a4-bfa2-cd025e894ebc')
+ .description(
+ 'UUID of the receiver community for federation cross-community transactions if the receiver is unknown',
+ )
+ .required(),
+
+ FEDERATION_XCOM_MAXREPEAT_REVERTSENDCOINS: Joi.number()
+ .integer()
+ .min(0)
+ .default(3)
+ .description('Maximum number of retries for reverting send coins transactions')
+ .required(),
+})
diff --git a/core/src/graphql/logic/processXComSendCoins.ts b/core/src/graphql/logic/processXComSendCoins.ts
index a50fa2f8d..6846ed143 100644
--- a/core/src/graphql/logic/processXComSendCoins.ts
+++ b/core/src/graphql/logic/processXComSendCoins.ts
@@ -3,14 +3,19 @@ import {
FederatedCommunity as DbFederatedCommunity,
PendingTransaction as DbPendingTransaction,
User as dbUser,
+ TransactionLink as DbTransactionLink,
PendingTransactionLoggingView,
CommunityLoggingView,
UserLoggingView,
countOpenPendingTransactions,
+ getCommunityByUuid,
+ findUserByIdentifier,
+ findTransactionLinkByCode,
} from 'database'
import { Decimal } from 'decimal.js-light'
import { LOG4JS_BASE_CATEGORY_NAME } from '@config/const'
+import { CONFIG as CONFIG_CORE } from '@/config'
import { SendCoinsClient as V1_0_SendCoinsClient } from '@federation/client/1_0/SendCoinsClient'
import { SendCoinsArgs } from '@federation/client/1_0/model/SendCoinsArgs'
@@ -28,56 +33,93 @@ import { SendCoinsArgsLoggingView } from '@federation/client/1_0/logging/SendCoi
import { SendCoinsResultLoggingView } from '@federation/client/1_0/logging/SendCoinsResultLogging.view'
import { EncryptedTransferArgs } from '@graphql/model/EncryptedTransferArgs'
import { randombytes_random } from 'sodium-native'
+import { storeForeignUser } from './storeForeignUser'
const createLogger = (method: string) => getLogger(`${LOG4JS_BASE_CATEGORY_NAME}.graphql.resolver.util.processXComSendCoins.${method}`)
-/*
-export async function processXComTransaction(
- receiverCom: DbCommunity,
- senderCom: DbCommunity,
- creationDate: Date,
- amount: Decimal,
+
+export async function processXComCompleteTransaction(
+ sendercommunityuuid: string,
+ sendergradidoid: string,
+ recipientcommunityuuid: string,
+ recipientgradidoid: string,
+ amount: string,
memo: string,
- sender: dbUser,
- recipientIdentifier: string,
+ code?: string,
+ creationDate?: Date,
+ recipientfirstname?: string,
+ recipientalias?: string,
): Promise {
- const methodLogger = createLogger(`processXComTransaction`)
+ const methodLogger = createLogger(`processXComCompleteTransaction`)
// processing a x-community sendCoins
- methodLogger.info('X-Com: processing a x-community transaction...')
- if (!CONFIG.FEDERATION_XCOM_SENDCOINS_ENABLED) {
- throw new LogError('X-Community sendCoins disabled per configuration!')
+ methodLogger.info('processing a x-community transaction...')
+ if (!CONFIG_CORE.FEDERATION_XCOM_SENDCOINS_ENABLED) {
+ const errmsg = 'X-Community sendCoins disabled per configuration!'
+ methodLogger.error(errmsg)
+ throw new Error(errmsg)
}
- const recipCom = await getCommunityByIdentifier(recipientCommunityIdentifier)
- methodLogger.debug('recipient community: ', recipCom?.id)
- if (recipCom === null) {
- throw new LogError(
- `no recipient community found for identifier: ${recipientCommunityIdentifier}`,
- )
+ const senderCom = await getCommunityByUuid(sendercommunityuuid)
+ methodLogger.debug('sender community: ', senderCom?.id)
+ if (senderCom === null) {
+ const errmsg = `no sender community found for identifier: ${sendercommunityuuid}`
+ methodLogger.error(errmsg)
+ throw new Error(errmsg)
}
- if (recipCom !== null && recipCom.authenticatedAt === null) {
- throw new LogError('recipient community is connected, but still not authenticated yet!')
+ const senderUser = await findUserByIdentifier(sendergradidoid, sendercommunityuuid)
+ if (senderUser === null) {
+ const errmsg = `no sender user found for identifier: ${sendercommunityuuid}:${sendergradidoid}`
+ methodLogger.error(errmsg)
+ throw new Error(errmsg)
+ }
+ const recipientCom = await getCommunityByUuid(recipientcommunityuuid)
+ methodLogger.debug('recipient community: ', recipientCom?.id)
+ if (recipientCom === null) {
+ const errmsg = `no recipient community found for identifier: ${recipientcommunityuuid}`
+ methodLogger.error(errmsg)
+ throw new Error(errmsg)
+ }
+ if (recipientCom !== null && recipientCom.authenticatedAt === null) {
+ const errmsg = 'recipient community is connected, but still not authenticated yet!'
+ methodLogger.error(errmsg)
+ throw new Error(errmsg)
+ }
+ if(code !== undefined) {
+ try {
+ const dbTransactionLink = await findTransactionLinkByCode(code)
+ if (dbTransactionLink && dbTransactionLink.validUntil < new Date()) {
+ const errmsg = `TransactionLink ${code} is expired!`
+ methodLogger.error(errmsg)
+ throw new Error(errmsg)
+ }
+ } catch (_err) {
+ const errmsg = `TransactionLink ${code} not found any more!`
+ methodLogger.error(errmsg)
+ throw new Error(errmsg)
+ }
+ }
+ if(creationDate === undefined) {
+ creationDate = new Date()
}
let pendingResult: SendCoinsResponseJwtPayloadType | null = null
let committingResult: SendCoinsResult
- const creationDate = new Date()
-
+
try {
pendingResult = await processXComPendingSendCoins(
- recipCom,
- homeCom,
+ recipientCom,
+ senderCom,
creationDate,
- amount,
+ new Decimal(amount),
memo,
senderUser,
- recipientIdentifier,
+ recipientgradidoid,
)
methodLogger.debug('processXComPendingSendCoins result: ', pendingResult)
if (pendingResult && pendingResult.vote && pendingResult.recipGradidoID) {
methodLogger.debug('vor processXComCommittingSendCoins... ')
committingResult = await processXComCommittingSendCoins(
- recipCom,
- homeCom,
+ recipientCom,
+ senderCom,
creationDate,
- amount,
+ new Decimal(amount),
memo,
senderUser,
pendingResult,
@@ -85,28 +127,28 @@ export async function processXComTransaction(
methodLogger.debug('processXComCommittingSendCoins result: ', committingResult)
if (!committingResult.vote) {
methodLogger.fatal('FATAL ERROR: on processXComCommittingSendCoins for', committingResult)
- throw new LogError(
- 'FATAL ERROR: on processXComCommittingSendCoins with ',
- recipientCommunityIdentifier,
- recipientIdentifier,
- amount.toString(),
+ throw new Error(
+ 'FATAL ERROR: on processXComCommittingSendCoins with ' +
+ recipientCom.communityUuid +
+ recipientgradidoid +
+ amount.toString() +
memo,
)
}
// after successful x-com-tx store the recipient as foreign user
methodLogger.debug('store recipient as foreign user...')
- if (await storeForeignUser(recipCom, committingResult)) {
+ if (await storeForeignUser(recipientCom, committingResult)) {
methodLogger.info(
'X-Com: new foreign user inserted successfully...',
- recipCom.communityUuid,
+ recipientCom.communityUuid,
committingResult.recipGradidoID,
)
}
}
} catch (err) {
const errmsg = `ERROR: on processXComCommittingSendCoins with ` +
- recipientCommunityIdentifier +
- recipientIdentifier +
+ recipientcommunityuuid +
+ recipientgradidoid +
amount.toString() +
memo +
err
@@ -115,151 +157,7 @@ export async function processXComTransaction(
}
return true
}
-*/
-/*
-export async function processXComPendingSendCoins(
- receiverCom: DbCommunity,
- senderCom: DbCommunity,
- creationDate: Date,
- amount: Decimal,
- memo: string,
- sender: dbUser,
- recipientIdentifier: string,
-): Promise {
- let voteResult: SendCoinsResponseJwtPayloadType
- 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
- }
- )
- }
- 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 LogError(errmsg)
- }
- const handshakeID = randombytes_random().toString()
- methodLogger.addContext('handshakeID', handshakeID)
- // first calculate the sender balance and check if the transaction is allowed
- const senderBalance = await calculateSenderBalance(sender.id, amount.mul(-1), creationDate)
- if (!senderBalance) {
- const errmsg = `User has not enough GDD or amount is < 0`
- methodLogger.error(errmsg)
- throw new LogError(errmsg)
- }
- if(methodLogger.isDebugEnabled()) {
- methodLogger.debug(`calculated senderBalance = ${JSON.stringify(senderBalance, null, 2)}`)
- }
- const receiverFCom = await DbFederatedCommunity.findOneOrFail({
- where: {
- publicKey: Buffer.from(receiverCom.publicKey),
- apiVersion: CONFIG.FEDERATION_BACKEND_SEND_ON_API,
- },
- })
- const client = SendCoinsClientFactory.getInstance(receiverFCom)
-
- if (client instanceof V1_0_SendCoinsClient) {
- const payload = new SendCoinsJwtPayloadType(handshakeID,
- receiverCom.communityUuid!,
- recipientIdentifier,
- creationDate.toISOString(),
- amount,
- memo,
- senderCom.communityUuid!,
- sender.gradidoID,
- fullName(sender.firstName, sender.lastName),
- sender.alias
- )
- if(methodLogger.isDebugEnabled()) {
- methodLogger.debug(`ready for voteForSendCoins with payload=${payload}`)
- }
- const jws = await encryptAndSign(payload, senderCom.privateJwtKey!, receiverCom.publicJwtKey!)
- if(methodLogger.isDebugEnabled()) {
- methodLogger.debug('jws', jws)
- }
- // prepare the args for the client invocation
- const args = new EncryptedTransferArgs()
- args.publicKey = senderCom.publicKey.toString('hex')
- args.jwt = jws
- args.handshakeID = handshakeID
- if(methodLogger.isDebugEnabled()) {
- methodLogger.debug('before client.voteForSendCoins() args:', args)
- }
-
- const responseJwt = await client.voteForSendCoins(args)
- 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()) {
- methodLogger.debug(`calculated voteResult = ${JSON.stringify(voteResult, null, 2)}`)
- }
- if (voteResult && voteResult.vote && voteResult.recipGradidoID) {
- methodLogger.debug('vor processXComCommittingSendCoins... ')
- const committingResult = await processXComCommittingSendCoins(
- receiverCom,
- senderCom,
- creationDate,
- amount,
- memo,
- sender,
- voteResult,
- )
- methodLogger.debug('processXComCommittingSendCoins result: ', committingResult)
- if (!committingResult.vote) {
- methodLogger.fatal('FATAL ERROR: on processXComCommittingSendCoins for', committingResult)
- throw new LogError(
- 'FATAL ERROR: on processXComCommittingSendCoins with ',
- recipientCommunityIdentifier,
- recipientIdentifier,
- amount.toString(),
- memo,
- )
- }
- // after successful x-com-tx store the recipient as foreign user
- methodLogger.debug('store recipient as foreign user...')
- if (await storeForeignUser(receiverCom, committingResult)) {
- methodLogger.info(
- 'X-Com: new foreign user inserted successfully...',
- receiverCom.communityUuid,
- committingResult.recipGradidoID,
- )
- }
- }
- }
- } else {
- const errmsg = `Client is not instance of V1_0_SendCoinsClient`
- methodLogger.error(errmsg)
- throw new LogError(errmsg)
- }
- } catch (err) {
- const errmsg = `ERROR: on processXComCommittingSendCoins with ` +
- recipientCommunityIdentifier +
- recipientIdentifier +
- amount.toString() +
- memo +
- err
- throw new LogError(errmsg)
- }
-}
- memo,
- err,
- )
- }
- }
-}
-*/
export async function processXComPendingSendCoins(
receiverCom: DbCommunity,
senderCom: DbCommunity,
@@ -306,7 +204,7 @@ export async function processXComPendingSendCoins(
const receiverFCom = await DbFederatedCommunity.findOneOrFail({
where: {
publicKey: Buffer.from(receiverCom.publicKey),
- apiVersion: CONFIG.FEDERATION_BACKEND_SEND_ON_API,
+ apiVersion: CONFIG_CORE.FEDERATION_BACKEND_SEND_ON_API,
},
})
const client = SendCoinsClientFactory.getInstance(receiverFCom)
@@ -401,7 +299,7 @@ export async function processXComPendingSendCoins(
methodLogger.error(errmsg)
throw new Error(errmsg)
}
- } while (CONFIG.FEDERATION_XCOM_MAXREPEAT_REVERTSENDCOINS > revertCount++)
+ } 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)
methodLogger.error(errmsg)
throw new Error(errmsg)
@@ -456,7 +354,7 @@ export async function processXComCommittingSendCoins(
userGradidoID: sender.gradidoID,
userName: fullName(sender.firstName, sender.lastName),
linkedUserCommunityUuid:
- receiverCom.communityUuid ?? CONFIG.FEDERATION_XCOM_RECEIVER_COMMUNITY_UUID,
+ receiverCom.communityUuid ?? CONFIG_CORE.FEDERATION_XCOM_RECEIVER_COMMUNITY_UUID,
linkedUserGradidoID: recipient.recipGradidoID ? recipient.recipGradidoID : undefined,
typeId: TransactionTypeId.SEND,
state: PendingTransactionState.NEW,
@@ -470,7 +368,7 @@ export async function processXComCommittingSendCoins(
const receiverFCom = await DbFederatedCommunity.findOneOrFail({
where: {
publicKey: Buffer.from(receiverCom.publicKey),
- apiVersion: CONFIG.FEDERATION_BACKEND_SEND_ON_API,
+ apiVersion: CONFIG_CORE.FEDERATION_BACKEND_SEND_ON_API,
},
})
const client = SendCoinsClientFactory.getInstance(receiverFCom)
@@ -480,7 +378,7 @@ export async function processXComCommittingSendCoins(
handshakeID,
pendingTx.linkedUserCommunityUuid
? pendingTx.linkedUserCommunityUuid
- : CONFIG.FEDERATION_XCOM_RECEIVER_COMMUNITY_UUID,
+ : CONFIG_CORE.FEDERATION_XCOM_RECEIVER_COMMUNITY_UUID,
pendingTx.linkedUserGradidoID!,
pendingTx.balanceDate.toISOString(),
pendingTx.amount.mul(-1),
@@ -492,7 +390,7 @@ export async function processXComCommittingSendCoins(
)
payload.recipientCommunityUuid = pendingTx.linkedUserCommunityUuid
? pendingTx.linkedUserCommunityUuid
- : CONFIG.FEDERATION_XCOM_RECEIVER_COMMUNITY_UUID
+ : CONFIG_CORE.FEDERATION_XCOM_RECEIVER_COMMUNITY_UUID
if (pendingTx.linkedUserGradidoID) {
payload.recipientUserIdentifier = pendingTx.linkedUserGradidoID
}
@@ -533,20 +431,21 @@ export async function processXComCommittingSendCoins(
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 revertSetteledSendCoins of receiver')
+ methodLogger.debug('first try to revertSettledSendCoins of receiver')
do {
if (await client.revertSettledSendCoins(args)) {
methodLogger.debug(
`revertSettledSendCoins()-1_0... successfull after revertCount=${revertCount}`,
)
// treat revertingSettledSendCoins as an error of the whole sendCoins-process
- throw new LogError('Error in settle sender pending transaction: ', err)
+ const errmsg = `Error in settle sender pending transaction: ${JSON.stringify(err, null, 2)}`
+ methodLogger.error(errmsg)
+ throw new Error(errmsg)
}
- } while (CONFIG.FEDERATION_XCOM_MAXREPEAT_REVERTSENDCOINS > revertCount++)
- throw new LogError(
- `Error in reverting receiver pending transaction even after revertCount=${revertCount}`,
- err,
- )
+ } while (CONFIG_CORE.FEDERATION_XCOM_MAXREPEAT_REVERTSENDCOINS > revertCount++)
+ const errmsg = `Error in reverting receiver pending transaction even after revertCount=${revertCount}`
+ methodLogger.error(errmsg)
+ throw new Error(errmsg)
}
}
}
diff --git a/backend/src/graphql/resolver/util/storeForeignUser.ts b/core/src/graphql/logic/storeForeignUser.ts
similarity index 83%
rename from backend/src/graphql/resolver/util/storeForeignUser.ts
rename to core/src/graphql/logic/storeForeignUser.ts
index 8c33c8923..402a9a835 100644
--- a/backend/src/graphql/resolver/util/storeForeignUser.ts
+++ b/core/src/graphql/logic/storeForeignUser.ts
@@ -1,10 +1,10 @@
-import { Community as DbCommunity, User as DbUser } from 'database'
+import { Community as DbCommunity, User as DbUser, findForeignUserByUuids } from 'database'
-import { SendCoinsResult } from 'core/src/federation/client/1_0/model/SendCoinsResult'
+import { SendCoinsResult } from '@federation/client/1_0/model/SendCoinsResult'
import { LOG4JS_BASE_CATEGORY_NAME } from '@/config/const'
import { getLogger } from 'log4js'
-const logger = getLogger(`${LOG4JS_BASE_CATEGORY_NAME}.graphql.resolver.util.storeForeignUser`)
+const logger = getLogger(`${LOG4JS_BASE_CATEGORY_NAME}.graphql.logic.storeForeignUser`)
export async function storeForeignUser(
recipCom: DbCommunity,
@@ -12,13 +12,7 @@ export async function storeForeignUser(
): Promise {
if (recipCom.communityUuid !== null && committingResult.recipGradidoID !== null) {
try {
- const user = await DbUser.findOne({
- where: {
- foreign: true,
- communityUuid: recipCom.communityUuid,
- gradidoID: committingResult.recipGradidoID,
- },
- })
+ const user = await findForeignUserByUuids(recipCom.communityUuid, committingResult.recipGradidoID)
if (!user) {
logger.debug(
'no foreignUser found for:',
diff --git a/core/src/index.ts b/core/src/index.ts
index 9ee34cc19..85042ef0b 100644
--- a/core/src/index.ts
+++ b/core/src/index.ts
@@ -14,9 +14,10 @@ export * from './graphql/enum/TransactionTypeId'
export * from './graphql/logging/DecayLogging.view'
export * from './graphql/logic/interpretEncryptedTransferArgs'
export * from './graphql/logic/processXComSendCoins'
+export * from './graphql/logic/settlePendingSenderTransaction'
+export * from './graphql/logic/storeForeignUser'
export * from './graphql/model/Decay'
export * from './graphql/model/EncryptedTransferArgs'
export * from './util/calculateSenderBalance'
export * from './util/utilities'
export * from './validation/user'
-
diff --git a/database/src/queries/communities.ts b/database/src/queries/communities.ts
index 868db42e8..3afdaf883 100644
--- a/database/src/queries/communities.ts
+++ b/database/src/queries/communities.ts
@@ -8,4 +8,10 @@ export async function getHomeCommunity(): Promise {
return await DbCommunity.findOne({
where: { foreign: false },
})
-}
\ No newline at end of file
+}
+
+export async function getCommunityByUuid(communityUuid: string): Promise {
+ return await DbCommunity.findOne({
+ where: [{ communityUuid }],
+ })
+}
diff --git a/database/src/queries/index.ts b/database/src/queries/index.ts
index b8ca12b86..1fec568bf 100644
--- a/database/src/queries/index.ts
+++ b/database/src/queries/index.ts
@@ -4,5 +4,6 @@ export * from './user'
export * from './communities'
export * from './pendingTransactions'
export * from './transactions'
+export * from './transactionLinks'
export const LOG4JS_QUERIES_CATEGORY_NAME = `${LOG4JS_BASE_CATEGORY_NAME}.queries`
diff --git a/database/src/queries/transactionLinks.ts b/database/src/queries/transactionLinks.ts
new file mode 100644
index 000000000..9a4cda064
--- /dev/null
+++ b/database/src/queries/transactionLinks.ts
@@ -0,0 +1,8 @@
+import { TransactionLink as DbTransactionLink } from "../entity/TransactionLink"
+
+export async function findTransactionLinkByCode(code: string): Promise {
+ return await DbTransactionLink.findOneOrFail({
+ where: { code },
+ withDeleted: true,
+ })
+}
diff --git a/database/src/queries/user.ts b/database/src/queries/user.ts
index b968e9433..c4f0a023c 100644
--- a/database/src/queries/user.ts
+++ b/database/src/queries/user.ts
@@ -60,3 +60,12 @@ export const findUserByIdentifier = async (
getLogger(`${LOG4JS_QUERIES_CATEGORY_NAME}.user.findUserByIdentifier`).warn('Unknown identifier type', identifier)
return null
}
+
+export async function findForeignUserByUuids(
+ communityUuid: string,
+ gradidoID: string,
+): Promise {
+ return DbUser.findOne({
+ where: { foreign: true, communityUuid, gradidoID },
+ })
+}
From a02771b35d9b2f7d5f29a1f4026969b1aa929682 Mon Sep 17 00:00:00 2001
From: clauspeterhuebner
Date: Thu, 21 Aug 2025 22:39:49 +0200
Subject: [PATCH 06/48] add i18n
---
core/package.json | 1 +
1 file changed, 1 insertion(+)
diff --git a/core/package.json b/core/package.json
index c85b5e504..bd7ce462f 100644
--- a/core/package.json
+++ b/core/package.json
@@ -28,6 +28,7 @@
"@biomejs/biome": "2.0.0",
"@types/node": "^17.0.21",
"decimal.js-light": "^2.5.1",
+ "i18n": "^0.15.1",
"jest": "27.2.4",
"type-graphql": "^1.1.1",
"typescript": "^4.9.5"
From 621b41cb05c8f8d5a638116183496e4acd5f3263 Mon Sep 17 00:00:00 2001
From: clauspeterhuebner
Date: Fri, 22 Aug 2025 00:12:24 +0200
Subject: [PATCH 07/48] correct package dependencies
---
bun.lock | 5 +++++
core/package.json | 2 ++
2 files changed, 7 insertions(+)
diff --git a/bun.lock b/bun.lock
index 30a87f9af..d524f7999 100644
--- a/bun.lock
+++ b/bun.lock
@@ -192,6 +192,10 @@
"devDependencies": {
"@biomejs/biome": "2.0.0",
"@types/node": "^17.0.21",
+ "config-schema": "*",
+ "decimal.js-light": "^2.5.1",
+ "graphql-request": "5.0.0",
+ "i18n": "^0.15.1",
"jest": "27.2.4",
"type-graphql": "^1.1.1",
"typescript": "^4.9.5",
@@ -229,6 +233,7 @@
"@types/geojson": "^7946.0.13",
"@types/jest": "27.0.2",
"@types/node": "^18.7.14",
+ "await-semaphore": "^0.1.3",
"crypto-random-bigint": "^2.1.1",
"jest": "27.2.4",
"ts-jest": "27.0.5",
diff --git a/core/package.json b/core/package.json
index bd7ce462f..72687d629 100644
--- a/core/package.json
+++ b/core/package.json
@@ -27,7 +27,9 @@
"devDependencies": {
"@biomejs/biome": "2.0.0",
"@types/node": "^17.0.21",
+ "config-schema": "*",
"decimal.js-light": "^2.5.1",
+ "graphql-request": "5.0.0",
"i18n": "^0.15.1",
"jest": "27.2.4",
"type-graphql": "^1.1.1",
From 21d05193eb7362991b8141518335323c1e802bd0 Mon Sep 17 00:00:00 2001
From: clauspeterhuebner
Date: Fri, 22 Aug 2025 00:20:48 +0200
Subject: [PATCH 08/48] correct dependencies
---
core/package.json | 1 +
1 file changed, 1 insertion(+)
diff --git a/core/package.json b/core/package.json
index 72687d629..8317808e2 100644
--- a/core/package.json
+++ b/core/package.json
@@ -41,6 +41,7 @@
"jose": "^4.14.4",
"log4js": "^6.9.1",
"shared": "*",
+ "sodium-native": "^3.4.1",
"zod": "^3.25.61"
},
"engines": {
From a0b0e58059462859170efb14adabd9e4413dfe36 Mon Sep 17 00:00:00 2001
From: clauspeterhuebner
Date: Fri, 22 Aug 2025 00:37:18 +0200
Subject: [PATCH 09/48] next try for changed dependencies
---
core/package.json | 22 +++++++++----------
.../src/graphql/logic/processXComSendCoins.ts | 21 ++++++++----------
2 files changed, 20 insertions(+), 23 deletions(-)
diff --git a/core/package.json b/core/package.json
index 8317808e2..092b4ff00 100644
--- a/core/package.json
+++ b/core/package.json
@@ -24,26 +24,26 @@
"lint:fix": "biome check --error-on-warnings . --write",
"clear": "rm -rf node_modules && rm -rf build && rm -rf .turbo"
},
- "devDependencies": {
- "@biomejs/biome": "2.0.0",
- "@types/node": "^17.0.21",
- "config-schema": "*",
- "decimal.js-light": "^2.5.1",
- "graphql-request": "5.0.0",
- "i18n": "^0.15.1",
- "jest": "27.2.4",
- "type-graphql": "^1.1.1",
- "typescript": "^4.9.5"
- },
"dependencies": {
"database": "*",
"esbuild": "^0.25.2",
+ "i18n": "^0.15.1",
"jose": "^4.14.4",
"log4js": "^6.9.1",
"shared": "*",
"sodium-native": "^3.4.1",
"zod": "^3.25.61"
},
+ "devDependencies": {
+ "@biomejs/biome": "2.0.0",
+ "@types/node": "^17.0.21",
+ "config-schema": "*",
+ "decimal.js-light": "^2.5.1",
+ "graphql-request": "5.0.0",
+ "jest": "27.2.4",
+ "type-graphql": "^1.1.1",
+ "typescript": "^4.9.5"
+ },
"engines": {
"node": ">=18"
}
diff --git a/core/src/graphql/logic/processXComSendCoins.ts b/core/src/graphql/logic/processXComSendCoins.ts
index 6846ed143..5b93a3d2b 100644
--- a/core/src/graphql/logic/processXComSendCoins.ts
+++ b/core/src/graphql/logic/processXComSendCoins.ts
@@ -1,38 +1,35 @@
import {
+ CommunityLoggingView,
+ countOpenPendingTransactions,
Community as DbCommunity,
FederatedCommunity as DbFederatedCommunity,
PendingTransaction as DbPendingTransaction,
User as dbUser,
- TransactionLink as DbTransactionLink,
- PendingTransactionLoggingView,
- CommunityLoggingView,
- UserLoggingView,
- countOpenPendingTransactions,
- getCommunityByUuid,
- findUserByIdentifier,
findTransactionLinkByCode,
+ findUserByIdentifier,
+ getCommunityByUuid,
+ PendingTransactionLoggingView,
+ UserLoggingView
} from 'database'
import { Decimal } from 'decimal.js-light'
-import { LOG4JS_BASE_CATEGORY_NAME } from '@config/const'
import { CONFIG as CONFIG_CORE } from '@/config'
+import { LOG4JS_BASE_CATEGORY_NAME } from '@config/const'
import { SendCoinsClient as V1_0_SendCoinsClient } from '@federation/client/1_0/SendCoinsClient'
-import { SendCoinsArgs } from '@federation/client/1_0/model/SendCoinsArgs'
import { SendCoinsResult } from '@federation/client/1_0/model/SendCoinsResult'
import { SendCoinsClientFactory } from '@federation/client/SendCoinsClientFactory'
-import { encryptAndSign, PendingTransactionState, SendCoinsJwtPayloadType, SendCoinsResponseJwtPayloadType, verifyAndDecrypt } from 'shared'
import { TransactionTypeId } from '@graphql/enum/TransactionTypeId'
+import { encryptAndSign, PendingTransactionState, SendCoinsJwtPayloadType, SendCoinsResponseJwtPayloadType, verifyAndDecrypt } from 'shared'
// import { LogError } from '@server/LogError'
import { calculateSenderBalance } from '@util/calculateSenderBalance'
import { fullName } from '@util/utilities'
import { getLogger } from 'log4js'
-import { settlePendingSenderTransaction } from './settlePendingSenderTransaction'
-import { SendCoinsArgsLoggingView } from '@federation/client/1_0/logging/SendCoinsArgsLogging.view'
import { SendCoinsResultLoggingView } from '@federation/client/1_0/logging/SendCoinsResultLogging.view'
import { EncryptedTransferArgs } from '@graphql/model/EncryptedTransferArgs'
import { randombytes_random } from 'sodium-native'
+import { settlePendingSenderTransaction } from './settlePendingSenderTransaction'
import { storeForeignUser } from './storeForeignUser'
const createLogger = (method: string) => getLogger(`${LOG4JS_BASE_CATEGORY_NAME}.graphql.resolver.util.processXComSendCoins.${method}`)
From b0688fd8fe4b2e509b7fadb88ddca966d6528f91 Mon Sep 17 00:00:00 2001
From: clauspeterhuebner
Date: Mon, 25 Aug 2025 15:19:47 +0200
Subject: [PATCH 10/48] after change i18n dependency
---
bun.lock | 3 ++-
1 file changed, 2 insertions(+), 1 deletion(-)
diff --git a/bun.lock b/bun.lock
index d524f7999..9b49f0b8d 100644
--- a/bun.lock
+++ b/bun.lock
@@ -184,9 +184,11 @@
"dependencies": {
"database": "*",
"esbuild": "^0.25.2",
+ "i18n": "^0.15.1",
"jose": "^4.14.4",
"log4js": "^6.9.1",
"shared": "*",
+ "sodium-native": "^3.4.1",
"zod": "^3.25.61",
},
"devDependencies": {
@@ -195,7 +197,6 @@
"config-schema": "*",
"decimal.js-light": "^2.5.1",
"graphql-request": "5.0.0",
- "i18n": "^0.15.1",
"jest": "27.2.4",
"type-graphql": "^1.1.1",
"typescript": "^4.9.5",
From 7910528a6f363c3da655c8b54d21f0ca200df294 Mon Sep 17 00:00:00 2001
From: clauspeterhuebner
Date: Mon, 25 Aug 2025 16:55:29 +0200
Subject: [PATCH 11/48] reorg all imports in core to relative pathes
---
.../resolver/ContributionResolver.test.ts | 2 +-
.../resolver/TransactionLinkResolver.ts | 1 +
.../src/graphql/resolver/UserResolver.test.ts | 2 +-
.../federation/client/1_0/SendCoinsClient.ts | 6 +++---
.../1_0/logging/SendCoinsArgsLogging.view.ts | 2 +-
.../logging/SendCoinsResultLogging.view.ts | 2 +-
.../federation/client/1_1/SendCoinsClient.ts | 2 +-
.../client/SendCoinsClientFactory.ts | 6 +++---
core/src/graphql/logging/DecayLogging.view.ts | 2 +-
.../logic/interpretEncryptedTransferArgs.ts | 4 ++--
.../src/graphql/logic/processXComSendCoins.ts | 20 +++++++++----------
.../logic/settlePendingSenderTransaction.ts | 2 +-
core/src/graphql/logic/storeForeignUser.ts | 4 ++--
core/src/util/calculateSenderBalance.ts | 2 +-
core/tsconfig.json | 2 +-
15 files changed, 30 insertions(+), 29 deletions(-)
diff --git a/backend/src/graphql/resolver/ContributionResolver.test.ts b/backend/src/graphql/resolver/ContributionResolver.test.ts
index 14dfa614f..6dee20592 100644
--- a/backend/src/graphql/resolver/ContributionResolver.test.ts
+++ b/backend/src/graphql/resolver/ContributionResolver.test.ts
@@ -50,7 +50,7 @@ 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 '@/util/utilities'
+import { getFirstDayOfPreviousNMonth } from 'core'
import { getLogger } from 'config-schema/test/testSetup'
import { getLogger as originalGetLogger } from 'log4js'
diff --git a/backend/src/graphql/resolver/TransactionLinkResolver.ts b/backend/src/graphql/resolver/TransactionLinkResolver.ts
index 28375bcab..532cfec2f 100644
--- a/backend/src/graphql/resolver/TransactionLinkResolver.ts
+++ b/backend/src/graphql/resolver/TransactionLinkResolver.ts
@@ -8,6 +8,7 @@ import { ContributionStatus } from '@enum/ContributionStatus'
import { ContributionType } from '@enum/ContributionType'
import { ContributionLink } from '@model/ContributionLink'
import { RedeemJwtLink } from '@model/RedeemJwtLink'
+import { Community } from '@model/Community'
import { TransactionLink, TransactionLinkResult } from '@model/TransactionLink'
import { User } from '@model/User'
import { QueryLinkResult } from '@union/QueryLinkResult'
diff --git a/backend/src/graphql/resolver/UserResolver.test.ts b/backend/src/graphql/resolver/UserResolver.test.ts
index bf2cb1f59..64817bd3e 100644
--- a/backend/src/graphql/resolver/UserResolver.test.ts
+++ b/backend/src/graphql/resolver/UserResolver.test.ts
@@ -65,7 +65,7 @@ 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 '@/util/utilities'
+import { objectValuesToArray } from 'core'
import { LOG4JS_BASE_CATEGORY_NAME } from '@/config/const'
import { getLogger } from 'config-schema/test/testSetup'
diff --git a/core/src/federation/client/1_0/SendCoinsClient.ts b/core/src/federation/client/1_0/SendCoinsClient.ts
index bb8d2c858..a872c438d 100644
--- a/core/src/federation/client/1_0/SendCoinsClient.ts
+++ b/core/src/federation/client/1_0/SendCoinsClient.ts
@@ -1,15 +1,15 @@
import { FederatedCommunity as DbFederatedCommunity } from 'database'
import { GraphQLClient } from 'graphql-request'
-import { ensureUrlEndsWithSlash } from '@/util/utilities'
+import { ensureUrlEndsWithSlash } from '../../../util/utilities'
import { getLogger } from 'log4js'
-import { LOG4JS_BASE_CATEGORY_NAME } from '@/config/const'
+import { LOG4JS_BASE_CATEGORY_NAME } from '../../../config/const'
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'
+import { EncryptedTransferArgs } from '../../../graphql/model/EncryptedTransferArgs'
const logger = getLogger(`${LOG4JS_BASE_CATEGORY_NAME}.federation.client.1_0.SendCoinsClient`)
diff --git a/core/src/federation/client/1_0/logging/SendCoinsArgsLogging.view.ts b/core/src/federation/client/1_0/logging/SendCoinsArgsLogging.view.ts
index 1db8c2887..11afa4346 100644
--- a/core/src/federation/client/1_0/logging/SendCoinsArgsLogging.view.ts
+++ b/core/src/federation/client/1_0/logging/SendCoinsArgsLogging.view.ts
@@ -1,6 +1,6 @@
import { AbstractLoggingView } from 'database'
-import { SendCoinsArgs } from '@federation/client/1_0/model/SendCoinsArgs'
+import { SendCoinsArgs } from '../model/SendCoinsArgs'
export class SendCoinsArgsLoggingView extends AbstractLoggingView {
public constructor(private self: SendCoinsArgs) {
diff --git a/core/src/federation/client/1_0/logging/SendCoinsResultLogging.view.ts b/core/src/federation/client/1_0/logging/SendCoinsResultLogging.view.ts
index 383f4fd37..1eb08c432 100644
--- a/core/src/federation/client/1_0/logging/SendCoinsResultLogging.view.ts
+++ b/core/src/federation/client/1_0/logging/SendCoinsResultLogging.view.ts
@@ -1,6 +1,6 @@
import { AbstractLoggingView } from 'database'
-import { SendCoinsResult } from '@federation/client/1_0/model/SendCoinsResult'
+import { SendCoinsResult } from '../model/SendCoinsResult'
export class SendCoinsResultLoggingView extends AbstractLoggingView {
public constructor(private self: SendCoinsResult) {
diff --git a/core/src/federation/client/1_1/SendCoinsClient.ts b/core/src/federation/client/1_1/SendCoinsClient.ts
index 8c7f9caec..b0eab7c0c 100644
--- a/core/src/federation/client/1_1/SendCoinsClient.ts
+++ b/core/src/federation/client/1_1/SendCoinsClient.ts
@@ -1,3 +1,3 @@
-import { SendCoinsClient as V1_0_SendCoinsClient } from '@federation/client/1_0/SendCoinsClient'
+import { SendCoinsClient as V1_0_SendCoinsClient } from '../1_0/SendCoinsClient'
export class SendCoinsClient extends V1_0_SendCoinsClient {}
diff --git a/core/src/federation/client/SendCoinsClientFactory.ts b/core/src/federation/client/SendCoinsClientFactory.ts
index 8251da3cb..4a2772175 100644
--- a/core/src/federation/client/SendCoinsClientFactory.ts
+++ b/core/src/federation/client/SendCoinsClientFactory.ts
@@ -1,8 +1,8 @@
import { FederatedCommunity as DbFederatedCommunity } from 'database'
-import { SendCoinsClient as V1_0_SendCoinsClient } from '@federation/client/1_0/SendCoinsClient'
-import { SendCoinsClient as V1_1_SendCoinsClient } from '@federation/client/1_1/SendCoinsClient'
-import { ApiVersionType } from '@federation/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/logging/DecayLogging.view.ts b/core/src/graphql/logging/DecayLogging.view.ts
index f4f20ab6f..2c485447a 100644
--- a/core/src/graphql/logging/DecayLogging.view.ts
+++ b/core/src/graphql/logging/DecayLogging.view.ts
@@ -1,6 +1,6 @@
import { AbstractLoggingView } from 'database'
-import { Decay } from '@graphql/model/Decay'
+import { Decay } from '../model/Decay'
import type { Decay as DecayInterface } from 'shared'
export class DecayLoggingView extends AbstractLoggingView {
diff --git a/core/src/graphql/logic/interpretEncryptedTransferArgs.ts b/core/src/graphql/logic/interpretEncryptedTransferArgs.ts
index 0d522bff7..301f6da16 100644
--- a/core/src/graphql/logic/interpretEncryptedTransferArgs.ts
+++ b/core/src/graphql/logic/interpretEncryptedTransferArgs.ts
@@ -6,10 +6,10 @@ import { CommunityLoggingView, getHomeCommunity } from 'database'
import { verifyAndDecrypt } from 'shared'
import { LOG4JS_BASE_CATEGORY_NAME } from '../../config/const'
-const logger = getLogger(`${LOG4JS_BASE_CATEGORY_NAME}.graphql.resolver.util.interpretEncryptedTransferArgs`)
+const logger = getLogger(`${LOG4JS_BASE_CATEGORY_NAME}.graphql.logic.interpretEncryptedTransferArgs`)
export const interpretEncryptedTransferArgs = async (args: EncryptedTransferArgs): Promise => {
- const methodLogger = getLogger(`${LOG4JS_BASE_CATEGORY_NAME}.graphql.resolver.util.interpretEncryptedTransferArgs-method`)
+ const methodLogger = getLogger(`${LOG4JS_BASE_CATEGORY_NAME}.graphql.logic.interpretEncryptedTransferArgs-method`)
methodLogger.addContext('handshakeID', args.handshakeID)
methodLogger.debug('interpretEncryptedTransferArgs()... args:', args)
// first find with args.publicKey the community 'requestingCom', which starts the request
diff --git a/core/src/graphql/logic/processXComSendCoins.ts b/core/src/graphql/logic/processXComSendCoins.ts
index 5b93a3d2b..19c75898f 100644
--- a/core/src/graphql/logic/processXComSendCoins.ts
+++ b/core/src/graphql/logic/processXComSendCoins.ts
@@ -13,21 +13,21 @@ import {
} from 'database'
import { Decimal } from 'decimal.js-light'
-import { CONFIG as CONFIG_CORE } from '@/config'
-import { LOG4JS_BASE_CATEGORY_NAME } from '@config/const'
+import { CONFIG as CONFIG_CORE } from '../../config'
+import { LOG4JS_BASE_CATEGORY_NAME } from '../../config/const'
-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 { 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 { encryptAndSign, PendingTransactionState, SendCoinsJwtPayloadType, SendCoinsResponseJwtPayloadType, verifyAndDecrypt } from 'shared'
// import { LogError } from '@server/LogError'
-import { calculateSenderBalance } from '@util/calculateSenderBalance'
-import { fullName } from '@util/utilities'
+import { calculateSenderBalance } from '../../util/calculateSenderBalance'
+import { fullName } from '../../util/utilities'
import { getLogger } from 'log4js'
-import { SendCoinsResultLoggingView } from '@federation/client/1_0/logging/SendCoinsResultLogging.view'
-import { EncryptedTransferArgs } from '@graphql/model/EncryptedTransferArgs'
+import { SendCoinsResultLoggingView } from '../../federation/client/1_0/logging/SendCoinsResultLogging.view'
+import { EncryptedTransferArgs } from '../../graphql/model/EncryptedTransferArgs'
import { randombytes_random } from 'sodium-native'
import { settlePendingSenderTransaction } from './settlePendingSenderTransaction'
import { storeForeignUser } from './storeForeignUser'
diff --git a/core/src/graphql/logic/settlePendingSenderTransaction.ts b/core/src/graphql/logic/settlePendingSenderTransaction.ts
index 8abd511c1..87ab8116c 100644
--- a/core/src/graphql/logic/settlePendingSenderTransaction.ts
+++ b/core/src/graphql/logic/settlePendingSenderTransaction.ts
@@ -10,7 +10,7 @@ import {
} from 'database'
import { Decimal } from 'decimal.js-light'
-import { LOG4JS_BASE_CATEGORY_NAME } from '@/config/const'
+import { LOG4JS_BASE_CATEGORY_NAME } from '../../config/const'
import { PendingTransactionState } from 'shared'
// import { LogError } from '@/server/LogError'
import { calculateSenderBalance } from 'core'
diff --git a/core/src/graphql/logic/storeForeignUser.ts b/core/src/graphql/logic/storeForeignUser.ts
index 402a9a835..1e6b8153f 100644
--- a/core/src/graphql/logic/storeForeignUser.ts
+++ b/core/src/graphql/logic/storeForeignUser.ts
@@ -1,7 +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 { SendCoinsResult } from '../../federation/client/1_0/model/SendCoinsResult'
+import { LOG4JS_BASE_CATEGORY_NAME } from '../../config/const'
import { getLogger } from 'log4js'
const logger = getLogger(`${LOG4JS_BASE_CATEGORY_NAME}.graphql.logic.storeForeignUser`)
diff --git a/core/src/util/calculateSenderBalance.ts b/core/src/util/calculateSenderBalance.ts
index ce7609895..7fe5ae19f 100644
--- a/core/src/util/calculateSenderBalance.ts
+++ b/core/src/util/calculateSenderBalance.ts
@@ -1,6 +1,6 @@
import { Decimal } from 'decimal.js-light'
-import { Decay } from '@graphql/model/Decay'
+import { Decay } from '../graphql/model/Decay'
import { getLastTransaction } from 'database'
diff --git a/core/tsconfig.json b/core/tsconfig.json
index 660381127..c30aab30d 100644
--- a/core/tsconfig.json
+++ b/core/tsconfig.json
@@ -51,7 +51,7 @@
"@federation/*": ["src/federation/*"],
"@graphql/*": ["src/graphql/*"],
"@util/*": ["src/util/*"],
- "@validation/*": ["src/validation/*"],
+ "@validation/*": ["src/validation/*"]
},
// "rootDirs": [".", "../database"], /* List of root folders whose combined content represents the structure of the project at runtime. */
// "typeRoots": [], /* List of folders to include type definitions from. */
From 1ad378aa2204a34815e9d108d6af42e0af228b80 Mon Sep 17 00:00:00 2001
From: clauspeterhuebner
Date: Mon, 25 Aug 2025 21:41:31 +0200
Subject: [PATCH 12/48] correct path for mock transaction-lock
---
backend/src/graphql/resolver/TransactionLinkResolver.test.ts | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/backend/src/graphql/resolver/TransactionLinkResolver.test.ts b/backend/src/graphql/resolver/TransactionLinkResolver.test.ts
index 03ac5524b..6997c0e93 100644
--- a/backend/src/graphql/resolver/TransactionLinkResolver.test.ts
+++ b/backend/src/graphql/resolver/TransactionLinkResolver.test.ts
@@ -43,7 +43,7 @@ const logErrorLogger = getLogger(`${LOG4JS_BASE_CATEGORY_NAME}.server.LogError`)
jest.mock('@/password/EncryptorUtils')
// mock semaphore to allow use fake timers
-jest.mock('@/util/TRANSACTIONS_LOCK')
+jest.mock('database/util/TRANSACTIONS_LOCK')
TRANSACTIONS_LOCK.acquire = jest.fn().mockResolvedValue(jest.fn())
let mutate: ApolloServerTestClient['mutate']
From a0cde876cd21c3981717bd2f80b16cb7635e6e7e Mon Sep 17 00:00:00 2001
From: clauspeterhuebner
Date: Mon, 25 Aug 2025 23:07:48 +0200
Subject: [PATCH 13/48] correct import of entities
---
database/src/queries/communities.ts | 2 +-
database/src/queries/transactionLinks.ts | 2 +-
database/src/queries/transactions.ts | 2 +-
3 files changed, 3 insertions(+), 3 deletions(-)
diff --git a/database/src/queries/communities.ts b/database/src/queries/communities.ts
index 3afdaf883..edc3bd7ed 100644
--- a/database/src/queries/communities.ts
+++ b/database/src/queries/communities.ts
@@ -1,4 +1,4 @@
-import { Community as DbCommunity } from '../entity/Community'
+import { Community as DbCommunity } from '../entity'
/**
* Retrieves the home community, i.e., a community that is not foreign.
diff --git a/database/src/queries/transactionLinks.ts b/database/src/queries/transactionLinks.ts
index 9a4cda064..eb9908101 100644
--- a/database/src/queries/transactionLinks.ts
+++ b/database/src/queries/transactionLinks.ts
@@ -1,4 +1,4 @@
-import { TransactionLink as DbTransactionLink } from "../entity/TransactionLink"
+import { TransactionLink as DbTransactionLink } from "../entity"
export async function findTransactionLinkByCode(code: string): Promise {
return await DbTransactionLink.findOneOrFail({
diff --git a/database/src/queries/transactions.ts b/database/src/queries/transactions.ts
index 0e5b236e2..5df8186e7 100644
--- a/database/src/queries/transactions.ts
+++ b/database/src/queries/transactions.ts
@@ -1,4 +1,4 @@
-import { Transaction as DbTransaction } from 'database'
+import { Transaction as DbTransaction } from '../entity'
export const getLastTransaction = async (
userId: number,
From bfd2e61d65f6b9c8ee45b24b2793117a057dc818 Mon Sep 17 00:00:00 2001
From: clauspeterhuebner
Date: Mon, 25 Aug 2025 23:54:48 +0200
Subject: [PATCH 14/48] modify jest.mock for TRANSACTIONS_LOCK
---
backend/src/graphql/resolver/TransactionLinkResolver.test.ts | 2 +-
database/src/util/index.ts | 2 +-
2 files changed, 2 insertions(+), 2 deletions(-)
diff --git a/backend/src/graphql/resolver/TransactionLinkResolver.test.ts b/backend/src/graphql/resolver/TransactionLinkResolver.test.ts
index 6997c0e93..03ac5524b 100644
--- a/backend/src/graphql/resolver/TransactionLinkResolver.test.ts
+++ b/backend/src/graphql/resolver/TransactionLinkResolver.test.ts
@@ -43,7 +43,7 @@ const logErrorLogger = getLogger(`${LOG4JS_BASE_CATEGORY_NAME}.server.LogError`)
jest.mock('@/password/EncryptorUtils')
// mock semaphore to allow use fake timers
-jest.mock('database/util/TRANSACTIONS_LOCK')
+jest.mock('@/util/TRANSACTIONS_LOCK')
TRANSACTIONS_LOCK.acquire = jest.fn().mockResolvedValue(jest.fn())
let mutate: ApolloServerTestClient['mutate']
diff --git a/database/src/util/index.ts b/database/src/util/index.ts
index b16b20d19..d2fde2126 100644
--- a/database/src/util/index.ts
+++ b/database/src/util/index.ts
@@ -1,2 +1,2 @@
export * from './TRANSACTIONS_LOCK'
-export * from './TRANSACTION_LINK_LOCK'
\ No newline at end of file
+export * from './TRANSACTION_LINK_LOCK'
From 738fe6f9ec4721184a767c130d17a925475a2975 Mon Sep 17 00:00:00 2001
From: clauspeterhuebner
Date: Tue, 26 Aug 2025 00:06:01 +0200
Subject: [PATCH 15/48] next try jest.mock TRANSACTIONS_LOCK
---
backend/src/graphql/resolver/TransactionLinkResolver.test.ts | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/backend/src/graphql/resolver/TransactionLinkResolver.test.ts b/backend/src/graphql/resolver/TransactionLinkResolver.test.ts
index 03ac5524b..bac8e6cea 100644
--- a/backend/src/graphql/resolver/TransactionLinkResolver.test.ts
+++ b/backend/src/graphql/resolver/TransactionLinkResolver.test.ts
@@ -43,7 +43,7 @@ const logErrorLogger = getLogger(`${LOG4JS_BASE_CATEGORY_NAME}.server.LogError`)
jest.mock('@/password/EncryptorUtils')
// mock semaphore to allow use fake timers
-jest.mock('@/util/TRANSACTIONS_LOCK')
+jest.mock('database')
TRANSACTIONS_LOCK.acquire = jest.fn().mockResolvedValue(jest.fn())
let mutate: ApolloServerTestClient['mutate']
From ce1cf8595694d1b3d8667bab1c2e5532876eca70 Mon Sep 17 00:00:00 2001
From: clauspeterhuebner
Date: Tue, 26 Aug 2025 00:27:55 +0200
Subject: [PATCH 16/48] next try
---
backend/src/graphql/resolver/TransactionLinkResolver.test.ts | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/backend/src/graphql/resolver/TransactionLinkResolver.test.ts b/backend/src/graphql/resolver/TransactionLinkResolver.test.ts
index bac8e6cea..6997c0e93 100644
--- a/backend/src/graphql/resolver/TransactionLinkResolver.test.ts
+++ b/backend/src/graphql/resolver/TransactionLinkResolver.test.ts
@@ -43,7 +43,7 @@ const logErrorLogger = getLogger(`${LOG4JS_BASE_CATEGORY_NAME}.server.LogError`)
jest.mock('@/password/EncryptorUtils')
// mock semaphore to allow use fake timers
-jest.mock('database')
+jest.mock('database/util/TRANSACTIONS_LOCK')
TRANSACTIONS_LOCK.acquire = jest.fn().mockResolvedValue(jest.fn())
let mutate: ApolloServerTestClient['mutate']
From 071488f0e8824c2c9ff6743a90a7dd562125fc87 Mon Sep 17 00:00:00 2001
From: einhornimmond
Date: Tue, 26 Aug 2025 08:03:11 +0200
Subject: [PATCH 17/48] need full path for mocking part of submodule
---
backend/src/graphql/resolver/TransactionLinkResolver.test.ts | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/backend/src/graphql/resolver/TransactionLinkResolver.test.ts b/backend/src/graphql/resolver/TransactionLinkResolver.test.ts
index 6997c0e93..d7c2fc713 100644
--- a/backend/src/graphql/resolver/TransactionLinkResolver.test.ts
+++ b/backend/src/graphql/resolver/TransactionLinkResolver.test.ts
@@ -43,7 +43,7 @@ const logErrorLogger = getLogger(`${LOG4JS_BASE_CATEGORY_NAME}.server.LogError`)
jest.mock('@/password/EncryptorUtils')
// mock semaphore to allow use fake timers
-jest.mock('database/util/TRANSACTIONS_LOCK')
+jest.mock('database/src/util/TRANSACTIONS_LOCK')
TRANSACTIONS_LOCK.acquire = jest.fn().mockResolvedValue(jest.fn())
let mutate: ApolloServerTestClient['mutate']
From 16fcaad7d4b941e6cfc97163d8f6582bf004b390 Mon Sep 17 00:00:00 2001
From: einhornimmond
Date: Tue, 26 Aug 2025 08:07:08 +0200
Subject: [PATCH 18/48] add type specification for sodium in core
---
bun.lock | 1 +
core/package.json | 1 +
yarn.lock | 5 +++++
3 files changed, 7 insertions(+)
diff --git a/bun.lock b/bun.lock
index 9b49f0b8d..564c3b0fa 100644
--- a/bun.lock
+++ b/bun.lock
@@ -194,6 +194,7 @@
"devDependencies": {
"@biomejs/biome": "2.0.0",
"@types/node": "^17.0.21",
+ "@types/sodium-native": "^2.3.5",
"config-schema": "*",
"decimal.js-light": "^2.5.1",
"graphql-request": "5.0.0",
diff --git a/core/package.json b/core/package.json
index 092b4ff00..e1d805c66 100644
--- a/core/package.json
+++ b/core/package.json
@@ -37,6 +37,7 @@
"devDependencies": {
"@biomejs/biome": "2.0.0",
"@types/node": "^17.0.21",
+ "@types/sodium-native": "^2.3.5",
"config-schema": "*",
"decimal.js-light": "^2.5.1",
"graphql-request": "5.0.0",
diff --git a/yarn.lock b/yarn.lock
index 235b04ce6..2b815e0ef 100644
--- a/yarn.lock
+++ b/yarn.lock
@@ -2667,6 +2667,11 @@
resolved "https://registry.npmjs.org/@types/node/-/node-10.17.60.tgz"
integrity sha512-F0KIgDJfy2nA3zMLmWGKxcH2ZVEtCZXHHdOQs2gSaQ27+lNeEfGxzkIw90aXswATX7AZ33tahPbzy6KAfUreVw==
+"@types/node@^14.11.2":
+ version "14.18.63"
+ resolved "https://registry.yarnpkg.com/@types/node/-/node-14.18.63.tgz#1788fa8da838dbb5f9ea994b834278205db6ca2b"
+ integrity sha512-fAtCfv4jJg+ExtXhvCkCqUKZ+4ok/JQk01qDKhL5BDDoS3AxKXhV5/MAVUZyQnSEd2GT92fkgZl0pz0Q0AzcIQ==
+
"@types/node@^17.0.21", "@types/node@^17.0.45":
version "17.0.45"
resolved "https://registry.npmjs.org/@types/node/-/node-17.0.45.tgz"
From 75477a493ed474ad54a9cebba5d3478a3d64636d Mon Sep 17 00:00:00 2001
From: einhornimmond
Date: Tue, 26 Aug 2025 08:20:01 +0200
Subject: [PATCH 19/48] add @types/i18n in core
---
bun.lock | 1 +
core/package.json | 1 +
2 files changed, 2 insertions(+)
diff --git a/bun.lock b/bun.lock
index 564c3b0fa..5c1e61306 100644
--- a/bun.lock
+++ b/bun.lock
@@ -193,6 +193,7 @@
},
"devDependencies": {
"@biomejs/biome": "2.0.0",
+ "@types/i18n": "^0.13.4",
"@types/node": "^17.0.21",
"@types/sodium-native": "^2.3.5",
"config-schema": "*",
diff --git a/core/package.json b/core/package.json
index e1d805c66..9e745f948 100644
--- a/core/package.json
+++ b/core/package.json
@@ -36,6 +36,7 @@
},
"devDependencies": {
"@biomejs/biome": "2.0.0",
+ "@types/i18n": "^0.13.4",
"@types/node": "^17.0.21",
"@types/sodium-native": "^2.3.5",
"config-schema": "*",
From d7c5c852e92be7e556143667526e4afc86cfb18d Mon Sep 17 00:00:00 2001
From: clauspeterhuebner
Date: Wed, 27 Aug 2025 16:03:42 +0200
Subject: [PATCH 20/48] correct devDependencies after Darios info
---
core/package.json | 2 ++
1 file changed, 2 insertions(+)
diff --git a/core/package.json b/core/package.json
index 092b4ff00..9e745f948 100644
--- a/core/package.json
+++ b/core/package.json
@@ -36,7 +36,9 @@
},
"devDependencies": {
"@biomejs/biome": "2.0.0",
+ "@types/i18n": "^0.13.4",
"@types/node": "^17.0.21",
+ "@types/sodium-native": "^2.3.5",
"config-schema": "*",
"decimal.js-light": "^2.5.1",
"graphql-request": "5.0.0",
From 15157ed2595f79ae2891d815738deeeceecffc41 Mon Sep 17 00:00:00 2001
From: clauspeterhuebner
Date: Wed, 27 Aug 2025 16:04:27 +0200
Subject: [PATCH 21/48] correct jest.mock TRANSACTION_LOCK after Darios info
---
backend/src/graphql/resolver/TransactionLinkResolver.test.ts | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/backend/src/graphql/resolver/TransactionLinkResolver.test.ts b/backend/src/graphql/resolver/TransactionLinkResolver.test.ts
index 6997c0e93..d7c2fc713 100644
--- a/backend/src/graphql/resolver/TransactionLinkResolver.test.ts
+++ b/backend/src/graphql/resolver/TransactionLinkResolver.test.ts
@@ -43,7 +43,7 @@ const logErrorLogger = getLogger(`${LOG4JS_BASE_CATEGORY_NAME}.server.LogError`)
jest.mock('@/password/EncryptorUtils')
// mock semaphore to allow use fake timers
-jest.mock('database/util/TRANSACTIONS_LOCK')
+jest.mock('database/src/util/TRANSACTIONS_LOCK')
TRANSACTIONS_LOCK.acquire = jest.fn().mockResolvedValue(jest.fn())
let mutate: ApolloServerTestClient['mutate']
From f844e08c8d218b12e36ccc6910d59f0c4b4f4adb Mon Sep 17 00:00:00 2001
From: clauspeterhuebner
Date: Wed, 27 Aug 2025 16:40:52 +0200
Subject: [PATCH 22/48] add invokation of processXComCompleteTransaction in
Disbursement-Process
---
.../client/1_0/DisbursementClient.ts | 8 +++----
.../src/graphql/logic/processXComSendCoins.ts | 2 +-
.../api/1_0/resolver/DisbursementResolver.ts | 21 +++++++++++++++++++
3 files changed, 26 insertions(+), 5 deletions(-)
diff --git a/backend/src/federation/client/1_0/DisbursementClient.ts b/backend/src/federation/client/1_0/DisbursementClient.ts
index abaf1818b..8ca859070 100644
--- a/backend/src/federation/client/1_0/DisbursementClient.ts
+++ b/backend/src/federation/client/1_0/DisbursementClient.ts
@@ -31,10 +31,10 @@ export class DisbursementClient {
logger.debug('sendDisburseJwtToSenderCommunity against endpoint=', this.endpoint)
try {
const { data } = await this.client.rawRequest<{ processDisburseJwtOnSenderCommunity: string }>(processDisburseJwtOnSenderCommunityQuery, { args })
- const responseJwt = data?.processDisburseJwtOnSenderCommunity
- if (responseJwt) {
- logger.debug('received response jwt', responseJwt)
- return responseJwt
+ const response = data?.processDisburseJwtOnSenderCommunity
+ if (response) {
+ logger.debug('received response:', response)
+ return response
}
} catch (err) {
const errmsg = `sendDisburseJwtToSenderCommunity failed for endpoint=${this.endpoint}, err=${err}`
diff --git a/core/src/graphql/logic/processXComSendCoins.ts b/core/src/graphql/logic/processXComSendCoins.ts
index 19c75898f..dc8e3127f 100644
--- a/core/src/graphql/logic/processXComSendCoins.ts
+++ b/core/src/graphql/logic/processXComSendCoins.ts
@@ -42,9 +42,9 @@ export async function processXComCompleteTransaction(
amount: string,
memo: string,
code?: string,
- creationDate?: Date,
recipientfirstname?: string,
recipientalias?: string,
+ creationDate?: Date,
): Promise {
const methodLogger = createLogger(`processXComCompleteTransaction`)
// processing a x-community sendCoins
diff --git a/federation/src/graphql/api/1_0/resolver/DisbursementResolver.ts b/federation/src/graphql/api/1_0/resolver/DisbursementResolver.ts
index 629da9e54..2388aaec0 100644
--- a/federation/src/graphql/api/1_0/resolver/DisbursementResolver.ts
+++ b/federation/src/graphql/api/1_0/resolver/DisbursementResolver.ts
@@ -5,6 +5,7 @@ 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}`)
@@ -29,5 +30,25 @@ export class DisbursementResolver {
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,
+ )) {
+ result = 'Disbursement of Redeem-Link successfull!'
+ }
+ } catch (err) {
+ result = `Error in Disbursement of Redeem-Link: ` + err
+ methodLogger.error(result)
+ }
+ return result
}
}
\ No newline at end of file
From 1d248f9e344ee8d386dbf056ad565ed0fb244733 Mon Sep 17 00:00:00 2001
From: clauspeterhuebner
Date: Wed, 27 Aug 2025 23:29:30 +0200
Subject: [PATCH 23/48] introduce encryptAndSign for createRedeemJwt
---
.../resolver/TransactionLinkResolver.ts | 54 ++++++++++++-------
1 file changed, 34 insertions(+), 20 deletions(-)
diff --git a/backend/src/graphql/resolver/TransactionLinkResolver.ts b/backend/src/graphql/resolver/TransactionLinkResolver.ts
index 532cfec2f..227f6b4ba 100644
--- a/backend/src/graphql/resolver/TransactionLinkResolver.ts
+++ b/backend/src/graphql/resolver/TransactionLinkResolver.ts
@@ -425,27 +425,41 @@ export class TransactionLinkResolver {
alias,
validUntil,
})
-
- const redeemJwtPayloadType = new RedeemJwtPayloadType(
- senderCommunityUuid,
- gradidoId,
- alias ?? firstName ?? '',
- code,
- amount,
- memo,
- validUntil ?? '',
- )
- // TODO:encode/sign the jwt normally with the private key of the sender/home community, but interims with uuid
- const homeCom = await getHomeCommunity()
- if (!homeCom) {
- throw new LogError('Home community not found')
+ try {
+ const redeemJwtPayloadType = new RedeemJwtPayloadType(
+ senderCommunityUuid,
+ gradidoId,
+ alias ?? firstName ?? '',
+ code,
+ amount,
+ memo,
+ validUntil ?? '',
+ )
+ // encode/sign the jwt with the private key of the sender/home community
+ const senderCom = await getCommunityByUuid(senderCommunityUuid)
+ if (!senderCom) {
+ throw new LogError('Sender community not found')
+ }
+ if (!senderCom.privateJwtKey) {
+ throw new LogError('Sender community privateJwtKey is not set')
+ }
+ const recipientCom = await getCommunityByUuid(recipientCommunityUuid)
+ if (!recipientCom) {
+ throw new LogError('Recipient community not found')
+ }
+ if (!recipientCom.publicJwtKey) {
+ throw new LogError('Recipient community publicJwtKey is not set')
+ }
+ const redeemJwt = await encryptAndSign(redeemJwtPayloadType, senderCom.privateJwtKey!, recipientCom.publicJwtKey!)
+ if (!redeemJwt) {
+ throw new LogError('Redeem JWT was not created successfully')
+ }
+ return redeemJwt
+ } catch (e) {
+ const errmsg = `Error on creating Redeem JWT: error=${e}`
+ methodLogger.error(errmsg)
+ throw new LogError(errmsg)
}
- if (!homeCom.communityUuid) {
- throw new LogError('Home community UUID is not set')
- }
- const redeemJwt = await encode(redeemJwtPayloadType, homeCom.communityUuid)
- // TODO: encrypt the payload with the public key of the target community
- return redeemJwt
}
@Authorized([RIGHTS.DISBURSE_TRANSACTION_LINK])
From 9d9e6a14be7074da4382df6c890bcd5cf0258631 Mon Sep 17 00:00:00 2001
From: clauspeterhuebner
Date: Thu, 28 Aug 2025 19:02:02 +0200
Subject: [PATCH 24/48] transfer redeemJwt in an envelopJwt with pubKey
---
.../resolver/TransactionLinkResolver.ts | 177 +++++++++---------
.../src/graphql/resolver/util/communities.ts | 5 +
shared/src/index.ts | 1 +
.../payloadtypes/SignedTransferPayloadType.ts | 21 +++
4 files changed, 117 insertions(+), 87 deletions(-)
create mode 100644 shared/src/jwt/payloadtypes/SignedTransferPayloadType.ts
diff --git a/backend/src/graphql/resolver/TransactionLinkResolver.ts b/backend/src/graphql/resolver/TransactionLinkResolver.ts
index 227f6b4ba..e4d042914 100644
--- a/backend/src/graphql/resolver/TransactionLinkResolver.ts
+++ b/backend/src/graphql/resolver/TransactionLinkResolver.ts
@@ -6,13 +6,13 @@ import { TransactionLinkFilters } from '@arg/TransactionLinkFilters'
import { ContributionCycleType } from '@enum/ContributionCycleType'
import { ContributionStatus } from '@enum/ContributionStatus'
import { ContributionType } from '@enum/ContributionType'
+import { Community } from '@model/Community'
import { ContributionLink } from '@model/ContributionLink'
import { RedeemJwtLink } from '@model/RedeemJwtLink'
-import { Community } from '@model/Community'
import { TransactionLink, TransactionLinkResult } from '@model/TransactionLink'
import { User } from '@model/User'
import { QueryLinkResult } from '@union/QueryLinkResult'
-import { Decay, TransactionTypeId } from 'core'
+import { Decay, interpretEncryptedTransferArgs, TransactionTypeId } from 'core'
import {
AppDatabase, Community as DbCommunity, Contribution as DbContribution,
ContributionLink as DbContributionLink, FederatedCommunity as DbFederatedCommunity, Transaction as DbTransaction,
@@ -48,11 +48,14 @@ import { randombytes_random } from 'sodium-native'
import { executeTransaction } from './TransactionResolver'
import {
getAuthenticatedCommunities,
+ getCommunityByIdentifier,
+ getCommunityByPublicKey,
getCommunityByUuid,
} from './util/communities'
import { getUserCreation, validateContribution } from './util/creations'
import { sendTransactionsToDltConnector } from './util/sendTransactionsToDltConnector'
import { transactionLinkList } from './util/transactionLinkList'
+import { SignedTransferPayloadType } from 'shared'
const createLogger = (method: string) => getLogger(`${LOG4JS_BASE_CATEGORY_NAME}.graphql.resolver.TransactionLinkResolver.${method}`)
@@ -454,7 +457,31 @@ export class TransactionLinkResolver {
if (!redeemJwt) {
throw new LogError('Redeem JWT was not created successfully')
}
- return redeemJwt
+ // prepare the args for the client invocation
+ const args = new EncryptedTransferArgs()
+ args.publicKey = senderCom.publicKey.toString('hex')
+ args.jwt = redeemJwt
+ args.handshakeID = randombytes_random().toString()
+ if(methodLogger.isDebugEnabled()) {
+ methodLogger.debug('successfully created RedeemJWT-Response with args:', args)
+ }
+ const signedTransferPayload = new SignedTransferPayloadType(
+ args.publicKey,
+ args.jwt,
+ args.handshakeID,
+ )
+ 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)
+ }
+
+ return signedTransferJwt
} catch (e) {
const errmsg = `Error on creating Redeem JWT: error=${e}`
methodLogger.error(errmsg)
@@ -592,98 +619,75 @@ export class TransactionLinkResolver {
}
async queryRedeemJwtLink(code: string, logger: Logger): Promise {
- logger.debug('TransactionLinkResolver.queryRedeemJwtLink... redeem jwt-token found')
- // decode token first to get the senderCommunityUuid as input for verify token
- const decodedPayload = decode(code)
- logger.debug('TransactionLinkResolver.queryRedeemJwtLink... decodedPayload=', decodedPayload)
- if (
- decodedPayload != null &&
- decodedPayload.tokentype === RedeemJwtPayloadType.REDEEM_ACTIVATION_TYPE
- ) {
- const redeemJwtPayload = new RedeemJwtPayloadType(
- decodedPayload.sendercommunityuuid as string,
- decodedPayload.sendergradidoid as string,
- decodedPayload.sendername as string,
- decodedPayload.redeemcode as string,
- decodedPayload.amount as string,
- decodedPayload.memo as string,
- decodedPayload.validuntil as string,
- )
- logger.debug(
- 'TransactionLinkResolver.queryRedeemJwtLink... redeemJwtPayload=',
- redeemJwtPayload,
- )
- const senderCom = await getCommunityByUuid(redeemJwtPayload.sendercommunityuuid)
+ 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)
+ if(decodedPayload !== null && decodedPayload.tokentype === SignedTransferPayloadType.SIGNED_TRANSFER_TYPE) {
+ const signedTransferPayload = new SignedTransferPayloadType(
+ decodedPayload.publicKey,
+ decodedPayload.jwt,
+ decodedPayload.handshakeID)
+ logger.debug('queryRedeemJwtLink... signedTransferPayload=', signedTransferPayload)
+ const senderCom = await getCommunityByPublicKey(Buffer.from(signedTransferPayload.publicKey))
if (!senderCom) {
- throw new LogError('Sender community not found:', redeemJwtPayload.sendercommunityuuid)
+ const errmsg = `Sender community not found with publicKey=${signedTransferPayload.publicKey}`
+ logger.error(errmsg)
+ throw new Error(errmsg)
}
- logger.debug('TransactionLinkResolver.queryRedeemJwtLink... senderCom=', senderCom)
- if (!senderCom.communityUuid) {
- throw new LogError('Sender community UUID is not set')
- }
- // now with the sender community UUID the jwt token can be verified
- const verifiedJwtPayload = await verify('handshakeID', code, senderCom.communityUuid)
- logger.debug(
- 'TransactionLinkResolver.queryRedeemJwtLink... nach verify verifiedJwtPayload=',
- verifiedJwtPayload,
- )
+ logger.debug('queryRedeemJwtLink... senderCom=', senderCom)
+ const verifiedJwtPayload = await verify(signedTransferPayload.handshakeID, signedTransferPayload.jwt, signedTransferPayload.publicKey) as SignedTransferPayloadType
+ logger.debug('queryRedeemJwtLink... verifiedJwtPayload=', verifiedJwtPayload)
let verifiedRedeemJwtPayload: RedeemJwtPayloadType | null = null
- if (verifiedJwtPayload !== null) {
- if (verifiedJwtPayload.exp !== undefined) {
- const expDate = new Date(verifiedJwtPayload.exp * 1000)
+ if (verifiedJwtPayload === null) {
+ const errmsg = `Error on verify transferred redeem token with publicKey=${signedTransferPayload.publicKey}`
+ logger.error(errmsg)
+ throw new Error(errmsg)
+ } else {
+ const encryptedTransferArgs = new EncryptedTransferArgs()
+ encryptedTransferArgs.publicKey = verifiedJwtPayload.publicKey
+ encryptedTransferArgs.jwt = verifiedJwtPayload.jwt
+ encryptedTransferArgs.handshakeID = verifiedJwtPayload.handshakeID
+
+ 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` + verifiedJwtPayload.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
+ 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
+ logger.error(errmsg)
+ throw new Error(errmsg)
+ }
+ if (verifiedRedeemJwtPayload.exp !== undefined) {
+ const expDate = new Date(verifiedRedeemJwtPayload.exp * 1000)
logger.debug(
- 'TransactionLinkResolver.queryRedeemJwtLink... expDate, exp =',
+ 'queryRedeemJwtLink... expDate, exp =',
expDate,
- verifiedJwtPayload.exp,
+ verifiedRedeemJwtPayload.exp,
)
if (expDate < new Date()) {
- throw new LogError('Redeem JWT-Token expired! jwtPayload.exp=', expDate)
+ const errmsg = `Redeem JWT-Token expired! jwtPayload.exp=${expDate}`
+ logger.error(errmsg)
+ throw new Error(errmsg)
}
}
- if (verifiedJwtPayload.tokentype === RedeemJwtPayloadType.REDEEM_ACTIVATION_TYPE) {
- logger.debug(
- 'TransactionLinkResolver.queryRedeemJwtLink... verifiedJwtPayload.tokentype=',
- verifiedJwtPayload.tokentype,
- )
- verifiedRedeemJwtPayload = new RedeemJwtPayloadType(
- verifiedJwtPayload.sendercommunityuuid as string,
- verifiedJwtPayload.sendergradidoid as string,
- verifiedJwtPayload.sendername as string,
- verifiedJwtPayload.redeemcode as string,
- verifiedJwtPayload.amount as string,
- verifiedJwtPayload.memo as string,
- verifiedJwtPayload.validuntil as string,
- )
- logger.debug(
- 'TransactionLinkResolver.queryRedeemJwtLink... nach verify verifiedRedeemJwtPayload=',
- verifiedRedeemJwtPayload,
- )
- }
- }
- if (verifiedRedeemJwtPayload === null) {
- logger.debug(
- 'TransactionLinkResolver.queryRedeemJwtLink... verifiedRedeemJwtPayload===null',
- )
- verifiedRedeemJwtPayload = new RedeemJwtPayloadType(
- decodedPayload.sendercommunityuuid as string,
- decodedPayload.sendergradidoid as string,
- decodedPayload.sendername as string,
- decodedPayload.redeemcode as string,
- decodedPayload.amount as string,
- decodedPayload.memo as string,
- decodedPayload.validuntil as string,
- )
- } else {
- // TODO: as long as the verification fails, fallback to simply decoded payload
- verifiedRedeemJwtPayload = redeemJwtPayload
- logger.debug(
- 'TransactionLinkResolver.queryRedeemJwtLink... fallback to decode verifiedRedeemJwtPayload=',
- verifiedRedeemJwtPayload,
- )
}
const homeCommunity = await getHomeCommunity()
if (!homeCommunity) {
- throw new LogError('Home community not found')
+ const errmsg = `Home community not found`
+ logger.error(errmsg)
+ throw new Error(errmsg)
}
const recipientCommunity = new Community(homeCommunity)
const senderCommunity = new Community(senderCom)
@@ -699,10 +703,9 @@ export class TransactionLinkResolver {
logger.debug('TransactionLinkResolver.queryRedeemJwtLink... redeemJwtLink=', redeemJwtLink)
return redeemJwtLink
} else {
- throw new LogError(
- 'Redeem with wrong type of JWT-Token or expired! decodedPayload=',
- decodedPayload,
- )
+ const errmsg = `transfer of redeem JWT with wrong envelope! code=${code}`
+ logger.error(errmsg)
+ throw new Error(errmsg)
}
}
}
diff --git a/backend/src/graphql/resolver/util/communities.ts b/backend/src/graphql/resolver/util/communities.ts
index ee7a0f96d..d1288a1ea 100644
--- a/backend/src/graphql/resolver/util/communities.ts
+++ b/backend/src/graphql/resolver/util/communities.ts
@@ -78,6 +78,11 @@ export async function getCommunityByUuid(communityUuid: string): Promise {
+ return await DbCommunity.findOne({
+ where: [{ publicKey: publicKey }],
+ })
+}
export async function getAuthenticatedCommunities(): Promise {
const dbCommunities: DbCommunity[] = await DbCommunity.find({
diff --git a/shared/src/index.ts b/shared/src/index.ts
index afbe82bce..dd7965fdc 100644
--- a/shared/src/index.ts
+++ b/shared/src/index.ts
@@ -12,4 +12,5 @@ export * from './jwt/payloadtypes/OpenConnectionCallbackJwtPayloadType'
export * from './jwt/payloadtypes/RedeemJwtPayloadType'
export * from './jwt/payloadtypes/SendCoinsJwtPayloadType'
export * from './jwt/payloadtypes/SendCoinsResponseJwtPayloadType'
+export * from './jwt/payloadtypes/SignedTransferPayloadType'
diff --git a/shared/src/jwt/payloadtypes/SignedTransferPayloadType.ts b/shared/src/jwt/payloadtypes/SignedTransferPayloadType.ts
new file mode 100644
index 000000000..26c4235f3
--- /dev/null
+++ b/shared/src/jwt/payloadtypes/SignedTransferPayloadType.ts
@@ -0,0 +1,21 @@
+import { JwtPayloadType } from './JwtPayloadType'
+
+export class SignedTransferPayloadType extends JwtPayloadType {
+ static SIGNED_TRANSFER_TYPE = 'signed-transfer'
+
+ publicKey: string
+ jwt: string
+
+ constructor(
+ publicKey: string,
+ jwt: string,
+ handshakeID: string,
+ ) {
+ // eslint-disable-next-line @typescript-eslint/no-unsafe-call
+ super(handshakeID)
+ // eslint-disable-next-line @typescript-eslint/no-unsafe-assignment
+ this.tokentype = SignedTransferPayloadType.SIGNED_TRANSFER_TYPE
+ this.publicKey = publicKey
+ this.jwt = jwt
+ }
+}
From e1fc80f6bbb1dfc40aa70f69b5eeae0cd0de6cd0 Mon Sep 17 00:00:00 2001
From: clauspeterhuebner
Date: Thu, 28 Aug 2025 19:18:37 +0200
Subject: [PATCH 25/48] search senderCom with publicKey as Buffer(string, hex)
---
backend/src/graphql/resolver/TransactionLinkResolver.ts | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/backend/src/graphql/resolver/TransactionLinkResolver.ts b/backend/src/graphql/resolver/TransactionLinkResolver.ts
index e4d042914..8432ae9d5 100644
--- a/backend/src/graphql/resolver/TransactionLinkResolver.ts
+++ b/backend/src/graphql/resolver/TransactionLinkResolver.ts
@@ -630,7 +630,7 @@ export class TransactionLinkResolver {
decodedPayload.jwt,
decodedPayload.handshakeID)
logger.debug('queryRedeemJwtLink... signedTransferPayload=', signedTransferPayload)
- const senderCom = await getCommunityByPublicKey(Buffer.from(signedTransferPayload.publicKey))
+ const senderCom = await getCommunityByPublicKey(Buffer.from(signedTransferPayload.publicKey, 'hex'))
if (!senderCom) {
const errmsg = `Sender community not found with publicKey=${signedTransferPayload.publicKey}`
logger.error(errmsg)
From 364bb05da813de75ff4267cd8f548304f2a5b90b Mon Sep 17 00:00:00 2001
From: clauspeterhuebner
Date: Fri, 29 Aug 2025 00:49:34 +0200
Subject: [PATCH 26/48] now use the correct senderCom.publicJwtKey to verify
transferredRedeemJwt
---
backend/src/graphql/resolver/TransactionLinkResolver.ts | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/backend/src/graphql/resolver/TransactionLinkResolver.ts b/backend/src/graphql/resolver/TransactionLinkResolver.ts
index 8432ae9d5..f5341d383 100644
--- a/backend/src/graphql/resolver/TransactionLinkResolver.ts
+++ b/backend/src/graphql/resolver/TransactionLinkResolver.ts
@@ -637,7 +637,7 @@ export class TransactionLinkResolver {
throw new Error(errmsg)
}
logger.debug('queryRedeemJwtLink... senderCom=', senderCom)
- const verifiedJwtPayload = await verify(signedTransferPayload.handshakeID, signedTransferPayload.jwt, signedTransferPayload.publicKey) as SignedTransferPayloadType
+ const verifiedJwtPayload = await verify(signedTransferPayload.handshakeID, signedTransferPayload.jwt, senderCom.publicJwtKey!) as SignedTransferPayloadType
logger.debug('queryRedeemJwtLink... verifiedJwtPayload=', verifiedJwtPayload)
let verifiedRedeemJwtPayload: RedeemJwtPayloadType | null = null
if (verifiedJwtPayload === null) {
From 0c8b233dfd6392e630e26a3ea672904ec23ff1da Mon Sep 17 00:00:00 2001
From: clauspeterhuebner
Date: Fri, 29 Aug 2025 14:32:43 +0200
Subject: [PATCH 27/48] correct result treatment of verifyJwtResult
---
backend/src/graphql/resolver/TransactionLinkResolver.ts | 7 ++++---
1 file changed, 4 insertions(+), 3 deletions(-)
diff --git a/backend/src/graphql/resolver/TransactionLinkResolver.ts b/backend/src/graphql/resolver/TransactionLinkResolver.ts
index f5341d383..80a5e94d3 100644
--- a/backend/src/graphql/resolver/TransactionLinkResolver.ts
+++ b/backend/src/graphql/resolver/TransactionLinkResolver.ts
@@ -637,14 +637,15 @@ export class TransactionLinkResolver {
throw new Error(errmsg)
}
logger.debug('queryRedeemJwtLink... senderCom=', senderCom)
- const verifiedJwtPayload = await verify(signedTransferPayload.handshakeID, signedTransferPayload.jwt, senderCom.publicJwtKey!) as SignedTransferPayloadType
- logger.debug('queryRedeemJwtLink... verifiedJwtPayload=', verifiedJwtPayload)
+ const verifiedJwtResult = await verify(signedTransferPayload.handshakeID, signedTransferPayload.jwt, senderCom.publicJwtKey!)
+ logger.debug('queryRedeemJwtLink... verifiedJwtResult=', verifiedJwtResult)
let verifiedRedeemJwtPayload: RedeemJwtPayloadType | null = null
- if (verifiedJwtPayload === null) {
+ if (verifiedJwtResult === null) {
const errmsg = `Error on verify transferred redeem token with publicKey=${signedTransferPayload.publicKey}`
logger.error(errmsg)
throw new Error(errmsg)
} else {
+ const verifiedJwtPayload = verifiedJwtResult.payload as SignedTransferPayloadType
const encryptedTransferArgs = new EncryptedTransferArgs()
encryptedTransferArgs.publicKey = verifiedJwtPayload.publicKey
encryptedTransferArgs.jwt = verifiedJwtPayload.jwt
From d5c7f036c47877ddd6eb128b9f3224e4d8e25263 Mon Sep 17 00:00:00 2001
From: clauspeterhuebner
Date: Fri, 29 Aug 2025 15:02:36 +0200
Subject: [PATCH 28/48] next try
---
backend/src/graphql/resolver/TransactionLinkResolver.ts | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/backend/src/graphql/resolver/TransactionLinkResolver.ts b/backend/src/graphql/resolver/TransactionLinkResolver.ts
index 80a5e94d3..68dec8279 100644
--- a/backend/src/graphql/resolver/TransactionLinkResolver.ts
+++ b/backend/src/graphql/resolver/TransactionLinkResolver.ts
@@ -153,7 +153,7 @@ export class TransactionLinkResolver {
@Query(() => QueryLinkResult)
async queryTransactionLink(@Arg('code') code: string): Promise {
const methodLogger = createLogger('queryTransactionLink')
- methodLogger.addContext('code', code.substring(0, 6))
+ methodLogger.addContext('handshakeID', randombytes_random().toString())
methodLogger.debug('queryTransactionLink...')
if (code.match(/^CL-/)) {
const contributionLink = await DbContributionLink.findOneOrFail({
From 4857852f8d45a62dc339c379959a848d55d4f20d Mon Sep 17 00:00:00 2001
From: clauspeterhuebner
Date: Mon, 1 Sep 2025 16:55:20 +0200
Subject: [PATCH 29/48] next try to queryRedeemJwtLink
---
.../graphql/resolver/TransactionLinkResolver.ts | 15 ++++++++++-----
1 file changed, 10 insertions(+), 5 deletions(-)
diff --git a/backend/src/graphql/resolver/TransactionLinkResolver.ts b/backend/src/graphql/resolver/TransactionLinkResolver.ts
index 68dec8279..1e0a06bfb 100644
--- a/backend/src/graphql/resolver/TransactionLinkResolver.ts
+++ b/backend/src/graphql/resolver/TransactionLinkResolver.ts
@@ -36,7 +36,7 @@ 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, decode, DisburseJwtPayloadType, encode, encryptAndSign, RedeemJwtPayloadType, verify } from 'shared'
+import { calculateDecay, decode, DisburseJwtPayloadType, encode, encryptAndSign, EncryptedJWEJwtPayloadType, RedeemJwtPayloadType, verify } from 'shared'
import { LOG4JS_BASE_CATEGORY_NAME } from '@/config/const'
import { DisbursementClient as V1_0_DisbursementClient } from '@/federation/client/1_0/DisbursementClient'
@@ -624,6 +624,8 @@ export class TransactionLinkResolver {
// 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.addContext('handshakeID', decodedPayload.handshakeID)
if(decodedPayload !== null && decodedPayload.tokentype === SignedTransferPayloadType.SIGNED_TRANSFER_TYPE) {
const signedTransferPayload = new SignedTransferPayloadType(
decodedPayload.publicKey,
@@ -637,15 +639,18 @@ export class TransactionLinkResolver {
throw new Error(errmsg)
}
logger.debug('queryRedeemJwtLink... senderCom=', senderCom)
- const verifiedJwtResult = await verify(signedTransferPayload.handshakeID, signedTransferPayload.jwt, senderCom.publicJwtKey!)
- logger.debug('queryRedeemJwtLink... verifiedJwtResult=', verifiedJwtResult)
+ const jweVerifyResult = await verify(signedTransferPayload.handshakeID, signedTransferPayload.jwt, senderCom.publicJwtKey!)
+ logger.debug('queryRedeemJwtLink... jweVerifyResult=', jweVerifyResult)
let verifiedRedeemJwtPayload: RedeemJwtPayloadType | null = null
- if (verifiedJwtResult === null) {
+ if (jweVerifyResult === null) {
const errmsg = `Error on verify transferred redeem token with publicKey=${signedTransferPayload.publicKey}`
logger.error(errmsg)
throw new Error(errmsg)
} else {
- const verifiedJwtPayload = verifiedJwtResult.payload as SignedTransferPayloadType
+ const jwePayload = jweVerifyResult.payload as EncryptedJWEJwtPayloadType
+ logger.debug('queryRedeemJwtLink... jwePayload=', jwePayload)
+ const verifiedJwtPayload = jweVerifyResult.payload as SignedTransferPayloadType
+ logger.debug('queryRedeemJwtLink... verifiedJwtPayload=', verifiedJwtPayload)
const encryptedTransferArgs = new EncryptedTransferArgs()
encryptedTransferArgs.publicKey = verifiedJwtPayload.publicKey
encryptedTransferArgs.jwt = verifiedJwtPayload.jwt
From 5e21df03857bee65b74f96ef1d840967cac115cd Mon Sep 17 00:00:00 2001
From: clauspeterhuebner
Date: Mon, 1 Sep 2025 17:13:59 +0200
Subject: [PATCH 30/48] correct initialization of EncryptedTransferArgs
---
.../src/graphql/resolver/TransactionLinkResolver.ts | 12 ++++--------
1 file changed, 4 insertions(+), 8 deletions(-)
diff --git a/backend/src/graphql/resolver/TransactionLinkResolver.ts b/backend/src/graphql/resolver/TransactionLinkResolver.ts
index 1e0a06bfb..eb7e0be16 100644
--- a/backend/src/graphql/resolver/TransactionLinkResolver.ts
+++ b/backend/src/graphql/resolver/TransactionLinkResolver.ts
@@ -647,21 +647,17 @@ export class TransactionLinkResolver {
logger.error(errmsg)
throw new Error(errmsg)
} else {
- const jwePayload = jweVerifyResult.payload as EncryptedJWEJwtPayloadType
- logger.debug('queryRedeemJwtLink... jwePayload=', jwePayload)
- const verifiedJwtPayload = jweVerifyResult.payload as SignedTransferPayloadType
- logger.debug('queryRedeemJwtLink... verifiedJwtPayload=', verifiedJwtPayload)
const encryptedTransferArgs = new EncryptedTransferArgs()
- encryptedTransferArgs.publicKey = verifiedJwtPayload.publicKey
- encryptedTransferArgs.jwt = verifiedJwtPayload.jwt
- encryptedTransferArgs.handshakeID = verifiedJwtPayload.handshakeID
+ encryptedTransferArgs.publicKey = signedTransferPayload.publicKey
+ encryptedTransferArgs.jwt = signedTransferPayload.jwt
+ encryptedTransferArgs.handshakeID = signedTransferPayload.handshakeID
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` + verifiedJwtPayload.publicKey
+ const errmsg = `invalid authentication payload of requesting community with publicKey` + signedTransferPayload.publicKey
logger.error(errmsg)
throw new Error(errmsg)
}
From 3dada669ddd31e5dc3a5b789c4aa325dfcb61704 Mon Sep 17 00:00:00 2001
From: clauspeterhuebner
Date: Mon, 1 Sep 2025 17:32:34 +0200
Subject: [PATCH 31/48] correct check on token type
---
backend/src/graphql/resolver/TransactionLinkResolver.ts | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/backend/src/graphql/resolver/TransactionLinkResolver.ts b/backend/src/graphql/resolver/TransactionLinkResolver.ts
index eb7e0be16..99668d724 100644
--- a/backend/src/graphql/resolver/TransactionLinkResolver.ts
+++ b/backend/src/graphql/resolver/TransactionLinkResolver.ts
@@ -661,7 +661,7 @@ export class TransactionLinkResolver {
logger.error(errmsg)
throw new Error(errmsg)
}
- if (verifiedRedeemJwtPayload.tokentype === RedeemJwtPayloadType.REDEEM_ACTIVATION_TYPE) {
+ if (verifiedRedeemJwtPayload.tokentype !== 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)
From d2ad847d2221b92e03c462daf781c37604122f0e Mon Sep 17 00:00:00 2001
From: clauspeterhuebner
Date: Wed, 3 Sep 2025 15:21:56 +0200
Subject: [PATCH 32/48] add logoutput for testing
---
.../LinkInformations/RedeemCommunitySelection.vue | 9 +++++++--
1 file changed, 7 insertions(+), 2 deletions(-)
diff --git a/frontend/src/components/LinkInformations/RedeemCommunitySelection.vue b/frontend/src/components/LinkInformations/RedeemCommunitySelection.vue
index 46e9eb81f..0739ce33c 100644
--- a/frontend/src/components/LinkInformations/RedeemCommunitySelection.vue
+++ b/frontend/src/components/LinkInformations/RedeemCommunitySelection.vue
@@ -167,14 +167,19 @@ async function onSwitch(event) {
alias: props.linkData.senderUser?.alias,
validUntil: props.linkData.validUntil,
})
- // console.log('RedeemCommunitySelection.onSwitch... response=', data)
+ console.log('RedeemCommunitySelection.onSwitch... response=', data)
if (!data?.createRedeemJwt) {
throw new Error('Failed to get redeem token')
}
const targetUrl = currentRecipientCommunity.value.url.replace(/\/api\/?$/, '')
+ console.log('RedeemCommunitySelection.onSwitch... targetUrl=', targetUrl)
+ console.log(
+ 'RedeemCommunitySelection.onSwitch... data.createRedeemJwt=',
+ data.createRedeemJwt,
+ )
window.location.href = targetUrl + '/redeem/' + data.createRedeemJwt
} catch (error) {
- // console.error('RedeemCommunitySelection.onSwitch error:', error)
+ console.error('RedeemCommunitySelection.onSwitch error:', error)
throw error
}
}
From eb7e2ad57918e8762609019ec0d4ffa46dee75fb Mon Sep 17 00:00:00 2001
From: clauspeterhuebner
Date: Wed, 3 Sep 2025 15:41:11 +0200
Subject: [PATCH 33/48] other logoutput for testings
---
.../RedeemCommunitySelection.vue | 9 +-
frontend/src/pages/TransactionLink.vue | 179 +++++++++---------
2 files changed, 90 insertions(+), 98 deletions(-)
diff --git a/frontend/src/components/LinkInformations/RedeemCommunitySelection.vue b/frontend/src/components/LinkInformations/RedeemCommunitySelection.vue
index 0739ce33c..46e9eb81f 100644
--- a/frontend/src/components/LinkInformations/RedeemCommunitySelection.vue
+++ b/frontend/src/components/LinkInformations/RedeemCommunitySelection.vue
@@ -167,19 +167,14 @@ async function onSwitch(event) {
alias: props.linkData.senderUser?.alias,
validUntil: props.linkData.validUntil,
})
- console.log('RedeemCommunitySelection.onSwitch... response=', data)
+ // console.log('RedeemCommunitySelection.onSwitch... response=', data)
if (!data?.createRedeemJwt) {
throw new Error('Failed to get redeem token')
}
const targetUrl = currentRecipientCommunity.value.url.replace(/\/api\/?$/, '')
- console.log('RedeemCommunitySelection.onSwitch... targetUrl=', targetUrl)
- console.log(
- 'RedeemCommunitySelection.onSwitch... data.createRedeemJwt=',
- data.createRedeemJwt,
- )
window.location.href = targetUrl + '/redeem/' + data.createRedeemJwt
} catch (error) {
- console.error('RedeemCommunitySelection.onSwitch error:', error)
+ // console.error('RedeemCommunitySelection.onSwitch error:', error)
throw error
}
}
diff --git a/frontend/src/pages/TransactionLink.vue b/frontend/src/pages/TransactionLink.vue
index 285625882..edf46bd58 100644
--- a/frontend/src/pages/TransactionLink.vue
+++ b/frontend/src/pages/TransactionLink.vue
@@ -116,8 +116,8 @@ const tokenExpiresInSeconds = computed(() => {
})
const validLink = computed(() => {
- // console.log('TransactionLink.validLink... linkData.value.validUntil=', linkData.value.validUntil)
- // console.log('TransactionLink.validLink... new Date()=', new Date())
+ console.log('TransactionLink.validLink... linkData.value.validUntil=', linkData.value.validUntil)
+ console.log('TransactionLink.validLink... new Date()=', new Date())
if (!isTransactionLinkLoaded.value) {
return false
}
@@ -125,46 +125,46 @@ const validLink = computed(() => {
return false
}
const validUntilDate = new Date(linkData.value.validUntil)
- // console.log('TransactionLink.validLink... validUntilDate=', validUntilDate)
- // console.log('TransactionLink.validLink... new Date()=', new Date())
- // console.log(
- // 'TransactionLink.validLink... validUntilDate.getTime() >= new Date().getTime()=',
- // validUntilDate.getTime() >= new Date().getTime(),
- // )
+ console.log('TransactionLink.validLink... validUntilDate=', validUntilDate)
+ console.log('TransactionLink.validLink... new Date()=', new Date())
+ console.log(
+ 'TransactionLink.validLink... validUntilDate.getTime() >= new Date().getTime()=',
+ validUntilDate.getTime() >= new Date().getTime(),
+ )
return validUntilDate.getTime() >= new Date().getTime()
})
const itemType = computed(() => {
- // console.log('TransactionLink.itemType... isTransactionLinkLoaded=', isTransactionLinkLoaded.value)
+ console.log('TransactionLink.itemType... isTransactionLinkLoaded=', isTransactionLinkLoaded.value)
if (isTransactionLinkLoaded.value) {
- // console.log('TransactionLink.itemType... linkData.value=', linkData.value)
+ console.log('TransactionLink.itemType... linkData.value=', linkData.value)
if (linkData.value.deletedAt) {
- // console.log('TransactionLink.itemType... TEXT_DELETED')
+ console.log('TransactionLink.itemType... TEXT_DELETED')
return 'TEXT_DELETED'
}
const validUntilDate = new Date(linkData.value.validUntil)
- // console.log('TransactionLink.itemType... validUntilDate=', validUntilDate)
- // console.log('TransactionLink.itemType... new Date()=', new Date())
- // console.log(
- // 'TransactionLink.itemType... validUntilDate.getTime() < new Date().getTime()=',
- // validUntilDate.getTime() < new Date().getTime(),
- // )
+ console.log('TransactionLink.itemType... validUntilDate=', validUntilDate)
+ console.log('TransactionLink.itemType... new Date()=', new Date())
+ console.log(
+ 'TransactionLink.itemType... validUntilDate.getTime() < new Date().getTime()=',
+ validUntilDate.getTime() < new Date().getTime(),
+ )
if (validUntilDate.getTime() < new Date().getTime()) {
- // console.log('TransactionLink.itemType... TEXT_EXPIRED')
+ console.log('TransactionLink.itemType... TEXT_EXPIRED')
return 'TEXT_EXPIRED'
}
if (linkData.value.redeemedAt) {
- // console.log('TransactionLink.itemType... TEXT_REDEEMED')
+ console.log('TransactionLink.itemType... TEXT_REDEEMED')
return 'TEXT_REDEEMED'
}
if (linkData.value.deletedAt) {
- // console.log('TransactionLink.itemType... TEXT_DELETED')
+ console.log('TransactionLink.itemType... TEXT_DELETED')
return 'TEXT_DELETED'
}
if (store.state.token && store.state.tokenTime) {
if (tokenExpiresInSeconds.value < 5) {
- // console.log('TransactionLink.itemType... REDEEM_SELECT_COMMUNITY')
+ console.log('TransactionLink.itemType... REDEEM_SELECT_COMMUNITY')
if (CONFIG.CROSS_TX_REDEEM_LINK_ACTIVE) {
return 'REDEEM_SELECT_COMMUNITY'
} else {
@@ -172,28 +172,28 @@ const itemType = computed(() => {
}
}
}
- // console.log(
- // 'TransactionLink.itemType... linkData.value.recipientUser=',
- // linkData.value.recipientUser,
- // )
- // console.log('TransactionLink.itemType... linkData.value=', linkData.value)
- // console.log('TransactionLink.itemType... store.state.gradidoID=', store.state.gradidoID)
- // console.log('TransactionLink.itemType... isRedeemJwtLink=', isRedeemJwtLink.value)
- // console.log('TransactionLink.itemType... linkData.value.senderUser=', linkData.value.senderUser)
- // console.log(
- // 'TransactionLink.itemType... linkData.value.recipientUser.gradidoID=',
- // linkData.value.recipientUser?.gradidoID,
- // )
- // console.log(
- // 'TransactionLink.itemType... linkData.value.senderUser.gradidoID=',
- // linkData.value.senderUser?.gradidoID,
- // )
+ console.log(
+ 'TransactionLink.itemType... linkData.value.recipientUser=',
+ linkData.value.recipientUser,
+ )
+ console.log('TransactionLink.itemType... linkData.value=', linkData.value)
+ console.log('TransactionLink.itemType... store.state.gradidoID=', store.state.gradidoID)
+ console.log('TransactionLink.itemType... isRedeemJwtLink=', isRedeemJwtLink.value)
+ console.log('TransactionLink.itemType... linkData.value.senderUser=', linkData.value.senderUser)
+ console.log(
+ 'TransactionLink.itemType... linkData.value.recipientUser.gradidoID=',
+ linkData.value.recipientUser?.gradidoID,
+ )
+ console.log(
+ 'TransactionLink.itemType... linkData.value.senderUser.gradidoID=',
+ linkData.value.senderUser?.gradidoID,
+ )
if (
linkData.value.senderUser &&
linkData.value.recipientUser &&
linkData.value.senderUser.gradidoID === linkData.value.recipientUser.gradidoID
) {
- // console.log('TransactionLink.itemType... SELF_CREATOR')
+ console.log('TransactionLink.itemType... SELF_CREATOR')
return 'SELF_CREATOR'
}
if (
@@ -202,22 +202,22 @@ const itemType = computed(() => {
linkData.value.senderUser.gradidoID !== linkData.value.recipientUser.gradidoID &&
store.state.gradidoID === linkData.value.recipientUser.gradidoID
) {
- // console.log('TransactionLink.itemType... VALID')
- // console.log('TransactionLink.itemType... linkData.value=', linkData.value)
- // console.log('TransactionLink.itemType... store.state.gradidoID=', store.state.gradidoID)
- // console.log(
- // 'TransactionLink.itemType... linkData.value.recipientUser.gradidoID=',
- // linkData.value.recipientUser.gradidoID,
- // )
- // console.log(
- // 'TransactionLink.itemType... linkData.value.senderUser.gradidoID=',
- // linkData.value.senderUser.gradidoID,
- // )
+ console.log('TransactionLink.itemType... VALID')
+ console.log('TransactionLink.itemType... linkData.value=', linkData.value)
+ console.log('TransactionLink.itemType... store.state.gradidoID=', store.state.gradidoID)
+ console.log(
+ 'TransactionLink.itemType... linkData.value.recipientUser.gradidoID=',
+ linkData.value.recipientUser.gradidoID,
+ )
+ console.log(
+ 'TransactionLink.itemType... linkData.value.senderUser.gradidoID=',
+ linkData.value.senderUser.gradidoID,
+ )
return 'VALID'
}
}
if (CONFIG.CROSS_TX_REDEEM_LINK_ACTIVE) {
- // console.log('TransactionLink.itemType...last return= REDEEM_SELECT_COMMUNITY')
+ console.log('TransactionLink.itemType...last return= REDEEM_SELECT_COMMUNITY')
return 'REDEEM_SELECT_COMMUNITY'
} else {
return 'LOGGED_OUT'
@@ -225,8 +225,8 @@ const itemType = computed(() => {
})
const itemTypeExt = computed(() => {
- // console.log('TransactionLink.itemTypeExt... itemType=', itemType.value)
- // console.log('TransactionLink.itemTypeExt... validLink=', validLink.value)
+ console.log('TransactionLink.itemTypeExt... itemType=', itemType.value)
+ console.log('TransactionLink.itemTypeExt... validLink=', validLink.value)
if (itemType.value.startsWith('TEXT')) {
return 'TEXT'
}
@@ -234,13 +234,13 @@ const itemTypeExt = computed(() => {
})
watch(itemType, (newItemType) => {
- // console.log('TransactionLink.watch... itemType=', itemType.value)
- // console.log('TransactionLink.watch... validLink=', validLink.value)
+ console.log('TransactionLink.watch... itemType=', itemType.value)
+ console.log('TransactionLink.watch... validLink=', validLink.value)
updateRedeemedBoxText(newItemType)
})
function updateRedeemedBoxText(type) {
- // console.log('TransactionLink.updateRedeemedBoxText... type=', type)
+ console.log('TransactionLink.updateRedeemedBoxText... type=', type)
switch (type) {
case 'TEXT_DELETED':
redeemedBoxText.value = t('gdd_per_link.link-deleted', {
@@ -260,90 +260,87 @@ function updateRedeemedBoxText(type) {
default:
redeemedBoxText.value = ''
}
- // console.log('TransactionLink.updateRedeemedBoxText... redeemedBoxText=', redeemedBoxText)
+ console.log('TransactionLink.updateRedeemedBoxText... redeemedBoxText=', redeemedBoxText)
}
const emit = defineEmits(['set-mobile-start'])
onMounted(() => {
- // console.log('TransactionLink.onMounted... params=', params)
+ console.log('TransactionLink.onMounted... params=', params)
emit('set-mobile-start', false)
})
onResult(() => {
- // console.log('TransactionLink.onResult... result=', result.value)
- // console.log('TransactionLink.onResult... stringify result=', JSON.stringify(result.value))
+ console.log('TransactionLink.onResult... result=', result.value)
+ console.log('TransactionLink.onResult... stringify result=', JSON.stringify(result.value))
if (result.value?.queryTransactionLink?.__typename === 'TransactionLink') {
- // console.log('TransactionLink.onResult... TransactionLink')
+ console.log('TransactionLink.onResult... TransactionLink')
isTransactionLinkLoaded.value = true
setTransactionLinkInformation()
} else if (result.value?.queryTransactionLink?.__typename === 'ContributionLink') {
- // console.log('TransactionLink.onResult... ContributionLink')
+ console.log('TransactionLink.onResult... ContributionLink')
isTransactionLinkLoaded.value = true
setContributionLinkInformation()
} else if (result.value?.queryTransactionLink?.__typename === 'RedeemJwtLink') {
- // console.log('TransactionLink.onResult... RedeemJwtLink')
+ console.log('TransactionLink.onResult... RedeemJwtLink')
isTransactionLinkLoaded.value = true
setRedeemJwtLinkInformation()
} else {
- // console.log('TransactionLink.onResult... unknown type:', result.value)
+ console.log('TransactionLink.onResult... unknown type:', result.value)
}
})
onError(() => {
- // console.log('TransactionLink.onError... error=', error)
+ console.log('TransactionLink.onError... error=', error)
toastError(t('gdd_per_link.redeemlink-error'))
})
function setTransactionLinkInformation() {
- // console.log('TransactionLink.setTransactionLinkInformation... result=', result.value)
+ console.log('TransactionLink.setTransactionLinkInformation... result=', result.value)
// const queryTransactionLink = result.value.queryTransactionLink
const deepCopy = JSON.parse(JSON.stringify(result.value))
- // console.log('TransactionLink.setTransactionLinkInformation... deepCopy=', deepCopy)
+ console.log('TransactionLink.setTransactionLinkInformation... deepCopy=', deepCopy)
if (deepCopy && deepCopy.queryTransactionLink.__typename === 'TransactionLink') {
- // console.log('TransactionLink.setTransactionLinkInformation... typename === TransactionLink')
+ console.log('TransactionLink.setTransactionLinkInformation... typename === TransactionLink')
// recipientUser is only set if the user is logged in
if (store.state.gradidoID !== null) {
- // console.log(
- // 'TransactionLink.setTransactionLinkInformation... gradidoID=',
- // store.state.gradidoID,
- // )
+ console.log(
+ 'TransactionLink.setTransactionLinkInformation... gradidoID=',
+ store.state.gradidoID,
+ )
deepCopy.queryTransactionLink.recipientUser = {
__typename: 'User',
gradidoID: store.state.gradidoID,
firstName: store.state.firstName,
alias: store.state.alias,
}
- // console.log(
- // 'TransactionLink.setTransactionLinkInformation... deepCopy.queryTransactionLink.recipientUser=',
- // deepCopy.queryTransactionLink.recipientUser,
- // )
+ console.log(
+ 'TransactionLink.setTransactionLinkInformation... deepCopy.queryTransactionLink.recipientUser=',
+ deepCopy.queryTransactionLink.recipientUser,
+ )
}
linkData.value = deepCopy.queryTransactionLink
- // console.log('TransactionLink.setTransactionLinkInformation... linkData.value=', linkData.value)
+ console.log('TransactionLink.setTransactionLinkInformation... linkData.value=', linkData.value)
}
}
function setContributionLinkInformation() {
linkData.value = result.value.queryTransactionLink
if (linkData.value.__typename === 'ContributionLink' && store.state.token) {
- // console.log('TransactionLink.setTransactionLinkInformation... typename === ContributionLink')
+ console.log('TransactionLink.setTransactionLinkInformation... typename === ContributionLink')
// explicit no await
mutationLink(linkData.value.amount)
}
}
function setRedeemJwtLinkInformation() {
- // console.log('TransactionLink.setRedeemJwtLinkInformation... result=', result.value)
+ console.log('TransactionLink.setRedeemJwtLinkInformation... result=', result.value)
const deepCopy = JSON.parse(JSON.stringify(result.value))
- // console.log('TransactionLink.setRedeemJwtLinkInformation... deepCopy=', deepCopy)
+ console.log('TransactionLink.setRedeemJwtLinkInformation... deepCopy=', deepCopy)
if (deepCopy) {
// recipientUser is only set if the user is logged in
if (store.state.gradidoID !== null) {
- // console.log(
- // 'TransactionLink.setRedeemJwtLinkInformation... gradidoID=',
- // store.state.gradidoID,
- // )
+ console.log('TransactionLink.setRedeemJwtLinkInformation... gradidoID=', store.state.gradidoID)
deepCopy.queryTransactionLink.recipientUser = {
__typename: 'User',
gradidoID: store.state.gradidoID,
@@ -351,19 +348,19 @@ function setRedeemJwtLinkInformation() {
alias: store.state.alias,
}
}
- // console.log(
- // 'TransactionLink.setRedeemJwtLinkInformation... deepCopy.queryTransactionLink.recipientUser=',
- // deepCopy.queryTransactionLink.recipientUser,
- // )
+ console.log(
+ 'TransactionLink.setRedeemJwtLinkInformation... deepCopy.queryTransactionLink.recipientUser=',
+ deepCopy.queryTransactionLink.recipientUser,
+ )
linkData.value = deepCopy.queryTransactionLink
- // console.log('TransactionLink.setRedeemJwtLinkInformation... linkData.value=', linkData.value)
+ console.log('TransactionLink.setRedeemJwtLinkInformation... linkData.value=', linkData.value)
}
}
async function mutationLink(amount) {
- // console.log('TransactionLink.mutationLink... params=', params)
+ console.log('TransactionLink.mutationLink... params=', params)
if (isRedeemJwtLink.value) {
- // console.log('TransactionLink.mutationLink... trigger disbursement from recipient-community')
+ console.log('TransactionLink.mutationLink... trigger disbursement from recipient-community')
try {
await disburseMutate({
code: params.code,
@@ -375,7 +372,7 @@ async function mutationLink(amount) {
await router.push('/overview')
}
} else {
- // console.log('TransactionLink.mutationLink... local transaction or contribution')
+ console.log('TransactionLink.mutationLink... local transaction or contribution')
try {
await redeemMutate({
code: redeemCode.value,
From 50b45a79bffa49a49dcf66a76f4828a450c0e9e2 Mon Sep 17 00:00:00 2001
From: clauspeterhuebner
Date: Wed, 3 Sep 2025 16:09:47 +0200
Subject: [PATCH 34/48] more logoutput for tests
---
frontend/src/pages/TransactionLink.vue | 2 ++
1 file changed, 2 insertions(+)
diff --git a/frontend/src/pages/TransactionLink.vue b/frontend/src/pages/TransactionLink.vue
index edf46bd58..e6da36121 100644
--- a/frontend/src/pages/TransactionLink.vue
+++ b/frontend/src/pages/TransactionLink.vue
@@ -359,6 +359,8 @@ function setRedeemJwtLinkInformation() {
async function mutationLink(amount) {
console.log('TransactionLink.mutationLink... params=', params)
+ console.log('TransactionLink.mutationLink... linkData.value=', linkData.value)
+ console.log('TransactionLink.mutationLink... linkData=', linkData)
if (isRedeemJwtLink.value) {
console.log('TransactionLink.mutationLink... trigger disbursement from recipient-community')
try {
From 9318d173289c5586f7c3bb3db794275db9690646 Mon Sep 17 00:00:00 2001
From: clauspeterhuebner
Date: Wed, 3 Sep 2025 16:34:59 +0200
Subject: [PATCH 35/48] correct parameters for invokation of disburseMutation
---
frontend/src/pages/TransactionLink.vue | 12 +++++++++++-
1 file changed, 11 insertions(+), 1 deletion(-)
diff --git a/frontend/src/pages/TransactionLink.vue b/frontend/src/pages/TransactionLink.vue
index e6da36121..60c110553 100644
--- a/frontend/src/pages/TransactionLink.vue
+++ b/frontend/src/pages/TransactionLink.vue
@@ -365,7 +365,17 @@ async function mutationLink(amount) {
console.log('TransactionLink.mutationLink... trigger disbursement from recipient-community')
try {
await disburseMutate({
- code: params.code,
+ senderCommunityUuid: linkData.value.senderCommunity.uuid,
+ senderGradidoId: linkData.value.senderUser.gradidoID,
+ recipientCommunityUuid: linkData.value.recipientCommunity.uuid,
+ recipientCommunityName: linkData.value.recipientCommunity.name,
+ recipientGradidoId: linkData.value.recipientUser.gradidoID,
+ recipientFirstName: linkData.value.recipientUser.firstName,
+ code: linkData.value.code,
+ amount: linkData.value.amount,
+ memo: linkData.value.memo,
+ validUntil: linkData.value.validUntil,
+ recipientAlias: linkData.value.recipientUser.alias,
})
toastSuccess(t('gdd_per_link.disbured', { n: amount }))
await router.push('/overview')
From be51e3709292e8ea70409c509d0a482cf4016890 Mon Sep 17 00:00:00 2001
From: clauspeterhuebner
Date: Wed, 3 Sep 2025 17:01:50 +0200
Subject: [PATCH 36/48] remove loggers and export DisbursementResolver
---
federation/src/graphql/api/1_0/schema.ts | 3 +-
frontend/src/pages/TransactionLink.vue | 178 +++++++++++------------
2 files changed, 91 insertions(+), 90 deletions(-)
diff --git a/federation/src/graphql/api/1_0/schema.ts b/federation/src/graphql/api/1_0/schema.ts
index 7b88fba5c..fcb05c803 100644
--- a/federation/src/graphql/api/1_0/schema.ts
+++ b/federation/src/graphql/api/1_0/schema.ts
@@ -1,9 +1,10 @@
import { NonEmptyArray } from 'type-graphql'
import { AuthenticationResolver } from './resolver/AuthenticationResolver'
+import { DisbursementResolver } from './resolver/DisbursementResolver'
import { PublicCommunityInfoResolver } from './resolver/PublicCommunityInfoResolver'
import { PublicKeyResolver } from './resolver/PublicKeyResolver'
import { SendCoinsResolver } from './resolver/SendCoinsResolver'
export const getApiResolvers = (): NonEmptyArray => {
- return [AuthenticationResolver, PublicCommunityInfoResolver, PublicKeyResolver, SendCoinsResolver]
+ return [AuthenticationResolver, DisbursementResolver, PublicCommunityInfoResolver, PublicKeyResolver, SendCoinsResolver]
}
diff --git a/frontend/src/pages/TransactionLink.vue b/frontend/src/pages/TransactionLink.vue
index 60c110553..2e81d8913 100644
--- a/frontend/src/pages/TransactionLink.vue
+++ b/frontend/src/pages/TransactionLink.vue
@@ -116,8 +116,8 @@ const tokenExpiresInSeconds = computed(() => {
})
const validLink = computed(() => {
- console.log('TransactionLink.validLink... linkData.value.validUntil=', linkData.value.validUntil)
- console.log('TransactionLink.validLink... new Date()=', new Date())
+ // console.log('TransactionLink.validLink... linkData.value.validUntil=', linkData.value.validUntil)
+ // console.log('TransactionLink.validLink... new Date()=', new Date())
if (!isTransactionLinkLoaded.value) {
return false
}
@@ -125,46 +125,46 @@ const validLink = computed(() => {
return false
}
const validUntilDate = new Date(linkData.value.validUntil)
- console.log('TransactionLink.validLink... validUntilDate=', validUntilDate)
- console.log('TransactionLink.validLink... new Date()=', new Date())
- console.log(
- 'TransactionLink.validLink... validUntilDate.getTime() >= new Date().getTime()=',
- validUntilDate.getTime() >= new Date().getTime(),
- )
+ // console.log('TransactionLink.validLink... validUntilDate=', validUntilDate)
+ // console.log('TransactionLink.validLink... new Date()=', new Date())
+ // console.log(
+ // 'TransactionLink.validLink... validUntilDate.getTime() >= new Date().getTime()=',
+ // validUntilDate.getTime() >= new Date().getTime(),
+ // )
return validUntilDate.getTime() >= new Date().getTime()
})
const itemType = computed(() => {
- console.log('TransactionLink.itemType... isTransactionLinkLoaded=', isTransactionLinkLoaded.value)
+ // console.log('TransactionLink.itemType... isTransactionLinkLoaded=', isTransactionLinkLoaded.value)
if (isTransactionLinkLoaded.value) {
- console.log('TransactionLink.itemType... linkData.value=', linkData.value)
+ // console.log('TransactionLink.itemType... linkData.value=', linkData.value)
if (linkData.value.deletedAt) {
- console.log('TransactionLink.itemType... TEXT_DELETED')
+ // console.log('TransactionLink.itemType... TEXT_DELETED')
return 'TEXT_DELETED'
}
const validUntilDate = new Date(linkData.value.validUntil)
- console.log('TransactionLink.itemType... validUntilDate=', validUntilDate)
- console.log('TransactionLink.itemType... new Date()=', new Date())
- console.log(
- 'TransactionLink.itemType... validUntilDate.getTime() < new Date().getTime()=',
- validUntilDate.getTime() < new Date().getTime(),
- )
+ // console.log('TransactionLink.itemType... validUntilDate=', validUntilDate)
+ // console.log('TransactionLink.itemType... new Date()=', new Date())
+ // console.log(
+ // 'TransactionLink.itemType... validUntilDate.getTime() < new Date().getTime()=',
+ // validUntilDate.getTime() < new Date().getTime(),
+ // )
if (validUntilDate.getTime() < new Date().getTime()) {
console.log('TransactionLink.itemType... TEXT_EXPIRED')
return 'TEXT_EXPIRED'
}
if (linkData.value.redeemedAt) {
- console.log('TransactionLink.itemType... TEXT_REDEEMED')
+ // console.log('TransactionLink.itemType... TEXT_REDEEMED')
return 'TEXT_REDEEMED'
}
if (linkData.value.deletedAt) {
- console.log('TransactionLink.itemType... TEXT_DELETED')
+ // console.log('TransactionLink.itemType... TEXT_DELETED')
return 'TEXT_DELETED'
}
if (store.state.token && store.state.tokenTime) {
if (tokenExpiresInSeconds.value < 5) {
- console.log('TransactionLink.itemType... REDEEM_SELECT_COMMUNITY')
+ // console.log('TransactionLink.itemType... REDEEM_SELECT_COMMUNITY')
if (CONFIG.CROSS_TX_REDEEM_LINK_ACTIVE) {
return 'REDEEM_SELECT_COMMUNITY'
} else {
@@ -172,28 +172,28 @@ const itemType = computed(() => {
}
}
}
- console.log(
- 'TransactionLink.itemType... linkData.value.recipientUser=',
- linkData.value.recipientUser,
- )
- console.log('TransactionLink.itemType... linkData.value=', linkData.value)
- console.log('TransactionLink.itemType... store.state.gradidoID=', store.state.gradidoID)
- console.log('TransactionLink.itemType... isRedeemJwtLink=', isRedeemJwtLink.value)
- console.log('TransactionLink.itemType... linkData.value.senderUser=', linkData.value.senderUser)
- console.log(
- 'TransactionLink.itemType... linkData.value.recipientUser.gradidoID=',
- linkData.value.recipientUser?.gradidoID,
- )
- console.log(
- 'TransactionLink.itemType... linkData.value.senderUser.gradidoID=',
- linkData.value.senderUser?.gradidoID,
- )
+ // console.log(
+ // 'TransactionLink.itemType... linkData.value.recipientUser=',
+ // linkData.value.recipientUser,
+ // )
+ // console.log('TransactionLink.itemType... linkData.value=', linkData.value)
+ // console.log('TransactionLink.itemType... store.state.gradidoID=', store.state.gradidoID)
+ // console.log('TransactionLink.itemType... isRedeemJwtLink=', isRedeemJwtLink.value)
+ // console.log('TransactionLink.itemType... linkData.value.senderUser=', linkData.value.senderUser)
+ // console.log(
+ // 'TransactionLink.itemType... linkData.value.recipientUser.gradidoID=',
+ // linkData.value.recipientUser?.gradidoID,
+ // )
+ // console.log(
+ // 'TransactionLink.itemType... linkData.value.senderUser.gradidoID=',
+ // linkData.value.senderUser?.gradidoID,
+ // )
if (
linkData.value.senderUser &&
linkData.value.recipientUser &&
linkData.value.senderUser.gradidoID === linkData.value.recipientUser.gradidoID
) {
- console.log('TransactionLink.itemType... SELF_CREATOR')
+ // console.log('TransactionLink.itemType... SELF_CREATOR')
return 'SELF_CREATOR'
}
if (
@@ -202,22 +202,22 @@ const itemType = computed(() => {
linkData.value.senderUser.gradidoID !== linkData.value.recipientUser.gradidoID &&
store.state.gradidoID === linkData.value.recipientUser.gradidoID
) {
- console.log('TransactionLink.itemType... VALID')
- console.log('TransactionLink.itemType... linkData.value=', linkData.value)
- console.log('TransactionLink.itemType... store.state.gradidoID=', store.state.gradidoID)
- console.log(
- 'TransactionLink.itemType... linkData.value.recipientUser.gradidoID=',
- linkData.value.recipientUser.gradidoID,
- )
- console.log(
- 'TransactionLink.itemType... linkData.value.senderUser.gradidoID=',
- linkData.value.senderUser.gradidoID,
- )
+ // console.log('TransactionLink.itemType... VALID')
+ // console.log('TransactionLink.itemType... linkData.value=', linkData.value)
+ // console.log('TransactionLink.itemType... store.state.gradidoID=', store.state.gradidoID)
+ // console.log(
+ // 'TransactionLink.itemType... linkData.value.recipientUser.gradidoID=',
+ // linkData.value.recipientUser.gradidoID,
+ // )
+ // console.log(
+ // 'TransactionLink.itemType... linkData.value.senderUser.gradidoID=',
+ // linkData.value.senderUser.gradidoID,
+ // )
return 'VALID'
}
}
if (CONFIG.CROSS_TX_REDEEM_LINK_ACTIVE) {
- console.log('TransactionLink.itemType...last return= REDEEM_SELECT_COMMUNITY')
+ // console.log('TransactionLink.itemType...last return= REDEEM_SELECT_COMMUNITY')
return 'REDEEM_SELECT_COMMUNITY'
} else {
return 'LOGGED_OUT'
@@ -225,8 +225,8 @@ const itemType = computed(() => {
})
const itemTypeExt = computed(() => {
- console.log('TransactionLink.itemTypeExt... itemType=', itemType.value)
- console.log('TransactionLink.itemTypeExt... validLink=', validLink.value)
+ // console.log('TransactionLink.itemTypeExt... itemType=', itemType.value)
+ // console.log('TransactionLink.itemTypeExt... validLink=', validLink.value)
if (itemType.value.startsWith('TEXT')) {
return 'TEXT'
}
@@ -234,13 +234,13 @@ const itemTypeExt = computed(() => {
})
watch(itemType, (newItemType) => {
- console.log('TransactionLink.watch... itemType=', itemType.value)
- console.log('TransactionLink.watch... validLink=', validLink.value)
+ // console.log('TransactionLink.watch... itemType=', itemType.value)
+ // console.log('TransactionLink.watch... validLink=', validLink.value)
updateRedeemedBoxText(newItemType)
})
function updateRedeemedBoxText(type) {
- console.log('TransactionLink.updateRedeemedBoxText... type=', type)
+ // console.log('TransactionLink.updateRedeemedBoxText... type=', type)
switch (type) {
case 'TEXT_DELETED':
redeemedBoxText.value = t('gdd_per_link.link-deleted', {
@@ -260,87 +260,87 @@ function updateRedeemedBoxText(type) {
default:
redeemedBoxText.value = ''
}
- console.log('TransactionLink.updateRedeemedBoxText... redeemedBoxText=', redeemedBoxText)
+ // console.log('TransactionLink.updateRedeemedBoxText... redeemedBoxText=', redeemedBoxText)
}
const emit = defineEmits(['set-mobile-start'])
onMounted(() => {
- console.log('TransactionLink.onMounted... params=', params)
+ // console.log('TransactionLink.onMounted... params=', params)
emit('set-mobile-start', false)
})
onResult(() => {
- console.log('TransactionLink.onResult... result=', result.value)
- console.log('TransactionLink.onResult... stringify result=', JSON.stringify(result.value))
+ // console.log('TransactionLink.onResult... result=', result.value)
+ // console.log('TransactionLink.onResult... stringify result=', JSON.stringify(result.value))
if (result.value?.queryTransactionLink?.__typename === 'TransactionLink') {
- console.log('TransactionLink.onResult... TransactionLink')
+ // console.log('TransactionLink.onResult... TransactionLink')
isTransactionLinkLoaded.value = true
setTransactionLinkInformation()
} else if (result.value?.queryTransactionLink?.__typename === 'ContributionLink') {
- console.log('TransactionLink.onResult... ContributionLink')
+ // console.log('TransactionLink.onResult... ContributionLink')
isTransactionLinkLoaded.value = true
setContributionLinkInformation()
} else if (result.value?.queryTransactionLink?.__typename === 'RedeemJwtLink') {
- console.log('TransactionLink.onResult... RedeemJwtLink')
+ // console.log('TransactionLink.onResult... RedeemJwtLink')
isTransactionLinkLoaded.value = true
setRedeemJwtLinkInformation()
} else {
- console.log('TransactionLink.onResult... unknown type:', result.value)
+ // console.log('TransactionLink.onResult... unknown type:', result.value)
}
})
onError(() => {
- console.log('TransactionLink.onError... error=', error)
+ // console.log('TransactionLink.onError... error=', error)
toastError(t('gdd_per_link.redeemlink-error'))
})
function setTransactionLinkInformation() {
- console.log('TransactionLink.setTransactionLinkInformation... result=', result.value)
+ // console.log('TransactionLink.setTransactionLinkInformation... result=', result.value)
// const queryTransactionLink = result.value.queryTransactionLink
const deepCopy = JSON.parse(JSON.stringify(result.value))
- console.log('TransactionLink.setTransactionLinkInformation... deepCopy=', deepCopy)
+ // console.log('TransactionLink.setTransactionLinkInformation... deepCopy=', deepCopy)
if (deepCopy && deepCopy.queryTransactionLink.__typename === 'TransactionLink') {
- console.log('TransactionLink.setTransactionLinkInformation... typename === TransactionLink')
+ // console.log('TransactionLink.setTransactionLinkInformation... typename === TransactionLink')
// recipientUser is only set if the user is logged in
if (store.state.gradidoID !== null) {
- console.log(
- 'TransactionLink.setTransactionLinkInformation... gradidoID=',
- store.state.gradidoID,
- )
+ // console.log(
+ // 'TransactionLink.setTransactionLinkInformation... gradidoID=',
+ // store.state.gradidoID,
+ // )
deepCopy.queryTransactionLink.recipientUser = {
__typename: 'User',
gradidoID: store.state.gradidoID,
firstName: store.state.firstName,
alias: store.state.alias,
}
- console.log(
- 'TransactionLink.setTransactionLinkInformation... deepCopy.queryTransactionLink.recipientUser=',
- deepCopy.queryTransactionLink.recipientUser,
- )
+ // console.log(
+ // 'TransactionLink.setTransactionLinkInformation... deepCopy.queryTransactionLink.recipientUser=',
+ // deepCopy.queryTransactionLink.recipientUser,
+ // )
}
linkData.value = deepCopy.queryTransactionLink
- console.log('TransactionLink.setTransactionLinkInformation... linkData.value=', linkData.value)
+ // console.log('TransactionLink.setTransactionLinkInformation... linkData.value=', linkData.value)
}
}
function setContributionLinkInformation() {
linkData.value = result.value.queryTransactionLink
if (linkData.value.__typename === 'ContributionLink' && store.state.token) {
- console.log('TransactionLink.setTransactionLinkInformation... typename === ContributionLink')
+ // console.log('TransactionLink.setTransactionLinkInformation... typename === ContributionLink')
// explicit no await
mutationLink(linkData.value.amount)
}
}
function setRedeemJwtLinkInformation() {
- console.log('TransactionLink.setRedeemJwtLinkInformation... result=', result.value)
+ // console.log('TransactionLink.setRedeemJwtLinkInformation... result=', result.value)
const deepCopy = JSON.parse(JSON.stringify(result.value))
- console.log('TransactionLink.setRedeemJwtLinkInformation... deepCopy=', deepCopy)
+ // console.log('TransactionLink.setRedeemJwtLinkInformation... deepCopy=', deepCopy)
if (deepCopy) {
// recipientUser is only set if the user is logged in
if (store.state.gradidoID !== null) {
- console.log('TransactionLink.setRedeemJwtLinkInformation... gradidoID=', store.state.gradidoID)
+ // console.log('TransactionLink.setRedeemJwtLinkInformation... gradidoID=', store.state.gradidoID)
deepCopy.queryTransactionLink.recipientUser = {
__typename: 'User',
gradidoID: store.state.gradidoID,
@@ -348,21 +348,21 @@ function setRedeemJwtLinkInformation() {
alias: store.state.alias,
}
}
- console.log(
- 'TransactionLink.setRedeemJwtLinkInformation... deepCopy.queryTransactionLink.recipientUser=',
- deepCopy.queryTransactionLink.recipientUser,
- )
+ // console.log(
+ // 'TransactionLink.setRedeemJwtLinkInformation... deepCopy.queryTransactionLink.recipientUser=',
+ // deepCopy.queryTransactionLink.recipientUser,
+ // )
linkData.value = deepCopy.queryTransactionLink
- console.log('TransactionLink.setRedeemJwtLinkInformation... linkData.value=', linkData.value)
+ // console.log('TransactionLink.setRedeemJwtLinkInformation... linkData.value=', linkData.value)
}
}
async function mutationLink(amount) {
- console.log('TransactionLink.mutationLink... params=', params)
- console.log('TransactionLink.mutationLink... linkData.value=', linkData.value)
- console.log('TransactionLink.mutationLink... linkData=', linkData)
+ // console.log('TransactionLink.mutationLink... params=', params)
+ // console.log('TransactionLink.mutationLink... linkData.value=', linkData.value)
+ // console.log('TransactionLink.mutationLink... linkData=', linkData)
if (isRedeemJwtLink.value) {
- console.log('TransactionLink.mutationLink... trigger disbursement from recipient-community')
+ // console.log('TransactionLink.mutationLink... trigger disbursement from recipient-community')
try {
await disburseMutate({
senderCommunityUuid: linkData.value.senderCommunity.uuid,
@@ -384,7 +384,7 @@ async function mutationLink(amount) {
await router.push('/overview')
}
} else {
- console.log('TransactionLink.mutationLink... local transaction or contribution')
+ // console.log('TransactionLink.mutationLink... local transaction or contribution')
try {
await redeemMutate({
code: redeemCode.value,
From 881e78dfd55f8f355336bbd241a9bc05a9a42bf1 Mon Sep 17 00:00:00 2001
From: clauspeterhuebner
Date: Wed, 3 Sep 2025 17:36:27 +0200
Subject: [PATCH 37/48] correct publicKey in DisbursementRequest of
EncryptedTransferArgs
---
backend/src/graphql/resolver/TransactionLinkResolver.ts | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/backend/src/graphql/resolver/TransactionLinkResolver.ts b/backend/src/graphql/resolver/TransactionLinkResolver.ts
index 99668d724..4ddd082d2 100644
--- a/backend/src/graphql/resolver/TransactionLinkResolver.ts
+++ b/backend/src/graphql/resolver/TransactionLinkResolver.ts
@@ -565,7 +565,7 @@ export class TransactionLinkResolver {
methodLogger.debug('jws=', jws)
}
const args = new EncryptedTransferArgs()
- args.publicKey = senderCom.publicKey.toString('hex')
+ args.publicKey = recipientCom.publicKey.toString('hex')
args.jwt = jws
args.handshakeID = handshakeID
try {
From d92b9c81e72f9f40573f2b7c3542fc341a9939bd Mon Sep 17 00:00:00 2001
From: clauspeterhuebner
Date: Wed, 3 Sep 2025 18:42:30 +0200
Subject: [PATCH 38/48] remove console.log
---
frontend/src/pages/TransactionLink.vue | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/frontend/src/pages/TransactionLink.vue b/frontend/src/pages/TransactionLink.vue
index 2e81d8913..53a742313 100644
--- a/frontend/src/pages/TransactionLink.vue
+++ b/frontend/src/pages/TransactionLink.vue
@@ -151,7 +151,7 @@ const itemType = computed(() => {
// validUntilDate.getTime() < new Date().getTime(),
// )
if (validUntilDate.getTime() < new Date().getTime()) {
- console.log('TransactionLink.itemType... TEXT_EXPIRED')
+ // console.log('TransactionLink.itemType... TEXT_EXPIRED')
return 'TEXT_EXPIRED'
}
if (linkData.value.redeemedAt) {
From 29809bf9839f0852e94cae6530f70609bbf39875 Mon Sep 17 00:00:00 2001
From: clauspeterhuebner
Date: Wed, 3 Sep 2025 22:05:36 +0200
Subject: [PATCH 39/48] remove inactive code
---
.../graphql/resolver/TransactionResolver.ts | 74 -------------------
1 file changed, 74 deletions(-)
diff --git a/backend/src/graphql/resolver/TransactionResolver.ts b/backend/src/graphql/resolver/TransactionResolver.ts
index 2ef7b69ff..c9d68de35 100644
--- a/backend/src/graphql/resolver/TransactionResolver.ts
+++ b/backend/src/graphql/resolver/TransactionResolver.ts
@@ -467,80 +467,6 @@ export class TransactionResolver {
amount.valueOf(),
memo,
)
- /*
- // processing a x-community sendCoins
- logger.info('X-Com: processing a x-community transaction...')
- if (!CONFIG.FEDERATION_XCOM_SENDCOINS_ENABLED) {
- throw new LogError('X-Community sendCoins disabled per configuration!')
- }
- const recipCom = await getCommunityByIdentifier(recipientCommunityIdentifier)
- logger.debug('recipient community: ', recipCom?.id)
- if (recipCom === null) {
- throw new LogError(
- `no recipient community found for identifier: ${recipientCommunityIdentifier}`,
- )
- }
- if (recipCom !== null && recipCom.authenticatedAt === null) {
- throw new LogError('recipient community is connected, but still not authenticated yet!')
- }
- let pendingResult: SendCoinsResponseJwtPayloadType | null = null
- let committingResult: SendCoinsResult
- const creationDate = new Date()
-
- try {
- pendingResult = await processXComPendingSendCoins(
- recipCom,
- homeCom,
- creationDate,
- amount,
- memo,
- senderUser,
- recipientIdentifier,
- )
- logger.debug('processXComPendingSendCoins result: ', pendingResult)
- if (pendingResult && pendingResult.vote && pendingResult.recipGradidoID) {
- logger.debug('vor processXComCommittingSendCoins... ')
- committingResult = await processXComCommittingSendCoins(
- recipCom,
- homeCom,
- creationDate,
- amount,
- memo,
- senderUser,
- pendingResult,
- )
- logger.debug('processXComCommittingSendCoins result: ', committingResult)
- if (!committingResult.vote) {
- logger.fatal('FATAL ERROR: on processXComCommittingSendCoins for', committingResult)
- throw new LogError(
- 'FATAL ERROR: on processXComCommittingSendCoins with ',
- recipientCommunityIdentifier,
- recipientIdentifier,
- amount.toString(),
- memo,
- )
- }
- // after successful x-com-tx store the recipient as foreign user
- logger.debug('store recipient as foreign user...')
- if (await storeForeignUser(recipCom, committingResult)) {
- logger.info(
- 'X-Com: new foreign user inserted successfully...',
- recipCom.communityUuid,
- committingResult.recipGradidoID,
- )
- }
- }
- } catch (err) {
- throw new LogError(
- 'ERROR: on processXComCommittingSendCoins with ',
- recipientCommunityIdentifier,
- recipientIdentifier,
- amount.toString(),
- memo,
- err,
- )
- }
- */
}
return true
}
From 951e92f88a837d0d95c51aece800c644abbf580f Mon Sep 17 00:00:00 2001
From: clauspeterhuebner
Date: Wed, 3 Sep 2025 22:47:40 +0200
Subject: [PATCH 40/48] increase timeouts
---
e2e-tests/cypress.config.ts | 4 ++--
1 file changed, 2 insertions(+), 2 deletions(-)
diff --git a/e2e-tests/cypress.config.ts b/e2e-tests/cypress.config.ts
index b182e7f32..254640e81 100644
--- a/e2e-tests/cypress.config.ts
+++ b/e2e-tests/cypress.config.ts
@@ -35,8 +35,8 @@ export default defineConfig({
excludeSpecPattern: '*.js',
baseUrl: 'http://127.0.0.1:3000',
chromeWebSecurity: false,
- defaultCommandTimeout: 25000,
- pageLoadTimeout: 24000,
+ defaultCommandTimeout: 50000,
+ pageLoadTimeout: 32000,
supportFile: 'cypress/support/index.ts',
viewportHeight: 720,
viewportWidth: 1280,
From 12b2caa73563e6f641b42a04ab66bb0d58093b25 Mon Sep 17 00:00:00 2001
From: clauspeterhuebner
Date: Fri, 5 Sep 2025 16:35:55 +0200
Subject: [PATCH 41/48] removed federation-config properties from backend,
because of shift to core-modul
---
backend/.env.dist | 2 +-
backend/.env.org | 2 +-
backend/.env.template | 2 +-
backend/src/config/index.ts | 16 ++++++++--------
backend/src/config/schema.ts | 9 +++++----
5 files changed, 16 insertions(+), 15 deletions(-)
diff --git a/backend/.env.dist b/backend/.env.dist
index 8d5ba317c..5794b6130 100644
--- a/backend/.env.dist
+++ b/backend/.env.dist
@@ -63,7 +63,7 @@ WEBHOOK_ELOPAGE_SECRET=secret
# Federation
FEDERATION_VALIDATE_COMMUNITY_TIMER=60000
-FEDERATION_XCOM_SENDCOINS_ENABLED=false
+# FEDERATION_XCOM_SENDCOINS_ENABLED=false
# GMS
# GMS_ACTIVE=true
diff --git a/backend/.env.org b/backend/.env.org
index a0082aab1..2999c5ccc 100644
--- a/backend/.env.org
+++ b/backend/.env.org
@@ -63,7 +63,7 @@ LOG_LEVEL=INFO
# Federation
FEDERATION_VALIDATE_COMMUNITY_TIMER=60000
-FEDERATION_XCOM_SENDCOINS_ENABLED=false
+# FEDERATION_XCOM_SENDCOINS_ENABLED=false
# GMS
# GMS_ACTIVE=true
diff --git a/backend/.env.template b/backend/.env.template
index 6c3867978..ba26f4122 100644
--- a/backend/.env.template
+++ b/backend/.env.template
@@ -63,7 +63,7 @@ WEBHOOK_ELOPAGE_SECRET=$WEBHOOK_ELOPAGE_SECRET
# Federation
FEDERATION_VALIDATE_COMMUNITY_TIMER=$FEDERATION_VALIDATE_COMMUNITY_TIMER
-FEDERATION_XCOM_SENDCOINS_ENABLED=$FEDERATION_XCOM_SENDCOINS_ENABLED
+# FEDERATION_XCOM_SENDCOINS_ENABLED=$FEDERATION_XCOM_SENDCOINS_ENABLED
# GMS
GMS_ACTIVE=$GMS_ACTIVE
diff --git a/backend/src/config/index.ts b/backend/src/config/index.ts
index 9d61c2da4..85b82cc27 100644
--- a/backend/src/config/index.ts
+++ b/backend/src/config/index.ts
@@ -99,19 +99,19 @@ const webhook = {
process.env.APP_SECRET = server.JWT_SECRET
const federation = {
- FEDERATION_BACKEND_SEND_ON_API: process.env.FEDERATION_BACKEND_SEND_ON_API ?? '1_0',
+// FEDERATION_BACKEND_SEND_ON_API: process.env.FEDERATION_BACKEND_SEND_ON_API ?? '1_0',
// ?? operator don't work here as expected
FEDERATION_VALIDATE_COMMUNITY_TIMER: Number(
process.env.FEDERATION_VALIDATE_COMMUNITY_TIMER ?? 60000,
),
- FEDERATION_XCOM_SENDCOINS_ENABLED:
- process.env.FEDERATION_XCOM_SENDCOINS_ENABLED === 'true' || false,
+// FEDERATION_XCOM_SENDCOINS_ENABLED:
+// process.env.FEDERATION_XCOM_SENDCOINS_ENABLED === 'true' || false,
// default value for community-uuid is equal uuid of stage-3
- FEDERATION_XCOM_RECEIVER_COMMUNITY_UUID:
- process.env.FEDERATION_XCOM_RECEIVER_COMMUNITY_UUID ?? '56a55482-909e-46a4-bfa2-cd025e894ebc',
- FEDERATION_XCOM_MAXREPEAT_REVERTSENDCOINS: parseInt(
- process.env.FEDERATION_XCOM_MAXREPEAT_REVERTSENDCOINS ?? '3',
- ),
+// FEDERATION_XCOM_RECEIVER_COMMUNITY_UUID:
+// process.env.FEDERATION_XCOM_RECEIVER_COMMUNITY_UUID ?? '56a55482-909e-46a4-bfa2-cd025e894ebc',
+// FEDERATION_XCOM_MAXREPEAT_REVERTSENDCOINS: parseInt(
+// process.env.FEDERATION_XCOM_MAXREPEAT_REVERTSENDCOINS ?? '3',
+// ),
}
const gms = {
diff --git a/backend/src/config/schema.ts b/backend/src/config/schema.ts
index f305a7488..7baea6c07 100644
--- a/backend/src/config/schema.ts
+++ b/backend/src/config/schema.ts
@@ -208,20 +208,20 @@ export const schema = Joi.object({
.default(10)
.description('Time in minutes before a new code can be requested')
.required(),
-
+/*
FEDERATION_BACKEND_SEND_ON_API: Joi.string()
.pattern(/^\d+_\d+$/)
.default('1_0')
.description('API Version of sending requests to another communities, e.g., "1_0"')
.required(),
-
+*/
FEDERATION_VALIDATE_COMMUNITY_TIMER: Joi.number()
.integer()
.min(1000)
.default(60000)
.description('Timer interval in milliseconds for community validation')
.required(),
-
+/*
FEDERATION_XCOM_SENDCOINS_ENABLED: Joi.boolean()
.default(false)
.description('Enable or disable the federation send coins feature')
@@ -235,12 +235,13 @@ export const schema = Joi.object({
)
.required(),
- FEDERATION_XCOM_MAXREPEAT_REVERTSENDCOINS: Joi.number()
+ FEDERATION_XCOM_MAXREPEAT_REVERTSENDCOINS: Joi.number()
.integer()
.min(0)
.default(3)
.description('Maximum number of retries for reverting send coins transactions')
.required(),
+*/
GMS_CREATE_USER_THROW_ERRORS: Joi.boolean()
.default(false)
From 1ef2505c030fcf5efcaeb5d888d270219b2da4dd Mon Sep 17 00:00:00 2001
From: clauspeterhuebner
Date: Fri, 5 Sep 2025 16:41:57 +0200
Subject: [PATCH 42/48] correct config core export and usage
---
backend/src/federation/authenticateCommunities.ts | 4 ++--
core/src/index.ts | 2 ++
2 files changed, 4 insertions(+), 2 deletions(-)
diff --git a/backend/src/federation/authenticateCommunities.ts b/backend/src/federation/authenticateCommunities.ts
index 179c7e996..ad2d91469 100644
--- a/backend/src/federation/authenticateCommunities.ts
+++ b/backend/src/federation/authenticateCommunities.ts
@@ -1,7 +1,7 @@
import { CommunityLoggingView, Community as DbCommunity, FederatedCommunity as DbFederatedCommunity, FederatedCommunityLoggingView, getHomeCommunity } from 'database'
import { validate as validateUUID, version as versionUUID } from 'uuid'
import { randombytes_random } from 'sodium-native'
-import { CONFIG } from '@/config'
+import { CONFIG as CONFIG_CORE } from 'core'
import { AuthenticationClient as V1_0_AuthenticationClient } from '@/federation/client/1_0/AuthenticationClient'
import { ensureUrlEndsWithSlash } from 'core'
@@ -27,7 +27,7 @@ export async function startCommunityAuthentication(
methodLogger.debug('homeComA', new CommunityLoggingView(homeComA!))
const homeFedComA = await DbFederatedCommunity.findOneByOrFail({
foreign: false,
- apiVersion: CONFIG.FEDERATION_BACKEND_SEND_ON_API,
+ apiVersion: CONFIG_CORE.FEDERATION_BACKEND_SEND_ON_API,
})
methodLogger.debug('homeFedComA', new FederatedCommunityLoggingView(homeFedComA))
const comB = await DbCommunity.findOneByOrFail({ publicKey: fedComB.publicKey })
diff --git a/core/src/index.ts b/core/src/index.ts
index 85042ef0b..a355bb9bd 100644
--- a/core/src/index.ts
+++ b/core/src/index.ts
@@ -21,3 +21,5 @@ export * from './graphql/model/EncryptedTransferArgs'
export * from './util/calculateSenderBalance'
export * from './util/utilities'
export * from './validation/user'
+export * from './config/index'
+
From 0b973ee2e12cda90a7256d57e562b696939d0a7a Mon Sep 17 00:00:00 2001
From: clauspeterhuebner
Date: Fri, 5 Sep 2025 16:45:24 +0200
Subject: [PATCH 43/48] remove inactive code
---
backend/.env.dist | 1 -
backend/.env.org | 1 -
backend/.env.template | 1 -
backend/src/config/index.ts | 10 ----------
backend/src/config/schema.ts | 31 ++-----------------------------
5 files changed, 2 insertions(+), 42 deletions(-)
diff --git a/backend/.env.dist b/backend/.env.dist
index 5794b6130..133ba5554 100644
--- a/backend/.env.dist
+++ b/backend/.env.dist
@@ -63,7 +63,6 @@ WEBHOOK_ELOPAGE_SECRET=secret
# Federation
FEDERATION_VALIDATE_COMMUNITY_TIMER=60000
-# FEDERATION_XCOM_SENDCOINS_ENABLED=false
# GMS
# GMS_ACTIVE=true
diff --git a/backend/.env.org b/backend/.env.org
index 2999c5ccc..2267fdc50 100644
--- a/backend/.env.org
+++ b/backend/.env.org
@@ -63,7 +63,6 @@ LOG_LEVEL=INFO
# Federation
FEDERATION_VALIDATE_COMMUNITY_TIMER=60000
-# FEDERATION_XCOM_SENDCOINS_ENABLED=false
# GMS
# GMS_ACTIVE=true
diff --git a/backend/.env.template b/backend/.env.template
index ba26f4122..9b0bc7df2 100644
--- a/backend/.env.template
+++ b/backend/.env.template
@@ -63,7 +63,6 @@ WEBHOOK_ELOPAGE_SECRET=$WEBHOOK_ELOPAGE_SECRET
# Federation
FEDERATION_VALIDATE_COMMUNITY_TIMER=$FEDERATION_VALIDATE_COMMUNITY_TIMER
-# FEDERATION_XCOM_SENDCOINS_ENABLED=$FEDERATION_XCOM_SENDCOINS_ENABLED
# GMS
GMS_ACTIVE=$GMS_ACTIVE
diff --git a/backend/src/config/index.ts b/backend/src/config/index.ts
index 85b82cc27..aa0a7dbf2 100644
--- a/backend/src/config/index.ts
+++ b/backend/src/config/index.ts
@@ -99,19 +99,9 @@ const webhook = {
process.env.APP_SECRET = server.JWT_SECRET
const federation = {
-// FEDERATION_BACKEND_SEND_ON_API: process.env.FEDERATION_BACKEND_SEND_ON_API ?? '1_0',
- // ?? operator don't work here as expected
FEDERATION_VALIDATE_COMMUNITY_TIMER: Number(
process.env.FEDERATION_VALIDATE_COMMUNITY_TIMER ?? 60000,
),
-// FEDERATION_XCOM_SENDCOINS_ENABLED:
-// process.env.FEDERATION_XCOM_SENDCOINS_ENABLED === 'true' || false,
- // default value for community-uuid is equal uuid of stage-3
-// FEDERATION_XCOM_RECEIVER_COMMUNITY_UUID:
-// process.env.FEDERATION_XCOM_RECEIVER_COMMUNITY_UUID ?? '56a55482-909e-46a4-bfa2-cd025e894ebc',
-// FEDERATION_XCOM_MAXREPEAT_REVERTSENDCOINS: parseInt(
-// process.env.FEDERATION_XCOM_MAXREPEAT_REVERTSENDCOINS ?? '3',
-// ),
}
const gms = {
diff --git a/backend/src/config/schema.ts b/backend/src/config/schema.ts
index 7baea6c07..144608992 100644
--- a/backend/src/config/schema.ts
+++ b/backend/src/config/schema.ts
@@ -208,40 +208,13 @@ export const schema = Joi.object({
.default(10)
.description('Time in minutes before a new code can be requested')
.required(),
-/*
- FEDERATION_BACKEND_SEND_ON_API: Joi.string()
- .pattern(/^\d+_\d+$/)
- .default('1_0')
- .description('API Version of sending requests to another communities, e.g., "1_0"')
- .required(),
-*/
- FEDERATION_VALIDATE_COMMUNITY_TIMER: Joi.number()
+
+ FEDERATION_VALIDATE_COMMUNITY_TIMER: Joi.number()
.integer()
.min(1000)
.default(60000)
.description('Timer interval in milliseconds for community validation')
.required(),
-/*
- FEDERATION_XCOM_SENDCOINS_ENABLED: Joi.boolean()
- .default(false)
- .description('Enable or disable the federation send coins feature')
- .optional(),
-
- FEDERATION_XCOM_RECEIVER_COMMUNITY_UUID: Joi.string()
- .uuid()
- .default('56a55482-909e-46a4-bfa2-cd025e894ebc')
- .description(
- 'UUID of the receiver community for federation cross-community transactions if the receiver is unknown',
- )
- .required(),
-
- FEDERATION_XCOM_MAXREPEAT_REVERTSENDCOINS: Joi.number()
- .integer()
- .min(0)
- .default(3)
- .description('Maximum number of retries for reverting send coins transactions')
- .required(),
-*/
GMS_CREATE_USER_THROW_ERRORS: Joi.boolean()
.default(false)
From 30e7ecd7d9e788028ffbcf3e563bcf99eab28a54 Mon Sep 17 00:00:00 2001
From: clauspeterhuebner
Date: Fri, 5 Sep 2025 16:49:33 +0200
Subject: [PATCH 44/48] remove eslint command-lines
---
shared/src/jwt/payloadtypes/EncryptedJWEJwtPayloadType.ts | 2 --
.../jwt/payloadtypes/OpenConnectionCallbackJwtPayloadType.ts | 2 --
shared/src/jwt/payloadtypes/OpenConnectionJwtPayloadType.ts | 2 --
shared/src/jwt/payloadtypes/RedeemJwtPayloadType.ts | 2 --
shared/src/jwt/payloadtypes/SendCoinsJwtPayloadType.ts | 2 --
shared/src/jwt/payloadtypes/SendCoinsResponseJwtPayloadType.ts | 2 --
shared/src/jwt/payloadtypes/SignedTransferPayloadType.ts | 2 --
7 files changed, 14 deletions(-)
diff --git a/shared/src/jwt/payloadtypes/EncryptedJWEJwtPayloadType.ts b/shared/src/jwt/payloadtypes/EncryptedJWEJwtPayloadType.ts
index f353d885b..0d6d86476 100644
--- a/shared/src/jwt/payloadtypes/EncryptedJWEJwtPayloadType.ts
+++ b/shared/src/jwt/payloadtypes/EncryptedJWEJwtPayloadType.ts
@@ -9,9 +9,7 @@ export class EncryptedJWEJwtPayloadType extends JwtPayloadType {
handshakeID: string,
jwe: string,
) {
- // eslint-disable-next-line @typescript-eslint/no-unsafe-call
super(handshakeID)
- // eslint-disable-next-line @typescript-eslint/no-unsafe-assignment
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 7b4992284..544e23800 100644
--- a/shared/src/jwt/payloadtypes/OpenConnectionCallbackJwtPayloadType.ts
+++ b/shared/src/jwt/payloadtypes/OpenConnectionCallbackJwtPayloadType.ts
@@ -11,9 +11,7 @@ export class OpenConnectionCallbackJwtPayloadType extends JwtPayloadType {
oneTimeCode: string,
url: string,
) {
- // eslint-disable-next-line @typescript-eslint/no-unsafe-call
super(handshakeID)
- // eslint-disable-next-line @typescript-eslint/no-unsafe-assignment
this.tokentype = OpenConnectionCallbackJwtPayloadType.OPEN_CONNECTION_CALLBACK_TYPE
this.oneTimeCode = oneTimeCode
this.url = url
diff --git a/shared/src/jwt/payloadtypes/OpenConnectionJwtPayloadType.ts b/shared/src/jwt/payloadtypes/OpenConnectionJwtPayloadType.ts
index 3a3c249cb..a9e7e0a5a 100644
--- a/shared/src/jwt/payloadtypes/OpenConnectionJwtPayloadType.ts
+++ b/shared/src/jwt/payloadtypes/OpenConnectionJwtPayloadType.ts
@@ -9,9 +9,7 @@ export class OpenConnectionJwtPayloadType extends JwtPayloadType {
handshakeID: string,
url: string,
) {
- // eslint-disable-next-line @typescript-eslint/no-unsafe-call
super(handshakeID)
- // eslint-disable-next-line @typescript-eslint/no-unsafe-assignment
this.tokentype = OpenConnectionJwtPayloadType.OPEN_CONNECTION_TYPE
this.url = url
}
diff --git a/shared/src/jwt/payloadtypes/RedeemJwtPayloadType.ts b/shared/src/jwt/payloadtypes/RedeemJwtPayloadType.ts
index faeda2b71..841f725e1 100644
--- a/shared/src/jwt/payloadtypes/RedeemJwtPayloadType.ts
+++ b/shared/src/jwt/payloadtypes/RedeemJwtPayloadType.ts
@@ -20,9 +20,7 @@ export class RedeemJwtPayloadType extends JwtPayloadType {
memo: string,
validUntil: string,
) {
- // eslint-disable-next-line @typescript-eslint/no-unsafe-call
super('handshakeID')
- // eslint-disable-next-line @typescript-eslint/no-unsafe-assignment
this.tokentype = RedeemJwtPayloadType.REDEEM_ACTIVATION_TYPE
this.sendercommunityuuid = senderCom
this.sendergradidoid = senderUser
diff --git a/shared/src/jwt/payloadtypes/SendCoinsJwtPayloadType.ts b/shared/src/jwt/payloadtypes/SendCoinsJwtPayloadType.ts
index 6048eb254..833b004fc 100644
--- a/shared/src/jwt/payloadtypes/SendCoinsJwtPayloadType.ts
+++ b/shared/src/jwt/payloadtypes/SendCoinsJwtPayloadType.ts
@@ -26,9 +26,7 @@ export class SendCoinsJwtPayloadType extends JwtPayloadType {
senderUserName: string,
senderAlias?: string | null,
) {
- // eslint-disable-next-line @typescript-eslint/no-unsafe-call
super(handshakeID)
- // eslint-disable-next-line @typescript-eslint/no-unsafe-assignment
this.tokentype = SendCoinsJwtPayloadType.SEND_COINS_TYPE
this.recipientCommunityUuid = recipientCommunityUuid
this.recipientUserIdentifier = recipientUserIdentifier
diff --git a/shared/src/jwt/payloadtypes/SendCoinsResponseJwtPayloadType.ts b/shared/src/jwt/payloadtypes/SendCoinsResponseJwtPayloadType.ts
index e76cf00eb..fb08d6a97 100644
--- a/shared/src/jwt/payloadtypes/SendCoinsResponseJwtPayloadType.ts
+++ b/shared/src/jwt/payloadtypes/SendCoinsResponseJwtPayloadType.ts
@@ -17,9 +17,7 @@ export class SendCoinsResponseJwtPayloadType extends JwtPayloadType {
recipLastName: string | null,
recipAlias: string | null,
) {
- // eslint-disable-next-line @typescript-eslint/no-unsafe-call
super(handshakeID)
- // eslint-disable-next-line @typescript-eslint/no-unsafe-assignment
this.tokentype = SendCoinsResponseJwtPayloadType.SEND_COINS_RESPONSE_TYPE
this.vote = vote
this.recipGradidoID = recipGradidoID
diff --git a/shared/src/jwt/payloadtypes/SignedTransferPayloadType.ts b/shared/src/jwt/payloadtypes/SignedTransferPayloadType.ts
index 26c4235f3..1b3f3a468 100644
--- a/shared/src/jwt/payloadtypes/SignedTransferPayloadType.ts
+++ b/shared/src/jwt/payloadtypes/SignedTransferPayloadType.ts
@@ -11,9 +11,7 @@ export class SignedTransferPayloadType extends JwtPayloadType {
jwt: string,
handshakeID: string,
) {
- // eslint-disable-next-line @typescript-eslint/no-unsafe-call
super(handshakeID)
- // eslint-disable-next-line @typescript-eslint/no-unsafe-assignment
this.tokentype = SignedTransferPayloadType.SIGNED_TRANSFER_TYPE
this.publicKey = publicKey
this.jwt = jwt
From abbfed963e203c1b6c0ce14d42be3a2bcbd205d7 Mon Sep 17 00:00:00 2001
From: clauspeterhuebner
Date: Fri, 5 Sep 2025 17:09:00 +0200
Subject: [PATCH 45/48] camelcase the parameter names of
processXComCompleteTransaction
---
.../src/graphql/logic/processXComSendCoins.ts | 32 +++++++++----------
1 file changed, 16 insertions(+), 16 deletions(-)
diff --git a/core/src/graphql/logic/processXComSendCoins.ts b/core/src/graphql/logic/processXComSendCoins.ts
index dc8e3127f..5b3d6584a 100644
--- a/core/src/graphql/logic/processXComSendCoins.ts
+++ b/core/src/graphql/logic/processXComSendCoins.ts
@@ -35,15 +35,15 @@ import { storeForeignUser } from './storeForeignUser'
const createLogger = (method: string) => getLogger(`${LOG4JS_BASE_CATEGORY_NAME}.graphql.resolver.util.processXComSendCoins.${method}`)
export async function processXComCompleteTransaction(
- sendercommunityuuid: string,
- sendergradidoid: string,
- recipientcommunityuuid: string,
- recipientgradidoid: string,
+ senderCommunityUuid: string,
+ senderGradidoId: string,
+ recipientCommunityUuid: string,
+ recipientGradidoId: string,
amount: string,
memo: string,
code?: string,
- recipientfirstname?: string,
- recipientalias?: string,
+ recipientFirstName?: string,
+ recipientAlias?: string,
creationDate?: Date,
): Promise {
const methodLogger = createLogger(`processXComCompleteTransaction`)
@@ -54,23 +54,23 @@ export async function processXComCompleteTransaction(
methodLogger.error(errmsg)
throw new Error(errmsg)
}
- const senderCom = await getCommunityByUuid(sendercommunityuuid)
+ const senderCom = await getCommunityByUuid(senderCommunityUuid)
methodLogger.debug('sender community: ', senderCom?.id)
if (senderCom === null) {
- const errmsg = `no sender community found for identifier: ${sendercommunityuuid}`
+ const errmsg = `no sender community found for identifier: ${senderCommunityUuid}`
methodLogger.error(errmsg)
throw new Error(errmsg)
}
- const senderUser = await findUserByIdentifier(sendergradidoid, sendercommunityuuid)
+ const senderUser = await findUserByIdentifier(senderGradidoId, senderCommunityUuid)
if (senderUser === null) {
- const errmsg = `no sender user found for identifier: ${sendercommunityuuid}:${sendergradidoid}`
+ const errmsg = `no sender user found for identifier: ${senderCommunityUuid}:${senderGradidoId}`
methodLogger.error(errmsg)
throw new Error(errmsg)
}
- const recipientCom = await getCommunityByUuid(recipientcommunityuuid)
+ const recipientCom = await getCommunityByUuid(recipientCommunityUuid)
methodLogger.debug('recipient community: ', recipientCom?.id)
if (recipientCom === null) {
- const errmsg = `no recipient community found for identifier: ${recipientcommunityuuid}`
+ const errmsg = `no recipient community found for identifier: ${recipientCommunityUuid}`
methodLogger.error(errmsg)
throw new Error(errmsg)
}
@@ -107,7 +107,7 @@ export async function processXComCompleteTransaction(
new Decimal(amount),
memo,
senderUser,
- recipientgradidoid,
+ recipientGradidoId,
)
methodLogger.debug('processXComPendingSendCoins result: ', pendingResult)
if (pendingResult && pendingResult.vote && pendingResult.recipGradidoID) {
@@ -127,7 +127,7 @@ export async function processXComCompleteTransaction(
throw new Error(
'FATAL ERROR: on processXComCommittingSendCoins with ' +
recipientCom.communityUuid +
- recipientgradidoid +
+ recipientGradidoId +
amount.toString() +
memo,
)
@@ -144,8 +144,8 @@ export async function processXComCompleteTransaction(
}
} catch (err) {
const errmsg = `ERROR: on processXComCommittingSendCoins with ` +
- recipientcommunityuuid +
- recipientgradidoid +
+ recipientCommunityUuid +
+ recipientGradidoId +
amount.toString() +
memo +
err
From 42007418b1d08ce1dfc97ec026e231bcb20a3aa4 Mon Sep 17 00:00:00 2001
From: clauspeterhuebner
Date: Fri, 5 Sep 2025 17:57:21 +0200
Subject: [PATCH 46/48] use getCommunityByUuid
---
backend/src/graphql/resolver/TransactionLinkResolver.ts | 4 ++--
1 file changed, 2 insertions(+), 2 deletions(-)
diff --git a/backend/src/graphql/resolver/TransactionLinkResolver.ts b/backend/src/graphql/resolver/TransactionLinkResolver.ts
index 4ddd082d2..8acbd7b53 100644
--- a/backend/src/graphql/resolver/TransactionLinkResolver.ts
+++ b/backend/src/graphql/resolver/TransactionLinkResolver.ts
@@ -523,7 +523,7 @@ export class TransactionLinkResolver {
recipientAlias,
})
}
- const senderCom = await DbCommunity.findOneBy({ communityUuid: senderCommunityUuid })
+ const senderCom = await getCommunityByUuid(senderCommunityUuid)
if (!senderCom) {
const errmsg = `Sender community not found with uuid=${senderCommunityUuid}`
methodLogger.error(errmsg)
@@ -535,7 +535,7 @@ export class TransactionLinkResolver {
methodLogger.error(errmsg)
throw new LogError(errmsg)
}
- const recipientCom = await DbCommunity.findOneBy({ communityUuid: recipientCommunityUuid })
+ const recipientCom = await getCommunityByUuid(recipientCommunityUuid)
if (!recipientCom) {
const errmsg = `Recipient community not found with uuid=${recipientCommunityUuid}`
methodLogger.error(errmsg)
From b96cbd064caf8dfd436ee7025345d92f0c7e314b Mon Sep 17 00:00:00 2001
From: clauspeterhuebner
Date: Fri, 5 Sep 2025 18:02:45 +0200
Subject: [PATCH 47/48] removed unused configs
---
core/tsconfig.json | 11 ++---------
1 file changed, 2 insertions(+), 9 deletions(-)
diff --git a/core/tsconfig.json b/core/tsconfig.json
index c30aab30d..b8e0f1d0a 100644
--- a/core/tsconfig.json
+++ b/core/tsconfig.json
@@ -44,15 +44,8 @@
/* Module Resolution Options */
// "moduleResolution": "node", /* Specify module resolution strategy: 'node' (Node.js) or 'classic' (TypeScript pre-1.6). */
- "baseUrl": ".", /* Base directory to resolve non-absolute module names. */
- "paths": { /* A series of entries which re-map imports to lookup locations relative to the 'baseUrl'. */
- "@/*": ["src/*"],
- "@config/*": ["src/config/*"],
- "@federation/*": ["src/federation/*"],
- "@graphql/*": ["src/graphql/*"],
- "@util/*": ["src/util/*"],
- "@validation/*": ["src/validation/*"]
- },
+ // "baseUrl": ".", /* Base directory to resolve non-absolute module names. */
+ // "paths": { }, /* A series of entries which re-map imports to lookup locations relative to the 'baseUrl'. */
// "rootDirs": [".", "../database"], /* List of root folders whose combined content represents the structure of the project at runtime. */
// "typeRoots": [], /* List of folders to include type definitions from. */
// "types": ["bun-types"], /* Type declaration files to be included in compilation. */
From 2f43f37a420968abe3ebafa3da6e3895d4b8a1de Mon Sep 17 00:00:00 2001
From: clauspeterhuebner
Date: Fri, 5 Sep 2025 18:31:12 +0200
Subject: [PATCH 48/48] reinserted the porperty
FEDERATION_XCOM_SENDCOINS_ENABLED
---
backend/.env.dist | 1 +
1 file changed, 1 insertion(+)
diff --git a/backend/.env.dist b/backend/.env.dist
index 133ba5554..8d5ba317c 100644
--- a/backend/.env.dist
+++ b/backend/.env.dist
@@ -63,6 +63,7 @@ WEBHOOK_ELOPAGE_SECRET=secret
# Federation
FEDERATION_VALIDATE_COMMUNITY_TIMER=60000
+FEDERATION_XCOM_SENDCOINS_ENABLED=false
# GMS
# GMS_ACTIVE=true