From ddae7f647dc1f7aa1d1324f4fbd1a937bd6935ab Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Claus-Peter=20H=C3=BCbner?= Date: Wed, 15 Feb 2023 23:11:16 +0100 Subject: [PATCH 01/37] describe and draw the current federation moduls and handshake --- .../TechnicalRequirements/Federation.md | 47 ++- .../graphics/TechnicalOverview_V1-19.drawio | 282 ++++++++++++++++++ .../image/TechnicalOverview_V1-19.svg | 1 + 3 files changed, 303 insertions(+), 27 deletions(-) create mode 100644 docu/Concepts/TechnicalRequirements/graphics/TechnicalOverview_V1-19.drawio create mode 100644 docu/Concepts/TechnicalRequirements/image/TechnicalOverview_V1-19.svg diff --git a/docu/Concepts/TechnicalRequirements/Federation.md b/docu/Concepts/TechnicalRequirements/Federation.md index 959aa8afe..7210756ff 100644 --- a/docu/Concepts/TechnicalRequirements/Federation.md +++ b/docu/Concepts/TechnicalRequirements/Federation.md @@ -4,29 +4,6 @@ This document contains the concept and technical details for the *federation* of But meanwhile the usage of a DHT like HyperSwarm promises more coverage of the gradido requirements out of the box. More details about HyperSwarm can be found here [@hyperswarm/dht](https://github.com/hyperswarm/dht). -## ActivityPub (deprecated) - -The activity pub defines a server-to-server federation protocol to share information between decentralized instances and will be the main komponent for the gradido community federation. - -At first we asume a *gradido community* as an *ActivityPub user*. A user is represented by "*actors*" via the users's accounts on servers. User's accounts on different servers corrsponds to different actors, which means community accounts on different servers corrsponds to different communities. - -Every community (actor) has an: - -* inbox: to get messages from the world -* outbox: to send messages to others - -and are simple endpoints or just URLs, which are described in the *ActivityStream* of each *ActivityPub community*. - -### Open Decision: - -It has to be decided, if the Federation will work with an internal or with external ActivityPub-Server, as shown in the picture below: - -![FederationActivityPub](./image/FederationActivityPub.png " ") - -The Variant A with an internal server contains the benefit to be as independent as possible from third party service providers and will not cause additional hosting costs. But this solution will cause the additional efforts of impementing an ActivityPub-Server in the gradido application and the responsibility for this component. - -The Varaint B with an external server contains the benefit to reduce the implementation efforts and the responsibility for an own ActivitPub-Server. But it will cause an additional dependency to a third party service provider and the growing hosting costs. - ## HyperSwarm The decision to switch from ActivityPub to HyperSwarm base on the arguments, that the *hyperswarm/dht* library will satify the most federation requirements out of the box. It is now to design the business requirements of the [gradido community communication](../BusinessRequirements/CommunityVerwaltung.md#UC-createCommunity) in a technical conception. @@ -41,12 +18,28 @@ To enable such a relationship between an existing community and a new community 2. Authentication 3. Autorized Communication -### Overview +### Overview of Federation-Handshake At first the following diagramm gives an overview of the three stages and shows the handshake between an existing community-A and a new created community-B including the data exchange for buildup such a federated, authenticated and autorized relationship. ![FederationHyperSwarm.png](./image/FederationHyperSwarm.png) +### Technical Architecture + +The previous described handshake will be done by several technical moduls of the gradido system. The following picture gives an overview about the moduls and how the communicate with each other. + +![img](./image/TechnicalOverview_V1-19.svg) + +As soon as a Gradido Community is up and running the DHT-Modul first write the home-community-entries in the database and starts with the federation per HyperSwarm. Each community, which is configured to listen on the GRADIDO_HUB of the DHT will be part of the Gradido-Net-Federation. That means each DHT-Modul of each community will receive the publicKey of all connected communities. The DHT-Modul will open for each received publicKey a communication-socket with the associated community DHT-Modul, to exchange api-version info and hosted urls for later direct communication between both communities. The exchanged api-version info and urls will be written in the own database. + +The up and running Backend-Modul contains a validation logic to verify the community entries from the own DHT-Modul. For each announced but unverified community-entry the GraphQL-Client is used to invoke a getPublicKey-Request. Depending on the containing api-version the matching GraphQL-Client is used and the getPublicKey-Request will be send to the given URL. + +As soon as the FederationModul of the assoziated community received the getPublicKey-request the own publicKey is read from database and send back in the response. + +The GraphQL-Client will read from the returned response data the publicKey of the other community and compare it with the data of the community-entry, which cause the getPublicKey-Request. If they match the community-entry will be updated be inserting the current timestamp in the verifiedAt-field of this community-entry. + +This federation and verification logic will work the whole time and can be monitored by observing the communities-table changes. The Admin-UI will contain a Page to have a look on the current state of the communities table content. + ### Prerequisits Before starting in describing the details of the federation handshake, some prerequisits have to be defined. @@ -235,7 +228,7 @@ For the first federation release the *DHT-Node* will be part of the *apollo serv | communityApiVersion.apiversion | keep existing value | | communityApiVersion.validFrom | exchangedData.API.validFrom | | communityApiVersion.verifiedAt | keep existing value | - * + * 3. After all received data is stored successfully, the *DHT-Node* starts the *stage2 - Authentication* of the federation handshake ### Stage2 - Authentication @@ -284,8 +277,8 @@ As soon the *openConnection* request is invoked: 3. check if the decrypted `parameter.signedAndEncryptedURL` is equals the selected url from the previous selected CommunityFederationEntry 1. if not then break the further processing of this request by only writing an error-log event. There will be no answer to the invoker community, because this community will only go on with a `openConnectionRedirect`-request from this community. 2. if yes then verify the signature of `parameter.signedAndEncryptedURL` with the `cf.pubKey` read in step 2 before - 3. -4. + 3. +4. ### Stage3 - Autorized Business Communication diff --git a/docu/Concepts/TechnicalRequirements/graphics/TechnicalOverview_V1-19.drawio b/docu/Concepts/TechnicalRequirements/graphics/TechnicalOverview_V1-19.drawio new file mode 100644 index 000000000..534804e1d --- /dev/null +++ b/docu/Concepts/TechnicalRequirements/graphics/TechnicalOverview_V1-19.drawio @@ -0,0 +1,282 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/docu/Concepts/TechnicalRequirements/image/TechnicalOverview_V1-19.svg b/docu/Concepts/TechnicalRequirements/image/TechnicalOverview_V1-19.svg new file mode 100644 index 000000000..4b407aa5a --- /dev/null +++ b/docu/Concepts/TechnicalRequirements/image/TechnicalOverview_V1-19.svg @@ -0,0 +1 @@ +
Community  "Gradido-Akademie"
Community  "Gradido-Akademie"
Gradido - technical Infrastructure-Overview
State of 02.2023
Gradido - technical Infrastructure-Overview...
Backend-Modul
GraphQL-API
Backend-Modul...
CommunityServer DB
CommunityServer DB
Layer 1:
Layer 1:
Layer 2:
Layer 2:
"GDT-Server"
base on C++ + mySQL
"GDT-Server"...
GDT-Server DB
GDT-Server DB
json-
ajax-
request
json-...
Layer 3:
Layer 3:
"Elopage"
external Service-Portal
"Elopage"...
"User-UI"
"User-UI"
graphql
graphql
json-
request
json-...
graphql
graphql
"Admin-UI"
"Admin-UI"
DHT-Modul
HyperSwarm
DHT-Modul...
Federation-Modul
GraphQL-API V2_0
Federation-Modul...
Federation-Modul
GraphQL-API V1_x
Federation-Modul...
Federation-Modul
GraphQL-API V1_1
Federation-Modul...
Federation-Modul
GraphQL-API V1_0
Federation-Modul...
GraphQL-Client V1_0
GraphQL-Client V1_0
GraphQL-Client V1_0
GraphQL-Client V1_0
GraphQL-Client V1_0
GraphQL-Client V1_0
GraphQL-Client V1_0
GraphQL-Client V1_0
Community "GallischesDorf-TBB"
Community "GallischesDorf-TBB"
Backend-Modul
GraphQL-API
Backend-Modul...
CommunityServer DB
CommunityServer DB
Layer 1:
Layer 1:
Layer 2:
Layer 2:
Layer 3:
Layer 3:
"User-UI"
"User-UI"
graphql
graphql
graphql
graphql
"Admin-UI"
"Admin-UI"
 DHT-Socket Communication 
 DHT-Socket Communication 
DHT-Modul
HyperSwarm
DHT-Modul...
Federation-Modul
GraphQL-API V1_1
Federation-Modul...
Federation-Modul
GraphQL-API V1_0
Federation-Modul...
graphQL-Handshake
graphQL-Handshake
GraphQL-Client V1_1
GraphQL-Client V1_1
graphQL-Handshake
graphQL-Handshake
GraphQL-Client V1_0
GraphQL-Client V1_0
graphQL-Handshake
graphQL-Handshake
graphQL-Handshake
graphQL-Handshake
Viewer does not support full SVG 1.1
\ No newline at end of file From d6044b4fe61bd26ec0ba7318523d12c1318bbb22 Mon Sep 17 00:00:00 2001 From: Einhornimmond Date: Thu, 16 Feb 2023 14:46:12 +0100 Subject: [PATCH 02/37] correct error with gdt server in graphic --- .../graphics/TechnicalOverview_V1-19.drawio | 144 +++++++++--------- .../image/TechnicalOverview_V1-19.svg | 2 +- 2 files changed, 73 insertions(+), 73 deletions(-) diff --git a/docu/Concepts/TechnicalRequirements/graphics/TechnicalOverview_V1-19.drawio b/docu/Concepts/TechnicalRequirements/graphics/TechnicalOverview_V1-19.drawio index 534804e1d..3ce2508d9 100644 --- a/docu/Concepts/TechnicalRequirements/graphics/TechnicalOverview_V1-19.drawio +++ b/docu/Concepts/TechnicalRequirements/graphics/TechnicalOverview_V1-19.drawio @@ -1,277 +1,277 @@ - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + diff --git a/docu/Concepts/TechnicalRequirements/image/TechnicalOverview_V1-19.svg b/docu/Concepts/TechnicalRequirements/image/TechnicalOverview_V1-19.svg index 4b407aa5a..2f5264182 100644 --- a/docu/Concepts/TechnicalRequirements/image/TechnicalOverview_V1-19.svg +++ b/docu/Concepts/TechnicalRequirements/image/TechnicalOverview_V1-19.svg @@ -1 +1 @@ -
Community  "Gradido-Akademie"
Community  "Gradido-Akademie"
Gradido - technical Infrastructure-Overview
State of 02.2023
Gradido - technical Infrastructure-Overview...
Backend-Modul
GraphQL-API
Backend-Modul...
CommunityServer DB
CommunityServer DB
Layer 1:
Layer 1:
Layer 2:
Layer 2:
"GDT-Server"
base on C++ + mySQL
"GDT-Server"...
GDT-Server DB
GDT-Server DB
json-
ajax-
request
json-...
Layer 3:
Layer 3:
"Elopage"
external Service-Portal
"Elopage"...
"User-UI"
"User-UI"
graphql
graphql
json-
request
json-...
graphql
graphql
"Admin-UI"
"Admin-UI"
DHT-Modul
HyperSwarm
DHT-Modul...
Federation-Modul
GraphQL-API V2_0
Federation-Modul...
Federation-Modul
GraphQL-API V1_x
Federation-Modul...
Federation-Modul
GraphQL-API V1_1
Federation-Modul...
Federation-Modul
GraphQL-API V1_0
Federation-Modul...
GraphQL-Client V1_0
GraphQL-Client V1_0
GraphQL-Client V1_0
GraphQL-Client V1_0
GraphQL-Client V1_0
GraphQL-Client V1_0
GraphQL-Client V1_0
GraphQL-Client V1_0
Community "GallischesDorf-TBB"
Community "GallischesDorf-TBB"
Backend-Modul
GraphQL-API
Backend-Modul...
CommunityServer DB
CommunityServer DB
Layer 1:
Layer 1:
Layer 2:
Layer 2:
Layer 3:
Layer 3:
"User-UI"
"User-UI"
graphql
graphql
graphql
graphql
"Admin-UI"
"Admin-UI"
 DHT-Socket Communication 
 DHT-Socket Communication 
DHT-Modul
HyperSwarm
DHT-Modul...
Federation-Modul
GraphQL-API V1_1
Federation-Modul...
Federation-Modul
GraphQL-API V1_0
Federation-Modul...
graphQL-Handshake
graphQL-Handshake
GraphQL-Client V1_1
GraphQL-Client V1_1
graphQL-Handshake
graphQL-Handshake
GraphQL-Client V1_0
GraphQL-Client V1_0
graphQL-Handshake
graphQL-Handshake
graphQL-Handshake
graphQL-Handshake
Viewer does not support full SVG 1.1
\ No newline at end of file +
Community  "Gradido-Akademie"
Community  "Gradido-Akademie"
Gradido - technical Infrastructure-Overview
State of 02.2023
Gradido - technical Infrastructure-Overview...
Backend-Modul
GraphQL-API
Backend-Modul...
CommunityServer DB
CommunityServer DB
Layer 1:
Layer 1:
Layer 2:
Layer 2:
"GDT-Server"
base on cakephp + mySQL
"GDT-Server"...
GDT-Server DB
GDT-Server DB
json-
ajax-
request
json-...
Layer 3:
Layer 3:
"Elopage"
external Service-Portal
"Elopage"...
"User-UI"
"User-UI"
graphql
graphql
json-
request
json-...
graphql
graphql
"Admin-UI"
"Admin-UI"
DHT-Modul
HyperSwarm
DHT-Modul...
Federation-Modul
GraphQL-API V2_0
Federation-Modul...
Federation-Modul
GraphQL-API V1_x
Federation-Modul...
Federation-Modul
GraphQL-API V1_1
Federation-Modul...
Federation-Modul
GraphQL-API V1_0
Federation-Modul...
GraphQL-Client V1_0
GraphQL-Client V1_0
GraphQL-Client V1_0
GraphQL-Client V1_0
GraphQL-Client V1_0
GraphQL-Client V1_0
GraphQL-Client V1_0
GraphQL-Client V1_0
Community "GallischesDorf-TBB"
Community "GallischesDorf-TBB"
Backend-Modul
GraphQL-API
Backend-Modul...
CommunityServer DB
CommunityServer DB
Layer 1:
Layer 1:
Layer 2:
Layer 2:
Layer 3:
Layer 3:
"User-UI"
"User-UI"
graphql
graphql
graphql
graphql
"Admin-UI"
"Admin-UI"
 DHT-Socket Communication 
 DHT-Socket Communication 
DHT-Modul
HyperSwarm
DHT-Modul...
Federation-Modul
GraphQL-API V1_1
Federation-Modul...
Federation-Modul
GraphQL-API V1_0
Federation-Modul...
graphQL-Handshake
graphQL-Handshake
GraphQL-Client V1_1
GraphQL-Client V1_1
graphQL-Handshake
graphQL-Handshake
GraphQL-Client V1_0
GraphQL-Client V1_0
graphQL-Handshake
graphQL-Handshake
graphQL-Handshake
graphQL-Handshake
Text is not SVG - cannot display
\ No newline at end of file From d3a1b8afe5844cf179fad61f6da8212fcb7e8249 Mon Sep 17 00:00:00 2001 From: clauspeterhuebner <86960882+clauspeterhuebner@users.noreply.github.com> Date: Mon, 27 Feb 2023 12:32:22 +0100 Subject: [PATCH 03/37] Update docu/Concepts/TechnicalRequirements/Federation.md Co-authored-by: Ulf Gebhardt --- docu/Concepts/TechnicalRequirements/Federation.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/docu/Concepts/TechnicalRequirements/Federation.md b/docu/Concepts/TechnicalRequirements/Federation.md index 7210756ff..5e674e7d1 100644 --- a/docu/Concepts/TechnicalRequirements/Federation.md +++ b/docu/Concepts/TechnicalRequirements/Federation.md @@ -26,7 +26,7 @@ At first the following diagramm gives an overview of the three stages and shows ### Technical Architecture -The previous described handshake will be done by several technical moduls of the gradido system. The following picture gives an overview about the moduls and how the communicate with each other. +The previous described handshake will be done by several technical modules of the gradido system. The following picture gives an overview about the modules and how the communicate with each other. ![img](./image/TechnicalOverview_V1-19.svg) From 73ce45034401c6a409215d3b9f54c9dcf00823e1 Mon Sep 17 00:00:00 2001 From: clauspeterhuebner <86960882+clauspeterhuebner@users.noreply.github.com> Date: Mon, 27 Feb 2023 12:35:45 +0100 Subject: [PATCH 04/37] Update docu/Concepts/TechnicalRequirements/Federation.md Co-authored-by: Ulf Gebhardt --- docu/Concepts/TechnicalRequirements/Federation.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/docu/Concepts/TechnicalRequirements/Federation.md b/docu/Concepts/TechnicalRequirements/Federation.md index 5e674e7d1..afa7116d3 100644 --- a/docu/Concepts/TechnicalRequirements/Federation.md +++ b/docu/Concepts/TechnicalRequirements/Federation.md @@ -34,7 +34,7 @@ As soon as a Gradido Community is up and running the DHT-Modul first write the h The up and running Backend-Modul contains a validation logic to verify the community entries from the own DHT-Modul. For each announced but unverified community-entry the GraphQL-Client is used to invoke a getPublicKey-Request. Depending on the containing api-version the matching GraphQL-Client is used and the getPublicKey-Request will be send to the given URL. -As soon as the FederationModul of the assoziated community received the getPublicKey-request the own publicKey is read from database and send back in the response. +As soon as the FederationModul of the associated community received the getPublicKey-request the own publicKey is read from database and send back in the response. The GraphQL-Client will read from the returned response data the publicKey of the other community and compare it with the data of the community-entry, which cause the getPublicKey-Request. If they match the community-entry will be updated be inserting the current timestamp in the verifiedAt-field of this community-entry. From b617149138ec1c161ecf70f31a3fe34e12a196c3 Mon Sep 17 00:00:00 2001 From: clauspeterhuebner <86960882+clauspeterhuebner@users.noreply.github.com> Date: Mon, 27 Feb 2023 12:36:02 +0100 Subject: [PATCH 05/37] Update docu/Concepts/TechnicalRequirements/Federation.md Co-authored-by: Ulf Gebhardt --- docu/Concepts/TechnicalRequirements/Federation.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/docu/Concepts/TechnicalRequirements/Federation.md b/docu/Concepts/TechnicalRequirements/Federation.md index afa7116d3..a5ecc984d 100644 --- a/docu/Concepts/TechnicalRequirements/Federation.md +++ b/docu/Concepts/TechnicalRequirements/Federation.md @@ -36,7 +36,7 @@ The up and running Backend-Modul contains a validation logic to verify the commu As soon as the FederationModul of the associated community received the getPublicKey-request the own publicKey is read from database and send back in the response. -The GraphQL-Client will read from the returned response data the publicKey of the other community and compare it with the data of the community-entry, which cause the getPublicKey-Request. If they match the community-entry will be updated be inserting the current timestamp in the verifiedAt-field of this community-entry. +The GraphQL-Client will read the publicKey of the other community from the returned response data and compare it with the data of the community-entry, which caused the getPublicKey-Request. If they match the community-entry will be updated be inserting the current timestamp in the verifiedAt-field of this community-entry. This federation and verification logic will work the whole time and can be monitored by observing the communities-table changes. The Admin-UI will contain a Page to have a look on the current state of the communities table content. From c89a1916aea0ad0f78283df749f05262166d2a8a Mon Sep 17 00:00:00 2001 From: clauspeterhuebner <86960882+clauspeterhuebner@users.noreply.github.com> Date: Mon, 27 Feb 2023 12:37:04 +0100 Subject: [PATCH 06/37] Update docu/Concepts/TechnicalRequirements/Federation.md Co-authored-by: Hannes Heine --- docu/Concepts/TechnicalRequirements/Federation.md | 2 -- 1 file changed, 2 deletions(-) diff --git a/docu/Concepts/TechnicalRequirements/Federation.md b/docu/Concepts/TechnicalRequirements/Federation.md index a5ecc984d..6ba5589e3 100644 --- a/docu/Concepts/TechnicalRequirements/Federation.md +++ b/docu/Concepts/TechnicalRequirements/Federation.md @@ -277,8 +277,6 @@ As soon the *openConnection* request is invoked: 3. check if the decrypted `parameter.signedAndEncryptedURL` is equals the selected url from the previous selected CommunityFederationEntry 1. if not then break the further processing of this request by only writing an error-log event. There will be no answer to the invoker community, because this community will only go on with a `openConnectionRedirect`-request from this community. 2. if yes then verify the signature of `parameter.signedAndEncryptedURL` with the `cf.pubKey` read in step 2 before - 3. -4. ### Stage3 - Autorized Business Communication From 66d077c256897501d89f15998d8610c89bb4e159 Mon Sep 17 00:00:00 2001 From: clauspeterhuebner <86960882+clauspeterhuebner@users.noreply.github.com> Date: Mon, 27 Feb 2023 12:37:14 +0100 Subject: [PATCH 07/37] Update docu/Concepts/TechnicalRequirements/Federation.md Co-authored-by: Hannes Heine --- docu/Concepts/TechnicalRequirements/Federation.md | 1 - 1 file changed, 1 deletion(-) diff --git a/docu/Concepts/TechnicalRequirements/Federation.md b/docu/Concepts/TechnicalRequirements/Federation.md index 6ba5589e3..f9a94d7a1 100644 --- a/docu/Concepts/TechnicalRequirements/Federation.md +++ b/docu/Concepts/TechnicalRequirements/Federation.md @@ -228,7 +228,6 @@ For the first federation release the *DHT-Node* will be part of the *apollo serv | communityApiVersion.apiversion | keep existing value | | communityApiVersion.validFrom | exchangedData.API.validFrom | | communityApiVersion.verifiedAt | keep existing value | - * 3. After all received data is stored successfully, the *DHT-Node* starts the *stage2 - Authentication* of the federation handshake ### Stage2 - Authentication From abcad503b000c97315104321c7350aa06c1e0428 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Claus-Peter=20H=C3=BCbner?= Date: Mon, 6 Mar 2023 22:40:41 +0100 Subject: [PATCH 08/37] optimize log-output --- federation/src/graphql/api/1_0/resolver/PublicKeyResolver.ts | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/federation/src/graphql/api/1_0/resolver/PublicKeyResolver.ts b/federation/src/graphql/api/1_0/resolver/PublicKeyResolver.ts index 53f0d0bd4..8670c3d1d 100644 --- a/federation/src/graphql/api/1_0/resolver/PublicKeyResolver.ts +++ b/federation/src/graphql/api/1_0/resolver/PublicKeyResolver.ts @@ -7,12 +7,12 @@ import { GetPublicKeyResult } from '../model/GetPublicKeyResult' export class PublicKeyResolver { @Query(() => GetPublicKeyResult) async getPublicKey(): Promise { - logger.info(`getPublicKey()...`) + logger.debug(`getPublicKey() via apiVersion=1_0 ...`) const homeCom = await DbCommunity.findOneOrFail({ foreign: false, apiVersion: '1_0', }) - logger.info(`getPublicKey()... with publicKey=${homeCom.publicKey}`) + logger.info(`getPublicKey()-1_0... return publicKey=${homeCom.publicKey}`) return new GetPublicKeyResult(homeCom.publicKey.toString()) } } From 46831167bc905345283bfd0807a81c2d2744a893 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Claus-Peter=20H=C3=BCbner?= Date: Tue, 7 Mar 2023 01:14:18 +0100 Subject: [PATCH 09/37] new testclass --- .../1_0/resolver/PublicKeyResolver.test.ts | 54 +++++++++++++++++++ 1 file changed, 54 insertions(+) create mode 100644 federation/src/graphql/api/1_0/resolver/PublicKeyResolver.test.ts diff --git a/federation/src/graphql/api/1_0/resolver/PublicKeyResolver.test.ts b/federation/src/graphql/api/1_0/resolver/PublicKeyResolver.test.ts new file mode 100644 index 000000000..1622c7be4 --- /dev/null +++ b/federation/src/graphql/api/1_0/resolver/PublicKeyResolver.test.ts @@ -0,0 +1,54 @@ +/* eslint-disable @typescript-eslint/no-explicit-any */ +/* eslint-disable @typescript-eslint/explicit-module-boundary-types */ +import { createTestClient } from 'apollo-server-testing' +import createServer from '@/server/createServer' +import { Community as DbCommunity } from '@entity/Community' + +let query: any +let testEnv: any + +// to do: We need a setup for the tests that closes the connection +let con: any + +beforeAll(async () => { + const server = await createServer() + con = server.con + query = createTestClient(server.apollo).query + DbCommunity.clear() +}) + +afterAll(async () => { + await con.close() +}) + +describe('PublicKeyResolver', () => { + const getPublicKeyQuery = ` + query { + getPublicKey + { + publicKey + } + } + ` + + describe('getPublicKey', () => { + beforeEach(async () => { + const homeCom = new DbCommunity() + homeCom.foreign = false + homeCom.apiVersion = '1_0' + homeCom.endPoint = 'endpoint-url' + homeCom.publicKey = Buffer.from('homeCommunity-publicKey') + await DbCommunity.insert(homeCom) + }) + + it('returns homeCommunity-publicKey', async () => { + await expect(query({ query: getPublicKeyQuery })).resolves.toMatchObject({ + data: { + getPublicKey: { + publicKey: 'homeCommunity-publicKey', + }, + }, + }) + }) + }) +}) From c71e293e6732ae68ca7673c6698e445f6d311d10 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Claus-Peter=20H=C3=BCbner?= Date: Tue, 7 Mar 2023 03:48:43 +0100 Subject: [PATCH 10/37] next try for test --- .../src/graphql/api/1_0/resolver/PublicKeyResolver.test.ts | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/federation/src/graphql/api/1_0/resolver/PublicKeyResolver.test.ts b/federation/src/graphql/api/1_0/resolver/PublicKeyResolver.test.ts index 1622c7be4..25fde9f3c 100644 --- a/federation/src/graphql/api/1_0/resolver/PublicKeyResolver.test.ts +++ b/federation/src/graphql/api/1_0/resolver/PublicKeyResolver.test.ts @@ -42,13 +42,14 @@ describe('PublicKeyResolver', () => { }) it('returns homeCommunity-publicKey', async () => { - await expect(query({ query: getPublicKeyQuery })).resolves.toMatchObject({ + await expect(query({ query: getPublicKeyQuery })).resolves.toEqual(expect.objectContaining({ data: { getPublicKey: { publicKey: 'homeCommunity-publicKey', }, }, }) + ) }) }) }) From b604be584780e774789e3a52dd333cb0c6011e4f Mon Sep 17 00:00:00 2001 From: Moriz Wahl Date: Tue, 7 Mar 2023 17:16:53 +0100 Subject: [PATCH 11/37] object as arg for find contributions --- .../graphql/resolver/ContributionResolver.ts | 27 +++++++++---------- .../resolver/util/findContributions.ts | 27 ++++++++++++------- 2 files changed, 30 insertions(+), 24 deletions(-) diff --git a/backend/src/graphql/resolver/ContributionResolver.ts b/backend/src/graphql/resolver/ContributionResolver.ts index ab177d759..5946b0237 100644 --- a/backend/src/graphql/resolver/ContributionResolver.ts +++ b/backend/src/graphql/resolver/ContributionResolver.ts @@ -135,15 +135,15 @@ export class ContributionResolver { ): Promise { const user = getUser(context) - const [dbContributions, count] = await findContributions( + const [dbContributions, count] = await findContributions({ order, currentPage, pageSize, - true, - ['messages'], - user.id, + withDeleted: true, + relations: ['messages'], + userId: user.id, statusFilter, - ) + }) return new ContributionListResult( count, dbContributions.map((contribution) => new Contribution(contribution, user)), @@ -158,15 +158,13 @@ export class ContributionResolver { @Arg('statusFilter', () => [ContributionStatus], { nullable: true }) statusFilter?: ContributionStatus[], ): Promise { - const [dbContributions, count] = await findContributions( + const [dbContributions, count] = await findContributions({ order, currentPage, pageSize, - false, - ['user'], - undefined, + relations: ['user'], statusFilter, - ) + }) return new ContributionListResult( count, @@ -386,15 +384,14 @@ export class ContributionResolver { @Arg('statusFilter', () => [ContributionStatus], { nullable: true }) statusFilter?: ContributionStatus[], ): Promise { - const [dbContributions, count] = await findContributions( + const [dbContributions, count] = await findContributions({ order, currentPage, pageSize, - true, - ['user'], - undefined, + withDeleted: true, + relations: ['user'], statusFilter, - ) + }) return new ContributionListResult( count, diff --git a/backend/src/graphql/resolver/util/findContributions.ts b/backend/src/graphql/resolver/util/findContributions.ts index 5201284aa..48f08f041 100644 --- a/backend/src/graphql/resolver/util/findContributions.ts +++ b/backend/src/graphql/resolver/util/findContributions.ts @@ -3,16 +3,24 @@ import { Order } from '@enum/Order' import { Contribution as DbContribution } from '@entity/Contribution' import { In } from '@dbTools/typeorm' +interface FindContributionsOptions { + order: Order + currentPage: number + pageSize: number + withDeleted?: boolean + relations?: string[] + userId?: number + statusFilter?: ContributionStatus[] +} + export const findContributions = async ( - order: Order, - currentPage: number, - pageSize: number, - withDeleted: boolean, - relations: string[], - userId?: number, - statusFilter?: ContributionStatus[], -): Promise<[DbContribution[], number]> => - DbContribution.findAndCount({ + options: FindContributionsOptions, +): Promise<[DbContribution[], number]> => { + const { order, currentPage, pageSize, withDeleted, relations, userId, statusFilter } = { + withDeleted: false, + ...options, + } + return DbContribution.findAndCount({ where: { ...(statusFilter && statusFilter.length && { contributionStatus: In(statusFilter) }), ...(userId && { userId }), @@ -26,3 +34,4 @@ export const findContributions = async ( skip: (currentPage - 1) * pageSize, take: pageSize, }) +} From e48bbd7b47baf70857aac67506018b1aa52e29ae Mon Sep 17 00:00:00 2001 From: Moriz Wahl Date: Tue, 7 Mar 2023 17:33:18 +0100 Subject: [PATCH 12/37] rename admin list all contributions query --- ...ributions.js => adminListContributions.js} | 4 ++-- admin/src/pages/CreationConfirm.spec.js | 20 +++++++++---------- admin/src/pages/CreationConfirm.vue | 10 +++++----- admin/src/pages/Overview.spec.js | 14 ++++++------- admin/src/pages/Overview.vue | 8 ++++---- backend/src/auth/RIGHTS.ts | 2 +- .../resolver/ContributionResolver.test.ts | 20 +++++++++---------- .../graphql/resolver/ContributionResolver.ts | 6 +++--- backend/src/seeds/graphql/queries.ts | 4 ++-- 9 files changed, 44 insertions(+), 44 deletions(-) rename admin/src/graphql/{adminListAllContributions.js => adminListContributions.js} (88%) diff --git a/admin/src/graphql/adminListAllContributions.js b/admin/src/graphql/adminListContributions.js similarity index 88% rename from admin/src/graphql/adminListAllContributions.js rename to admin/src/graphql/adminListContributions.js index cd47cd1d4..7b6848bd5 100644 --- a/admin/src/graphql/adminListAllContributions.js +++ b/admin/src/graphql/adminListContributions.js @@ -1,13 +1,13 @@ import gql from 'graphql-tag' -export const adminListAllContributions = gql` +export const adminListContributions = gql` query ( $currentPage: Int = 1 $pageSize: Int = 25 $order: Order = DESC $statusFilter: [ContributionStatus!] ) { - adminListAllContributions( + adminListContributions( currentPage: $currentPage pageSize: $pageSize order: $order diff --git a/admin/src/pages/CreationConfirm.spec.js b/admin/src/pages/CreationConfirm.spec.js index 87f94e91f..c9d9661c2 100644 --- a/admin/src/pages/CreationConfirm.spec.js +++ b/admin/src/pages/CreationConfirm.spec.js @@ -2,7 +2,7 @@ import { mount } from '@vue/test-utils' import CreationConfirm from './CreationConfirm' import { adminDeleteContribution } from '../graphql/adminDeleteContribution' import { denyContribution } from '../graphql/denyContribution' -import { adminListAllContributions } from '../graphql/adminListAllContributions' +import { adminListContributions } from '../graphql/adminListContributions' import { confirmContribution } from '../graphql/confirmContribution' import { toastErrorSpy, toastSuccessSpy } from '../../test/testSetup' import VueApollo from 'vue-apollo' @@ -38,7 +38,7 @@ const mocks = { const defaultData = () => { return { - adminListAllContributions: { + adminListContributions: { contributionCount: 2, contributionList: [ { @@ -92,14 +92,14 @@ const defaultData = () => { describe('CreationConfirm', () => { let wrapper - const adminListAllContributionsMock = jest.fn() + const adminListContributionsMock = jest.fn() const adminDeleteContributionMock = jest.fn() const adminDenyContributionMock = jest.fn() const confirmContributionMock = jest.fn() mockClient.setRequestHandler( - adminListAllContributions, - adminListAllContributionsMock + adminListContributions, + adminListContributionsMock .mockRejectedValueOnce({ message: 'Ouch!' }) .mockResolvedValue({ data: defaultData() }), ) @@ -337,7 +337,7 @@ describe('CreationConfirm', () => { }) it('refetches contributions with proper filter', () => { - expect(adminListAllContributionsMock).toBeCalledWith({ + expect(adminListContributionsMock).toBeCalledWith({ currentPage: 1, order: 'DESC', pageSize: 25, @@ -352,7 +352,7 @@ describe('CreationConfirm', () => { }) it('refetches contributions with proper filter', () => { - expect(adminListAllContributionsMock).toBeCalledWith({ + expect(adminListContributionsMock).toBeCalledWith({ currentPage: 1, order: 'DESC', pageSize: 25, @@ -368,7 +368,7 @@ describe('CreationConfirm', () => { }) it('refetches contributions with proper filter', () => { - expect(adminListAllContributionsMock).toBeCalledWith({ + expect(adminListContributionsMock).toBeCalledWith({ currentPage: 1, order: 'DESC', pageSize: 25, @@ -384,7 +384,7 @@ describe('CreationConfirm', () => { }) it('refetches contributions with proper filter', () => { - expect(adminListAllContributionsMock).toBeCalledWith({ + expect(adminListContributionsMock).toBeCalledWith({ currentPage: 1, order: 'DESC', pageSize: 25, @@ -400,7 +400,7 @@ describe('CreationConfirm', () => { }) it('refetches contributions with proper filter', () => { - expect(adminListAllContributionsMock).toBeCalledWith({ + expect(adminListContributionsMock).toBeCalledWith({ currentPage: 1, order: 'DESC', pageSize: 25, diff --git a/admin/src/pages/CreationConfirm.vue b/admin/src/pages/CreationConfirm.vue index 55b819268..aad03ffde 100644 --- a/admin/src/pages/CreationConfirm.vue +++ b/admin/src/pages/CreationConfirm.vue @@ -73,7 +73,7 @@