diff --git a/.env b/.env
new file mode 100644
index 0000000000..341dd7d012
--- /dev/null
+++ b/.env
@@ -0,0 +1,4 @@
+## GUARDIAN ECOSYSTEM ENVIRONMENT NAME
+# if you already started to use actively Guardian leave GUARDIAN_ENV empty when you want to use it as usual
+# if you want to use a new environment configure GUARDIAN_ENV with a significative environment name
+GUARDIAN_ENV=""
diff --git a/.env.example b/.env.example
deleted file mode 100644
index 70954594c0..0000000000
--- a/.env.example
+++ /dev/null
@@ -1,14 +0,0 @@
-# guardian service
-OPERATOR_ID="..."
-OPERATOR_KEY="..."
-SCHEMA_TOPIC_ID="..."
-HEDERA_NET="testnet"
-INITIALIZATION_TOPIC_ID="0.0.2030"
-MESSAGE_LANG="en-US"
-LOG_LEVEL="2"
-MAX_TRANSACTION_FEE="20"
-INITIAL_BALANCE="30"
-INITIAL_STANDARD_REGISTRY_BALANCE=100
-
-# IPFS
-IPFS_STORAGE_API_KEY="..."
diff --git a/.env.template b/.env.template
new file mode 100644
index 0000000000..341dd7d012
--- /dev/null
+++ b/.env.template
@@ -0,0 +1,4 @@
+## GUARDIAN ECOSYSTEM ENVIRONMENT NAME
+# if you already started to use actively Guardian leave GUARDIAN_ENV empty when you want to use it as usual
+# if you want to use a new environment configure GUARDIAN_ENV with a significative environment name
+GUARDIAN_ENV=""
diff --git a/.gitignore b/.gitignore
index d45f0007c0..9d2b08eca0 100644
--- a/.gitignore
+++ b/.gitignore
@@ -1,3 +1,4 @@
+.env
node_modules/
dist/
.vscode/
@@ -16,6 +17,7 @@ tsconfig.tsbuildinfo
.pnp.*
node_modules
runtime-data/
+000_*
# OSX related metadata removal and IDE nonsense
.DS_store
diff --git a/Makefile.justCOMPILE b/Makefile.justCOMPILE
new file mode 100644
index 0000000000..bdd06cc22e
--- /dev/null
+++ b/Makefile.justCOMPILE
@@ -0,0 +1,12 @@
+guardian_build:
+ cd interfaces && npm install && npm run build --prod
+ cd common && npm install && npm run build --prod
+ cd logger-service && npm install && npm run build --prod
+ cd api-gateway && npm install && npm run build --prod
+ cd auth-service && npm install && npm run build --prod
+ cd worker-service && npm install && npm run build --prod
+ cd guardian-service && npm install && npm run build --prod
+ cd policy-service && npm install && npm run build --prod
+ cd topic-viewer && npm install && npm run build --prod
+ cd mrv-sender && npm install && npm run build --prod
+ cd frontend && npm install && export NODE_OPTIONS=--openssl-legacy-provider && npm run build --prod
diff --git a/Methodology Library/CDM/CDM.policy b/Methodology Library/CDM/CDM.policy
new file mode 100644
index 0000000000..df77e34614
Binary files /dev/null and b/Methodology Library/CDM/CDM.policy differ
diff --git a/Methodology Library/CDM/readme.md b/Methodology Library/CDM/readme.md
new file mode 100644
index 0000000000..baf1add063
--- /dev/null
+++ b/Methodology Library/CDM/readme.md
@@ -0,0 +1,23 @@
+## CDM AR-ACM0003: Methodology for Afforestation and Reforestation of Lands Except Wetlands
+
+**Policy Description**:
+
+The CDM AR-ACM0003 methodology is a comprehensive framework developed under the Clean Development Mechanism (CDM) to guide afforestation and reforestation projects aimed at combating climate change and promoting sustainable land use practices. This methodology facilitates the identification of suitable project sites, establishes baselines for measuring greenhouse gas emissions, ensures the additionality of emissions reductions, implements robust monitoring and reporting systems, addresses leakage and permanence concerns, and seeks validation and certification from accredited entities. By adhering to this methodology, projects can effectively sequester carbon dioxide, conserve biodiversity, provide ecosystem services, and generate socio-economic co-benefits, contributing to global climate change mitigation and sustainable development goals.
+
+The Guardian policy for afforestation and reforestation of lands except wetlands (AR-ACM0003) incorporates schemas for project details, baseline scenario GHG removals, project scenario GHG removals, project scenario emissions, and leakage. These schemas provide a structured framework for site selection, emissions quantification, and monitoring procedures.
+
+**Workflow Description**:
+
+The workflow for the afforestation and reforestation of lands except wetlands (AR-ACM0003) Guardian policy involves the Project Proponent preparing and submitting the project description, which is then reviewed and approved by the Designated National Authority (DNA). The UNFCCC Secretariat adds the approved project to the project pipeline and registry. The Project Proponent conducts monitoring and submits the monitoring report to the Designated Operational Entity (VVB) for assessment and validation. Upon certification by the VVB, the UNFCCC Secretariat reviews the project and issues Certified Emission Reductions (CERs).
+
+
+
+**Note** :
+For Demo purpose, we have uploaded CDM Policy into IPFS and created Timestamps, which are mentioned in the below table.
+
+**Verra REDD Versions and their IPFS timestamps:**
+
+| Version | IPFS Timestamp | Policy File Link | Version Differences |
+|---|---|---|---:|
+| CDM AR-ACM0003 | 1684768427.831434003 | [Link](https://github.com/hashgraph/guardian/blob/main/Methodology%20Library/CDM/CDM.policy) | CDM AR-ACM0003 Methodology |
+
diff --git a/Methodology Library/Improved CookStove/policies/Improved Cookstove Policy - Agent Application Subpolicy.policy b/Methodology Library/Improved CookStove/policies/Improved Cookstove Policy - Agent Application Subpolicy.policy
new file mode 100644
index 0000000000..92fdb53efa
Binary files /dev/null and b/Methodology Library/Improved CookStove/policies/Improved Cookstove Policy - Agent Application Subpolicy.policy differ
diff --git a/Methodology Library/Improved CookStove/policies/Improved Cookstove Policy - MR Verification Subpolicy.policy b/Methodology Library/Improved CookStove/policies/Improved Cookstove Policy - MR Verification Subpolicy.policy
new file mode 100644
index 0000000000..57920cad99
Binary files /dev/null and b/Methodology Library/Improved CookStove/policies/Improved Cookstove Policy - MR Verification Subpolicy.policy differ
diff --git a/Methodology Library/Improved CookStove/policies/Improved Cookstove Policy - PDD Validation Subpolicy.policy b/Methodology Library/Improved CookStove/policies/Improved Cookstove Policy - PDD Validation Subpolicy.policy
new file mode 100644
index 0000000000..57e9f7934c
Binary files /dev/null and b/Methodology Library/Improved CookStove/policies/Improved Cookstove Policy - PDD Validation Subpolicy.policy differ
diff --git a/Methodology Library/Improved CookStove/policies/Improved Cookstove Policy.policy b/Methodology Library/Improved CookStove/policies/Improved Cookstove Policy.policy
new file mode 100644
index 0000000000..ad99a51830
Binary files /dev/null and b/Methodology Library/Improved CookStove/policies/Improved Cookstove Policy.policy differ
diff --git a/Methodology Library/Improved CookStove/policies/policy_1666966023463.policy b/Methodology Library/Improved CookStove/policies/policy_1666966023463.policy
deleted file mode 100644
index 240db45141..0000000000
Binary files a/Methodology Library/Improved CookStove/policies/policy_1666966023463.policy and /dev/null differ
diff --git a/Methodology Library/Improved CookStove/readme.md b/Methodology Library/Improved CookStove/readme.md
index f900f31d60..ff1c563aac 100644
--- a/Methodology Library/Improved CookStove/readme.md
+++ b/Methodology Library/Improved CookStove/readme.md
@@ -1,75 +1,136 @@
## Guardian Policy for Improved Cookstoves
-**Introduction**:
+**Introduction**
Currently, there are many different types of cookstoves and several Standards Bodies, each with their own Standard that must be followed in order to prove the quality of a given GHG emission reduction claim. This process is time and labor intensive, creating barriers to those willing to enter the market. Digitization of this manual, paper driven process is a necessary step to scaling at the speed required for climate change.
The Value of Digitizing the Methodology:
-Creates trust via
+1. Creates trust via
+- Traceability and transparency of data
+- Digital quality assurance
+- Immutability of data
+- Transparency of Verifier credentials and approval data
+
+2. Reduces barriers to entry
+- Accessible and standardized policies and processes inform and encourage suppliers to bring their projects to market
+- Decentralized project management reduces dependency on Standards Bodies and reduces time to market.
+
+3. Contributes to Climate Goals
+- Achieves higher confidence carbon project outcomes, and scales the finance and rollout of carbon projects at the speed required by the climate emergency
+
+This first of its kind Hedera Guardian Improved Cookstove Policy (ICP) was designed per the [Anthropogenic Impact Accounting Ontology](https://wiki.hyperledger.org/display/CASIG/An+ontology+for+anthropogenic+impact+accounting). To this end, the Guardian Policy does not adhere to a specific Standard or approved methodology for carbon offset quantification, rather it abstracts concepts from the most commonly used standards and methodologies, categorizes them, models their relationships, and then instantiates them in the form of this digitally native Guardian Policy and its associated Guardian Schema. This policy issues a non-fungible Improved Cookstove Carbon Credit (ICCC) Token.
+
+**Scope and Applicability**
+
+Scope: Quantification of greenhouse gas (GHG) emission reductions from improved biomass cookstoves developed by the Nova Institute and Tolam Earth, Inc.
+
+Applicability: Applicable to activities reducing GHG emissions from cookstoves through switching to more energy efficient stoves.
+
+Token: Non-Fungible
+
+Type: Carbon Offset
+
+Standard: Multiple
+
+Methodology: Multiple
+
+Required Documents: Project Design Document (PDD), PDD Validation Report, Monitoring Report, Monitoring Report Verification, Double Counting Certification, VVB Certification and Conflict of Interest Statement. See 'Preconditions' below for more detail.
+
+NFT Owner: The agent fulfilling the 'Project Developer' role.
+
+**Preconditions**
+
+1. Standard Registry account on a Guardian instance to import the policy and its subpolicies. See [Guardian documentation](https://docs.hedera.com/guardian/policy-creation-using-the-guardian-apis/prerequesite-steps) for steps to create an account and import a policy.
+2. User accounts within the Guardian to fill the roles defined in the policy and its subpolicies.
+3. Required Project Documentation posted to traceable, immutable source which can be accessed by the Tolam Earth Marketplace.
+4. To fulfil the Project Developer role (see 'Roles' below for details), an agent must obtain an HGICP Project Developer License (HGICP-L-PD) from the ICP Agent Application Subpolicy.
+5. To fulfil the PDD Validator role, an agent must obtain an HGICP PDD Validator License (HGICP-L-PV) from the ICP Agent Application Subpolicy.
+6. To fulfil the MR Verifier role, an agent must obtain an HGICP MR Verifier License (HGICP-L-MV) form the ICP Agent Application Subpolicy.
+7. In addition to an HGICP-L-PD, a Project Developer will need to obtain an HGICP PDD Validation Certificate (HGICP-VCERT-PDD, issued by the ICP PDD Validation Subpolicy) to complete the project registration step of the main policy. To apply for an ICCC issuance, a Project Developer will furthermore need to obtain an HGICP MR Verification Certificate (HGICP-VCERT-MR, issued by the ICP MR Verification Subpolicy).
+
+Testnet message IDs:
+- Improved Cookstove Policy (main): 1676641566.153212434
+- Improved Cookstove Policy - Agent Application Subpolicy: 1676640723.598879583
+- Improved Cookstove Policy - PDD Validation Subpolicy: 1676641042.365033796
+- Improved Cookstove Policy - MR Verification Subpolicy: 1676641311.452316505
+
+**Policy User Roles**
+
+Improved Cookstove Policy (main):
+1. Project Developer (PROJECT_DEVELOPER): Person responsible for executing the Project Design and collecting Data as per the Project Application. The Project Developer submits Monitoring Reports and is the beneficiary of the Credit Claims.
+2. Public Viewer (VIEWER): Any member of the public who wishes to view the Guardian TrustChain for a specific ICCC issuance.
+3. Standard Body (OWNER): Administrative role that approves Verifiers, approves Project Applications, and manages the issuance of claims.
+
+Improved Cookstove Policy - Agent Application Subpolicy:
+1. (Anyone): Any person or legal entity who wishes to fulfil one or more of the following ICP roles:
+- Project Developer (in any of the four policies)
+- PDD Validator (in the PDD Validation Subpolicy)
+- MR Verifier (in the MR Verification Subpolicy)
+2. Standard Body (OWNER): See Improved Cookstove Policy (main).
+
+Improved Cookstove Policy - PDD Validation Subpolicy:
+1. Project Developer (PROJECT_DEVELOPER): See Improved Cookstove Policy (main).
+2. Validator (VALIDATOR): An agent who validates Project Designs by reviewing Project Design Documents.
+3. Public Viewer: Not yet implemented.
+
+Improved Cookstove Policy - MR Verification Subpolicy:
+1. Project Developer (PROJECT_DEVELOPER): See Improved Cookstove Policy (main).
+2. Verifier (VERIFIER): Approved, independent person or organization that verifies Claims Data in the form of Monitoring Reports.
+3. Public Viewer: Not yet implemented.
+
+**Schema**
+
+Improved Cookstove Policy (main):
+- Presentation Request: Role License (PR-RL)
+- Project Listing Application (PLA)
+- Document Review: Project Listing Application (DR-PLA)
+- Project Registration Request (PRR)
+- HGICV Token Issuance Request (TIR)
+
+ICP Agent Application Subpolicy:
+- Role Application (RA)
+- Agent Details (AD)
+
+ICP PDD Validation Subpolicy:
+- Presentation Request: Role License (PR-RL)
+- PDD Section A - Description of Project (PDD-XA)
+- Document Review: PDD Section A (DR-PDD-XA)
+- PDD Section B - Methodologies (PDD-XB)
+- Document Review: PDD Section B (DR-PDD-XB)
+- PDD Section C - Crediting Period (PDD-XC)
+- Document Review: PDD Section C (DR-PDD-XC)
+- PDD Section D - Other Impacts (PDD-XD)
+- Document Review: PDD Section D (DR-PDD-XD)
+- PDD Section E - Stakeholder Engagement (PDD-XE)
+- Document Review: PDD Section E (DR-PDD-XE)
+- Project Design Document (PDD)
+- Location
+- GeoCoordinate
+- GeoLine
+- GeoPolygon
+- Technology or Measure
+- Project Party
+- Table: Project Boundary
+- Table Row: Project Boundary
+- Emission Reduction Calculation
+- Table Row: Data/Parameter Monitoring
+- Table Row: Ex Ante Emissions Estimations
+- Monitoring Plan
+
+ICP MR Verification Subpolicy:
+- Presentation Request: Role License (PR-RL)
+- Monitoring Report (MR)
+- Table Row: Data/Parameter Monitoring
+- Document Review: Monitoring Report (DR-MR)
+
+**Workflow**
+
+![Table showing the workflows of the Improved Cookstove Policy and its subpolicies](https://bafybeib4ms5lkfbcccbpc6tlcs3cilsiqmgszld7mlndllg653ywjhvzyu.ipfs.w3s.link/PolicyWorkflow.png)
+
+**Glossary**
-● Traceability and transparency of data
-
-● Digital quality assurance
-
-● Immutability of data
-
-● Transparency of Verifier credentials and approval data
-
-Reduces barriers to entry
-
-● Accessible and standardized policies and processes inform and encourage suppliers to bring their projects to market
-
-● Decentralized project management reduces dependency on Standards Bodies and reduces time to market.
-
-Contributes to Climate Goals
-
-● Achieves higher confidence carbon project outcomes, and scales the finance and rollout of carbon projects at the speed required by the climate emergency
-
-This first of its kind Improved Cookstove Guardian Policy was designed per the Anthropogenic Impact Accounting Ontology found here An ontology for anthropogenic impact accounting. To this end, the Guardian Policy does not adhere to a specific Standard or approved methodology for carbon offset quantification, rather it abstracts concepts from all known standards and methodologies, categorizes them, models their relationships, and then instantiates them in the form of this digitally native Guardian Policy and its associated Guardian Schema. This policy issues a non fungible Improved Cookstove Carbon Credit (ICCC) Token.
-
-**Scope and Applicability**:
-
-Guardian implementation of a digitally native methodology for quantifying greenhouse gas (GHG) emission reductions from improved biomass cookstoves developed by the Nova Institute and Tolam Earth, Inc.
-
-
-Applicable to activities reducing GHG emissions from cookstoves:
-
-1. Through switching to more efficient stove technology
-
-Token: Non-Fungible Type: Carbon Offset Standard: Multiple Methodology: Multiple
-
-Required Documents: Project Design Document (PDD), PDD Validation Report, Monitoring Report, Monitoring Report Verification, Double Counting Certification,
-
-VVB Certification and Conflict of Interest Statement
-
-NFT Owner:
-
-**Preconditions**:
-1. Standard Registry account on a Guardian instance to import the policy. See Guardian documentation at
- (https://docs.hedera.com/guardian/policy-creation-using-the-guardian-apis/prerequesite-
- steps) for steps to create an account and import a policy.
-2. User accounts within the Guardian to fill the roles defined in this policy.
-3. Required Project Documentation posted to traceable, immutable source which can be accessed by the Tolam Earth Marketplace.
-
-**Policy User Roles**:
-1. Project Developer: Person responsible for executing the Project Design and collecting Data as per the Project Application. The Project Developer submits Monitoring Reports and is the beneficiary of the Credit Claims.
-2. Verifier: Approved, independent person or organization that Verifies the Project Application and Claims Data in the form of Monitoring Reports.
-3. Standard Body: Administrative role that approves Verifiers, approves Project Applications, and manages the issuance of claims.
-
-**Schema**:
-
-1. Agent Application (AA)
-2. Project Listing Application (PLA)
-3. Project Listing Application (PLA) - Review
-4. Project Design Document (PDD)
-5. Project Design Document (PDD) - Review
-6. Project Registration Request (PRR)
-7. Monitoring Report (MR)
-8. Monitoring Report (MR) - Review
-9. ICCC Issuance Request (CIR)
-
-**Glossary**:
+Claim: The end result of execution of a project, often expressed per unit time, which quantifies the impact of the initiative.
Guardian: The Guardian is a modular open-source solution that includes best-in-class identity management and Decentralized Ledger Technology (DLT) libraries. At the heart of the Guardian solution is a sophisticated Policy Workflow Engine (PWE) that enables applications to offer a requirements-based tokenization implementation.
@@ -77,22 +138,18 @@ Guardian Policy: Defines activities, rules, and interactions between activities
Guardian Schema: Describes the structure and definition of data fields required within an activity, sub-activity, or sub-sub-activity. Essentially, the schema defines the data fields that must be supplied for each activity and the characteristics of those fields.
-Standard: Set of project design, monitoring, and reporting criteria against which activities’ impacts can be certified or verified, e.g. Greenhouse Gas (GHG) emission reductions, or social benefits.
-
-Standards Body: Organization which defines the standard and approves project design, monitoring, and reporting criteria within it.
-
Methodology: As part of a Standard, Methodologies define the rules for calculating emissions increase, footprint, reductions and/or removals.
-Project Documentation: Any documentation required by the Guardian Schema. This may include Monitoring Reports, Project Design Documents, Verifier Credentials, etc.
+Monitoring Report: Document that describes and justifies any changes to the Project Design Document, based upon what happened during execution of a project. Also includes any data and/or calculations made during the time period covered by the document. A single project can have multiple Monitoring Reports associated with it, and each Monitoring Report is associated with a Claim.
Project Design Document: Documentation of plans for an activity to be executed following the prescriptions of the Standard in a concrete context for generation of assets.
+Project Documentation: Any documentation required by the Guardian Schema. This may include Monitoring Reports, Project Design Documents, Verifier Credentials, etc.
+
Project Listing Application: Process during which a Project Developer expresses their intent to develop a (cookstove) project towards a specific Registry, and the Registry then acknowledges that intent by assigning a project code to the project and listing it in the Registry’s public database of projects.
Project Registration: When Project Design Documents are approved by a Registry.
+Standard: Set of project design, monitoring, and reporting criteria against which activities’ impacts can be certified or verified, e.g. Greenhouse Gas (GHG) emission reductions, or social benefits.
-**Monitoring Report**:
-
-Document that describes and justifies any changes to the Project Design Document, based upon what happened during execution of a project. Also includes any data and/or calculations made during the time period covered by the document. A single project can have multiple Monitoring Reports associated, and each Monitoring Report is associated with a Claim.
-Claim: The end result of execution of a project, often expressed per unit time, which quantifies the impact of the initiative.
+Standards Body: Organization which defines the standard and approves project design, monitoring, and reporting criteria within it.
diff --git a/Methodology Library/iREC/Policies/iRec 10 Recipient (1684757087.809526003).policy b/Methodology Library/iREC/Policies/iRec 10 Recipient (1684757087.809526003).policy
new file mode 100644
index 0000000000..367af71f37
Binary files /dev/null and b/Methodology Library/iREC/Policies/iRec 10 Recipient (1684757087.809526003).policy differ
diff --git a/Methodology Library/iREC/Policies/iRec 10 Source (1684756995.238994037).policy b/Methodology Library/iREC/Policies/iRec 10 Source (1684756995.238994037).policy
new file mode 100644
index 0000000000..d5b6ef62f5
Binary files /dev/null and b/Methodology Library/iREC/Policies/iRec 10 Source (1684756995.238994037).policy differ
diff --git a/README.md b/README.md
index 5c86856e57..824662d601 100644
--- a/README.md
+++ b/README.md
@@ -37,7 +37,7 @@ When building the reference implementation, you can [manually build every compon
* [Docker](https://www.docker.com)
-If you build with docker [MongoDB V6](https://www.mongodb.com), [NodeJS V16](https://nodejs.org) and [Nats 1.12.2](https://nats.io/) will be installed and configured automatically. Make sure you use Docker Compose V2 (comes with Docker Desktop > 3.6.0) as at https://docs.docker.com/compose/install/
+If you build with docker [MongoDB V6](https://www.mongodb.com), [NodeJS V16](https://nodejs.org) and [Nats 1.12.2](https://nats.io/) will be installed and configured automatically.
### Installation
@@ -47,22 +47,20 @@ If you build with docker [MongoDB V6](https://www.mongodb.com), [NodeJS V16](htt
git clone https://github.com/hashgraph/guardian.git
```
-2. Update the following files with your Hedera Testnet account info (see prerequisites) as indicated. Please check complete steps to generate Operation ID and Operator Key by looking at link : [How to Create Operator ID and Operator Key](https://docs.hedera.com/guardian/getting-started/getting-started/how-to-create-operator-id-and-operator-key). There will be other steps in the Demo Usage Guide that will require the generation of Operator IDs and Operator Keys. It is important to mention that the Operator IDs and Operator Keys in the .env will be used to generate demo accounts.
+2. Update the following files with your Hedera Testnet account info (see prerequisites) as indicated. Please check complete steps to generate Operation ID and Operator Key by looking at link : [How to Create Operator ID and Operator Key](https://docs.hedera.com/guardian/getting-started/getting-started/how-to-create-operator-id-and-operator-key). There will be other steps in the Demo Usage Guide that will require the generation of Operator IDs and Operator Keys. It is important to mention that the Operator IDs and Operator Keys in the ./guardian/configs/.env.\.guardian.system will be used to generate demo accounts.
For example:
- in `guardian-service/.env`:
-
+ in ./guardian/.env you may choose name of the Guardian platform. Leave the field empty or unspecified if you update a production environment to keep previous data (for more details read at https://github.com/IntellectEU/guardian/blob/feature/environment/docs/environments/Ecosystem-Envitonment.md)
```plaintext
- OPERATOR_ID=""
- OPERATOR_KEY=""
+ GUARDIAN_ENV="develop"
```
-
- in `guardian-service/.env.docker`:
+
+ in ./guardian/configs/.env.develop.guardian.system
```plaintext
- OPERATOR_ID=""
- OPERATOR_KEY=""
+ OPERATOR_ID="..."
+ OPERATOR_KEY="..."
```
**Note**. You can use the Schema Topic ID (`INITIALIZATION_TOPIC_ID`) already present in the configuration files, or you can specify your own.
@@ -71,24 +69,24 @@ If you build with docker [MongoDB V6](https://www.mongodb.com), [NodeJS V16](htt
**3.1 Setting up IPFS Local node:**
- 3.1.1 We need to install and configure any IPFS node.
+ - 3.1.1 We need to install and configure any IPFS node.
For example: https://github.com/yeasy/docker-ipfs
- 3.1.2 For setup IPFS local node you need to set variables in `worker-service` folder
+ - 3.1.2 For setup IPFS local node you need to set variables in the same file ./guardian/configs/.env.develop.guardian.system
```
IPFS_NODE_ADDRESS="..." # Default IPFS_NODE_ADDRESS="http://localhost:5002"
- IPFS_PUBLIC_GATEWAY="..." # Default IPFS_PUBLIC_GATEWAY="https://localhost:8080/ipfs/${cid}"
+ IPFS_PUBLIC_GATEWAY='...' # Default IPFS_PUBLIC_GATEWAY='https://localhost:8080/ipfs/${cid}'
IPFS_PROVIDER="local"
```
**Note**
1. Default IPFS_NODE_ADDRESS="http://localhost:5002"
- 2. Default IPFS_PUBLIC_GATEWAY="https://localhost:8080/ipfs/${cid}"
+ 2. Default IPFS_PUBLIC_GATEWAY='https://localhost:8080/ipfs/${cid}'
**3.2 Setting up IPFS Web3Storage node:**
- 3.2.1 For setup IPFS web3storage node you need to set variables in `worker-service` folder:
+ 3.2.1 For setup IPFS web3storage node you need to set variables in the same file ./guardian/configs/.env.develop.guardian.system
```
IPFS_STORAGE_API_KEY="..."
@@ -100,8 +98,10 @@ If you build with docker [MongoDB V6](https://www.mongodb.com), [NodeJS V16](htt
4. Build and launch with Docker. Please note that this build is meant to be used in production and will not contain any debug information. From the project's root folder:
```shell
- docker-compose up -d --build
+ docker compose up -d --build
```
+**Note**. about docker-compose: from the end of June 2023 Compose V1 won’t be supported anymore and will be removed from all Docker Desktop versions. Make sure you use Docker Compose V2 (comes with Docker Desktop > 3.6.0) as at https://docs.docker.com/compose/install/
+
5. Browse to and complete the setup.
@@ -118,6 +118,25 @@ If you want to manually build every component with debug information, then build
### Build and start each component
Install, configure and start all the prerequisites, then build and start each component.
+Configure .env file in each service
+
+ For example:
+
+ in `guardian-service/.env`:
+ ```plaintext
+ GUARDIAN_ENV="develop"
+ ```
+
+ If need to configure OVERRIDE variables add it in .env file.
+ ```plaintext
+ OVERRIDE="false"
+ ```
+
+ in `guardian-service/configs/.env.guardian.develop`:
+ ```plaintext
+ OPERATOR_ID="..."
+ OPERATOR_KEY="..."
+ ```
**Note: Once you start each service, please wait for the initialization process to be completed.**
@@ -329,7 +348,7 @@ Install, configure and start all the prerequisites, then build and start each co
2. Start local development using docker compose
```shell
- docker-compose -f docker-compose-dev.yml up --build
+ docker compose -f docker-compose-dev.yml up --build
```
3. Access local development using or
@@ -345,7 +364,7 @@ Install, configure and start all the prerequisites, then build and start each co
**To run by cleaning Docker cache**:
```shell
- docker-compose build --no-cache
+ docker compose build --no-cache
```
([back to top](readme))
diff --git a/api-docs/.env (1) b/api-docs/.env (1)
new file mode 100644
index 0000000000..e69de29bb2
diff --git a/api-docs/api/swagger/swagger.yaml b/api-docs/api/swagger/swagger.yaml
index 60d56d26c6..f8d1af8cee 100644
--- a/api-docs/api/swagger/swagger.yaml
+++ b/api-docs/api/swagger/swagger.yaml
@@ -2,7 +2,7 @@ openapi: 3.0.0
info:
title: "Guardian"
description: "The Guardian is a modular open-source solution that includes best-in-class identity management and decentralized ledger technology (DLT) libraries. At the heart of the Guardian solution is a sophisticated Policy Workflow Engine (PWE) that enables applications to offer a requirements-based tokenization implementation."
- version: "2.12.0"
+ version: "2.13.0"
contact:
name: "API developer"
url: "https://envisionblockchain.com"
@@ -848,6 +848,90 @@ components:
items:
type: string
example: ["type"]
+ WizardConfig:
+ type: object
+ required:
+ - policy
+ - roles
+ - schemas
+ - trustChain
+ properties:
+ roles:
+ type: array
+ items:
+ type: string
+ policy:
+ type: object
+ properties:
+ name:
+ type: string
+ description:
+ type: string
+ topicDescription:
+ type: string
+ policyTag:
+ type: string
+ schemas:
+ type: array
+ items:
+ type: object
+ properties:
+ name:
+ type: string
+ iri:
+ type: string
+ isApproveEnable:
+ type: boolean
+ isMintSchema:
+ type: boolean
+ mintOptions:
+ type: object
+ properties:
+ tokenId:
+ type: string
+ rule:
+ type: string
+ dependencySchemaIri:
+ type: string
+ relationshipsSchemaIri:
+ type: string
+ initialRolesFor:
+ type: array
+ items:
+ type: string
+ rolesConfig:
+ type: array
+ items:
+ type: object
+ properties:
+ role:
+ type: string
+ isApprover:
+ type: boolean
+ isCreator:
+ type: boolean
+ gridColumns:
+ type: array
+ items:
+ type: object
+ properties:
+ field:
+ type: string
+ title:
+ type: string
+ trustChain:
+ type: array
+ items:
+ type: object
+ properties:
+ role:
+ type: string
+ mintSchemaIri:
+ type: string
+ viewOnlyOwnDocuments:
+ type: boolean
+
+
tags:
- name: "accounts"
description: "Operations related to Guardian users"
@@ -859,7 +943,7 @@ tags:
description: "Operations with data schemas"
- name: "tokens"
description: "Everything about tokens"
- - name: "trustchains"
+ - name: "trust-chains"
description: "Audit and trust chain"
- name: "policies"
description: "Policy engine operations"
@@ -887,6 +971,8 @@ tags:
description: "Operations with Tags"
- name: "themes"
description: "Operations with Themes"
+ - name: "wizard"
+ description: "Operations with policy wizard"
paths:
/accounts:
get:
@@ -987,7 +1073,7 @@ paths:
$ref: "#/components/schemas/Credentials"
responses:
201:
- description: Successful operation.
+ description: Created.
content:
application/json:
schema:
@@ -1166,7 +1252,7 @@ paths:
$ref: "#/components/schemas/User"
responses:
201:
- description: Successful operation.
+ description: Created.
401:
description: Unauthorized.
403:
@@ -1331,7 +1417,7 @@ paths:
$ref: "#/components/schemas/Schema"
responses:
201:
- description: Successful operation.
+ description: Created.
401:
description: Unauthorized.
403:
@@ -1639,7 +1725,7 @@ paths:
required: true
responses:
201:
- description: Successful operation.
+ description: Created.
content:
application/json:
schema:
@@ -1733,7 +1819,7 @@ paths:
type: string
responses:
201:
- description: Successful operation.
+ description: Created.
content:
application/json:
schema:
@@ -2026,7 +2112,7 @@ paths:
$ref: "#/components/schemas/Schema"
responses:
201:
- description: Successful operation.
+ description: Created.
401:
description: Unauthorized.
403:
@@ -2223,12 +2309,12 @@ paths:
type: string
enum:
[
- STANDARD_REGISTRY,
- USER,
- POLICY,
- MINT_TOKEN,
- WIPE_TOKEN,
- MINT_NFTOKEN,
+ STANDARD_REGISTRY,
+ USER,
+ POLICY,
+ MINT_TOKEN,
+ WIPE_TOKEN,
+ MINT_NFTOKEN,
]
required: true
description: schema type.
@@ -2302,7 +2388,7 @@ paths:
$ref: "#/components/schemas/Token"
responses:
201:
- description: Successful operation.
+ description: Created.
content:
application/json:
schema:
@@ -2534,8 +2620,178 @@ paths:
schema:
$ref: "#/components/schemas/Error"
+ /tokens/{tokenId}/{username}/grant-kyc:
+ put:
+ tags:
+ - tokens
+ description: Sets the KYC flag for the user. Only users with the Standard Registry role are allowed to make the request.
+ parameters:
+ - in: path
+ name: tokenId
+ schema:
+ type: string
+ required: true
+ description: Token ID.
+ - in: path
+ name: username
+ schema:
+ type: string
+ required: true
+ description: Username.
+ security:
+ - bearerAuth: []
+ summary: Sets the KYC flag for the user.
+ responses:
+ 200:
+ description: Successful operation.
+ content:
+ application/json:
+ schema:
+ $ref: "#/components/schemas/TokenInfo"
+ 400:
+ description: Bad Request.
+ content:
+ application/json:
+ schema:
+ $ref: "#/components/schemas/Error"
+ 401:
+ description: Unauthorized.
+ 403:
+ description: Forbidden.
+ 500:
+ description: Internal server error.
+ content:
+ application/json:
+ schema:
+ $ref: "#/components/schemas/Error"
+
+ /tokens/push/{tokenId}/{username}/grant-kyc:
+ put:
+ tags:
+ - tokens
+ description: Sets the KYC flag for the user. Only users with the Standard Registry role are allowed to make the request.
+ security:
+ - bearerAuth: []
+ summary: Sets the KYC flag for the user.
+ parameters:
+ - in: path
+ name: tokenId
+ schema:
+ type: string
+ required: true
+ description: Token ID.
+ - in: path
+ name: username
+ schema:
+ type: string
+ required: true
+ description: Username.
+ responses:
+ 202:
+ description: Successful operation.
+ content:
+ application/json:
+ schema:
+ $ref: "#/components/schemas/Task"
+ 401:
+ description: Unauthorized.
+ 403:
+ description: Forbidden.
+ 500:
+ description: Internal server error.
+ content:
+ application/json:
+ schema:
+ $ref: "#/components/schemas/Error"
+
+ /tokens/{tokenId}/{username}/revoke-kyc:
+ put:
+ tags:
+ - tokens
+ description: Unsets the KYC flag for the user. Only users with the Standard Registry role are allowed to make the request.
+ parameters:
+ - in: path
+ name: tokenId
+ schema:
+ type: string
+ required: true
+ description: Token ID.
+ - in: path
+ name: username
+ schema:
+ type: string
+ required: true
+ description: Username.
+ security:
+ - bearerAuth: []
+ summary: Unsets the KYC flag for the user.
+ responses:
+ 200:
+ description: Successful operation.
+ content:
+ application/json:
+ schema:
+ $ref: "#/components/schemas/TokenInfo"
+ 400:
+ description: Bad Request.
+ content:
+ application/json:
+ schema:
+ $ref: "#/components/schemas/Error"
+ 401:
+ description: Unauthorized.
+ 403:
+ description: Forbidden.
+ 500:
+ description: Internal server error.
+ content:
+ application/json:
+ schema:
+ $ref: "#/components/schemas/Error"
+
+ /tokens/push/{tokenId}/{username}/revoke-kyc:
+ put:
+ tags:
+ - tokens
+ description: Unsets the KYC flag for the user. Only users with the Standard Registry role are allowed to make the request.
+ security:
+ - bearerAuth: []
+ summary: Unsets the KYC flag for the user.
+ parameters:
+ - in: path
+ name: tokenId
+ schema:
+ type: string
+ required: true
+ description: Token ID.
+ - in: path
+ name: username
+ schema:
+ type: string
+ required: true
+ description: Username.
+ responses:
+ 202:
+ description: Successful operation.
+ content:
+ application/json:
+ schema:
+ $ref: "#/components/schemas/Task"
+ 401:
+ description: Unauthorized.
+ 403:
+ description: Forbidden.
+ 500:
+ description: Internal server error.
+ content:
+ application/json:
+ schema:
+ $ref: "#/components/schemas/Error"
+
+
/tokens/{tokenId}/{username}/grantKyc:
put:
+ deprecated: true
tags:
- tokens
description: Sets the KYC flag for the user. Only users with the Standard Registry role are allowed to make the request.
@@ -2581,6 +2837,7 @@ paths:
/tokens/push/{tokenId}/{username}/grantKyc:
put:
+ deprecated: true
tags:
- tokens
description: Sets the KYC flag for the user. Only users with the Standard Registry role are allowed to make the request.
@@ -2620,6 +2877,7 @@ paths:
/tokens/{tokenId}/{username}/revokeKyc:
put:
+ deprecated: true
tags:
- tokens
description: Unsets the KYC flag for the user. Only users with the Standard Registry role are allowed to make the request.
@@ -2665,6 +2923,7 @@ paths:
/tokens/push/{tokenId}/{username}/revokeKyc:
put:
+ deprecated: true
tags:
- tokens
description: Unsets the KYC flag for the user. Only users with the Standard Registry role are allowed to make the request.
@@ -2853,12 +3112,109 @@ paths:
required: true
description: Username.
responses:
- 202:
+ 202:
+ description: Successful operation.
+ content:
+ application/json:
+ schema:
+ $ref: "#/components/schemas/Task"
+ 401:
+ description: Unauthorized.
+ 403:
+ description: Forbidden.
+ 500:
+ description: Internal server error.
+ content:
+ application/json:
+ schema:
+ $ref: "#/components/schemas/Error"
+
+ /trustchains:
+ get:
+ deprecated: true
+ tags:
+ - trust-chains
+ description: Requests all VP documents. Only users with the Auditor role are allowed to make the request.
+ security:
+ - bearerAuth: []
+ summary: Returns a list of all VP documents.
+ parameters:
+ - in: query
+ name: pageIndex
+ schema:
+ type: integer
+ description: The number of pages to skip before starting to collect the result set
+ examples:
+ pageIndex:
+ summary: Example of a pageIndex
+ value: 0
+ - in: query
+ name: pageSize
+ schema:
+ type: integer
+ description: The numbers of items to return
+ examples:
+ pageSize:
+ summary: Example of a pageSize
+ value: 100
+ - in: query
+ name: policyId
+ schema:
+ type: string
+ description: Selected policy ID.
+ - in: query
+ name: policyOwner
+ schema:
+ type: string
+ description: Selected Standard Registry (DID).
+ responses:
+ 200:
+ description: Successful operation.
+ headers:
+ x-total-count:
+ schema:
+ type: integer
+ description: Total items in the collection.
+ content:
+ application/json:
+ schema:
+ type: array
+ items:
+ $ref: "#/components/schemas/VerifiablePresentation"
+ 401:
+ description: Unauthorized.
+ 403:
+ description: Forbidden.
+ 500:
+ description: Internal server error.
+ content:
+ application/json:
+ schema:
+ $ref: "#/components/schemas/Error"
+
+ /trustchains/{hash}:
+ get:
+ deprecated: true
+ tags:
+ - trust-chains
+ description: Builds and returns a trustchain, from the VP to the root VC document. Only users with the Auditor role are allowed to make the request.
+ parameters:
+ - in: path
+ name: hash
+ schema:
+ type: string
+ required: true
+ description: Hash or ID of a VP document.
+ security:
+ - bearerAuth: []
+ summary: Returns a trustchain for a VP document.
+ responses:
+ 200:
description: Successful operation.
content:
application/json:
schema:
- $ref: "#/components/schemas/Task"
+ $ref: "#/components/schemas/TrustChains"
401:
description: Unauthorized.
403:
@@ -2870,7 +3226,7 @@ paths:
schema:
$ref: "#/components/schemas/Error"
- /trustchains:
+ /trust-chains:
get:
tags:
- trustchains
@@ -2932,7 +3288,7 @@ paths:
schema:
$ref: "#/components/schemas/Error"
- /trustchains/{hash}:
+ /trust-chains/{hash}:
get:
tags:
- trustchains
@@ -3039,7 +3395,7 @@ paths:
$ref: "#/components/schemas/PolicyConfig"
responses:
201:
- description: Successful operation.
+ description: Created.
401:
description: Unauthorized.
403:
@@ -3616,7 +3972,7 @@ paths:
type: string
responses:
201:
- description: Successful operation.
+ description: Created.
content:
application/json:
schema:
@@ -3698,7 +4054,7 @@ paths:
format: binary
responses:
201:
- description: Successful operation.
+ description: Created.
content:
application/json:
schema:
@@ -3872,8 +4228,8 @@ paths:
required: true
description: Policy ID.
responses:
- 200:
- description: Successful operation.
+ 201:
+ description: Created.
content:
application/json:
schema:
@@ -4436,9 +4792,9 @@ paths:
/demo/randomKey:
get:
+ deprecated: true
tags:
- demo
- deprecated: true
description: Generates a new Hedera account with a random private key.
security:
- bearerAuth: []
@@ -4555,7 +4911,7 @@ paths:
- bearerAuth: []
responses:
201:
- description: Successful operation.
+ description: Created.
content:
binary/octet-stream:
schema:
@@ -4588,7 +4944,7 @@ paths:
- bearerAuth: []
responses:
201:
- description: Successful operation.
+ description: Created.
content:
application/json:
schema:
@@ -4636,8 +4992,8 @@ paths:
- bearerAuth: []
summary: Set settings.
responses:
- 200:
- description: Successful operation.
+ 201:
+ description: Created.
401:
description: Unauthorized.
403:
@@ -4782,8 +5138,144 @@ paths:
schema:
$ref: "#/components/schemas/Error"
+ /artifacts:
+ get:
+ tags:
+ - artifacts
+ description: Returns all artifacts.
+ security:
+ - bearerAuth: []
+ summary: Returns all artifacts.
+ parameters:
+ - in: query
+ name: policyId
+ schema:
+ type: string
+ description: Policy identifier
+ - in: query
+ name: pageIndex
+ schema:
+ type: integer
+ description: The number of pages to skip before starting to collect the result set
+ examples:
+ pageIndex:
+ summary: Example of a pageIndex
+ value: 0
+ - in: query
+ name: pageSize
+ schema:
+ type: integer
+ description: The numbers of items to return
+ examples:
+ pageSize:
+ summary: Example of a pageSize
+ value: 100
+ responses:
+ 200:
+ description: Successful operation.
+ headers:
+ x-total-count:
+ schema:
+ type: integer
+ description: Total items in the collection.
+ content:
+ application/json:
+ schema:
+ type: array
+ items:
+ $ref: "#/components/schemas/Artifact"
+ 401:
+ description: Unauthorized.
+ 403:
+ description: Forbidden.
+ 500:
+ description: Internal server error.
+ content:
+ application/json:
+ schema:
+ $ref: "#/components/schemas/Error"
+
+ /artifacts/{policyId}:
+ post:
+ tags:
+ - artifacts
+ description: Upload artifact. For users with the Standard Registry role only.
+ security:
+ - bearerAuth: []
+ requestBody:
+ content:
+ multipart/form-data:
+ schema:
+ type: object
+ properties:
+ artifacts:
+ type: array
+ items:
+ type: string
+ format: binary
+ parameters:
+ - in: path
+ name: policyId
+ schema:
+ type: string
+ required: true
+ description: Policy identifier
+ summary: Upload Artifact.
+ responses:
+ 200:
+ description: Successful operation.
+ content:
+ application/json:
+ schema:
+ type: array
+ items:
+ $ref: "#/components/schemas/Artifact"
+ 401:
+ description: Unauthorized.
+ 403:
+ description: Forbidden.
+ 500:
+ description: Internal server error.
+ content:
+ application/json:
+ schema:
+ $ref: "#/components/schemas/Error"
+
+ /artifacts/{artifactId}:
+ delete:
+ tags:
+ - artifacts
+ description: Delete artifact.
+ security:
+ - bearerAuth: []
+ summary: Delete artifact.
+ parameters:
+ - in: path
+ name: artifactId
+ schema:
+ type: string
+ required: true
+ description: Artifact identifier
+ responses:
+ 200:
+ description: Successful operation.
+ content:
+ application/json:
+ schema:
+ type: boolean
+ 401:
+ description: Unauthorized.
+ 403:
+ description: Forbidden.
+ 500:
+ description: Internal server error.
+ content:
+ application/json:
+ schema:
+ $ref: "#/components/schemas/Error"
/artifact:
get:
+ deprecated: true
tags:
- artifacts
description: Returns all artifacts.
@@ -4841,6 +5333,7 @@ paths:
/artifact/{policyId}:
post:
+ deprecated: true
tags:
- artifacts
description: Upload artifact. For users with the Standard Registry role only.
@@ -4887,6 +5380,7 @@ paths:
/artifact/{artifactId}:
delete:
+ deprecated: true
tags:
- artifacts
description: Delete artifact.
@@ -4988,8 +5482,8 @@ paths:
example:
description: "Smart Contract Description"
responses:
- 200:
- description: Successful operation.
+ 201:
+ description: Created.
content:
application/json:
schema:
@@ -4998,6 +5492,8 @@ paths:
description: Unauthorized.
403:
description: Forbidden.
+ 422:
+ description: Unprocessable Entity.
500:
description: Internal server error.
content:
@@ -5490,7 +5986,7 @@ paths:
$ref: "#/components/schemas/Module"
responses:
201:
- description: Successful operation.
+ description: Created.
401:
description: Unauthorized.
403:
@@ -5747,7 +6243,7 @@ paths:
type: string
responses:
201:
- description: Successful operation.
+ description: Created.
content:
application/json:
schema:
@@ -5781,7 +6277,7 @@ paths:
format: binary
responses:
201:
- description: Successful operation.
+ description: Created.
content:
application/json:
schema:
@@ -5940,7 +6436,7 @@ paths:
$ref: "#/components/schemas/Tag"
responses:
201:
- description: Successful operation.
+ description: Created.
content:
application/json:
schema:
@@ -5984,12 +6480,12 @@ paths:
type: string
enum:
[
- Schema,
- Policy,
- Token,
- Module,
- Contract,
- PolicyDocument,
+ Schema,
+ Policy,
+ Token,
+ Module,
+ Contract,
+ PolicyDocument,
]
target:
type: string
@@ -6002,12 +6498,12 @@ paths:
type: string
enum:
[
- Schema,
- Policy,
- Token,
- Module,
- Contract,
- PolicyDocument,
+ Schema,
+ Policy,
+ Token,
+ Module,
+ Contract,
+ PolicyDocument,
]
targets:
type: array
@@ -6189,7 +6685,7 @@ paths:
$ref: "#/components/schemas/Schema"
responses:
201:
- description: Successful operation.
+ description: Created.
content:
application/json:
schema:
@@ -6381,7 +6877,7 @@ paths:
$ref: "#/components/schemas/Theme"
responses:
201:
- description: Successful operation.
+ description: Created.
401:
description: Unauthorized.
403:
@@ -6511,7 +7007,7 @@ paths:
format: binary
responses:
201:
- description: Successful operation.
+ description: Created.
content:
application/json:
schema:
@@ -6526,3 +7022,119 @@ paths:
application/json:
schema:
$ref: "#/components/schemas/Error"
+
+ /wizard/policy:
+ post:
+ tags:
+ - wizard
+ description: Creates a new policy by wizard. Only users with the Standard Registry role are allowed to make the request.
+ security:
+ - bearerAuth: []
+ summary: Creates a new policy.
+ requestBody:
+ description: Object that contains wizard configuration.
+ required: true
+ content:
+ application/json:
+ schema:
+ $ref: "#/components/schemas/WizardConfig"
+ responses:
+ 201:
+ description: Successful operation.
+ content:
+ application/json:
+ schema:
+ type: object
+ properties:
+ policyId:
+ type: string
+ wizardConfig:
+ $ref: "#/components/schemas/WizardConfig"
+ 401:
+ description: Unauthorized.
+ 403:
+ description: Forbidden.
+ 500:
+ description: Internal server error.
+ content:
+ application/json:
+ schema:
+ $ref: "#/components/schemas/Error"
+
+ /wizard/policy/push:
+ post:
+ tags:
+ - wizard
+ description: Creates a new policy by wizard. Only users with the Standard Registry role are allowed to make the request.
+ security:
+ - bearerAuth: []
+ summary: Creates a new policy.
+ requestBody:
+ description: Object that contains wizard configuration.
+ required: true
+ content:
+ application/json:
+ schema:
+ $ref: "#/components/schemas/WizardConfig"
+ responses:
+ 202:
+ description: Successful operation.
+ content:
+ application/json:
+ schema:
+ $ref: "#/components/schemas/Task"
+ 401:
+ description: Unauthorized.
+ 403:
+ description: Forbidden.
+ 500:
+ description: Internal server error.
+ content:
+ application/json:
+ schema:
+ $ref: "#/components/schemas/Error"
+
+ /wizard/{policyId}/config:
+ post:
+ tags:
+ - wizard
+ description: Get policy config by wizard. Only users with the Standard Registry role are allowed to make the request.
+ parameters:
+ - in: path
+ name: policyId
+ schema:
+ type: string
+ required: true
+ description: Policy identifier.
+ security:
+ - bearerAuth: []
+ summary: Get policy config.
+ requestBody:
+ description: Object that contains wizard configuration.
+ required: true
+ content:
+ application/json:
+ schema:
+ $ref: "#/components/schemas/WizardConfig"
+ responses:
+ 200:
+ description: Successful operation.
+ content:
+ application/json:
+ schema:
+ type: object
+ properties:
+ policyConfig:
+ $ref: "#/components/schemas/PolicyConfig"
+ wizardConfig:
+ $ref: "#/components/schemas/WizardConfig"
+ 401:
+ description: Unauthorized.
+ 403:
+ description: Forbidden.
+ 500:
+ description: Internal server error.
+ content:
+ application/json:
+ schema:
+ $ref: "#/components/schemas/Error"
diff --git a/api-docs/package.json b/api-docs/package.json
index a1c4d1b63e..e987ddc921 100644
--- a/api-docs/package.json
+++ b/api-docs/package.json
@@ -1,6 +1,6 @@
{
"name": "api-docs",
- "version": "2.12.2",
+ "version": "2.13.0-prerelease",
"description": "Swagger Documentation",
"main": "dist/index.js",
"scripts": {
@@ -24,5 +24,6 @@
"@types/swagger-ui-express": "^4.1.3",
"tslint": "^6.1.3",
"typescript": "^4.6.3"
- }
+ },
+ "stableVersion": "2.12.0"
}
diff --git a/api-gateway/.env b/api-gateway/.env
index 5edd71fe8b..18face0ea2 100644
--- a/api-gateway/.env
+++ b/api-gateway/.env
@@ -1,11 +1 @@
-ENV="develop"
-HEDERA_NET="testnet"
-PREUSED_HEDERA_NET="testnet"
-MQ_ADDRESS="localhost"
-SERVICE_CHANNEL="api-gateway"
-MRV_ADDRESS="http://localhost:3003/mrv"
-MQ_MAX_PAYLOAD="1048576"
-#LOG_LEVEL="2"
-#MQ_MESSAGE_CHUNK=5000000
-#RAW_REQUEST_LIMIT="1gb"
-#JSON_REQUEST_LIMIT="1mb"
+GUARDIAN_ENV=""
diff --git a/api-gateway/.env.docker.example b/api-gateway/.env.docker.example
deleted file mode 100644
index 1b28c61274..0000000000
--- a/api-gateway/.env.docker.example
+++ /dev/null
@@ -1,9 +0,0 @@
-HEDERA_NET="testnet"
-PREUSED_HEDERA_NET="testnet"
-MQ_ADDRESS="message-broker"
-SERVICE_CHANNEL="api-gateway"
-MRV_ADDRESS="http://message-broker:3003/mrv"
-#LOG_LEVEL="2"
-#MQ_MESSAGE_CHUNK=5000000
-#RAW_REQUEST_LIMIT="1gb"
-#JSON_REQUEST_LIMIT="1mb"
diff --git a/api-gateway/.env.template b/api-gateway/.env.template
new file mode 100644
index 0000000000..dd4ffe0d89
--- /dev/null
+++ b/api-gateway/.env.template
@@ -0,0 +1,2 @@
+GUARDIAN_ENV=""
+#OVVERRIDE="false"
\ No newline at end of file
diff --git a/api-gateway/Dockerfile b/api-gateway/Dockerfile
index 89b3d072fc..cef1cbcb9f 100644
--- a/api-gateway/Dockerfile
+++ b/api-gateway/Dockerfile
@@ -36,7 +36,8 @@ COPY --from=interfacesModuleBuilder /usr/local/interfaces/guardian-interfaces-*.
COPY --from=commonModuleBuilder /usr/local/common/guardian-common-*.tgz /tmp/common.tgz
COPY --from=apiGatewayBuilder /usr/local/api-gateway/yarn.lock ./
COPY ./api-gateway/package.json ./
-# COPY ./api-gateway/.env.docker ./.env
+RUN mkdir -p ./configs
+COPY ./api-gateway/configs/* ./configs
RUN node -e "const fs=require('fs'); const input=JSON.parse(fs.readFileSync('package.json')); input.dependencies['@guardian/interfaces']='file:/tmp/interfaces.tgz'; fs.writeFileSync('package.json', JSON.stringify(input));"
RUN node -e "const fs=require('fs'); const input=JSON.parse(fs.readFileSync('package.json')); input.dependencies['@guardian/common']='file:/tmp/common.tgz'; fs.writeFileSync('package.json', JSON.stringify(input));"
RUN yarn install --frozen-lockfile
diff --git a/api-gateway/.env.example b/api-gateway/configs/.env.gateway
similarity index 65%
rename from api-gateway/.env.example
rename to api-gateway/configs/.env.gateway
index 5104c77e4e..9b2a565503 100644
--- a/api-gateway/.env.example
+++ b/api-gateway/configs/.env.gateway
@@ -1,9 +1,13 @@
-ENV="develop"
+# Gateway Service Specialized Variables
+SERVICE_CHANNEL="api-gateway"
+DIRECT_MESSAGE_PORT="6555"
+
+# Ecosystem Defined Variables
HEDERA_NET="testnet"
PREUSED_HEDERA_NET="testnet"
MQ_ADDRESS="localhost"
-SERVICE_CHANNEL="api-gateway"
MRV_ADDRESS="http://localhost:3003/mrv"
+MQ_MAX_PAYLOAD="1048576"
#LOG_LEVEL="2"
#MQ_MESSAGE_CHUNK=5000000
#RAW_REQUEST_LIMIT="1gb"
diff --git a/api-gateway/configs/.env.gateway.develop b/api-gateway/configs/.env.gateway.develop
new file mode 100644
index 0000000000..a5b9168ebe
--- /dev/null
+++ b/api-gateway/configs/.env.gateway.develop
@@ -0,0 +1,14 @@
+# Gateway Service Specialized Variables
+SERVICE_CHANNEL="api-gateway"
+#DIRECT_MESSAGE_PORT="6555"
+
+# Ecosystem Defined Variables
+HEDERA_NET="testnet"
+PREUSED_HEDERA_NET="testnet"
+MQ_ADDRESS="localhost"
+MRV_ADDRESS="http://localhost:3003/mrv"
+MQ_MAX_PAYLOAD="1048576"
+#LOG_LEVEL="2"
+#MQ_MESSAGE_CHUNK=5000000
+#RAW_REQUEST_LIMIT="1gb"
+#JSON_REQUEST_LIMIT="1mb"
diff --git a/api-gateway/configs/.env.gateway.template b/api-gateway/configs/.env.gateway.template
new file mode 100644
index 0000000000..04952e8b97
--- /dev/null
+++ b/api-gateway/configs/.env.gateway.template
@@ -0,0 +1,14 @@
+# Gateway Service Specialized Variables
+SERVICE_CHANNEL="api-gateway"
+DIRECT_MESSAGE_PORT="6555"
+
+# Ecosystem Defined Variables
+HEDERA_NET=""
+PREUSED_HEDERA_NET=""
+MQ_ADDRESS=""
+MRV_ADDRESS=""
+MQ_MAX_PAYLOAD=""
+#LOG_LEVEL="2"
+#MQ_MESSAGE_CHUNK=5000000
+#RAW_REQUEST_LIMIT="1gb"
+#JSON_REQUEST_LIMIT="1mb"
diff --git a/api-gateway/package.json b/api-gateway/package.json
index 815bb0db02..8f7190f0d6 100644
--- a/api-gateway/package.json
+++ b/api-gateway/package.json
@@ -8,9 +8,15 @@
},
"author": "Envision Blockchain Solutions ",
"dependencies": {
- "@guardian/common": "^2.12.2",
- "@guardian/interfaces": "^2.12.2",
+ "@guardian/common": "^2.13.0-prerelease",
+ "@guardian/interfaces": "^2.13.0-prerelease",
+ "@nestjs/common": "^9.4.1",
+ "@nestjs/core": "^9.4.1",
+ "@nestjs/microservices": "^9.4.1",
+ "@nestjs/platform-express": "^9.4.2",
"@types/express-fileupload": "^1.4.1",
+ "class-transformer": "^0.5.1",
+ "class-validator": "^0.14.0",
"dotenv": "^16.0.0",
"express": "^4.17.1",
"express-fileupload": "^1.4.0",
@@ -18,6 +24,8 @@
"http-errors": "^2.0.0",
"jszip": "^3.7.1",
"module-alias": "^2.2.2",
+ "prom-client": "^14.1.1",
+ "prometheus-api-metrics": "3.2.2",
"reflect-metadata": "^0.1.13",
"ws": "^8.2.1",
"yup": "^1.1.1"
@@ -55,5 +63,6 @@
"start": "node dist/index.js",
"test": "mocha tests/**/*.test.js --reporter mocha-junit-reporter --reporter-options mochaFile=../test_results/ui-service.xml"
},
- "version": "2.12.2"
+ "version": "2.13.0-prerelease",
+ "stableVersion": "2.12.0"
}
diff --git a/api-gateway/src/api/service/account.ts b/api-gateway/src/api/service/account.ts
index 56b2d1835c..415e455239 100644
--- a/api-gateway/src/api/service/account.ts
+++ b/api-gateway/src/api/service/account.ts
@@ -1,117 +1,154 @@
-import { Request, Response, Router, NextFunction } from 'express';
-import { permissionHelper, authorizationHelper } from '@auth/authorization-helper';
import { Users } from '@helpers/users';
-import { AuthenticatedRequest, Logger } from '@guardian/common';
+import { Logger } from '@guardian/common';
import { Guardians } from '@helpers/guardians';
import { UserRole } from '@guardian/interfaces';
-import validate, { prepareValidationResponse } from '@middlewares/validation';
-import { registerSchema, loginSchema } from '@middlewares/validation/schemas/accounts';
+import { ClientProxy } from '@nestjs/microservices';
+import { Body, Controller, Get, Headers, HttpCode, HttpException, HttpStatus, Inject, Post, Req } from '@nestjs/common';
+import { checkPermission } from '@auth/authorization-helper';
+import { LoginUserDTO, RegisterUserDTO } from '@middlewares/validation/schemas/accounts';
/**
* User account route
*/
-export const accountAPI = Router();
+@Controller('accounts')
+export class AccountApi {
-accountAPI.get('/session', authorizationHelper, async (req: Request, res: Response, next: NextFunction) => {
- const users = new Users();
- try {
- const authHeader = req.headers.authorization;
- const token = authHeader.split(' ')[1];
- res.json(await users.getUserByToken(token));
- } catch (error) {
- new Logger().error(error, ['API_GATEWAY']);
- return next(error);
+ constructor(@Inject('GUARDIANS') public readonly client: ClientProxy) {
}
-});
-accountAPI.post('/register', validate(registerSchema()),async (req: Request, res: Response, next: NextFunction) => {
- const users = new Users();
- try {
- const { username, password } = req.body;
- let { role } = req.body;
- // @deprecated 2022-10-01
- if (role === 'ROOT_AUTHORITY') {
- role = UserRole.STANDARD_REGISTRY;
- }
- res.status(201).json(await users.registerNewUser(username, password, role));
- } catch (error) {
- new Logger().error(error, ['API_GATEWAY']);
- if (error.message.includes('already exists')) {
- return res.status(422).json(prepareValidationResponse('An account with the same name already exists.'));
+ /**
+ * getSession
+ * @param headers
+ */
+ @Get('/session')
+ @HttpCode(HttpStatus.OK)
+ async getSession(@Headers() headers): Promise {
+ const users = new Users();
+ try {
+ const authHeader = headers.authorization;
+ const token = authHeader.split(' ')[1];
+ return await users.getUserByToken(token);
+ } catch (error) {
+ new Logger().error(error, ['API_GATEWAY']);
+ throw error;
}
- next(error)
- }
-});
-accountAPI.post('/login', validate(loginSchema()), async (req: Request, res: Response, next: NextFunction) => {
- const users = new Users();
- try {
- const { username, password } = req.body;
- res.json(await users.generateNewToken(username, password));
- } catch (error) {
- new Logger().error(error, ['API_GATEWAY']);
- next(error)
}
-});
-accountAPI.get('/', [authorizationHelper, permissionHelper(UserRole.STANDARD_REGISTRY)],
- async (req: AuthenticatedRequest, res: Response, next: NextFunction) => {
- try {
+ /**
+ * register
+ * @param body
+ */
+ @Post('/register')
+ @HttpCode(HttpStatus.CREATED)
+ async register(@Body() body: RegisterUserDTO): Promise {
const users = new Users();
- res.json(await users.getAllUserAccounts());
- } catch (error) {
- new Logger().error(error, ['API_GATEWAY']);
- next(error)
+ try {
+ const {username, password} = body;
+ let {role} = body;
+ // @deprecated 2022-10-01
+ if (role === 'ROOT_AUTHORITY') {
+ role = UserRole.STANDARD_REGISTRY;
+ }
+ return await users.registerNewUser(username, password, role);
+ } catch (error) {
+ new Logger().error(error, ['API_GATEWAY']);
+ if (error.message.includes('already exists')) {
+ throw new HttpException('An account with the same name already exists.', HttpStatus.INTERNAL_SERVER_ERROR);
+ }
+ throw error;
+ }
}
-});
-/**
- * @deprecated 2022-10-01
- */
-accountAPI.get('/root-authorities', authorizationHelper, async (req: Request, res: Response, next: NextFunction) => {
- try {
+ /**
+ * Login
+ */
+ @Post('/login')
+ @HttpCode(HttpStatus.OK)
+ async login(@Body() body: LoginUserDTO): Promise {
const users = new Users();
- const standardRegistries = await users.getAllStandardRegistryAccounts();
- res.json(standardRegistries);
- } catch (error) {
- new Logger().error(error.message, ['API_GATEWAY']);
- return next(error)
+ try {
+ const {username, password} = body;
+ return await users.generateNewToken(username, password);
+ } catch (error) {
+ new Logger().error(error, ['API_GATEWAY']);
+ throw error;
+ }
}
-});
-accountAPI.get('/standard-registries', authorizationHelper, async (req: Request, res: Response, next: NextFunction) => {
- try {
- const users = new Users();
- const standardRegistries = await users.getAllStandardRegistryAccounts();
- res.json(standardRegistries);
- } catch (error) {
- new Logger().error(error.message, ['API_GATEWAY']);
- return next(error);
+ /**
+ * Accounts
+ */
+ @Get()
+ @HttpCode(HttpStatus.OK)
+ async getAllAccounts(@Req() req): Promise {
+ await checkPermission(UserRole.STANDARD_REGISTRY)(req.user);
+ try {
+ const users = new Users();
+ return await users.getAllUserAccounts();
+ } catch (error) {
+ new Logger().error(error, ['API_GATEWAY']);
+ throw error;
+ }
}
-});
-accountAPI.get('/balance', authorizationHelper, async (req: Request, res: Response, next: NextFunction) => {
- try {
- const authHeader = req.headers.authorization;
- const users = new Users();
- if (authHeader) {
- const token = authHeader.split(' ')[1];
- try {
- const user = await users.getUserByToken(token) as any;
- if (user) {
- const guardians = new Guardians();
- const balance = await guardians.getBalance(user.username);
- return res.json(balance);
- }
- return res.json({});
+ /**
+ * Get root authorities
+ * @deprecated 2022-10-01
+ */
+ @Get('/root-authorities')
+ @HttpCode(HttpStatus.OK)
+ async getRootAuthorities(): Promise {
+ try {
+ const users = new Users();
+ return await users.getAllStandardRegistryAccounts();
+ } catch (error) {
+ new Logger().error(error.message, ['API_GATEWAY']);
+ throw error;
+ }
+ }
- } catch (error) {
- return res.json({});
+ /**
+ * Get SAs
+ */
+ @Get('/standard-registries')
+ @HttpCode(HttpStatus.OK)
+ async getStandatdRegistries(): Promise {
+ try {
+ const users = new Users();
+ return await users.getAllStandardRegistryAccounts();
+ } catch (error) {
+ new Logger().error(error.message, ['API_GATEWAY']);
+ throw error;
+ }
+ }
+
+ @Get('/balance')
+ @HttpCode(HttpStatus.OK)
+ async getBalance(@Headers() headers): Promise {
+ try {
+ const authHeader = headers.authorization;
+ const users = new Users();
+ if (authHeader) {
+ const token = authHeader.split(' ')[1];
+ try {
+ const user = await users.getUserByToken(token) as any;
+ if (user) {
+ const guardians = new Guardians();
+ return await guardians.getBalance(user.username);
+ // const balance = await this.client.send(MessageAPI.GET_BALANCE, { username: user.username }).toPromise()
+ // return balance;
+ }
+ return {};
+
+ } catch (error) {
+ return {};
+ }
}
+ return {};
+ } catch (error) {
+ new Logger().error(error, ['API_GATEWAY']);
+ throw error;
}
- res.json({});
- } catch (error) {
- new Logger().error(error, ['API_GATEWAY']);
- return next(error)
}
-});
+}
diff --git a/api-gateway/src/api/service/analytics.ts b/api-gateway/src/api/service/analytics.ts
index a2fde30608..2a8a669a2b 100644
--- a/api-gateway/src/api/service/analytics.ts
+++ b/api-gateway/src/api/service/analytics.ts
@@ -1,94 +1,111 @@
import { Guardians } from '@helpers/guardians';
-import { Response, Router, NextFunction } from 'express';
-import { AuthenticatedRequest, Logger } from '@guardian/common';
+import { Logger } from '@guardian/common';
+import { Body, Controller, HttpCode, HttpStatus, Post, Req } from '@nestjs/common';
-/**
- * User analytics route
- */
-export const analyticsAPI = Router();
-
-analyticsAPI.post('/compare/policies', async (req: AuthenticatedRequest, res: Response, next: NextFunction) => {
- const guardians = new Guardians();
- const policyId1 = req.body ? req.body.policyId1 : null;
- const policyId2 = req.body ? req.body.policyId2 : null;
- const eventsLvl = req.body ? req.body.eventsLvl : null;
- const propLvl = req.body ? req.body.propLvl : null;
- const childrenLvl = req.body ? req.body.childrenLvl : null;
- const idLvl = req.body ? req.body.idLvl : null;
- const user = req.user;
- try {
- const result = await guardians.comparePolicies(
- user,
- null,
- policyId1,
- policyId2,
- eventsLvl,
- propLvl,
- childrenLvl,
- idLvl
- );
- res.send(result);
- } catch (error) {
- new Logger().error(error, ['API_GATEWAY']);
- return next(error);
+@Controller('analytics')
+export class AnalyticsApi {
+ @Post('/compare/policies')
+ @HttpCode(HttpStatus.OK)
+ async comparePolicies(@Body() body, @Req() req): Promise {
+ const guardians = new Guardians();
+ const policyId1 = body ? body.policyId1 : null;
+ const policyId2 = body ? body.policyId2 : null;
+ const eventsLvl = body ? body.eventsLvl : null;
+ const propLvl = body ? body.propLvl : null;
+ const childrenLvl = body ? body.childrenLvl : null;
+ const idLvl = body ? body.idLvl : null;
+ const user = req.user;
+ try {
+ const result = await guardians.comparePolicies(
+ user,
+ null,
+ policyId1,
+ policyId2,
+ eventsLvl,
+ propLvl,
+ childrenLvl,
+ idLvl
+ );
+ return result;
+ } catch (error) {
+ new Logger().error(error, ['API_GATEWAY']);
+ throw error;
+ }
}
-});
-analyticsAPI.post('/compare/schemas', async (req: AuthenticatedRequest, res: Response, next: NextFunction) => {
- const guardians = new Guardians();
- const schemaId1 = req.body ? req.body.schemaId1 : null;
- const schemaId2 = req.body ? req.body.schemaId2 : null;
- const idLvl = req.body ? req.body.idLvl : null;
- const user = req.user;
- try {
- const result = await guardians.compareSchemas(user, null, schemaId1, schemaId2, idLvl);
- return res.send(result);
- } catch (error) {
- new Logger().error(error, ['API_GATEWAY']);
- return next(error);
+ /**
+ * Compare schemas
+ */
+ @Post('/compare/schemas')
+ @HttpCode(HttpStatus.OK)
+ async compareSchemas(@Body() body, @Req() req): Promise {
+ const guardians = new Guardians();
+ const schemaId1 = body ? body.schemaId1 : null;
+ const schemaId2 = body ? body.schemaId2 : null;
+ const idLvl = body ? body.idLvl : null;
+ const user = req.user;
+ try {
+ return await guardians.compareSchemas(user, null, schemaId1, schemaId2, idLvl);
+ } catch (error) {
+ new Logger().error(error, ['API_GATEWAY']);
+ throw error;
+ }
}
-});
-analyticsAPI.post('/compare/policies/export', async (req: AuthenticatedRequest, res: Response, next: NextFunction) => {
- const guardians = new Guardians();
- const type = req.query ? req.query.type : null;
- const policyId1 = req.body ? req.body.policyId1 : null;
- const policyId2 = req.body ? req.body.policyId2 : null;
- const eventsLvl = req.body ? req.body.eventsLvl : null;
- const propLvl = req.body ? req.body.propLvl : null;
- const childrenLvl = req.body ? req.body.childrenLvl : null;
- const idLvl = req.body ? req.body.idLvl : null;
- const user = req.user;
- try {
- const result = await guardians.comparePolicies(
- user,
- type,
- policyId1,
- policyId2,
- eventsLvl,
- propLvl,
- childrenLvl,
- idLvl
- );
- return res.send(result);
- } catch (error) {
- new Logger().error(error, ['API_GATEWAY']);
- return next(error);
+ /**
+ * Compare policies export
+ * @param body
+ * @param req
+ */
+ @Post('/compare/policies/export')
+ @HttpCode(HttpStatus.OK)
+ async comparePoliciesExport(@Body() body, @Req() req): Promise {
+ const guardians = new Guardians();
+ const type = req.query ? req.query.type : null;
+ const policyId1 = body ? body.policyId1 : null;
+ const policyId2 = body ? body.policyId2 : null;
+ const eventsLvl = body ? body.eventsLvl : null;
+ const propLvl = body ? body.propLvl : null;
+ const childrenLvl = body ? body.childrenLvl : null;
+ const idLvl = body ? body.idLvl : null;
+ const user = req.user;
+ try {
+ const result = await guardians.comparePolicies(
+ user,
+ type,
+ policyId1,
+ policyId2,
+ eventsLvl,
+ propLvl,
+ childrenLvl,
+ idLvl
+ );
+ return result
+ } catch (error) {
+ new Logger().error(error, ['API_GATEWAY']);
+ throw error;
+ }
}
-});
-analyticsAPI.post('/compare/schemas/export', async (req: AuthenticatedRequest, res: Response, next: NextFunction) => {
- const guardians = new Guardians();
- const type = req.query ? req.query.type : null;
- const schemaId1 = req.body ? req.body.schemaId1 : null;
- const schemaId2 = req.body ? req.body.schemaId2 : null;
- const idLvl = req.body ? req.body.idLvl : null;
- const user = req.user;
- try {
- const result = await guardians.compareSchemas(user, type, schemaId1, schemaId2, idLvl);
- return res.send(result);
- } catch (error) {
- new Logger().error(error, ['API_GATEWAY']);
- return next(error);
+ /**
+ * compareSchemasExport
+ * @param body
+ * @param req
+ */
+ @Post('/compare/schemas/export')
+ @HttpCode(HttpStatus.OK)
+ async compareSchemasExport(@Body() body, @Req() req): Promise {
+ const guardians = new Guardians();
+ const type = req.query ? req.query.type : null;
+ const schemaId1 = body ? body.schemaId1 : null;
+ const schemaId2 = body ? body.schemaId2 : null;
+ const idLvl = body ? body.idLvl : null;
+ const user = req.user;
+ try {
+ return await guardians.compareSchemas(user, type, schemaId1, schemaId2, idLvl);
+ } catch (error) {
+ new Logger().error(error, ['API_GATEWAY']);
+ throw error;
+ }
}
-});
+}
diff --git a/api-gateway/src/api/service/artifact.ts b/api-gateway/src/api/service/artifact.ts
index 8eccb041ae..5b19a8b2cf 100644
--- a/api-gateway/src/api/service/artifact.ts
+++ b/api-gateway/src/api/service/artifact.ts
@@ -1,78 +1,91 @@
-import { permissionHelper } from '@auth/authorization-helper';
-import { Response, Router, NextFunction } from 'express';
import { PolicyType, UserRole } from '@guardian/interfaces';
-import { AuthenticatedRequest, Logger } from '@guardian/common';
+import { Logger } from '@guardian/common';
import { Guardians } from '@helpers/guardians';
import { PolicyEngine } from '@helpers/policy-engine';
-import createError from 'http-errors';
+import { Controller, Delete, Get, HttpCode, HttpException, HttpStatus, Post, Req, Response } from '@nestjs/common';
+import { checkPermission } from '@auth/authorization-helper';
-/**
- * Artifact route
- */
-export const artifactAPI = Router();
+@Controller('artifacts')
+export class ArtifactApi {
-artifactAPI.get('/',
- permissionHelper(UserRole.STANDARD_REGISTRY),
- async (req: AuthenticatedRequest, res: Response, next: NextFunction) => {
- try {
- const policyId = req.query.policyId as string;
- const guardians = new Guardians();
- let pageIndex: any;
- let pageSize: any;
- if (req.query && req.query.pageIndex && req.query.pageSize) {
- pageIndex = req.query.pageIndex;
- pageSize = req.query.pageSize;
+ /**
+ * Get artifacts
+ * @param req
+ * @param res
+ */
+ @Get('/')
+ @HttpCode(HttpStatus.OK)
+ async getArtifacts(@Req() req, @Response() res): Promise {
+ await checkPermission(UserRole.STANDARD_REGISTRY)(req.user);
+ try {
+ const policyId = req.query.policyId as string;
+ const guardians = new Guardians();
+ let pageIndex: any;
+ let pageSize: any;
+ if (req.query && req.query.pageIndex && req.query.pageSize) {
+ pageIndex = req.query.pageIndex;
+ pageSize = req.query.pageSize;
+ }
+ const { artifacts, count } = await guardians.getArtifacts(req.user.did, policyId, pageIndex, pageSize);
+ return res.setHeader('X-Total-Count', count).json(artifacts);
+ } catch (error) {
+ new Logger().error(error, ['API_GATEWAY']);
+ throw error;
}
- const { artifacts, count } = await guardians.getArtifacts(req.user.did, policyId, pageIndex, pageSize);
- return res.setHeader('X-Total-Count', count).json(artifacts);
- } catch (error) {
- new Logger().error(error, ['API_GATEWAY']);
- return next(error);
}
-});
-artifactAPI.post('/:policyId', permissionHelper(UserRole.STANDARD_REGISTRY),
- async (req: AuthenticatedRequest, res: Response, next: NextFunction) => {
- try {
- const guardian = new Guardians();
- const policyEngine = new PolicyEngine();
- const policy = await policyEngine.getPolicy({
- filters: {
- id: req.params.policyId,
- owner: req.user.did
+ /**
+ * upload
+ * @param req
+ * @param res
+ */
+ @Post('/:policyId')
+ @HttpCode(HttpStatus.CREATED)
+ async uploadArtifacts(@Req() req, @Response() res): Promise {
+ await checkPermission(UserRole.STANDARD_REGISTRY)(req.user);
+ try {
+ const guardian = new Guardians();
+ const policyEngine = new PolicyEngine();
+ const policy = await policyEngine.getPolicy({
+ filters: {
+ id: req.params.policyId,
+ owner: req.user.did
+ }
+ });
+ if (!policy || policy.status !== PolicyType.DRAFT) {
+ throw new HttpException('There is no appropriate policy or policy is not in DRAFT status', HttpStatus.UNPROCESSABLE_ENTITY);
}
- });
- if (!policy || policy.status !== PolicyType.DRAFT) {
- return next(createError(422, 'There is no appropriate policy or policy is not in DRAFT status'));
- }
- const files = req.files;
- if (!files) {
- return next(createError(422, 'There are no files to upload'));
- }
- const artifacts = Array.isArray(files.artifacts) ? files.artifacts : [files.artifacts];
- const uploadedArtifacts = [];
- for (const artifact of artifacts) {
- if (!artifact) {
- continue;
+ const files = req.files;
+ if (!files) {
+ throw new HttpException('There are no files to upload', HttpStatus.UNPROCESSABLE_ENTITY)
+ // return next(createError(422, 'There are no files to upload'));
}
- uploadedArtifacts.push(await guardian.uploadArtifact(artifact, req.user.did, req.params.policyId));
+ const artifacts = Array.isArray(files.artifacts) ? files.artifacts : [files.artifacts];
+ const uploadedArtifacts = [];
+ for (const artifact of artifacts) {
+ if (!artifact) {
+ continue;
+ }
+ uploadedArtifacts.push(await guardian.uploadArtifact(artifact, req.user.did, req.params.policyId));
+ }
+ return res.status(201).json(uploadedArtifacts);
+ } catch (error) {
+ new Logger().error(error, ['API_GATEWAY']);
+ throw error;
}
- return res.status(201).json(uploadedArtifacts);
- } catch (error) {
- new Logger().error(error, ['API_GATEWAY']);
- return next(error);
}
-});
-artifactAPI.delete('/:artifactId',
- permissionHelper(UserRole.STANDARD_REGISTRY),
- async (req: AuthenticatedRequest, res: Response, next: NextFunction) => {
- try {
- const guardian = new Guardians();
- await guardian.deleteArtifact(req.params.artifactId, req.user.did)
- return res.status(204).send();
- } catch (error) {
- new Logger().error(error, ['API_GATEWAY']);
- return next(error);
+ @Delete('/:artifactId')
+ @HttpCode(HttpStatus.NO_CONTENT)
+ async deleteArtifact(@Req() req, @Response() res): Promise {
+ await checkPermission(UserRole.STANDARD_REGISTRY)(req.user);
+ try {
+ const guardian = new Guardians();
+ await guardian.deleteArtifact(req.params.artifactId, req.user.did)
+ return res.status(204).send();
+ } catch (error) {
+ new Logger().error(error, ['API_GATEWAY']);
+ throw error;
+ }
}
-});
+}
diff --git a/api-gateway/src/api/service/contract.ts b/api-gateway/src/api/service/contract.ts
index c816309f20..8cabfb4deb 100644
--- a/api-gateway/src/api/service/contract.ts
+++ b/api-gateway/src/api/service/contract.ts
@@ -1,240 +1,245 @@
import { Guardians } from '@helpers/guardians';
-import { Response, Router, NextFunction } from 'express';
-import { UserRole} from '@guardian/interfaces';
-import { permissionHelper } from '@auth/authorization-helper';
-import { AuthenticatedRequest, Logger } from '@guardian/common';
-import validate from '@middlewares/validation';
-import { importSchema, retireRequestSchema, retireSchema } from '@middlewares/validation/schemas/contracts';
+import { UserRole } from '@guardian/interfaces';
+import { Logger } from '@guardian/common';
+import { Controller, Delete, Get, HttpCode, HttpStatus, Post, Req, Response } from '@nestjs/common';
+import { checkPermission } from '@auth/authorization-helper';
/**
- * Contract route
+ * Contracts api
*/
-export const contractAPI = Router();
+@Controller('contracts')
+export class ContractsApi {
-contractAPI.get('/', async (req: AuthenticatedRequest, res: Response, next: NextFunction) => {
- try {
- const user = req.user;
- const guardians = new Guardians();
- const [contracts, count] = await guardians.getContracts(
- user.parent || user.did,
- req.query.pageIndex as any,
- req.query.pageSize as any
- );
- return res.setHeader('X-Total-Count', count).json(contracts);
- } catch (error) {
- new Logger().error(error, ['API_GATEWAY']);
- return next(error)
- }
-});
+ /**
+ * Get contracts
+ * @param req
+ * @param res
+ */
+ @Get()
+ @HttpCode(HttpStatus.OK)
+ async getContracts(@Req() req, @Response() res): Promise {
+ try {
+ const user = req.user;
+ const guardians = new Guardians();
+ const [contracts, count] = await guardians.getContracts(
+ user.parent || user.did,
+ req.query.pageIndex as any,
+ req.query.pageSize as any
+ );
+ return res.setHeader('X-Total-Count', count).json(contracts);
+ } catch (error) {
+ new Logger().error(error, ['API_GATEWAY']);
+ throw error;
+ }
+ }
-contractAPI.post(
- '/',
- permissionHelper(UserRole.STANDARD_REGISTRY),
- async (req: AuthenticatedRequest, res: Response, next: NextFunction) => {
- try {
- const user = req.user;
- const {description} = req.body;
- const guardians = new Guardians();
- return res.json(
- await guardians.createContract(user.did, description)
- );
- } catch (error) {
- new Logger().error(error, ['API_GATEWAY']);
- return next(error)
+ /**
+ * Set contracts
+ * @param req
+ * @param res
+ */
+ @Post('/')
+ @HttpCode(HttpStatus.OK)
+ async setContracts(@Req() req, @Response() res): Promise {
+ await checkPermission(UserRole.STANDARD_REGISTRY)(req.user);
+ try {
+ const user = req.user;
+ const {description} = req.body;
+ const guardians = new Guardians();
+ return res.status(201).json(
+ await guardians.createContract(user.did, description)
+ );
+ } catch (error) {
+ new Logger().error(error, ['API_GATEWAY']);
+ throw error;
+ }
}
- }
-);
-contractAPI.post(
- '/import',
- [validate(importSchema()), permissionHelper(UserRole.STANDARD_REGISTRY)],
- async (req: AuthenticatedRequest, res: Response, next: NextFunction) => {
- try {
- const user = req.user;
- const {contractId, description} = req.body;
- const guardians = new Guardians();
- return res.json(
- await guardians.importContract(
- user.did,
- contractId,
- description
- )
- );
- } catch (error) {
- new Logger().error(error, ['API_GATEWAY']);
- return next(error)
+ @Post('/import')
+ @HttpCode(HttpStatus.OK)
+ async importContracts(@Req() req, @Response() res): Promise {
+ await checkPermission(UserRole.STANDARD_REGISTRY)(req.user);
+ try {
+ const user = req.user;
+ const {contractId, description} = req.body;
+ const guardians = new Guardians();
+ return res.json(
+ await guardians.importContract(
+ user.did,
+ contractId,
+ description
+ )
+ );
+ } catch (error) {
+ new Logger().error(error, ['API_GATEWAY']);
+ throw error;
+ }
}
- }
-);
-contractAPI.post(
- '/:contractId/user',
- permissionHelper(UserRole.STANDARD_REGISTRY),
- async (req: AuthenticatedRequest, res: Response, next: NextFunction) => {
- try {
- const user = req.user;
- const {userId} = req.body;
- const guardians = new Guardians();
- return res.json(
- await guardians.addUser(user.did, userId, req.params.contractId)
- );
- } catch (error) {
- new Logger().error(error, ['API_GATEWAY']);
- return next(error)
+ @Post('/:contractId/user')
+ @HttpCode(HttpStatus.OK)
+ async userContract(@Req() req, @Response() res): Promise {
+ await checkPermission(UserRole.STANDARD_REGISTRY)(req.user);
+ try {
+ const user = req.user;
+ const {userId} = req.body;
+ const guardians = new Guardians();
+ return res.json(
+ await guardians.addUser(user.did, userId, req.params.contractId)
+ );
+ } catch (error) {
+ new Logger().error(error, ['API_GATEWAY']);
+ throw error;
+ }
}
- }
-);
-contractAPI.post(
- '/:contractId/status',
- permissionHelper(UserRole.STANDARD_REGISTRY),
- async (req: AuthenticatedRequest, res: Response, next: NextFunction) => {
- try {
- const user = req.user;
- const guardians = new Guardians();
- return res.json(
- await guardians.updateStatus(user.did, req.params.contractId)
- );
- } catch (error) {
- new Logger().error(error, ['API_GATEWAY']);
- return next(error)
+ @Post(':contractId/status')
+ @HttpCode(HttpStatus.OK)
+ async contractStatus(@Req() req, @Response() res): Promise {
+ await checkPermission(UserRole.STANDARD_REGISTRY)(req.user);
+ try {
+ const user = req.user;
+ const guardians = new Guardians();
+ return res.json(
+ await guardians.updateStatus(user.did, req.params.contractId)
+ );
+ } catch (error) {
+ new Logger().error(error, ['API_GATEWAY']);
+ throw error;
+ }
}
- }
-);
-contractAPI.get('/pair', async (req: AuthenticatedRequest, res: Response, next: NextFunction) => {
- try {
- const user = req.user;
- const guardians = new Guardians();
- return res.json(
- await guardians.getContractPair(
- user.did,
- user.parent || user.did,
- req.query?.baseTokenId as string,
- req.query?.oppositeTokenId as string
- )
- );
- } catch (error) {
- new Logger().error(error, ['API_GATEWAY']);
- return next(error);
- }
-});
+ @Get('/pair')
+ @HttpCode(HttpStatus.OK)
+ async contractPair(@Req() req, @Response() res): Promise {
+ try {
+ const user = req.user;
+ const guardians = new Guardians();
+ return res.json(
+ await guardians.getContractPair(
+ user.did,
+ user.parent || user.did,
+ req.query?.baseTokenId as string,
+ req.query?.oppositeTokenId as string
+ )
+ );
+ } catch (error) {
+ new Logger().error(error, ['API_GATEWAY']);
+ throw error;
+ }
+ }
-contractAPI.post(
- '/:contractId/pair',
- permissionHelper(UserRole.STANDARD_REGISTRY),
- async (req: AuthenticatedRequest, res: Response, next: NextFunction) => {
- try {
- const user = req.user;
- const {
- baseTokenId,
- oppositeTokenId,
- baseTokenCount,
- oppositeTokenCount,
- } = req.body;
- const guardians = new Guardians();
- return res.json(
- await guardians.addContractPair(
- user.did,
- req.params.contractId,
- baseTokenId,
- oppositeTokenId,
- baseTokenCount,
- oppositeTokenCount
- )
- );
- } catch (error) {
- new Logger().error(error, ['API_GATEWAY']);
- return next(error);
+ @Post('/:contractId/pair')
+ @HttpCode(HttpStatus.OK)
+ async setPair(@Req() req, @Response() res): Promise {
+ await checkPermission(UserRole.STANDARD_REGISTRY)(req.user);
+ try {
+ const user = req.user;
+ const {
+ baseTokenId,
+ oppositeTokenId,
+ baseTokenCount,
+ oppositeTokenCount,
+ } = req.body;
+ const guardians = new Guardians();
+ return res.json(
+ await guardians.addContractPair(
+ user.did,
+ req.params.contractId,
+ baseTokenId,
+ oppositeTokenId,
+ baseTokenCount,
+ oppositeTokenCount
+ )
+ );
+ } catch (error) {
+ new Logger().error(error, ['API_GATEWAY']);
+ throw error;
+ }
}
- }
-);
-contractAPI.get(
- '/retire/request',
- async (req: AuthenticatedRequest, res: Response, next: NextFunction) => {
- try {
- const user = req.user;
- const guardians = new Guardians();
- const [requests, count] = await guardians.getRetireRequests(
- user.parent || user.did,
- user.role === UserRole.USER ? user.did : null,
- req.query?.contractId as string,
- req.query?.pageIndex as any,
- req.query?.pageSize as any
- );
- return res.setHeader('X-Total-Count', count).json(requests);
- } catch (error) {
- new Logger().error(error, ['API_GATEWAY']);
- return next(error);
+ @Get('/retire/request')
+ @HttpCode(HttpStatus.OK)
+ async retireRequest(@Req() req, @Response() res): Promise {
+ try {
+ const user = req.user;
+ const guardians = new Guardians();
+ const [requests, count] = await guardians.getRetireRequests(
+ user.parent || user.did,
+ user.role === UserRole.USER ? user.did : null,
+ req.query?.contractId as string,
+ req.query?.pageIndex as any,
+ req.query?.pageSize as any
+ );
+ return res.setHeader('X-Total-Count', count).json(requests);
+ } catch (error) {
+ new Logger().error(error, ['API_GATEWAY']);
+ throw error;
+ }
}
- }
-);
-contractAPI.post(
- '/:contractId/retire/request', validate(retireRequestSchema()),
- async (req: AuthenticatedRequest, res: Response, next: NextFunction) => {
- try {
- const user = req.user;
- const {
- baseTokenId,
- oppositeTokenId,
- baseTokenCount,
- oppositeTokenCount,
- baseTokenSerials,
- oppositeTokenSerials,
- } = req.body;
- const guardians = new Guardians();
- return res.json(
- await guardians.retireRequest(
- user.did,
- req.params.contractId,
- baseTokenId,
- oppositeTokenId,
- baseTokenCount,
- oppositeTokenCount,
- baseTokenSerials,
- oppositeTokenSerials
- )
- );
- } catch (error) {
- new Logger().error(error, ['API_GATEWAY']);
- return next(error)
+ @Post('/:contractId/retire/request')
+ @HttpCode(HttpStatus.OK)
+ async postRetireRequest(@Req() req, @Response() res): Promise {
+ try {
+ const user = req.user;
+ const {
+ baseTokenId,
+ oppositeTokenId,
+ baseTokenCount,
+ oppositeTokenCount,
+ baseTokenSerials,
+ oppositeTokenSerials,
+ } = req.body;
+ const guardians = new Guardians();
+ return res.json(
+ await guardians.retireRequest(
+ user.did,
+ req.params.contractId,
+ baseTokenId,
+ oppositeTokenId,
+ baseTokenCount,
+ oppositeTokenCount,
+ baseTokenSerials,
+ oppositeTokenSerials
+ )
+ );
+ } catch (error) {
+ new Logger().error(error, ['API_GATEWAY']);
+ throw error;
+ }
}
- }
-);
-contractAPI.delete(
- '/retire/request',
- async (req: AuthenticatedRequest, res: Response, next: NextFunction) => {
- try {
- const user = req.user;
- const guardians = new Guardians();
- return res.json(
- await guardians.cancelRetireRequest(
- user.did,
- req.query?.requestId as string
- )
- );
- } catch (error) {
- new Logger().error(error, ['API_GATEWAY']);
- return next(error)
+ @Delete('/retire/request')
+ @HttpCode(HttpStatus.OK)
+ async deleteRetireRequest(@Req() req, @Response() res): Promise {
+ try {
+ const user = req.user;
+ const guardians = new Guardians();
+ return res.json(
+ await guardians.cancelRetireRequest(
+ user.did,
+ req.query?.requestId as string
+ )
+ );
+ } catch (error) {
+ new Logger().error(error, ['API_GATEWAY']);
+ throw error;
+ }
}
- }
-);
-contractAPI.post(
- '/retire',
- [validate(retireSchema()), permissionHelper(UserRole.STANDARD_REGISTRY)],
- async (req: AuthenticatedRequest, res: Response, next: NextFunction) => {
- try {
- const user = req.user;
- const { requestId } = req.body;
- const guardians = new Guardians();
- return res.json(await guardians.retire(user.did, requestId));
- } catch (error) {
- new Logger().error(error, ['API_GATEWAY']);
- return next(error)
+ @Post('/retire')
+ @HttpCode(HttpStatus.OK)
+ async retire(@Req() req, @Response() res): Promise {
+ await checkPermission(UserRole.STANDARD_REGISTRY)(req.user);
+ try {
+ const user = req.user;
+ const { requestId } = req.body;
+ const guardians = new Guardians();
+ return res.json(await guardians.retire(user.did, requestId));
+ } catch (error) {
+ new Logger().error(error, ['API_GATEWAY']);
+ throw error;
+ }
}
- }
-);
+}
diff --git a/api-gateway/src/api/service/demo.ts b/api-gateway/src/api/service/demo.ts
index a56ed8e863..b5ac596711 100644
--- a/api-gateway/src/api/service/demo.ts
+++ b/api-gateway/src/api/service/demo.ts
@@ -1,164 +1,176 @@
-import { Request, Response, Router, NextFunction } from 'express';
import { Guardians } from '@helpers/guardians';
import { Users } from '@helpers/users';
import { Logger, RunFunctionAsync } from '@guardian/common';
import { TaskManager } from '@helpers/task-manager';
import { ServiceError } from '@helpers/service-requests-base';
-
-/**
- * Route for demo api
- */
-export const demoAPI = Router();
-
-/**
- * @deprecated 2023-03-01
- */
-demoAPI.get('/registeredUsers', async (req: Request, res: Response) => {
- const users = new Users();
- const guardians = new Guardians();
- try {
- const demoUsers: any = await users.getAllUserAccountsDemo();
-
- for (const element of demoUsers) {
- if (element.did) {
- element.policyRoles = await guardians.getUserRoles(element.did);
- } else {
- element.policyRoles = [];
- }
- }
-
- res.json(demoUsers);
- } catch (error) {
- new Logger().error(error, ['API_GATEWAY']);
- res.status(500).send({ code: 500, message: error.message });
- }
-});
-
-/**
- * @deprecated 2023-03-01
- */
-demoAPI.get('/randomKey', async (req: Request, res: Response) => {
- try {
+import { Controller, Get, HttpCode, HttpStatus, Req, Response } from '@nestjs/common';
+
+@Controller('demo')
+export class DemoApi {
+
+ /**
+ * @deprecated 2023-03-01
+ */
+ @Get('/registeredUsers')
+ @HttpCode(HttpStatus.OK)
+ async registeredUsers(@Req() req, @Response() res): Promise {
+ const users = new Users();
const guardians = new Guardians();
- let role = null;
try {
- const authHeader = req?.headers?.authorization;
- if (authHeader) {
- const users = new Users();
- const token = authHeader.split(' ')[1];
- const user = await users.getUserByToken(token) as any;
- role = user?.role;
+ const demoUsers: any = await users.getAllUserAccountsDemo();
+
+ for (const element of demoUsers) {
+ if (element.did) {
+ element.policyRoles = await guardians.getUserRoles(element.did);
+ } else {
+ element.policyRoles = [];
+ }
}
+
+ return res.json(demoUsers);
} catch (error) {
- role = null;
+ new Logger().error(error, ['API_GATEWAY']);
+ throw error;
}
- const demoKey = await guardians.generateDemoKey(role);
- res.status(200).json(demoKey);
- } catch (error) {
- new Logger().error(error, ['API_GATEWAY']);
- res.status(500).json({ code: 500, message: error.message });
}
-});
-/**
- * @deprecated 2023-03-01
- */
-demoAPI.get('/push/randomKey', async (req: Request, res: Response) => {
- const taskManager = new TaskManager();
- const { taskId, expectation } = taskManager.start('Create random key');
-
- const authHeader = req?.headers?.authorization;
- RunFunctionAsync(async () => {
- const guardians = new Guardians();
- let role = null;
- if (authHeader) {
+ /**
+ * @deprecated 2023-03-01
+ */
+ @Get('/randomKey')
+ @HttpCode(HttpStatus.OK)
+ async randomKey(@Req() req, @Response() res): Promise {
+ try {
+ const guardians = new Guardians();
+ let role = null;
try {
- const users = new Users();
- const token = authHeader.split(' ')[1];
- const user = await users.getUserByToken(token) as any;
- role = user?.role;
+ const authHeader = req?.headers?.authorization;
+ if (authHeader) {
+ const users = new Users();
+ const token = authHeader.split(' ')[1];
+ const user = await users.getUserByToken(token) as any;
+ role = user?.role;
+ }
} catch (error) {
role = null;
}
+ const demoKey = await guardians.generateDemoKey(role);
+ return demoKey;
+ } catch (error) {
+ new Logger().error(error, ['API_GATEWAY']);
+ throw error;
}
+ }
- await guardians.generateDemoKeyAsync(role, taskId);
- }, async (error) => {
- new Logger().error(error, ['API_GATEWAY']);
- taskManager.addError(taskId, { code: 500, message: error.message });
- });
-
- res.status(201).send({ taskId, expectation });
-});
-
-demoAPI.get('/registered-users', async (req: Request, res: Response, next: NextFunction) => {
- const users = new Users();
- const guardians = new Guardians();
- try {
- const demoUsers: any = await users.getAllUserAccountsDemo();
-
- for (const element of demoUsers) {
- if (element.did) {
- element.policyRoles = await guardians.getUserRoles(element.did);
- } else {
- element.policyRoles = [];
+ /**
+ * @deprecated 2023-03-01
+ */
+ @Get('/push/randomKey')
+ @HttpCode(HttpStatus.CREATED)
+ async pushRandomKey(@Req() req, @Response() res): Promise {
+ const taskManager = new TaskManager();
+ const { taskId, expectation } = taskManager.start('Create random key');
+
+ const authHeader = req?.headers?.authorization;
+ RunFunctionAsync(async () => {
+ const guardians = new Guardians();
+ let role = null;
+ if (authHeader) {
+ try {
+ const users = new Users();
+ const token = authHeader.split(' ')[1];
+ const user = await users.getUserByToken(token) as any;
+ role = user?.role;
+ } catch (error) {
+ role = null;
+ }
}
- }
- res.json(demoUsers);
- } catch (error) {
- new Logger().error(error, ['API_GATEWAY']);
- return next(error);
+ await guardians.generateDemoKeyAsync(role, taskId);
+ }, async (error) => {
+ new Logger().error(error, ['API_GATEWAY']);
+ taskManager.addError(taskId, { code: 500, message: error.message });
+ });
+
+ return res.status(201).send({ taskId, expectation });
}
-});
-demoAPI.get('/random-key', async (req: Request, res: Response, next: NextFunction) => {
- try {
+ @Get('/registered-users')
+ @HttpCode(HttpStatus.OK)
+ async registeredUsers2(@Req() req, @Response() res): Promise {
+ const users = new Users();
const guardians = new Guardians();
- let role = null;
try {
- const authHeader = req?.headers?.authorization;
- if (authHeader) {
- const users = new Users();
- const token = authHeader.split(' ')[1];
- const user = await users.getUserByToken(token) as any;
- role = user?.role;
+ const demoUsers: any = await users.getAllUserAccountsDemo();
+
+ for (const element of demoUsers) {
+ if (element.did) {
+ element.policyRoles = await guardians.getUserRoles(element.did);
+ } else {
+ element.policyRoles = [];
+ }
}
+
+ return res.json(demoUsers);
} catch (error) {
- role = null;
+ new Logger().error(error, ['API_GATEWAY']);
+ throw error;
}
- const demoKey = await guardians.generateDemoKey(role);
- return res.json(demoKey);
- } catch (error) {
- new Logger().error(error, ['API_GATEWAY']);
- return next(error);
}
-});
-
-demoAPI.get('/push/random-key', async (req: Request, res: Response) => {
- const taskManager = new TaskManager();
- const { taskId, expectation } = taskManager.start('Create random key');
- const authHeader = req?.headers?.authorization;
- RunFunctionAsync(async () => {
- const guardians = new Guardians();
- let role = null;
- if (authHeader) {
+ @Get('/random-key')
+ @HttpCode(HttpStatus.OK)
+ async randomKey2(@Req() req): Promise {
+ try {
+ const guardians = new Guardians();
+ let role = null;
try {
- const users = new Users();
- const token = authHeader.split(' ')[1];
- const user = await users.getUserByToken(token) as any;
- role = user?.role;
+ const authHeader = req?.headers?.authorization;
+ if (authHeader) {
+ const users = new Users();
+ const token = authHeader.split(' ')[1];
+ const user = await users.getUserByToken(token) as any;
+ role = user?.role;
+ }
} catch (error) {
role = null;
}
+ const demoKey = await guardians.generateDemoKey(role);
+ return demoKey;
+ } catch (error) {
+ new Logger().error(error, ['API_GATEWAY']);
+ throw error;
}
+ }
+
+ @Get('/push/random-key')
+ @HttpCode(HttpStatus.ACCEPTED)
+ async pushRandomKey2(@Req() req, @Response() res): Promise {
+ const taskManager = new TaskManager();
+ const { taskId, expectation } = taskManager.start('Create random key');
- await guardians.generateDemoKeyAsync(role, taskId);
- }, async (error) => {
- new Logger().error(error, ['API_GATEWAY']);
- taskManager.addError(taskId, { code: 500, message: error.message });
- });
+ const authHeader = req?.headers?.authorization;
+ RunFunctionAsync(async () => {
+ const guardians = new Guardians();
+ let role = null;
+ if (authHeader) {
+ try {
+ const users = new Users();
+ const token = authHeader.split(' ')[1];
+ const user = await users.getUserByToken(token) as any;
+ role = user?.role;
+ } catch (error) {
+ role = null;
+ }
+ }
+
+ await guardians.generateDemoKeyAsync(role, taskId);
+ }, async (error) => {
+ new Logger().error(error, ['API_GATEWAY']);
+ taskManager.addError(taskId, { code: 500, message: error.message });
+ });
+
+ return res.status(202).send({ taskId, expectation });
+ }
- return res.status(202).send({ taskId, expectation });
-});
+}
diff --git a/api-gateway/src/api/service/external.ts b/api-gateway/src/api/service/external.ts
index a88cd3d3d7..0b2535001f 100644
--- a/api-gateway/src/api/service/external.ts
+++ b/api-gateway/src/api/service/external.ts
@@ -1,19 +1,19 @@
-import { Request, Response, Router, NextFunction } from 'express';
import { PolicyEngine } from '@helpers/policy-engine';
import { Logger } from '@guardian/common';
+import { Controller, HttpCode, HttpStatus, Post, Req, Response } from '@nestjs/common';
-/**
- * Route for demo api
- */
-export const externalAPI = Router();
+@Controller('external')
+export class ExternalApi {
+ @Post('/')
+ @HttpCode(HttpStatus.OK)
+ async receiveExternalData(@Req() req, @Response() res): Promise {
+ const engineService = new PolicyEngine();
-externalAPI.post('/', async (req: Request, res: Response, next: NextFunction) => {
- const engineService = new PolicyEngine();
-
- try {
- res.send(await engineService.receiveExternalData(req.body));
- } catch (error) {
- new Logger().error(error, ['API_GATEWAY']);
- return next(error);
+ try {
+ return res.send(await engineService.receiveExternalData(req.body));
+ } catch (error) {
+ new Logger().error(error, ['API_GATEWAY']);
+ throw error;
+ }
}
-});
+}
diff --git a/api-gateway/src/api/service/index.ts b/api-gateway/src/api/service/index.ts
index 90370e15a8..d187bbde98 100644
--- a/api-gateway/src/api/service/index.ts
+++ b/api-gateway/src/api/service/index.ts
@@ -1,15 +1,16 @@
-export { trustchainsAPI } from '@api/service/trustchains';
-export { trustChainsAPI } from '@api/service/trust-chains';
-export { profileAPI } from '@api/service/profile';
-export { schemaAPI } from '@api/service/schema';
-export { tokenAPI } from '@api/service/tokens';
-export { accountAPI } from '@api/service/account';
-export { demoAPI } from '@api/service/demo';
-export { externalAPI } from '@api/service/external';
-export { ipfsAPI } from '@api/service/ipfs'
-export { loggerAPI } from '@api/service/logger';
-export { settingsAPI } from '@api/service/settings';
-export { analyticsAPI } from '@api/service/analytics';
-export { moduleAPI } from '@api/service/module';
-export { tagsAPI } from '@api/service/tags';
-export { themesAPI } from '@api/service/themes';
\ No newline at end of file
+// export { trustchainsAPI } from '@api/service/trustchains';
+// export { trustChainsAPI } from '@api/service/trust-chains';
+// export { profileAPI } from '@api/service/profile';
+// export { schemaAPI } from '@api/service/schema';
+// export { tokenAPI } from '@api/service/tokens';
+// export { accountAPI } from '@api/service/account';
+// export { demoAPI } from '@api/service/demo';
+// export { externalAPI } from '@api/service/external';
+// export { ipfsAPI } from '@api/service/ipfs'
+// export { loggerAPI } from '@api/service/logger';
+// export { settingsAPI } from '@api/service/settings';
+// export { analyticsAPI } from '@api/service/analytics';
+// export { moduleAPI } from '@api/service/module';
+// export { tagsAPI } from '@api/service/tags';
+// export { themesAPI } from '@api/service/themes';
+// export { metricsAPI } from '@api/service/metrics';
diff --git a/api-gateway/src/api/service/ipfs.ts b/api-gateway/src/api/service/ipfs.ts
index c8f5d03620..1155590078 100644
--- a/api-gateway/src/api/service/ipfs.ts
+++ b/api-gateway/src/api/service/ipfs.ts
@@ -1,48 +1,49 @@
-import { Response, Router, NextFunction} from 'express';
-import { AuthenticatedRequest, Logger } from '@guardian/common';
+import { Logger } from '@guardian/common';
import { Guardians } from '@helpers/guardians';
-import createError from 'http-errors';
-import { prepareValidationResponse } from '@middlewares/validation';
+import { Controller, Get, HttpCode, HttpException, HttpStatus, Post, Req, Response } from '@nestjs/common';
-/**
- * IPFS route
- */
-export const ipfsAPI = Router();
+@Controller('ipfs')
+export class IpfsApi {
+ @Post('/file')
+ @HttpCode(HttpStatus.CREATED)
+ async postFile(@Req() req, @Response() res): Promise {
+ try {
+ if (!Object.values(req.body).length) {
+ throw new HttpException('Body content in request is empty', HttpStatus.UNPROCESSABLE_ENTITY)
+ }
-ipfsAPI.post('/file', async (req: AuthenticatedRequest, res: Response, next: NextFunction) => {
- try {
- if (!Object.values(req.body).length) {
- return res.status(422).json(prepareValidationResponse('Body content in request is empty'));
- }
+ const guardians = new Guardians();
+ const { cid } = await guardians.addFileIpfs(req.body);
+ if (!cid) {
+ throw new HttpException('File is not uploaded', HttpStatus.BAD_REQUEST)
+ // return next(createError(400, 'File is not uploaded'));
+ }
- const guardians = new Guardians();
- const { cid } = await guardians.addFileIpfs(req.body);
- if (!cid) {
- return next(createError(400, 'File is not uploaded'));
+ return res.status(201).json(cid);
+ } catch (error) {
+ new Logger().error(error, ['API_GATEWAY']);
+ throw error;
}
-
- return res.status(201).json(cid);
- } catch (error) {
- new Logger().error(error, ['API_GATEWAY']);
- return next(error);
}
-});
-ipfsAPI.get('/file/:cid', async (req: AuthenticatedRequest, res: Response, next: NextFunction) => {
- try {
- const guardians = new Guardians();
- const result = await guardians.getFileIpfs(req.params.cid, 'raw');
- const resultBuffer = Buffer.from(result);
- if (!result) {
- return next(createError(404, 'File is not uploaded'));
+ @Get('/file/:cid')
+ @HttpCode(HttpStatus.OK)
+ async getFile(@Req() req, @Response() res): Promise {
+ try {
+ const guardians = new Guardians();
+ const result = await guardians.getFileIpfs(req.params.cid, 'raw');
+ const resultBuffer = Buffer.from(result);
+ if (!result) {
+ throw new HttpException('File is not uploaded', HttpStatus.NOT_FOUND)
+ }
+ res.writeHead(200, {
+ 'Content-Type': 'binary/octet-stream',
+ 'Content-Length': resultBuffer.length,
+ });
+ return res.end(resultBuffer, 'binary');
+ } catch (error) {
+ new Logger().error(error, ['API_GATEWAY']);
+ throw error;
}
- res.writeHead(200, {
- 'Content-Type': 'binary/octet-stream',
- 'Content-Length': resultBuffer.length,
- });
- return res.end(resultBuffer, 'binary');
- } catch (error) {
- new Logger().error(error, ['API_GATEWAY']);
- return next(error);
}
-});
+}
diff --git a/api-gateway/src/api/service/logger.ts b/api-gateway/src/api/service/logger.ts
index 17d98bcf8b..c5d9f0074a 100644
--- a/api-gateway/src/api/service/logger.ts
+++ b/api-gateway/src/api/service/logger.ts
@@ -1,12 +1,96 @@
-import { permissionHelper } from '@auth/authorization-helper';
-import { Request, Response, Router, NextFunction } from 'express';
-import { IPageParameters, UserRole } from '@guardian/interfaces';
+import { IPageParameters, MessageAPI, UserRole } from '@guardian/interfaces';
import { Logger } from '@guardian/common';
+import { Controller, Get, HttpCode, HttpStatus, Inject, Injectable, Post, Req, Response } from '@nestjs/common';
+import { ClientProxy } from '@nestjs/microservices';
+import { checkPermission } from '@auth/authorization-helper';
+
+@Injectable()
+export class LoggerService {
+ constructor(@Inject('GUARDIANS') private readonly client: ClientProxy) {
+ }
+
+ async getLogs(filters?: any, pageParameters?: IPageParameters, sortDirection?: string): Promise {
+ const logs = await this.client.send(MessageAPI.GET_LOGS, {
+ filters, pageParameters, sortDirection
+ }).toPromise();
+ return logs.body;
+ }
+
+ async getAttributes(name?: string, existingAttributes: string[] = []): Promise {
+ const logs = await this.client.send(MessageAPI.GET_ATTRIBUTES, {
+ name, existingAttributes
+ }).toPromise();
+ return logs.body;
+ }
+}
+
+@Controller('logs')
+export class LoggerApi {
+ constructor(private readonly loggerService: LoggerService) {
+ }
+
+ @Post('/')
+ @HttpCode(HttpStatus.OK)
+ async getLogs(@Req() req, @Response() res): Promise {
+ await checkPermission(UserRole.STANDARD_REGISTRY)(req.user);
+ try {
+ const filters: any = {};
+ const pageParameters: IPageParameters = {};
+ if (req.body.type) {
+ filters.type = req.body.type;
+ }
+ if (req.body.startDate && req.body.endDate) {
+ const sDate = new Date(req.body.startDate);
+ sDate.setHours(0, 0, 0, 0);
+ const eDate = new Date(req.body.endDate);
+ eDate.setHours(23, 59, 59, 999);
+ filters.datetime = {
+ $gte: sDate,
+ $lt: eDate
+ };
+ }
+ if (req.body.attributes && req.body.attributes.length !== 0) {
+ filters.attributes = { $in: req.body.attributes };
+ }
+ if (req.body.message) {
+ filters.message = {
+ $regex: `.*${escapeRegExp(req.body.message)}.*`,
+ $options: 'i'
+ }
+ }
+ if (req.body.pageSize) {
+ pageParameters.offset = (req.body.pageIndex || 0) * req.body.pageSize;
+ pageParameters.limit = req.body.pageSize;
+ }
+ const logsObj = await this.loggerService.getLogs(filters, pageParameters, req.body.sortDirection);
+ return res.send(logsObj);
+ } catch (error) {
+ new Logger().error(error, ['API_GATEWAY']);
+ throw error;
+ }
+ }
+
+ @Get('attributes')
+ @HttpCode(HttpStatus.OK)
+ async getAttributes(@Req() req, @Response() res): Promise {
+ await checkPermission(UserRole.STANDARD_REGISTRY)(req.user);
+ try {
+ if (req.query.existingAttributes && !Array.isArray(req.query.existingAttributes)) {
+ req.query.existingAttributes = [req.query.existingAttributes as string];
+ }
+ const attributes = await this.loggerService.getAttributes(escapeRegExp(req.query.name as string), req.query.existingAttributes as string[]);
+ return res.send(attributes);
+ } catch (error) {
+ new Logger().error(error, ['API_GATEWAY']);
+ throw error;
+ }
+ }
+}
/**
* Logger route
*/
-export const loggerAPI = Router();
+// export const loggerAPI = Router();
/**
* Add escape characters
@@ -20,57 +104,3 @@ function escapeRegExp(text: string): string {
return text.replace(/[-[\]{}()*+?.,\\^$|#\s]/g, '\\$&');
}
-
-loggerAPI.post('/', permissionHelper(UserRole.STANDARD_REGISTRY), async (req: Request, res: Response, next: NextFunction) => {
- try {
- const filters: any = {};
- const pageParameters: IPageParameters = {};
- if (req.body.type) {
- filters.type = req.body.type;
- }
- if (req.body.startDate && req.body.endDate) {
- const sDate = new Date(req.body.startDate);
- sDate.setHours(0, 0, 0, 0);
- const eDate = new Date(req.body.endDate);
- eDate.setHours(23, 59, 59, 999);
- filters.datetime = {
- $gte: sDate,
- $lt: eDate
- };
- }
- if (req.body.attributes && req.body.attributes.length !== 0) {
- filters.attributes = { $in: req.body.attributes };
- }
- if (req.body.message) {
- filters.message = {
- $regex: `.*${escapeRegExp(req.body.message)}.*`,
- $options: 'i'
- }
- }
- if (req.body.pageSize) {
- pageParameters.offset = (req.body.pageIndex || 0) * req.body.pageSize;
- pageParameters.limit = req.body.pageSize;
- }
- const logger = new Logger();
- const logsObj = await logger.getLogs(filters, pageParameters, req.body.sortDirection);
- return res.send(logsObj);
- } catch (error) {
- new Logger().error(error, ['API_GATEWAY']);
- return next(error);
- }
-});
-
-loggerAPI.get('/attributes', permissionHelper(UserRole.STANDARD_REGISTRY),
- async (req: Request, res: Response, next: NextFunction) => {
- try {
- const logger = new Logger();
- if (req.query.existingAttributes && !Array.isArray(req.query.existingAttributes)) {
- req.query.existingAttributes = [req.query.existingAttributes as string];
- }
- const attributes = await logger.getAttributes(escapeRegExp(req.query.name as string), req.query.existingAttributes as string[]);
- return res.send(attributes);
- } catch (error) {
- new Logger().error(error, ['API_GATEWAY']);
- return next(error);
- }
-});
diff --git a/api-gateway/src/api/service/map.ts b/api-gateway/src/api/service/map.ts
index 6c009b1621..b9e872968f 100644
--- a/api-gateway/src/api/service/map.ts
+++ b/api-gateway/src/api/service/map.ts
@@ -1,21 +1,12 @@
-import { Response, Router, NextFunction } from 'express';
-import { AuthenticatedRequest, Logger } from '@guardian/common';
import { Guardians } from '@helpers/guardians';
+import { Controller, Get, HttpCode, HttpStatus } from '@nestjs/common';
-/**
- * Map route
- */
-export const mapAPI = Router();
-
-mapAPI.get(
- '/key',
- async (req: AuthenticatedRequest, res: Response, next: NextFunction) => {
- try {
- const guardians = new Guardians();
- res.send(await guardians.getMapApiKey());
- } catch (error) {
- new Logger().error(error, ['API_GATEWAY']);
- return next(error);
- }
+@Controller('map')
+export class MapApi {
+ @Get('/key')
+ @HttpCode(HttpStatus.OK)
+ async getKey() {
+ const guardians = new Guardians();
+ return await guardians.getMapApiKey();
}
-);
+}
diff --git a/api-gateway/src/api/service/metrics.ts b/api-gateway/src/api/service/metrics.ts
new file mode 100644
index 0000000000..4ea7fb328c
--- /dev/null
+++ b/api-gateway/src/api/service/metrics.ts
@@ -0,0 +1,12 @@
+import client from 'prom-client';
+import { Controller, Get, HttpCode, HttpStatus, Response } from '@nestjs/common';
+
+@Controller('metrics')
+export class MetricsApi {
+ @Get('/')
+ @HttpCode(HttpStatus.OK)
+ async getMetrics(@Response() res) {
+ res.set('Content-Type', client.register.contentType);
+ return res.send(await client.register.metrics());
+ }
+}
diff --git a/api-gateway/src/api/service/module.ts b/api-gateway/src/api/service/module.ts
index 19013c951b..50c1e9657f 100644
--- a/api-gateway/src/api/service/module.ts
+++ b/api-gateway/src/api/service/module.ts
@@ -1,193 +1,232 @@
-import { permissionHelper } from '@auth/authorization-helper';
-import { Response, Router, NextFunction } from 'express';
-import { UserRole } from '@guardian/interfaces';
-import { AuthenticatedRequest, Logger } from '@guardian/common';
+import { Logger } from '@guardian/common';
import { Guardians } from '@helpers/guardians';
-import createError from 'http-errors';
+import { Controller, Delete, Get, HttpCode, HttpException, HttpStatus, Post, Put, Req, Response } from '@nestjs/common';
+import { checkPermission } from '@auth/authorization-helper';
+import { UserRole } from '@guardian/interfaces';
-/**
- * Module route
- */
-export const moduleAPI = Router();
+@Controller('modules')
+export class ModulesApi {
+ @Post('/')
+ @HttpCode(HttpStatus.CREATED)
+ async postModules(@Req() req, @Response() res): Promise {
+ await checkPermission(UserRole.STANDARD_REGISTRY)(req.user);
+ try {
+ const guardian = new Guardians();
+ const module = req.body;
+ if (!module.config || module.config.blockType !== 'module') {
+ throw new HttpException('Invalid module config', HttpStatus.UNPROCESSABLE_ENTITY);
+ }
+ const item = await guardian.createModule(module, req.user.did);
+ return res.status(201).json(item);
+ } catch (error) {
+ new Logger().error(error, ['API_GATEWAY']);
+ throw new HttpException(error.message, HttpStatus.INTERNAL_SERVER_ERROR);
+ }
+ }
-moduleAPI.post('/', permissionHelper(UserRole.STANDARD_REGISTRY), async (req: AuthenticatedRequest, res: Response, next: NextFunction) => {
- try {
- const guardian = new Guardians();
- const module = req.body;
- if (!module.config || module.config.blockType !== 'module') {
- return next(createError(422, 'Invalid module config'));
+ @Get('/')
+ @HttpCode(HttpStatus.OK)
+ async getModules(@Req() req, @Response() res): Promise {
+ await checkPermission(UserRole.STANDARD_REGISTRY)(req.user);
+ try {
+ const guardians = new Guardians();
+
+ let pageIndex: any;
+ let pageSize: any;
+ if (req.query && req.query.pageIndex && req.query.pageSize) {
+ pageIndex = req.query.pageIndex;
+ pageSize = req.query.pageSize;
+ }
+ const { items, count } = await guardians.getModule({
+ owner: req.user.did,
+ pageIndex,
+ pageSize
+ });
+ return res.setHeader('X-Total-Count', count).json(items);
+ } catch (error) {
+ new Logger().error(error, ['API_GATEWAY']);
+ throw new HttpException(error.message, HttpStatus.INTERNAL_SERVER_ERROR);
}
- const item = await guardian.createModule(module, req.user.did);
- res.status(201).json(item);
- } catch (error) {
- new Logger().error(error, ['API_GATEWAY']);
- return next(error);
}
-});
-moduleAPI.get('/', permissionHelper(UserRole.STANDARD_REGISTRY), async (req: AuthenticatedRequest, res: Response, next: NextFunction) => {
- try {
- const guardians = new Guardians();
+ @Delete('/:uuid')
+ @HttpCode(HttpStatus.OK)
+ async deleteModule(@Req() req, @Response() res): Promise {
+ await checkPermission(UserRole.STANDARD_REGISTRY)(req.user);
+ try {
+ const guardian = new Guardians();
+ if (!req.params.uuid) {
+ throw new Error('Invalid uuid')
+ }
+ const result = await guardian.deleteModule(req.params.uuid, req.user.did);
+ return res.status(200).json(result);
+ } catch (error) {
+ new Logger().error(error, ['API_GATEWAY']);
+ throw new HttpException(error.message, HttpStatus.INTERNAL_SERVER_ERROR);
+ }
+ }
- let pageIndex: any;
- let pageSize: any;
- if (req.query && req.query.pageIndex && req.query.pageSize) {
- pageIndex = req.query.pageIndex;
- pageSize = req.query.pageSize;
+ @Get('/menu')
+ @HttpCode(HttpStatus.OK)
+ async getMenu(@Req() req, @Response() res): Promise {
+ await checkPermission(UserRole.STANDARD_REGISTRY)(req.user);
+ try {
+ const guardians = new Guardians();
+ const items = await guardians.getMenuModule(req.user.did);
+ return res.json(items);
+ } catch (error) {
+ new Logger().error(error, ['API_GATEWAY']);
+ throw new HttpException(error.message, HttpStatus.INTERNAL_SERVER_ERROR);
}
- const { items, count } = await guardians.getModule({
- owner: req.user.did,
- pageIndex,
- pageSize
- });
- res.setHeader('X-Total-Count', count).json(items);
- } catch (error) {
- new Logger().error(error, ['API_GATEWAY']);
- return next(error);
}
-});
-moduleAPI.delete('/:uuid', permissionHelper(UserRole.STANDARD_REGISTRY), async (req: AuthenticatedRequest, res: Response, next: NextFunction) => {
- try {
- const guardian = new Guardians();
- if (!req.params.uuid) {
- return next(createError(422, 'Invalid uuid'));
+ @Get('/:uuid')
+ @HttpCode(HttpStatus.OK)
+ async getModule(@Req() req, @Response() res): Promise {
+ await checkPermission(UserRole.STANDARD_REGISTRY)(req.user);
+ try {
+ const guardian = new Guardians();
+ if (!req.params.uuid) {
+ throw new HttpException('Invalid uuid', HttpStatus.UNPROCESSABLE_ENTITY)
+ }
+ const item = await guardian.getModuleById(req.params.uuid, req.user.did);
+ return res.json(item);
+ } catch (error) {
+ new Logger().error(error, ['API_GATEWAY']);
+ throw error;
}
- const result = await guardian.deleteModule(req.params.uuid, req.user.did);
- res.status(201).json(result);
- } catch (error) {
- new Logger().error(error, ['API_GATEWAY']);
- return next(error);
}
-});
-
-moduleAPI.get('/menu', permissionHelper(UserRole.STANDARD_REGISTRY), async (req: AuthenticatedRequest, res: Response, next: NextFunction) => {
- try {
- const guardians = new Guardians();
- const items = await guardians.getMenuModule(req.user.did);
- res.json(items);
- } catch (error) {
- new Logger().error(error, ['API_GATEWAY']);
- return next(error);
+
+ @Put('/:uuid')
+ @HttpCode(HttpStatus.CREATED)
+ async putModule(@Req() req, @Response() res): Promise {
+ await checkPermission(UserRole.STANDARD_REGISTRY)(req.user);
+ try {
+ const guardian = new Guardians();
+ if (!req.params.uuid) {
+ throw new HttpException('Invalid uuid', HttpStatus.UNPROCESSABLE_ENTITY);
+ }
+ const module = req.body;
+ if (!module.config || module.config.blockType !== 'module') {
+ throw new HttpException('Invalid module config', HttpStatus.UNPROCESSABLE_ENTITY)
+ }
+ const result = await guardian.updateModule(req.params.uuid, module, req.user.did);
+ return res.status(201).json(result);
+ } catch (error) {
+ new Logger().error(error, ['API_GATEWAY']);
+ throw error;
+ }
}
-});
-moduleAPI.get('/:uuid', permissionHelper(UserRole.STANDARD_REGISTRY), async (req: AuthenticatedRequest, res: Response, next: NextFunction) => {
- try {
+ @Get('/:uuid/export/file')
+ @HttpCode(HttpStatus.OK)
+ async moduleExportFile(@Req() req, @Response() res): Promise {
+ await checkPermission(UserRole.STANDARD_REGISTRY)(req.user);
const guardian = new Guardians();
- if (!req.params.uuid) {
- return next(createError(422, 'Invalid uuid'));
+ try {
+ const file: any = await guardian.exportModuleFile(req.params.uuid, req.user.did);
+ res.setHeader('Content-disposition', `attachment; filename=module_${Date.now()}`);
+ res.setHeader('Content-type', 'application/zip');
+ return res.send(file);
+ } catch (error) {
+ new Logger().error(error, ['API_GATEWAY']);
+ throw error
}
- const item = await guardian.getModuleById(req.params.uuid, req.user.did);
- res.json(item);
- } catch (error) {
- new Logger().error(error, ['API_GATEWAY']);
- return next(error);
}
-});
-moduleAPI.put('/:uuid', permissionHelper(UserRole.STANDARD_REGISTRY), async (req: AuthenticatedRequest, res: Response, next: NextFunction) => {
- try {
+ @Get('/:uuid/export/message')
+ @HttpCode(HttpStatus.OK)
+ async moduleExportMessage(@Req() req, @Response() res): Promise {
+ await checkPermission(UserRole.STANDARD_REGISTRY)(req.user);
const guardian = new Guardians();
- if (!req.params.uuid) {
- return next(createError(422, 'Invalid uuid'));
+ try {
+ return res.send(await guardian.exportModuleMessage(req.params.uuid, req.user.did));
+ } catch (error) {
+ new Logger().error(error, ['API_GATEWAY']);
+ throw error;
}
- const module = req.body;
- if (!module.config || module.config.blockType !== 'module') {
- return next(createError(422, 'Invalid module config'));
- }
- const result = await guardian.updateModule(req.params.uuid, module, req.user.did);
- res.status(201).json(result);
- } catch (error) {
- new Logger().error(error, ['API_GATEWAY']);
- return next(error);
- }
-});
-
-moduleAPI.get('/:uuid/export/file', permissionHelper(UserRole.STANDARD_REGISTRY), async (req: AuthenticatedRequest, res: Response, next: NextFunction) => {
- const guardian = new Guardians();
- try {
- const file: any = await guardian.exportModuleFile(req.params.uuid, req.user.did);
- res.setHeader('Content-disposition', `attachment; filename=module_${Date.now()}`);
- res.setHeader('Content-type', 'application/zip');
- res.send(file);
- } catch (error) {
- new Logger().error(error, ['API_GATEWAY']);
- return next(error);
}
-});
-
-moduleAPI.get('/:uuid/export/message', permissionHelper(UserRole.STANDARD_REGISTRY), async (req: AuthenticatedRequest, res: Response, next: NextFunction) => {
- const guardian = new Guardians();
- try {
- res.send(await guardian.exportModuleMessage(req.params.uuid, req.user.did));
- } catch (error) {
- new Logger().error(error, ['API_GATEWAY']);
- return next(error);
- }
-});
-
-moduleAPI.post('/import/message', permissionHelper(UserRole.STANDARD_REGISTRY), async (req: AuthenticatedRequest, res: Response, next: NextFunction) => {
- const guardian = new Guardians();
- try {
- const module = await guardian.importModuleMessage(req.body.messageId, req.user.did);
- res.status(201).send(module);
- } catch (error) {
- new Logger().error(error, ['API_GATEWAY']);
- return next(error);
+
+ @Post('/import/message')
+ @HttpCode(HttpStatus.CREATED)
+ async moduleImportMessage(@Req() req, @Response() res): Promise {
+ await checkPermission(UserRole.STANDARD_REGISTRY)(req.user);
+ const guardian = new Guardians();
+ try {
+ const module = await guardian.importModuleMessage(req.body.messageId, req.user.did);
+ return res.status(201).send(module);
+ } catch (error) {
+ new Logger().error(error, ['API_GATEWAY']);
+ throw error;
+ }
}
-});
-
-moduleAPI.post('/import/file', permissionHelper(UserRole.STANDARD_REGISTRY), async (req: AuthenticatedRequest, res: Response, next: NextFunction) => {
- const guardian = new Guardians();
- try {
- const module = await guardian.importModuleFile(req.body, req.user.did);
- res.status(201).send(module);
- } catch (error) {
- new Logger().error(error, ['API_GATEWAY']);
- return next(error);
+
+ @Post('/import/file')
+ @HttpCode(HttpStatus.CREATED)
+ async moduleImportFile(@Req() req, @Response() res): Promise {
+ await checkPermission(UserRole.STANDARD_REGISTRY)(req.user);
+ const guardian = new Guardians();
+ try {
+ const module = await guardian.importModuleFile(req.body, req.user.did);
+ return res.status(201).send(module);
+ } catch (error) {
+ new Logger().error(error, ['API_GATEWAY']);
+ throw error
+ }
}
-});
-
-moduleAPI.post('/import/message/preview', permissionHelper(UserRole.STANDARD_REGISTRY), async (req: AuthenticatedRequest, res: Response, next: NextFunction) => {
- const guardian = new Guardians();
- try {
- const module = await guardian.previewModuleMessage(req.body.messageId, req.user.did);
- res.send(module);
- } catch (error) {
- new Logger().error(error, ['API_GATEWAY']);
- return next(error);
+
+ @Post('/import/message/preview')
+ @HttpCode(HttpStatus.OK)
+ async moduleImportMessagePreview(@Req() req, @Response() res): Promise {
+ await checkPermission(UserRole.STANDARD_REGISTRY)(req.user);
+ const guardian = new Guardians();
+ try {
+ const module = await guardian.previewModuleMessage(req.body.messageId, req.user.did);
+ return res.send(module);
+ } catch (error) {
+ new Logger().error(error, ['API_GATEWAY']);
+ throw error;
+ }
}
-});
-
-moduleAPI.post('/import/file/preview', permissionHelper(UserRole.STANDARD_REGISTRY), async (req: AuthenticatedRequest, res: Response, next: NextFunction) => {
- const guardian = new Guardians();
- try {
- const module = await guardian.previewModuleFile(req.body, req.user.did);
- res.send(module);
- } catch (error) {
- new Logger().error(error, ['API_GATEWAY']);
- return next(error);
+
+ @Post('/import/file/preview')
+ @HttpCode(HttpStatus.OK)
+ async moduleImportFilePreview(@Req() req, @Response() res): Promise {
+ await checkPermission(UserRole.STANDARD_REGISTRY)(req.user);
+ const guardian = new Guardians();
+ try {
+ const module = await guardian.previewModuleFile(req.body, req.user.did);
+ return res.send(module);
+ } catch (error) {
+ new Logger().error(error, ['API_GATEWAY']);
+ throw error
+ }
}
-});
-
-moduleAPI.put('/:uuid/publish', permissionHelper(UserRole.STANDARD_REGISTRY), async (req: AuthenticatedRequest, res: Response, next: NextFunction) => {
- const guardian = new Guardians();
- try {
- const module = await guardian.publishModule(req.params.uuid, req.user.did, req.body);
- res.json(module);
- } catch (error) {
- new Logger().error(error, ['API_GATEWAY']);
- return next(error);
+
+ @Put('/:uuid/publish')
+ @HttpCode(HttpStatus.OK)
+ async publishModule(@Req() req, @Response() res): Promise {
+ await checkPermission(UserRole.STANDARD_REGISTRY)(req.user);
+ const guardian = new Guardians();
+ try {
+ const module = await guardian.publishModule(req.params.uuid, req.user.did, req.body);
+ return res.json(module);
+ } catch (error) {
+ new Logger().error(error, ['API_GATEWAY']);
+ throw error;
+ }
}
-});
-
-moduleAPI.post('/validate', async (req: AuthenticatedRequest, res: Response, next: NextFunction) => {
- const guardian = new Guardians();
- try {
- res.send(await guardian.validateModule(req.user.did, req.body));
- } catch (error) {
- new Logger().error(error, ['API_GATEWAY']);
- return next(error);
+
+ @Post('/validate')
+ @HttpCode(HttpStatus.OK)
+ async validateModule(@Req() req, @Response() res): Promise {
+ const guardian = new Guardians();
+ try {
+ return res.send(await guardian.validateModule(req.user.did, req.body));
+ } catch (error) {
+ new Logger().error(error, ['API_GATEWAY']);
+ throw error
+ }
}
-});
+
+}
diff --git a/api-gateway/src/api/service/policy.ts b/api-gateway/src/api/service/policy.ts
index c80020a526..f638a7235e 100644
--- a/api-gateway/src/api/service/policy.ts
+++ b/api-gateway/src/api/service/policy.ts
@@ -1,626 +1,715 @@
-import { Response, Router, NextFunction } from 'express';
import { PolicyType, UserRole } from '@guardian/interfaces';
import { PolicyEngine } from '@helpers/policy-engine';
import { Users } from '@helpers/users';
import { AuthenticatedRequest, Logger, RunFunctionAsync } from '@guardian/common';
-import { permissionHelper } from '@auth/authorization-helper';
import { TaskManager } from '@helpers/task-manager';
import { ServiceError } from '@helpers/service-requests-base';
-import createError from 'http-errors';
-
-export const policyAPI = Router();
-
-policyAPI.get('/', async (req: AuthenticatedRequest, res: Response, next: NextFunction) => {
- const users = new Users();
- const engineService = new PolicyEngine();
- try {
- const user = await users.getUser(req.user.username);
- if (!user.did && user.role !== UserRole.AUDITOR) {
- return res.setHeader('X-Total-Count', 0).json([]);
- }
- let pageIndex: any;
- let pageSize: any;
- if (req.query && req.query.pageIndex && req.query.pageSize) {
- pageIndex = req.query.pageIndex;
- pageSize = req.query.pageSize;
- }
- let result: any;
- if (user.role === UserRole.STANDARD_REGISTRY) {
- result = await engineService.getPolicies({
- filters: {
- owner: user.did,
- },
- userDid: user.did,
- pageIndex,
- pageSize
- });
- } else if (user.role === UserRole.AUDITOR) {
- const filters: any = {
- status: PolicyType.PUBLISH,
+import { Controller, Delete, Get, HttpCode, HttpException, HttpStatus, Post, Put, RawBodyRequest, Req, Response } from '@nestjs/common';
+import { checkPermission } from '@auth/authorization-helper';
+
+@Controller('policies')
+export class PolicyApi {
+ @Get('/')
+ @HttpCode(HttpStatus.OK)
+ async getPolicies(@Req() req, @Response() res): Promise {
+ const users = new Users();
+ const engineService = new PolicyEngine();
+ try {
+ const user = await users.getUser(req.user.username);
+ if (!user.did && user.role !== UserRole.AUDITOR) {
+ return res.setHeader('X-Total-Count', 0).json([]);
}
- result = await engineService.getPolicies({
- filters,
- userDid: user.did,
- pageIndex,
- pageSize
- });
- } else {
- const filters: any = {
- status: PolicyType.PUBLISH,
+ let pageIndex: any;
+ let pageSize: any;
+ if (req.query && req.query.pageIndex && req.query.pageSize) {
+ pageIndex = req.query.pageIndex;
+ pageSize = req.query.pageSize;
}
- if (user.parent) {
- filters.owner = user.parent;
+ let result: any;
+ if (user.role === UserRole.STANDARD_REGISTRY) {
+ result = await engineService.getPolicies({
+ filters: {
+ owner: user.did,
+ },
+ userDid: user.did,
+ pageIndex,
+ pageSize
+ });
+ } else if (user.role === UserRole.AUDITOR) {
+ const filters: any = {
+ status: PolicyType.PUBLISH,
+ }
+ result = await engineService.getPolicies({
+ filters,
+ userDid: user.did,
+ pageIndex,
+ pageSize
+ });
+ } else {
+ const filters: any = {
+ status: PolicyType.PUBLISH,
+ }
+ if (user.parent) {
+ filters.owner = user.parent;
+ }
+ result = await engineService.getPolicies({
+ filters,
+ userDid: user.did,
+ pageIndex,
+ pageSize
+ });
}
- result = await engineService.getPolicies({
- filters,
+ const { policies, count } = result;
+ return res.setHeader('X-Total-Count', count).json(policies);
+ } catch (error) {
+ new Logger().error(error, ['API_GATEWAY']);
+ throw error
+ }
+ }
+
+ @Post('/')
+ @HttpCode(HttpStatus.CREATED)
+ async createPolicy(@Req() req, @Response() res): Promise {
+ await checkPermission(UserRole.STANDARD_REGISTRY)(req.user);
+ const engineService = new PolicyEngine();
+ try {
+ const policies = await engineService.createPolicy(req.body, req.user)
+ return res.status(201).json(policies);
+ } catch (error) {
+ new Logger().error(error, ['API_GATEWAY']);
+ throw error;
+ }
+ }
+
+ @Post('/push')
+ @HttpCode(HttpStatus.ACCEPTED)
+ async createPolicyAsync(@Req() req, @Response() res): Promise {
+ await checkPermission(UserRole.STANDARD_REGISTRY)(req.user);
+ const taskManager = new TaskManager();
+ const { taskId, expectation } = taskManager.start('Create policy');
+ const model = req.body;
+ const user = req.user;
+ RunFunctionAsync(async () => {
+ const engineService = new PolicyEngine();
+ await engineService.createPolicyAsync(model, user, taskId);
+ }, async (error) => {
+ new Logger().error(error, ['API_GATEWAY']);
+ taskManager.addError(taskId, { code: 500, message: error.message });
+ });
+ return res.status(202).send({ taskId, expectation });
+ }
+
+ @Post('/push/:policyId')
+ @HttpCode(HttpStatus.ACCEPTED)
+ async updatePolicyAsync(@Req() req, @Response() res): Promise {
+ await checkPermission(UserRole.STANDARD_REGISTRY)(req.user);
+ const taskManager = new TaskManager();
+ const { taskId, expectation } = taskManager.start('Clone policy');
+ const policyId = req.params.policyId;
+ const model = req.body;
+ const user = req.user;
+
+ RunFunctionAsync(async () => {
+ const engineService = new PolicyEngine();
+ await engineService.clonePolicyAsync(policyId, model, user, taskId);
+ }, async (error) => {
+ new Logger().error(error, ['API_GATEWAY']);
+ taskManager.addError(taskId, { code: 500, message: error.message });
+ });
+ return res.status(202).send({ taskId, expectation });
+ }
+
+ @Delete('/push/:policyId')
+ @HttpCode(HttpStatus.ACCEPTED)
+ async deletePOlicyAsync(@Req() req, @Response() res): Promise {
+ await checkPermission(UserRole.STANDARD_REGISTRY)(req.user);
+ const taskManager = new TaskManager();
+ const { taskId, expectation } = taskManager.start('Delete policy');
+ const policyId = req.params.policyId;
+ const user = req.user;
+
+ RunFunctionAsync(async () => {
+ const engineService = new PolicyEngine();
+ await engineService.deletePolicyAsync(policyId, user, taskId);
+ }, async (error) => {
+ new Logger().error(error, ['API_GATEWAY']);
+ taskManager.addError(taskId, { code: 500, message: error.message });
+ });
+ return res.status(202).send({ taskId, expectation });
+ }
+
+ @Get('/:policyId')
+ @HttpCode(HttpStatus.OK)
+ async getPolicy(@Req() req, @Response() res): Promise {
+ const users = new Users();
+ const engineService = new PolicyEngine();
+ try {
+ const user = await users.getUser(req.user.username);
+ const model = (await engineService.getPolicy({
+ filters: req.params.policyId,
userDid: user.did,
- pageIndex,
- pageSize
- });
- }
- const { policies, count } = result;
- return res.setHeader('X-Total-Count', count).json(policies);
- } catch (error) {
- new Logger().error(error, ['API_GATEWAY']);
- return next(error);
- }
-});
-
-policyAPI.post('/', permissionHelper(UserRole.STANDARD_REGISTRY),
- async (req: AuthenticatedRequest, res: Response, next: NextFunction) => {
- const engineService = new PolicyEngine();
- try {
- const policies = await engineService.createPolicy(req.body, req.user)
- return res.status(201).json(policies);
- } catch (error) {
- new Logger().error(error, ['API_GATEWAY']);
- return next(error);
- }
-});
-
-policyAPI.post('/push', permissionHelper(UserRole.STANDARD_REGISTRY), async (req: AuthenticatedRequest, res: Response) => {
- const taskManager = new TaskManager();
- const { taskId, expectation } = taskManager.start('Create policy');
- const model = req.body;
- const user = req.user;
- RunFunctionAsync(async () => {
- const engineService = new PolicyEngine();
- await engineService.createPolicyAsync(model, user, taskId);
- }, async (error) => {
- new Logger().error(error, ['API_GATEWAY']);
- taskManager.addError(taskId, { code: 500, message: error.message });
- });
- res.status(202).send({ taskId, expectation });
-});
-
-policyAPI.post('/push/:policyId', permissionHelper(UserRole.STANDARD_REGISTRY), async (req: AuthenticatedRequest, res: Response, next: NextFunction) => {
- const taskManager = new TaskManager();
- const { taskId, expectation } = taskManager.start('Clone policy');
- const policyId = req.params.policyId;
- const model = req.body;
- const user = req.user;
-
- RunFunctionAsync(async () => {
- const engineService = new PolicyEngine();
- await engineService.clonePolicyAsync(policyId, model, user, taskId);
- }, async (error) => {
- new Logger().error(error, ['API_GATEWAY']);
- taskManager.addError(taskId, { code: 500, message: error.message });
- });
- res.status(202).send({ taskId, expectation });
-});
-
-policyAPI.delete('/push/:policyId', permissionHelper(UserRole.STANDARD_REGISTRY), async (req: AuthenticatedRequest, res: Response, next: NextFunction) => {
- const taskManager = new TaskManager();
- const { taskId, expectation } = taskManager.start('Delete policy');
- const policyId = req.params.policyId;
- const user = req.user;
-
- RunFunctionAsync(async () => {
- const engineService = new PolicyEngine();
- await engineService.deletePolicyAsync(policyId, user, taskId);
- }, async (error) => {
- new Logger().error(error, ['API_GATEWAY']);
- taskManager.addError(taskId, { code: 500, message: error.message });
- });
- res.status(202).send({ taskId, expectation });
-});
-
-policyAPI.get('/:policyId',
- async (req: AuthenticatedRequest, res: Response, next: NextFunction) => {
- const users = new Users();
- const engineService = new PolicyEngine();
- try {
- const user = await users.getUser(req.user.username);
- const model = (await engineService.getPolicy({
- filters: req.params.policyId,
- userDid: user.did,
- })) as any;
- return res.send(model);
- } catch (error) {
- new Logger().error(error, ['API_GATEWAY']);
- return next(error);
- }
-});
-
-policyAPI.put('/:policyId', async (req: AuthenticatedRequest, res: Response, next: NextFunction) => {
- const engineService = new PolicyEngine();
- try {
- const model = await engineService.getPolicy({ filters: req.params.policyId }) as any;
- const policy = req.body;
-
- model.config = policy.config;
- model.name = policy.name;
- model.version = policy.version;
- model.description = policy.description;
- model.topicDescription = policy.topicDescription;
- model.policyRoles = policy.policyRoles;
- model.policyTopics = policy.policyTopics;
- model.policyTokens = policy.policyTokens;
- model.policyGroups = policy.policyGroups;
- const result = await engineService.savePolicy(model, req.user, req.params.policyId);
- res.json(result);
- } catch (error) {
- new Logger().error(error, ['API_GATEWAY']);
- return next(error);
- }
-});
-//
-policyAPI.put('/:policyId/publish',
- permissionHelper(UserRole.STANDARD_REGISTRY),
- async (req: AuthenticatedRequest, res: Response, next: NextFunction) => {
- const engineService = new PolicyEngine();
- try {
- return res.json(await engineService.publishPolicy(req.body, req.user, req.params.policyId));
- } catch (error) {
- new Logger().error(error, ['API_GATEWAY']);
- return next(error);
- }
-});
-
-policyAPI.put('/push/:policyId/publish', permissionHelper(UserRole.STANDARD_REGISTRY), async (req: AuthenticatedRequest, res: Response, next: NextFunction) => {
- const taskManager = new TaskManager();
- const { taskId, expectation } = taskManager.start('Publish policy');
-
- const model = req.body;
- const user = req.user;
- const policyId = req.params.policyId;
- RunFunctionAsync(async () => {
- const engineService = new PolicyEngine();
- await engineService.publishPolicyAsync(model, user, policyId, taskId);
- }, async (error) => {
- new Logger().error(error, ['API_GATEWAY']);
- taskManager.addError(taskId, { code: 500, message: error.message || error });
- });
-
- res.status(202).send({ taskId, expectation });
-});
-
-policyAPI.put('/:policyId/dry-run',
- permissionHelper(UserRole.STANDARD_REGISTRY),
- async (req: AuthenticatedRequest, res: Response, next: NextFunction) => {
- const engineService = new PolicyEngine();
- try {
- return res.json(await engineService.dryRunPolicy(req.user, req.params.policyId));
- } catch (error) {
- new Logger().error(error, ['API_GATEWAY']);
- return next(error);
- }
-});
-
-policyAPI.put('/:policyId/draft', permissionHelper(UserRole.STANDARD_REGISTRY),
- async (req: AuthenticatedRequest, res: Response, next: NextFunction) => {
- const engineService = new PolicyEngine();
- try {
- res.json(await engineService.draft(req.user, req.params.policyId));
- } catch (error) {
- new Logger().error(error, ['API_GATEWAY']);
- return next(error);
- }
-});
-
-policyAPI.post('/validate', async (req: AuthenticatedRequest, res: Response, next: NextFunction) => {
- const engineService = new PolicyEngine();
- try {
- return res.send(await engineService.validatePolicy(req.body, req.user));
- } catch (error) {
- new Logger().error(error, ['API_GATEWAY']);
- return next(error);
- }
-});
-//
-
-policyAPI.get('/:policyId/groups',
- async (req: AuthenticatedRequest, res: Response, next: NextFunction) => {
- const engineService = new PolicyEngine();
- try {
- return res.send(await engineService.getGroups(req.user, req.params.policyId));
- } catch (error) {
- new Logger().error(error, ['API_GATEWAY']);
- return next(error);
- }
-});
-
-policyAPI.post('/:policyId/groups',
- async (req: AuthenticatedRequest, res: Response, next: NextFunction) => {
- const engineService = new PolicyEngine();
- try {
- return res.send(await engineService.selectGroup(req.user, req.params.policyId, req.body.uuid));
- } catch (error) {
- new Logger().error(error, ['API_GATEWAY']);
- return next(error);
- }
-});
-
-policyAPI.get('/:policyId/blocks', async (req: AuthenticatedRequest, res: Response, next: NextFunction) => {
- const engineService = new PolicyEngine();
- try {
- return res.send(await engineService.getPolicyBlocks(req.user, req.params.policyId));
- } catch (error) {
- new Logger().error(error, ['API_GATEWAY']);
- return next(error);
- }
-});
-
-policyAPI.get('/:policyId/blocks/:uuid',
- async (req: AuthenticatedRequest, res: Response, next: NextFunction) => {
- const engineService = new PolicyEngine();
- try {
- return res.send(await engineService.getBlockData(req.user, req.params.policyId, req.params.uuid));
- } catch (error) {
- new Logger().error(error, ['API_GATEWAY']);
- return next(error);
- }
-});
-
-policyAPI.post('/:policyId/blocks/:uuid',
- async (req: AuthenticatedRequest, res: Response, next: NextFunction) => {
- const engineService = new PolicyEngine();
- try {
- return res.send(
- await engineService.setBlockData(req.user, req.params.policyId, req.params.uuid, req.body)
- );
- } catch (error) {
- new Logger().error(error, ['API_GATEWAY']);
- return next(error);
- }
-});
-
-policyAPI.post('/:policyId/tag/:tagName/blocks',
- async (req: AuthenticatedRequest, res: Response, next: NextFunction) => {
- const engineService = new PolicyEngine();
- try {
- return res.send(await engineService.setBlockDataByTag(req.user, req.params.policyId, req.params.tagName, req.body));
- } catch (error) {
- new Logger().error(error, ['API_GATEWAY']);
- return next(error);
- }
-});
-
-policyAPI.get('/:policyId/tag/:tagName', async (req: AuthenticatedRequest, res: Response, next: NextFunction) => {
- const engineService = new PolicyEngine();
- try {
- res.send(await engineService.getBlockByTagName(req.user, req.params.policyId, req.params.tagName));
- } catch (error) {
- new Logger().error(error, ['API_GATEWAY']);
- return next(error);
- }
-});
-
-policyAPI.get('/:policyId/tag/:tagName/blocks', async (req: AuthenticatedRequest, res: Response, next: NextFunction) => {
- const engineService = new PolicyEngine();
- try {
- res.send(await engineService.getBlockDataByTag(req.user, req.params.policyId, req.params.tagName));
- } catch (error) {
- new Logger().error(error, ['API_GATEWAY']);
- return next(error);
- }
-});
-
-policyAPI.get('/:policyId/blocks/:uuid/parents', async (req: AuthenticatedRequest, res: Response, next: NextFunction) => {
- const engineService = new PolicyEngine();
- try {
- res.send(await engineService.getBlockParents(req.user, req.params.policyId, req.params.uuid));
- } catch (error) {
- new Logger().error(error, ['API_GATEWAY']);
- return next(error);
- }
-});
-
-policyAPI.get('/:policyId/export/file', permissionHelper(UserRole.STANDARD_REGISTRY), async (req: AuthenticatedRequest, res: Response, next: NextFunction) => {
- const engineService = new PolicyEngine();
- try {
- const policyFile: any = await engineService.exportFile(req.user, req.params.policyId);
- const policy: any = await engineService.getPolicy({ filters: req.params.policyId });
- res.setHeader('Content-disposition', `attachment; filename=${policy.name}`);
- res.setHeader('Content-type', 'application/zip');
- res.send(policyFile);
- } catch (error) {
- new Logger().error(error, ['API_GATEWAY']);
- return next(error);
- }
-});
-
-policyAPI.get('/:policyId/export/message', permissionHelper(UserRole.STANDARD_REGISTRY), async (req: AuthenticatedRequest, res: Response, next: NextFunction) => {
- const engineService = new PolicyEngine();
- try {
- res.send(await engineService.exportMessage(req.user, req.params.policyId));
- } catch (error) {
- new Logger().error(error, ['API_GATEWAY']);
- return next(error);
- }
-});
-
-policyAPI.post('/import/message', permissionHelper(UserRole.STANDARD_REGISTRY), async (req: AuthenticatedRequest, res: Response, next: NextFunction) => {
- const engineService = new PolicyEngine();
- const versionOfTopicId = req.query ? req.query.versionOfTopicId : null;
- try {
- const policies = await engineService.importMessage(req.user, req.body.messageId, versionOfTopicId);
- res.status(201).send(policies);
- } catch (error) {
- new Logger().error(error, ['API_GATEWAY']);
- return next(error);
- }
-});
-
-policyAPI.post('/push/import/message', permissionHelper(UserRole.STANDARD_REGISTRY), async (req: AuthenticatedRequest, res: Response) => {
- const taskManager = new TaskManager();
- const { taskId, expectation } = taskManager.start('Import policy message');
-
- const user = req.user;
- const messageId = req.body.messageId;
- const versionOfTopicId = req.query ? req.query.versionOfTopicId : null;
- RunFunctionAsync(async () => {
- const engineService = new PolicyEngine();
- await engineService.importMessageAsync(user, messageId, versionOfTopicId, taskId);
- }, async (error) => {
- new Logger().error(error, ['API_GATEWAY']);
- taskManager.addError(taskId, { code: 500, message: 'Unknown error: ' + error.message });
- });
- res.status(202).send({ taskId, expectation });
-});
-
-policyAPI.post('/import/file', permissionHelper(UserRole.STANDARD_REGISTRY), async (req: AuthenticatedRequest, res: Response, next: NextFunction) => {
- const engineService = new PolicyEngine();
- const versionOfTopicId = req.query ? req.query.versionOfTopicId : null;
- try {
- const policies = await engineService.importFile(req.user, req.body, versionOfTopicId);
- res.status(201).send(policies);
- } catch (error) {
- new Logger().error(error, ['API_GATEWAY']);
- return next(error);
- }
-});
-
-policyAPI.post('/push/import/file', permissionHelper(UserRole.STANDARD_REGISTRY), async (req: AuthenticatedRequest, res: Response) => {
- const taskManager = new TaskManager();
- const { taskId, expectation } = taskManager.start('Import policy file');
-
- const user = req.user;
- const zip = req.body;
- const versionOfTopicId = req.query ? req.query.versionOfTopicId : null;
- RunFunctionAsync(async () => {
- const engineService = new PolicyEngine();
- await engineService.importFileAsync(user, zip, versionOfTopicId, taskId);
- }, async (error) => {
- new Logger().error(error, ['API_GATEWAY']);
- taskManager.addError(taskId, { code: 500, message: 'Unknown error: ' + error.message });
- });
- res.status(202).send({ taskId, expectation });
-});
-
-policyAPI.post('/import/message/preview', permissionHelper(UserRole.STANDARD_REGISTRY), async (req: AuthenticatedRequest, res: Response, next: NextFunction) => {
- const engineService = new PolicyEngine();
- try {
- res.send(await engineService.importMessagePreview(req.user, req.body.messageId));
- } catch (error) {
- new Logger().error(error, ['API_GATEWAY']);
- return next(error);
- }
-});
-
-policyAPI.post('/push/import/message/preview', permissionHelper(UserRole.STANDARD_REGISTRY), async (req: AuthenticatedRequest, res: Response) => {
- const taskManager = new TaskManager();
- const { taskId, expectation } = taskManager.start('Preview policy message');
-
- const user = req.user;
- const messageId = req.body.messageId;
- RunFunctionAsync(async () => {
- const engineService = new PolicyEngine();
- await engineService.importMessagePreviewAsync(user, messageId, taskId);
- }, async (error) => {
- new Logger().error(error, ['API_GATEWAY']);
- taskManager.addError(taskId, { code: 500, message: 'Unknown error: ' + error.message });
- });
-
- res.status(202).send({ taskId, expectation });
-});
-
-policyAPI.post('/import/file/preview', permissionHelper(UserRole.STANDARD_REGISTRY), async (req: AuthenticatedRequest, res: Response, next: NextFunction) => {
- const engineService = new PolicyEngine();
- try {
- res.send(await engineService.importFilePreview(req.user, req.body));
- } catch (error) {
- new Logger().error(error, ['API_GATEWAY']);
- return next(error);
- }
-});
-
-policyAPI.get('/blocks/about', async (req: AuthenticatedRequest, res: Response, next: NextFunction) => {
- const engineService = new PolicyEngine();
- try {
- res.send(await engineService.blockAbout());
- } catch (error) {
- new Logger().error(error, ['API_GATEWAY']);
- return next(error);
- }
-});
-
-policyAPI.get('/:policyId/dry-run/users',
- permissionHelper(UserRole.STANDARD_REGISTRY), async (req: AuthenticatedRequest, res: Response, next: NextFunction) => {
- const engineService = new PolicyEngine();
- try {
- const policy = await engineService.getPolicy({ filters: req.params.policyId }) as any;
- if (!policy) {
- return next(createError(404, 'Policy does not exist.'));
- }
- if (policy.owner !== req.user.did) {
- return next(createError(403, 'Invalid owner.'));
- }
-
- return res.send(await engineService.getVirtualUsers(req.params.policyId));
- } catch (error) {
- new Logger().error(error, ['API_GATEWAY']);
- return next(error);
- }
-});
-
-policyAPI.post('/:policyId/dry-run/user', permissionHelper(UserRole.STANDARD_REGISTRY), async (req: AuthenticatedRequest, res: Response, next: NextFunction) => {
- const engineService = new PolicyEngine();
- try {
- const policy = await engineService.getPolicy({ filters: req.params.policyId }) as any;
- if (!policy) {
- return next(createError(404, 'Policy does not exist.'));
- }
- if (policy.owner !== req.user.did) {
- return next(createError(403, 'Invalid owner.'));
- }
-
- res.send(await engineService.createVirtualUser(req.params.policyId, req.user.did));
- } catch (error) {
- new Logger().error(error, ['API_GATEWAY']);
- return next(error);
- }
-});
-
-policyAPI.post('/:policyId/dry-run/login', permissionHelper(UserRole.STANDARD_REGISTRY),
- async (req: AuthenticatedRequest, res: Response, next: NextFunction) => {
- const engineService = new PolicyEngine();
- try {
- const policy = await engineService.getPolicy({ filters: req.params.policyId }) as any;
- if (!policy) {
- return next(createError(404, 'Policy does not exist.'));
- }
- if (policy.owner !== req.user.did) {
- return next(createError(403, 'Invalid owner.'));
- }
-
- res.send(await engineService.loginVirtualUser(req.params.policyId, req.body.did));
- } catch (error) {
- new Logger().error(error, ['API_GATEWAY']);
- return next(error);
- }
-});
-
-policyAPI.post('/:policyId/dry-run/restart', permissionHelper(UserRole.STANDARD_REGISTRY), async (req: AuthenticatedRequest, res: Response, next: NextFunction) => {
- const engineService = new PolicyEngine();
- try {
- const policy = await engineService.getPolicy({ filters: req.params.policyId }) as any;
- if (!policy) {
- return next(createError(404, 'Policy does not exist.'));
- }
- if (policy.owner !== req.user.did) {
- return next(createError(403, 'Invalid owner.'));
- }
-
- res.json(await engineService.restartDryRun(req.body, req.user, req.params.policyId));
- } catch (error) {
- new Logger().error(error, ['API_GATEWAY']);
- return next(error);
- }
-});
-
-policyAPI.get('/:policyId/dry-run/transactions', permissionHelper(UserRole.STANDARD_REGISTRY), async (req: AuthenticatedRequest, res: Response, next: NextFunction) => {
- const engineService = new PolicyEngine();
- try {
- const policy = await engineService.getPolicy({ filters: req.params.policyId }) as any;
- if (!policy) {
- return next(createError(404, 'Policy does not exist.'));
- }
- if (policy.owner !== req.user.did) {
- return next(createError(403, 'Invalid owner.'));
- }
-
- let pageIndex: any;
- let pageSize: any;
- if (req.query && req.query.pageIndex && req.query.pageSize) {
- pageIndex = req.query.pageIndex;
- pageSize = req.query.pageSize;
- }
- const [data, count] = await engineService.getVirtualDocuments(req.params.policyId, 'transactions', pageIndex, pageSize)
- return res.setHeader('X-Total-Count', count).json(data);
- } catch (error) {
- new Logger().error(error, ['API_GATEWAY']);
- return next(error);
+ })) as any;
+ return res.send(model);
+ } catch (error) {
+ new Logger().error(error, ['API_GATEWAY']);
+ throw error;
+ }
+ }
+
+ @Put('/:policyId')
+ @HttpCode(HttpStatus.OK)
+ async updatePolicy(@Req() req, @Response() res): Promise {
+ const engineService = new PolicyEngine();
+ try {
+ const model = await engineService.getPolicy({ filters: req.params.policyId }) as any;
+ const policy = req.body;
+
+ model.config = policy.config;
+ model.name = policy.name;
+ model.version = policy.version;
+ model.description = policy.description;
+ model.topicDescription = policy.topicDescription;
+ model.policyRoles = policy.policyRoles;
+ model.policyTopics = policy.policyTopics;
+ model.policyTokens = policy.policyTokens;
+ model.policyGroups = policy.policyGroups;
+ const result = await engineService.savePolicy(model, req.user, req.params.policyId);
+ return res.json(result);
+ } catch (error) {
+ new Logger().error(error, ['API_GATEWAY']);
+ throw error;
+ }
+ }
+
+ @Put('/:policyId/publish')
+ @HttpCode(HttpStatus.OK)
+ async publishPolicy(@Req() req, @Response() res): Promise {
+ await checkPermission(UserRole.STANDARD_REGISTRY)(req.user);
+ const engineService = new PolicyEngine();
+ try {
+ return res.json(await engineService.publishPolicy(req.body, req.user, req.params.policyId));
+ } catch (error) {
+ new Logger().error(error, ['API_GATEWAY']);
+ throw error
+ }
+ }
+
+ @Put('/push/:policyId/publish')
+ @HttpCode(HttpStatus.ACCEPTED)
+ async publishPolicyAsync(@Req() req, @Response() res): Promise {
+ await checkPermission(UserRole.STANDARD_REGISTRY)(req.user);
+ const taskManager = new TaskManager();
+ const { taskId, expectation } = taskManager.start('Publish policy');
+
+ const model = req.body;
+ const user = req.user;
+ const policyId = req.params.policyId;
+ RunFunctionAsync(async () => {
+ const engineService = new PolicyEngine();
+ await engineService.publishPolicyAsync(model, user, policyId, taskId);
+ }, async (error) => {
+ new Logger().error(error, ['API_GATEWAY']);
+ taskManager.addError(taskId, { code: 500, message: error.message || error });
+ });
+
+ return res.status(202).send({ taskId, expectation });
+ }
+
+ @Put('/:policyId/dry-run')
+ @HttpCode(HttpStatus.OK)
+ async dryRunPolicy(@Req() req, @Response() res): Promise {
+ await checkPermission(UserRole.STANDARD_REGISTRY)(req.user);
+ const engineService = new PolicyEngine();
+ try {
+ return res.json(await engineService.dryRunPolicy(req.user, req.params.policyId));
+ } catch (error) {
+ new Logger().error(error, ['API_GATEWAY']);
+ throw error;
+ }
+ }
+
+ @Put('/:policyId/draft')
+ @HttpCode(HttpStatus.OK)
+ async draftPolicy(@Req() req, @Response() res): Promise {
+ await checkPermission(UserRole.STANDARD_REGISTRY)(req.user);
+ const engineService = new PolicyEngine();
+ try {
+ return res.json(await engineService.draft(req.user, req.params.policyId));
+ } catch (error) {
+ new Logger().error(error, ['API_GATEWAY']);
+ throw error;
+ }
+ }
+
+ @Post('/validate')
+ @HttpCode(HttpStatus.OK)
+ async validatePolicy(@Req() req, @Response() res): Promise {
+ const engineService = new PolicyEngine();
+ try {
+ return res.send(await engineService.validatePolicy(req.body, req.user));
+ } catch (error) {
+ new Logger().error(error, ['API_GATEWAY']);
+ throw error
+ }
+ }
+
+ @Get('/:policyId/groups')
+ @HttpCode(HttpStatus.OK)
+ async getPolicyGroups(@Req() req, @Response() res): Promise {
+ const engineService = new PolicyEngine();
+ try {
+ return res.send(await engineService.getGroups(req.user, req.params.policyId));
+ } catch (error) {
+ new Logger().error(error, ['API_GATEWAY']);
+ throw error;
+ }
+ }
+
+ @Post('/:policyId/groups')
+ @HttpCode(HttpStatus.OK)
+ async setPolicyGroups(@Req() req, @Response() res): Promise {
+ const engineService = new PolicyEngine();
+ try {
+ return res.send(await engineService.selectGroup(req.user, req.params.policyId, req.body.uuid));
+ } catch (error) {
+ new Logger().error(error, ['API_GATEWAY']);
+ throw error;
+ }
+ }
+
+ @Get('/:policyId/blocks')
+ @HttpCode(HttpStatus.OK)
+ async getPolicyBlocks(@Req() req, @Response() res): Promise {
+ const engineService = new PolicyEngine();
+ try {
+ return res.send(await engineService.getPolicyBlocks(req.user, req.params.policyId));
+ } catch (error) {
+ new Logger().error(error, ['API_GATEWAY']);
+ throw error
+ }
+ }
+
+ @Get('/:policyId/blocks/:uuid')
+ @HttpCode(HttpStatus.OK)
+ async getBlockData(@Req() req, @Response() res): Promise {
+ const engineService = new PolicyEngine();
+ try {
+ return res.send(await engineService.getBlockData(req.user, req.params.policyId, req.params.uuid));
+ } catch (error) {
+ new Logger().error(error, ['API_GATEWAY']);
+ throw error;
+ }
+ }
+
+ @Post('/:policyId/blocks/:uuid')
+ @HttpCode(HttpStatus.OK)
+ async setBlockData(@Req() req, @Response() res): Promise {
+ const engineService = new PolicyEngine();
+ try {
+ return res.send(
+ await engineService.setBlockData(req.user, req.params.policyId, req.params.uuid, req.body)
+ );
+ } catch (error) {
+ new Logger().error(error, ['API_GATEWAY']);
+ throw error;
+ }
+ }
+
+ @Post('/:policyId/tag/:tagName/blocks')
+ @HttpCode(HttpStatus.OK)
+ async setBlocksByTagName(@Req() req, @Response() res): Promise {
+ const engineService = new PolicyEngine();
+ try {
+ return res.send(await engineService.setBlockDataByTag(req.user, req.params.policyId, req.params.tagName, req.body));
+ } catch (error) {
+ new Logger().error(error, ['API_GATEWAY']);
+ throw error;
+ }
+ }
+
+ @Get('/:policyId/tag/:tagName')
+ @HttpCode(HttpStatus.OK)
+ async getBlockByTagName(@Req() req, @Response() res): Promise {
+ const engineService = new PolicyEngine();
+ try {
+ return res.send(await engineService.getBlockByTagName(req.user, req.params.policyId, req.params.tagName));
+ } catch (error) {
+ new Logger().error(error, ['API_GATEWAY']);
+ throw error;
+ }
+ }
+
+ @Get('/:policyId/tag/:tagName/blocks')
+ @HttpCode(HttpStatus.OK)
+ async getBlocksByTagName(@Req() req, @Response() res): Promise {
+ const engineService = new PolicyEngine();
+ try {
+ return res.send(await engineService.getBlockDataByTag(req.user, req.params.policyId, req.params.tagName));
+ } catch (error) {
+ new Logger().error(error, ['API_GATEWAY']);
+ throw error;
+ }
+ }
+
+ @Get('/:policyId/blocks/:uuid/parents')
+ @HttpCode(HttpStatus.OK)
+ async getBlockParents(@Req() req, @Response() res): Promise {
+ const engineService = new PolicyEngine();
+ try {
+ return res.send(await engineService.getBlockParents(req.user, req.params.policyId, req.params.uuid));
+ } catch (error) {
+ new Logger().error(error, ['API_GATEWAY']);
+ throw error;
+ }
+ }
+
+ @Get('/:policyId/export/file')
+ @HttpCode(HttpStatus.OK)
+ async getPolicyExportFile(@Req() req, @Response() res): Promise {
+ await checkPermission(UserRole.STANDARD_REGISTRY)(req.user);
+ const engineService = new PolicyEngine();
+ try {
+ const policyFile: any = await engineService.exportFile(req.user, req.params.policyId);
+ const policy: any = await engineService.getPolicy({ filters: req.params.policyId });
+ res.setHeader('Content-disposition', `attachment; filename=${policy.name}`);
+ res.setHeader('Content-type', 'application/zip');
+ return res.send(policyFile);
+ } catch (error) {
+ new Logger().error(error, ['API_GATEWAY']);
+ throw error
+ }
+ }
+
+ @Get('/:policyId/export/message')
+ @HttpCode(HttpStatus.OK)
+ async getPolicyExportMessage(@Req() req, @Response() res): Promise {
+ await checkPermission(UserRole.STANDARD_REGISTRY)(req.user);
+ const engineService = new PolicyEngine();
+ try {
+ return res.send(await engineService.exportMessage(req.user, req.params.policyId));
+ } catch (error) {
+ new Logger().error(error, ['API_GATEWAY']);
+ throw error
+ }
+ }
+
+ @Post('/import/message')
+ @HttpCode(HttpStatus.CREATED)
+ async importPolicyFromMessage(@Req() req, @Response() res): Promise {
+ await checkPermission(UserRole.STANDARD_REGISTRY)(req.user);
+ const engineService = new PolicyEngine();
+ const versionOfTopicId = req.query ? req.query.versionOfTopicId : null;
+ try {
+ const policies = await engineService.importMessage(req.user, req.body.messageId, versionOfTopicId);
+ return res.status(201).send(policies);
+ } catch (error) {
+ new Logger().error(error, ['API_GATEWAY']);
+ throw error
+ }
}
-});
-policyAPI.get('/:policyId/dry-run/artifacts', permissionHelper(UserRole.STANDARD_REGISTRY), async (req: AuthenticatedRequest, res: Response, next: NextFunction) => {
- const engineService = new PolicyEngine();
- try {
- const policy = await engineService.getPolicy({ filters: req.params.policyId }) as any;
- if (!policy) {
- return next(createError(404, 'Policy does not exist.'));
+ @Post('/push/import/message')
+ @HttpCode(HttpStatus.ACCEPTED)
+ async importPolicyFromMessageAsync(@Req() req, @Response() res): Promise {
+ await checkPermission(UserRole.STANDARD_REGISTRY)(req.user);
+ const taskManager = new TaskManager();
+ const { taskId, expectation } = taskManager.start('Import policy message');
+
+ const user = req.user;
+ const messageId = req.body.messageId;
+ const versionOfTopicId = req.query ? req.query.versionOfTopicId : null;
+ RunFunctionAsync(async () => {
+ const engineService = new PolicyEngine();
+ await engineService.importMessageAsync(user, messageId, versionOfTopicId, taskId);
+ }, async (error) => {
+ new Logger().error(error, ['API_GATEWAY']);
+ taskManager.addError(taskId, { code: 500, message: 'Unknown error: ' + error.message });
+ });
+ return res.status(202).send({ taskId, expectation });
+ }
+
+ @Post('/import/file')
+ @HttpCode(HttpStatus.CREATED)
+ async importPolicyFromFile(@Req() req, @Response() res): Promise {
+ await checkPermission(UserRole.STANDARD_REGISTRY)(req.user);
+ const engineService = new PolicyEngine();
+ const versionOfTopicId = req.query ? req.query.versionOfTopicId : null;
+ try {
+ const policies = await engineService.importFile(req.user, req.body, versionOfTopicId);
+ return res.status(201).send(policies);
+ } catch (error) {
+ new Logger().error(error, ['API_GATEWAY']);
+ throw error;
}
- if (policy.owner !== req.user.did) {
- return next(createError(403, 'Invalid owner.'));
+ }
+
+ @Post('/push/import/file')
+ @HttpCode(HttpStatus.ACCEPTED)
+ async importPolicyFromFileAsync(@Req() req, @Response() res): Promise {
+ await checkPermission(UserRole.STANDARD_REGISTRY)(req.user);
+ const taskManager = new TaskManager();
+ const { taskId, expectation } = taskManager.start('Import policy file');
+
+ const user = req.user;
+ const zip = req.body;
+ const versionOfTopicId = req.query ? req.query.versionOfTopicId : null;
+ RunFunctionAsync(async () => {
+ const engineService = new PolicyEngine();
+ await engineService.importFileAsync(user, zip, versionOfTopicId, taskId);
+ }, async (error) => {
+ new Logger().error(error, ['API_GATEWAY']);
+ taskManager.addError(taskId, { code: 500, message: 'Unknown error: ' + error.message });
+ });
+ return res.status(202).send({ taskId, expectation });
+ }
+
+ @Post('/import/message/preview')
+ @HttpCode(HttpStatus.OK)
+ async importMessage(@Req() req, @Response() res): Promise {
+ await checkPermission(UserRole.STANDARD_REGISTRY)(req.user);
+ const engineService = new PolicyEngine();
+ try {
+ return res.send(await engineService.importMessagePreview(req.user, req.body.messageId));
+ } catch (error) {
+ new Logger().error(error, ['API_GATEWAY']);
+ throw error;
}
+ }
+
+ @Post('/push/import/message/preview')
+ @HttpCode(HttpStatus.ACCEPTED)
+ async importFromMessagePreview(@Req() req, @Response() res) {
+ await checkPermission(UserRole.STANDARD_REGISTRY)(req.user);
+ const taskManager = new TaskManager();
+ const { taskId, expectation } = taskManager.start('Preview policy message');
+
+ const user = req.user;
+ const messageId = req.body.messageId;
+ RunFunctionAsync(async () => {
+ const engineService = new PolicyEngine();
+ await engineService.importMessagePreviewAsync(user, messageId, taskId);
+ }, async (error) => {
+ new Logger().error(error, ['API_GATEWAY']);
+ taskManager.addError(taskId, { code: 500, message: 'Unknown error: ' + error.message });
+ });
+
+ return res.status(202).send({ taskId, expectation });
+ }
- let pageIndex: any;
- let pageSize: any;
- if (req.query && req.query.pageIndex && req.query.pageSize) {
- pageIndex = req.query.pageIndex;
- pageSize = req.query.pageSize;
+ @Post('/import/file/preview')
+ @HttpCode(HttpStatus.OK)
+ async importPolicyFromFilePreview(@Req() req: RawBodyRequest, @Response() res) {
+ await checkPermission(UserRole.STANDARD_REGISTRY)(req.user);
+ const engineService = new PolicyEngine();
+ try {
+ return res.send(await engineService.importFilePreview(req.user, req.body));
+ } catch (error) {
+ new Logger().error(error, ['API_GATEWAY']);
+ throw error;
}
- const [data, count] = await engineService.getVirtualDocuments(req.params.policyId, 'artifacts', pageIndex, pageSize);
- return res.setHeader('X-Total-Count', count).json(data);
- } catch (error) {
- new Logger().error(error, ['API_GATEWAY']);
- return next(error);
}
-});
-policyAPI.get('/:policyId/dry-run/ipfs', permissionHelper(UserRole.STANDARD_REGISTRY), async (req: AuthenticatedRequest, res: Response, next: NextFunction) => {
- const engineService = new PolicyEngine();
- try {
- const policy = await engineService.getPolicy({ filters: req.params.policyId }) as any;
- if (!policy) {
- return next(createError(404, 'Policy does not exist.'));
- }
- if (policy.owner !== req.user.did) {
- return next(createError(403, 'Invalid owner.'));
+ @Get('/blocks/about')
+ @HttpCode(HttpStatus.OK)
+ async getBlockAbout(@Req() req, @Response() res) {
+ const engineService = new PolicyEngine();
+ try {
+ return res.send(await engineService.blockAbout());
+ } catch (error) {
+ new Logger().error(error, ['API_GATEWAY']);
+ throw error;
}
+ }
- let pageIndex: any;
- let pageSize: any;
- if (req.query && req.query.pageIndex && req.query.pageSize) {
- pageIndex = req.query.pageIndex;
- pageSize = req.query.pageSize;
- }
- const [data, count] = await engineService.getVirtualDocuments(req.params.policyId, 'ipfs', pageIndex, pageSize)
- return res.setHeader('X-Total-Count', count).json(data);
- } catch (error) {
- new Logger().error(error, ['API_GATEWAY']);
- return next(error);
+ @Get('/:policyId/dry-run/users')
+ @HttpCode(HttpStatus.OK)
+ async getDryRunUsers(@Req() req, @Response() res) {
+ await checkPermission(UserRole.STANDARD_REGISTRY)(req.user);
+ const engineService = new PolicyEngine();
+ try {
+ const policy = await engineService.getPolicy({ filters: req.params.policyId }) as any;
+ if (!policy) {
+ throw new HttpException('Policy does not exist.', HttpStatus.NOT_FOUND)
+ }
+ if (policy.owner !== req.user.did) {
+ throw new HttpException('Invalid owner.', HttpStatus.FORBIDDEN)
+ }
+
+ return res.send(await engineService.getVirtualUsers(req.params.policyId));
+ } catch (error) {
+ new Logger().error(error, ['API_GATEWAY']);
+ throw error;
+ }
+ }
+
+ @Post('/:policyId/dry-run/user')
+ @HttpCode(HttpStatus.CREATED)
+ async setDryRunUser(@Req() req, @Response() res) {
+ await checkPermission(UserRole.STANDARD_REGISTRY)(req.user);
+ const engineService = new PolicyEngine();
+ try {
+ const policy = await engineService.getPolicy({ filters: req.params.policyId }) as any;
+ if (!policy) {
+ throw new HttpException('Policy does not exist.', HttpStatus.NOT_FOUND)
+ }
+ if (policy.owner !== req.user.did) {
+ throw new HttpException('Invalid owner.', HttpStatus.FORBIDDEN)
+ }
+
+ return res.status(201).send(await engineService.createVirtualUser(req.params.policyId, req.user.did));
+ } catch (error) {
+ new Logger().error(error, ['API_GATEWAY']);
+ throw error;
+ }
+ }
+
+ @Post('/:policyId/dry-run/login')
+ @HttpCode(HttpStatus.OK)
+ async loginDryRunUser(@Req() req, @Response() res) {
+ await checkPermission(UserRole.STANDARD_REGISTRY)(req.user);
+ const engineService = new PolicyEngine();
+ try {
+ const policy = await engineService.getPolicy({ filters: req.params.policyId }) as any;
+ if (!policy) {
+ throw new HttpException('Policy does not exist.', HttpStatus.NOT_FOUND)
+ }
+ if (policy.owner !== req.user.did) {
+ throw new HttpException('Invalid owner.', HttpStatus.FORBIDDEN)
+ }
+
+ return res.send(await engineService.loginVirtualUser(req.params.policyId, req.body.did));
+ } catch (error) {
+ new Logger().error(error, ['API_GATEWAY']);
+ throw error;
+ }
+ }
+
+ @Post('/:policyId/dry-run/restart')
+ @HttpCode(HttpStatus.OK)
+ async restartDryRun(@Req() req, @Response() res) {
+ await checkPermission(UserRole.STANDARD_REGISTRY)(req.user);
+ const engineService = new PolicyEngine();
+ try {
+ const policy = await engineService.getPolicy({ filters: req.params.policyId }) as any;
+ if (!policy) {
+ throw new HttpException('Policy does not exist.', HttpStatus.NOT_FOUND)
+ }
+ if (policy.owner !== req.user.did) {
+ throw new HttpException('Invalid owner.', HttpStatus.FORBIDDEN)
+ }
+
+ return res.json(await engineService.restartDryRun(req.body, req.user, req.params.policyId));
+ } catch (error) {
+ new Logger().error(error, ['API_GATEWAY']);
+ throw error;
+ }
+ }
+
+ @Get('/:policyId/dry-run/transactions')
+ @HttpCode(HttpStatus.OK)
+ async getDryRunTransactions(@Req() req, @Response() res) {
+ await checkPermission(UserRole.STANDARD_REGISTRY)(req.user);
+ const engineService = new PolicyEngine();
+ try {
+ const policy = await engineService.getPolicy({ filters: req.params.policyId }) as any;
+ if (!policy) {
+ throw new HttpException('Policy does not exist.', HttpStatus.NOT_FOUND)
+ }
+ if (policy.owner !== req.user.did) {
+ throw new HttpException('Invalid owner.', HttpStatus.FORBIDDEN)
+ }
+
+ let pageIndex: any;
+ let pageSize: any;
+ if (req.query && req.query.pageIndex && req.query.pageSize) {
+ pageIndex = req.query.pageIndex;
+ pageSize = req.query.pageSize;
+ }
+ const [data, count] = await engineService.getVirtualDocuments(req.params.policyId, 'transactions', pageIndex, pageSize)
+ return res.setHeader('X-Total-Count', count).json(data);
+ } catch (error) {
+ new Logger().error(error, ['API_GATEWAY']);
+ throw error;
+ }
+ }
+
+ @Get('/:policyId/dry-run/artifacts')
+ @HttpCode(HttpStatus.OK)
+ async getDryRunArtifacts(@Req() req, @Response() res) {
+ await checkPermission(UserRole.STANDARD_REGISTRY)(req.user);
+ const engineService = new PolicyEngine();
+ try {
+ const policy = await engineService.getPolicy({ filters: req.params.policyId }) as any;
+ if (!policy) {
+ throw new HttpException('Policy does not exist.', HttpStatus.NOT_FOUND)
+ }
+ if (policy.owner !== req.user.did) {
+ throw new HttpException('Invalid owner.', HttpStatus.FORBIDDEN)
+ }
+
+ let pageIndex: any;
+ let pageSize: any;
+ if (req.query && req.query.pageIndex && req.query.pageSize) {
+ pageIndex = req.query.pageIndex;
+ pageSize = req.query.pageSize;
+ }
+ const [data, count] = await engineService.getVirtualDocuments(req.params.policyId, 'artifacts', pageIndex, pageSize);
+ return res.setHeader('X-Total-Count', count).json(data);
+ } catch (error) {
+ new Logger().error(error, ['API_GATEWAY']);
+ throw error;
+ }
+ }
+
+ @Get('/:policyId/dry-run/ipfs')
+ @HttpCode(HttpStatus.OK)
+ async getDryRunIpfs(@Req() req, @Response() res) {
+ await checkPermission(UserRole.STANDARD_REGISTRY)(req.user);
+ const engineService = new PolicyEngine();
+ try {
+ const policy = await engineService.getPolicy({ filters: req.params.policyId }) as any;
+ if (!policy) {
+ throw new HttpException('Policy does not exist.', HttpStatus.NOT_FOUND)
+ }
+ if (policy.owner !== req.user.did) {
+ throw new HttpException('Invalid owner.', HttpStatus.FORBIDDEN)
+ }
+
+ let pageIndex: any;
+ let pageSize: any;
+ if (req.query && req.query.pageIndex && req.query.pageSize) {
+ pageIndex = req.query.pageIndex;
+ pageSize = req.query.pageSize;
+ }
+ const [data, count] = await engineService.getVirtualDocuments(req.params.policyId, 'ipfs', pageIndex, pageSize)
+ return res.setHeader('X-Total-Count', count).json(data);
+ } catch (error) {
+ new Logger().error(error, ['API_GATEWAY']);
+ throw error;
+ }
+ }
+
+ @Get('/:policyId/multiple')
+ @HttpCode(HttpStatus.OK)
+ async getMultiplePolicies(@Req() req, @Response() res) {
+ const engineService = new PolicyEngine();
+ try {
+ return res.send(await engineService.getMultiPolicy(req.user, req.params.policyId));
+ } catch (error) {
+ new Logger().error(error, ['API_GATEWAY']);
+ throw error;
+ }
+ }
+
+ @Post('/:policyId/multiple/')
+ @HttpCode(HttpStatus.OK)
+ async setMultiplePolicies(@Req() req, @Response() res) {
+ const engineService = new PolicyEngine();
+ try {
+ return res.send(await engineService.setMultiPolicy(req.user, req.params.policyId, req.body));
+ } catch (error) {
+ new Logger().error(error, ['API_GATEWAY']);
+ throw error
+ }
}
-});
-
-policyAPI.get('/:policyId/multiple', async (req: AuthenticatedRequest, res: Response, next: NextFunction) => {
- const engineService = new PolicyEngine();
- try {
- res.send(await engineService.getMultiPolicy(req.user, req.params.policyId));
- } catch (error) {
- new Logger().error(error, ['API_GATEWAY']);
- return next(error);
- }
-});
-
-policyAPI.post('/:policyId/multiple/', async (req: AuthenticatedRequest, res: Response, next: NextFunction) => {
- const engineService = new PolicyEngine();
- try {
- res.send(await engineService.setMultiPolicy(req.user, req.params.policyId, req.body));
- } catch (error) {
- new Logger().error(error, ['API_GATEWAY']);
- return next(error);
- }
-});
+}
diff --git a/api-gateway/src/api/service/profile.ts b/api-gateway/src/api/service/profile.ts
index b107716f33..63d06c1494 100644
--- a/api-gateway/src/api/service/profile.ts
+++ b/api-gateway/src/api/service/profile.ts
@@ -1,171 +1,177 @@
import { Guardians } from '@helpers/guardians';
import { Users } from '@helpers/users';
-import { Request, Response, Router, NextFunction } from 'express';
-import {
- DidDocumentStatus,
- IUser,
- SchemaEntity,
- TopicType, UserRole
-} from '@guardian/interfaces';
-import { AuthenticatedRequest, Logger, RunFunctionAsync } from '@guardian/common';
+import { DidDocumentStatus, IUser, SchemaEntity, TopicType, UserRole } from '@guardian/interfaces';
+import { Logger, RunFunctionAsync } from '@guardian/common';
import { TaskManager } from '@helpers/task-manager';
-import { permissionHelper } from '@auth/authorization-helper';
import { ServiceError } from '@helpers/service-requests-base';
-import createError from 'http-errors';
+import { Controller, Get, HttpCode, HttpException, HttpStatus, Put, Req, Response } from '@nestjs/common';
+import { checkPermission } from '@auth/authorization-helper';
-/**
- * User profile route
- */
-export const profileAPI = Router();
+@Controller('profiles')
+export class ProfileApi {
+ @Get('/:username/')
+ @HttpCode(HttpStatus.OK)
+ async getProfile(@Req() req, @Response() res): Promise {
+ try {
+ const guardians = new Guardians();
+ const users = new Users();
-profileAPI.get('/:username/', async (req: AuthenticatedRequest, res: Response, next: NextFunction) => {
- try {
- const guardians = new Guardians();
- const users = new Users();
+ const user = await users.getUser(req.user.username);
- const user = await users.getUser(req.user.username);
-
- let didDocument: any = null;
- if (user.did) {
- const didDocuments = await guardians.getDidDocuments({ did: user.did });
- if (didDocuments) {
- didDocument = didDocuments[didDocuments.length - 1];
+ let didDocument: any = null;
+ if (user.did) {
+ const didDocuments = await guardians.getDidDocuments({ did: user.did });
+ if (didDocuments) {
+ didDocument = didDocuments[didDocuments.length - 1];
+ }
}
- }
- let vcDocument: any = null;
- if (user.did) {
- let vcDocuments = await guardians.getVcDocuments({
- owner: user.did,
- type: SchemaEntity.USER
- });
- if (vcDocuments && vcDocuments.length) {
- vcDocument = vcDocuments[vcDocuments.length - 1];
+ let vcDocument: any = null;
+ if (user.did) {
+ let vcDocuments = await guardians.getVcDocuments({
+ owner: user.did,
+ type: SchemaEntity.USER
+ });
+ if (vcDocuments && vcDocuments.length) {
+ vcDocument = vcDocuments[vcDocuments.length - 1];
+ }
+ vcDocuments = await guardians.getVcDocuments({
+ owner: user.did,
+ type: SchemaEntity.STANDARD_REGISTRY
+ });
+ if (vcDocuments && vcDocuments.length) {
+ vcDocument = vcDocuments[vcDocuments.length - 1];
+ }
}
- vcDocuments = await guardians.getVcDocuments({
- owner: user.did,
- type: SchemaEntity.STANDARD_REGISTRY
- });
- if (vcDocuments && vcDocuments.length) {
- vcDocument = vcDocuments[vcDocuments.length - 1];
+
+ let topic: any;
+ if (user.did || user.parent) {
+ const filters = [];
+ if (user.did) {
+ filters.push(user.did);
+ }
+ if (user.parent) {
+ filters.push(user.parent);
+ }
+ topic = await guardians.getTopic({
+ type: TopicType.UserTopic,
+ owner: { $in: filters }
+ });
}
+
+ const result: IUser = {
+ username: user.username,
+ role: user.role,
+ did: user.did,
+ parent: user.parent,
+ hederaAccountId: user.hederaAccountId,
+ confirmed: !!(didDocument && didDocument.status === DidDocumentStatus.CREATE),
+ failed: !!(didDocument && didDocument.status === DidDocumentStatus.FAILED),
+ hederaAccountKey: null,
+ topicId: topic?.topicId,
+ parentTopicId: topic?.parent,
+ didDocument,
+ vcDocument
+ };
+ return res.json(result);
+ } catch (error) {
+ new Logger().error(error, ['API_GATEWAY']);
+ throw error;
}
+ }
- let topic: any;
- if (user.did || user.parent) {
- const filters = [];
- if (user.did) {
- filters.push(user.did);
- }
- if (user.parent) {
- filters.push(user.parent);
- }
- topic = await guardians.getTopic({
- type: TopicType.UserTopic,
- owner: { $in: filters }
- });
+ @Put('/:username')
+ @HttpCode(HttpStatus.NO_CONTENT)
+ async setUserProfile(@Req() req, @Response() res): Promise {
+ try {
+ const guardians = new Guardians();
+
+ const profile: any = req.body;
+ const username: string = req.user.username;
+
+ await guardians.createUserProfileCommon(username, profile);
+
+ return res.status(204).send();
+ } catch (error) {
+ new Logger().error(error, ['API_GATEWAY']);
+ throw error;
}
+ }
+
+ @Put('/push/:username')
+ @HttpCode(HttpStatus.ACCEPTED)
+ async setUserProfileAsync(@Req() req, @Response() res): Promise {
+ const taskManager = new TaskManager();
+ const {taskId, expectation} = taskManager.start('Connect user');
- const result: IUser = {
- username: user.username,
- role: user.role,
- did: user.did,
- parent: user.parent,
- hederaAccountId: user.hederaAccountId,
- confirmed: !!(didDocument && didDocument.status === DidDocumentStatus.CREATE),
- failed: !!(didDocument && didDocument.status === DidDocumentStatus.FAILED),
- hederaAccountKey: null,
- topicId: topic?.topicId,
- parentTopicId: topic?.parent,
- didDocument,
- vcDocument
- };
- return res.json(result);
- } catch (error) {
- new Logger().error(error, ['API_GATEWAY']);
- return next(error);
+ const profile: any = req.body;
+ const username: string = req.user.username;
+ RunFunctionAsync(async () => {
+ const guardians = new Guardians();
+ await guardians.createUserProfileCommonAsync(username, profile, taskId);
+ }, async (error) => {
+ new Logger().error(error, ['API_GATEWAY']);
+ taskManager.addError(taskId, {code: error.code || 500, message: error.message});
+ });
+
+ return res.status(202).send({taskId, expectation});
}
-});
-profileAPI.put('/:username', async (req: AuthenticatedRequest, res: Response, next: NextFunction) => {
- try {
- const guardians = new Guardians();
+ @Put('/restore/:username')
+ @HttpCode(HttpStatus.ACCEPTED)
+ async resoreUserProfile(@Req() req, @Response() res): Promise {
+ await checkPermission(UserRole.STANDARD_REGISTRY)(req.user);
+ const taskManager = new TaskManager();
+ const {taskId, expectation} = taskManager.start('Restore user profile');
const profile: any = req.body;
const username: string = req.user.username;
- await guardians.createUserProfileCommon(username, profile);
+ RunFunctionAsync(async () => {
+ const guardians = new Guardians();
+ await guardians.restoreUserProfileCommonAsync(username, profile, taskId);
+ }, async (error) => {
+ new Logger().error(error, ['API_GATEWAY']);
+ taskManager.addError(taskId, {code: error.code || 500, message: error.message});
+ })
- return res.status(204).send();
- } catch (error) {
- new Logger().error(error, ['API_GATEWAY']);
- return next(error);
+ return res.status(202).send({taskId, expectation});
}
-});
-
-profileAPI.put('/push/:username', async (req: AuthenticatedRequest, res: Response) => {
- const taskManager = new TaskManager();
- const {taskId, expectation} = taskManager.start('Connect user');
-
- const profile: any = req.body;
- const username: string = req.user.username;
- RunFunctionAsync(async () => {
- const guardians = new Guardians();
- await guardians.createUserProfileCommonAsync(username, profile, taskId);
- }, async (error) => {
- new Logger().error(error, ['API_GATEWAY']);
- taskManager.addError(taskId, {code: error.code || 500, message: error.message});
- });
-
- return res.status(202).send({taskId, expectation});
-});
-
-profileAPI.put('/restore/:username', permissionHelper(UserRole.STANDARD_REGISTRY), async (req: AuthenticatedRequest, res: Response) => {
- const taskManager = new TaskManager();
- const {taskId, expectation} = taskManager.start('Restore user profile');
-
- const profile: any = req.body;
- const username: string = req.user.username;
-
- RunFunctionAsync(async () => {
- const guardians = new Guardians();
- await guardians.restoreUserProfileCommonAsync(username, profile, taskId);
- }, async (error) => {
- new Logger().error(error, ['API_GATEWAY']);
- taskManager.addError(taskId, {code: error.code || 500, message: error.message});
- })
-
- return res.status(202).send({taskId, expectation});
-});
-
-profileAPI.put('/restore/topics/:username', permissionHelper(UserRole.STANDARD_REGISTRY), async (req: AuthenticatedRequest, res: Response) => {
- const taskManager = new TaskManager();
- const {taskId, expectation} = taskManager.start('Get user topics');
-
- const profile: any = req.body;
- const username: string = req.user.username;
-
- RunFunctionAsync(async () => {
- const guardians = new Guardians();
- await guardians.getAllUserTopicsAsync(username, profile, taskId);
- }, async (error) => {
- new Logger().error(error, ['API_GATEWAY']);
- taskManager.addError(taskId, {code: error.code || 500, message: error.message});
- })
-
- return res.status(202).send({taskId, expectation});
-});
-
-profileAPI.get('/:username/balance', async (req: Request, res: Response, next: NextFunction) => {
- try {
- const guardians = new Guardians();
- const balance = await guardians.getUserBalance(req.params.username);
- if (balance.toLowerCase().includes('invalid account')) {
- return next(createError(404, 'Account not found'));
+
+ @Put('/restore/topics/:username')
+ @HttpCode(HttpStatus.ACCEPTED)
+ async restoreTopic(@Req() req, @Response() res): Promise {
+ await checkPermission(UserRole.STANDARD_REGISTRY)(req.user);
+ const taskManager = new TaskManager();
+ const {taskId, expectation} = taskManager.start('Get user topics');
+
+ const profile: any = req.body;
+ const username: string = req.user.username;
+
+ RunFunctionAsync(async () => {
+ const guardians = new Guardians();
+ await guardians.getAllUserTopicsAsync(username, profile, taskId);
+ }, async (error) => {
+ new Logger().error(error, ['API_GATEWAY']);
+ taskManager.addError(taskId, {code: error.code || 500, message: error.message});
+ })
+
+ return res.status(202).send({taskId, expectation});
+ }
+
+ @Get('/:username/balance')
+ @HttpCode(HttpStatus.OK)
+ async getUserBalance(@Req() req, @Response() res): Promise {
+ try {
+ const guardians = new Guardians();
+ const balance = await guardians.getUserBalance(req.params.username);
+ if (balance.toLowerCase().includes('invalid account')) {
+ throw new HttpException('Account not found', HttpStatus.NOT_FOUND)
+ }
+ return res.json(balance);
+ } catch (error) {
+ new Logger().error(error, ['API_GATEWAY']);
+ throw error;
}
- return res.json(balance);
- } catch (error) {
- new Logger().error(error, ['API_GATEWAY']);
- return next(error);
}
-});
+}
diff --git a/api-gateway/src/api/service/schema.ts b/api-gateway/src/api/service/schema.ts
index 14f1d7fdb1..87d5b92ee9 100644
--- a/api-gateway/src/api/service/schema.ts
+++ b/api-gateway/src/api/service/schema.ts
@@ -1,23 +1,14 @@
import { Guardians } from '@helpers/guardians';
-import { NextFunction, Request, Response, Router } from 'express';
-import {
- ISchema,
- SchemaCategory,
- SchemaEntity,
- SchemaHelper,
- SchemaStatus,
- StatusType,
- UserRole
-} from '@guardian/interfaces';
-import { permissionHelper } from '@auth/authorization-helper';
-import { AuthenticatedRequest, Logger, RunFunctionAsync } from '@guardian/common';
+import { ISchema, SchemaCategory, SchemaEntity, SchemaHelper, SchemaStatus, StatusType, UserRole } from '@guardian/interfaces';
+import { Logger, RunFunctionAsync } from '@guardian/common';
import { PolicyEngine } from '@helpers/policy-engine';
import { TaskManager } from '@helpers/task-manager';
import { ServiceError } from '@helpers/service-requests-base';
import { SchemaUtils } from '@helpers/schema-utils';
-import createError from 'http-errors';
-import validate from '@middlewares/validation';
-import { schemaSchema, systemEntitySchema } from '@middlewares/validation/schemas/schemas';
+import { Controller, Delete, Get, HttpCode, HttpException, HttpStatus, Post, Put, Req, Response } from '@nestjs/common';
+import { checkPermission } from '@auth/authorization-helper';
+import { Client, ClientProxy, Transport } from '@nestjs/microservices';
+import process from 'process';
/**
* Prepare new schema object
@@ -110,220 +101,246 @@ export async function updateSchema(newSchema: ISchema, owner: string): Promise {
+ try {
+ const user = req.user;
+ const schemaId = req.params.schemaId;
+ const guardians = new Guardians();
+ const schema = await guardians.getSchemaById(schemaId);
+ if (!schema) {
+ throw new HttpException('Schema not found', HttpStatus.NOT_FOUND)
+ }
+ let owner = user.parent;
+ if (user.role === UserRole.STANDARD_REGISTRY) {
+ owner = user.did;
+ }
+ if (!schema.system && schema.owner && schema.owner !== owner) {
+ throw new HttpException('Invalid creator.', HttpStatus.FORBIDDEN)
-singleSchemaRoute.get('/:schemaId', async (req: AuthenticatedRequest, res: Response, next: NextFunction) => {
- try {
- const user = req.user;
- const schemaId = req.params.schemaId;
- const guardians = new Guardians();
- const schema = await guardians.getSchemaById(schemaId);
- if (!schema) {
- return next(createError(404, 'Schema not found'));
- }
- let owner = user.parent;
- if (user.role === UserRole.STANDARD_REGISTRY) {
- owner = user.did;
+ }
+ if (schema.system) {
+ schema.readonly = schema.readonly || schema.owner !== owner;
+ } else {
+ SchemaHelper.updatePermission([schema], owner);
+ }
+ return res.json(SchemaUtils.toOld(schema));
+ } catch (error) {
+ new Logger().error(error, ['API_GATEWAY']);
+ throw error
}
- if (!schema.system && schema.owner && schema.owner !== owner) {
- return next(createError(403, 'Invalid creator.'));
+ }
+}
+
+@Controller('schemas')
+export class SchemaApi {
+
+ @Client({
+ transport: Transport.NATS,
+ options: {
+ // name: `${process.env.SERVICE_CHANNEL}`,
+ servers: [
+ `nats://${process.env.MQ_ADDRESS}:4222`
+ ]
}
- if (schema.system) {
- schema.readonly = schema.readonly || schema.owner !== owner;
- } else {
- SchemaHelper.updatePermission([schema], owner);
+ })
+ client: ClientProxy;
+
+ @Post('/:topicId')
+ @HttpCode(HttpStatus.CREATED)
+ async setTopicId(@Req() req, @Response() res): Promise {
+ await checkPermission(UserRole.STANDARD_REGISTRY)(req.user);
+ try {
+ const user = req.user;
+ const newSchema = req.body;
+ SchemaUtils.fromOld(newSchema);
+ const topicId = req.params.topicId;
+ const schemas = await createSchema(
+ newSchema,
+ user.did,
+ topicId,
+ );
+ return res.status(201).json(SchemaUtils.toOld(schemas));
+ } catch (error) {
+ new Logger().error(error, ['API_GATEWAY']);
+ throw error;
}
- res.json(SchemaUtils.toOld(schema));
- } catch (error) {
- new Logger().error(error, ['API_GATEWAY']);
- return next(error);
}
-});
-/**
- * Schema route
- */
-export const schemaAPI = Router();
+ @Post('/push/:topicId')
+ @HttpCode(HttpStatus.ACCEPTED)
+ async setTopicIdAsync(@Req() req, @Response() res): Promise {
+ await checkPermission(UserRole.STANDARD_REGISTRY)(req.user);
+ const taskManager = new TaskManager();
+ const { taskId, expectation } = taskManager.start('Create schema');
-schemaAPI.post('/:topicId', permissionHelper(UserRole.STANDARD_REGISTRY), async (req: AuthenticatedRequest, res: Response, next: NextFunction) => {
- try {
const user = req.user;
const newSchema = req.body;
- SchemaUtils.fromOld(newSchema);
const topicId = req.params.topicId;
- const schemas = await createSchema(newSchema, user.did, topicId);
- return res.status(201).json(SchemaUtils.toOld(schemas));
- } catch (error) {
- new Logger().error(error, ['API_GATEWAY']);
- return next(error);
+ RunFunctionAsync(async () => {
+ SchemaUtils.fromOld(newSchema);
+ await createSchemaAsync(
+ newSchema,
+ user.did,
+ topicId,
+ taskId,
+ );
+ }, async (error) => {
+ new Logger().error(error, ['API_GATEWAY']);
+ taskManager.addError(taskId, { code: 500, message: error.message });
+ });
+
+ return res.status(202).send({ taskId, expectation });
}
-});
-schemaAPI.post('/push/:topicId', permissionHelper(UserRole.STANDARD_REGISTRY), async (req: AuthenticatedRequest, res: Response, next: NextFunction) => {
- const taskManager = new TaskManager();
- const { taskId, expectation } = taskManager.start('Create schema');
-
- const user = req.user;
- const newSchema = req.body;
- const topicId = req.params.topicId;
- RunFunctionAsync(async () => {
- SchemaUtils.fromOld(newSchema);
- await createSchemaAsync(newSchema, user.did, topicId, taskId);
- }, async (error) => {
- new Logger().error(error, ['API_GATEWAY']);
- taskManager.addError(taskId, { code: 500, message: error.message });
- });
-
- res.status(202).send({ taskId, expectation });
-});
+ @Get('/')
+ @HttpCode(HttpStatus.OK)
+ async getSchemas(@Req() req, @Response() res): Promise {
+ try {
+ const user = req.user;
+ const { guardians, pageIndex, pageSize, owner } = prepareSchemaPagination(req, user);
+ let topicId = null;
+ const policyId = req.query?.policyId;
+ if (policyId) {
+ const engineService = new PolicyEngine();
+ const model = (await engineService.getPolicy({
+ filters: policyId,
+ userDid: user.did,
+ }));
+ topicId = model?.topicId;
+ }
-/**
- * Prepare the schema pagination
- *
- * @param req
- * @param user
- */
-function prepareSchemaPagination(req, user) {
- const guardians = new Guardians();
- let pageIndex: any;
- let pageSize: any;
- if (req.query && req.query.pageIndex && req.query.pageSize) {
- pageIndex = req.query.pageIndex;
- pageSize = req.query.pageSize;
- }
- let owner = user.parent;
- if (user.role === UserRole.STANDARD_REGISTRY) {
- owner = user.did;
+ const { items, count } = await guardians.getSchemasByOwner(owner, topicId, pageIndex, pageSize);
+ // const result = await this.client.send(MessageAPI.GET_SCHEMAS, {
+ // owner,
+ // topicId,
+ // pageIndex,
+ // pageSize
+ // }).toPromise();
+ // const { items, count } = result.body;
+ SchemaHelper.updatePermission(items, user.did);
+ return res.setHeader('X-Total-Count', count).json(SchemaUtils.toOld(items));
+ } catch (error) {
+ new Logger().error(error, ['API_GATEWAY']);
+ throw error;
+ }
}
- return { guardians, pageIndex, pageSize, owner };
-}
-schemaAPI.get('/', async (req: AuthenticatedRequest, res: Response, next: NextFunction) => {
- try {
- const user = req.user;
- const { guardians, pageIndex, pageSize, owner } = prepareSchemaPagination(req, user);
- let topicId = null;
- const policyId = req.query?.policyId;
- if (policyId) {
- const engineService = new PolicyEngine();
- const model = (await engineService.getPolicy({
- filters: policyId,
- userDid: user.did,
- }));
- topicId = model?.topicId;
+ @Get('/:topicId')
+ @HttpCode(HttpStatus.OK)
+ async getByTopicId(@Req() req, @Response() res): Promise {
+ try {
+ const user = req.user;
+ const { topicId } = req.params;
+ const { guardians, pageIndex, pageSize, owner } = prepareSchemaPagination(req, user);
+ const { items, count } = await guardians.getSchemasByOwner(owner, topicId, pageIndex, pageSize);
+ SchemaHelper.updatePermission(items, user.did);
+ return res.setHeader('X-Total-Count', count).json(SchemaUtils.toOld(items));
+ } catch (error) {
+ new Logger().error(error, ['API_GATEWAY']);
+ throw error;
}
-
- const { items, count } = await guardians.getSchemasByOwner(owner, topicId, pageIndex, pageSize);
- SchemaHelper.updatePermission(items, user.did);
- res.setHeader('X-Total-Count', count).json(SchemaUtils.toOld(items));
- } catch (error) {
- new Logger().error(error, ['API_GATEWAY']);
- return next(error);
}
-});
-schemaAPI.get('/:topicId', async (req: AuthenticatedRequest, res: Response, next: NextFunction) => {
- try {
- const user = req.user;
- const { topicId } = req.params;
- const { guardians, pageIndex, pageSize, owner } = prepareSchemaPagination(req, user);
- const { items, count } = await guardians.getSchemasByOwner(owner, topicId, pageIndex, pageSize);
- SchemaHelper.updatePermission(items, user.did);
- res.setHeader('X-Total-Count', count).json(SchemaUtils.toOld(items));
- } catch (error) {
- new Logger().error(error, ['API_GATEWAY']);
- return next(error);
- }
-});
-
-schemaAPI.put('/', permissionHelper(UserRole.STANDARD_REGISTRY), async (req: AuthenticatedRequest, res: Response, next: NextFunction) => {
- try {
- const user = req.user;
- const newSchema = req.body;
- const guardians = new Guardians();
- const schema = await guardians.getSchemaById(newSchema.id);
- if (!schema) {
- return next(createError(404, 'Schema not found.'));
- }
- const error = SchemaUtils.checkPermission(schema, user, SchemaCategory.POLICY);
- if (error) {
- return next(createError(403, error));
- }
- if (schema.status === SchemaStatus.PUBLISHED) {
- return next(createError(422, 'Schema is published.'));
+ @Put('/')
+ @HttpCode(HttpStatus.OK)
+ async setSchema(@Req() req, @Response() res): Promise {
+ await checkPermission(UserRole.STANDARD_REGISTRY)(req.user);
+ try {
+ const user = req.user;
+ const newSchema = req.body;
+ const guardians = new Guardians();
+ const schema = await guardians.getSchemaById(newSchema.id);
+ if (!schema) {
+ throw new HttpException('Schema not found.', HttpStatus.NOT_FOUND)
+ }
+ const error = SchemaUtils.checkPermission(schema, user, SchemaCategory.POLICY);
+ if (error) {
+ throw new HttpException(error, HttpStatus.FORBIDDEN)
+ }
+ if (schema.status === SchemaStatus.PUBLISHED) {
+ throw new HttpException('Schema is published.', HttpStatus.UNPROCESSABLE_ENTITY)
+ }
+ SchemaUtils.fromOld(newSchema);
+ const schemas = await updateSchema(newSchema, user.did);
+ return res.json(SchemaUtils.toOld(schemas));
+ } catch (error) {
+ new Logger().error(error, ['API_GATEWAY']);
+ throw error;
}
- SchemaUtils.fromOld(newSchema);
- const schemas = await updateSchema(newSchema, user.did);
- res.json(SchemaUtils.toOld(schemas));
- } catch (error) {
- new Logger().error(error, ['API_GATEWAY']);
- return next(error);
}
-});
-schemaAPI.delete('/:schemaId', permissionHelper(UserRole.STANDARD_REGISTRY), async (req: AuthenticatedRequest, res: Response, next: NextFunction) => {
- try {
- const user = req.user;
- const guardians = new Guardians();
- const schemaId = req.params.schemaId;
- const schema = await guardians.getSchemaById(schemaId);
- if (!schema) {
- return next(createError(404, 'Schema not found.'));
- }
- const error = SchemaUtils.checkPermission(schema, user, SchemaCategory.POLICY);
- if (error) {
- return next(createError(403, error));
- }
- if (schema.status === SchemaStatus.PUBLISHED) {
- return next(createError(422, 'Schema is published.'));
+ @Delete('/:schemaId')
+ @HttpCode(HttpStatus.OK)
+ async deleteSchema(@Req() req, @Response() res): Promise {
+ await checkPermission(UserRole.STANDARD_REGISTRY)(req.user);
+ try {
+ const user = req.user;
+ const guardians = new Guardians();
+ const schemaId = req.params.schemaId;
+ const schema = await guardians.getSchemaById(schemaId);
+ if (!schema) {
+ throw new HttpException('Schema not found.', HttpStatus.NOT_FOUND)
+ }
+ const error = SchemaUtils.checkPermission(schema, user, SchemaCategory.POLICY);
+ if (error) {
+ throw new HttpException(error, HttpStatus.FORBIDDEN)
+ }
+ if (schema.status === SchemaStatus.PUBLISHED) {
+ throw new HttpException('Schema is published.', HttpStatus.UNPROCESSABLE_ENTITY)
+ }
+ const schemas = (await guardians.deleteSchema(schemaId, true) as ISchema[]);
+ SchemaHelper.updatePermission(schemas, user.did);
+ return res.json(SchemaUtils.toOld(schemas));
+ } catch (error) {
+ new Logger().error(error, ['API_GATEWAY']);
+ throw error;
}
- const schemas = (await guardians.deleteSchema(schemaId, true) as ISchema[]);
- SchemaHelper.updatePermission(schemas, user.did);
- res.json(SchemaUtils.toOld(schemas));
- } catch (error) {
- new Logger().error(error, ['API_GATEWAY']);
- return next(error);
}
-});
-schemaAPI.put('/:schemaId/publish', permissionHelper(UserRole.STANDARD_REGISTRY), async (req: AuthenticatedRequest, res: Response, next: NextFunction) => {
- try {
- const user = req.user;
- const guardians = new Guardians();
- const schemaId = req.params.schemaId;
- const schema = await guardians.getSchemaById(schemaId);
- if (!schema) {
- return next(createError(404, 'Schema not found.'));
- }
- const error = SchemaUtils.checkPermission(schema, user, SchemaCategory.POLICY);
- if (error) {
- return next(createError(403, error));
- }
- if (schema.status === SchemaStatus.PUBLISHED) {
- return next(createError(422, 'Schema is published.'));
- }
- const allVersion = await guardians.getSchemasByUUID(schema.uuid);
- const { version } = req.body;
- if (allVersion.findIndex(s => s.version === version) !== -1) {
- return next(createError(422, 'Version already exists.'));
- }
+ @Put('/:schemaId/publish')
+ @HttpCode(HttpStatus.OK)
+ async publishSchema(@Req() req, @Response() res): Promise {
+ await checkPermission(UserRole.STANDARD_REGISTRY)(req.user);
+ try {
+ const user = req.user;
+ const guardians = new Guardians();
+ const schemaId = req.params.schemaId;
+ const schema = await guardians.getSchemaById(schemaId);
+ if (!schema) {
+ throw new HttpException('Schema not found.', HttpStatus.NOT_FOUND)
+ }
+ const error = SchemaUtils.checkPermission(schema, user, SchemaCategory.POLICY);
+ if (error) {
+ throw new HttpException(error, HttpStatus.FORBIDDEN)
+ }
+ if (schema.status === SchemaStatus.PUBLISHED) {
+ throw new HttpException('Schema is published.', HttpStatus.UNPROCESSABLE_ENTITY)
+ }
+ const allVersion = await guardians.getSchemasByUUID(schema.uuid);
+ const { version } = req.body;
+ if (allVersion.findIndex(s => s.version === version) !== -1) {
+ throw new HttpException('Version already exists.', HttpStatus.UNPROCESSABLE_ENTITY)
+ }
- await guardians.publishSchema(schemaId, version, user.did);
+ await guardians.publishSchema(schemaId, version, user.did);
- const { items, count } = await guardians.getSchemasByOwner(user.did);
- SchemaHelper.updatePermission(items, user.did);
- res.setHeader('X-Total-Count', count).json(SchemaUtils.toOld(items));
- } catch (error) {
- new Logger().error(error, ['API_GATEWAY']);
- return next(error);
+ const { items, count } = await guardians.getSchemasByOwner(user.did);
+ SchemaHelper.updatePermission(items, user.did);
+ return res.setHeader('X-Total-Count', count).json(SchemaUtils.toOld(items));
+ } catch (error) {
+ new Logger().error(error, ['API_GATEWAY']);
+ throw error;
+ }
}
-});
-schemaAPI.put('/push/:schemaId/publish', permissionHelper(UserRole.STANDARD_REGISTRY),
- async (req: AuthenticatedRequest, res: Response, next: NextFunction) => {
+ @Put('/push/:schemaId/publish')
+ @HttpCode(HttpStatus.ACCEPTED)
+ async publishSchemaAsync(@Req() req, @Response() res): Promise {
+ await checkPermission(UserRole.STANDARD_REGISTRY)(req.user);
const taskManager = new TaskManager();
const { taskId, expectation } = taskManager.start('Publish schema');
@@ -332,11 +349,11 @@ schemaAPI.put('/push/:schemaId/publish', permissionHelper(UserRole.STANDARD_REGI
const guardians = new Guardians();
const schema = await guardians.getSchemaById(schemaId);
if (!schema) {
- return next(createError(404, 'Schema not found'));
+ throw new HttpException('Schema not found', HttpStatus.NOT_FOUND)
}
const notAllowed = SchemaUtils.checkPermission(schema, user, SchemaCategory.POLICY);
if (notAllowed) {
- return next(createError(403, notAllowed));
+ throw new HttpException(notAllowed, HttpStatus.FORBIDDEN)
}
const version = req.body.version;
RunFunctionAsync(async () => {
@@ -356,66 +373,69 @@ schemaAPI.put('/push/:schemaId/publish', permissionHelper(UserRole.STANDARD_REGI
taskManager.addError(taskId, { code: 500, message: error.message });
});
- res.status(202).send({ taskId, expectation });
- });
+ return res.status(202).send({ taskId, expectation });
+ }
-schemaAPI.post('/import/message/preview', [
- validate(schemaSchema()), permissionHelper(UserRole.STANDARD_REGISTRY)
-], async (req: AuthenticatedRequest, res: Response, next: NextFunction) => {
- try {
- const messageId = req.body.messageId;
- const guardians = new Guardians();
- const schemaToPreview = await guardians.previewSchemasByMessages([messageId]);
- return res.json(schemaToPreview);
- } catch (error) {
- new Logger().error(error, ['API_GATEWAY']);
- return next(error);
+ @Post('/import/message/preview')
+ @HttpCode(HttpStatus.OK)
+ async importFromMessagePreview(@Req() req, @Response() res): Promise {
+ await checkPermission(UserRole.STANDARD_REGISTRY)(req.user);
+ try {
+ const messageId = req.body.messageId;
+ const guardians = new Guardians();
+ const schemaToPreview = await guardians.previewSchemasByMessages([messageId]);
+ return res.json(schemaToPreview);
+ } catch (error) {
+ new Logger().error(error, ['API_GATEWAY']);
+ throw error;
+ }
}
-});
-schemaAPI.post('/push/import/message/preview', [
- validate(schemaSchema()), permissionHelper(UserRole.STANDARD_REGISTRY)
-], async (req: AuthenticatedRequest, res: Response, next: NextFunction) => {
- const taskManager = new TaskManager();
- const { taskId, expectation } = taskManager.start('Preview schema message');
+ @Post('/push/import/message/preview')
+ @HttpCode(HttpStatus.ACCEPTED)
+ async importFromMessagePreviewAsync(@Req() req, @Response() res): Promise {
+ await checkPermission(UserRole.STANDARD_REGISTRY)(req.user);
+ const taskManager = new TaskManager();
+ const { taskId, expectation } = taskManager.start('Preview schema message');
- const messageId = req.body.messageId;
- RunFunctionAsync(async () => {
- if (!messageId) {
- throw new Error('Schema ID in body is empty');
- }
- const guardians = new Guardians();
- await guardians.previewSchemasByMessagesAsync([messageId], taskId);
- }, async (error) => {
- new Logger().error(error, ['API_GATEWAY']);
- taskManager.addError(taskId, { code: 500, message: error.message });
- });
+ const messageId = req.body.messageId;
+ RunFunctionAsync(async () => {
+ if (!messageId) {
+ throw new Error('Schema ID in body is empty');
+ }
+ const guardians = new Guardians();
+ await guardians.previewSchemasByMessagesAsync([messageId], taskId);
+ }, async (error) => {
+ new Logger().error(error, ['API_GATEWAY']);
+ taskManager.addError(taskId, { code: 500, message: error.message });
+ });
- res.status(202).send({ taskId, expectation });
-});
+ return res.status(202).send({ taskId, expectation });
+ }
-schemaAPI.post('/import/file/preview', permissionHelper(UserRole.STANDARD_REGISTRY), async (req: AuthenticatedRequest, res: Response, next: NextFunction) => {
- try {
- const zip = req.body;
- if (!zip) {
- return next(createError(422, 'File in body is empty'));
+ @Post('/import/file/preview')
+ @HttpCode(HttpStatus.OK)
+ async importFromFilePreview(@Req() req, @Response() res): Promise {
+ await checkPermission(UserRole.STANDARD_REGISTRY)(req.user);
+ try {
+ const zip = req.body;
+ if (!zip) {
+ throw new HttpException('File in body is empty', HttpStatus.UNPROCESSABLE_ENTITY)
+ }
+ const guardians = new Guardians();
+ const { schemas } = await SchemaUtils.parseZipFile(zip);
+ const schemaToPreview = await guardians.previewSchemasByFile(schemas);
+ return res.json(schemaToPreview);
+ } catch (error) {
+ new Logger().error(error, ['API_GATEWAY']);
+ throw error
}
- const guardians = new Guardians();
- const { schemas } = await SchemaUtils.parseZipFile(zip);
- const schemaToPreview = await guardians.previewSchemasByFile(schemas);
- res.json(schemaToPreview);
- } catch (error) {
- new Logger().error(error, ['API_GATEWAY']);
- return next(error);
- }
-});
-
-schemaAPI.post('/:topicId/import/message',
- [
- validate(schemaSchema()),
- permissionHelper(UserRole.STANDARD_REGISTRY)
- ]
- , async (req: AuthenticatedRequest, res: Response, next: NextFunction) => {
+ }
+
+ @Post('/:topicId/import/message')
+ @HttpCode(HttpStatus.CREATED)
+ async importFromMessage(@Req() req, @Response() res): Promise {
+ await checkPermission(UserRole.STANDARD_REGISTRY)(req.user);
try {
const user = req.user;
const topicId = req.params.topicId;
@@ -424,191 +444,204 @@ schemaAPI.post('/:topicId/import/message',
await guardians.importSchemasByMessages([messageId], req.user.did, topicId);
const { items, count } = await guardians.getSchemasByOwner(user.did);
SchemaHelper.updatePermission(items, user.did);
- res.status(201).setHeader('X-Total-Count', count).json(SchemaUtils.toOld(items));
+ return res.status(201).setHeader('X-Total-Count', count).json(SchemaUtils.toOld(items));
} catch (error) {
new Logger().error(error, ['API_GATEWAY']);
- return next(error);
+ throw error;
}
- });
+ }
-schemaAPI.post('/push/:topicId/import/message', [
- validate(schemaSchema()),
- permissionHelper(UserRole.STANDARD_REGISTRY)
-], async (req: AuthenticatedRequest, res: Response, next: NextFunction) => {
- const taskManager = new TaskManager();
- const { taskId, expectation } = taskManager.start('Import schema message');
+ @Post('/push/:topicId/import/message')
+ @HttpCode(HttpStatus.ACCEPTED)
+ async importFromMessageAsync(@Req() req, @Response() res): Promise {
+ await checkPermission(UserRole.STANDARD_REGISTRY)(req.user);
+ const taskManager = new TaskManager();
+ const { taskId, expectation } = taskManager.start('Import schema message');
- const user = req.user;
- const topicId = req.params.topicId;
- const messageId = req.body.messageId;
- RunFunctionAsync(async () => {
- const guardians = new Guardians();
- await guardians.importSchemasByMessagesAsync([messageId], user.did, topicId, taskId);
- }, async (error) => {
- new Logger().error(error, ['API_GATEWAY']);
- taskManager.addError(taskId, { code: 500, message: error.message });
- });
+ const user = req.user;
+ const topicId = req.params.topicId;
+ const messageId = req.body.messageId;
+ RunFunctionAsync(async () => {
+ const guardians = new Guardians();
+ await guardians.importSchemasByMessagesAsync([messageId], user.did, topicId, taskId);
+ }, async (error) => {
+ new Logger().error(error, ['API_GATEWAY']);
+ taskManager.addError(taskId, { code: 500, message: error.message });
+ });
+
+ return res.status(202).send({ taskId, expectation });
+ }
+
+ @Post('/:topicId/import/file')
+ @HttpCode(HttpStatus.CREATED)
+ async importToTopicFromFile(@Req() req, @Response() res): Promise {
+ await checkPermission(UserRole.STANDARD_REGISTRY)(req.user);
+ try {
+ const user = req.user;
+ const guardians = new Guardians();
+ const zip = req.body;
+ const topicId = req.params.topicId;
+ if (!zip) {
+ throw new HttpException('File in body is empty', HttpStatus.UNPROCESSABLE_ENTITY)
+ }
+ const files = await SchemaUtils.parseZipFile(zip);
+ await guardians.importSchemasByFile(files, req.user.did, topicId);
+ const { items, count } = await guardians.getSchemasByOwner(user.did);
+ SchemaHelper.updatePermission(items, user.did);
+ return res.status(201).setHeader('X-Total-Count', count).json(SchemaUtils.toOld(items));
+ } catch (error) {
+ new Logger().error(error, ['API_GATEWAY']);
+ throw error
+ }
+ }
- res.status(202).send({ taskId, expectation });
-});
+ @Post('/push/:topicId/import/file')
+ @HttpCode(HttpStatus.ACCEPTED)
+ async importToTopicFromFileAsync(@Req() req, @Response() res): Promise {
+ await checkPermission(UserRole.STANDARD_REGISTRY)(req.user);
+ const taskManager = new TaskManager();
+ const { taskId, expectation } = taskManager.start('Import schema file');
-schemaAPI.post('/:topicId/import/file', permissionHelper(UserRole.STANDARD_REGISTRY), async (req: AuthenticatedRequest, res: Response, next: NextFunction) => {
- try {
const user = req.user;
- const guardians = new Guardians();
const zip = req.body;
- const topicId = req.params.topicId;
if (!zip) {
- return next(createError(422, 'File in body is empty'));
+ throw new HttpException('File in body is empty', HttpStatus.UNPROCESSABLE_ENTITY)
}
- const files = await SchemaUtils.parseZipFile(zip);
- await guardians.importSchemasByFile(files, req.user.did, topicId);
- const { items, count } = await guardians.getSchemasByOwner(user.did);
- SchemaHelper.updatePermission(items, user.did);
- res.status(201).setHeader('X-Total-Count', count).json(SchemaUtils.toOld(items));
- } catch (error) {
- new Logger().error(error, ['API_GATEWAY']);
- return next(error);
- }
-});
-
-schemaAPI.post('/push/:topicId/import/file', permissionHelper(UserRole.STANDARD_REGISTRY), async (req: AuthenticatedRequest, res: Response, next: NextFunction) => {
- const taskManager = new TaskManager();
- const { taskId, expectation } = taskManager.start('Import schema file');
-
- const user = req.user;
- const zip = req.body;
- if (!zip) {
- return next(createError(422, 'File in body is empty'));
- }
- const topicId = req.params.topicId;
- RunFunctionAsync(async () => {
- taskManager.addStatus(taskId, 'Parse file', StatusType.PROCESSING);
- const files = await SchemaUtils.parseZipFile(zip);
- taskManager.addStatus(taskId, 'Parse file', StatusType.COMPLETED);
- const guardians = new Guardians();
- await guardians.importSchemasByFileAsync(files, user.did, topicId, taskId);
- }, async (error) => {
- new Logger().error(error, ['API_GATEWAY']);
- taskManager.addError(taskId, { code: 500, message: error.message });
- });
+ const topicId = req.params.topicId;
+ RunFunctionAsync(async () => {
+ taskManager.addStatus(taskId, 'Parse file', StatusType.PROCESSING);
+ const files = await SchemaUtils.parseZipFile(zip);
+ taskManager.addStatus(taskId, 'Parse file', StatusType.COMPLETED);
+ const guardians = new Guardians();
+ await guardians.importSchemasByFileAsync(files, user.did, topicId, taskId);
+ }, async (error) => {
+ new Logger().error(error, ['API_GATEWAY']);
+ taskManager.addError(taskId, { code: 500, message: error.message });
+ });
- res.status(202).send({ taskId, expectation });
-});
+ return res.status(202).send({ taskId, expectation });
+ }
-schemaAPI.get('/:schemaId/export/message', permissionHelper(UserRole.STANDARD_REGISTRY), async (req: Request, res: Response, next: NextFunction) => {
- try {
- const guardians = new Guardians();
- const id = req.params.schemaId;
- const schemas = await guardians.exportSchemas([id]);
- const scheme = schemas[0];
- if (!scheme) {
- return next(createError(422, `Cannot export policy ${req.params.schemaId}`));
+ @Get('/:schemaId/export/message')
+ @HttpCode(HttpStatus.OK)
+ async exportMessage(@Req() req, @Response() res): Promise {
+ await checkPermission(UserRole.STANDARD_REGISTRY)(req.user);
+ try {
+ const guardians = new Guardians();
+ const id = req.params.schemaId;
+ const schemas = await guardians.exportSchemas([id]);
+ const scheme = schemas[0];
+ if (!scheme) {
+ throw new HttpException(`Cannot export schema ${req.params.schemaId}`, HttpStatus.UNPROCESSABLE_ENTITY);
+ }
+ return res.send({
+ id: scheme.id,
+ name: scheme.name,
+ description: scheme.description,
+ version: scheme.version,
+ messageId: scheme.messageId,
+ owner: scheme.owner
+ });
+ } catch (error) {
+ new Logger().error(error, ['API_GATEWAY']);
+ throw error
}
- res.send({
- id: scheme.id,
- name: scheme.name,
- description: scheme.description,
- version: scheme.version,
- messageId: scheme.messageId,
- owner: scheme.owner
- });
- } catch (error) {
- new Logger().error(error, ['API_GATEWAY']);
- return next(error);
}
-});
-schemaAPI.get('/:schemaId/export/file', permissionHelper(UserRole.STANDARD_REGISTRY), async (req: AuthenticatedRequest, res: Response, next: NextFunction) => {
- try {
- const guardians = new Guardians();
- const id = req.params.schemaId;
- const schemas = await guardians.exportSchemas([id]);
- if (!schemas || !schemas.length) {
- return next(createError(422, `Cannot export policy ${req.params.schemaId}`));
- }
- const ids = schemas.map(s => s.id);
- const tags = await guardians.exportTags('Schema', ids);
- const name = `${Date.now()}`;
- const zip = await SchemaUtils.generateZipFile(schemas, tags);
- const arcStream = zip.generateNodeStream({
- type: 'nodebuffer',
- compression: 'DEFLATE',
- compressionOptions: {
- level: 3
+ @Get('/:schemaId/export/file')
+ @HttpCode(HttpStatus.OK)
+ async exportToFile(@Req() req, @Response() res): Promise {
+ await checkPermission(UserRole.STANDARD_REGISTRY)(req.user);
+ try {
+ const guardians = new Guardians();
+ const id = req.params.schemaId;
+ const schemas = await guardians.exportSchemas([id]);
+ if (!schemas || !schemas.length) {
+ throw new HttpException(`Cannot export schema ${req.params.schemaId}`, HttpStatus.UNPROCESSABLE_ENTITY)
}
- });
- res.setHeader('Content-disposition', `attachment; filename=${name}`);
- res.setHeader('Content-type', 'application/zip');
- arcStream.pipe(res);
- } catch (error) {
- new Logger().error(error, ['API_GATEWAY']);
- return next(error);
+ const ids = schemas.map(s => s.id);
+ const tags = await guardians.exportTags('Schema', ids);
+ const name = `${Date.now()}`;
+ const zip = await SchemaUtils.generateZipFile(schemas, tags);
+ const arcStream = zip.generateNodeStream({
+ type: 'nodebuffer',
+ compression: 'DEFLATE',
+ compressionOptions: {
+ level: 3
+ }
+ });
+ res.setHeader('Content-disposition', `attachment; filename=${name}`);
+ res.setHeader('Content-type', 'application/zip');
+ arcStream.pipe(res);
+ return res;
+ } catch (error) {
+ new Logger().error(error, ['API_GATEWAY']);
+ throw error;
+ }
}
-});
-schemaAPI.get('/type/:schemaType', async (req: AuthenticatedRequest, res: Response, next: NextFunction) => {
- try {
- const guardians = new Guardians();
- const schema = await guardians.getSchemaByType(req.params.schemaType);
- if (!schema) {
- return next(createError(404, `Schema not found: ${req.params.schemaType}`));
+ @Get('/type/:schemaType')
+ @HttpCode(HttpStatus.OK)
+ async getSchemaType(@Req() req, @Response() res): Promise {
+ try {
+ const guardians = new Guardians();
+ const schema = await guardians.getSchemaByType(req.params.schemaType);
+ if (!schema) {
+ throw new HttpException( `Schema not found: ${req.params.schemaType}`, HttpStatus.NOT_FOUND);
+ }
+ return res.send({
+ uuid: schema.uuid,
+ iri: schema.iri,
+ name: schema.name,
+ version: schema.version,
+ document: schema.document,
+ documentURL: schema.documentURL,
+ context: schema.context,
+ contextURL: schema.contextURL,
+ });
+ } catch (error) {
+ new Logger().error(error, ['API_GATEWAY']);
+ return error
}
- res.send({
- uuid: schema.uuid,
- iri: schema.iri,
- name: schema.name,
- version: schema.version,
- document: schema.document,
- documentURL: schema.documentURL,
- context: schema.context,
- contextURL: schema.contextURL,
- });
- } catch (error) {
- new Logger().error(error, ['API_GATEWAY']);
- return next(error);
- }
-});
-
-schemaAPI.post('/system/:username', [
- validate(systemEntitySchema()),
- permissionHelper(UserRole.STANDARD_REGISTRY)
-], async (
- req: AuthenticatedRequest, res: Response, next: NextFunction
-) => {
- try {
- const user = req.user;
- const newSchema = req.body;
+ }
- if (newSchema.entity !== SchemaEntity.STANDARD_REGISTRY
- && newSchema.entity !== SchemaEntity.USER) {
- return next(createError(422,
- `Invalid schema types. Entity must be ${SchemaEntity.STANDARD_REGISTRY} or ${SchemaEntity.USER}`
- ));
- }
+ @Post('/system/:username')
+ @HttpCode(HttpStatus.CREATED)
+ async postSystemSchema(@Req() req, @Response() res): Promise {
+ await checkPermission(UserRole.STANDARD_REGISTRY)(req.user);
+ try {
+ const user = req.user;
+ const newSchema = req.body;
- const guardians = new Guardians();
- const owner = user.username;
+ if (newSchema.entity !== SchemaEntity.STANDARD_REGISTRY
+ && newSchema.entity !== SchemaEntity.USER) {
+ throw new HttpException(`Invalid schema types. Entity must be ${SchemaEntity.STANDARD_REGISTRY} or ${SchemaEntity.USER}`, HttpStatus.UNPROCESSABLE_ENTITY)
+ }
- SchemaUtils.fromOld(newSchema);
- delete newSchema.version;
- delete newSchema.id;
- delete newSchema._id;
- delete newSchema.status;
- delete newSchema.topicId;
+ const guardians = new Guardians();
+ const owner = user.username;
- SchemaHelper.updateOwner(newSchema, owner);
- const schema = await guardians.createSystemSchema(newSchema);
+ SchemaUtils.fromOld(newSchema);
+ delete newSchema.version;
+ delete newSchema.id;
+ delete newSchema._id;
+ delete newSchema.status;
+ delete newSchema.topicId;
- res.status(201).json(SchemaUtils.toOld(schema));
- } catch (error) {
- new Logger().error(error, ['API_GATEWAY']);
- return next(error);
+ SchemaHelper.updateOwner(newSchema, owner);
+ const schema = await guardians.createSystemSchema(newSchema);
+
+ return res.status(201).json(SchemaUtils.toOld(schema));
+ } catch (error) {
+ new Logger().error(error, ['API_GATEWAY']);
+ throw error;
+ }
}
-});
-schemaAPI.get('/system/:username', permissionHelper(UserRole.STANDARD_REGISTRY),
- async (req: AuthenticatedRequest, res: Response, next: NextFunction) => {
+ @Get('/system/:username')
+ @HttpCode(HttpStatus.OK)
+ async getSystemSchema(@Req() req, @Response() res): Promise {
+ await checkPermission(UserRole.STANDARD_REGISTRY)(req.user);
try {
const user = req.user;
const guardians = new Guardians();
@@ -621,118 +654,154 @@ schemaAPI.get('/system/:username', permissionHelper(UserRole.STANDARD_REGISTRY),
}
const { items, count } = await guardians.getSystemSchemas(owner, pageIndex, pageSize);
items.forEach((s) => { s.readonly = s.readonly || s.owner !== owner });
- res.setHeader('X-Total-Count', count).json(SchemaUtils.toOld(items));
+ return res.setHeader('X-Total-Count', count).json(SchemaUtils.toOld(items));
} catch (error) {
new Logger().error(error, ['API_GATEWAY']);
- return next(error);
+ throw error;
}
- });
+ }
-schemaAPI.delete('/system/:schemaId', permissionHelper(UserRole.STANDARD_REGISTRY), async (req: AuthenticatedRequest, res: Response, next: NextFunction) => {
- try {
- const user = req.user;
- const guardians = new Guardians();
- const schemaId = req.params.schemaId;
- const schema = await guardians.getSchemaById(schemaId);
- if (!schema) {
- return next(createError(404, 'Schema not found.'));
- }
- const error = SchemaUtils.checkPermission(schema, user, SchemaCategory.SYSTEM);
- if (error) {
- return next(createError(403, error))
- }
- if (schema.active) {
- return next(createError(422, 'Schema is active.'));
+ @Delete('/system/:schemaId')
+ @HttpCode(HttpStatus.NO_CONTENT)
+ async deleteSystemSchema(@Req() req, @Response() res): Promise {
+ await checkPermission(UserRole.STANDARD_REGISTRY)(req.user);
+ try {
+ const user = req.user;
+ const guardians = new Guardians();
+ const schemaId = req.params.schemaId;
+ const schema = await guardians.getSchemaById(schemaId);
+ if (!schema) {
+ throw new HttpException('Schema not found.', HttpStatus.NOT_FOUND)
+ }
+ const error = SchemaUtils.checkPermission(schema, user, SchemaCategory.SYSTEM);
+ if (error) {
+ throw new HttpException(error, HttpStatus.FORBIDDEN);
+ }
+ if (schema.active) {
+ throw new HttpException('Schema is active.', HttpStatus.UNPROCESSABLE_ENTITY);
+ }
+ await guardians.deleteSchema(schemaId);
+ return res.status(204).send();
+ } catch (error) {
+ new Logger().error(error, ['API_GATEWAY']);
+ throw error;
}
- await guardians.deleteSchema(schemaId);
- res.status(204).send();
- } catch (error) {
- new Logger().error(error, ['API_GATEWAY']);
- return next(error);
}
-});
-schemaAPI.put('/system/:schemaId', permissionHelper(UserRole.STANDARD_REGISTRY), async (req: AuthenticatedRequest, res: Response, next: NextFunction) => {
- try {
- const user = req.user;
- const newSchema = req.body;
- const guardians = new Guardians();
- const schema = await guardians.getSchemaById(newSchema.id);
- if (!schema) {
- return next(createError(404, 'Schema not found.'));
- }
- const error = SchemaUtils.checkPermission(schema, user, SchemaCategory.SYSTEM);
- if (error) {
- return next(createError(403, error))
- }
- if (schema.active) {
- return next(createError(422, 'Schema is active.'));
+ @Put('/system/:schemaId')
+ @HttpCode(HttpStatus.OK)
+ async setSystemSchema(@Req() req, @Response() res): Promise {
+ await checkPermission(UserRole.STANDARD_REGISTRY)(req.user);
+ try {
+ const user = req.user;
+ const newSchema = req.body;
+ const guardians = new Guardians();
+ const schema = await guardians.getSchemaById(newSchema.id);
+ if (!schema) {
+ throw new HttpException('Schema not found.', HttpStatus.NOT_FOUND);
+ }
+ const error = SchemaUtils.checkPermission(schema, user, SchemaCategory.SYSTEM);
+ if (error) {
+ throw new HttpException(error, HttpStatus.FORBIDDEN);
+ }
+ if (schema.active) {
+ throw new HttpException('Schema is active.', HttpStatus.UNPROCESSABLE_ENTITY);
+ }
+ SchemaUtils.fromOld(newSchema);
+ const schemas = await updateSchema(newSchema, user.username);
+ return res.json(SchemaUtils.toOld(schemas));
+ } catch (error) {
+ new Logger().error(error, ['API_GATEWAY']);
+ throw error;
}
- SchemaUtils.fromOld(newSchema);
- const schemas = await updateSchema(newSchema, user.username);
- res.json(SchemaUtils.toOld(schemas));
- } catch (error) {
- new Logger().error(error, ['API_GATEWAY']);
- return next(error);
}
-});
-schemaAPI.put('/system/:schemaId/active', permissionHelper(UserRole.STANDARD_REGISTRY), async (req: AuthenticatedRequest, res: Response, next: NextFunction) => {
- try {
- const guardians = new Guardians();
- const schemaId = req.params.schemaId;
- const schema = await guardians.getSchemaById(schemaId);
- if (!schema) {
- return next(createError(404, 'Schema not found.'));
- }
- if (!schema.system) {
- return next(createError(403, 'Schema is not system.'));
- }
- if (schema.active) {
- return next(createError(422, 'Schema is active.'));
+ @Put('/system/:schemaId/active')
+ @HttpCode(HttpStatus.OK)
+ async activeSystemSchema(@Req() req: any): Promise {
+ await checkPermission(UserRole.STANDARD_REGISTRY)(req.user);
+ try {
+ const guardians = new Guardians();
+ const schemaId = req.params.schemaId;
+ const schema = await guardians.getSchemaById(schemaId);
+ if (!schema) {
+ throw new HttpException('Schema not found.', HttpStatus.NOT_FOUND);
+ }
+ if (!schema.system) {
+ throw new HttpException('Schema not found.', HttpStatus.FORBIDDEN);
+ }
+ if (schema.active) {
+ throw new HttpException('Schema is active.', HttpStatus.UNPROCESSABLE_ENTITY);
+ }
+ await guardians.activeSchema(schemaId);
+ return null;
+ } catch (error) {
+ new Logger().error(error, ['API_GATEWAY']);
+ throw error;
}
- await guardians.activeSchema(schemaId);
- return res.json(null);
- } catch (error) {
- new Logger().error(error, ['API_GATEWAY']);
- return next(error);
}
-});
-schemaAPI.get('/system/entity/:schemaEntity', async (req: AuthenticatedRequest, res: Response, next: NextFunction) => {
- try {
- const guardians = new Guardians();
- const schema = await guardians.getSchemaByEntity(req.params.schemaEntity);
- if (!schema) {
- return res.send(null);
+ @Get('/system/entity/:schemaEntity')
+ @HttpCode(HttpStatus.OK)
+ async getSchemaEntity(@Req() req, @Response() res): Promise {
+ try {
+ const guardians = new Guardians();
+ const schema = await guardians.getSchemaByEntity(req.params.schemaEntity);
+ if (!schema) {
+ return res.send(null);
+ }
+ return res.send({
+ uuid: schema.uuid,
+ iri: schema.iri,
+ name: schema.name,
+ version: schema.version,
+ document: schema.document,
+ documentURL: schema.documentURL,
+ context: schema.context,
+ contextURL: schema.contextURL,
+ });
+ } catch (error) {
+ new Logger().error(error, ['API_GATEWAY']);
+ throw error
}
- return res.send({
- uuid: schema.uuid,
- iri: schema.iri,
- name: schema.name,
- version: schema.version,
- document: schema.document,
- documentURL: schema.documentURL,
- context: schema.context,
- contextURL: schema.contextURL,
- });
- } catch (error) {
- new Logger().error(error, ['API_GATEWAY']);
- return next(error);
}
-});
-schemaAPI.get('/list/all', permissionHelper(UserRole.STANDARD_REGISTRY), async (req: AuthenticatedRequest, res: Response, next: NextFunction) => {
- try {
- const user = req.user;
- const guardians = new Guardians();
- if (user.did) {
- const schemas = await guardians.getListSchemas(user.did);
- return res.send(schemas);
+ @Get('/list/all')
+ @HttpCode(HttpStatus.OK)
+ async getAll(@Req() req, @Response() res): Promise {
+ await checkPermission(UserRole.STANDARD_REGISTRY)(req.user);
+ try {
+ const user = req.user;
+ const guardians = new Guardians();
+ if (user.did) {
+ const schemas = await guardians.getListSchemas(user.did);
+ return res.send(schemas);
+ }
+ res.send([]);
+ } catch (error) {
+ new Logger().error(error, ['API_GATEWAY']);
+ throw error;
}
- res.send([]);
- } catch (error) {
- new Logger().error(error, ['API_GATEWAY']);
- return next(error);
}
-});
+}
+
+/**
+ * Prepare the schema pagination
+ *
+ * @param req
+ * @param user
+ */
+function prepareSchemaPagination(req, user) {
+ const guardians = new Guardians();
+ let pageIndex: any;
+ let pageSize: any;
+ if (req.query && req.query.pageIndex && req.query.pageSize) {
+ pageIndex = req.query.pageIndex;
+ pageSize = req.query.pageSize;
+ }
+ let owner = user.parent;
+ if (user.role === UserRole.STANDARD_REGISTRY) {
+ owner = user.did;
+ }
+ return { guardians, pageIndex, pageSize, owner };
+}
diff --git a/api-gateway/src/api/service/settings.ts b/api-gateway/src/api/service/settings.ts
index 5aea93d790..cd58a6454a 100644
--- a/api-gateway/src/api/service/settings.ts
+++ b/api-gateway/src/api/service/settings.ts
@@ -1,56 +1,60 @@
-import { permissionHelper } from '@auth/authorization-helper';
import { Guardians } from '@helpers/guardians';
-import { Request, Response, Router, NextFunction } from 'express';
import { CommonSettings, UserRole } from '@guardian/interfaces';
import { Logger } from '@guardian/common';
-import validate, { prepareValidationResponse } from '@middlewares/validation';
-import { updateSettings } from '@middlewares/validation/schemas/settings';
+import { prepareValidationResponse } from '@middlewares/validation';
+import { Controller, Get, HttpCode, HttpStatus, Post, Req, Response } from '@nestjs/common';
+import { checkPermission } from '@auth/authorization-helper';
-/**
- * Settings route
- */
-export const settingsAPI = Router();
-
-settingsAPI.post('/', validate(updateSettings()), permissionHelper(UserRole.STANDARD_REGISTRY),
- async (req: Request, res: Response, next: NextFunction) => {
- try {
- const settings = req.body as CommonSettings;
- if (!settings || Object.keys(settings).length === 0) {
- return res.status(422).json(prepareValidationResponse('Invalid settings'));
+@Controller('settings')
+export class SettingsApi {
+ @Post('/')
+ @HttpCode(HttpStatus.CREATED)
+ async updateSettings(@Req() req, @Response() res): Promise {
+ await checkPermission(UserRole.STANDARD_REGISTRY)(req.user);
+ try {
+ const settings = req.body as CommonSettings;
+ if (!settings || Object.keys(settings).length === 0) {
+ return res.status(422).json(prepareValidationResponse('Invalid settings'));
+ }
+ const guardians = new Guardians();
+ await Promise.all([
+ guardians.updateSettings(settings)
+ ]);
+ return res.status(201).json(null);
+ } catch (error) {
+ new Logger().error(error, ['API_GATEWAY']);
+ throw error
}
- const guardians = new Guardians();
- await Promise.all([
- guardians.updateSettings(settings)
- ]);
- res.json(null);
- } catch (error) {
- new Logger().error(error, ['API_GATEWAY']);
- return next(error);
}
-});
-settingsAPI.get('/', permissionHelper(UserRole.STANDARD_REGISTRY), async (req: Request, res: Response, next: NextFunction) => {
- try {
- const guardians = new Guardians();
- const [guardiansSettings] = await Promise.all([
- guardians.getSettings()
- ]);
- res.json({
- ...guardiansSettings
- });
- } catch (error) {
- new Logger().error(error, ['API_GATEWAY']);
- return next(error);
+ @Get('/')
+ @HttpCode(HttpStatus.OK)
+ async getSettings(@Req() req, @Response() res): Promise {
+ await checkPermission(UserRole.STANDARD_REGISTRY)(req.user);
+ try {
+ const guardians = new Guardians();
+ const [guardiansSettings] = await Promise.all([
+ guardians.getSettings()
+ ]);
+ res.json({
+ ...guardiansSettings
+ });
+ } catch (error) {
+ new Logger().error(error, ['API_GATEWAY']);
+ throw error;
+ }
}
-});
-settingsAPI.get('/environment', async (req: Request, res: Response, next: NextFunction) => {
- try {
- const guardians = new Guardians();
- const environment = await guardians.getEnvironment();
- res.send(environment);
- } catch (error) {
- new Logger().error(error, ['API_GATEWAY']);
- return next(error);
+ @Get('/environment')
+ @HttpCode(HttpStatus.OK)
+ async getEnvironment(@Req() req, @Response() res): Promise {
+ try {
+ const guardians = new Guardians();
+ const environment = await guardians.getEnvironment();
+ return res.send(environment);
+ } catch (error) {
+ new Logger().error(error, ['API_GATEWAY']);
+ throw error;
+ }
}
-})
+}
diff --git a/api-gateway/src/api/service/tags.ts b/api-gateway/src/api/service/tags.ts
index 65136de628..fb738cafb5 100644
--- a/api-gateway/src/api/service/tags.ts
+++ b/api-gateway/src/api/service/tags.ts
@@ -1,238 +1,262 @@
-import { Response, Router, NextFunction } from 'express';
-import { AuthenticatedRequest, Logger } from '@guardian/common';
+import { Logger } from '@guardian/common';
import { Guardians } from '@helpers/guardians';
-import { permissionHelper } from '@auth/authorization-helper';
import { SchemaCategory, SchemaHelper, UserRole } from '@guardian/interfaces';
import { SchemaUtils } from '@helpers/schema-utils';
-import createError from 'http-errors';
-
-/**
- * Tags route
- */
-export const tagsAPI = Router();
-
-tagsAPI.post('/', async (req: AuthenticatedRequest, res: Response, next: NextFunction) => {
- try {
- const guardian = new Guardians();
- const item = await guardian.createTag(req.body, req.user.did);
- res.status(201).json(item);
- } catch (error) {
- await (new Logger()).error(error, ['API_GATEWAY']);
- return next(error);
- }
-});
-
-tagsAPI.post('/search', async (req: AuthenticatedRequest, res: Response, next: NextFunction) => {
- try {
- const guardians = new Guardians();
- const { entity, target, targets } = req.body;
- let _targets: string[];
- if (!entity) {
- return next(createError(422, 'Invalid entity'));
+import { Controller, Delete, Get, HttpCode, HttpException, HttpStatus, Post, Put, Req, Response } from '@nestjs/common';
+import { checkPermission } from '@auth/authorization-helper';
+
+@Controller('tags')
+export class TagsApi {
+ @Post('/')
+ @HttpCode(HttpStatus.CREATED)
+ async setTags(@Req() req, @Response() res): Promise {
+ try {
+ const guardian = new Guardians();
+ const item = await guardian.createTag(req.body, req.user.did);
+ return res.status(201).json(item);
+ } catch (error) {
+ await (new Logger()).error(error, ['API_GATEWAY']);
+ throw error
}
- if (target) {
- if (typeof target !== 'string') {
- return next(createError(422, 'Invalid target'));
- } else {
- _targets = [target];
+ }
+
+ @Post('/search')
+ @HttpCode(HttpStatus.OK)
+ async searchTags(@Req() req, @Response() res): Promise {
+ try {
+ const guardians = new Guardians();
+ const { entity, target, targets } = req.body;
+ let _targets: string[];
+ if (!entity) {
+ throw new HttpException('Invalid entity', HttpStatus.UNPROCESSABLE_ENTITY)
}
- } else if (targets) {
- if (!Array.isArray(targets)) {
- return next(createError(422, 'Invalid target'));
+ if (target) {
+ if (typeof target !== 'string') {
+ throw new HttpException('Invalid target', HttpStatus.UNPROCESSABLE_ENTITY)
+ } else {
+ _targets = [target];
+ }
+ } else if (targets) {
+ if (!Array.isArray(targets)) {
+ throw new HttpException('Invalid target', HttpStatus.UNPROCESSABLE_ENTITY)
+ } else {
+ _targets = targets;
+ }
} else {
- _targets = targets;
+ throw new HttpException('Invalid target', HttpStatus.UNPROCESSABLE_ENTITY)
}
- } else {
- return next(createError(422, 'Invalid target'));
- }
- const items = await guardians.getTags(entity, _targets);
- const dates = await guardians.getTagCache(entity, _targets);
+ const items = await guardians.getTags(entity, _targets);
+ const dates = await guardians.getTagCache(entity, _targets);
- const dateMap = {};
- for (const date of dates) {
- dateMap[date.localTarget] = date.date;
- }
+ const dateMap = {};
+ for (const date of dates) {
+ dateMap[date.localTarget] = date.date;
+ }
- const tagMap = {};
- for (const tag of items) {
- if (tagMap[tag.localTarget]) {
- tagMap[tag.localTarget].tags.push(tag);
- } else {
- tagMap[tag.localTarget] = {
- entity,
- refreshDate: dateMap[tag.localTarget],
- target: tag.localTarget,
- tags: [tag]
+ const tagMap = {};
+ for (const tag of items) {
+ if (tagMap[tag.localTarget]) {
+ tagMap[tag.localTarget].tags.push(tag);
+ } else {
+ tagMap[tag.localTarget] = {
+ entity,
+ refreshDate: dateMap[tag.localTarget],
+ target: tag.localTarget,
+ tags: [tag]
+ }
}
}
+ return res.json(tagMap);
+ } catch (error) {
+ await (new Logger()).error(error, ['API_GATEWAY']);
+ throw error
}
- return res.json(tagMap);
- } catch (error) {
- await (new Logger()).error(error, ['API_GATEWAY']);
- return next(error);
}
-});
-tagsAPI.delete('/:uuid', async (req: AuthenticatedRequest, res: Response, next: NextFunction) => {
- try {
- const guardian = new Guardians();
- if (!req.params.uuid) {
- return next(createError(422, 'Invalid uuid'));
+ @Delete('/:uuid')
+ @HttpCode(HttpStatus.OK)
+ async deleteTag(@Req() req, @Response() res): Promise {
+ try {
+ const guardian = new Guardians();
+ if (!req.params.uuid) {
+ throw new HttpException('Invalid uuid', HttpStatus.UNPROCESSABLE_ENTITY)
+ }
+ const result = await guardian.deleteTag(req.params.uuid, req.user.did);
+ return res.json(result);
+ } catch (error) {
+ await (new Logger()).error(error, ['API_GATEWAY']);
+ throw error;
+ // return next(error);
}
- const result = await guardian.deleteTag(req.params.uuid, req.user.did);
- res.json(result);
- } catch (error) {
- await (new Logger()).error(error, ['API_GATEWAY']);
- return next(error);
}
-});
-tagsAPI.post('/synchronization', async (req: AuthenticatedRequest, res: Response, next: NextFunction) => {
- try {
- const guardians = new Guardians();
- const { entity, target } = req.body;
+ @Post('/synchronization')
+ @HttpCode(HttpStatus.OK)
+ async synchronizationTags(@Req() req, @Response() res): Promise {
+ try {
+ const guardians = new Guardians();
+ const { entity, target } = req.body;
- if (!entity) {
- return next(createError(422, 'Invalid entity'));
- }
+ if (!entity) {
+ throw new HttpException('Invalid entity', HttpStatus.UNPROCESSABLE_ENTITY)
+ }
- if (typeof target !== 'string') {
- return next(createError(422, 'Invalid target'));
- }
+ if (typeof target !== 'string') {
+ throw new HttpException('Invalid target', HttpStatus.UNPROCESSABLE_ENTITY)
+ }
- const tags = await guardians.synchronizationTags(entity, target);
+ const tags = await guardians.synchronizationTags(entity, target);
- const result = {
- entity,
- target,
- tags,
- refreshDate: (new Date()).toISOString(),
+ const result = {
+ entity,
+ target,
+ tags,
+ refreshDate: (new Date()).toISOString(),
+ }
+ return res.json(result);
+ } catch (error) {
+ await (new Logger()).error(error, ['API_GATEWAY']);
+ throw error
}
- return res.json(result);
- } catch (error) {
- await (new Logger()).error(error, ['API_GATEWAY']);
- return next(error);
}
-});
-
-tagsAPI.get('/schemas', permissionHelper(UserRole.STANDARD_REGISTRY), async (req: AuthenticatedRequest, res: Response, next: NextFunction) => {
- try {
- const user = req.user;
- const guardians = new Guardians();
- const owner = user.did;
- let pageIndex: any;
- let pageSize: any;
- if (req.query && req.query.pageIndex && req.query.pageSize) {
- pageIndex = req.query.pageIndex;
- pageSize = req.query.pageSize;
+
+ @Get('/schemas')
+ @HttpCode(HttpStatus.OK)
+ async getSchemas(@Req() req, @Response() res): Promise {
+ await checkPermission(UserRole.STANDARD_REGISTRY)(req.user);
+ try {
+ const user = req.user;
+ const guardians = new Guardians();
+ const owner = user.did;
+ let pageIndex: any;
+ let pageSize: any;
+ if (req.query && req.query.pageIndex && req.query.pageSize) {
+ pageIndex = req.query.pageIndex;
+ pageSize = req.query.pageSize;
+ }
+ const { items, count } = await guardians.getTagSchemas(owner, pageIndex, pageSize);
+ items.forEach((s) => { s.readonly = s.readonly || s.owner !== owner });
+ return res
+ .setHeader('X-Total-Count', count)
+ .json(SchemaUtils.toOld(items));
+ } catch (error) {
+ await (new Logger()).error(error, ['API_GATEWAY']);
+ throw error;
}
- const { items, count } = await guardians.getTagSchemas(owner, pageIndex, pageSize);
- items.forEach((s) => { s.readonly = s.readonly || s.owner !== owner });
- return res
- .setHeader('X-Total-Count', count)
- .json(SchemaUtils.toOld(items));
- } catch (error) {
- await (new Logger()).error(error, ['API_GATEWAY']);
- return next(error);
}
-});
-tagsAPI.post('/schemas', permissionHelper(UserRole.STANDARD_REGISTRY), async (req: AuthenticatedRequest, res: Response, next: NextFunction) => {
- try {
- const user = req.user;
- const newSchema = req.body;
+ @Post('/schemas')
+ @HttpCode(HttpStatus.CREATED)
+ async postSchemas(@Req() req, @Response() res): Promise {
+ await checkPermission(UserRole.STANDARD_REGISTRY)(req.user);
+ try {
+ const user = req.user;
+ const newSchema = req.body;
- if (!newSchema) {
- return next(createError(422, 'Schema does not exist.'));
- }
+ if (!newSchema) {
+ throw new HttpException('Schema does not exist.', HttpStatus.UNPROCESSABLE_ENTITY)
+ }
- const guardians = new Guardians();
- const owner = user.did;
+ const guardians = new Guardians();
+ const owner = user.did;
- SchemaUtils.fromOld(newSchema);
- delete newSchema.version;
- delete newSchema.id;
- delete newSchema._id;
- delete newSchema.status;
- delete newSchema.topicId;
+ SchemaUtils.fromOld(newSchema);
+ delete newSchema.version;
+ delete newSchema.id;
+ delete newSchema._id;
+ delete newSchema.status;
+ delete newSchema.topicId;
- SchemaHelper.updateOwner(newSchema, owner);
- const schema = await guardians.createTagSchema(newSchema);
+ SchemaHelper.updateOwner(newSchema, owner);
+ const schema = await guardians.createTagSchema(newSchema);
- res.status(201).json(SchemaUtils.toOld(schema));
- } catch (error) {
- await (new Logger()).error(error, ['API_GATEWAY']);
- return next(error);
+ return res.status(201).json(SchemaUtils.toOld(schema));
+ } catch (error) {
+ await (new Logger()).error(error, ['API_GATEWAY']);
+ throw error;
+ }
}
-});
-
-tagsAPI.delete('/schemas/:schemaId', permissionHelper(UserRole.STANDARD_REGISTRY), async (req: AuthenticatedRequest, res: Response, next: NextFunction) => {
- try {
- const user = req.user;
- const guardians = new Guardians();
- const schemaId = req.params.schemaId;
- const schema = await guardians.getSchemaById(schemaId);
- const error = SchemaUtils.checkPermission(schema, user, SchemaCategory.TAG);
- if (error) {
- return next(createError(403, error));
+
+ @Delete('/schemas/:schemaId')
+ @HttpCode(HttpStatus.OK)
+ async deleteSchema(@Req() req, @Response() res): Promise {
+ await checkPermission(UserRole.STANDARD_REGISTRY)(req.user);
+ try {
+ const user = req.user;
+ const guardians = new Guardians();
+ const schemaId = req.params.schemaId;
+ const schema = await guardians.getSchemaById(schemaId);
+ const error = SchemaUtils.checkPermission(schema, user, SchemaCategory.TAG);
+ if (error) {
+ throw new HttpException('error', HttpStatus.FORBIDDEN)
+ }
+ await guardians.deleteSchema(schemaId);
+ return res.json(true);
+ } catch (error) {
+ await (new Logger()).error(error, ['API_GATEWAY']);
+ throw error;
}
- await guardians.deleteSchema(schemaId);
- return res.json(true);
- } catch (error) {
- await (new Logger()).error(error, ['API_GATEWAY']);
- return next(error);
}
-});
-
-tagsAPI.put('/schemas/:schemaId', permissionHelper(UserRole.STANDARD_REGISTRY), async (req: AuthenticatedRequest, res: Response, next: NextFunction) => {
- try {
- const user = req.user;
- const newSchema = req.body;
- const owner = user.did;
- const guardians = new Guardians();
- const schema = await guardians.getSchemaById(newSchema.id);
- const error = SchemaUtils.checkPermission(schema, user, SchemaCategory.TAG);
- if (error) {
- return next(createError(403, error));
+
+ @Put('/schemas/:schemaId')
+ @HttpCode(HttpStatus.OK)
+ async setTag(@Req() req, @Response() res): Promise {
+ await checkPermission(UserRole.STANDARD_REGISTRY)(req.user);
+ try {
+ const user = req.user;
+ const newSchema = req.body;
+ const owner = user.did;
+ const guardians = new Guardians();
+ const schema = await guardians.getSchemaById(newSchema.id);
+ const error = SchemaUtils.checkPermission(schema, user, SchemaCategory.TAG);
+ if (error) {
+ throw new HttpException('error', HttpStatus.FORBIDDEN)
+ }
+ SchemaUtils.fromOld(newSchema);
+ SchemaHelper.checkSchemaKey(newSchema);
+ SchemaHelper.updateOwner(newSchema, owner);
+ await guardians.updateSchema(newSchema);
+ return res.json(newSchema);
+ } catch (error) {
+ await (new Logger()).error(error, ['API_GATEWAY']);
+ // return next(error);
+ throw error;
}
- SchemaUtils.fromOld(newSchema);
- SchemaHelper.checkSchemaKey(newSchema);
- SchemaHelper.updateOwner(newSchema, owner);
- await guardians.updateSchema(newSchema);
- return res.json(newSchema);
- } catch (error) {
- await (new Logger()).error(error, ['API_GATEWAY']);
- return next(error);
}
-});
-
-tagsAPI.put('/schemas/:schemaId/publish', permissionHelper(UserRole.STANDARD_REGISTRY), async (req: AuthenticatedRequest, res: Response, next: NextFunction) => {
- try {
- const user = req.user;
- const guardians = new Guardians();
- const schemaId = req.params.schemaId;
- const schema = await guardians.getSchemaById(schemaId);
- const version = '1.0.0';
- const error = SchemaUtils.checkPermission(schema, user, SchemaCategory.TAG);
- if (error) {
- return next(createError(403, error));
+
+ @Put('/schemas/:schemaId/publish')
+ @HttpCode(HttpStatus.OK)
+ async publishTag(@Req() req, @Response() res): Promise {
+ await checkPermission(UserRole.STANDARD_REGISTRY)(req.user);
+ try {
+ const user = req.user;
+ const guardians = new Guardians();
+ const schemaId = req.params.schemaId;
+ const schema = await guardians.getSchemaById(schemaId);
+ const version = '1.0.0';
+ const error = SchemaUtils.checkPermission(schema, user, SchemaCategory.TAG);
+ if (error) {
+ throw new HttpException('error', HttpStatus.FORBIDDEN)
+ }
+ const result = await guardians.publishTagSchema(schemaId, version, user.did);
+ return res.json(result);
+ } catch (error) {
+ await (new Logger()).error(error, ['API_GATEWAY']);
+ throw error;
}
- const result = await guardians.publishTagSchema(schemaId, version, user.did);
- return res.json(result);
- } catch (error) {
- await (new Logger()).error(error, ['API_GATEWAY']);
- return next(error);
}
-});
-
-tagsAPI.get('/schemas/published', async (req: AuthenticatedRequest, res: Response, next: NextFunction) => {
- try {
- const guardians = new Guardians();
- const schemas = await guardians.getPublishedTagSchemas();
- return res.send(schemas);
- } catch (error) {
- await (new Logger()).error(error, ['API_GATEWAY']);
- return next(error);
+
+ @Get('/schemas/published')
+ @HttpCode(HttpStatus.OK)
+ async getPublished(@Req() req, @Response() res): Promise {
+ try {
+ const guardians = new Guardians();
+ const schemas = await guardians.getPublishedTagSchemas();
+ return res.send(schemas);
+ } catch (error) {
+ await (new Logger()).error(error, ['API_GATEWAY']);
+ throw error;
+ }
}
-});
+}
diff --git a/api-gateway/src/api/service/task.ts b/api-gateway/src/api/service/task.ts
index c5f9682688..2a570f61b7 100644
--- a/api-gateway/src/api/service/task.ts
+++ b/api-gateway/src/api/service/task.ts
@@ -1,17 +1,20 @@
-import { Response, Router, NextFunction } from 'express';
-import { AuthenticatedRequest, Logger } from '@guardian/common';
+import { Logger } from '@guardian/common';
import { TaskManager } from '@helpers/task-manager';
+import { Controller, Get, HttpCode, HttpStatus, Req, Response } from '@nestjs/common';
-export const taskAPI = Router();
-
-taskAPI.get('/:taskId', async (req: AuthenticatedRequest, res: Response, next: NextFunction) => {
- const taskManager = new TaskManager();
- try {
- const taskId = req.params.taskId;
- const taskState = taskManager.getState(taskId);
- return res.json(taskState);
- } catch (error) {
- new Logger().error(error, ['API_GATEWAY']);
- return next(error);
+@Controller('tasks')
+export class TaskApi {
+ @Get('/:taskId')
+ @HttpCode(HttpStatus.OK)
+ async getTask(@Req() req, @Response() res): Promise {
+ const taskManager = new TaskManager();
+ try {
+ const taskId = req.params.taskId;
+ const taskState = taskManager.getState(taskId);
+ return res.json(taskState);
+ } catch (error) {
+ new Logger().error(error, ['API_GATEWAY']);
+ throw error;
+ }
}
-});
+}
diff --git a/api-gateway/src/api/service/themes.ts b/api-gateway/src/api/service/themes.ts
index b8b77d2754..9cb5173d3f 100644
--- a/api-gateway/src/api/service/themes.ts
+++ b/api-gateway/src/api/service/themes.ts
@@ -1,111 +1,102 @@
-import { Response, Router, NextFunction } from 'express';
-import { AuthenticatedRequest, Logger } from '@guardian/common';
+import { Logger } from '@guardian/common';
import { Guardians } from '@helpers/guardians';
-import createError from 'http-errors';
+import { Controller, Delete, Get, HttpCode, HttpException, HttpStatus, Post, Put, Req, Response } from '@nestjs/common';
-/**
- * Theme route
- */
-export const themesAPI = Router();
-
-/**
- * Create Theme
- */
-themesAPI.post('/', async (req: AuthenticatedRequest, res: Response, next: NextFunction) => {
- try {
- const guardians = new Guardians();
- const item = await guardians.createTheme(req.body, req.user.did);
- return res.status(201).json(item);
- } catch (error) {
- await (new Logger()).error(error, ['API_GATEWAY']);
- return next(error);
+@Controller('themes')
+export class ThemesApi {
+ @Post('/')
+ @HttpCode(HttpStatus.CREATED)
+ async setThemes(@Req() req, @Response() res): Promise {
+ try {
+ const guardians = new Guardians();
+ const item = await guardians.createTheme(req.body, req.user.did);
+ return res.status(201).json(item);
+ } catch (error) {
+ await (new Logger()).error(error, ['API_GATEWAY']);
+ throw error;
+ }
}
-});
-/**
- * Update Theme
- */
-themesAPI.put('/:themeId', async (req: AuthenticatedRequest, res: Response, next: NextFunction) => {
- try {
- const user = req.user;
- const newTheme = req.body;
- const guardians = new Guardians();
- if (!req.params.themeId) {
- return next(createError(422, 'Invalid theme id'));
- }
- const oldTheme = await guardians.getThemeById(req.params.themeId);
- if (!oldTheme) {
- return next(createError(404, 'Theme not found.'));
+ @Put('/:themeId')
+ @HttpCode(HttpStatus.OK)
+ async updateTheme(@Req() req, @Response() res): Promise {
+ try {
+ const user = req.user;
+ const newTheme = req.body;
+ const guardians = new Guardians();
+ if (!req.params.themeId) {
+ throw new HttpException('Invalid theme id', HttpStatus.UNPROCESSABLE_ENTITY)
+ }
+ const oldTheme = await guardians.getThemeById(req.params.themeId);
+ if (!oldTheme) {
+ throw new HttpException('Theme not found.', HttpStatus.NOT_FOUND)
+ }
+ const theme = await guardians.updateTheme(req.params.themeId, newTheme, user.did);
+ return res.json(theme);
+ } catch (error) {
+ new Logger().error(error, ['API_GATEWAY']);
+ throw error;
}
- const theme = await guardians.updateTheme(req.params.themeId, newTheme, user.did);
- return res.json(theme);
- } catch (error) {
- new Logger().error(error, ['API_GATEWAY']);
- return next(error);
}
-});
-/**
- * Delete Theme
- */
-themesAPI.delete('/:themeId', async (req: AuthenticatedRequest, res: Response, next: NextFunction) => {
- try {
- const guardians = new Guardians();
- if (!req.params.themeId) {
- return next(createError(422, 'Invalid theme id'));
+ @Delete('/:themeId')
+ @HttpCode(HttpStatus.OK)
+ async deleteTheme(@Req() req, @Response() res): Promise {
+ try {
+ const guardians = new Guardians();
+ if (!req.params.themeId) {
+ throw new HttpException('Invalid theme id', HttpStatus.UNPROCESSABLE_ENTITY)
+ }
+ const result = await guardians.deleteTheme(req.params.themeId, req.user.did);
+ return res.json(result);
+ } catch (error) {
+ await (new Logger()).error(error, ['API_GATEWAY']);
+ throw error;
}
- const result = await guardians.deleteTheme(req.params.themeId, req.user.did);
- return res.json(result);
- } catch (error) {
- await (new Logger()).error(error, ['API_GATEWAY']);
- return next(error);
}
-});
-/**
- * Get Themes
- */
-themesAPI.get('/', async (req: AuthenticatedRequest, res: Response, next: NextFunction) => {
- try {
- const user = req.user;
- const guardians = new Guardians();
- if (user.did) {
- const themes = await guardians.getThemes(user.did);
- return res.send(themes);
+ @Get('/')
+ @HttpCode(HttpStatus.OK)
+ async getThemes(@Req() req, @Response() res): Promise {
+ try {
+ const user = req.user;
+ const guardians = new Guardians();
+ if (user.did) {
+ const themes = await guardians.getThemes(user.did);
+ return res.send(themes);
+ }
+ return res.send([]);
+ } catch (error) {
+ new Logger().error(error, ['API_GATEWAY']);
+ throw error
}
- return res.send([]);
- } catch (error) {
- new Logger().error(error, ['API_GATEWAY']);
- return next(error);
}
-});
-/**
- * Import Theme
- */
-themesAPI.post('/import/file', async (req: AuthenticatedRequest, res: Response, next: NextFunction) => {
- const guardian = new Guardians();
- try {
- const theme = await guardian.importThemeFile(req.body, req.user.did);
- return res.status(201).send(theme);
- } catch (error) {
- new Logger().error(error, ['API_GATEWAY']);
- return next(error);
+ @Post('/import/file')
+ @HttpCode(HttpStatus.CREATED)
+ async importTheme(@Req() req, @Response() res): Promise {
+ const guardian = new Guardians();
+ try {
+ const theme = await guardian.importThemeFile(req.body, req.user.did);
+ return res.status(201).send(theme);
+ } catch (error) {
+ new Logger().error(error, ['API_GATEWAY']);
+ throw error;
+ }
}
-});
-/**
- * Export Theme
- */
-themesAPI.get('/:themeId/export/file', async (req: AuthenticatedRequest, res: Response, next: NextFunction) => {
- const guardian = new Guardians();
- try {
- const file: any = await guardian.exportThemeFile(req.params.themeId, req.user.did);
- res.setHeader('Content-disposition', `attachment; filename=theme_${Date.now()}`);
- res.setHeader('Content-type', 'application/zip');
- return res.send(file);
- } catch (error) {
- new Logger().error(error, ['API_GATEWAY']);
- return next(error);
+ @Get('/:themeId/export/file')
+ @HttpCode(HttpStatus.OK)
+ async exportTheme(@Req() req, @Response() res): Promise {
+ const guardian = new Guardians();
+ try {
+ const file: any = await guardian.exportThemeFile(req.params.themeId, req.user.did);
+ res.setHeader('Content-disposition', `attachment; filename=theme_${Date.now()}`);
+ res.setHeader('Content-type', 'application/zip');
+ return res.send(file);
+ } catch (error) {
+ new Logger().error(error, ['API_GATEWAY']);
+ throw error;
+ }
}
-});
\ No newline at end of file
+}
diff --git a/api-gateway/src/api/service/tokens.ts b/api-gateway/src/api/service/tokens.ts
index ccf20a0cda..0cc7bb9912 100644
--- a/api-gateway/src/api/service/tokens.ts
+++ b/api-gateway/src/api/service/tokens.ts
@@ -1,18 +1,17 @@
import { Guardians } from '@helpers/guardians';
-import { permissionHelper } from '@auth/authorization-helper';
-import { Response, Router, NextFunction } from 'express';
import { IToken, ITokenInfo, UserRole } from '@guardian/interfaces';
-import { AuthenticatedRequest, Logger, RunFunctionAsync } from '@guardian/common';
+import { Logger, RunFunctionAsync } from '@guardian/common';
import { PolicyEngine } from '@helpers/policy-engine';
import { TaskManager } from '@helpers/task-manager';
import { ServiceError } from '@helpers/service-requests-base';
-import createError from 'http-errors';
import { prepareValidationResponse } from '@middlewares/validation';
+import { Controller, Delete, Get, HttpCode, HttpException, HttpStatus, Post, Put, Req, Response } from '@nestjs/common';
+import { checkPermission } from '@auth/authorization-helper';
/**
* Token route
*/
-export const tokenAPI = Router();
+// export const tokenAPI = Router();
/**
* Connect policies to tokens
@@ -69,536 +68,625 @@ async function setDynamicTokenPolicy(tokens: any[], engineService?: PolicyEngine
return tokens;
}
-tokenAPI.get('/', permissionHelper(UserRole.STANDARD_REGISTRY, UserRole.USER),
- async (req: AuthenticatedRequest, res: Response, next: NextFunction) => {
- try {
- const guardians = new Guardians();
- const engineService = new PolicyEngine();
+@Controller('tokens')
+export class TokensApi {
+ @Get('/')
+ @HttpCode(HttpStatus.OK)
+ async getTokens(@Req() req, @Response() res): Promise {
+ await checkPermission(UserRole.STANDARD_REGISTRY, UserRole.USER)(req.user);
+ try {
+ const guardians = new Guardians();
+ const engineService = new PolicyEngine();
+
+ const user = req.user;
+ const policyId = req.query?.policy;
+
+ let tokens: IToken[] = [];
+ if (user.role === UserRole.STANDARD_REGISTRY) {
+ tokens = await guardians.getTokens({ did: user.did });
+ const map = await engineService.getTokensMap(user.did);
+ tokens = await setDynamicTokenPolicy(tokens, engineService);
+ tokens = setTokensPolicies(tokens, map, policyId, false);
+ } else if (user.did) {
+ tokens = await guardians.getAssociatedTokens(user.did);
+ const map = await engineService.getTokensMap(user.parent, 'PUBLISH');
+ tokens = await setDynamicTokenPolicy(tokens, engineService);
+ tokens = setTokensPolicies(tokens, map, policyId, true);
+ }
+ return res.json(tokens);
+ } catch (error) {
+ new Logger().error(error, ['API_GATEWAY']);
+ throw error;
+ }
+ }
- const user = req.user;
- const policyId = req.query?.policy;
+ @Post('/')
+ @HttpCode(HttpStatus.CREATED)
+ async newToken(@Req() req, @Response() res): Promise {
+ await checkPermission(UserRole.STANDARD_REGISTRY)(req.user);
+ try {
+ const guardians = new Guardians();
+ const engineService = new PolicyEngine();
+ const user = req.user;
+
+ if (!user.did) {
+ return res.status(422).json(prepareValidationResponse('User not registered'));
+ }
+
+ let tokens = await guardians.setToken({
+ token: req.body,
+ owner: user.did
+ });
- let tokens: IToken[] = [];
- if (user.role === UserRole.STANDARD_REGISTRY) {
tokens = await guardians.getTokens({ did: user.did });
const map = await engineService.getTokensMap(user.did);
- tokens = await setDynamicTokenPolicy(tokens, engineService);
- tokens = setTokensPolicies(tokens, map, policyId, false);
- } else if (user.did) {
- tokens = await guardians.getAssociatedTokens(user.did);
- const map = await engineService.getTokensMap(user.parent, 'PUBLISH');
- tokens = await setDynamicTokenPolicy(tokens, engineService);
- tokens = setTokensPolicies(tokens, map, policyId, true);
+ tokens = setTokensPolicies(tokens, map);
+
+ return res.status(201).json(tokens);
+ } catch (error) {
+ new Logger().error(error, ['API_GATEWAY']);
+ throw error;
}
- return res.json(tokens);
- } catch (error) {
- new Logger().error(error, ['API_GATEWAY']);
- return next(error);
}
-});
-tokenAPI.post('/', permissionHelper(UserRole.STANDARD_REGISTRY), async (req: AuthenticatedRequest, res: Response, next: NextFunction) => {
- try {
- const guardians = new Guardians();
- const engineService = new PolicyEngine();
+ @Post('/push')
+ @HttpCode(HttpStatus.ACCEPTED)
+ async pushTokenAsync(@Req() req, @Response() res): Promise {
+ await checkPermission(UserRole.STANDARD_REGISTRY)(req.user);
+ const taskManager = new TaskManager();
+ const { taskId, expectation } = taskManager.start('Create token');
const user = req.user;
-
if (!user.did) {
return res.status(422).json(prepareValidationResponse('User not registered'));
}
- let tokens = (await guardians.setToken({
- token: req.body,
- owner: user.did
- }));
-
- tokens = await guardians.getTokens({ did: user.did });
- const map = await engineService.getTokensMap(user.did);
- tokens = setTokensPolicies(tokens, map);
+ const token = req.body;
+ RunFunctionAsync(async () => {
+ const guardians = new Guardians();
+ await guardians.setTokenAsync(token, user.did, taskId);
+ }, async (error) => {
+ new Logger().error(error, ['API_GATEWAY']);
+ taskManager.addError(taskId, { code: error.code || 500, message: error.message });
+ });
- return res.status(201).json(tokens);
- } catch (error) {
- new Logger().error(error, ['API_GATEWAY']);
- return next(error);
- }
-});
-
-tokenAPI.post('/push/', permissionHelper(UserRole.STANDARD_REGISTRY), async (req: AuthenticatedRequest, res: Response, next: NextFunction) => {
- const taskManager = new TaskManager();
- const { taskId, expectation } = taskManager.start('Create token');
- const user = req.user;
- if (!user.did) {
- return res.status(422).json(prepareValidationResponse('User not registered'));
+ return res.status(202).send({ taskId, expectation });
}
- const token = req.body;
- RunFunctionAsync(async () => {
- const guardians = new Guardians();
- await guardians.setTokenAsync(token, user.did, taskId);
- }, async (error) => {
- new Logger().error(error, ['API_GATEWAY']);
- taskManager.addError(taskId, { code: error.code || 500, message: error.message });
- });
+ @Put('/push')
+ @HttpCode(HttpStatus.ACCEPTED)
+ async updateTokenAsync(@Req() req, @Response() res): Promise {
+ await checkPermission(UserRole.STANDARD_REGISTRY)(req.user);
+ try {
+ const taskManager = new TaskManager();
+ const { taskId, expectation } = taskManager.start('Update token');
- res.status(202).send({ taskId, expectation });
-});
+ const user = req.user;
+ const token = req.body;
-tokenAPI.put('/push/', permissionHelper(UserRole.STANDARD_REGISTRY), async (req: AuthenticatedRequest, res: Response, next: NextFunction) => {
- try {
- const taskManager = new TaskManager();
- const { taskId, expectation } = taskManager.start('Update token');
+ if (!user.did) {
+ return res.status(422).json(prepareValidationResponse('User not registered'));
+ }
- const user = req.user;
- const token = req.body;
+ if (!token.tokenId) {
+ return res.status(422).json(prepareValidationResponse('The field tokenId is required'));
+ }
- if (!user.did) {
- return res.status(422).json(prepareValidationResponse('User not registered'));
- }
+ const guardians = new Guardians();
+ const tokenObject = await guardians.getTokenById(token.tokenId);
- if (!token.tokenId) {
- return res.status(422).json(prepareValidationResponse('The field tokenId is required'));
- }
+ if (!tokenObject) {
+ throw new HttpException('Token not found', HttpStatus.NOT_FOUND)
+ }
- const guardians = new Guardians();
- const tokenObject = await guardians.getTokenById(token.tokenId);
+ if (tokenObject.owner !== user.did) {
+ throw new HttpException('Invalid creator.', HttpStatus.FORBIDDEN)
+ }
- if (!tokenObject) {
- return next(createError(404, 'Token not found'));
- }
+ RunFunctionAsync(async () => {
+ await guardians.updateTokenAsync(token, taskId);
+ }, async (error) => {
+ new Logger().error(error, ['API_GATEWAY']);
+ taskManager.addError(taskId, { code: error.code || 500, message: error.message });
+ });
- if (tokenObject.owner !== user.did) {
- return next(createError(403, 'Invalid creator.'));
+ return res.status(202).send({ taskId, expectation });
+ } catch (error) {
+ new Logger().error(error, ['API_GATEWAY']);
+ throw error;
}
+ }
- RunFunctionAsync(async () => {
- await guardians.updateTokenAsync(token, taskId);
- }, async (error) => {
- new Logger().error(error, ['API_GATEWAY']);
- taskManager.addError(taskId, { code: error.code || 500, message: error.message });
- });
+ @Delete('/push/:tokenId')
+ @HttpCode(HttpStatus.ACCEPTED)
+ async deleteTokenAsync(@Req() req, @Response() res): Promise {
+ await checkPermission(UserRole.STANDARD_REGISTRY)(req.user);
+ try {
+ const taskManager = new TaskManager();
+ const { taskId, expectation } = taskManager.start('Update token');
- return res.status(202).send({ taskId, expectation });
- } catch (error) {
- new Logger().error(error, ['API_GATEWAY']);
- return next(error);
- }
-});
+ const user = req.user;
+ const tokenId = req.params.tokenId;
-tokenAPI.delete('/push/:tokenId', permissionHelper(UserRole.STANDARD_REGISTRY), async (req: AuthenticatedRequest, res: Response, next: NextFunction) => {
- try {
- const taskManager = new TaskManager();
- const { taskId, expectation } = taskManager.start('Update token');
+ if (!user.did) {
+ return res.status(422).json(prepareValidationResponse('User not registered'));
+ }
- const user = req.user;
- const tokenId = req.params.tokenId;
+ const guardians = new Guardians();
+ const tokenObject = await guardians.getTokenById(tokenId);
- if (!user.did) {
- return res.status(422).json(prepareValidationResponse('User not registered'));
- }
+ if (!tokenObject) {
+ throw new HttpException('Token does not exist.', HttpStatus.NOT_FOUND)
+ }
- const guardians = new Guardians();
- const tokenObject = await guardians.getTokenById(tokenId);
+ if (tokenObject.owner !== user.did) {
+ throw new HttpException('Invalid creator.', HttpStatus.FORBIDDEN);
+ }
- if (!tokenObject) {
- return next(createError(404, 'Token does not exist.'));
- }
+ RunFunctionAsync(async () => {
+ await guardians.deleteTokenAsync(tokenId, taskId);
+ }, async (error) => {
+ new Logger().error(error, ['API_GATEWAY']);
+ taskManager.addError(taskId, { code: error.code || 500, message: error.message });
+ });
- if (tokenObject.owner !== user.did) {
- return next(createError(403, 'Invalid creator.'));
+ return res.status(202).send({ taskId, expectation });
+ } catch (error) {
+ new Logger().error(error, ['API_GATEWAY']);
+ throw error;
}
+ }
- RunFunctionAsync(async () => {
- await guardians.deleteTokenAsync(tokenId, taskId);
- }, async (error) => {
+ @Put('/:tokenId/associate')
+ @HttpCode(HttpStatus.OK)
+ async associateToken(@Req() req, @Response() res): Promise {
+ await checkPermission(UserRole.USER)(req.user);
+ try {
+ const guardians = new Guardians();
+ const tokenId = req.params.tokenId;
+ const userDid = req.user.did;
+ if (!userDid) {
+ return res.status(422).json(prepareValidationResponse('User not registered'));
+ }
+ const status = await guardians.associateToken(tokenId, userDid);
+ return res.json(status);
+ } catch (error) {
new Logger().error(error, ['API_GATEWAY']);
- taskManager.addError(taskId, { code: error.code || 500, message: error.message });
- });
-
- return res.status(202).send({ taskId, expectation });
- } catch (error) {
- new Logger().error(error, ['API_GATEWAY']);
- return next(error);
+ if (error?.message?.toLowerCase().includes('user not found')) {
+ throw new HttpException('User not found', HttpStatus.NOT_FOUND)
+ }
+ if (error?.message?.toLowerCase().includes('token not found')) {
+ throw new HttpException('Token does not exist.', HttpStatus.NOT_FOUND)
+ }
+ throw error;
+ }
}
-});
-tokenAPI.put('/:tokenId/associate', permissionHelper(UserRole.USER), async (req: AuthenticatedRequest, res: Response, next: NextFunction) => {
- try {
- const guardians = new Guardians();
+ @Put('/push/:tokenId/associate')
+ @HttpCode(HttpStatus.ACCEPTED)
+ async associateTokenAsync(@Req() req, @Response() res): Promise {
+ await checkPermission(UserRole.USER)(req.user);
+ const taskManager = new TaskManager();
+ const { taskId, expectation } = taskManager.start('Associate/dissociate token');
+
const tokenId = req.params.tokenId;
const userDid = req.user.did;
if (!userDid) {
return res.status(422).json(prepareValidationResponse('User not registered'));
}
- const status = await guardians.associateToken(tokenId, userDid);
- return res.json(status);
- } catch (error) {
- new Logger().error(error, ['API_GATEWAY']);
- if (error?.message?.toLowerCase().includes('user not found')) {
- return next(createError(404, 'User not found'));
- }
- if (error?.message?.toLowerCase().includes('token not found')) {
- return next(createError(404, 'Token not found'));
- }
- return next(error);
- }
-});
-tokenAPI.put('/push/:tokenId/associate', permissionHelper(UserRole.USER), async (req: AuthenticatedRequest, res: Response, next: NextFunction) => {
- const taskManager = new TaskManager();
- const { taskId, expectation } = taskManager.start('Associate/dissociate token');
+ RunFunctionAsync(async () => {
+ const guardians = new Guardians();
+ await guardians.associateTokenAsync(tokenId, userDid, taskId);
+ }, async (error) => {
+ new Logger().error(error, ['API_GATEWAY']);
+ taskManager.addError(taskId, { code: error.code || 500, message: error.message });
+ });
- const tokenId = req.params.tokenId;
- const userDid = req.user.did;
- if (!userDid) {
- return res.status(422).json(prepareValidationResponse('User not registered'));
+ return res.status(202).send({ taskId, expectation });
}
- RunFunctionAsync(async () => {
- const guardians = new Guardians();
- await guardians.associateTokenAsync(tokenId, userDid, taskId);
- }, async (error) => {
- new Logger().error(error, ['API_GATEWAY']);
- taskManager.addError(taskId, { code: error.code || 500, message: error.message });
- });
+ @Put('/:tokenId/dissociate')
+ @HttpCode(HttpStatus.OK)
+ async dissociateToken(@Req() req, @Response() res): Promise {
+ await checkPermission(UserRole.USER)(req.user);
+ try {
+ const guardians = new Guardians();
+ const tokenId = req.params.tokenId;
+ const userDid = req.user.did;
+ if (!userDid) {
+ return res.status(422).json(prepareValidationResponse('User not registered'));
+ }
+ const status = await guardians.dissociateToken(tokenId, userDid);
+ return res.json(status);
+ } catch (error) {
+ new Logger().error(error, ['API_GATEWAY']);
+ if (error?.message?.toLowerCase().includes('user not found')) {
+ throw new HttpException('User not found', HttpStatus.NOT_FOUND)
+ }
+ if (error?.message?.toLowerCase().includes('token not found')) {
+ throw new HttpException('Token does not exist.', HttpStatus.NOT_FOUND)
+ }
+ throw error;
+ }
+ }
- return res.status(202).send({ taskId, expectation });
-});
+ @Put('/push/:tokenId/dissociate')
+ @HttpCode(HttpStatus.ACCEPTED)
+ async dissociateTokenAsync(@Req() req, @Response() res): Promise {
+ await checkPermission(UserRole.USER)(req.user);
+ const taskManager = new TaskManager();
+ const { taskId, expectation } = taskManager.start('Associate/dissociate token');
-tokenAPI.put('/:tokenId/dissociate', permissionHelper(UserRole.USER), async (req: AuthenticatedRequest, res: Response, next: NextFunction) => {
- try {
- const guardians = new Guardians();
const tokenId = req.params.tokenId;
const userDid = req.user.did;
if (!userDid) {
return res.status(422).json(prepareValidationResponse('User not registered'));
}
- const status = await guardians.dissociateToken(tokenId, userDid);
- return res.json(status);
- } catch (error) {
- new Logger().error(error, ['API_GATEWAY']);
- if (error?.message?.toLowerCase().includes('user not found')) {
- return next(createError(404, 'User not found'));
- }
- if (error?.message?.toLowerCase().includes('token not found')) {
- return next(createError(404, 'Token not found'));
+ RunFunctionAsync(async () => {
+ const guardians = new Guardians();
+ await guardians.dissociateTokenAsync(tokenId, userDid, taskId);
+ }, async (error) => {
+ new Logger().error(error, ['API_GATEWAY']);
+ taskManager.addError(taskId, { code: error.code || 500, message: error.message });
+ });
+
+ return res.status(202).send({ taskId, expectation });
+ }
+
+ /**
+ * @deprecated
+ */
+ @Put('/:tokenId/:username/grantKyc')
+ @HttpCode(HttpStatus.OK)
+ async grantKycOld(@Req() req, @Response() res): Promise {
+ await checkPermission(UserRole.STANDARD_REGISTRY)(req.user);
+ try {
+ const guardians = new Guardians();
+ const tokenId = req.params.tokenId;
+ const username = req.params.username;
+ const owner = req.user.did;
+ if (!owner) {
+ return res.status(500).json({ code: 500, message: 'User not registered' });
+ return;
+ }
+ const result = await guardians.grantKycToken(tokenId, username, owner);
+ return res.status(200).json(result);
+ } catch (error) {
+ new Logger().error(error, ['API_GATEWAY']);
+ return res.status(500).json({ code: error.code || 500, message: error.message });
}
- return next(error);
}
-});
-tokenAPI.put('/push/:tokenId/dissociate', permissionHelper(UserRole.USER), async (req: AuthenticatedRequest, res: Response, next: NextFunction) => {
- const taskManager = new TaskManager();
- const { taskId, expectation } = taskManager.start('Associate/dissociate token');
+ /**
+ * @deprecated
+ */
+ @Put('/:tokenId/:username/grantKyc')
+ @HttpCode(HttpStatus.OK)
+ async grantKycOld2(@Req() req, @Response() res): Promise {
+ await checkPermission(UserRole.STANDARD_REGISTRY)(req.user);
+ try {
+ const guardians = new Guardians();
+ const tokenId = req.params.tokenId;
+ const username = req.params.username;
+ const owner = req.user.did;
+ if (!owner) {
+ return res.status(500).json({ code: 500, message: 'User not registered' });
+ }
+ const result = await guardians.grantKycToken(tokenId, username, owner);
+ res.status(200).json(result);
+ } catch (error) {
+ new Logger().error(error, ['API_GATEWAY']);
+ return res.status(500).json({ code: error.code || 500, message: error.message });
+ }
+ }
- const tokenId = req.params.tokenId;
- const userDid = req.user.did;
- if (!userDid) {
- return res.status(422).json(prepareValidationResponse('User not registered'));
+ @Put('/:tokenId/:username/grant-kyc')
+ @HttpCode(HttpStatus.OK)
+ async grantKyc(@Req() req, @Response() res): Promise {
+ await checkPermission(UserRole.STANDARD_REGISTRY)(req.user);
+ try {
+ const guardians = new Guardians();
+ const tokenId = req.params.tokenId;
+ const username = req.params.username;
+ const userDid = req.user.did;
+ if (!userDid) {
+ return res.status(422).json(prepareValidationResponse('User not registered'));
+ }
+ return res.json(await guardians.grantKycToken(tokenId, username, userDid));
+ } catch (error) {
+ new Logger().error(error, ['API_GATEWAY']);
+ if (error?.message?.toLowerCase().includes('user not found')) {
+ throw new HttpException('User not found', HttpStatus.NOT_FOUND)
+ }
+ if (error?.message?.toLowerCase().includes('token not found')) {
+ throw new HttpException('Token not found', HttpStatus.NOT_FOUND)
+ }
+ throw error;
+ }
}
- RunFunctionAsync(async () => {
- const guardians = new Guardians();
- await guardians.dissociateTokenAsync(tokenId, userDid, taskId);
- }, async (error) => {
- new Logger().error(error, ['API_GATEWAY']);
- taskManager.addError(taskId, { code: error.code || 500, message: error.message });
- });
- return res.status(202).send({ taskId, expectation });
-});
+ /**
+ * @deprecated
+ */
+ @Put('/push/:tokenId/:username/grantKyc')
+ @HttpCode(HttpStatus.OK)
+ async grantKycAsyncOld(@Req() req, @Response() res): Promise {
+ await checkPermission(UserRole.STANDARD_REGISTRY)(req.user);
+ const taskManager = new TaskManager();
+ const { taskId, expectation } = taskManager.start('Grant KYC');
-/**
- * @deprecated
- */
-tokenAPI.put('/:tokenId/:username/grantKyc', permissionHelper(UserRole.STANDARD_REGISTRY), async (req: AuthenticatedRequest, res: Response) => {
- try {
- const guardians = new Guardians();
const tokenId = req.params.tokenId;
const username = req.params.username;
const owner = req.user.did;
if (!owner) {
- res.status(500).json({ code: 500, message: 'User not registered' });
+ return res.status(500).json({ code: 500, message: 'User not registered' });
return;
}
- const result = await guardians.grantKycToken(tokenId, username, owner);
- res.status(200).json(result);
- } catch (error) {
- new Logger().error(error, ['API_GATEWAY']);
- res.status(500).json({ code: error.code || 500, message: error.message });
+
+ RunFunctionAsync(async () => {
+ const guardians = new Guardians();
+ await guardians.grantKycTokenAsync(tokenId, username, owner, taskId);
+ }, async (error) => {
+ new Logger().error(error, ['API_GATEWAY']);
+ taskManager.addError(taskId, { code: error.code || 500, message: error.message });
+ });
+
+ return res.status(200).send({ taskId, expectation });
}
-});
-tokenAPI.put('/:tokenId/:username/grant-kyc', permissionHelper(UserRole.STANDARD_REGISTRY), async (req: AuthenticatedRequest, res: Response, next: NextFunction) => {
- try {
- const guardians = new Guardians();
+ @Put('/push/:tokenId/:username/grant-kyc')
+ @HttpCode(HttpStatus.ACCEPTED)
+ async grantKycAsync(@Req() req, @Response() res): Promise {
+ await checkPermission(UserRole.STANDARD_REGISTRY)(req.user);
+ const taskManager = new TaskManager();
+ const { taskId, expectation } = taskManager.start('Grant KYC');
+
const tokenId = req.params.tokenId;
const username = req.params.username;
const userDid = req.user.did;
if (!userDid) {
return res.status(422).json(prepareValidationResponse('User not registered'));
}
- return res.json(await guardians.grantKycToken(tokenId, username, userDid));
- } catch (error) {
- new Logger().error(error, ['API_GATEWAY']);
- if (error?.message?.toLowerCase().includes('user not found')) {
- return next(createError(404, 'User not found'));
- }
- if (error?.message?.toLowerCase().includes('token not found')) {
- return next(createError(404, 'Token not found'));
- }
- return next(error);
- }
-});
-/**
- * @deprecated
- */
-tokenAPI.put('/push/:tokenId/:username/grantKyc', permissionHelper(UserRole.STANDARD_REGISTRY), async (req: AuthenticatedRequest, res: Response) => {
- const taskManager = new TaskManager();
- const { taskId, expectation } = taskManager.start('Grant KYC');
-
- const tokenId = req.params.tokenId;
- const username = req.params.username;
- const owner = req.user.did;
- if (!owner) {
- res.status(500).json({ code: 500, message: 'User not registered' });
- return;
+ RunFunctionAsync(async () => {
+ const guardians = new Guardians();
+ await guardians.grantKycTokenAsync(tokenId, username, userDid, taskId);
+ }, async (error) => {
+ new Logger().error(error, ['API_GATEWAY']);
+ taskManager.addError(taskId, { code: error.code || 500, message: error.message });
+ });
+
+ return res.status(202).send({ taskId, expectation });
}
- RunFunctionAsync(async () => {
- const guardians = new Guardians();
- await guardians.grantKycTokenAsync(tokenId, username, owner, taskId);
- }, async (error) => {
- new Logger().error(error, ['API_GATEWAY']);
- taskManager.addError(taskId, { code: error.code || 500, message: error.message });
- });
-
- res.status(200).send({ taskId, expectation });
-});
-
-tokenAPI.put('/push/:tokenId/:username/grant-kyc', permissionHelper(UserRole.STANDARD_REGISTRY), async (req: AuthenticatedRequest, res: Response, next: NextFunction) => {
- const taskManager = new TaskManager();
- const { taskId, expectation } = taskManager.start('Grant KYC');
-
- const tokenId = req.params.tokenId;
- const username = req.params.username;
- const userDid = req.user.did;
- if (!userDid) {
- return res.status(422).json(prepareValidationResponse('User not registered'));
+ /**
+ * @deprecated
+ */
+ @Put('/:tokenId/:username/revokeKyc')
+ @HttpCode(HttpStatus.OK)
+ async revokeKycOld(@Req() req, @Response() res): Promise {
+ await checkPermission(UserRole.STANDARD_REGISTRY)(req.user);
+ try {
+ const guardians = new Guardians();
+ const tokenId = req.params.tokenId;
+ const username = req.params.username;
+ const owner = req.user.did;
+ if (!owner) {
+ return res.status(500).json({ code: 500, message: 'User not registered' });
+ return;
+ }
+ const result = await guardians.revokeKycToken(tokenId, username, owner);
+ res.status(200).json(result);
+ } catch (error) {
+ new Logger().error(error, ['API_GATEWAY']);
+ return res.status(500).json({ code: error.code || 500, message: error.message });
+ }
}
- RunFunctionAsync(async () => {
- const guardians = new Guardians();
- await guardians.grantKycTokenAsync(tokenId, username, userDid, taskId);
- }, async (error) => {
- new Logger().error(error, ['API_GATEWAY']);
- taskManager.addError(taskId, { code: error.code || 500, message: error.message });
- });
+ @Put('/:tokenId/:username/revoke-kyc')
+ @HttpCode(HttpStatus.OK)
+ async revokeKyc(@Req() req, @Response() res): Promise {
+ await checkPermission(UserRole.STANDARD_REGISTRY)(req.user);
+ try {
+ const guardians = new Guardians();
+ const tokenId = req.params.tokenId;
+ const username = req.params.username;
+ const userDid = req.user.did;
+ if (!userDid) {
+ return res.status(422).json(prepareValidationResponse('User not registered'));
+ }
+ const result = await guardians.revokeKycToken(tokenId, username, userDid);
+ return res.json(result);
+ } catch (error) {
+ new Logger().error(error, ['API_GATEWAY']);
+ if (error?.message?.toLowerCase().includes('user not found')) {
+ throw new HttpException('User not found', HttpStatus.NOT_FOUND)
+ }
+ if (error?.message?.toLowerCase().includes('token not found')) {
+ throw new HttpException('Token not found', HttpStatus.NOT_FOUND)
+ }
+ throw error;
+ }
+ }
- return res.status(202).send({ taskId, expectation });
-});
+ /**
+ * @deprecated
+ */
+ @Put('/push/:tokenId/:username/revokeKyc')
+ @HttpCode(HttpStatus.OK)
+ async revokeKycAsyncOld(@Req() req, @Response() res): Promise {
+ await checkPermission(UserRole.STANDARD_REGISTRY)(req.user);
+ const taskManager = new TaskManager();
+ const { taskId, expectation } = taskManager.start('Revoke KYC');
-/**
- * @deprecated
- */
-tokenAPI.put('/:tokenId/:username/revokeKyc', permissionHelper(UserRole.STANDARD_REGISTRY), async (req: AuthenticatedRequest, res: Response) => {
- try {
- const guardians = new Guardians();
const tokenId = req.params.tokenId;
const username = req.params.username;
const owner = req.user.did;
if (!owner) {
- res.status(500).json({ code: 500, message: 'User not registered' });
- return;
+ return res.status(500).json({ code: 500, message: 'User not registered' });
}
- const result = await guardians.revokeKycToken(tokenId, username, owner);
- res.status(200).json(result);
- } catch (error) {
- new Logger().error(error, ['API_GATEWAY']);
- res.status(500).json({ code: error.code || 500, message: error.message });
+
+ RunFunctionAsync(async () => {
+ const guardians = new Guardians();
+ await guardians.revokeKycTokenAsync(tokenId, username, owner, taskId);
+ }, async (error) => {
+ new Logger().error(error, ['API_GATEWAY']);
+ taskManager.addError(taskId, { code: error.code || 500, message: error.message });
+ });
+
+ return res.status(200).send({ taskId, expectation });
}
-});
-tokenAPI.put('/:tokenId/:username/revoke-kyc', permissionHelper(UserRole.STANDARD_REGISTRY), async (req: AuthenticatedRequest, res: Response, next: NextFunction) => {
- try {
- const guardians = new Guardians();
+ @Put('/push/:tokenId/:username/revoke-kyc')
+ @HttpCode(HttpStatus.ACCEPTED)
+ async revokeKycAsync(@Req() req, @Response() res): Promise {
+ await checkPermission(UserRole.STANDARD_REGISTRY)(req.user);
+ const taskManager = new TaskManager();
+ const { taskId, expectation } = taskManager.start('Revoke KYC');
+
const tokenId = req.params.tokenId;
const username = req.params.username;
const userDid = req.user.did;
if (!userDid) {
- return res.status(422).json(prepareValidationResponse('User not registered'));
- }
- const result = await guardians.revokeKycToken(tokenId, username, userDid);
- return res.json(result);
- } catch (error) {
- new Logger().error(error, ['API_GATEWAY']);
- if (error?.message?.toLowerCase().includes('user not found')) {
- return next(createError(404, 'User not found'));
+ throw new HttpException('User not registered', HttpStatus.UNPROCESSABLE_ENTITY);
}
- if (error?.message?.toLowerCase().includes('token not found')) {
- return next(createError(404, 'Token not found'));
- }
- return next(error);
- }
-});
-/**
- * @deprecated
- */
-tokenAPI.put('/push/:tokenId/:username/revokeKyc', permissionHelper(UserRole.STANDARD_REGISTRY), async (req: AuthenticatedRequest, res: Response) => {
- const taskManager = new TaskManager();
- const { taskId, expectation } = taskManager.start('Revoke KYC');
-
- const tokenId = req.params.tokenId;
- const username = req.params.username;
- const owner = req.user.did;
- if (!owner) {
- res.status(500).json({ code: 500, message: 'User not registered' });
- return;
- }
+ RunFunctionAsync(async () => {
+ const guardians = new Guardians();
+ await guardians.revokeKycTokenAsync(tokenId, username, userDid, taskId);
+ }, async (error) => {
+ new Logger().error(error, ['API_GATEWAY']);
+ taskManager.addError(taskId, { code: error.code || 500, message: error.message });
+ });
- RunFunctionAsync(async () => {
- const guardians = new Guardians();
- await guardians.revokeKycTokenAsync(tokenId, username, owner, taskId);
- }, async (error) => {
- new Logger().error(error, ['API_GATEWAY']);
- taskManager.addError(taskId, { code: error.code || 500, message: error.message });
- });
-
- res.status(200).send({ taskId, expectation });
-});
-
-tokenAPI.put('/push/:tokenId/:username/revoke-kyc', permissionHelper(UserRole.STANDARD_REGISTRY), async (req: AuthenticatedRequest, res: Response, next: NextFunction) => {
- const taskManager = new TaskManager();
- const { taskId, expectation } = taskManager.start('Revoke KYC');
-
- const tokenId = req.params.tokenId;
- const username = req.params.username;
- const userDid = req.user.did;
- if (!userDid) {
- return next(createError(422, 'User not registered'));
+ return res.status(202).send({ taskId, expectation });
}
- RunFunctionAsync(async () => {
- const guardians = new Guardians();
- await guardians.revokeKycTokenAsync(tokenId, username, userDid, taskId);
- }, async (error) => {
- new Logger().error(error, ['API_GATEWAY']);
- taskManager.addError(taskId, { code: error.code || 500, message: error.message });
- });
-
- return res.status(202).send({ taskId, expectation });
-});
-
-tokenAPI.put('/:tokenId/:username/freeze', permissionHelper(UserRole.STANDARD_REGISTRY), async (req: AuthenticatedRequest, res: Response, next: NextFunction) => {
- try {
- const guardians = new Guardians();
- const tokenId = req.params.tokenId;
- const username = req.params.username;
- const userDid = req.user.did;
- if (!userDid) {
- return res.status(422).json(prepareValidationResponse('User not registered'));
- }
- const result = await guardians.freezeToken(tokenId, username, userDid);
- return res.json(result);
- } catch (error) {
- new Logger().error(error, ['API_GATEWAY']);
- if (error?.message?.toLowerCase().includes('user not found')) {
- return next(createError(404, 'User not found'));
+ @Put('/:tokenId/:username/freeze')
+ @HttpCode(HttpStatus.OK)
+ async freezeToken(@Req() req, @Response() res): Promise {
+ await checkPermission(UserRole.STANDARD_REGISTRY)(req.user);
+ try {
+ const guardians = new Guardians();
+ const tokenId = req.params.tokenId;
+ const username = req.params.username;
+ const userDid = req.user.did;
+ if (!userDid) {
+ return res.status(422).json(prepareValidationResponse('User not registered'));
+ }
+ const result = await guardians.freezeToken(tokenId, username, userDid);
+ return res.json(result);
+ } catch (error) {
+ new Logger().error(error, ['API_GATEWAY']);
+ if (error?.message?.toLowerCase().includes('user not found')) {
+ throw new HttpException('User not registered', HttpStatus.NOT_FOUND);
+ }
+ if (error?.message?.toLowerCase().includes('token not found')) {
+ throw new HttpException('Token not registered', HttpStatus.NOT_FOUND);
+ }
+ throw error
}
- if (error?.message?.toLowerCase().includes('token not found')) {
- return next(createError(404, 'Token not found'));
+ }
+
+ @Put('/:tokenId/:username/unfreeze')
+ @HttpCode(HttpStatus.OK)
+ async unfreezeToken(@Req() req, @Response() res): Promise {
+ await checkPermission(UserRole.STANDARD_REGISTRY)(req.user);
+ try {
+ const guardians = new Guardians();
+ const tokenId = req.params.tokenId;
+ const username = req.params.username;
+ const userDid = req.user.did;
+ if (!userDid) {
+ return res.status(422).json(prepareValidationResponse('User not registered'));
+ }
+ const result = await guardians.unfreezeToken(tokenId, username, userDid);
+ return res.json(result);
+ } catch (error) {
+ new Logger().error(error, ['API_GATEWAY']);
+ if (error?.message?.toLowerCase().includes('user not found')) {
+ throw new HttpException('User not registered', HttpStatus.NOT_FOUND);
+ }
+ if (error?.message?.toLowerCase().includes('token not found')) {
+ throw new HttpException('Token not registered', HttpStatus.NOT_FOUND);
+ }
+ throw error;
}
- return next(error);
}
-});
-tokenAPI.put('/:tokenId/:username/unfreeze', permissionHelper(UserRole.STANDARD_REGISTRY), async (req: AuthenticatedRequest, res: Response, next: NextFunction) => {
- try {
- const guardians = new Guardians();
+ @Put('/push/:tokenId/:username/freeze')
+ @HttpCode(HttpStatus.ACCEPTED)
+ async freezeTokenAsync(@Req() req, @Response() res): Promise {
+ await checkPermission(UserRole.STANDARD_REGISTRY)(req.user);
+ const taskManager = new TaskManager();
+ const { taskId, expectation } = taskManager.start('Freeze Token');
+
const tokenId = req.params.tokenId;
const username = req.params.username;
const userDid = req.user.did;
if (!userDid) {
return res.status(422).json(prepareValidationResponse('User not registered'));
}
- const result = await guardians.unfreezeToken(tokenId, username, userDid);
- return res.json(result);
- } catch (error) {
- new Logger().error(error, ['API_GATEWAY']);
- if (error?.message?.toLowerCase().includes('user not found')) {
- return next(createError(404, 'User not found'));
- }
- if (error?.message?.toLowerCase().includes('token not found')) {
- return next(createError(404, 'Token not found'));
- }
- return next(error);
- }
-});
-tokenAPI.put('/push/:tokenId/:username/freeze', permissionHelper(UserRole.STANDARD_REGISTRY), async (req: AuthenticatedRequest, res: Response, next: NextFunction) => {
- const taskManager = new TaskManager();
- const { taskId, expectation } = taskManager.start('Freeze Token');
+ RunFunctionAsync(async () => {
+ const guardians = new Guardians();
+ await guardians.freezeTokenAsync(tokenId, username, userDid, taskId);
+ }, async (error) => {
+ new Logger().error(error, ['API_GATEWAY']);
+ taskManager.addError(taskId, { code: error.code || 500, message: error.message });
+ });
- const tokenId = req.params.tokenId;
- const username = req.params.username;
- const userDid = req.user.did;
- if (!userDid) {
- return res.status(422).json(prepareValidationResponse('User not registered'));
+ return res.status(202).send({ taskId, expectation });
}
- RunFunctionAsync(async () => {
- const guardians = new Guardians();
- await guardians.freezeTokenAsync(tokenId, username, userDid, taskId);
- }, async (error) => {
- new Logger().error(error, ['API_GATEWAY']);
- taskManager.addError(taskId, { code: error.code || 500, message: error.message });
- });
-
- return res.status(202).send({ taskId, expectation });
-});
-
-tokenAPI.put('/push/:tokenId/:username/unfreeze', permissionHelper(UserRole.STANDARD_REGISTRY), async (req: AuthenticatedRequest, res: Response, next: NextFunction) => {
- const taskManager = new TaskManager();
- const { taskId, expectation } = taskManager.start('Unfreeze Token');
-
- const tokenId = req.params.tokenId;
- const username = req.params.username;
- const userDid = req.user.did;
- if (!userDid) {
- return res.status(422).json(prepareValidationResponse('User not registered'));
- }
+ @Put('/push/:tokenId/:username/unfreeze')
+ @HttpCode(HttpStatus.ACCEPTED)
+ async unfreezeTokenAsync(@Req() req, @Response() res): Promise {
+ await checkPermission(UserRole.STANDARD_REGISTRY)(req.user);
+ const taskManager = new TaskManager();
+ const { taskId, expectation } = taskManager.start('Freeze Token');
- RunFunctionAsync(async () => {
- const guardians = new Guardians();
- await guardians.unfreezeTokenAsync(tokenId, username, userDid, taskId);
- }, async (error) => {
- new Logger().error(error, ['API_GATEWAY']);
- taskManager.addError(taskId, { code: error.code || 500, message: error.message });
- });
-
- return res.status(202).send({ taskId, expectation });
-});
-
-tokenAPI.get('/:tokenId/:username/info', permissionHelper(UserRole.STANDARD_REGISTRY),
- async (req: AuthenticatedRequest, res: Response, next: NextFunction) => {
- try {
- const guardians = new Guardians();
const tokenId = req.params.tokenId;
const username = req.params.username;
const userDid = req.user.did;
if (!userDid) {
return res.status(422).json(prepareValidationResponse('User not registered'));
}
- const result = await guardians.getInfoToken(tokenId, username, userDid);
- return res.json(result as ITokenInfo);
- } catch (error) {
- new Logger().error(error, ['API_GATEWAY']);
- if (error?.message?.toLowerCase().includes('user not found')) {
- return next(createError(404, 'User not found'));
- }
- if (error?.message?.toLowerCase().includes('token not found')) {
- return next(createError(404, 'Token not found'));
+
+ RunFunctionAsync(async () => {
+ const guardians = new Guardians();
+ await guardians.freezeTokenAsync(tokenId, username, userDid, taskId);
+ }, async (error) => {
+ new Logger().error(error, ['API_GATEWAY']);
+ taskManager.addError(taskId, { code: error.code || 500, message: error.message });
+ });
+
+ return res.status(202).send({ taskId, expectation });
+ }
+
+ @Get('/:tokenId/:username/info')
+ @HttpCode(HttpStatus.OK)
+ async getTokenInfo(@Req() req, @Response() res): Promise {
+ await checkPermission(UserRole.STANDARD_REGISTRY)(req.user);
+ try {
+ const guardians = new Guardians();
+ const tokenId = req.params.tokenId;
+ const username = req.params.username;
+ const userDid = req.user.did;
+ if (!userDid) {
+ return res.status(422).json(prepareValidationResponse('User not registered'));
+ }
+ const result = await guardians.getInfoToken(tokenId, username, userDid);
+ return res.json(result as ITokenInfo);
+ } catch (error) {
+ new Logger().error(error, ['API_GATEWAY']);
+ if (error?.message?.toLowerCase().includes('user not found')) {
+ throw new HttpException('User not registered', HttpStatus.NOT_FOUND);
+ }
+ if (error?.message?.toLowerCase().includes('token not found')) {
+ throw new HttpException('Token not registered', HttpStatus.NOT_FOUND);
+ }
+ throw error;
}
- return next(error);
}
-});
+}
diff --git a/api-gateway/src/api/service/trust-chains.ts b/api-gateway/src/api/service/trust-chains.ts
index 86d9e8fdc5..163495a761 100644
--- a/api-gateway/src/api/service/trust-chains.ts
+++ b/api-gateway/src/api/service/trust-chains.ts
@@ -1,78 +1,80 @@
import { Guardians } from '@helpers/guardians';
-import { Response, Router, NextFunction } from 'express';
-import { UserRole } from '@guardian/interfaces';
-import { permissionHelper } from '@auth/authorization-helper';
import { Users } from '@helpers/users';
-import { AuthenticatedRequest, IAuthUser, Logger } from '@guardian/common';
-
-/**
- * Audit route
- */
-export const trustChainsAPI = Router();
+import { IAuthUser, Logger } from '@guardian/common';
+import { Controller, Get, HttpCode, HttpStatus, Req, Response } from '@nestjs/common';
+import { checkPermission } from '@auth/authorization-helper';
+import { UserRole } from '@guardian/interfaces';
-trustChainsAPI.get('/', permissionHelper(UserRole.AUDITOR),
- async (req: AuthenticatedRequest, res: Response, next: NextFunction) => {
- try {
- const guardians = new Guardians();
- let pageIndex: any;
- let pageSize: any;
- let filters: any;
- if (req.query) {
- if (req.query.pageIndex && req.query.pageSize) {
- pageIndex = req.query.pageIndex;
- pageSize = req.query.pageSize;
- }
- if (req.query.policyId) {
- filters = {
- policyId: req.query.policyId
+@Controller('trust-chains')
+export class TrustChainsApi {
+ @Get('/')
+ @HttpCode(HttpStatus.OK)
+ async getTrustChains(@Req() req, @Response() res): Promise {
+ await checkPermission(UserRole.AUDITOR)(req.user);
+ try {
+ const guardians = new Guardians();
+ let pageIndex: any;
+ let pageSize: any;
+ let filters: any;
+ if (req.query) {
+ if (req.query.pageIndex && req.query.pageSize) {
+ pageIndex = req.query.pageIndex;
+ pageSize = req.query.pageSize;
}
- } else if (req.query.policyOwner) {
- filters = {
- policyOwner: req.query.policyOwner
+ if (req.query.policyId) {
+ filters = {
+ policyId: req.query.policyId
+ }
+ } else if (req.query.policyOwner) {
+ filters = {
+ policyOwner: req.query.policyOwner
+ }
}
}
+ const { items, count } = await guardians.getVpDocuments({
+ filters,
+ pageIndex,
+ pageSize
+ });
+ return res.setHeader('X-Total-Count', count).json(items);
+ } catch (error) {
+ new Logger().error(error, ['API_GATEWAY']);
+ throw error;
}
- const { items, count } = await guardians.getVpDocuments({
- filters,
- pageIndex,
- pageSize
- });
- return res.setHeader('X-Total-Count', count).json(items);
- } catch (error) {
- new Logger().error(error, ['API_GATEWAY']);
- return next(error);
}
-});
-trustChainsAPI.get('/:hash', permissionHelper(UserRole.AUDITOR),
- async (req: AuthenticatedRequest, res: Response, next: NextFunction) => {
- try {
- const guardians = new Guardians();
- const hash = req.params.hash;
- const chain = await guardians.getChain(hash);
- const DIDs = chain.map((item) => {
- if (item.type === 'VC' && item.document) {
- if (typeof item.document.issuer === 'string') {
- return item.document.issuer;
- } else {
- return item.document.issuer.id;
+ @Get('/:hash')
+ @HttpCode(HttpStatus.OK)
+ async getTrustChainByHash(@Req() req, @Response() res): Promise {
+ await checkPermission(UserRole.AUDITOR)(req.user);
+ try {
+ const guardians = new Guardians();
+ const hash = req.params.hash;
+ const chain = await guardians.getChain(hash);
+ const DIDs = chain.map((item) => {
+ if (item.type === 'VC' && item.document) {
+ if (typeof item.document.issuer === 'string') {
+ return item.document.issuer;
+ } else {
+ return item.document.issuer.id;
+ }
}
- }
- if (item.type === 'DID') {
- return item.id;
- }
- return null;
- }).filter(did => !!did);
+ if (item.type === 'DID') {
+ return item.id;
+ }
+ return null;
+ }).filter(did => !!did);
- const users = new Users();
- const allUsers = (await users.getUsersByIds(DIDs)) || [];
- const userMap = allUsers.map((user: IAuthUser) => {
- return { username: user.username, did: user.did }
- })
+ const users = new Users();
+ const allUsers = (await users.getUsersByIds(DIDs)) || [];
+ const userMap = allUsers.map((user: IAuthUser) => {
+ return { username: user.username, did: user.did }
+ })
- res.json({ chain, userMap });
- } catch (error) {
- new Logger().error(error, ['API_GATEWAY']);
- return next(error);
+ return res.json({ chain, userMap });
+ } catch (error) {
+ new Logger().error(error, ['API_GATEWAY']);
+ throw error
+ }
}
-});
+}
diff --git a/api-gateway/src/api/service/trustchains.ts b/api-gateway/src/api/service/trustchains.ts
index d5292bdc31..d5a7e8054b 100644
--- a/api-gateway/src/api/service/trustchains.ts
+++ b/api-gateway/src/api/service/trustchains.ts
@@ -1,82 +1,156 @@
import { Guardians } from '@helpers/guardians';
-import { Response, Router } from 'express';
import { UserRole } from '@guardian/interfaces';
-import { permissionHelper } from '@auth/authorization-helper';
+import { checkPermission } from '@auth/authorization-helper';
import { Users } from '@helpers/users';
-import { AuthenticatedRequest, IAuthUser, Logger } from '@guardian/common';
+import { IAuthUser, Logger } from '@guardian/common';
+import { Controller, Get, HttpCode, HttpStatus, Req, Response } from '@nestjs/common';
-/**
- * Audit route
- */
-export const trustchainsAPI = Router();
-
-/**
- * @deprecated
- */
-trustchainsAPI.get('/', permissionHelper(UserRole.AUDITOR), async (req: AuthenticatedRequest, res: Response) => {
- try {
- const guardians = new Guardians();
- let pageIndex: any;
- let pageSize: any;
- let filters: any;
- if (req.query) {
- if (req.query.pageIndex && req.query.pageSize) {
- pageIndex = req.query.pageIndex;
- pageSize = req.query.pageSize;
- }
- if (req.query.policyId) {
- filters = {
- policyId: req.query.policyId
+@Controller('trustchains')
+export class TrustChainsOldApi {
+ @Get('/')
+ @HttpCode(HttpStatus.OK)
+ async getTrustChains(@Req() req, @Response() res): Promise {
+ await checkPermission(UserRole.AUDITOR)(req.user);
+ try {
+ const guardians = new Guardians();
+ let pageIndex: any;
+ let pageSize: any;
+ let filters: any;
+ if (req.query) {
+ if (req.query.pageIndex && req.query.pageSize) {
+ pageIndex = req.query.pageIndex;
+ pageSize = req.query.pageSize;
}
- } else if (req.query.policyOwner) {
- filters = {
- policyOwner: req.query.policyOwner
+ if (req.query.policyId) {
+ filters = {
+ policyId: req.query.policyId
+ }
+ } else if (req.query.policyOwner) {
+ filters = {
+ policyOwner: req.query.policyOwner
+ }
}
}
+ const { items, count } = await guardians.getVpDocuments({
+ filters,
+ pageIndex,
+ pageSize
+ });
+ return res.setHeader('X-Total-Count', count).json(items);
+ } catch (error) {
+ new Logger().error(error, ['API_GATEWAY']);
+ throw error;
}
- const { items, count } = await guardians.getVpDocuments({
- filters,
- pageIndex,
- pageSize
- });
- res.status(200).setHeader('X-Total-Count', count).json(items);
- } catch (error) {
- new Logger().error(error, ['API_GATEWAY']);
- res.status(500).json({ code: 500, message: error.message });
}
-});
-/**
- * @deprecated
- */
-trustchainsAPI.get('/:hash', permissionHelper(UserRole.AUDITOR), async (req: AuthenticatedRequest, res: Response) => {
- try {
- const guardians = new Guardians();
- const hash = req.params.hash;
- const chain = await guardians.getChain(hash);
- const DIDs = chain.map((item) => {
- if (item.type === 'VC' && item.document) {
- if (typeof item.document.issuer === 'string') {
- return item.document.issuer;
- } else {
- return item.document.issuer.id;
+ @Get('/:hash')
+ @HttpCode(HttpStatus.OK)
+ async getTrustChainByHash(@Req() req, @Response() res): Promise {
+ await checkPermission(UserRole.AUDITOR)(req.user);
+ try {
+ const guardians = new Guardians();
+ const hash = req.params.hash;
+ const chain = await guardians.getChain(hash);
+ const DIDs = chain.map((item) => {
+ if (item.type === 'VC' && item.document) {
+ if (typeof item.document.issuer === 'string') {
+ return item.document.issuer;
+ } else {
+ return item.document.issuer.id;
+ }
}
- }
- if (item.type === 'DID') {
- return item.id;
- }
- return null;
- }).filter(did => !!did);
+ if (item.type === 'DID') {
+ return item.id;
+ }
+ return null;
+ }).filter(did => !!did);
- const users = new Users();
- const allUsers = (await users.getUsersByIds(DIDs)) || [];
- const userMap = allUsers.map((user: IAuthUser) => {
- return { username: user.username, did: user.did }
- })
+ const users = new Users();
+ const allUsers = (await users.getUsersByIds(DIDs)) || [];
+ const userMap = allUsers.map((user: IAuthUser) => {
+ return { username: user.username, did: user.did }
+ })
- res.status(200).json({ chain, userMap });
- } catch (error) {
- new Logger().error(error, ['API_GATEWAY']);
- res.status(500).json({ code: 500, message: error.message });
+ return res.json({ chain, userMap });
+ } catch (error) {
+ new Logger().error(error, ['API_GATEWAY']);
+ throw error
+ }
}
-});
+}
+
+// /**
+// * Audit route
+// */
+// export const trustchainsAPI = Router();
+//
+// /**
+// * @deprecated
+// */
+// trustchainsAPI.get('/', permissionHelper(UserRole.AUDITOR), async (req: AuthenticatedRequest, res: Response) => {
+// try {
+// const guardians = new Guardians();
+// let pageIndex: any;
+// let pageSize: any;
+// let filters: any;
+// if (req.query) {
+// if (req.query.pageIndex && req.query.pageSize) {
+// pageIndex = req.query.pageIndex;
+// pageSize = req.query.pageSize;
+// }
+// if (req.query.policyId) {
+// filters = {
+// policyId: req.query.policyId
+// }
+// } else if (req.query.policyOwner) {
+// filters = {
+// policyOwner: req.query.policyOwner
+// }
+// }
+// }
+// const { items, count } = await guardians.getVpDocuments({
+// filters,
+// pageIndex,
+// pageSize
+// });
+// res.status(200).setHeader('X-Total-Count', count).json(items);
+// } catch (error) {
+// new Logger().error(error, ['API_GATEWAY']);
+// res.status(500).json({ code: 500, message: error.message });
+// }
+// });
+//
+// /**
+// * @deprecated
+// */
+// trustchainsAPI.get('/:hash', permissionHelper(UserRole.AUDITOR), async (req: AuthenticatedRequest, res: Response) => {
+// try {
+// const guardians = new Guardians();
+// const hash = req.params.hash;
+// const chain = await guardians.getChain(hash);
+// const DIDs = chain.map((item) => {
+// if (item.type === 'VC' && item.document) {
+// if (typeof item.document.issuer === 'string') {
+// return item.document.issuer;
+// } else {
+// return item.document.issuer.id;
+// }
+// }
+// if (item.type === 'DID') {
+// return item.id;
+// }
+// return null;
+// }).filter(did => !!did);
+//
+// const users = new Users();
+// const allUsers = (await users.getUsersByIds(DIDs)) || [];
+// const userMap = allUsers.map((user: IAuthUser) => {
+// return { username: user.username, did: user.did }
+// })
+//
+// res.status(200).json({ chain, userMap });
+// } catch (error) {
+// new Logger().error(error, ['API_GATEWAY']);
+// res.status(500).json({ code: 500, message: error.message });
+// }
+// });
diff --git a/api-gateway/src/api/service/websockets.ts b/api-gateway/src/api/service/websockets.ts
index 79b6f10dc0..a8fac831d1 100644
--- a/api-gateway/src/api/service/websockets.ts
+++ b/api-gateway/src/api/service/websockets.ts
@@ -1,19 +1,10 @@
import WebSocket from 'ws';
import { IncomingMessage, Server } from 'http';
import { Users } from '@helpers/users';
-import {
- MessageAPI,
- IStatus,
- ApplicationStates, GenerateUUIDv4
-} from '@guardian/interfaces';
-import {
- MessageResponse,
- Logger,
- NatsService,
- Singleton
-} from '@guardian/common';
+import { ApplicationStates, GenerateUUIDv4, IStatus, MessageAPI } from '@guardian/interfaces';
+import { Logger, MessageResponse, NatsService, Singleton } from '@guardian/common';
import { NatsConnection } from 'nats';
-// import { Guardians } from '@helpers/guardians';
+import { Injectable } from '@nestjs/common';
/**
* WebSocketsServiceChannel
@@ -44,7 +35,7 @@ export class WebSocketsServiceChannel extends NatsService {
/**
* WebSocket service class
*/
-@Singleton
+@Injectable()
export class WebSocketsService {
/**
* Channel
@@ -113,7 +104,7 @@ export class WebSocketsService {
if (this.checkUserByDid(client, msg)) {
this.send(client, {
type: 'update-event',
- data: msg.uuid
+ data: msg.blocks
});
}
});
diff --git a/api-gateway/src/api/service/wizard.ts b/api-gateway/src/api/service/wizard.ts
new file mode 100644
index 0000000000..8942035c35
--- /dev/null
+++ b/api-gateway/src/api/service/wizard.ts
@@ -0,0 +1,77 @@
+import { Guardians } from '@helpers/guardians';
+import { Logger, RunFunctionAsync, } from '@guardian/common';
+import { TaskManager } from '@helpers/task-manager';
+import { ServiceError } from '@helpers/service-requests-base';
+import { Controller, HttpCode, HttpStatus, Post, Req, Response } from '@nestjs/common';
+import { checkPermission } from '@auth/authorization-helper';
+import { UserRole } from '@guardian/interfaces';
+
+@Controller('wizard')
+export class WizardApi {
+ @Post('/policy')
+ @HttpCode(HttpStatus.CREATED)
+ async setPolicy(@Req() req, @Response() res): Promise {
+ await checkPermission(UserRole.STANDARD_REGISTRY)(req.user);
+ try {
+ const wizardConfig = req.body;
+ const user = req.user;
+ const guardians = new Guardians();
+ return res.status(201).json(
+ await guardians.wizardPolicyCreate(wizardConfig, user.did)
+ );
+ } catch (error) {
+ new Logger().error(error, ['API_GATEWAY']);
+ throw error;
+ }
+ }
+
+ @Post('/policy/push')
+ @HttpCode(HttpStatus.ACCEPTED)
+ async setPolicyAsync(@Req() req, @Response() res): Promise {
+ await checkPermission(UserRole.STANDARD_REGISTRY)(req.user);
+ const taskManager = new TaskManager();
+ const { taskId, expectation } = taskManager.start('Create policy');
+ const wizardConfig = req.body;
+ const user = req.user;
+ RunFunctionAsync(
+ async () => {
+ const guardians = new Guardians();
+ await guardians.wizardPolicyCreateAsync(
+ wizardConfig,
+ user.did,
+ taskId
+ );
+ },
+ async (error) => {
+ new Logger().error(error, ['API_GATEWAY']);
+ taskManager.addError(taskId, {
+ code: 500,
+ message: error.message,
+ });
+ }
+ );
+ return res.status(202).send({ taskId, expectation });
+ }
+
+ @Post('/:policyId/config')
+ @HttpCode(HttpStatus.OK)
+ async setPolicyConfig(@Req() req, @Response() res): Promise {
+ await checkPermission(UserRole.STANDARD_REGISTRY)(req.user);
+ try {
+ const wizardConfig = req.body;
+ const user = req.user;
+ const { policyId } = req.params;
+ const guardians = new Guardians();
+ return res.json(
+ await guardians.wizardGetPolicyConfig(
+ policyId,
+ wizardConfig,
+ user.did
+ )
+ );
+ } catch (error) {
+ new Logger().error(error, ['API_GATEWAY']);
+ throw error;
+ }
+ }
+}
diff --git a/api-gateway/src/app.module.ts b/api-gateway/src/app.module.ts
new file mode 100644
index 0000000000..7d55930733
--- /dev/null
+++ b/api-gateway/src/app.module.ts
@@ -0,0 +1,103 @@
+import { MiddlewareConsumer, Module } from '@nestjs/common';
+import { AccountApi } from '@api/service/account';
+import { AnalyticsApi } from '@api/service/analytics';
+import { ArtifactApi } from '@api/service/artifact';
+import { ContractsApi } from '@api/service/contract';
+import { DemoApi } from '@api/service/demo';
+import { ExternalApi } from '@api/service/external';
+import { IpfsApi } from '@api/service/ipfs';
+import { LoggerApi, LoggerService } from '@api/service/logger';
+import { MapApi } from '@api/service/map';
+import { ClientsModule, Transport } from '@nestjs/microservices';
+import { MetricsApi } from '@api/service/metrics';
+import { ModulesApi } from '@api/service/module';
+import { ProfileApi } from '@api/service/profile';
+import { authorizationHelper } from '@auth/authorization-helper';
+import { PolicyApi } from '@api/service/policy';
+import { SchemaApi, SingleSchemaApi } from '@api/service/schema';
+import { SettingsApi } from '@api/service/settings';
+import { TagsApi } from '@api/service/tags';
+import { TaskApi } from '@api/service/task';
+import { TokensApi } from '@api/service/tokens';
+import { TrustChainsApi } from '@api/service/trust-chains';
+import { WizardApi } from '@api/service/wizard';
+import process from 'process';
+import express from 'express';
+import fileUpload from 'express-fileupload';
+import hpp from 'hpp';
+import { ThemesApi } from '@api/service/themes';
+import { TrustChainsOldApi } from '@api/service/trustchains';
+
+const RAW_REQUEST_LIMIT = process.env.RAW_REQUEST_LIMIT || '1gb';
+
+@Module({
+ imports: [
+ ClientsModule.register([{
+ name: 'GUARDIANS',
+ transport: Transport.NATS,
+ options: {
+ name: `${process.env.SERVICE_CHANNEL}`,
+ servers: [
+ `nats://${process.env.MQ_ADDRESS}:4222`
+ ]
+ }
+ }]),
+ ],
+ controllers: [
+ AccountApi,
+ AnalyticsApi,
+ ArtifactApi,
+ ContractsApi,
+ DemoApi,
+ ExternalApi,
+ IpfsApi,
+ LoggerApi,
+ MapApi,
+ MetricsApi,
+ ModulesApi,
+ ProfileApi,
+ PolicyApi,
+ SingleSchemaApi,
+ SchemaApi,
+ SettingsApi,
+ TagsApi,
+ TaskApi,
+ TokensApi,
+ ThemesApi,
+ TrustChainsApi,
+ TrustChainsOldApi,
+ WizardApi
+ ],
+ providers: [
+ LoggerService
+ ]
+})
+export class AppModule {
+ configure(consumer: MiddlewareConsumer) {
+ consumer.apply(authorizationHelper).forRoutes(AccountApi);
+ consumer.apply(authorizationHelper).forRoutes(ProfileApi);
+ consumer.apply(authorizationHelper).forRoutes(PolicyApi);
+ consumer.apply(authorizationHelper).forRoutes(SettingsApi);
+ consumer.apply(authorizationHelper).forRoutes(SingleSchemaApi);
+ consumer.apply(authorizationHelper).forRoutes(SchemaApi);
+ consumer.apply(authorizationHelper).forRoutes(ArtifactApi);
+ consumer.apply(authorizationHelper).forRoutes(IpfsApi);
+ consumer.apply(authorizationHelper).forRoutes(LoggerApi);
+ consumer.apply(authorizationHelper).forRoutes(AnalyticsApi);
+ consumer.apply(authorizationHelper).forRoutes(ContractsApi);
+ consumer.apply(authorizationHelper).forRoutes(ModulesApi);
+ consumer.apply(authorizationHelper).forRoutes(TagsApi);
+ consumer.apply(authorizationHelper).forRoutes(ThemesApi);
+ consumer.apply(authorizationHelper).forRoutes(TokensApi);
+ consumer.apply(authorizationHelper).forRoutes(TrustChainsApi);
+ consumer.apply(authorizationHelper).forRoutes(WizardApi);
+
+ consumer.apply(express.raw({
+ inflate: true,
+ limit: RAW_REQUEST_LIMIT,
+ type: 'binary/octet-stream'
+ })).forRoutes('*');
+ consumer.apply(fileUpload()).forRoutes('*');
+ consumer.apply(hpp()).forRoutes('*');
+ }
+}
diff --git a/api-gateway/src/app.ts b/api-gateway/src/app.ts
index 9a2a79c7b2..1a74460044 100644
--- a/api-gateway/src/app.ts
+++ b/api-gateway/src/app.ts
@@ -1,61 +1,49 @@
-import hpp from 'hpp';
-
-import {
- accountAPI,
- trustchainsAPI,
- trustChainsAPI,
- demoAPI,
- profileAPI,
- schemaAPI,
- tokenAPI,
- externalAPI,
- ipfsAPI,
- analyticsAPI,
- moduleAPI,
- tagsAPI,
- themesAPI
-} from '@api/service';
+// import client from 'prom-client';
import { Guardians } from '@helpers/guardians';
-import express from 'express';
-import { createServer } from 'http';
-import { authorizationHelper } from '@auth/authorization-helper';
import { IPFS } from '@helpers/ipfs';
-import { policyAPI } from '@api/service/policy';
import { PolicyEngine } from '@helpers/policy-engine';
import { WebSocketsService } from '@api/service/websockets';
import { Users } from '@helpers/users';
import { Wallet } from '@helpers/wallet';
-import { settingsAPI } from '@api/service/settings';
-import { loggerAPI } from '@api/service/logger';
-import { MessageBrokerChannel, Logger, LargePayloadContainer } from '@guardian/common';
-import { taskAPI } from '@api/service/task';
+import { LargePayloadContainer, Logger, MessageBrokerChannel } from '@guardian/common';
import { TaskManager } from '@helpers/task-manager';
-import { singleSchemaRoute } from '@api/service/schema';
-import { artifactAPI } from '@api/service/artifact';
-import fileupload from 'express-fileupload';
-import { contractAPI } from '@api/service/contract';
-import { mapAPI } from '@api/service/map';
+import { AppModule } from './app.module';
+import { NestFactory } from '@nestjs/core';
+import { MicroserviceOptions, Transport } from '@nestjs/microservices';
+import process from 'process';
+import { HttpStatus, ValidationPipe } from '@nestjs/common';
const PORT = process.env.PORT || 3002;
-const RAW_REQUEST_LIMIT = process.env.RAW_REQUEST_LIMIT || '1gb';
-const JSON_REQUEST_LIMIT = process.env.JSON_REQUEST_LIMIT || '1mb';
+// const RAW_REQUEST_LIMIT = process.env.RAW_REQUEST_LIMIT || '1gb';
+// const JSON_REQUEST_LIMIT = process.env.JSON_REQUEST_LIMIT || '1mb';
+
+// const restResponseTimeHistogram = new client.Histogram({
+// name: 'api_gateway_rest_response_time_duration_seconds',
+// help: 'api-gateway a histogram metric',
+// labelNames: ['method', 'route', 'statusCode'],
+// buckets: [0.1, 5, 15, 50, 100, 500],
+// });
Promise.all([
+ NestFactory.create(AppModule, {
+ rawBody: true
+ }),
MessageBrokerChannel.connect('API_GATEWAY'),
-]).then(async ([cn]) => {
+]).then(async ([app, cn]) => {
try {
- const app = express();
-
- app.use(express.json({
- limit: JSON_REQUEST_LIMIT
- }));
- app.use(express.raw({
- inflate: true,
- limit: RAW_REQUEST_LIMIT,
- type: 'binary/octet-stream'
+ app.connectMicroservice({
+ transport: Transport.NATS,
+ options: {
+ name: `${process.env.SERVICE_CHANNEL}`,
+ servers: [
+ `nats://${process.env.MQ_ADDRESS}:4222`
+ ]
+ },
+ });
+ app.useGlobalPipes(new ValidationPipe({
+ errorHttpStatusCode: HttpStatus.UNPROCESSABLE_ENTITY
}));
- app.use(fileupload());
- app.use(hpp());
+
new Logger().setConnection(cn);
await new Guardians().setConnection(cn).init();
await new IPFS().setConnection(cn).init();
@@ -63,54 +51,18 @@ Promise.all([
await new Users().setConnection(cn).init();
await new Wallet().setConnection(cn).init();
- const server = createServer(app);
+ const server = app.getHttpServer();
const wsService = new WebSocketsService(server, cn);
wsService.init();
new TaskManager().setDependecies(wsService, cn);
- ////////////////////////////////////////
-
- // Config routes
- app.use('/policies', authorizationHelper, policyAPI);
- app.use('/accounts', accountAPI);
- app.use('/profiles', authorizationHelper, profileAPI);
- app.use('/settings', authorizationHelper, settingsAPI);
- app.use('/schema', authorizationHelper, singleSchemaRoute);
- app.use('/schemas', authorizationHelper, schemaAPI);
- app.use('/tokens', authorizationHelper, tokenAPI);
- app.use('/artifacts', authorizationHelper, artifactAPI);
- app.use('/trust-chains/', authorizationHelper, trustChainsAPI);
- app.use('/external/', externalAPI);
- app.use('/demo/', demoAPI);
- app.use('/ipfs', authorizationHelper, ipfsAPI);
- app.use('/logs', authorizationHelper, loggerAPI);
- app.use('/tasks', taskAPI);
- app.use('/analytics', authorizationHelper, analyticsAPI);
- app.use('/contracts', authorizationHelper, contractAPI);
- app.use('/modules', authorizationHelper, moduleAPI);
- app.use('/tags', authorizationHelper, tagsAPI);
- app.use('/map', mapAPI);
- app.use('/themes', authorizationHelper, themesAPI);
-
- /**
- * @deprecated 2023-03-01
- */
- app.use('/trustchains/', authorizationHelper, trustchainsAPI);
- app.use('/artifact', authorizationHelper, artifactAPI);
- /////////////////////////////////////////
-
- // middleware error handler
- app.use((err, req, res, next) => {
- return res.status(err?.status || 500).json({ code: err?.status || 500, message: err.message })
- });
-
- server.setTimeout();
const maxPayload = parseInt(process.env.MQ_MAX_PAYLOAD, 10);
if (Number.isInteger(maxPayload)) {
new LargePayloadContainer().runServer();
}
- server.setTimeout(12000000).listen(PORT, () => {
+ app.listen(PORT, async () => {
+ console.log(await app.getUrl());
new Logger().info(`Started on ${PORT}`, ['API_GATEWAY']);
});
} catch (error) {
diff --git a/api-gateway/src/auth/authorization-helper.ts b/api-gateway/src/auth/authorization-helper.ts
index c9adb9b0e4..2aa5488c37 100644
--- a/api-gateway/src/auth/authorization-helper.ts
+++ b/api-gateway/src/auth/authorization-helper.ts
@@ -1,6 +1,53 @@
-import { Response } from 'express';
+import { NextFunction, Response } from 'express';
import { Users } from '@helpers/users';
import { AuthenticatedRequest, IAuthUser, Logger } from '@guardian/common';
+import { HttpException, HttpStatus, Injectable, NestMiddleware } from '@nestjs/common';
+
+/**
+ * Auth middleware
+ */
+@Injectable()
+export class AuthMiddleware implements NestMiddleware {
+
+ /**
+ * Use
+ * @param req
+ * @param res
+ * @param next
+ */
+ async use(req: AuthenticatedRequest, res: Response, next: NextFunction) {
+ const authHeader = req.headers.authorization;
+ const users = new Users();
+ if (authHeader) {
+ const token = authHeader.split(' ')[1];
+ try {
+ req.user = await users.getUserByToken(token) as IAuthUser;
+ next();
+ return;
+ } catch (error) {
+ new Logger().error(error, ['API_GATEWAY']);
+ }
+ }
+ res.sendStatus(401);
+ }
+}
+
+/**
+ * Permission middleware
+ */
+@Injectable()
+export class PermissionMiddleware implements NestMiddleware {
+
+ /**
+ * Permission middleware
+ * @param req
+ * @param res
+ * @param next
+ */
+ use(req: AuthenticatedRequest, res: Response, next: NextFunction) {
+ next();
+ }
+}
/**
* Authorization middleware
@@ -10,6 +57,10 @@ import { AuthenticatedRequest, IAuthUser, Logger } from '@guardian/common';
*/
export async function authorizationHelper(req: AuthenticatedRequest, res: Response, next: Function): Promise {
const authHeader = req.headers.authorization;
+ if (!authHeader) {
+ next();
+ return;
+ }
const users = new Users();
if (authHeader) {
const token = authHeader.split(' ')[1];
@@ -24,6 +75,25 @@ export async function authorizationHelper(req: AuthenticatedRequest, res: Respon
res.sendStatus(401);
}
+/**
+ * Calculate user permissions
+ * @param roles
+ */
+export function checkPermission(...roles: string[]) {
+ return async (user: IAuthUser): Promise => {
+ if (user) {
+ if(user.role) {
+ if(roles.indexOf(user.role) !== -1) {
+ return;
+ }
+ }
+ throw new HttpException('Forbidden', HttpStatus.FORBIDDEN)
+ } else {
+ throw new HttpException('Unauthorized', HttpStatus.UNAUTHORIZED)
+ }
+ }
+}
+
/**
* Calculate user permissions
* @param roles
diff --git a/api-gateway/src/config.ts b/api-gateway/src/config.ts
index 09b42d9446..e1dad3e9bc 100644
--- a/api-gateway/src/config.ts
+++ b/api-gateway/src/config.ts
@@ -1,6 +1,7 @@
import moduleAlias from 'module-alias';
import dotenv from 'dotenv';
import 'reflect-metadata'
+import fs from 'fs';
moduleAlias.addAliases({
'@api': __dirname + '/api',
@@ -11,3 +12,24 @@ moduleAlias.addAliases({
});
dotenv.config();
+
+const envPath = process.env.GUARDIAN_ENV ? `./configs/.env.gateway.${process.env.GUARDIAN_ENV}` : './configs/.env.gateway';
+
+if (!process.env.OVERRIDE || process.env.OVERRIDE === 'false'){
+ console.log('reading from', envPath, 'not overriding');
+ dotenv.config({ path: envPath});
+}else{
+ try {
+ const envConfig = dotenv.parse(fs.readFileSync(envPath));
+ for (const k of Object.keys(envConfig)) {
+ process.env[k] = envConfig[k]
+ }
+ } catch (err) {
+ if (err.code === 'ENOENT') {
+ console.log('WARN: Specific environment not loaded');
+ } else {
+ throw err;
+ }
+ }
+}
+// console.log('Charged Environment',process.env,'\r\n___ . ___');
diff --git a/api-gateway/src/helpers/guardians.ts b/api-gateway/src/helpers/guardians.ts
index 4b9a88d218..44660dd5d3 100644
--- a/api-gateway/src/helpers/guardians.ts
+++ b/api-gateway/src/helpers/guardians.ts
@@ -457,7 +457,8 @@ export class Guardians extends NatsService {
* @param username
*/
public async getBalance(username: string): Promise {
- return await this.sendMessage(MessageAPI.GET_BALANCE, { username });
+ const b = await this.sendMessage(MessageAPI.GET_BALANCE, { username });
+ return b as string;
}
/**
@@ -1507,4 +1508,45 @@ export class Guardians extends NatsService {
const file = await this.sendMessage(MessageAPI.THEME_EXPORT_FILE, { themeId, owner }) as any;
return Buffer.from(file, 'base64');
}
+
+ /**
+ * Create policy by wizard
+ * @param config Config
+ * @returns Config
+ */
+ // tslint:disable-next-line:completed-docs
+ public async wizardPolicyCreate(config: any, owner: string): Promise<{ wizardConfig: any; policyId: string; }> {
+ return await this.sendMessage(MessageAPI.WIZARD_POLICY_CREATE, {
+ owner,
+ config,
+ });
+ }
+
+ /**
+ * Create policy by wizard
+ * @param config Config
+ * @returns Config
+ */
+ public async wizardPolicyCreateAsync(config: any, owner: string, taskId: string) {
+ return await this.sendMessage(MessageAPI.WIZARD_POLICY_CREATE_ASYNC, {
+ owner,
+ config,
+ taskId
+ });
+ }
+
+ /**
+ * Get new policy config
+ * @param policyId Policy Identifier
+ * @param config Config
+ * @returns Config
+ */
+ // tslint:disable-next-line:completed-docs
+ public async wizardGetPolicyConfig(policyId: string, config: any, owner: string): Promise<{ wizardConfig: any; policyConfig: any; }> {
+ return await this.sendMessage(MessageAPI.WIZARD_GET_POLICY_CONFIG, {
+ policyId,
+ config,
+ owner,
+ });
+ }
}
diff --git a/api-gateway/src/middlewares/validation/schemas/accounts.ts b/api-gateway/src/middlewares/validation/schemas/accounts.ts
index 4378323851..62323cb5dc 100644
--- a/api-gateway/src/middlewares/validation/schemas/accounts.ts
+++ b/api-gateway/src/middlewares/validation/schemas/accounts.ts
@@ -1,5 +1,30 @@
import * as yup from 'yup';
import fieldsValidation from '../fields-validation'
+import { IsNotEmpty } from 'class-validator';
+import { UserRole } from '@guardian/interfaces';
+
+export class LoginUserDTO {
+ @IsNotEmpty()
+ username: string;
+
+ @IsNotEmpty()
+ password: string;
+}
+
+export class RegisterUserDTO {
+ @IsNotEmpty()
+ username: string;
+
+ @IsNotEmpty()
+ password: string;
+
+ @IsNotEmpty()
+ // tslint:disable-next-line:variable-name
+ password_confirmation: string;
+
+ @IsNotEmpty()
+ role: UserRole | string
+}
export const registerSchema = () => {
const { username, password, password_confirmation, role } = fieldsValidation
diff --git a/api-tests/index.js b/api-tests/index.js
index 43f92adb3e..240e0ea608 100644
--- a/api-tests/index.js
+++ b/api-tests/index.js
@@ -18,12 +18,12 @@ describe('Tests', async function () {
before(async function () {
this.timeout(10000000000);
const pathArray = [
- [path.resolve(path.join('..', 'logger-service')), {}],
- [path.resolve(path.join('..', 'worker-service')), {IPFS_STORAGE_API_KEY: process.env.IPFS_STORAGE_API_KEY}],
- [path.resolve(path.join('..', 'auth-service')), {HASHICORP_ADDRESS: `http://${process.env.HASHICORP_HOST}:${process.env.HASHICORP_PORT}`}],
- [path.resolve(path.join('..', 'policy-service')), {OPERATOR_ID: process.env.OPERATOR_ID, OPERATOR_KEY: process.env.OPERATOR_KEY}],
- [path.resolve(path.join('..', 'guardian-service')), {OPERATOR_ID: process.env.OPERATOR_ID, OPERATOR_KEY: process.env.OPERATOR_KEY}],
- [path.resolve(path.join('..', 'api-gateway')), {}]
+ [path.resolve(path.join('..', 'logger-service')), {GUARDIAN_ENV: 'develop'}],
+ [path.resolve(path.join('..', 'worker-service')), {IPFS_STORAGE_API_KEY: process.env.IPFS_STORAGE_API_KEY, GUARDIAN_ENV: 'develop'}],
+ [path.resolve(path.join('..', 'auth-service')), {HASHICORP_ADDRESS: `http://${process.env.HASHICORP_HOST}:${process.env.HASHICORP_PORT}`, GUARDIAN_ENV: 'develop'}],
+ [path.resolve(path.join('..', 'policy-service')), {OPERATOR_ID: process.env.OPERATOR_ID, OPERATOR_KEY: process.env.OPERATOR_KEY, GUARDIAN_ENV: 'develop'}],
+ [path.resolve(path.join('..', 'guardian-service')), {OPERATOR_ID: process.env.OPERATOR_ID, OPERATOR_KEY: process.env.OPERATOR_KEY, GUARDIAN_ENV: 'develop'}],
+ [path.resolve(path.join('..', 'api-gateway')), {GUARDIAN_ENV: 'develop'}]
];
for (let p of pathArray) {
processes.push(
diff --git a/api-tests/package.json b/api-tests/package.json
index 27c53692fe..bff3990ff5 100644
--- a/api-tests/package.json
+++ b/api-tests/package.json
@@ -1,6 +1,6 @@
{
"name": "api-tests",
- "version": "2.12.2",
+ "version": "2.13.0-prerelease",
"description": "API Tests",
"main": "index.js",
"scripts": {
@@ -18,5 +18,6 @@
"dependencies": {
"axios": "^1.3.6",
"dotenv": "^16.0.1"
- }
+ },
+ "stableVersion": "2.12.0"
}
diff --git a/application-events/package.json b/application-events/package.json
index 58ba5437b6..1d5215ca05 100644
--- a/application-events/package.json
+++ b/application-events/package.json
@@ -1,6 +1,6 @@
{
"name": "application-events",
- "version": "2.12.2",
+ "version": "1.0.0",
"description": "",
"main": "index.js",
"scripts": {
diff --git a/auth-service/.env b/auth-service/.env
index 54e02489af..18face0ea2 100644
--- a/auth-service/.env
+++ b/auth-service/.env
@@ -1,18 +1 @@
-ENV="develop"
-HEDERA_NET="testnet"
-PREUSED_HEDERA_NET="testnet"
-MQ_ADDRESS="localhost"
-SERVICE_CHANNEL="auth-service"
-ACCESS_TOKEN_SECRET="youraccesstokensecret"
-DB_HOST="localhost"
-DB_DATABASE="auth_db"
-VAULT_PROVIDER="database"
-HASHICORP_TOKEN="1234"
-HASHICORP_ADDRESS="http://localhost:8200"
-HASHICORP_NAMESPACE="admin"
-HASHICORP_ENCRIPTION_ALG="sha512"
-MQ_MAX_PAYLOAD="1048576"
-#LOG_LEVEL="2"
-#HASHICORP_USEAL_KEY=""
-#IMPORT_KEYS_FROM_DB=1
-#MQ_MESSAGE_CHUNK=5000000
+GUARDIAN_ENV=""
diff --git a/auth-service/.env.docker b/auth-service/.env.docker
index 337b612d26..ef5c546786 100644
--- a/auth-service/.env.docker
+++ b/auth-service/.env.docker
@@ -1,17 +1,25 @@
-HEDERA_NET="testnet"
-PREUSED_HEDERA_NET="testnet"
MQ_ADDRESS="message-broker"
SERVICE_CHANNEL="auth-service"
-ACCESS_TOKEN_SECRET="youraccesstokensecret"
DB_HOST="mongo"
DB_DATABASE="auth_db"
-VAULT_PROVIDER="database"
-HASHICORP_TOKEN="1234"
-HASHICORP_ADDRESS="http://vault:8200"
-HASHICORP_NAMESPACE="admin"
+
HASHICORP_ENCRIPTION_ALG="sha512"
MQ_MAX_PAYLOAD="1048576"
#LOG_LEVEL="2"
#HASHICORP_UNSEAL_KEY=""
#IMPORT_KEYS_FROM_DB=1
#MQ_MESSAGE_CHUNK=5000000
+
+# Vault Secret Manager Configs
+VAULT_API_VERSION=v1
+VAULT_ADDRESS=https://vault:8200
+
+VAULT_CA_CERT=tls/vault/client/ca.crt
+VAULT_CLIENT_CERT=tls/vault/client/tls.crt
+VAULT_CLIENT_KEY=tls/vault/client/tls.key
+
+VAULT_APPROLE_ROLE_ID=
+VAULT_APPROLE_SECRET_ID=
+
+# AWS Secret Manager Configs
+AWS_REGION=
diff --git a/auth-service/.env.docker.example b/auth-service/.env.docker.example
deleted file mode 100644
index d86cc7383e..0000000000
--- a/auth-service/.env.docker.example
+++ /dev/null
@@ -1,24 +0,0 @@
-MQ_ADDRESS="message-broker"
-SERVICE_CHANNEL="auth-service"
-DB_HOST="mongo"
-DB_DATABASE="auth_db"
-
-HASHICORP_ENCRIPTION_ALG="sha512"
-
-#LOG_LEVEL="2"
-#IMPORT_KEYS_FROM_DB=1
-#MQ_MESSAGE_CHUNK=5000000
-
-# Vault Secret Manager Configs
-VAULT_API_VERSION=v1
-VAULT_ADDRESS=https://vault:8200
-
-VAULT_CA_CERT=tls/vault/client/ca.crt
-VAULT_CLIENT_CERT=tls/vault/client/tls.crt
-VAULT_CLIENT_KEY=tls/vault/client/tls.key
-
-VAULT_APPROLE_ROLE_ID=
-VAULT_APPROLE_SECRET_ID=
-
-# AWS Secret Manager Configs
-AWS_REGION=
diff --git a/auth-service/.env.example b/auth-service/.env.example
deleted file mode 100644
index b7c604dfd5..0000000000
--- a/auth-service/.env.example
+++ /dev/null
@@ -1,24 +0,0 @@
-MQ_ADDRESS="localhost"
-SERVICE_CHANNEL="auth-service"
-DB_HOST="localhost"
-DB_DATABASE="auth_db"
-
-HASHICORP_ENCRIPTION_ALG="sha512"
-
-#LOG_LEVEL="2"
-#IMPORT_KEYS_FROM_DB=1
-#MQ_MESSAGE_CHUNK=5000000
-
-# Vault Secret Manager Configs
-VAULT_API_VERSION=v1
-VAULT_ADDRESS=https://localhost:8200
-
-VAULT_CA_CERT=tls/vault/client/ca.crt
-VAULT_CLIENT_CERT=tls/vault/client/tls.crt
-VAULT_CLIENT_KEY=tls/vault/client/tls.key
-
-VAULT_APPROLE_ROLE_ID=
-VAULT_APPROLE_SECRET_ID=
-
-# AWS Secret Manager Configs
-AWS_REGION=
diff --git a/auth-service/.env.template b/auth-service/.env.template
new file mode 100644
index 0000000000..dd4ffe0d89
--- /dev/null
+++ b/auth-service/.env.template
@@ -0,0 +1,2 @@
+GUARDIAN_ENV=""
+#OVVERRIDE="false"
\ No newline at end of file
diff --git a/auth-service/Dockerfile b/auth-service/Dockerfile
index c52b48d39b..62475f3570 100644
--- a/auth-service/Dockerfile
+++ b/auth-service/Dockerfile
@@ -36,7 +36,8 @@ COPY --from=interfacesModuleBuilder /usr/local/interfaces/guardian-interfaces-*.
COPY --from=commonModuleBuilder /usr/local/common/guardian-common-*.tgz /tmp/common.tgz
COPY --from=authServiceBuilder /usr/local/auth-service/yarn.lock ./
COPY ./auth-service/package.json ./
-# COPY ./auth-service/.env.docker ./.env
+RUN mkdir -p ./configs
+COPY ./auth-service/configs/* ./configs
RUN node -e "const fs=require('fs'); const input=JSON.parse(fs.readFileSync('package.json')); input.dependencies['@guardian/interfaces']='file:/tmp/interfaces.tgz'; fs.writeFileSync('package.json', JSON.stringify(input));"
RUN node -e "const fs=require('fs'); const input=JSON.parse(fs.readFileSync('package.json')); input.dependencies['@guardian/common']='file:/tmp/common.tgz'; fs.writeFileSync('package.json', JSON.stringify(input));"
RUN yarn install --frozen-lockfile
diff --git a/auth-service/configs/.env.auth b/auth-service/configs/.env.auth
new file mode 100644
index 0000000000..5df57d6971
--- /dev/null
+++ b/auth-service/configs/.env.auth
@@ -0,0 +1,21 @@
+# Auth Service Specialized Variables
+SERVICE_CHANNEL="auth-service"
+DB_DATABASE="auth_db"
+DIRECT_MESSAGE_PORT="6555"
+
+# Ecosystem Defined Variables
+HEDERA_NET="testnet"
+PREUSED_HEDERA_NET="testnet"
+MQ_ADDRESS="localhost"
+ACCESS_TOKEN_SECRET="youraccesstokensecret"
+DB_HOST="localhost"
+VAULT_PROVIDER="database"
+HASHICORP_TOKEN="1234"
+HASHICORP_ADDRESS="http://localhost:8200"
+HASHICORP_NAMESPACE="admin"
+HASHICORP_ENCRIPTION_ALG="sha512"
+MQ_MAX_PAYLOAD="1048576"
+#LOG_LEVEL="2"
+#HASHICORP_UNSEAL_KEY=""
+#IMPORT_KEYS_FROM_DB=1
+#MQ_MESSAGE_CHUNK=5000000
diff --git a/auth-service/configs/.env.auth.develop b/auth-service/configs/.env.auth.develop
new file mode 100644
index 0000000000..a151dfd1fa
--- /dev/null
+++ b/auth-service/configs/.env.auth.develop
@@ -0,0 +1,21 @@
+# Auth Service Specialized Variables
+SERVICE_CHANNEL="auth-service"
+DB_DATABASE="auth_db"
+#DIRECT_MESSAGE_PORT="6555"
+
+# Ecosystem Defined Variables
+HEDERA_NET="testnet"
+PREUSED_HEDERA_NET="testnet"
+MQ_ADDRESS="localhost"
+ACCESS_TOKEN_SECRET="youraccesstokensecret"
+DB_HOST="localhost"
+VAULT_PROVIDER="database"
+HASHICORP_TOKEN="1234"
+HASHICORP_ADDRESS="http://localhost:8200"
+HASHICORP_NAMESPACE="admin"
+HASHICORP_ENCRIPTION_ALG="sha512"
+MQ_MAX_PAYLOAD="1048576"
+#LOG_LEVEL="2"
+#HASHICORP_UNSEAL_KEY=""
+#IMPORT_KEYS_FROM_DB=1
+#MQ_MESSAGE_CHUNK=5000000
diff --git a/auth-service/configs/.env.auth.template b/auth-service/configs/.env.auth.template
new file mode 100644
index 0000000000..27145af8a9
--- /dev/null
+++ b/auth-service/configs/.env.auth.template
@@ -0,0 +1,21 @@
+# Auth Service Specialized Variables
+SERVICE_CHANNEL="auth-service"
+DB_DATABASE="auth_db"
+DIRECT_MESSAGE_PORT="6555"
+
+# Ecosystem Defined Variables
+HEDERA_NET=""
+PREUSED_HEDERA_NET=""
+MQ_ADDRESS=""
+ACCESS_TOKEN_SECRET="youraccesstokensecret"
+DB_HOST=""
+VAULT_PROVIDER="database"
+HASHICORP_TOKEN="1234"
+HASHICORP_ADDRESS=""
+HASHICORP_NAMESPACE="admin"
+HASHICORP_ENCRIPTION_ALG="sha512"
+MQ_MAX_PAYLOAD=""
+#LOG_LEVEL="2"
+#HASHICORP_UNSEAL_KEY=""
+#IMPORT_KEYS_FROM_DB=1
+#MQ_MESSAGE_CHUNK=5000000
diff --git a/auth-service/package.json b/auth-service/package.json
index ee94740f81..25a438487e 100644
--- a/auth-service/package.json
+++ b/auth-service/package.json
@@ -6,14 +6,20 @@
},
"author": "Envision Blockchain Solutions ",
"dependencies": {
- "@guardian/common": "^2.12.2",
- "@guardian/interfaces": "^2.12.2",
- "@mikro-orm/core": "~5.7.5",
- "@mikro-orm/mongodb": "~5.7.5",
+ "@guardian/common": "^2.13.0-prerelease",
+ "@guardian/interfaces": "^2.13.0-prerelease",
+ "@mikro-orm/core": "~5.7.7",
+ "@mikro-orm/mongodb": "~5.7.7",
+ "@nestjs/common": "^9.4.1",
+ "@nestjs/core": "^9.4.1",
+ "@nestjs/microservices": "^9.4.1",
"dotenv": "^16.0.0",
+ "express": "^4.17.1",
"jsonwebtoken": "^8.5.1",
"module-alias": "^2.2.2",
"node-vault": "^0.9.22",
+ "prom-client": "^14.1.1",
+ "prometheus-api-metrics": "3.2.2",
"reflect-metadata": "^0.1.13"
},
"description": "",
@@ -47,5 +53,6 @@
"start": "node dist/index.js",
"test": "mocha tests/**/*.test.js --reporter mocha-junit-reporter --reporter-options mochaFile=../test_results/ui-service.xml"
},
- "version": "2.12.2"
+ "version": "2.13.0-prerelease",
+ "stableVersion": "2.12.0"
}
diff --git a/auth-service/src/api/account-service.ts b/auth-service/src/api/account-service.ts
index 60ad7ec9e5..cb91ff91e4 100644
--- a/auth-service/src/api/account-service.ts
+++ b/auth-service/src/api/account-service.ts
@@ -3,31 +3,27 @@ import { sign, verify } from 'jsonwebtoken';
import { User } from '@entity/user';
import * as util from 'util';
import crypto from 'crypto';
+import { DataBaseHelper, Logger, MessageError, MessageResponse, NatsService, SecretManager, Singleton } from '@guardian/common';
import {
- MessageResponse,
- MessageError,
- Logger,
- DataBaseHelper, NatsService, Singleton
-} from '@guardian/common';
-import {
- AuthEvents, UserRole,
- IGetUserByTokenMessage,
- IRegisterNewUserMessage,
+ AuthEvents,
+ GenerateUUIDv4,
IGenerateTokenMessage,
IGenerateTokenResponse,
IGetAllUserResponse,
IGetDemoUserResponse,
- IGetUserMessage,
- IUpdateUserMessage,
- ISaveUserMessage,
IGetUserByIdMessage,
+ IGetUserByTokenMessage,
+ IGetUserMessage,
+ IGetUsersByAccountMessage,
IGetUsersByIdMessage,
IGetUsersByIRoleMessage,
- IUser,
+ IRegisterNewUserMessage,
+ ISaveUserMessage,
IStandardRegistryUserResponse,
- IGetUsersByAccountMessage, GenerateUUIDv4
+ IUpdateUserMessage,
+ IUser,
+ UserRole
} from '@guardian/interfaces';
-import { SecretManager } from '@guardian/common/dist/secret-manager';
/**
* Account service
diff --git a/auth-service/src/api/wallet-service.ts b/auth-service/src/api/wallet-service.ts
index d656e11edf..0e5c9d409f 100644
--- a/auth-service/src/api/wallet-service.ts
+++ b/auth-service/src/api/wallet-service.ts
@@ -1,17 +1,6 @@
import { User } from '@entity/user';
-import {
- MessageResponse,
- MessageError,
- Logger,
- DataBaseHelper, NatsService, Singleton,
-} from '@guardian/common';
-import {
- WalletEvents,
- IGetKeyMessage,
- ISetKeyMessage,
- IGetKeyResponse,
- IGetGlobalApplicationKey, ISetGlobalApplicationKey, GenerateUUIDv4
-} from '@guardian/interfaces';
+import { DataBaseHelper, Logger, MessageError, MessageResponse, NatsService, Singleton, } from '@guardian/common';
+import { GenerateUUIDv4, IGetGlobalApplicationKey, IGetKeyMessage, IGetKeyResponse, ISetGlobalApplicationKey, ISetKeyMessage, WalletEvents } from '@guardian/interfaces';
import { IVault } from '../vaults';
/**
diff --git a/auth-service/src/app.module.ts b/auth-service/src/app.module.ts
new file mode 100644
index 0000000000..01068c524a
--- /dev/null
+++ b/auth-service/src/app.module.ts
@@ -0,0 +1,4 @@
+import { Module } from '@nestjs/common';
+
+@Module({})
+export class AppModule {}
diff --git a/auth-service/src/app.ts b/auth-service/src/app.ts
index faaaf8b46b..0a57186a4b 100644
--- a/auth-service/src/app.ts
+++ b/auth-service/src/app.ts
@@ -1,23 +1,16 @@
import { fixtures } from '@helpers/fixtures';
import { AccountService } from '@api/account-service';
import { WalletService } from '@api/wallet-service';
-import {
- ApplicationState,
- MessageBrokerChannel,
- Logger,
- DataBaseHelper,
- Migration,
- COMMON_CONNECTION_CONFIG,
- LargePayloadContainer
-} from '@guardian/common';
+import { ApplicationState, COMMON_CONNECTION_CONFIG, DataBaseHelper, LargePayloadContainer, Logger, MessageBrokerChannel, Migration, OldSecretManager, SecretManager } from '@guardian/common';
import { ApplicationStates } from '@guardian/interfaces';
import { MikroORM } from '@mikro-orm/core';
import { MongoDriver } from '@mikro-orm/mongodb';
import { InitializeVault } from './vaults';
import { ImportKeysFromDatabase } from '@helpers/import-keys-from-database';
import process from 'process';
-import { SecretManager } from '@guardian/common/dist/secret-manager';
-import { OldSecretManager } from '@guardian/common/dist/secret-manager/old-style/old-secret-manager';
+import { NestFactory } from '@nestjs/core';
+import { AppModule } from './app.module';
+import { MicroserviceOptions, Transport } from '@nestjs/microservices';
Promise.all([
Migration({
@@ -35,8 +28,17 @@ Promise.all([
ensureIndexes: true
}),
MessageBrokerChannel.connect('AUTH_SERVICE'),
+ NestFactory.createMicroservice(AppModule,{
+ transport: Transport.NATS,
+ options: {
+ name: `${process.env.SERVICE_CHANNEL}`,
+ servers: [
+ `nats://${process.env.MQ_ADDRESS}:4222`
+ ]
+ },
+ }),
InitializeVault(process.env.VAULT_PROVIDER)
-]).then(async ([_, db, cn, vault]) => {
+]).then(async ([_, db, cn, app, vault]) => {
DataBaseHelper.orm = db;
const state = new ApplicationState();
await state.setServiceName('AUTH_SERVICE').setConnection(cn).init();
@@ -44,6 +46,10 @@ Promise.all([
try {
await fixtures();
+ console.log(app);
+
+ app.listen();
+
new Logger().setConnection(cn);
await new AccountService().setConnection(cn).init();
new AccountService().registerListeners();
@@ -74,6 +80,8 @@ Promise.all([
console.error(error.message);
process.exit(1);
}
+
+ // startMetricsServer();
}, (reason) => {
console.log(reason);
process.exit(0);
diff --git a/auth-service/src/config.ts b/auth-service/src/config.ts
index fe48bc62a8..b3e587a95a 100644
--- a/auth-service/src/config.ts
+++ b/auth-service/src/config.ts
@@ -1,5 +1,6 @@
import moduleAlias from 'module-alias';
import dotenv from 'dotenv';
+import fs from 'fs';
moduleAlias.addAliases({
'@api': __dirname + '/api',
@@ -8,3 +9,24 @@ moduleAlias.addAliases({
});
dotenv.config();
+
+const envPath = process.env.GUARDIAN_ENV ? `./configs/.env.auth.${process.env.GUARDIAN_ENV}` : './configs/.env.auth';
+
+if (!process.env.OVERRIDE || process.env.OVERRIDE === 'false'){
+ console.log('reading from', envPath, 'not overriding');
+ dotenv.config({ path: envPath});
+}else{
+ try {
+ const envConfig = dotenv.parse(fs.readFileSync(envPath));
+ for (const k of Object.keys(envConfig)) {
+ process.env[k] = envConfig[k]
+ }
+ } catch (err) {
+ if (err.code === 'ENOENT') {
+ console.log('WARN: Specific environment not loaded');
+ } else {
+ throw err;
+ }
+ }
+}
+console.log('Charged Environment',process.env,'\r\n___ . ___');
diff --git a/auth-service/src/entity/user.ts b/auth-service/src/entity/user.ts
index 4351153959..6077b80f5c 100644
--- a/auth-service/src/entity/user.ts
+++ b/auth-service/src/entity/user.ts
@@ -1,4 +1,4 @@
-import { Entity, Property, Enum, BeforeCreate, Unique } from '@mikro-orm/core';
+import { BeforeCreate, Entity, Enum, Property, Unique } from '@mikro-orm/core';
import { IUser, UserRole } from '@guardian/interfaces';
import { BaseEntity } from '@guardian/common';
diff --git a/auth-service/src/utils/metrics.ts b/auth-service/src/utils/metrics.ts
new file mode 100644
index 0000000000..d4c86e45ed
--- /dev/null
+++ b/auth-service/src/utils/metrics.ts
@@ -0,0 +1,20 @@
+import express from 'express';
+import client from 'prom-client';
+import guardianServicePrometheusMetrics from 'prometheus-api-metrics';
+
+const app = express();
+
+const PORT = process.env.METRICS_PORT || 5005;
+
+export const startMetricsServer = () => {
+ app.use(guardianServicePrometheusMetrics());
+ app.get('/metrics', async (req, res) => {
+ res.set('Content-Type', client.register.contentType);
+
+ return res.send(await client.register.metrics());
+ });
+
+ app.listen(PORT, () => {
+ console.log(`auth-service metrics server started at http://localhost:${PORT}`);
+ });
+}
diff --git a/common/package.json b/common/package.json
index bdb746c2cd..9f78315a8b 100644
--- a/common/package.json
+++ b/common/package.json
@@ -2,13 +2,16 @@
"author": "Envision Blockchain Solutions ",
"dependencies": {
"@aws-sdk/client-secrets-manager": "^3.319.0",
- "@guardian/interfaces": "^2.12.2",
- "@hashgraph/sdk": "^2.22.0",
+ "@guardian/interfaces": "^2.13.0-prerelease",
+ "@hashgraph/sdk": "^2.24.2",
"@mattrglobal/jsonld-signatures-bbs": "^1.1.2",
"@meeco/cryppo": "^2.0.2",
- "@mikro-orm/core": "~5.7.5",
- "@mikro-orm/migrations-mongodb": "~5.7.5",
- "@mikro-orm/mongodb": "~5.7.5",
+ "@mikro-orm/core": "~5.7.7",
+ "@mikro-orm/migrations-mongodb": "~5.7.7",
+ "@mikro-orm/mongodb": "~5.7.7",
+ "@nestjs/common": "^9.4.1",
+ "@nestjs/core": "^9.4.1",
+ "@nestjs/microservices": "^9.4.1",
"@transmute/credentials-context": "^0.7.0-unstable.80",
"@transmute/did-context": "^0.7.0-unstable.80",
"@transmute/ed25519-signature-2018": "^0.7.0-unstable.80",
@@ -25,8 +28,9 @@
"lodash.get": "^4.4.2",
"lodash.set": "^4.3.2",
"moment": "^2.29.2",
- "mongodb": "^5.4.0",
+ "mongodb": "5.5.0",
"nats": "^2.6.1",
+ "nestjs": "^0.0.1",
"node-vault": "^0.9.22",
"reflect-metadata": "^0.1.13",
"winston": "^3.8.1",
@@ -59,5 +63,6 @@
"test:local": "mocha tests/**/*.test.js --exit",
"test:stability": "mocha tests/stability.test.js"
},
- "version": "2.12.2"
+ "version": "2.13.0-prerelease",
+ "stableVersion": "2.12.0"
}
diff --git a/common/src/database-modules/database-server.ts b/common/src/database-modules/database-server.ts
index f8b36bba54..243a8aa910 100644
--- a/common/src/database-modules/database-server.ts
+++ b/common/src/database-modules/database-server.ts
@@ -22,7 +22,8 @@ import {
PolicyModule,
Tag,
TagCache,
- Contract as ContractCollection
+ Contract as ContractCollection,
+ ExternalDocument
} from '../entity';
import { Binary } from 'bson';
import {
@@ -77,6 +78,7 @@ export class DatabaseServer {
this.classMap.set(SplitDocuments, 'SplitDocuments');
this.classMap.set(Tag, 'Tag');
this.classMap.set(TagCache, 'TagCache');
+ this.classMap.set(ExternalDocument, 'ExternalDocument');
}
/**
@@ -242,9 +244,25 @@ export class DatabaseServer {
* @param criteria
* @param row
*/
- private async update(entityClass: new () => T, criteria: any, row: T): Promise {
+ private async update(
+ entityClass: new () => T,
+ criteria: any,
+ row: any
+ ): Promise {
if (this.dryRun) {
- return await new DataBaseHelper(DryRun).update(row, criteria) as any;
+ if (Array.isArray(row)) {
+ for (const i of row) {
+ i.dryRunId = this.dryRun;
+ i.dryRunClass = this.classMap.get(entityClass);
+ }
+ } else {
+ row.dryRunId = this.dryRun;
+ row.dryRunClass = this.classMap.get(entityClass);
+ }
+ return (await new DataBaseHelper(DryRun).update(
+ row,
+ criteria
+ )) as any;
} else {
return await new DataBaseHelper(entityClass).update(row, criteria);
}
@@ -1345,6 +1363,69 @@ export class DatabaseServer {
});
}
+ /**
+ * Get External Topic
+ * @param policyId
+ * @param blockId
+ * @param userId
+ *
+ * @virtual
+ */
+ public async getExternalTopic(
+ policyId: string,
+ blockId: string,
+ userId: string
+ ): Promise {
+ return await this.findOne(ExternalDocument, {
+ where: {
+ policyId: { $eq: policyId },
+ blockId: { $eq: blockId },
+ owner: { $eq: userId }
+ }
+ });
+ }
+
+ /**
+ * Create External Topic
+ * @param row
+ *
+ * @virtual
+ */
+ public async createExternalTopic(row: any): Promise {
+ const item = this.create(ExternalDocument, row);
+ return await this.save(ExternalDocument, item);
+ }
+
+ /**
+ * Update External Topic
+ * @param row
+ *
+ * @virtual
+ */
+ public async updateExternalTopic(item: ExternalDocument): Promise {
+ return await this.save(ExternalDocument, item);
+ }
+
+ /**
+ * Get Active External Topic
+ * @param policyId
+ * @param blockId
+ *
+ * @virtual
+ */
+ public async getActiveExternalTopics(
+ policyId: string,
+ blockId: string
+ ): Promise {
+ return await this.find(ExternalDocument, {
+ where: {
+ policyId: { $eq: policyId },
+ blockId: { $eq: blockId },
+ active: { $eq: true }
+ }
+ });
+ }
+
/**
* Create tag
* @param tag
diff --git a/common/src/document-loader/dry-run-loader.ts b/common/src/document-loader/dry-run-loader.ts
new file mode 100644
index 0000000000..d939a7f9b4
--- /dev/null
+++ b/common/src/document-loader/dry-run-loader.ts
@@ -0,0 +1,44 @@
+import { DidRootKey, DocumentLoader, IDocumentFormat } from '../hedera-modules';
+import { DataBaseHelper } from '../helpers';
+import { DidDocument, DryRun } from '../entity';
+
+/**
+ * Dry Run loader
+ */
+export class DryRunLoader extends DocumentLoader {
+ /**
+ * Has context
+ * @param iri
+ */
+ public async has(iri: string): Promise {
+ const did = DidRootKey.create(iri).getController();
+ const document= await new DataBaseHelper(DryRun).findOne({did, dryRunClass: 'DidDocumentCollection'});
+ return !!document;
+ }
+
+ /**
+ * Get formatted document
+ * @param iri
+ */
+ public async get(iri: string): Promise {
+ const did = DidRootKey.create(iri).getController();
+ const document= await new DataBaseHelper(DryRun).findOne({did, dryRunClass: 'DidDocumentCollection'});
+ return {
+ documentUrl: iri,
+ document: document.document
+ };
+ }
+
+ /**
+ * Get document
+ * @param iri
+ */
+ public async getDocument(iri: string): Promise {
+ const did = DidRootKey.create(iri).getController();
+ const didDocuments = await new DataBaseHelper(DidDocument).findOne({ did });
+ if (didDocuments) {
+ return didDocuments.document;
+ }
+ throw new Error(`DID not found: ${iri}`);
+ }
+}
diff --git a/common/src/document-loader/hedera-loader.ts b/common/src/document-loader/hedera-loader.ts
new file mode 100644
index 0000000000..bc5ed74b81
--- /dev/null
+++ b/common/src/document-loader/hedera-loader.ts
@@ -0,0 +1,78 @@
+import { DidRootKey, DocumentLoader, IDocumentFormat } from '../hedera-modules';
+import { DataBaseHelper, IPFS, Workers } from '../helpers';
+import { DidDocument } from '../entity';
+import { WorkerTaskType } from '@guardian/interfaces';
+
+/**
+ * Hedera loader
+ */
+export class HederaLoader extends DocumentLoader {
+ /**
+ * Has context
+ * @param iri
+ */
+ public async has(iri: string): Promise {
+ if (!iri.startsWith('did:hedera:')) {
+ return false;
+ }
+ const document = await this.getDocument(iri);
+ return !document;
+
+ }
+
+ /**
+ * Get formatted document
+ * @param iri
+ */
+ public async get(iri: string): Promise {
+ const did = DidRootKey.create(iri).getController();
+ const splittedDid = did.split('_');
+ const topicId = splittedDid[splittedDid.length - 1];
+
+ const messages = await new Workers().addRetryableTask(
+ {
+ type: WorkerTaskType.GET_TOPIC_MESSAGES,
+ data: {
+ operatorId: null,
+ operatorKey: null,
+ dryRun: false,
+ topic: topicId,
+ },
+ },
+ 10
+ );
+ const didMessage = messages
+ .map(m => {
+ try {
+ return JSON.parse(m.message);
+ } catch (e) {
+ return undefined;
+ }
+ })
+ .find(m => {
+ return (m.type === 'DID-Document') && (m.did === did)
+ });
+ if (!didMessage) {
+ return null
+ }
+ const didDocument = await IPFS.getFile(didMessage.cid, 'json')
+
+ return {
+ documentUrl: iri,
+ document: didDocument
+ };
+ }
+
+ /**
+ * Get document
+ * @param iri
+ */
+ public async getDocument(iri: string): Promise {
+ const did = DidRootKey.create(iri).getController();
+ const didDocuments = await new DataBaseHelper(DidDocument).findOne({ did });
+ if (didDocuments) {
+ return didDocuments.document;
+ }
+ return false;
+ }
+}
diff --git a/common/src/document-loader/index.ts b/common/src/document-loader/index.ts
index a4f0691141..647362a7f8 100644
--- a/common/src/document-loader/index.ts
+++ b/common/src/document-loader/index.ts
@@ -3,3 +3,5 @@ export * from './did-document-loader';
export * from './schema-document-loader';
export * from './subject-schema-loader';
export * from './vc-schema-loader';
+export * from './dry-run-loader';
+export * from './hedera-loader';
diff --git a/common/src/entity/aggregate-documents.ts b/common/src/entity/aggregate-documents.ts
index 20bf5ddeb1..65fbbe902a 100644
--- a/common/src/entity/aggregate-documents.ts
+++ b/common/src/entity/aggregate-documents.ts
@@ -56,7 +56,7 @@ export class AggregateVC extends BaseEntity {
/**
* Document instance
*/
- @Property({ nullable: true })
+ @Property({ nullable: true, type: 'unknown' })
document?: IVC;
/**
@@ -182,6 +182,12 @@ export class AggregateVC extends BaseEntity {
@Property({ nullable: true })
messageIds?: string[];
+ /**
+ * Source document identifier
+ */
+ @Property({ nullable: true })
+ sourceDocumentId?: ObjectId;
+
/**
* Create document
*/
diff --git a/common/src/entity/dry-run.ts b/common/src/entity/dry-run.ts
index 5638a79ba4..a796ee4762 100644
--- a/common/src/entity/dry-run.ts
+++ b/common/src/entity/dry-run.ts
@@ -308,7 +308,7 @@ export class DryRun extends BaseEntity {
/**
* IRI
*/
- @Property({ nullable: true, type: 'unknown'})
+ @Property({ nullable: true, type: 'unknown' })
iri?: any;
/**
@@ -545,6 +545,66 @@ export class DryRun extends BaseEntity {
@Property({ nullable: true })
uri?: string;
+ /**
+ * Source document identifier
+ */
+ @Property({ nullable: true })
+ sourceDocumentId?: ObjectId;
+
+ /**
+ * Document Topic Id
+ */
+ @Property({ nullable: true, type: 'unknown' })
+ documentTopicId?: any;
+
+ /**
+ * Policy Topic Id
+ */
+ @Property({ nullable: true, type: 'unknown' })
+ policyTopicId?: any;
+
+ /**
+ * Document Message
+ */
+ @Property({ nullable: true, type: 'unknown' })
+ documentMessage?: any;
+
+ /**
+ * Policy Message
+ */
+ @Property({ nullable: true, type: 'unknown' })
+ policyMessage?: any;
+
+ /**
+ * Policy Instance Message
+ */
+ @Property({ nullable: true, type: 'unknown' })
+ policyInstanceMessage?: any;
+
+ /**
+ * Schemas
+ */
+ @Property({ nullable: true, type: 'unknown' })
+ schemas?: any;
+
+ /**
+ * Schema Id
+ */
+ @Property({ nullable: true, type: 'unknown' })
+ schemaId?: any;
+
+ /**
+ * Last Message
+ */
+ @Property({ nullable: true, type: 'unknown' })
+ lastMessage?: any;
+
+ /**
+ * Last Update
+ */
+ @Property({ nullable: true, type: 'unknown' })
+ lastUpdate?: any;
+
/**
* Default document values
*/
@@ -584,9 +644,9 @@ export class DryRun extends BaseEntity {
if (
(typeof fieldValue === 'string' &&
fieldValue.length <
- (+process.env
- .DOCUMENT_CACHE_FIELD_LIMIT ||
- 100)) ||
+ (+process.env
+ .DOCUMENT_CACHE_FIELD_LIMIT ||
+ 100)) ||
typeof fieldValue === 'number'
) {
ObjSet(newDocument, field, fieldValue);
diff --git a/common/src/entity/external-document.ts b/common/src/entity/external-document.ts
new file mode 100644
index 0000000000..ca86b651ad
--- /dev/null
+++ b/common/src/entity/external-document.ts
@@ -0,0 +1,117 @@
+import { BeforeCreate, Entity, Property } from '@mikro-orm/core';
+import { BaseEntity } from '../models';
+
+/**
+ * Artifact collection
+ */
+@Entity()
+export class ExternalDocument extends BaseEntity {
+ /**
+ * Block UUID
+ */
+ @Property({ nullable: true })
+ blockId?: string;
+
+ /**
+ * Policy id
+ */
+ @Property({
+ nullable: true,
+ index: true,
+ })
+ policyId?: string;
+
+ /**
+ * User
+ */
+ @Property({ nullable: true })
+ owner?: string;
+
+ /**
+ * Document Topic Id
+ */
+ @Property({ nullable: true })
+ documentTopicId?: string;
+
+ /**
+ * Policy Topic Id
+ */
+ @Property({ nullable: true })
+ policyTopicId?: string;
+
+ /**
+ * Instance Topic Id
+ */
+ @Property({ nullable: true })
+ instanceTopicId?: string;
+
+ /**
+ * Document Message
+ */
+ @Property({ nullable: true, type: 'unknown' })
+ documentMessage?: any;
+
+ /**
+ * Policy Message
+ */
+ @Property({ nullable: true, type: 'unknown' })
+ policyMessage?: any;
+
+ /**
+ * Policy Instance Message
+ */
+ @Property({ nullable: true, type: 'unknown' })
+ policyInstanceMessage?: any;
+
+ /**
+ * Schemas
+ */
+ @Property({ nullable: true, type: 'unknown' })
+ schemas?: any[];
+
+ /**
+ * Schema
+ */
+ @Property({ nullable: true, type: 'unknown' })
+ schema?: any;
+
+ /**
+ * Schema Id
+ */
+ @Property({ nullable: true })
+ schemaId?: string;
+
+ /**
+ * Status
+ */
+ @Property({ nullable: true })
+ active?: boolean;
+
+ /**
+ * Last Message
+ */
+ @Property({ nullable: true })
+ lastMessage?: string;
+
+ /**
+ * Last Update
+ */
+ @Property({ nullable: true })
+ lastUpdate?: string;
+
+ /**
+ * Status
+ */
+ @Property({ nullable: true })
+ status?: string;
+
+ /**
+ * Default document values
+ */
+ @BeforeCreate()
+ setDefaults() {
+ this.lastMessage = this.lastMessage || '';
+ this.lastUpdate = this.lastUpdate || '';
+ this.active = this.active || false;
+ }
+}
diff --git a/common/src/entity/index.ts b/common/src/entity/index.ts
index b9290e8a56..0cdaf28956 100644
--- a/common/src/entity/index.ts
+++ b/common/src/entity/index.ts
@@ -24,4 +24,5 @@ export * from './token';
export * from './topic';
export * from './vc-document';
export * from './vp-document';
-export * from './theme';
\ No newline at end of file
+export * from './theme';
+export * from './external-document';
\ No newline at end of file
diff --git a/common/src/entity/multi-documents.ts b/common/src/entity/multi-documents.ts
index b81d617ec7..c043d18b02 100644
--- a/common/src/entity/multi-documents.ts
+++ b/common/src/entity/multi-documents.ts
@@ -61,7 +61,7 @@ export class MultiDocuments extends BaseEntity {
/**
* Document instance
*/
- @Property({ persist: false })
+ @Property({ persist: false, type: 'unknown' })
document?: IVC;
/**
diff --git a/common/src/entity/retire-request.ts b/common/src/entity/retire-request.ts
index 6058f06257..65e16980e2 100644
--- a/common/src/entity/retire-request.ts
+++ b/common/src/entity/retire-request.ts
@@ -1,5 +1,6 @@
import { Entity, Property } from '@mikro-orm/core';
import { BaseEntity } from '../models';
+import { ObjectId } from 'mongodb';
/**
* Retire Request
@@ -58,5 +59,5 @@ export class RetireRequest extends BaseEntity {
* Vc Document Hash
*/
@Property({ nullable: true })
- vcDocumentHash?: string;
+ documentId?: ObjectId;
}
\ No newline at end of file
diff --git a/common/src/entity/vc-document.ts b/common/src/entity/vc-document.ts
index 5665e1965a..cdec7d7637 100644
--- a/common/src/entity/vc-document.ts
+++ b/common/src/entity/vc-document.ts
@@ -10,7 +10,6 @@ import {
Property,
Enum,
BeforeCreate,
- Unique,
OnLoad,
BeforeUpdate,
AfterDelete,
@@ -27,10 +26,6 @@ import ObjSet from 'lodash.set';
* VC documents collection
*/
@Entity()
-@Unique({
- properties: ['hash'],
- options: { partialFilterExpression: { hash: { $type: 'string' } } },
-})
export class VcDocument extends BaseEntity implements IVCDocument {
/**
* Document owner
@@ -64,7 +59,7 @@ export class VcDocument extends BaseEntity implements IVCDocument {
*/
@Property({
nullable: true,
- // index: true
+ index: true
})
hash?: string;
diff --git a/common/src/entity/vp-document.ts b/common/src/entity/vp-document.ts
index 697a3037b0..25b55c21a0 100644
--- a/common/src/entity/vp-document.ts
+++ b/common/src/entity/vp-document.ts
@@ -33,7 +33,7 @@ export class VpDocument extends BaseEntity implements IVPDocument {
/**
* Document instance
*/
- @Property({ nullable: true })
+ @Property({ nullable: true, type: 'unknown' })
document?: IVP;
/**
diff --git a/common/src/hedera-modules/message/message-server.ts b/common/src/hedera-modules/message/message-server.ts
index e297171031..635864a8bb 100644
--- a/common/src/hedera-modules/message/message-server.ts
+++ b/common/src/hedera-modules/message/message-server.ts
@@ -227,7 +227,7 @@ export class MessageServer {
message.setLang(MessageServer.lang);
const time = await this.messageStartLog('Hedera');
const buffer = message.toMessage();
- const id = await new Workers().addRetryableTask({
+ const timestamp = await new Workers().addRetryableTask({
type: WorkerTaskType.SEND_HEDERA,
data: {
topicId: this.topicId,
@@ -241,7 +241,7 @@ export class MessageServer {
}
}, 10);
await this.messageEndLog(time, 'Hedera');
- message.setId(id);
+ message.setId(timestamp);
message.setTopicId(this.topicId);
return message;
}
@@ -336,6 +336,8 @@ export class MessageServer {
new Logger().info(`getTopicMessage, ${timeStamp}, ${topicId}, ${message}`, ['GUARDIAN_SERVICE']);
const result = MessageServer.fromMessage(message, type);
+ result.setAccount(message.payer_account_id);
+ result.setIndex(message.sequence_number);
result.setId(timeStamp);
result.setTopicId(topicId);
return result;
@@ -346,12 +348,18 @@ export class MessageServer {
* @param topicId
* @param type
* @param action
+ * @param timestamp
* @private
*/
- private async getTopicMessages(topicId: string | TopicId, type?: MessageType, action?: MessageAction): Promise {
+ private async getTopicMessages(
+ topicId: string | TopicId,
+ type?: MessageType,
+ action?: MessageAction,
+ timestamp?: string
+ ): Promise {
const { operatorId, operatorKey, dryRun } = this.clientOptions;
- if(!topicId) {
+ if (!topicId) {
throw new Error(`Invalid Topic Id`);
}
@@ -363,7 +371,8 @@ export class MessageServer {
operatorId,
operatorKey,
dryRun,
- topic
+ topic,
+ timestamp
}
}, 10);
@@ -380,6 +389,8 @@ export class MessageServer {
filter = filter && item.action === action;
}
if (filter) {
+ item.setAccount(message.payer_account_id);
+ item.setIndex(message.sequence_number);
item.setId(message.id);
item.setTopicId(topic);
result.push(item);
@@ -470,6 +481,55 @@ export class MessageServer {
return await this.loadIPFS(message);
}
+ /**
+ * Load documents
+ * @param message
+ */
+ public async loadDocuments(messages: T[]): Promise {
+ for (const message of messages) {
+ const urls = message.getUrls();
+ const documents: any[] = [];
+ for (const url of urls) {
+ const doc = await this.getFile(url.cid, message.responseType);
+ documents.push(doc);
+ }
+ await message.loadDocuments(documents, this.clientOptions.operatorKey);
+ }
+ return messages;
+ }
+
+ /**
+ * Load document
+ * @param message
+ */
+ public static async loadDocument(message: T, cryptoKey?: string): Promise {
+ const urls = message.getUrls();
+ const documents: any[] = [];
+ for (const url of urls) {
+ const doc = await IPFS.getFile(url.cid, message.responseType);
+ documents.push(doc);
+ }
+ await message.loadDocuments(documents, cryptoKey);
+ return message;
+ }
+
+ /**
+ * Load documents
+ * @param message
+ */
+ public static async loadDocuments(messages: T[], cryptoKey?: string): Promise