From 6e5fb223d655d22bd9bedaa41518ee002f17ed76 Mon Sep 17 00:00:00 2001 From: clauspeterhuebner Date: Wed, 20 Aug 2025 16:26:02 +0200 Subject: [PATCH] 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