From 05c28573c06403d0ebe7ce347950007b033f2743 Mon Sep 17 00:00:00 2001
From: clauspeterhuebner
Date: Tue, 5 Aug 2025 16:48:46 +0200
Subject: [PATCH] tests of x-cross-tx per sendcoins now with security
---
.../logic/interpretEncryptedTransferArgs.ts | 6 +-
.../1_0/resolver/SendCoinsResolver.test.ts | 722 ++++++++++--------
.../api/1_0/resolver/SendCoinsResolver.ts | 22 +-
3 files changed, 418 insertions(+), 332 deletions(-)
diff --git a/core/src/graphql/logic/interpretEncryptedTransferArgs.ts b/core/src/graphql/logic/interpretEncryptedTransferArgs.ts
index b5b2f7f7a..0d522bff7 100644
--- a/core/src/graphql/logic/interpretEncryptedTransferArgs.ts
+++ b/core/src/graphql/logic/interpretEncryptedTransferArgs.ts
@@ -15,13 +15,13 @@ export const interpretEncryptedTransferArgs = async (args: EncryptedTransferArgs
// first find with args.publicKey the community 'requestingCom', which starts the request
const requestingCom = await DbCommunity.findOneBy({ publicKey: Buffer.from(args.publicKey, 'hex') })
if (!requestingCom) {
- const errmsg = `unknown requesting community with publicKey ${args.publicKey}`
+ const errmsg = `unknown requesting community with publicKey ${Buffer.from(args.publicKey, 'hex')}`
methodLogger.error(errmsg)
methodLogger.removeContext('handshakeID')
throw new Error(errmsg)
}
if (!requestingCom.publicJwtKey) {
- const errmsg = `missing publicJwtKey of requesting community with publicKey ${args.publicKey}`
+ const errmsg = `missing publicJwtKey of requesting community with publicKey ${Buffer.from(args.publicKey, 'hex')}`
methodLogger.error(errmsg)
methodLogger.removeContext('handshakeID')
throw new Error(errmsg)
@@ -31,7 +31,7 @@ export const interpretEncryptedTransferArgs = async (args: EncryptedTransferArgs
const homeCom = await getHomeCommunity()
const jwtPayload = await verifyAndDecrypt(args.handshakeID, args.jwt, homeCom!.privateJwtKey!, requestingCom.publicJwtKey) as JwtPayloadType
if (!jwtPayload) {
- const errmsg = `invalid payload of community with publicKey ${args.publicKey}`
+ const errmsg = `invalid payload of community with publicKey ${Buffer.from(args.publicKey, 'hex')}`
methodLogger.error(errmsg)
methodLogger.removeContext('handshakeID')
throw new Error(errmsg)
diff --git a/federation/src/graphql/api/1_0/resolver/SendCoinsResolver.test.ts b/federation/src/graphql/api/1_0/resolver/SendCoinsResolver.test.ts
index 5ba55f88a..d0417cb40 100644
--- a/federation/src/graphql/api/1_0/resolver/SendCoinsResolver.test.ts
+++ b/federation/src/graphql/api/1_0/resolver/SendCoinsResolver.test.ts
@@ -8,8 +8,8 @@ import Decimal from 'decimal.js-light'
import { GraphQLError } from 'graphql'
import { getLogger } from 'log4js'
import { DataSource } from 'typeorm'
-import { SendCoinsArgs } from '../model/SendCoinsArgs'
-
+import { EncryptedTransferArgs } from 'core'
+import { createKeyPair, encryptAndSign, SendCoinsJwtPayloadType, SendCoinsResponseJwtPayloadType, verifyAndDecrypt } from 'shared'
let mutate: ApolloServerTestClient['mutate'] // , con: Connection
// let query: ApolloServerTestClient['query']
@@ -21,8 +21,8 @@ let testEnv: {
CONFIG.FEDERATION_API = '1_0'
-let homeCom: DbCommunity
-let foreignCom: DbCommunity
+let recipientCom: DbCommunity
+let senderCom: DbCommunity
let sendUser: DbUser
let sendContact: DbUserContact
let recipUser: DbUser
@@ -37,7 +37,7 @@ beforeAll(async () => {
})
afterAll(async () => {
- // await cleanDB()
+ await cleanDB()
if (testEnv.con?.isInitialized) {
await testEnv.con.destroy()
}
@@ -45,53 +45,54 @@ afterAll(async () => {
describe('SendCoinsResolver', () => {
const voteForSendCoinsMutation = `
- mutation ($args: SendCoinsArgs!) {
- voteForSendCoins(data: $args) {
- vote
- recipGradidoID
- recipFirstName
- recipLastName
- recipAlias
- }
+ mutation ($args: EncryptedTransferArgs!) {
+ voteForSendCoins(data: $args)
}`
const settleSendCoinsMutation = `
- mutation ($args: SendCoinsArgs!) {
+ mutation ($args: EncryptedTransferArgs!) {
settleSendCoins(data: $args)
}`
const revertSendCoinsMutation = `
- mutation ($args: SendCoinsArgs!) {
+ mutation ($args: EncryptedTransferArgs!) {
revertSendCoins(data: $args)
}`
const revertSettledSendCoinsMutation = `
- mutation ($args: SendCoinsArgs!) {
+ mutation ($args: EncryptedTransferArgs!) {
revertSettledSendCoins(data: $args)
}`
beforeEach(async () => {
await cleanDB()
- homeCom = DbCommunity.create()
- homeCom.foreign = false
- homeCom.url = 'homeCom-url'
- homeCom.name = 'homeCom-Name'
- homeCom.description = 'homeCom-Description'
- homeCom.creationDate = new Date()
- homeCom.publicKey = Buffer.from('homeCom-publicKey')
- homeCom.communityUuid = '56a55482-909e-46a4-bfa2-cd025e894eba'
- await DbCommunity.insert(homeCom)
+ // Generate key pair using jose library
+ const { publicKey: homePublicKey, privateKey: homePrivateKey } = await createKeyPair();
+ recipientCom = DbCommunity.create()
+ recipientCom.foreign = false
+ recipientCom.url = 'homeCom-url'
+ recipientCom.name = 'homeCom-Name'
+ recipientCom.description = 'homeCom-Description'
+ recipientCom.creationDate = new Date()
+ recipientCom.publicKey = Buffer.alloc(32, '15F92F8EC2EA685D5FD51EE3588F5B4805EBD330EF9EDD16043F3BA9C35C0D91', 'hex') // 'homeCom-publicKey', 'hex')
+ recipientCom.publicJwtKey = homePublicKey;
+ recipientCom.privateJwtKey = homePrivateKey;
+ recipientCom.communityUuid = '56a55482-909e-46a4-bfa2-cd025e894eba'
+ await DbCommunity.insert(recipientCom)
- foreignCom = DbCommunity.create()
- foreignCom.foreign = true
- foreignCom.url = 'foreignCom-url'
- foreignCom.name = 'foreignCom-Name'
- foreignCom.description = 'foreignCom-Description'
- foreignCom.creationDate = new Date()
- foreignCom.publicKey = Buffer.from('foreignCom-publicKey')
- foreignCom.communityUuid = '56a55482-909e-46a4-bfa2-cd025e894ebb'
- await DbCommunity.insert(foreignCom)
+ const { publicKey: foreignPublicKey, privateKey: foreignPrivateKey } = await createKeyPair();
+ senderCom = DbCommunity.create()
+ senderCom.foreign = true
+ senderCom.url = 'foreignCom-url'
+ senderCom.name = 'foreignCom-Name'
+ senderCom.description = 'foreignCom-Description'
+ senderCom.creationDate = new Date()
+ senderCom.publicKey = Buffer.alloc(32, '15F92F8EC2EA685D5FD51EE3588F5B4805EBD330EF9EDD16043F3BA9C35C0D92', 'hex') // 'foreignCom-publicKey', 'hex')
+ senderCom.publicJwtKey = foreignPublicKey;
+ senderCom.privateJwtKey = foreignPrivateKey;
+ senderCom.communityUuid = '56a55482-909e-46a4-bfa2-cd025e894ebb'
+ await DbCommunity.insert(senderCom)
sendUser = DbUser.create()
sendUser.alias = 'sendUser-alias'
- sendUser.communityUuid = '56a55482-909e-46a4-bfa2-cd025e894eba'
+ sendUser.communityUuid = '56a55482-909e-46a4-bfa2-cd025e894ebb'
sendUser.firstName = 'sendUser-FirstName'
sendUser.gradidoID = '56a55482-909e-46a4-bfa2-cd025e894ebc'
sendUser.lastName = 'sendUser-LastName'
@@ -106,7 +107,7 @@ describe('SendCoinsResolver', () => {
recipUser = DbUser.create()
recipUser.alias = 'recipUser-alias'
- recipUser.communityUuid = '56a55482-909e-46a4-bfa2-cd025e894ebb'
+ recipUser.communityUuid = '56a55482-909e-46a4-bfa2-cd025e894eba'
recipUser.firstName = 'recipUser-FirstName'
recipUser.gradidoID = '56a55482-909e-46a4-bfa2-cd025e894ebd'
recipUser.lastName = 'recipUser-LastName'
@@ -120,30 +121,37 @@ describe('SendCoinsResolver', () => {
await DbUser.save(recipUser)
})
- describe('voteForSendCoins', () => {
+ describe('voteForSendCoins', () => {
describe('unknown recipient community', () => {
it('throws an error', async () => {
jest.clearAllMocks()
- const args = new SendCoinsArgs()
- args.recipientCommunityUuid = 'invalid foreignCom'
- args.recipientUserIdentifier = recipUser.gradidoID
- args.creationDate = new Date().toISOString()
- args.amount = new Decimal(100)
- args.memo = 'X-Com-TX memo'
- if (homeCom.communityUuid) {
- args.senderCommunityUuid = homeCom.communityUuid
- }
- args.senderUserUuid = sendUser.gradidoID
- args.senderUserName = fullName(sendUser.firstName, sendUser.lastName)
- args.senderAlias = sendUser.alias
+ const payload = new SendCoinsJwtPayloadType(
+ 'handshakeID',
+ 'invalid recipientCom',
+ recipUser.gradidoID,
+ new Date().toISOString(),
+ new Decimal(100),
+ 'X-Com-TX memo',
+ senderCom.communityUuid!,
+ sendUser.gradidoID,
+ fullName(sendUser.firstName, sendUser.lastName),
+ sendUser.alias
+ )
+ // invoke encryption as beeing on the foreignCom side to find in voteForSendCoins the correct homeCom
+ const jws = await encryptAndSign(payload, senderCom.privateJwtKey!, recipientCom.publicJwtKey!)
+ const args = new EncryptedTransferArgs()
+ args.publicKey = senderCom.publicKey.toString('hex')
+ args.jwt = jws
+ args.handshakeID = 'handshakeID'
+ const graphQLResponse = await mutate({
+ mutation: voteForSendCoinsMutation,
+ variables: { args },
+ })
expect(
- await mutate({
- mutation: voteForSendCoinsMutation,
- variables: { args },
- }),
+ graphQLResponse,
).toEqual(
expect.objectContaining({
- errors: [new GraphQLError('voteForSendCoins with wrong recipientCommunityUuid')],
+ errors: [new GraphQLError('voteForSendCoins with wrong recipientCommunityUuid: invalid recipientCom')],
}),
)
})
@@ -152,20 +160,25 @@ describe('SendCoinsResolver', () => {
describe('unknown recipient user', () => {
it('throws an error', async () => {
jest.clearAllMocks()
- const args = new SendCoinsArgs()
- if (foreignCom.communityUuid) {
- args.recipientCommunityUuid = foreignCom.communityUuid
- }
- args.recipientUserIdentifier = 'invalid recipient'
- args.creationDate = new Date().toISOString()
- args.amount = new Decimal(100)
- args.memo = 'X-Com-TX memo'
- if (homeCom.communityUuid) {
- args.senderCommunityUuid = homeCom.communityUuid
- }
- args.senderUserUuid = sendUser.gradidoID
- args.senderUserName = fullName(sendUser.firstName, sendUser.lastName)
- args.senderAlias = sendUser.alias
+
+ const payload = new SendCoinsJwtPayloadType(
+ 'handshakeID',
+ recipientCom.communityUuid!,
+ 'invalid recipient',
+ new Date().toISOString(),
+ new Decimal(100),
+ 'X-Com-TX memo',
+ senderCom.communityUuid!,
+ sendUser.gradidoID,
+ fullName(sendUser.firstName, sendUser.lastName),
+ sendUser.alias
+ )
+ // invoke encryption as beeing on the foreignCom side to find in voteForSendCoins the correct homeCom
+ const jws = await encryptAndSign(payload, senderCom.privateJwtKey!, recipientCom.publicJwtKey!)
+ const args = new EncryptedTransferArgs()
+ args.publicKey = senderCom.publicKey.toString('hex')
+ args.jwt = jws
+ args.handshakeID = 'handshakeID'
expect(
await mutate({
mutation: voteForSendCoinsMutation,
@@ -175,7 +188,7 @@ describe('SendCoinsResolver', () => {
expect.objectContaining({
errors: [
new GraphQLError(
- 'voteForSendCoins with unknown recipientUserIdentifier in the community=',
+ 'voteForSendCoins with unknown recipientUserIdentifier in the community=homeCom-Name',
),
],
}),
@@ -186,36 +199,42 @@ describe('SendCoinsResolver', () => {
describe('valid X-Com-TX voted per gradidoID', () => {
it('throws an error', async () => {
jest.clearAllMocks()
- const args = new SendCoinsArgs()
- if (foreignCom.communityUuid) {
- args.recipientCommunityUuid = foreignCom.communityUuid
- }
- args.recipientUserIdentifier = recipUser.gradidoID
- args.creationDate = new Date().toISOString()
- args.amount = new Decimal(100)
- args.memo = 'X-Com-TX memo'
- if (homeCom.communityUuid) {
- args.senderCommunityUuid = homeCom.communityUuid
- }
- args.senderUserUuid = sendUser.gradidoID
- args.senderUserName = fullName(sendUser.firstName, sendUser.lastName)
- args.senderAlias = sendUser.alias
+
+ const payload = new SendCoinsJwtPayloadType(
+ 'handshakeID',
+ recipientCom.communityUuid!,
+ recipUser.gradidoID,
+ new Date().toISOString(),
+ new Decimal(100),
+ 'X-Com-TX memo',
+ senderCom.communityUuid!,
+ sendUser.gradidoID,
+ fullName(sendUser.firstName, sendUser.lastName),
+ sendUser.alias
+ )
+ // invoke encryption as beeing on the foreignCom side to find in voteForSendCoins the correct homeCom
+ const jws = await encryptAndSign(payload, senderCom.privateJwtKey!, recipientCom.publicJwtKey!)
+ const args = new EncryptedTransferArgs()
+ args.publicKey = senderCom.publicKey.toString('hex')
+ args.jwt = jws
+ args.handshakeID = 'handshakeID'
+ const responseJwt = await mutate({
+ mutation: voteForSendCoinsMutation,
+ variables: { args },
+ })
+ const voteResult = await verifyAndDecrypt('handshakeID', responseJwt.data.voteForSendCoins, senderCom.privateJwtKey!, recipientCom.publicJwtKey!) as SendCoinsResponseJwtPayloadType
expect(
- await mutate({
- mutation: voteForSendCoinsMutation,
- variables: { args },
- }),
+ voteResult,
).toEqual(
expect.objectContaining({
- data: {
- voteForSendCoins: {
- recipGradidoID: '56a55482-909e-46a4-bfa2-cd025e894ebd',
- recipFirstName: 'recipUser-FirstName',
- recipLastName: 'recipUser-LastName',
- recipAlias: 'recipUser-alias',
- vote: true,
- },
- },
+ expiration: '10m',
+ handshakeID: 'handshakeID',
+ recipGradidoID: '56a55482-909e-46a4-bfa2-cd025e894ebd',
+ recipFirstName: 'recipUser-FirstName',
+ recipLastName: 'recipUser-LastName',
+ recipAlias: 'recipUser-alias',
+ tokentype: SendCoinsResponseJwtPayloadType.SEND_COINS_RESPONSE_TYPE,
+ vote: true,
}),
)
})
@@ -224,36 +243,39 @@ describe('SendCoinsResolver', () => {
describe('valid X-Com-TX voted per alias', () => {
it('throws an error', async () => {
jest.clearAllMocks()
- const args = new SendCoinsArgs()
- if (foreignCom.communityUuid) {
- args.recipientCommunityUuid = foreignCom.communityUuid
- }
- args.recipientUserIdentifier = recipUser.alias
- args.creationDate = new Date().toISOString()
- args.amount = new Decimal(100)
- args.memo = 'X-Com-TX memo'
- if (homeCom.communityUuid) {
- args.senderCommunityUuid = homeCom.communityUuid
- }
- args.senderUserUuid = sendUser.gradidoID
- args.senderUserName = fullName(sendUser.firstName, sendUser.lastName)
- args.senderAlias = sendUser.alias
+
+ const payload = new SendCoinsJwtPayloadType(
+ 'handshakeID',
+ recipientCom.communityUuid!,
+ recipUser.alias,
+ new Date().toISOString(),
+ new Decimal(100),
+ 'X-Com-TX memo',
+ senderCom.communityUuid!,
+ sendUser.gradidoID,
+ fullName(sendUser.firstName, sendUser.lastName),
+ sendUser.alias
+ )
+ // invoke encryption as beeing on the foreignCom side to find in voteForSendCoins the correct homeCom
+ const jws = await encryptAndSign(payload, senderCom.privateJwtKey!, recipientCom.publicJwtKey!)
+ const args = new EncryptedTransferArgs()
+ args.publicKey = senderCom.publicKey.toString('hex')
+ args.jwt = jws
+ args.handshakeID = 'handshakeID'
+ const responseJwt = await mutate({
+ mutation: voteForSendCoinsMutation,
+ variables: { args },
+ })
+ const voteResult = await verifyAndDecrypt('handshakeID', responseJwt.data.voteForSendCoins, senderCom.privateJwtKey!, recipientCom.publicJwtKey!) as SendCoinsResponseJwtPayloadType
expect(
- await mutate({
- mutation: voteForSendCoinsMutation,
- variables: { args },
- }),
+ voteResult,
).toEqual(
expect.objectContaining({
- data: {
- voteForSendCoins: {
- recipGradidoID: '56a55482-909e-46a4-bfa2-cd025e894ebd',
- recipFirstName: 'recipUser-FirstName',
- recipLastName: 'recipUser-LastName',
- recipAlias: 'recipUser-alias',
- vote: true,
- },
- },
+ recipGradidoID: '56a55482-909e-46a4-bfa2-cd025e894ebd',
+ recipFirstName: 'recipUser-FirstName',
+ recipLastName: 'recipUser-LastName',
+ recipAlias: 'recipUser-alias',
+ vote: true,
}),
)
})
@@ -262,36 +284,40 @@ describe('SendCoinsResolver', () => {
describe('valid X-Com-TX voted per email', () => {
it('throws an error', async () => {
jest.clearAllMocks()
- const args = new SendCoinsArgs()
- if (foreignCom.communityUuid) {
- args.recipientCommunityUuid = foreignCom.communityUuid
- }
- args.recipientUserIdentifier = recipContact.email
- args.creationDate = new Date().toISOString()
- args.amount = new Decimal(100)
- args.memo = 'X-Com-TX memo'
- if (homeCom.communityUuid) {
- args.senderCommunityUuid = homeCom.communityUuid
- }
- args.senderUserUuid = sendUser.gradidoID
- args.senderUserName = fullName(sendUser.firstName, sendUser.lastName)
- args.senderAlias = sendUser.alias
+
+
+ const payload = new SendCoinsJwtPayloadType(
+ 'handshakeID',
+ recipientCom.communityUuid!,
+ recipContact.email,
+ new Date().toISOString(),
+ new Decimal(100),
+ 'X-Com-TX memo',
+ senderCom.communityUuid!,
+ sendUser.gradidoID,
+ fullName(sendUser.firstName, sendUser.lastName),
+ sendUser.alias
+ )
+ // invoke encryption as beeing on the foreignCom side to find in voteForSendCoins the correct homeCom
+ const jws = await encryptAndSign(payload, senderCom.privateJwtKey!, recipientCom.publicJwtKey!)
+ const args = new EncryptedTransferArgs()
+ args.publicKey = senderCom.publicKey.toString('hex')
+ args.jwt = jws
+ args.handshakeID = 'handshakeID'
+ const responseJwt = await mutate({
+ mutation: voteForSendCoinsMutation,
+ variables: { args },
+ })
+ const voteResult = await verifyAndDecrypt('handshakeID', responseJwt.data.voteForSendCoins, senderCom.privateJwtKey!, recipientCom.publicJwtKey!) as SendCoinsResponseJwtPayloadType
expect(
- await mutate({
- mutation: voteForSendCoinsMutation,
- variables: { args },
- }),
+ voteResult,
).toEqual(
expect.objectContaining({
- data: {
- voteForSendCoins: {
- recipGradidoID: '56a55482-909e-46a4-bfa2-cd025e894ebd',
- recipFirstName: 'recipUser-FirstName',
- recipLastName: 'recipUser-LastName',
- recipAlias: 'recipUser-alias',
- vote: true,
- },
- },
+ recipGradidoID: '56a55482-909e-46a4-bfa2-cd025e894ebd',
+ recipFirstName: 'recipUser-FirstName',
+ recipLastName: 'recipUser-LastName',
+ recipAlias: 'recipUser-alias',
+ vote: true,
}),
)
})
@@ -302,20 +328,25 @@ describe('SendCoinsResolver', () => {
const creationDate = new Date()
beforeEach(async () => {
- const args = new SendCoinsArgs()
- if (foreignCom.communityUuid) {
- args.recipientCommunityUuid = foreignCom.communityUuid
- }
- args.recipientUserIdentifier = recipUser.gradidoID
- args.creationDate = creationDate.toISOString()
- args.amount = new Decimal(100)
- args.memo = 'X-Com-TX memo'
- if (homeCom.communityUuid) {
- args.senderCommunityUuid = homeCom.communityUuid
- }
- args.senderUserUuid = sendUser.gradidoID
- args.senderUserName = fullName(sendUser.firstName, sendUser.lastName)
- args.senderAlias = sendUser.alias
+
+ const payload = new SendCoinsJwtPayloadType(
+ 'handshakeID',
+ recipientCom.communityUuid!,
+ recipUser.gradidoID,
+ creationDate.toISOString(),
+ new Decimal(100),
+ 'X-Com-TX memo',
+ senderCom.communityUuid!,
+ sendUser.gradidoID,
+ fullName(sendUser.firstName, sendUser.lastName),
+ sendUser.alias
+ )
+ // invoke encryption as beeing on the foreignCom side to find in voteForSendCoins the correct homeCom
+ const jws = await encryptAndSign(payload, senderCom.privateJwtKey!, recipientCom.publicJwtKey!)
+ const args = new EncryptedTransferArgs()
+ args.publicKey = senderCom.publicKey.toString('hex')
+ args.jwt = jws
+ args.handshakeID = 'handshakeID'
await mutate({
mutation: voteForSendCoinsMutation,
variables: { args },
@@ -325,18 +356,25 @@ describe('SendCoinsResolver', () => {
describe('unknown recipient community', () => {
it('throws an error', async () => {
jest.clearAllMocks()
- const args = new SendCoinsArgs()
- args.recipientCommunityUuid = 'invalid foreignCom'
- args.recipientUserIdentifier = recipUser.gradidoID
- args.creationDate = creationDate.toISOString()
- args.amount = new Decimal(100)
- args.memo = 'X-Com-TX memo'
- if (homeCom.communityUuid) {
- args.senderCommunityUuid = homeCom.communityUuid
- }
- args.senderUserUuid = sendUser.gradidoID
- args.senderUserName = fullName(sendUser.firstName, sendUser.lastName)
- args.senderAlias = sendUser.alias
+
+ const payload = new SendCoinsJwtPayloadType(
+ 'handshakeID',
+ 'invalid recipientCom',
+ recipUser.gradidoID,
+ creationDate.toISOString(),
+ new Decimal(100),
+ 'X-Com-TX memo',
+ senderCom.communityUuid!,
+ sendUser.gradidoID,
+ fullName(sendUser.firstName, sendUser.lastName),
+ sendUser.alias
+ )
+ // invoke encryption as beeing on the foreignCom side to find in voteForSendCoins the correct homeCom
+ const jws = await encryptAndSign(payload, senderCom.privateJwtKey!, recipientCom.publicJwtKey!)
+ const args = new EncryptedTransferArgs()
+ args.publicKey = senderCom.publicKey.toString('hex')
+ args.jwt = jws
+ args.handshakeID = 'handshakeID'
expect(
await mutate({
mutation: revertSendCoinsMutation,
@@ -344,7 +382,7 @@ describe('SendCoinsResolver', () => {
}),
).toEqual(
expect.objectContaining({
- errors: [new GraphQLError('revertSendCoins with wrong recipientCommunityUuid')],
+ errors: [new GraphQLError('revertSendCoins with wrong recipientCommunityUuid=invalid recipientCom')],
}),
)
})
@@ -353,20 +391,25 @@ describe('SendCoinsResolver', () => {
describe('unknown recipient user', () => {
it('throws an error', async () => {
jest.clearAllMocks()
- const args = new SendCoinsArgs()
- if (foreignCom.communityUuid) {
- args.recipientCommunityUuid = foreignCom.communityUuid
- }
- args.recipientUserIdentifier = 'invalid recipient'
- args.creationDate = creationDate.toISOString()
- args.amount = new Decimal(100)
- args.memo = 'X-Com-TX memo'
- if (homeCom.communityUuid) {
- args.senderCommunityUuid = homeCom.communityUuid
- }
- args.senderUserUuid = sendUser.gradidoID
- args.senderUserName = fullName(sendUser.firstName, sendUser.lastName)
- args.senderAlias = sendUser.alias
+
+ const payload = new SendCoinsJwtPayloadType(
+ 'handshakeID',
+ recipientCom.communityUuid!,
+ 'invalid recipient',
+ creationDate.toISOString(),
+ new Decimal(100),
+ 'X-Com-TX memo',
+ senderCom.communityUuid!,
+ sendUser.gradidoID,
+ fullName(sendUser.firstName, sendUser.lastName),
+ sendUser.alias
+ )
+ // invoke encryption as beeing on the foreignCom side to find in voteForSendCoins the correct homeCom
+ const jws = await encryptAndSign(payload, senderCom.privateJwtKey!, recipientCom.publicJwtKey!)
+ const args = new EncryptedTransferArgs()
+ args.publicKey = senderCom.publicKey.toString('hex')
+ args.jwt = jws
+ args.handshakeID = 'handshakeID'
expect(
await mutate({
mutation: revertSendCoinsMutation,
@@ -376,7 +419,7 @@ describe('SendCoinsResolver', () => {
expect.objectContaining({
errors: [
new GraphQLError(
- 'revertSendCoins with unknown recipientUserIdentifier in the community=',
+ 'revertSendCoins with unknown recipientUserIdentifier in the community=homeCom-Name',
),
],
}),
@@ -387,20 +430,26 @@ describe('SendCoinsResolver', () => {
describe('valid X-Com-TX reverted', () => {
it('throws an error', async () => {
jest.clearAllMocks()
- const args = new SendCoinsArgs()
- if (foreignCom.communityUuid) {
- args.recipientCommunityUuid = foreignCom.communityUuid
- }
- args.recipientUserIdentifier = recipUser.gradidoID
- args.creationDate = creationDate.toISOString()
- args.amount = new Decimal(100)
- args.memo = 'X-Com-TX memo'
- if (homeCom.communityUuid) {
- args.senderCommunityUuid = homeCom.communityUuid
- }
- args.senderUserUuid = sendUser.gradidoID
- args.senderUserName = fullName(sendUser.firstName, sendUser.lastName)
- args.senderAlias = sendUser.alias
+
+ const payload = new SendCoinsJwtPayloadType(
+ 'handshakeID',
+ recipientCom.communityUuid!,
+ recipUser.gradidoID,
+ creationDate.toISOString(),
+ new Decimal(100),
+ 'X-Com-TX memo',
+ senderCom.communityUuid!,
+ sendUser.gradidoID,
+ fullName(sendUser.firstName, sendUser.lastName),
+ sendUser.alias
+ )
+ // invoke encryption as beeing on the foreignCom side to find in voteForSendCoins the correct homeCom
+ const jws = await encryptAndSign(payload, senderCom.privateJwtKey!, recipientCom.publicJwtKey!)
+ const args = new EncryptedTransferArgs()
+ args.publicKey = senderCom.publicKey.toString('hex')
+ args.jwt = jws
+ args.handshakeID = 'handshakeID'
+
expect(
await mutate({
mutation: revertSendCoinsMutation,
@@ -421,20 +470,25 @@ describe('SendCoinsResolver', () => {
const creationDate = new Date()
beforeEach(async () => {
- const args = new SendCoinsArgs()
- if (foreignCom.communityUuid) {
- args.recipientCommunityUuid = foreignCom.communityUuid
- }
- args.recipientUserIdentifier = recipUser.gradidoID
- args.creationDate = creationDate.toISOString()
- args.amount = new Decimal(100)
- args.memo = 'X-Com-TX memo'
- if (homeCom.communityUuid) {
- args.senderCommunityUuid = homeCom.communityUuid
- }
- args.senderUserUuid = sendUser.gradidoID
- args.senderUserName = fullName(sendUser.firstName, sendUser.lastName)
- args.senderAlias = sendUser.alias
+ const payload = new SendCoinsJwtPayloadType(
+ 'handshakeID',
+ recipientCom.communityUuid!,
+ recipUser.gradidoID,
+ creationDate.toISOString(),
+ new Decimal(100),
+ 'X-Com-TX memo',
+ senderCom.communityUuid!,
+ sendUser.gradidoID,
+ fullName(sendUser.firstName, sendUser.lastName),
+ sendUser.alias
+ )
+ // invoke encryption as beeing on the foreignCom side to find in voteForSendCoins the correct homeCom
+ const jws = await encryptAndSign(payload, senderCom.privateJwtKey!, recipientCom.publicJwtKey!)
+ const args = new EncryptedTransferArgs()
+ args.publicKey = senderCom.publicKey.toString('hex')
+ args.jwt = jws
+ args.handshakeID = 'handshakeID'
+
await mutate({
mutation: voteForSendCoinsMutation,
variables: { args },
@@ -444,18 +498,24 @@ describe('SendCoinsResolver', () => {
describe('unknown recipient community', () => {
it('throws an error', async () => {
jest.clearAllMocks()
- const args = new SendCoinsArgs()
- args.recipientCommunityUuid = 'invalid foreignCom'
- args.recipientUserIdentifier = recipUser.gradidoID
- args.creationDate = creationDate.toISOString()
- args.amount = new Decimal(100)
- args.memo = 'X-Com-TX memo'
- if (homeCom.communityUuid) {
- args.senderCommunityUuid = homeCom.communityUuid
- }
- args.senderUserUuid = sendUser.gradidoID
- args.senderUserName = fullName(sendUser.firstName, sendUser.lastName)
- args.senderAlias = sendUser.alias
+ const payload = new SendCoinsJwtPayloadType(
+ 'handshakeID',
+ 'invalid recipientCom',
+ recipUser.gradidoID,
+ creationDate.toISOString(),
+ new Decimal(100),
+ 'X-Com-TX memo',
+ senderCom.communityUuid!,
+ sendUser.gradidoID,
+ fullName(sendUser.firstName, sendUser.lastName),
+ sendUser.alias
+ )
+ // invoke encryption as beeing on the foreignCom side to find in voteForSendCoins the correct homeCom
+ const jws = await encryptAndSign(payload, senderCom.privateJwtKey!, recipientCom.publicJwtKey!)
+ const args = new EncryptedTransferArgs()
+ args.publicKey = senderCom.publicKey.toString('hex')
+ args.jwt = jws
+ args.handshakeID = 'handshakeID'
expect(
await mutate({
mutation: settleSendCoinsMutation,
@@ -463,7 +523,7 @@ describe('SendCoinsResolver', () => {
}),
).toEqual(
expect.objectContaining({
- errors: [new GraphQLError('settleSendCoins with wrong recipientCommunityUuid')],
+ errors: [new GraphQLError('settleSendCoins with wrong recipientCommunityUuid=invalid recipientCom')],
}),
)
})
@@ -472,20 +532,24 @@ describe('SendCoinsResolver', () => {
describe('unknown recipient user', () => {
it('throws an error', async () => {
jest.clearAllMocks()
- const args = new SendCoinsArgs()
- if (foreignCom.communityUuid) {
- args.recipientCommunityUuid = foreignCom.communityUuid
- }
- args.recipientUserIdentifier = 'invalid recipient'
- args.creationDate = creationDate.toISOString()
- args.amount = new Decimal(100)
- args.memo = 'X-Com-TX memo'
- if (homeCom.communityUuid) {
- args.senderCommunityUuid = homeCom.communityUuid
- }
- args.senderUserUuid = sendUser.gradidoID
- args.senderUserName = fullName(sendUser.firstName, sendUser.lastName)
- args.senderAlias = sendUser.alias
+ const payload = new SendCoinsJwtPayloadType(
+ 'handshakeID',
+ recipientCom.communityUuid!,
+ 'invalid recipient',
+ creationDate.toISOString(),
+ new Decimal(100),
+ 'X-Com-TX memo',
+ senderCom.communityUuid!,
+ sendUser.gradidoID,
+ fullName(sendUser.firstName, sendUser.lastName),
+ sendUser.alias
+ )
+ // invoke encryption as beeing on the foreignCom side to find in voteForSendCoins the correct homeCom
+ const jws = await encryptAndSign(payload, senderCom.privateJwtKey!, recipientCom.publicJwtKey!)
+ const args = new EncryptedTransferArgs()
+ args.publicKey = senderCom.publicKey.toString('hex')
+ args.jwt = jws
+ args.handshakeID = 'handshakeID'
expect(
await mutate({
mutation: settleSendCoinsMutation,
@@ -495,7 +559,7 @@ describe('SendCoinsResolver', () => {
expect.objectContaining({
errors: [
new GraphQLError(
- 'settleSendCoins with unknown recipientUserIdentifier in the community=',
+ 'settleSendCoins with unknown recipientUserIdentifier in the community=' + recipientCom.name,
),
],
}),
@@ -506,20 +570,24 @@ describe('SendCoinsResolver', () => {
describe('valid X-Com-TX settled', () => {
it('throws an error', async () => {
jest.clearAllMocks()
- const args = new SendCoinsArgs()
- if (foreignCom.communityUuid) {
- args.recipientCommunityUuid = foreignCom.communityUuid
- }
- args.recipientUserIdentifier = recipUser.gradidoID
- args.creationDate = creationDate.toISOString()
- args.amount = new Decimal(100)
- args.memo = 'X-Com-TX memo'
- if (homeCom.communityUuid) {
- args.senderCommunityUuid = homeCom.communityUuid
- }
- args.senderUserUuid = sendUser.gradidoID
- args.senderUserName = fullName(sendUser.firstName, sendUser.lastName)
- args.senderAlias = sendUser.alias
+ const payload = new SendCoinsJwtPayloadType(
+ 'handshakeID',
+ recipientCom.communityUuid!,
+ recipUser.gradidoID,
+ creationDate.toISOString(),
+ new Decimal(100),
+ 'X-Com-TX memo',
+ senderCom.communityUuid!,
+ sendUser.gradidoID,
+ fullName(sendUser.firstName, sendUser.lastName),
+ sendUser.alias
+ )
+ // invoke encryption as beeing on the foreignCom side to find in voteForSendCoins the correct homeCom
+ const jws = await encryptAndSign(payload, senderCom.privateJwtKey!, recipientCom.publicJwtKey!)
+ const args = new EncryptedTransferArgs()
+ args.publicKey = senderCom.publicKey.toString('hex')
+ args.jwt = jws
+ args.handshakeID = 'handshakeID'
expect(
await mutate({
mutation: settleSendCoinsMutation,
@@ -540,20 +608,24 @@ describe('SendCoinsResolver', () => {
const creationDate = new Date()
beforeEach(async () => {
- const args = new SendCoinsArgs()
- if (foreignCom.communityUuid) {
- args.recipientCommunityUuid = foreignCom.communityUuid
- }
- args.recipientUserIdentifier = recipUser.gradidoID
- args.creationDate = creationDate.toISOString()
- args.amount = new Decimal(100)
- args.memo = 'X-Com-TX memo'
- if (homeCom.communityUuid) {
- args.senderCommunityUuid = homeCom.communityUuid
- }
- args.senderUserUuid = sendUser.gradidoID
- args.senderUserName = fullName(sendUser.firstName, sendUser.lastName)
- args.senderAlias = sendUser.alias
+ const payload = new SendCoinsJwtPayloadType(
+ 'handshakeID',
+ recipientCom.communityUuid!,
+ recipUser.gradidoID,
+ creationDate.toISOString(),
+ new Decimal(100),
+ 'X-Com-TX memo',
+ senderCom.communityUuid!,
+ sendUser.gradidoID,
+ fullName(sendUser.firstName, sendUser.lastName),
+ sendUser.alias
+ )
+ // invoke encryption as beeing on the foreignCom side to find in voteForSendCoins the correct homeCom
+ const jws = await encryptAndSign(payload, senderCom.privateJwtKey!, recipientCom.publicJwtKey!)
+ const args = new EncryptedTransferArgs()
+ args.publicKey = senderCom.publicKey.toString('hex')
+ args.jwt = jws
+ args.handshakeID = 'handshakeID'
await mutate({
mutation: voteForSendCoinsMutation,
variables: { args },
@@ -567,18 +639,24 @@ describe('SendCoinsResolver', () => {
describe('unknown recipient community', () => {
it('throws an error', async () => {
jest.clearAllMocks()
- const args = new SendCoinsArgs()
- args.recipientCommunityUuid = 'invalid foreignCom'
- args.recipientUserIdentifier = recipUser.gradidoID
- args.creationDate = creationDate.toISOString()
- args.amount = new Decimal(100)
- args.memo = 'X-Com-TX memo'
- if (homeCom.communityUuid) {
- args.senderCommunityUuid = homeCom.communityUuid
- }
- args.senderUserUuid = sendUser.gradidoID
- args.senderUserName = fullName(sendUser.firstName, sendUser.lastName)
- args.senderAlias = sendUser.alias
+ const payload = new SendCoinsJwtPayloadType(
+ 'handshakeID',
+ 'invalid recipientCom',
+ recipUser.gradidoID,
+ creationDate.toISOString(),
+ new Decimal(100),
+ 'X-Com-TX memo',
+ senderCom.communityUuid!,
+ sendUser.gradidoID,
+ fullName(sendUser.firstName, sendUser.lastName),
+ sendUser.alias
+ )
+ // invoke encryption as beeing on the foreignCom side to find in voteForSendCoins the correct homeCom
+ const jws = await encryptAndSign(payload, senderCom.privateJwtKey!, recipientCom.publicJwtKey!)
+ const args = new EncryptedTransferArgs()
+ args.publicKey = senderCom.publicKey.toString('hex')
+ args.jwt = jws
+ args.handshakeID = 'handshakeID'
expect(
await mutate({
mutation: revertSettledSendCoinsMutation,
@@ -586,7 +664,7 @@ describe('SendCoinsResolver', () => {
}),
).toEqual(
expect.objectContaining({
- errors: [new GraphQLError('revertSettledSendCoins with wrong recipientCommunityUuid')],
+ errors: [new GraphQLError('revertSettledSendCoins with wrong recipientCommunityUuid=invalid recipientCom')],
}),
)
})
@@ -595,20 +673,24 @@ describe('SendCoinsResolver', () => {
describe('unknown recipient user', () => {
it('throws an error', async () => {
jest.clearAllMocks()
- const args = new SendCoinsArgs()
- if (foreignCom.communityUuid) {
- args.recipientCommunityUuid = foreignCom.communityUuid
- }
- args.recipientUserIdentifier = 'invalid recipient'
- args.creationDate = creationDate.toISOString()
- args.amount = new Decimal(100)
- args.memo = 'X-Com-TX memo'
- if (homeCom.communityUuid) {
- args.senderCommunityUuid = homeCom.communityUuid
- }
- args.senderUserUuid = sendUser.gradidoID
- args.senderUserName = fullName(sendUser.firstName, sendUser.lastName)
- args.senderAlias = sendUser.alias
+ const payload = new SendCoinsJwtPayloadType(
+ 'handshakeID',
+ recipientCom.communityUuid!,
+ 'invalid recipient',
+ creationDate.toISOString(),
+ new Decimal(100),
+ 'X-Com-TX memo',
+ senderCom.communityUuid!,
+ sendUser.gradidoID,
+ fullName(sendUser.firstName, sendUser.lastName),
+ sendUser.alias
+ )
+ // invoke encryption as beeing on the foreignCom side to find in voteForSendCoins the correct homeCom
+ const jws = await encryptAndSign(payload, senderCom.privateJwtKey!, recipientCom.publicJwtKey!)
+ const args = new EncryptedTransferArgs()
+ args.publicKey = senderCom.publicKey.toString('hex')
+ args.jwt = jws
+ args.handshakeID = 'handshakeID'
expect(
await mutate({
mutation: revertSettledSendCoinsMutation,
@@ -618,7 +700,7 @@ describe('SendCoinsResolver', () => {
expect.objectContaining({
errors: [
new GraphQLError(
- 'revertSettledSendCoins with unknown recipientUserIdentifier in the community=',
+ 'revertSettledSendCoins with unknown recipientUserIdentifier in the community=' + recipientCom.name,
),
],
}),
@@ -629,20 +711,24 @@ describe('SendCoinsResolver', () => {
describe('valid X-Com-TX settled', () => {
it('throws an error', async () => {
jest.clearAllMocks()
- const args = new SendCoinsArgs()
- if (foreignCom.communityUuid) {
- args.recipientCommunityUuid = foreignCom.communityUuid
- }
- args.recipientUserIdentifier = recipUser.gradidoID
- args.creationDate = creationDate.toISOString()
- args.amount = new Decimal(100)
- args.memo = 'X-Com-TX memo'
- if (homeCom.communityUuid) {
- args.senderCommunityUuid = homeCom.communityUuid
- }
- args.senderUserUuid = sendUser.gradidoID
- args.senderUserName = fullName(sendUser.firstName, sendUser.lastName)
- args.senderAlias = sendUser.alias
+ const payload = new SendCoinsJwtPayloadType(
+ 'handshakeID',
+ recipientCom.communityUuid!,
+ recipUser.gradidoID,
+ creationDate.toISOString(),
+ new Decimal(100),
+ 'X-Com-TX memo',
+ senderCom.communityUuid!,
+ sendUser.gradidoID,
+ fullName(sendUser.firstName, sendUser.lastName),
+ sendUser.alias
+ )
+ // invoke encryption as beeing on the foreignCom side to find in voteForSendCoins the correct homeCom
+ const jws = await encryptAndSign(payload, senderCom.privateJwtKey!, recipientCom.publicJwtKey!)
+ const args = new EncryptedTransferArgs()
+ args.publicKey = senderCom.publicKey.toString('hex')
+ args.jwt = jws
+ args.handshakeID = 'handshakeID'
expect(
await mutate({
mutation: revertSettledSendCoinsMutation,
diff --git a/federation/src/graphql/api/1_0/resolver/SendCoinsResolver.ts b/federation/src/graphql/api/1_0/resolver/SendCoinsResolver.ts
index 3c6d056af..938dca47c 100644
--- a/federation/src/graphql/api/1_0/resolver/SendCoinsResolver.ts
+++ b/federation/src/graphql/api/1_0/resolver/SendCoinsResolver.ts
@@ -52,7 +52,7 @@ export class SendCoinsResolver {
communityUuid: authArgs.recipientCommunityUuid,
})
if (!recipientCom) {
- const errmsg = `voteForSendCoins with wrong recipientCommunityUuid` + authArgs.recipientCommunityUuid
+ const errmsg = `voteForSendCoins with wrong recipientCommunityUuid: ${authArgs.recipientCommunityUuid}`
methodLogger.error(errmsg)
throw new Error(errmsg)
}
@@ -60,7 +60,7 @@ export class SendCoinsResolver {
communityUuid: authArgs.senderCommunityUuid,
})
if (!senderCom) {
- const errmsg = `voteForSendCoins with wrong senderCommunityUuid` + authArgs.senderCommunityUuid
+ const errmsg = `voteForSendCoins with wrong senderCommunityUuid: ${authArgs.senderCommunityUuid}`
methodLogger.error(errmsg)
throw new Error(errmsg)
}
@@ -136,7 +136,7 @@ export class SendCoinsResolver {
}
const authArgs = await interpretEncryptedTransferArgs(args) as SendCoinsJwtPayloadType
if (!authArgs) {
- const errmsg = `invalid revertSendCoins payload of requesting community with publicKey` + args.publicKey
+ const errmsg = `invalid revertSendCoins payload of requesting community with publicKey=${args.publicKey}`
methodLogger.error(errmsg)
throw new Error(errmsg)
}
@@ -148,7 +148,7 @@ export class SendCoinsResolver {
communityUuid: authArgs.recipientCommunityUuid,
})
if (!homeCom) {
- const errmsg = `revertSendCoins with wrong recipientCommunityUuid` + authArgs.recipientCommunityUuid
+ const errmsg = `revertSendCoins with wrong recipientCommunityUuid=${authArgs.recipientCommunityUuid}`
methodLogger.error(errmsg)
throw new Error(errmsg)
}
@@ -157,7 +157,7 @@ export class SendCoinsResolver {
// second check if receiver user exists in this community
receiverUser = await findUserByIdentifier(authArgs.recipientUserIdentifier)
if (!receiverUser) {
- const errmsg = `revertSendCoins with unknown recipientUserIdentifier in the community=` + homeCom.name
+ const errmsg = `revertSendCoins with unknown recipientUserIdentifier in the community=${homeCom.name}`
methodLogger.error(errmsg)
throw new Error(errmsg)
}
@@ -222,7 +222,7 @@ export class SendCoinsResolver {
}
const authArgs = await interpretEncryptedTransferArgs(args) as SendCoinsJwtPayloadType
if (!authArgs) {
- const errmsg = `invalid settleSendCoins payload of requesting community with publicKey` + args.publicKey
+ const errmsg = `invalid settleSendCoins payload of requesting community with publicKey=${args.publicKey}`
methodLogger.error(errmsg)
throw new Error(errmsg)
}
@@ -234,7 +234,7 @@ export class SendCoinsResolver {
communityUuid: authArgs.recipientCommunityUuid,
})
if (!homeCom) {
- const errmsg = `settleSendCoins with wrong recipientCommunityUuid` + authArgs.recipientCommunityUuid
+ const errmsg = `settleSendCoins with wrong recipientCommunityUuid=${authArgs.recipientCommunityUuid}`
methodLogger.error(errmsg)
throw new Error(errmsg)
}
@@ -242,7 +242,7 @@ export class SendCoinsResolver {
// second check if receiver user exists in this community
const receiverUser = await findUserByIdentifier(authArgs.recipientUserIdentifier)
if (!receiverUser) {
- const errmsg = `settleSendCoins with unknown recipientUserIdentifier in the community=` + homeCom.name
+ const errmsg = `settleSendCoins with unknown recipientUserIdentifier in the community=${homeCom.name}`
methodLogger.error(errmsg)
throw new Error(errmsg)
}
@@ -305,7 +305,7 @@ export class SendCoinsResolver {
}
const authArgs = await interpretEncryptedTransferArgs(args) as SendCoinsJwtPayloadType
if (!authArgs) {
- const errmsg = `invalid revertSettledSendCoins payload of requesting community with publicKey` + args.publicKey
+ const errmsg = `invalid revertSettledSendCoins payload of requesting community with publicKey=${args.publicKey}`
methodLogger.error(errmsg)
throw new Error(errmsg)
}
@@ -317,7 +317,7 @@ export class SendCoinsResolver {
communityUuid: authArgs.recipientCommunityUuid,
})
if (!homeCom) {
- const errmsg = `revertSettledSendCoins with wrong recipientCommunityUuid` + authArgs.recipientCommunityUuid
+ const errmsg = `revertSettledSendCoins with wrong recipientCommunityUuid=${authArgs.recipientCommunityUuid}`
methodLogger.error(errmsg)
throw new Error(errmsg)
}
@@ -325,7 +325,7 @@ export class SendCoinsResolver {
// second check if receiver user exists in this community
const receiverUser = await findUserByIdentifier(authArgs.recipientUserIdentifier)
if (!receiverUser) {
- const errmsg = `revertSettledSendCoins with unknown recipientUserIdentifier in the community=` + homeCom.name
+ const errmsg = `revertSettledSendCoins with unknown recipientUserIdentifier in the community=${homeCom.name}`
methodLogger.error(errmsg)
throw new Error(errmsg)
}