From f83d67781e3d41aef7be35ca38e80dbba2e22a2c Mon Sep 17 00:00:00 2001 From: javip97 Date: Tue, 16 Jan 2024 09:22:22 +0100 Subject: [PATCH 01/52] feat: adding Iden3commRevocationStatusV1 --- internal/config/config.go | 2 +- internal/config/credential_status.go | 11 ++- internal/core/services/claims.go | 32 +++++++- internal/core/services/revocation.go | 76 +++++++++++++++++++ .../iden3_revocation_status_v1.go | 18 +++++ pkg/credentials/revocation_status/resolver.go | 3 +- 6 files changed, 137 insertions(+), 5 deletions(-) create mode 100644 pkg/credentials/revocation_status/iden3_revocation_status_v1.go diff --git a/internal/config/config.go b/internal/config/config.go index a6889e3b6..c4bba2d3f 100644 --- a/internal/config/config.go +++ b/internal/config/config.go @@ -224,7 +224,7 @@ func (c *Configuration) sanitizeCredentialStatus(_ context.Context, host string) if c.CredentialStatus.RHSMode == none { c.CredentialStatus.DirectStatus.URL = host - c.CredentialStatus.CredentialStatusType = sparseMerkleTreeProof + c.CredentialStatus.CredentialStatusType = iden3commRevocationStatusV1 } if c.CredentialStatus.RHSMode == offChain { diff --git a/internal/config/credential_status.go b/internal/config/credential_status.go index c07c43a70..18363d1fa 100644 --- a/internal/config/credential_status.go +++ b/internal/config/credential_status.go @@ -1,11 +1,13 @@ package config import ( + "fmt" "strings" ) const ( sparseMerkleTreeProof = "SparseMerkleTreeProof" + iden3commRevocationStatusV1 = "Iden3commRevocationStatusV1.0" iden3ReverseSparseMerkleTreeProof = "Iden3ReverseSparseMerkleTreeProof" iden3OnchainSparseMerkleTreeProof2023 = "Iden3OnchainSparseMerkleTreeProof2023" onChain = "OnChain" @@ -23,7 +25,7 @@ type CredentialStatus struct { OnchainTreeStore OnchainTreeStore `mapstructure:"OnchainTreeStore"` RHSMode RHSMode `tip:"Reverse hash service mode (OffChain, OnChain, Mixed, None)"` SingleIssuer bool - CredentialStatusType string `mapstructure:"CredentialStatusType" default:"SparseMerkleTreeProof"` + CredentialStatusType string `mapstructure:"CredentialStatusType" default:"Iden3commRevocationStatusV1"` } // DirectStatus is the type of direct status @@ -31,11 +33,16 @@ type DirectStatus struct { URL string `mapstructure:"URL"` } -// GetURL returns the URL of the direct status +// GetURL returns the URL of the di rect status func (r *DirectStatus) GetURL() string { return strings.TrimSuffix(r.URL, "/") } +// GetAgentURL returns the URL of the agent endpoint +func (r *DirectStatus) GetAgentURL() string { + return fmt.Sprintf("%s/v1/agent", strings.TrimSuffix(r.URL, "/")) +} + // RHS is the type of RHS type RHS struct { URL string `mapstructure:"URL"` diff --git a/internal/core/services/claims.go b/internal/core/services/claims.go index 1511d1ad7..d56b178a1 100644 --- a/internal/core/services/claims.go +++ b/internal/core/services/claims.go @@ -367,7 +367,14 @@ func (c *claim) Agent(ctx context.Context, req *ports.AgentRequest) (*domain.Age return nil, fmt.Errorf("cannot proceed with this identity, not found") } - return c.getAgentCredential(ctx, req) // at this point the type is already validated + switch req.Type { + case protocol.CredentialFetchRequestMessageType: + return c.getAgentCredential(ctx, req) + case protocol.RevocationStatusRequestMessageType: + return c.getRevocationStatus(ctx, req) + default: + return nil, errors.New("invalid type") + } } func (c *claim) GetAuthClaim(ctx context.Context, did *w3c.DID) (*domain.Claim, error) { @@ -597,6 +604,29 @@ func (c *claim) revoke(ctx context.Context, did *w3c.DID, nonce uint64, descript return nil } +func (c *claim) getRevocationStatus(ctx context.Context, basicMessage *ports.AgentRequest) (*domain.Agent, error) { + revData := &protocol.RevocationStatusRequestMessageBody{} + err := json.Unmarshal(basicMessage.Body, revData) + if err != nil { + return nil, fmt.Errorf("invalid revocation request body: %w", err) + } + + var revStatus *verifiable.RevocationStatus + revStatus, err = c.GetRevocationStatus(ctx, *basicMessage.IssuerDID, revData.RevocationNonce) + if err != nil { + return nil, fmt.Errorf("failed get revocation status: %w", err) + } + + return &domain.Agent{ + ID: uuid.NewString(), + Type: protocol.RevocationStatusResponseMessageType, + ThreadID: basicMessage.ThreadID, + Body: protocol.RevocationStatusResponseMessageBody{RevocationStatus: *revStatus}, + From: basicMessage.IssuerDID.String(), + To: basicMessage.UserDID.String(), + }, nil +} + func (c *claim) getAgentCredential(ctx context.Context, basicMessage *ports.AgentRequest) (*domain.Agent, error) { fetchRequestBody := &protocol.CredentialFetchRequestMessageBody{} err := json.Unmarshal(basicMessage.Body, fetchRequestBody) diff --git a/internal/core/services/revocation.go b/internal/core/services/revocation.go index fe057df5b..e861b67d9 100644 --- a/internal/core/services/revocation.go +++ b/internal/core/services/revocation.go @@ -1,10 +1,12 @@ package services import ( + "bytes" "context" "encoding/json" "errors" "fmt" + "io" "math/big" "net/http" "net/url" @@ -13,12 +15,16 @@ import ( "time" ethCommon "github.com/ethereum/go-ethereum/common" + "github.com/google/uuid" abiOnchain "github.com/iden3/contracts-abi/onchain-credential-status-resolver/go/abi" "github.com/iden3/contracts-abi/state/go/abi" core "github.com/iden3/go-iden3-core/v2" "github.com/iden3/go-iden3-core/v2/w3c" "github.com/iden3/go-merkletree-sql/v2" "github.com/iden3/go-schema-processor/v2/verifiable" + "github.com/iden3/iden3comm/v2" + "github.com/iden3/iden3comm/v2/packers" + "github.com/iden3/iden3comm/v2/protocol" proofHttp "github.com/iden3/merkletree-proof/http" "github.com/polygonid/sh-id-platform/internal/common" @@ -73,6 +79,9 @@ func (r *Revocation) Status(ctx context.Context, credStatus interface{}, issuerD return r.getRevocationStatusFromRHS(ctx, issuerDID, status, issuerData) case verifiable.SparseMerkleTreeProof: return getRevocationProofFromIssuer(ctx, status.ID) + case verifiable.Iden3commRevocationStatusV1: + return getRevocationStatusFromAgent(ctx, issuerDID.String(), + issuerDID.String(), status.ID, status.RevocationNonce) case verifiable.Iden3OnchainSparseMerkleTreeProof2023: return r.getRevocationStatusFromOnchainCredStatusResolver(ctx, issuerDID, status) default: @@ -106,6 +115,73 @@ func convertCredentialStatus(credStatus interface{}) (verifiable.CredentialStatu return verifiable.CredentialStatus{}, errors.New("failed cast credential status to verifiable.CredentialStatus") } +func getRevocationStatusFromAgent(ctx context.Context, from, to, endpoint string, nonce uint64) (*verifiable.RevocationStatus, error) { + pkg := iden3comm.NewPackageManager() + if err := pkg.RegisterPackers(&packers.PlainMessagePacker{}); err != nil { + return nil, err + } + + revocationBody := protocol.RevocationStatusRequestMessageBody{ + RevocationNonce: nonce, + } + rawBody, err := json.Marshal(revocationBody) + if err != nil { + return nil, err + } + + msg := iden3comm.BasicMessage{ + ID: uuid.New().String(), + ThreadID: uuid.New().String(), + From: from, + To: to, + Type: protocol.RevocationStatusRequestMessageType, + Body: rawBody, + } + bytesMsg, err := json.Marshal(msg) + if err != nil { + return nil, err + } + + iden3commMsg, err := pkg.Pack(packers.MediaTypePlainMessage, bytesMsg, nil) + if err != nil { + return nil, err + } + + resp, err := http.DefaultClient.Post(endpoint, "application/json", bytes.NewBuffer(iden3commMsg)) + if err != nil { + return nil, err + } + defer func() { + if err := resp.Body.Close(); err != nil { + log.Warn(ctx, "failed to close response body: %s", err) + } + }() + + if resp.StatusCode != http.StatusOK { + return nil, fmt.Errorf("bad status code: %d", resp.StatusCode) + } + + b, err := io.ReadAll(resp.Body) + if err != nil { + return nil, err + } + basicMessage, _, err := pkg.Unpack(b) + if err != nil { + return nil, err + } + + if basicMessage.Type != protocol.RevocationStatusResponseMessageType { + return nil, fmt.Errorf("unexpected message type: %s", basicMessage.Type) + } + + var revocationStatus protocol.RevocationStatusResponseMessageBody + if err := json.Unmarshal(basicMessage.Body, &revocationStatus); err != nil { + return nil, err + } + + return &revocationStatus.RevocationStatus, nil +} + func getRevocationProofFromIssuer(ctx context.Context, url string) (*verifiable.RevocationStatus, error) { b, err := client.NewClient(*http.DefaultClient).Get(ctx, url) if err != nil { diff --git a/pkg/credentials/revocation_status/iden3_revocation_status_v1.go b/pkg/credentials/revocation_status/iden3_revocation_status_v1.go new file mode 100644 index 000000000..47d13f983 --- /dev/null +++ b/pkg/credentials/revocation_status/iden3_revocation_status_v1.go @@ -0,0 +1,18 @@ +package revocation_status + +import ( + "github.com/iden3/go-iden3-core/v2/w3c" + "github.com/iden3/go-schema-processor/v2/verifiable" + + "github.com/polygonid/sh-id-platform/internal/config" +) + +type iden3CommRevocationStatusV1Resolver struct{} + +func (r *iden3CommRevocationStatusV1Resolver) resolve(credentialStatusSettings config.CredentialStatus, issuerDID w3c.DID, nonce uint64, issuerState string) *verifiable.CredentialStatus { + return &verifiable.CredentialStatus{ + ID: credentialStatusSettings.DirectStatus.GetAgentURL(), + Type: verifiable.Iden3commRevocationStatusV1, + RevocationNonce: nonce, + } +} diff --git a/pkg/credentials/revocation_status/resolver.go b/pkg/credentials/revocation_status/resolver.go index c3167c7cc..5401ebc67 100644 --- a/pkg/credentials/revocation_status/resolver.go +++ b/pkg/credentials/revocation_status/resolver.go @@ -27,6 +27,7 @@ func NewRevocationStatusResolver(credentialStatusSettings config.CredentialStatu resolvers := make(map[verifiable.CredentialStatusType]revocationCredentialStatusResolver, resolversLength) resolvers[verifiable.Iden3ReverseSparseMerkleTreeProof] = &iden3ReverseSparseMerkleTreeProofResolver{} resolvers[verifiable.SparseMerkleTreeProof] = &sparseMerkleTreeProofResolver{} + resolvers[verifiable.Iden3commRevocationStatusV1] = &iden3CommRevocationStatusV1Resolver{} resolvers[verifiable.Iden3OnchainSparseMerkleTreeProof2023] = &iden3OnChainSparseMerkleTreeProof2023Resolver{} return &RevocationStatusResolver{ credentialStatusSettings: credentialStatusSettings, @@ -39,7 +40,7 @@ func NewRevocationStatusResolver(credentialStatusSettings config.CredentialStatu // If status is supported, a way to check revocation status is returned. func (rsr *RevocationStatusResolver) GetCredentialRevocationStatus(_ context.Context, issuerDID w3c.DID, nonce uint64, issuerState string, credentialStatusType verifiable.CredentialStatusType) (*verifiable.CredentialStatus, error) { if credentialStatusType == "" { - credentialStatusType = verifiable.SparseMerkleTreeProof + credentialStatusType = verifiable.Iden3commRevocationStatusV1 } resolver, ok := rsr.resolvers[credentialStatusType] if !ok { From 4cd199cbea3751b7c783932c5a136b8d2c23866f Mon Sep 17 00:00:00 2001 From: javip97 Date: Fri, 19 Jan 2024 10:52:18 +0100 Subject: [PATCH 02/52] fix: typo --- internal/config/credential_status.go | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/internal/config/credential_status.go b/internal/config/credential_status.go index 18363d1fa..15e7c2c6d 100644 --- a/internal/config/credential_status.go +++ b/internal/config/credential_status.go @@ -33,7 +33,7 @@ type DirectStatus struct { URL string `mapstructure:"URL"` } -// GetURL returns the URL of the di rect status +// GetURL returns the URL of the direct status func (r *DirectStatus) GetURL() string { return strings.TrimSuffix(r.URL, "/") } From c3d36f08ee896c4406adca1fef8c3768cddc99d3 Mon Sep 17 00:00:00 2001 From: daveroga Date: Tue, 16 Apr 2024 22:26:59 +0200 Subject: [PATCH 03/52] add config gasless network --- .env-issuer.sample | 1 + cmd/issuer_initializer/main.go | 1 + cmd/notifications/main.go | 1 + cmd/pending_publisher/main.go | 1 + internal/config/config.go | 2 + internal/core/services/account.go | 1 + internal/providers/blockchain/eth.go | 2 + .../templates/issuer-node-api-configmap.yaml | 1 + k8s/helm/values.yaml | 1 + pkg/blockchain/eth/client.go | 131 ++++++++++-------- 10 files changed, 85 insertions(+), 57 deletions(-) diff --git a/.env-issuer.sample b/.env-issuer.sample index a1445d2d8..d2b3b9a90 100644 --- a/.env-issuer.sample +++ b/.env-issuer.sample @@ -24,6 +24,7 @@ ISSUER_ETHEREUM_CONFIRMATION_BLOCK_COUNT=5 ISSUER_ETHEREUM_RECEIPT_TIMEOUT=600s ISSUER_ETHEREUM_MIN_GAS_PRICE=0 ISSUER_ETHEREUM_MAX_GAS_PRICE=2500000 +ISSUER_ETHEREUM_GASLESS=false ISSUER_ETHEREUM_RPC_RESPONSE_TIMEOUT=5s ISSUER_ETHEREUM_WAIT_RECEIPT_CYCLE_TIME=30s ISSUER_ETHEREUM_WAIT_BLOCK_CYCLE_TIME=30s diff --git a/cmd/issuer_initializer/main.go b/cmd/issuer_initializer/main.go index e42e672b5..30854e465 100644 --- a/cmd/issuer_initializer/main.go +++ b/cmd/issuer_initializer/main.go @@ -137,6 +137,7 @@ func main() { ReceiptTimeout: cfg.Ethereum.ReceiptTimeout, MinGasPrice: big.NewInt(int64(cfg.Ethereum.MinGasPrice)), MaxGasPrice: big.NewInt(int64(cfg.Ethereum.MaxGasPrice)), + GasLess: cfg.Ethereum.GasLess, RPCResponseTimeout: cfg.Ethereum.RPCResponseTimeout, WaitReceiptCycleTime: cfg.Ethereum.WaitReceiptCycleTime, WaitBlockCycleTime: cfg.Ethereum.WaitBlockCycleTime, diff --git a/cmd/notifications/main.go b/cmd/notifications/main.go index 8ba35b4d6..b235ba5a7 100644 --- a/cmd/notifications/main.go +++ b/cmd/notifications/main.go @@ -165,6 +165,7 @@ func newCredentialsService(ctx context.Context, cfg *config.Configuration, stora ReceiptTimeout: cfg.Ethereum.ReceiptTimeout, MinGasPrice: big.NewInt(int64(cfg.Ethereum.MinGasPrice)), MaxGasPrice: big.NewInt(int64(cfg.Ethereum.MaxGasPrice)), + GasLess: cfg.Ethereum.GasLess, RPCResponseTimeout: cfg.Ethereum.RPCResponseTimeout, WaitReceiptCycleTime: cfg.Ethereum.WaitReceiptCycleTime, WaitBlockCycleTime: cfg.Ethereum.WaitBlockCycleTime, diff --git a/cmd/pending_publisher/main.go b/cmd/pending_publisher/main.go index 94f8e894f..844c9c81d 100644 --- a/cmd/pending_publisher/main.go +++ b/cmd/pending_publisher/main.go @@ -151,6 +151,7 @@ func main() { ReceiptTimeout: cfg.Ethereum.ReceiptTimeout, MinGasPrice: big.NewInt(int64(cfg.Ethereum.MinGasPrice)), MaxGasPrice: big.NewInt(int64(cfg.Ethereum.MaxGasPrice)), + GasLess: cfg.Ethereum.GasLess, RPCResponseTimeout: cfg.Ethereum.RPCResponseTimeout, WaitReceiptCycleTime: cfg.Ethereum.WaitReceiptCycleTime, WaitBlockCycleTime: cfg.Ethereum.WaitBlockCycleTime, diff --git a/internal/config/config.go b/internal/config/config.go index 938ef8677..e6efb60c8 100644 --- a/internal/config/config.go +++ b/internal/config/config.go @@ -85,6 +85,7 @@ type Ethereum struct { ReceiptTimeout time.Duration `tip:"Receipt timeout"` MinGasPrice int `tip:"Minimum Gas Price"` MaxGasPrice int `tip:"The Datasource name locator"` + GasLess bool `tip:"Gasless transactions"` RPCResponseTimeout time.Duration `tip:"RPC Response timeout"` WaitReceiptCycleTime time.Duration `tip:"Wait Receipt Cycle Time"` WaitBlockCycleTime time.Duration `tip:"Wait Block Cycle Time"` @@ -464,6 +465,7 @@ func bindEnv() { _ = viper.BindEnv("Ethereum.ReceiptTimeout", "ISSUER_ETHEREUM_RECEIPT_TIMEOUT") _ = viper.BindEnv("Ethereum.MinGasPrice", "ISSUER_ETHEREUM_MIN_GAS_PRICE") _ = viper.BindEnv("Ethereum.MaxGasPrice", "ISSUER_ETHEREUM_MAX_GAS_PRICE") + _ = viper.BindEnv("Ethereum.GasLess", "ISSUER_ETHEREUM_GASLESS") _ = viper.BindEnv("Ethereum.RPCResponseTimeout", "ISSUER_ETHEREUM_RPC_RESPONSE_TIMEOUT") _ = viper.BindEnv("Ethereum.WaitReceiptCycleTime", "ISSUER_ETHEREUM_WAIT_RECEIPT_CYCLE_TIME") _ = viper.BindEnv("Ethereum.WaitBlockCycleTime", "ISSUER_ETHEREUM_WAIT_BLOCK_CYCLE_TIME") diff --git a/internal/core/services/account.go b/internal/core/services/account.go index 082c6b353..3ae931d41 100644 --- a/internal/core/services/account.go +++ b/internal/core/services/account.go @@ -35,6 +35,7 @@ func NewAccountService(ethConfig config.Ethereum, keyStore *kms.KMS) *AccountSer ReceiptTimeout: ethConfig.ReceiptTimeout, MinGasPrice: big.NewInt(int64(ethConfig.MinGasPrice)), MaxGasPrice: big.NewInt(int64(ethConfig.MaxGasPrice)), + GasLess: ethConfig.GasLess, RPCResponseTimeout: ethConfig.RPCResponseTimeout, WaitReceiptCycleTime: ethConfig.WaitReceiptCycleTime, WaitBlockCycleTime: ethConfig.WaitBlockCycleTime, diff --git a/internal/providers/blockchain/eth.go b/internal/providers/blockchain/eth.go index 1d0314041..829602b05 100644 --- a/internal/providers/blockchain/eth.go +++ b/internal/providers/blockchain/eth.go @@ -41,6 +41,7 @@ func InitEthConnect(cfg config.Ethereum, kms *kms.KMS) (*eth.Client, error) { ReceiptTimeout: cfg.ReceiptTimeout, MinGasPrice: big.NewInt(int64(cfg.MinGasPrice)), MaxGasPrice: big.NewInt(int64(cfg.MaxGasPrice)), + GasLess: cfg.GasLess, RPCResponseTimeout: cfg.RPCResponseTimeout, WaitReceiptCycleTime: cfg.WaitReceiptCycleTime, WaitBlockCycleTime: cfg.WaitBlockCycleTime, @@ -65,6 +66,7 @@ func Open(cfg *config.Configuration, kms *kms.KMS) (*eth.Client, error) { ReceiptTimeout: cfg.Ethereum.ReceiptTimeout, MinGasPrice: big.NewInt(int64(cfg.Ethereum.MinGasPrice)), MaxGasPrice: big.NewInt(int64(cfg.Ethereum.MaxGasPrice)), + GasLess: cfg.Ethereum.GasLess, RPCResponseTimeout: cfg.Ethereum.RPCResponseTimeout, WaitReceiptCycleTime: cfg.Ethereum.WaitReceiptCycleTime, WaitBlockCycleTime: cfg.Ethereum.WaitBlockCycleTime, diff --git a/k8s/helm/templates/issuer-node-api-configmap.yaml b/k8s/helm/templates/issuer-node-api-configmap.yaml index b9e51d244..1d3abf7bb 100644 --- a/k8s/helm/templates/issuer-node-api-configmap.yaml +++ b/k8s/helm/templates/issuer-node-api-configmap.yaml @@ -26,6 +26,7 @@ data: ISSUER_ETHEREUM_CONFIRMATION_BLOCK_COUNT: {{ .Values.apiIssuerNode.configMap.issuerEthereumConfirmationBlockCount | quote }} ISSUER_ETHEREUM_MAX_GAS_PRICE: {{ .Values.apiIssuerNode.configMap.issuerEthereumMaxGasPrice | quote }} ISSUER_ETHEREUM_MIN_GAS_PRICE: {{ .Values.apiIssuerNode.configMap.issuerEthereumMinGasPrice | quote }} + ISSUER_ETHEREUM_GASLESS: {{ .Values.apiIssuerNode.configMap.issuerEthereumGasLess | quote }} ISSUER_ETHEREUM_RPC_RESPONSE_TIMEOUT: {{ .Values.apiIssuerNode.configMap.issuerEthereumRpcResponseTimeout }} ISSUER_ETHEREUM_RECEIPT_TIMEOUT: {{ .Values.apiIssuerNode.configMap.issuerEthereumReceiptTimeout }} ISSUER_ETHEREUM_WAIT_BLOCK_CYCLE_TIME: {{ .Values.apiIssuerNode.configMap.issuerEthereumWaitBlockCycleTime }} diff --git a/k8s/helm/values.yaml b/k8s/helm/values.yaml index 993e7efd5..f02f40fab 100644 --- a/k8s/helm/values.yaml +++ b/k8s/helm/values.yaml @@ -56,6 +56,7 @@ apiIssuerNode: issuerEthereumDefaultGasLimit: "600000" issuerEthereumMaxGasPrice: "2500000" issuerEthereumMinGasPrice: "0" + issuerEthereumGasLess: "false" issuerEthereumReceiptTimeout: 600s issuerEthereumResolverPrefixMumbai: polygon:mumbai issuerEthereumResolverPrefixAmoy: polygon:amoy diff --git a/pkg/blockchain/eth/client.go b/pkg/blockchain/eth/client.go index ef1525724..2d8742f5d 100644 --- a/pkg/blockchain/eth/client.go +++ b/pkg/blockchain/eth/client.go @@ -65,6 +65,7 @@ type ClientConfig struct { DefaultGasLimit int `json:"default_gas_limit"` MinGasPrice *big.Int `json:"min_gas_price"` MaxGasPrice *big.Int `json:"max_gas_price"` + GasLess bool `json:"gas_less"` RPCResponseTimeout time.Duration `json:"rpc_response_time_out"` WaitReceiptCycleTime time.Duration `json:"wait_receipt_cycle_time_out"` WaitBlockCycleTime time.Duration `json:"wait_block_cycle_time_out"` @@ -317,18 +318,25 @@ func (c *Client) CreateTxOpts(ctx context.Context, kmsKey kms.KeyID) (*bind.Tran sigFn := c.signerFnFactory(ctx, kmsKey) - tip, err := c.suggestGasTipCap(ctx) - if err != nil { - return nil, err - } + // tip := big.NewInt(0) + gasLimit := uint64(c.Config.DefaultGasLimit) opts := &bind.TransactOpts{ - From: addr, - Signer: sigFn, - GasTipCap: tip, // The only option we need to set is gasTipCap as some Ethereum nodes don't support eth_maxPriorityFeePerGas - GasLimit: 0, // go-ethereum library will estimate gas limit automatically if it is 0 - Context: ctx, - NoSend: false, + From: addr, + Signer: sigFn, + GasLimit: gasLimit, // go-ethereum library will estimate gas limit automatically if it is 0 + Context: ctx, + NoSend: false, + } + + if !c.Config.GasLess { // Some Ethereum nodes don't support eth_maxPriorityFeePerGas so we set GasLess = true + tip, err := c.suggestGasTipCap(ctx) + if err != nil { + return nil, err + } + gasLimit = uint64(0) + opts.GasLimit = gasLimit + opts.GasTipCap = tip } return opts, nil @@ -357,63 +365,72 @@ func (c *Client) CreateRawTx(ctx context.Context, txParams TransactionParams) (* txParams.Nonce = &nonce } - _ctx2, cancel2 := context.WithTimeout(ctx, c.Config.RPCResponseTimeout) - defer cancel2() if txParams.Value == nil { txParams.Value = big.NewInt(0) } - gasLimit, err := c.client.EstimateGas(_ctx2, ethereum.CallMsg{ - From: txParams.FromAddress, // the sender of the 'transaction' + + baseTx := &types.DynamicFeeTx{ To: &txParams.ToAddress, - Gas: 0, // wei <-> gas exchange ratio - Value: txParams.Value, // amount of wei sent along with the call + Nonce: *txParams.Nonce, + Gas: uint64(c.Config.DefaultGasLimit), + Value: txParams.Value, Data: txParams.Payload, - }) - if err != nil { - return nil, fmt.Errorf("failed to estimate gas: %v", err) } - latestBlockHeader, err := c.HeaderByNumber(ctx, nil) - if err != nil { - return nil, err - } + if !c.Config.GasLess { + _ctx2, cancel2 := context.WithTimeout(ctx, c.Config.RPCResponseTimeout) + defer cancel2() + gasLimit, err := c.client.EstimateGas(_ctx2, ethereum.CallMsg{ + From: txParams.FromAddress, // the sender of the 'transaction' + To: &txParams.ToAddress, + Gas: 0, // wei <-> gas exchange ratio + Value: txParams.Value, // amount of wei sent along with the call + Data: txParams.Payload, + }) + + baseTx.Gas = gasLimit - if txParams.BaseFee == nil { - // since ETH and Polygon blockchain already supports London fork. - // no need set special block. - baseFee := eip1559.CalcBaseFee(¶ms.ChainConfig{LondonBlock: big.NewInt(1)}, latestBlockHeader) - - // add 25% to baseFee. baseFee always small value. - // since we use dynamic fee transactions we will get not used gas back. - b := math.Round(float64(baseFee.Int64()) * feeIncrement) - baseFee = big.NewInt(int64(b)) - txParams.BaseFee = baseFee - } - - if txParams.GasTips == nil { - _ctx3, cancel3 := context.WithTimeout(ctx, c.Config.RPCResponseTimeout) - defer cancel3() - gasTip, err := c.client.SuggestGasTipCap(_ctx3) - // since hardhad doesn't support 'eth_maxPriorityFeePerGas' rpc call. - // we should hardcode 0 as a mainer tips. More information: https://github.com/NomicFoundation/hardhat/issues/1664#issuecomment-1149006010 - if err != nil && strings.Contains(err.Error(), "eth_maxPriorityFeePerGas not found") { - log.Error(ctx, "failed get suggest gas tip: %s. use 0 instead", "err", err) - gasTip = big.NewInt(0) - } else if err != nil { - return nil, fmt.Errorf("failed get suggest gas tip: %v", err) + if err != nil { + return nil, fmt.Errorf("failed to estimate gas: %v", err) } - txParams.GasTips = gasTip - } - maxGasPricePerFee := big.NewInt(0).Add(txParams.BaseFee, txParams.GasTips) - baseTx := &types.DynamicFeeTx{ - To: &txParams.ToAddress, - Nonce: *txParams.Nonce, - Gas: gasLimit, - Value: txParams.Value, - Data: txParams.Payload, - GasTipCap: txParams.GasTips, - GasFeeCap: maxGasPricePerFee, + latestBlockHeader, err := c.HeaderByNumber(ctx, nil) + if err != nil { + return nil, err + } + + if txParams.BaseFee == nil { + // since ETH and Polygon blockchain already supports London fork. + // no need set special block. + baseFee := eip1559.CalcBaseFee(¶ms.ChainConfig{LondonBlock: big.NewInt(1)}, latestBlockHeader) + + // add 25% to baseFee. baseFee always small value. + // since we use dynamic fee transactions we will get not used gas back. + b := math.Round(float64(baseFee.Int64()) * feeIncrement) + baseFee = big.NewInt(int64(b)) + txParams.BaseFee = baseFee + } + + if txParams.GasTips == nil { + _ctx3, cancel3 := context.WithTimeout(ctx, c.Config.RPCResponseTimeout) + defer cancel3() + gasTip, err := c.client.SuggestGasTipCap(_ctx3) + // since hardhad doesn't support 'eth_maxPriorityFeePerGas' rpc call. + // we should hardcode 0 as a mainer tips. More information: https://github.com/NomicFoundation/hardhat/issues/1664#issuecomment-1149006010 + if err != nil && strings.Contains(err.Error(), "eth_maxPriorityFeePerGas not found") { + log.Error(ctx, "failed get suggest gas tip: %s. use 0 instead", "err", err) + gasTip = big.NewInt(0) + } else if err != nil { + return nil, fmt.Errorf("failed get suggest gas tip: %v", err) + } + txParams.GasTips = gasTip + } + + maxGasPricePerFee := big.NewInt(0).Add(txParams.BaseFee, txParams.GasTips) + + baseTx.GasTipCap = txParams.GasTips + baseTx.GasFeeCap = maxGasPricePerFee + } tx := types.NewTx(baseTx) From a3887fdf445beaad4bbd49fb9b383916574ecab2 Mon Sep 17 00:00:00 2001 From: daveroga Date: Wed, 17 Apr 2024 10:25:49 +0200 Subject: [PATCH 04/52] remove unnecessary tab --- k8s/helm/values.yaml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/k8s/helm/values.yaml b/k8s/helm/values.yaml index f02f40fab..f4f134c6d 100644 --- a/k8s/helm/values.yaml +++ b/k8s/helm/values.yaml @@ -56,7 +56,7 @@ apiIssuerNode: issuerEthereumDefaultGasLimit: "600000" issuerEthereumMaxGasPrice: "2500000" issuerEthereumMinGasPrice: "0" - issuerEthereumGasLess: "false" + issuerEthereumGasLess: "false" issuerEthereumReceiptTimeout: 600s issuerEthereumResolverPrefixMumbai: polygon:mumbai issuerEthereumResolverPrefixAmoy: polygon:amoy From f876fdcbc52edcc0fcb364678ac2813789c6ab4f Mon Sep 17 00:00:00 2001 From: Martin Saporiti Date: Mon, 20 May 2024 08:58:15 -0300 Subject: [PATCH 05/52] fix: revocation status url --- cmd/issuer_initializer/main.go | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/cmd/issuer_initializer/main.go b/cmd/issuer_initializer/main.go index e42e672b5..dcbec6501 100644 --- a/cmd/issuer_initializer/main.go +++ b/cmd/issuer_initializer/main.go @@ -142,11 +142,11 @@ func main() { WaitBlockCycleTime: cfg.Ethereum.WaitBlockCycleTime, }, keyStore) + // this is needed to create the did with the correct auth core claim revocation status URL + cfg.CredentialStatus.DirectStatus.URL = cfg.APIUI.ServerURL rhsFactory := reverse_hash.NewFactory(cfg.CredentialStatus.RHS.GetURL(), ethConn, common.HexToAddress(cfg.CredentialStatus.OnchainTreeStore.SupportedTreeStoreContract), reverse_hash.DefaultRHSTimeOut) revocationStatusResolver := revocation_status.NewRevocationStatusResolver(cfg.CredentialStatus) cfg.CredentialStatus.SingleIssuer = true - // this is needed to create the did with the correct auth core claim revocation status URL - cfg.CredentialStatus.DirectStatus.URL = cfg.APIUI.ServerURL identityService := services.NewIdentity(keyStore, identityRepository, mtRepository, identityStateRepository, mtService, nil, claimsRepository, nil, nil, storage, nil, nil, nil, cfg.CredentialStatus, rhsFactory, revocationStatusResolver) didCreationOptions := &ports.DIDCreationOptions{ From 8d7b8e3510da5b071fb3eb98497f68c180189d3f Mon Sep 17 00:00:00 2001 From: Martin Saporiti Date: Wed, 22 May 2024 09:53:46 -0300 Subject: [PATCH 06/52] chore: update libraries to support amoy network --- go.mod | 16 ++++++------ go.sum | 39 ++++++++++++---------------- internal/api/server.go | 1 + internal/core/services/proof.go | 14 ++-------- internal/core/services/revocation.go | 21 +++------------ 5 files changed, 30 insertions(+), 61 deletions(-) diff --git a/go.mod b/go.mod index 18a60a092..ff3dcffeb 100644 --- a/go.mod +++ b/go.mod @@ -12,17 +12,17 @@ require ( github.com/go-redis/cache/v8 v8.4.4 github.com/go-redis/redis/v8 v8.11.5 github.com/golangci/golangci-lint v1.55.2 - github.com/google/uuid v1.4.0 + github.com/google/uuid v1.6.0 github.com/hashicorp/go-retryablehttp v0.7.5 github.com/hashicorp/vault/api v1.10.0 github.com/hashicorp/vault/api/auth/userpass v0.5.0 github.com/iden3/contracts-abi/onchain-credential-status-resolver/go/abi v0.0.0-20230911113809-c58b7e7a69b0 github.com/iden3/contracts-abi/state/go/abi v1.0.2-0.20231006071010-f511d08ca36f - github.com/iden3/go-circuits/v2 v2.0.0 - github.com/iden3/go-iden3-auth/v2 v2.0.0-beta.2 - github.com/iden3/go-iden3-core/v2 v2.0.0 - github.com/iden3/go-iden3-crypto v0.0.15 - github.com/iden3/go-jwz/v2 v2.0.0 + github.com/iden3/go-circuits/v2 v2.2.0 + github.com/iden3/go-iden3-auth/v2 v2.2.2 + github.com/iden3/go-iden3-core/v2 v2.1.0 + github.com/iden3/go-iden3-crypto v0.0.16 + github.com/iden3/go-jwz/v2 v2.0.2 github.com/iden3/go-merkletree-sql/db/pgx/v2 v2.0.5 github.com/iden3/go-merkletree-sql/v2 v2.0.6 github.com/iden3/go-rapidsnark/prover v0.0.10 @@ -30,8 +30,8 @@ require ( github.com/iden3/go-rapidsnark/witness/v2 v2.0.0 github.com/iden3/go-rapidsnark/witness/wazero v0.0.0-20230524142950-0986cf057d4e github.com/iden3/go-schema-processor v1.3.1 - github.com/iden3/go-schema-processor/v2 v2.1.0 - github.com/iden3/iden3comm/v2 v2.0.0 + github.com/iden3/go-schema-processor/v2 v2.3.3 + github.com/iden3/iden3comm/v2 v2.3.2 github.com/iden3/merkletree-proof v0.0.4 github.com/ipfs/go-ipfs-api v0.7.0 github.com/jackc/pgconn v1.14.1 diff --git a/go.sum b/go.sum index 344640227..b7a7ac86a 100644 --- a/go.sum +++ b/go.sum @@ -310,7 +310,6 @@ github.com/gofrs/flock v0.8.1 h1:+gYjHKf32LDeiEEFhQaotPbLuUXjY5ZqxKgXy7n59aw= github.com/gofrs/flock v0.8.1/go.mod h1:F1TvTiK9OcQqauNUHlbJvyl9Qa1QvF/gOUDKA14jxHU= github.com/gofrs/uuid v4.0.0+incompatible h1:1SD/1F5pU8p29ybwgQSwpQk+mwdRrXCYuPhW6m+TnJw= github.com/gofrs/uuid v4.0.0+incompatible/go.mod h1:b2aQJv3Z4Fp6yNu3cdSllBxTCLRxnplIgP/c0N/04lM= -github.com/gofrs/uuid/v5 v5.0.0 h1:p544++a97kEL+svbcFbCQVM9KFu0Yo25UoISXGNNH9M= github.com/gogo/protobuf v1.1.1/go.mod h1:r8qH/GZQm5c6nD/R0oafs1akxWv10x8SbQlK7atdtwQ= github.com/gogo/protobuf v1.3.2 h1:Ov1cvc58UF3b5XjBnZv7+opcTcQFZebYjWzi34vdm4Q= github.com/gogo/protobuf v1.3.2/go.mod h1:P1XiOD3dCwIKUDQYPy72D8LYyHL2YPYrpS2s69NZV8Q= @@ -405,8 +404,8 @@ github.com/google/pprof v0.0.0-20230821062121-407c9e7a662f h1:pDhu5sgp8yJlEF/g6o github.com/google/renameio v0.1.0/go.mod h1:KWCgfxg9yswjAJkECMjeO8J8rahYeXnNhOm40UhjYkI= github.com/google/subcommands v1.2.0/go.mod h1:ZjhPrFU+Olkh9WazFPsl27BQ4UPiG37m3yTrtFlrHVk= github.com/google/uuid v1.1.2/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo= -github.com/google/uuid v1.4.0 h1:MtMxsa51/r9yyhkyLsVeVt0B+BGQZzpQiTQ4eHZ8bc4= -github.com/google/uuid v1.4.0/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo= +github.com/google/uuid v1.6.0 h1:NIvaJDMOsjHA8n1jAhLSgzrAzy1Hgr+hNrb57e+94F0= +github.com/google/uuid v1.6.0/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo= github.com/googleapis/gax-go/v2 v2.0.4/go.mod h1:0Wqv26UfaUD9n4G6kQubkQ+KchISgw+vpHVxEJEs9eg= github.com/googleapis/gax-go/v2 v2.0.5/go.mod h1:DWXyrwAJ9X0FpwwEdw+IPEYBICEFu5mhpdKc/us6bOk= github.com/googleapis/google-cloud-go-testing v0.0.0-20200911160855-bcd43fbb19e8/go.mod h1:dvDLG8qkwmyD9a/MJJN3XJcT3xFxOKAvTZGvuZmac9g= @@ -480,18 +479,18 @@ github.com/iden3/contracts-abi/rhs-storage/go/abi v0.0.0-20231006141557-7d13ef7e github.com/iden3/contracts-abi/rhs-storage/go/abi v0.0.0-20231006141557-7d13ef7e3c48/go.mod h1:kJmVPMk4HfWyl2kcta34aad/K4TAfCwB29xX9PsR7LQ= github.com/iden3/contracts-abi/state/go/abi v1.0.2-0.20231006071010-f511d08ca36f h1:aTYEBIh802oWF6B3jhXf5F7UVGxfPJG70shYkRXzb+s= github.com/iden3/contracts-abi/state/go/abi v1.0.2-0.20231006071010-f511d08ca36f/go.mod h1:TxgIrXCvxms3sbOdsy8kTvffUCIpEEifNy0fSXdkU4w= -github.com/iden3/go-circuits/v2 v2.0.0 h1:Bw0mpsqeip06d6I2ktgfhTVB7Jk9mSHi8myHZWkoc6w= -github.com/iden3/go-circuits/v2 v2.0.0/go.mod h1:VIFIp51+IH0hOzjnKhb84bCeyq7hq76zX/C14ua6zh4= -github.com/iden3/go-iden3-auth/v2 v2.0.0-beta.2 h1:r5vjH+MyPFzaJ7U62SO5Gz9N9O0RZfDORNHVd9JymNg= -github.com/iden3/go-iden3-auth/v2 v2.0.0-beta.2/go.mod h1:bYr47aev7sh23RL7Ru+TQQSlYDS94+wO8P8SDrwdifc= +github.com/iden3/go-circuits/v2 v2.2.0 h1:qJeySVPG9vxZwJyL/CsvXdUhccWOctXQUYGnyX5p2Kc= +github.com/iden3/go-circuits/v2 v2.2.0/go.mod h1:1LET+T8i9Rkfx+RNj2BBHKAPGDODEWWwSEFjR6g3h6c= +github.com/iden3/go-iden3-auth/v2 v2.2.2 h1:4uA+m5H2OvhfOsMJaeXaCjciV2sHypvHgGHewZfXB58= +github.com/iden3/go-iden3-auth/v2 v2.2.2/go.mod h1:1ytFvnSnuNK2m9BoVrgYJoLNH919Bg2pt68pFelcJcM= github.com/iden3/go-iden3-core v1.0.2 h1:HwNDFeqcUv4ybZj5tH+58JKWKarn/qqBpNCqTLxGP0Y= github.com/iden3/go-iden3-core v1.0.2/go.mod h1:X4PjlJG8OsEQEsSbzzYqqAk2olYGZ2nuGqiUPyEYjOo= -github.com/iden3/go-iden3-core/v2 v2.0.0 h1:sQEuuq3RLfyYSY8qPiqxQ6YBpGbiAwepHJD/vjf1adA= -github.com/iden3/go-iden3-core/v2 v2.0.0/go.mod h1:L9PxhWPvoS9qTb3inEkZBm1RpjHBt+VTwvxssdzbAdw= -github.com/iden3/go-iden3-crypto v0.0.15 h1:4MJYlrot1l31Fzlo2sF56u7EVFeHHJkxGXXZCtESgK4= -github.com/iden3/go-iden3-crypto v0.0.15/go.mod h1:dLpM4vEPJ3nDHzhWFXDjzkn1qHoBeOT/3UEhXsEsP3E= -github.com/iden3/go-jwz/v2 v2.0.0 h1:VsU2PrmcchPMx/V0IhamMZRNjiQYZoyJopO8K8uSZOY= -github.com/iden3/go-jwz/v2 v2.0.0/go.mod h1:JBJ58Cef8h+4Uz8qaVRsNjiT/Ubqb800dGKTZt66NkU= +github.com/iden3/go-iden3-core/v2 v2.1.0 h1:R1s7Tj3tIx5lDy8S7OJrSNuxXIFeRzWRmTBaQoQHJps= +github.com/iden3/go-iden3-core/v2 v2.1.0/go.mod h1:L9PxhWPvoS9qTb3inEkZBm1RpjHBt+VTwvxssdzbAdw= +github.com/iden3/go-iden3-crypto v0.0.16 h1:zN867xiz6HgErXVIV/6WyteGcOukE9gybYTorBMEdsk= +github.com/iden3/go-iden3-crypto v0.0.16/go.mod h1:dLpM4vEPJ3nDHzhWFXDjzkn1qHoBeOT/3UEhXsEsP3E= +github.com/iden3/go-jwz/v2 v2.0.2 h1:yx56x1TZcObeuj6cvX715Jd7QTxnCpHwbETKWCPJmhw= +github.com/iden3/go-jwz/v2 v2.0.2/go.mod h1:B1r6wJpPhIiuZTmgicNoogr7XD/VS3jZu9U519GwWz4= github.com/iden3/go-merkletree-sql/db/pgx/v2 v2.0.5 h1:CKry110riXxBu1bM9vhdPia37tlbqoKYg0s0dwGA4l4= github.com/iden3/go-merkletree-sql/db/pgx/v2 v2.0.5/go.mod h1:J17cXiT4pBP/c5FWN4nv0J7q2yT9I8JSzUfdIKyZIj4= github.com/iden3/go-merkletree-sql/v2 v2.0.6 h1:vsVDImnvnHf7Ggr45ptFOXJyWNA/8IwVQO1jzRLUlY8= @@ -508,10 +507,10 @@ github.com/iden3/go-rapidsnark/witness/wazero v0.0.0-20230524142950-0986cf057d4e github.com/iden3/go-rapidsnark/witness/wazero v0.0.0-20230524142950-0986cf057d4e/go.mod h1:UEBifEzw62T6VzIHJeHuUgeLg2U/J9ttf7hOwQEqnYk= github.com/iden3/go-schema-processor v1.3.1 h1:LJfFInfYGMOp0bTKKC17R8q4XI+VtqhFLPTEqnOIvlM= github.com/iden3/go-schema-processor v1.3.1/go.mod h1:NwJ1nuGdRlCFaN1/V6mS0AOAdvpLcGf4KKq0mluLG7U= -github.com/iden3/go-schema-processor/v2 v2.1.0 h1:8/fA7IVkyVmpbJij9Ar0X2zWPQJMlCaaPP4hfTZqbqU= -github.com/iden3/go-schema-processor/v2 v2.1.0/go.mod h1:EogHwnFnxQKOGRVme6upCcisoAQeEIl+HuRAGa7w3+w= -github.com/iden3/iden3comm/v2 v2.0.0 h1:cFDfF6aJ589ENg5zlTBEPK6Qqv4I11C/gliAWZORpyY= -github.com/iden3/iden3comm/v2 v2.0.0/go.mod h1:wrXoxi8eoQSLopatRW5+hYF9lDRvzGL2As9ZE88q/kA= +github.com/iden3/go-schema-processor/v2 v2.3.3 h1:GfChxMZHG4miA3p/5rLIrM7TGmKu/oAAXgLloYTBHSI= +github.com/iden3/go-schema-processor/v2 v2.3.3/go.mod h1:8y/R0iQpYhyhRQ3sL4F5Aja3+1T68M6uwGQdC4pQ4X0= +github.com/iden3/iden3comm/v2 v2.3.2 h1:ulD0oI/+qsEmnHVELWrxdLNvQOOWr/JLVMFXzEVbr5E= +github.com/iden3/iden3comm/v2 v2.3.2/go.mod h1:HVdSjre4og+kdJ5Cqe2b3Dt2ccOogOdfyWwKaUSAelw= github.com/iden3/merkletree-proof v0.0.4 h1:o1XXws6zb7+BBDQYXlo0GPUH+jUY3+GxkT88U1C4Sb8= github.com/iden3/merkletree-proof v0.0.4/go.mod h1:D49CVDG/tshMiZuDCxWjGJoNplRg9y9XIlg9/eMSYOc= github.com/inconshreveable/mousetrap v1.1.0 h1:wN+x4NVGpMsO7ErUn/mUI3vEoE6Jt13X2s0bqwp9tc8= @@ -740,8 +739,6 @@ github.com/multiformats/go-base32 v0.1.0 h1:pVx9xoSPqEIQG8o+UbAe7DNi51oej1NtK+aG github.com/multiformats/go-base32 v0.1.0/go.mod h1:Kj3tFY6zNr+ABYMqeUNeGvkIC/UYgtWibDcT0rExnbI= github.com/multiformats/go-base36 v0.2.0 h1:lFsAbNOGeKtuKozrtBsAkSVhv1p9D0/qedU9rQyccr0= github.com/multiformats/go-base36 v0.2.0/go.mod h1:qvnKE++v+2MWCfePClUEjE78Z7P2a1UV0xHgWc0hkp4= -github.com/multiformats/go-multiaddr v0.11.0 h1:XqGyJ8ufbCE0HmTDwx2kPdsrQ36AGPZNZX6s6xfJH10= -github.com/multiformats/go-multiaddr v0.11.0/go.mod h1:gWUm0QLR4thQ6+ZF6SXUw8YjtwQSPapICM+NmCkxHSM= github.com/multiformats/go-multiaddr v0.12.1 h1:vm+BA/WZA8QZDp1pF1FWhi5CT3g1tbi5GJmqpb6wnlk= github.com/multiformats/go-multiaddr v0.12.1/go.mod h1:7mPkiBMmLeFipt+nNSq9pHZUeJSt8lHBgH6yhj0YQzE= github.com/multiformats/go-multibase v0.2.0 h1:isdYCVLvksgWlMW9OZRYJEa9pZETFivncJHmHnnd87g= @@ -1069,8 +1066,6 @@ golang.org/x/crypto v0.0.0-20220722155217-630584e8d5aa/go.mod h1:IxCIyHEi3zRg3s0 golang.org/x/crypto v0.1.0/go.mod h1:RecgLatLF4+eUMCP1PoPZQb+cVrJcOPbHkTkbkB9sbw= golang.org/x/crypto v0.6.0/go.mod h1:OFC/31mSvZgRz0V1QTNCzfAI1aIRzbiufJtkMIlEp58= golang.org/x/crypto v0.13.0/go.mod h1:y6Z2r+Rw4iayiXXAIxJIDAJ1zMW4yaTpebo8fPOliYc= -golang.org/x/crypto v0.15.0 h1:frVn1TEaCEaZcn3Tmd7Y2b5KKPaZ+I32Q2OA3kYp5TA= -golang.org/x/crypto v0.15.0/go.mod h1:4ChreQoLWfG3xLDer1WdlH5NdlQ3+mwnQq1YTKY+72g= golang.org/x/crypto v0.17.0 h1:r8bRNjWL3GshPW3gkd+RpvzWrZAwPS49OmTGZ/uhM4k= golang.org/x/crypto v0.17.0/go.mod h1:gCAAfMLgwOJRpTjQ2zCCt2OcSfYMTeZVSRtQlPC7Nq4= golang.org/x/exp v0.0.0-20190121172915-509febef88a4/go.mod h1:CJ0aWSM057203Lf6IL+f9T1iT9GByDxfZKAQTCR3kQA= @@ -1280,8 +1275,6 @@ golang.org/x/sys v0.6.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.8.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.11.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.12.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= -golang.org/x/sys v0.14.0 h1:Vz7Qs629MkJkGyHxUlRHizWJRG2j8fbQKjELVSNhy7Q= -golang.org/x/sys v0.14.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA= golang.org/x/sys v0.15.0 h1:h48lPFYpsTvQJZF4EKyI4aLHaev3CxivZmv7yZig9pc= golang.org/x/sys v0.15.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA= golang.org/x/term v0.0.0-20201117132131-f5c789dd3221/go.mod h1:Nr5EML6q2oocZ2LXRh80K7BxOlk5/8JxuGnuhpl+muw= diff --git a/internal/api/server.go b/internal/api/server.go index 6db1aedd7..03509d5ab 100644 --- a/internal/api/server.go +++ b/internal/api/server.go @@ -392,6 +392,7 @@ func (s *Server) Agent(ctx context.Context, request AgentRequestObject) (AgentRe log.Debug(ctx, "agent empty request") return Agent400JSONResponse{N400JSONResponse{"cannot proceed with an empty request"}}, nil } + fmt.Println(request.Body) basicMessage, err := s.packageManager.UnpackWithType(packers.MediaTypeZKPMessage, []byte(*request.Body)) if err != nil { log.Debug(ctx, "agent bad request", "err", err, "body", *request.Body) diff --git a/internal/core/services/proof.go b/internal/core/services/proof.go index 4e90d1220..acb8eb366 100644 --- a/internal/core/services/proof.go +++ b/internal/core/services/proof.go @@ -334,12 +334,7 @@ func (p *Proof) checkRevocationStatus(ctx context.Context, claim *domain.Claim) } return &verifiable.RevocationStatus{ - Issuer: struct { - State *string `json:"state,omitempty"` - RootOfRoots *string `json:"rootOfRoots,omitempty"` - ClaimsTreeRoot *string `json:"claimsTreeRoot,omitempty"` - RevocationTreeRoot *string `json:"revocationTreeRoot,omitempty"` - }{ + Issuer: verifiable.TreeState{ State: bjp.IssuerData.State.Value, RootOfRoots: bjp.IssuerData.State.RootOfRoots, ClaimsTreeRoot: bjp.IssuerData.State.ClaimsTreeRoot, @@ -514,12 +509,7 @@ func (p *Proof) callNonRevProof(ctx context.Context, issuerData verifiable.Issue NodeAux: nil, }, TreeState: domain.RevocationStatusToTreeState(verifiable.RevocationStatus{ - Issuer: struct { - State *string `json:"state,omitempty"` - RootOfRoots *string `json:"rootOfRoots,omitempty"` - ClaimsTreeRoot *string `json:"claimsTreeRoot,omitempty"` - RevocationTreeRoot *string `json:"revocationTreeRoot,omitempty"` - }{ + Issuer: verifiable.TreeState{ State: issuerData.State.Value, RootOfRoots: issuerData.State.RootOfRoots, ClaimsTreeRoot: issuerData.State.ClaimsTreeRoot, diff --git a/internal/core/services/revocation.go b/internal/core/services/revocation.go index e861b67d9..3740537fb 100644 --- a/internal/core/services/revocation.go +++ b/internal/core/services/revocation.go @@ -227,12 +227,7 @@ func getNonRevocationProofFromRHS(ctx context.Context, rhsURL string, data, issu } return &verifiable.RevocationStatus{ - Issuer: struct { - State *string `json:"state,omitempty"` - RootOfRoots *string `json:"rootOfRoots,omitempty"` - ClaimsTreeRoot *string `json:"claimsTreeRoot,omitempty"` - RevocationTreeRoot *string `json:"revocationTreeRoot,omitempty"` - }{ + Issuer: verifiable.TreeState{ State: &s, ClaimsTreeRoot: &CTR, RevocationTreeRoot: &RTR, @@ -316,12 +311,7 @@ func getRevocationStatusFromIssuerData(did *w3c.DID, issuerData *verifiable.Issu } return &verifiable.RevocationStatus{ - Issuer: struct { - State *string `json:"state,omitempty"` - RootOfRoots *string `json:"rootOfRoots,omitempty"` - ClaimsTreeRoot *string `json:"claimsTreeRoot,omitempty"` - RevocationTreeRoot *string `json:"revocationTreeRoot,omitempty"` - }{ + Issuer: verifiable.TreeState{ State: issuerData.State.Value, RootOfRoots: issuerData.State.RootOfRoots, ClaimsTreeRoot: issuerData.State.ClaimsTreeRoot, @@ -427,12 +417,7 @@ func (r *Revocation) getRevocationStatusFromOnchainCredStatusResolver(ctx contex rorHex := ror.Hex() return &verifiable.RevocationStatus{ - Issuer: struct { - State *string `json:"state,omitempty"` - RootOfRoots *string `json:"rootOfRoots,omitempty"` - ClaimsTreeRoot *string `json:"claimsTreeRoot,omitempty"` - RevocationTreeRoot *string `json:"revocationTreeRoot,omitempty"` - }{ + Issuer: verifiable.TreeState{ State: &stateHex, ClaimsTreeRoot: &ctrHex, RevocationTreeRoot: &rtrHex, From 4b3737d90183b66bbb2ae0597f7d02259b43ad68 Mon Sep 17 00:00:00 2001 From: Martin Saporiti Date: Wed, 22 May 2024 11:00:47 -0300 Subject: [PATCH 07/52] chore: remove print --- internal/api/server.go | 1 - 1 file changed, 1 deletion(-) diff --git a/internal/api/server.go b/internal/api/server.go index e11b72374..68dac11a0 100644 --- a/internal/api/server.go +++ b/internal/api/server.go @@ -407,7 +407,6 @@ func (s *Server) Agent(ctx context.Context, request AgentRequestObject) (AgentRe log.Debug(ctx, "agent empty request") return Agent400JSONResponse{N400JSONResponse{"cannot proceed with an empty request"}}, nil } - fmt.Println(request.Body) basicMessage, err := s.packageManager.UnpackWithType(packers.MediaTypeZKPMessage, []byte(*request.Body)) if err != nil { log.Debug(ctx, "agent bad request", "err", err, "body", *request.Body) From 74de2926a2ea5ea84f7e516cee9a01f9564fe1de Mon Sep 17 00:00:00 2001 From: Viktor Date: Fri, 24 May 2024 02:26:36 -0700 Subject: [PATCH 08/52] update license (#657) --- LICENSE-APACHE | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/LICENSE-APACHE b/LICENSE-APACHE index 5ac2a9392..629a8cd17 100644 --- a/LICENSE-APACHE +++ b/LICENSE-APACHE @@ -1,4 +1,3 @@ -Copyright (C) 2023 ZKID Labs AG Apache License Version 2.0, January 2004 http://www.apache.org/licenses/ @@ -199,4 +198,4 @@ Copyright (C) 2023 ZKID Labs AG distributed under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and - limitations under the License. \ No newline at end of file + limitations under the License. From e17968fe705f547fe7a9d4f8d2a5ea4f8b2eff9e Mon Sep 17 00:00:00 2001 From: Martin Saporiti Date: Fri, 24 May 2024 06:29:58 -0300 Subject: [PATCH 09/52] fix: Reverse OnChain Contract updated (#655) --- k8s/helm/templates/_helpers.tpl | 8 ++++---- k8s/helm/values.yaml | 4 ++++ 2 files changed, 8 insertions(+), 4 deletions(-) diff --git a/k8s/helm/templates/_helpers.tpl b/k8s/helm/templates/_helpers.tpl index a2038e150..cd7201ba1 100644 --- a/k8s/helm/templates/_helpers.tpl +++ b/k8s/helm/templates/_helpers.tpl @@ -136,9 +136,9 @@ Define RHS_CHAIN_ID */}} {{- define "helpers.api-rsh-chain-id" -}} {{- if eq .Values.mainnet true }} -"137" +{{ .Values.apiIssuerNode.configMap.issuerRshChainIDMain | quote }} {{- else }} -"80002" +{{ .Values.apiIssuerNode.configMap.issuerRshChainIDAmoy | quote }} {{- end }} {{- end }} @@ -147,9 +147,9 @@ Define Rhs contract */}} {{- define "helpers.api-rsh-contract" -}} {{- if eq .Values.mainnet true }} -"0xbEeB6bB53504E8C872023451fd0D23BeF01d320B" +{{ .Values.apiIssuerNode.configMap.issuerRshContractMain | quote }} {{- else }} -"0x16A1ae4c460C0a42f0a87e69c526c61599B28BC9" +{{ .Values.apiIssuerNode.configMap.issuerRshContractAmoy | quote }} {{- end }} {{- end }} diff --git a/k8s/helm/values.yaml b/k8s/helm/values.yaml index f4f134c6d..74fd7a223 100644 --- a/k8s/helm/values.yaml +++ b/k8s/helm/values.yaml @@ -82,6 +82,10 @@ apiIssuerNode: issuerVaultUserpassAuthEnabled: "true" issuerCredentialStatusPublishingKeyPath: pbkey issuerIpfsGatewayUrl: https://gateway.pinata.cloud + issuerRshContractAmoy: 0x3d3763eC0a50CE1AdF83d0b5D99FBE0e3fEB43fb + issuerRshContractMain: 0xbEeB6bB53504E8C872023451fd0D23BeF01d320B + issuerRshChainIDMain: 137 + issuerRshChainIDAmoy: 80002 apiUiIssuerNode: deployment: From 06866af182811815e5524adee93378e16db657bc Mon Sep 17 00:00:00 2001 From: Martin Saporiti Date: Tue, 28 May 2024 14:01:00 -0300 Subject: [PATCH 10/52] chore: clean code and change endpoint to unpack with a different message --- cmd/platform/main.go | 17 +- cmd/platform_ui/main.go | 16 +- internal/api/server.go | 3 +- internal/core/ports/revocation_service.go | 13 - internal/core/services/claims.go | 1 + internal/core/services/proof.go | 737 ---------------------- internal/core/services/revocation.go | 482 -------------- pkg/protocol/packagemanager.go | 39 +- 8 files changed, 8 insertions(+), 1300 deletions(-) delete mode 100644 internal/core/ports/revocation_service.go delete mode 100644 internal/core/services/proof.go delete mode 100644 internal/core/services/revocation.go diff --git a/cmd/platform/main.go b/cmd/platform/main.go index f221e75f0..649052168 100644 --- a/cmd/platform/main.go +++ b/cmd/platform/main.go @@ -30,7 +30,6 @@ import ( "github.com/polygonid/sh-id-platform/internal/providers/blockchain" "github.com/polygonid/sh-id-platform/internal/redis" "github.com/polygonid/sh-id-platform/internal/repositories" - "github.com/polygonid/sh-id-platform/pkg/blockchain/eth" "github.com/polygonid/sh-id-platform/pkg/cache" "github.com/polygonid/sh-id-platform/pkg/credentials/revocation_status" circuitLoaders "github.com/polygonid/sh-id-platform/pkg/loaders" @@ -147,20 +146,6 @@ func main() { claimsService := services.NewClaim(claimsRepository, identityService, qrService, mtService, identityStateRepository, schemaLoader, storage, cfg.ServerUrl, ps, cfg.IPFS.GatewayURL, revocationStatusResolver) proofService := gateways.NewProver(ctx, cfg, circuitsLoaderService) - stateService, err := eth.NewStateService(eth.StateServiceConfig{ - EthClient: ethConn, - StateAddress: common.HexToAddress(cfg.Ethereum.ContractAddress), - ResponseTimeout: cfg.Ethereum.RPCResponseTimeout, - }) - if err != nil { - log.Error(ctx, "failed init state service", "err", err) - return - } - - onChainCredentialStatusResolverService := gateways.NewOnChainCredStatusResolverService(ethConn, cfg.Ethereum.RPCResponseTimeout) - revocationService := services.NewRevocationService(common.HexToAddress(cfg.Ethereum.ContractAddress), stateService, onChainCredentialStatusResolverService) - - zkProofService := services.NewProofService(claimsService, revocationService, identityService, mtService, claimsRepository, keyStore, storage, stateService, schemaLoader) transactionService, err := gateways.NewTransaction(ethereumClient, cfg.Ethereum.ConfirmationBlockCount) if err != nil { log.Error(ctx, "error creating transaction service", "err", err) @@ -175,7 +160,7 @@ func main() { publisher := gateways.NewPublisher(storage, identityService, claimsService, mtService, keyStore, transactionService, proofService, publisherGateway, cfg.Ethereum.ConfirmationTimeout, ps) - packageManager, err := protocol.InitPackageManager(ctx, stateContract, zkProofService, cfg.Circuit.Path) + packageManager, err := protocol.InitPackageManager(stateContract, cfg.Circuit.Path) if err != nil { log.Error(ctx, "failed init package protocol", "err", err) return diff --git a/cmd/platform_ui/main.go b/cmd/platform_ui/main.go index 27d9f5e3c..3c600c2cb 100644 --- a/cmd/platform_ui/main.go +++ b/cmd/platform_ui/main.go @@ -37,7 +37,6 @@ import ( "github.com/polygonid/sh-id-platform/internal/providers/blockchain" "github.com/polygonid/sh-id-platform/internal/redis" "github.com/polygonid/sh-id-platform/internal/repositories" - "github.com/polygonid/sh-id-platform/pkg/blockchain/eth" "github.com/polygonid/sh-id-platform/pkg/cache" "github.com/polygonid/sh-id-platform/pkg/credentials/revocation_status" circuitLoaders "github.com/polygonid/sh-id-platform/pkg/loaders" @@ -181,19 +180,6 @@ func main() { connectionsService := services.NewConnection(connectionsRepository, claimsRepository, storage) linkService := services.NewLinkService(storage, claimsService, qrService, claimsRepository, linkRepository, schemaRepository, schemaLoader, sessionRepository, ps, cfg.IPFS.GatewayURL) - stateService, err := eth.NewStateService(eth.StateServiceConfig{ - EthClient: ethConn, - StateAddress: common.HexToAddress(cfg.Ethereum.ContractAddress), - ResponseTimeout: cfg.Ethereum.RPCResponseTimeout, - }) - if err != nil { - log.Error(ctx, "failed init state service", "err", err) - return - } - - onChainCredentialStatusResolverService := gateways.NewOnChainCredStatusResolverService(ethConn, cfg.Ethereum.RPCResponseTimeout) - revocationService := services.NewRevocationService(common.HexToAddress(cfg.Ethereum.ContractAddress), stateService, onChainCredentialStatusResolverService) - zkProofService := services.NewProofService(claimsService, revocationService, identityService, mtService, claimsRepository, keyStore, storage, stateService, schemaLoader) transactionService, err := gateways.NewTransaction(ethereumClient, cfg.Ethereum.ConfirmationBlockCount) if err != nil { log.Error(ctx, "error creating transaction service", "err", err) @@ -208,7 +194,7 @@ func main() { publisher := gateways.NewPublisher(storage, identityService, claimsService, mtService, keyStore, transactionService, proofService, publisherGateway, cfg.Ethereum.ConfirmationTimeout, ps) - packageManager, err := protocol.InitPackageManager(ctx, stateContract, zkProofService, cfg.Circuit.Path) + packageManager, err := protocol.InitPackageManager(stateContract, cfg.Circuit.Path) if err != nil { log.Error(ctx, "failed init package protocol", "err", err) return diff --git a/internal/api/server.go b/internal/api/server.go index 68dac11a0..a026cb94e 100644 --- a/internal/api/server.go +++ b/internal/api/server.go @@ -407,7 +407,8 @@ func (s *Server) Agent(ctx context.Context, request AgentRequestObject) (AgentRe log.Debug(ctx, "agent empty request") return Agent400JSONResponse{N400JSONResponse{"cannot proceed with an empty request"}}, nil } - basicMessage, err := s.packageManager.UnpackWithType(packers.MediaTypeZKPMessage, []byte(*request.Body)) + + basicMessage, _, err := s.packageManager.Unpack([]byte(*request.Body)) if err != nil { log.Debug(ctx, "agent bad request", "err", err, "body", *request.Body) return Agent400JSONResponse{N400JSONResponse{"cannot proceed with the given request"}}, nil diff --git a/internal/core/ports/revocation_service.go b/internal/core/ports/revocation_service.go deleted file mode 100644 index efd7cc726..000000000 --- a/internal/core/ports/revocation_service.go +++ /dev/null @@ -1,13 +0,0 @@ -package ports - -import ( - "context" - - "github.com/iden3/go-iden3-core/v2/w3c" - "github.com/iden3/go-schema-processor/v2/verifiable" -) - -// RevocationService is the interface implemented by the RevocationService service -type RevocationService interface { - Status(ctx context.Context, credStatus interface{}, issuerDID *w3c.DID, issuerData *verifiable.IssuerData) (*verifiable.RevocationStatus, error) -} diff --git a/internal/core/services/claims.go b/internal/core/services/claims.go index 1a8192bca..5ed45b479 100644 --- a/internal/core/services/claims.go +++ b/internal/core/services/claims.go @@ -630,6 +630,7 @@ func (c *claim) getRevocationStatus(ctx context.Context, basicMessage *ports.Age Body: protocol.RevocationStatusResponseMessageBody{RevocationStatus: *revStatus}, From: basicMessage.IssuerDID.String(), To: basicMessage.UserDID.String(), + Typ: packers.MediaTypePlainMessage, }, nil } diff --git a/internal/core/services/proof.go b/internal/core/services/proof.go deleted file mode 100644 index acb8eb366..000000000 --- a/internal/core/services/proof.go +++ /dev/null @@ -1,737 +0,0 @@ -package services - -import ( - "context" - "encoding/json" - "errors" - "fmt" - "math/big" - "time" - - "github.com/google/uuid" - "github.com/iden3/go-circuits/v2" - core "github.com/iden3/go-iden3-core/v2" - "github.com/iden3/go-iden3-core/v2/w3c" - "github.com/iden3/go-iden3-crypto/babyjub" - "github.com/iden3/go-merkletree-sql/v2" - jsonSuite "github.com/iden3/go-schema-processor/v2/json" - "github.com/iden3/go-schema-processor/v2/merklize" - "github.com/iden3/go-schema-processor/v2/processor" - "github.com/iden3/go-schema-processor/v2/verifiable" - "github.com/jackc/pgx/v4" - "github.com/piprate/json-gold/ld" - - "github.com/polygonid/sh-id-platform/internal/common" - "github.com/polygonid/sh-id-platform/internal/core/domain" - "github.com/polygonid/sh-id-platform/internal/core/ports" - "github.com/polygonid/sh-id-platform/internal/db" - "github.com/polygonid/sh-id-platform/internal/jsonschema" - "github.com/polygonid/sh-id-platform/internal/kms" - "github.com/polygonid/sh-id-platform/internal/loader" - "github.com/polygonid/sh-id-platform/internal/log" - "github.com/polygonid/sh-id-platform/internal/repositories" - "github.com/polygonid/sh-id-platform/pkg/credentials/signature/circuit/signer" - "github.com/polygonid/sh-id-platform/pkg/protocol" -) - -const ( - defaultAtomicCircuitsID = 10 -) - -// ErrAllClaimsRevoked all claims are revoked. -var ( - ErrAllClaimsRevoked = errors.New("all claims are revoked") -) - -// Proof service generates and validates ZK zk -type Proof struct { - claimSrv ports.ClaimsService - revocationSrv ports.RevocationService - identitySrv ports.IdentityService - mtService ports.MtService - claimsRepository ports.ClaimsRepository - keyProvider *kms.KMS - storage *db.Storage - stateService ports.StateService - schemaLoader loader.DocumentLoader - merklizeOptions []merklize.MerklizeOption -} - -// NewProofService init proof service -func NewProofService(claimSrv ports.ClaimsService, revocationSrv ports.RevocationService, identitySrv ports.IdentityService, mtService ports.MtService, claimsRepository ports.ClaimsRepository, keyProvider *kms.KMS, storage *db.Storage, stateService ports.StateService, ld ld.DocumentLoader) ports.ProofService { - merklizeOptions := []merklize.MerklizeOption{ - merklize.WithDocumentLoader(ld), - } - return &Proof{ - claimSrv: claimSrv, - revocationSrv: revocationSrv, - identitySrv: identitySrv, - mtService: mtService, - claimsRepository: claimsRepository, - keyProvider: keyProvider, - storage: storage, - stateService: stateService, - schemaLoader: ld, - merklizeOptions: merklizeOptions, - } -} - -// PrepareInputs prepare inputs for circuit. -// -//nolint:gocyclo // refactor later to avoid big PR. -func (p *Proof) PrepareInputs(ctx context.Context, identifier *w3c.DID, query ports.Query) ([]byte, []*domain.Claim, error) { - var claims []*domain.Claim - var err error - var claim *domain.Claim - - var circuitInputs circuits.InputsMarshaller - switch circuits.CircuitID(query.CircuitID) { - case circuits.AtomicQuerySigV2CircuitID: - circuitInputs, claim, err = p.prepareAtomicQuerySigV2Circuit(ctx, identifier, query) - if err != nil { - return nil, nil, err - } - claims = append(claims, claim) - - case circuits.AtomicQueryMTPV2CircuitID: - circuitInputs, claim, err = p.prepareAtomicQueryMTPV2Circuit(ctx, identifier, query) - if err != nil { - return nil, nil, err - } - claims = append(claims, claim) - - case circuits.AuthV2CircuitID: - circuitInputs, err = p.prepareAuthV2Circuit(ctx, identifier, query.Challenge) - if err != nil { - return nil, nil, err - } - - default: - return nil, nil, fmt.Errorf("circuit with id %s is not supported", query.CircuitID) - } - - inputs, err := circuitInputs.InputsMarshal() - if err != nil { - return nil, nil, err - } - - log.Debug(ctx, "Circuit inputs", "inputs", string(inputs)) - - return inputs, claims, nil -} - -func (p *Proof) prepareAtomicQuerySigV2Circuit(ctx context.Context, did *w3c.DID, query ports.Query) (circuits.InputsMarshaller, *domain.Claim, error) { - claim, claimNonRevProof, err := p.getClaimDataForAtomicQueryCircuit(ctx, did, query) - if err != nil { - return nil, nil, err - } - - sigProof, err := claim.GetBJJSignatureProof2021() - if err != nil { - return nil, nil, err - } - - sig, err := signer.BJJSignatureFromHexString(sigProof.Signature) - if err != nil { - return nil, nil, err - } - - issuerDID, err := w3c.ParseDID(claim.Issuer) - if err != nil { - return nil, nil, err - } - - issuerAuthNonRevProof, err := p.callNonRevProof(ctx, sigProof.IssuerData, issuerDID) - if err != nil { - return nil, nil, err - } - - circuitQuery, err := p.toCircuitsQuery(ctx, *claim, query) - if err != nil { - return nil, nil, err - } - - authClaim := &core.Claim{} - err = authClaim.FromHex(sigProof.IssuerData.AuthCoreClaim) - if err != nil { - return nil, nil, err - } - - sig1 := circuits.BJJSignatureProof{ - Signature: sig, - IssuerAuthClaim: authClaim, - IssuerAuthIncProof: circuits.MTProof{ - Proof: sigProof.IssuerData.MTP, - TreeState: circuits.TreeState{ - State: common.StrMTHex(sigProof.IssuerData.State.Value), - ClaimsRoot: common.StrMTHex(sigProof.IssuerData.State.ClaimsTreeRoot), - RevocationRoot: common.StrMTHex(sigProof.IssuerData.State.RevocationTreeRoot), - RootOfRoots: common.StrMTHex(sigProof.IssuerData.State.RootOfRoots), - }, - }, - IssuerAuthNonRevProof: issuerAuthNonRevProof, - } - - id, err := core.IDFromDID(*did) - if err != nil { - return nil, nil, err - } - - inputs := circuits.AtomicQuerySigV2Inputs{ - RequestID: big.NewInt(defaultAtomicCircuitsID), - ID: &id, - ProfileNonce: big.NewInt(0), - ClaimSubjectProfileNonce: big.NewInt(0), - Claim: circuits.ClaimWithSigProof{ - IssuerID: &id, - Claim: claim.CoreClaim.Get(), - NonRevProof: *claimNonRevProof, - SignatureProof: sig1, - }, - Query: circuitQuery, - CurrentTimeStamp: time.Now().Unix(), - SkipClaimRevocationCheck: query.SkipClaimRevocationCheck, - } - - return inputs, claim, nil -} - -func (p *Proof) prepareAtomicQueryMTPV2Circuit(ctx context.Context, did *w3c.DID, query ports.Query) (circuits.InputsMarshaller, *domain.Claim, error) { - claim, claimNonRevProof, err := p.getClaimDataForAtomicQueryCircuit(ctx, did, query) - if err != nil { - return nil, nil, err - } - - claimInc, err := claim.GetCircuitIncProof() - if err != nil { - return nil, nil, err - } - - circuitQuery, err := p.toCircuitsQuery(ctx, *claim, query) - if err != nil { - return nil, nil, err - } - - id, err := core.IDFromDID(*did) - if err != nil { - return nil, nil, err - } - - inputs := circuits.AtomicQueryMTPV2Inputs{ - RequestID: big.NewInt(defaultAtomicCircuitsID), - ID: &id, - ProfileNonce: big.NewInt(0), - ClaimSubjectProfileNonce: big.NewInt(0), - Claim: circuits.ClaimWithMTPProof{ - IssuerID: &id, // claim.Issuer, - Claim: claim.CoreClaim.Get(), - NonRevProof: *claimNonRevProof, - IncProof: claimInc, - }, - Query: circuitQuery, - CurrentTimeStamp: time.Now().Unix(), - SkipClaimRevocationCheck: query.SkipClaimRevocationCheck, - } - - return inputs, claim, nil -} - -func (p *Proof) getClaimDataForAtomicQueryCircuit(ctx context.Context, identifier *w3c.DID, query ports.Query) (claim *domain.Claim, revStatus *circuits.MTProof, err error) { - var claims []*domain.Claim - - if query.ClaimID != "" { - // if claimID exist. Search by claimID. - claimUUID, err := uuid.Parse(query.ClaimID) - if err != nil { - return nil, nil, err - } - var c *domain.Claim - c, err = p.claimSrv.GetByID(ctx, identifier, claimUUID) - if err != nil { - return nil, nil, err - } - // we need to be sure that the hallmark selected by ID matches circuitQuery. - claims = append(claims, c) - } else { - // if claimID NOT exist in request select all claims and filter it. - claims, err = p.findClaimForQuery(ctx, identifier, query) - if err != nil { - return claim, nil, err - } - } - - var claimRs circuits.MTProof - if query.SkipClaimRevocationCheck { - claim = claims[0] - rsClaim, err := p.checkRevocationStatus(ctx, claim) - if err != nil { - return claim, nil, err - } - claimRs = circuits.MTProof{ - TreeState: domain.RevocationStatusToTreeState(*rsClaim), - Proof: &rsClaim.MTP, - } - } else { - claim, claimRs, err = p.findNonRevokedClaim(ctx, claims) - if err != nil { - return claim, nil, err - } - } - return claim, &claimRs, nil -} - -func (p *Proof) findClaimForQuery(ctx context.Context, identifier *w3c.DID, query ports.Query) ([]*domain.Claim, error) { - var err error - - // TODO "query_value": value, - // TODO "query_operator": operator, - filter := &ports.ClaimsFilter{SchemaType: query.SchemaType()} - if !query.SkipClaimRevocationCheck { - filter.Revoked = common.ToPointer(false) - } - - claim, _, err := p.claimsRepository.GetAllByIssuerID(ctx, p.storage.Pgx, *identifier, filter) - if errors.Is(err, repositories.ErrClaimDoesNotExist) { - return nil, fmt.Errorf("claim with credential type %v was not found", query) - } - - return claim, err -} - -func (p *Proof) checkRevocationStatus(ctx context.Context, claim *domain.Claim) (*verifiable.RevocationStatus, error) { - var ( - err error - claimRs *verifiable.RevocationStatus - ) - - var cs map[string]interface{} - if err = json.Unmarshal(claim.CredentialStatus.Bytes, &cs); err != nil { - return nil, fmt.Errorf("failed unmasrshal credentialStatus: %s", err) - } - issuerDID, err := w3c.ParseDID(claim.Issuer) - if err != nil { - return nil, err - } - - sigProof, err := claim.GetBJJSignatureProof2021() - if err != nil { - return nil, err - } - - claimRs, err = p.revocationSrv.Status(ctx, cs, issuerDID, &sigProof.IssuerData) - if err != nil && errors.Is(err, protocol.ErrStateNotFound) { - - bjp := new(verifiable.BJJSignatureProof2021) - if err := json.Unmarshal(claim.SignatureProof.Bytes, bjp); err != nil { - return nil, fmt.Errorf("failed parse signature proof for get genesys state: %s", err) - } - state, errIn := merkletree.NewHashFromHex(*bjp.IssuerData.State.Value) - if errIn != nil { - return nil, err - } - if common.CheckGenesisStateDID(issuerDID, state.BigInt()) != nil { - return nil, errors.New("issuer identity is not genesis and not published") - } - - return &verifiable.RevocationStatus{ - Issuer: verifiable.TreeState{ - State: bjp.IssuerData.State.Value, - RootOfRoots: bjp.IssuerData.State.RootOfRoots, - ClaimsTreeRoot: bjp.IssuerData.State.ClaimsTreeRoot, - RevocationTreeRoot: bjp.IssuerData.State.RevocationTreeRoot, - }, - MTP: merkletree.Proof{Existence: false}, - }, nil - } else if err != nil { - return nil, err - } - if claimRs.MTP.Existence { - // update revocation status - err = p.storage.Pgx.BeginFunc(ctx, func(tx pgx.Tx) error { - claim.Revoked = true - _, err = p.claimsRepository.Save(ctx, p.storage.Pgx, claim) - if err != nil { - return fmt.Errorf("can't save claim %v", err) - } - return nil - }) - if err != nil { - return nil, err - } - // claim revoked - return claimRs, nil - } - // claim not revoked - return claimRs, nil -} - -func (p *Proof) findNonRevokedClaim(ctx context.Context, claims []*domain.Claim) (*domain.Claim, circuits.MTProof, error) { - for _, claim := range claims { - rsClaim, err := p.checkRevocationStatus(ctx, claim) - if err != nil { - return nil, circuits.MTProof{}, err - } - // current claim revoked. To try next claim. - if rsClaim == nil { - continue - } - - revStatus := circuits.MTProof{ - TreeState: domain.RevocationStatusToTreeState(*rsClaim), - Proof: &rsClaim.MTP, - } - - return claim, revStatus, nil - } - return nil, circuits.MTProof{}, ErrAllClaimsRevoked -} - -func (p *Proof) toCircuitsQuery(ctx context.Context, claim domain.Claim, query ports.Query) (circuits.Query, error) { - // check if merklized - coreClaim := claim.CoreClaim.Get() - - merklizePosition, err := coreClaim.GetMerklizedPosition() - if err != nil { - return circuits.Query{}, err - } - if merklizePosition == core.MerklizedRootPositionNone { - credential, err := claim.GetVerifiableCredential() - if err != nil { - return circuits.Query{}, err - } - return p.prepareNonMerklizedQuery(ctx, credential.CredentialSchema.ID, query) - } - - return p.prepareMerklizedQuery(ctx, claim, query) -} - -func (p *Proof) prepareMerklizedQuery(ctx context.Context, claim domain.Claim, query ports.Query) (circuits.Query, error) { - vc, err := claim.GetVerifiableCredential() - if err != nil { - return circuits.Query{}, err - } - - mk, err := vc.Merklize(ctx, p.merklizeOptions...) - if err != nil { - return circuits.Query{}, err - } - - circuitQuery, field, err := parseQueryWithoutSlot(query.Req) - if err != nil { - return circuits.Query{}, err - } - - schema, err := jsonschema.Load(ctx, query.Context, p.schemaLoader) - if err != nil { - return circuits.Query{}, err - } - - fieldPath := merklize.Path{} - - if field != "" { - fieldPath, err = merklize.NewFieldPathFromContext(schema.BytesNoErr(), query.Type, field) - if err != nil { - return circuits.Query{}, err - } - } - - err = fieldPath.Prepend("https://www.w3.org/2018/credentials#credentialSubject") - if err != nil { - return circuits.Query{}, err - } - - jsonP, v, err := mk.Proof(ctx, fieldPath) - if err != nil { - return circuits.Query{}, err - } - - value, err := v.MtEntry() - if err != nil { - return circuits.Query{}, err - } - - path, err := fieldPath.MtEntry() - if err != nil { - return circuits.Query{}, err - } - - circuitQuery.ValueProof = &circuits.ValueProof{ - Path: path, - Value: value, - MTP: jsonP, - } - - return circuitQuery, nil -} - -func (p *Proof) prepareNonMerklizedQuery(ctx context.Context, jsonSchemaURL string, query ports.Query) (circuits.Query, error) { - parser := jsonSuite.Parser{} - pr := processor.InitProcessorOptions(&processor.Processor{}, - processor.WithParser(parser), - processor.WithDocumentLoader(p.schemaLoader)) - - schema, err := jsonschema.Load(ctx, jsonSchemaURL, p.schemaLoader) - if err != nil { - return circuits.Query{}, err - } - - if len(query.Req) > 1 { - return circuits.Query{}, errors.New("multiple requests are currently not supported") - } - - circuitQuery, field, err := parseQueryWithoutSlot(query.Req) - if err != nil { - return circuits.Query{}, err - } - - circuitQuery.SlotIndex, err = pr.GetFieldSlotIndex(field, query.Type, schema.BytesNoErr()) - if err != nil { - return circuits.Query{}, err - } - - return circuitQuery, nil -} - -func (p *Proof) callNonRevProof(ctx context.Context, issuerData verifiable.IssuerData, issuerDID *w3c.DID) (circuits.MTProof, error) { - nonRevProof, err := p.revocationSrv.Status(ctx, issuerData.CredentialStatus, issuerDID, &issuerData) - - if err != nil && errors.Is(err, protocol.ErrStateNotFound) { - state, errIn := merkletree.NewHashFromHex(*issuerData.State.Value) - if errIn != nil { - return circuits.MTProof{}, err - } - if common.CheckGenesisStateDID(issuerDID, state.BigInt()) != nil { - return circuits.MTProof{}, errors.New("issuer identity is not genesis and not published") - } - return circuits.MTProof{ - Proof: &merkletree.Proof{ - Existence: false, - NodeAux: nil, - }, - TreeState: domain.RevocationStatusToTreeState(verifiable.RevocationStatus{ - Issuer: verifiable.TreeState{ - State: issuerData.State.Value, - RootOfRoots: issuerData.State.RootOfRoots, - ClaimsTreeRoot: issuerData.State.ClaimsTreeRoot, - RevocationTreeRoot: issuerData.State.RevocationTreeRoot, - }, - MTP: merkletree.Proof{}, - }), - }, nil - } - - return circuits.MTProof{ - Proof: &nonRevProof.MTP, - TreeState: domain.RevocationStatusToTreeState(*nonRevProof), - }, nil -} - -func (p *Proof) prepareAuthV2Circuit(ctx context.Context, identifier *w3c.DID, challenge *big.Int) (circuits.AuthV2Inputs, error) { - authClaim, err := p.claimSrv.GetAuthClaim(ctx, identifier) - if err != nil { - return circuits.AuthV2Inputs{}, err - } - - authClaimData, err := p.fillAuthClaimData(ctx, identifier, authClaim) - if err != nil { - return circuits.AuthV2Inputs{}, err - } - signature, err := p.signChallange(ctx, authClaim, challenge) - if err != nil { - return circuits.AuthV2Inputs{}, err - } - globalTree, err := populateGlobalTree(ctx, identifier, p.stateService) - if err != nil { - return circuits.AuthV2Inputs{}, err - } - id, err := core.IDFromDID(*identifier) - if err != nil { - return circuits.AuthV2Inputs{}, err - } - circuitInputs := prepareAuthV2CircuitInputs(id, authClaimData, challenge, signature, globalTree) - return circuitInputs, nil -} - -func (p *Proof) signChallange(ctx context.Context, authClaim *domain.Claim, challenge *big.Int) (*babyjub.Signature, error) { - signingKeyID, err := p.identitySrv.GetKeyIDFromAuthClaim(ctx, authClaim) - if err != nil { - return nil, err - } - - challengeDigest := kms.BJJDigest(challenge) - - var sigBytes []byte - sigBytes, err = p.keyProvider.Sign(ctx, signingKeyID, challengeDigest) - if err != nil { - return nil, err - } - - return kms.DecodeBJJSignature(sigBytes) -} - -func (p *Proof) fillAuthClaimData(ctx context.Context, identifier *w3c.DID, authClaim *domain.Claim) (circuits.ClaimWithMTPProof, error) { - var authClaimData circuits.ClaimWithMTPProof - - err := p.storage.Pgx.BeginFunc( - ctx, func(tx pgx.Tx) error { - var errIn error - var idState *domain.IdentityState - idState, errIn = p.identitySrv.GetLatestStateByID(ctx, *identifier) - if errIn != nil { - return errIn - } - - identityTrees, errIn := p.mtService.GetIdentityMerkleTrees(ctx, tx, identifier) - if errIn != nil { - return errIn - } - - claimsTree, errIn := identityTrees.ClaimsTree() - if errIn != nil { - return errIn - } - // get index hash of authClaim - coreClaim := authClaim.CoreClaim.Get() - hIndex, errIn := coreClaim.HIndex() - if errIn != nil { - return errIn - } - - authClaimMTP, _, errIn := claimsTree.GenerateProof(ctx, hIndex, idState.TreeState().ClaimsRoot) - if errIn != nil { - return errIn - } - - authClaimData = circuits.ClaimWithMTPProof{ - Claim: coreClaim, - } - - authClaimData.IncProof = circuits.MTProof{ - Proof: authClaimMTP, - TreeState: idState.TreeState(), - } - - // revocation / non revocation MTP for the latest identity state - nonRevocationProof, errIn := identityTrees. - GenerateRevocationProof(ctx, new(big.Int).SetUint64(uint64(authClaim.RevNonce)), idState.TreeState().RevocationRoot) - - authClaimData.NonRevProof = circuits.MTProof{ - TreeState: idState.TreeState(), - Proof: nonRevocationProof, - } - - return errIn - }) - if err != nil { - return authClaimData, err - } - return authClaimData, nil -} - -func prepareAuthV2CircuitInputs(id core.ID, authClaim circuits.ClaimWithMTPProof, challenge *big.Int, signature *babyjub.Signature, globalMTP circuits.GISTProof) circuits.AuthV2Inputs { - return circuits.AuthV2Inputs{ - GenesisID: &id, - ProfileNonce: big.NewInt(0), - AuthClaim: authClaim.Claim, - AuthClaimIncMtp: authClaim.IncProof.Proof, - AuthClaimNonRevMtp: authClaim.NonRevProof.Proof, - TreeState: authClaim.IncProof.TreeState, - Signature: signature, - Challenge: challenge, - GISTProof: globalMTP, - } -} - -func populateGlobalTree(ctx context.Context, did *w3c.DID, stateService ports.StateService) (circuits.GISTProof, error) { - // get global root - gProof, err := stateService.GetGistProof(ctx, did) - if err != nil { - return circuits.GISTProof{}, err - } - - siblings := make([]*big.Int, len(gProof.Siblings)) - for i, s := range &gProof.Siblings { - siblings[i] = s - } - - proof, err := common.SmartContractProofToMtProofAdapter(common.SmartContractProof{ - Root: gProof.Root, - Existence: gProof.Existence, - Siblings: siblings, - Index: gProof.Index, - Value: gProof.Value, - AuxExistence: gProof.AuxExistence, - AuxIndex: gProof.AuxIndex, - AuxValue: gProof.AuxValue, - }) - if err != nil { - return circuits.GISTProof{}, err - } - - root, err := merkletree.NewHashFromBigInt(gProof.Root) - if err != nil { - return circuits.GISTProof{}, err - } - return circuits.GISTProof{ - Root: root, - Proof: proof, - }, nil -} - -func getValuesFromArray(v interface{}) ([]*big.Int, error) { - values := []*big.Int{} - - switch value := v.(type) { - case float64: - values = []*big.Int{new(big.Int).SetInt64(int64(value))} - case []interface{}: - for _, item := range value { - if itemFloat, ok := item.(float64); ok { - values = append(values, new(big.Int).SetInt64(int64(itemFloat))) - } else { - return nil, fmt.Errorf("unsupported values type in value element %T, expected float64", item) - } - } - default: - return nil, fmt.Errorf("unsupported values type %T", v) - } - - return values, nil -} - -func parseQueryWithoutSlot(req map[string]interface{}) (circuits.Query, string, error) { - for field, body := range req { - condition, ok := body.(map[string]interface{}) - - if !ok { - return circuits.Query{}, "", errors.New("failed cast type map[string]interface") - } - - if len(condition) > 1 { - return circuits.Query{}, "", errors.New("multiple predicates are currently not supported") - } - - for op, v := range condition { - - intOp, ok := circuits.QueryOperators[op] - if !ok { - return circuits.Query{}, "", errors.New("query operator is not supported") - } - - values, err := getValuesFromArray(v) - if err != nil { - return circuits.Query{}, "", err - } - - return circuits.Query{ - Operator: intOp, - Values: values, - }, field, nil - } - } - return circuits.Query{ - Operator: 0, - Values: []*big.Int{}, - SlotIndex: 0, - }, "", nil -} diff --git a/internal/core/services/revocation.go b/internal/core/services/revocation.go deleted file mode 100644 index 3740537fb..000000000 --- a/internal/core/services/revocation.go +++ /dev/null @@ -1,482 +0,0 @@ -package services - -import ( - "bytes" - "context" - "encoding/json" - "errors" - "fmt" - "io" - "math/big" - "net/http" - "net/url" - "strconv" - "strings" - "time" - - ethCommon "github.com/ethereum/go-ethereum/common" - "github.com/google/uuid" - abiOnchain "github.com/iden3/contracts-abi/onchain-credential-status-resolver/go/abi" - "github.com/iden3/contracts-abi/state/go/abi" - core "github.com/iden3/go-iden3-core/v2" - "github.com/iden3/go-iden3-core/v2/w3c" - "github.com/iden3/go-merkletree-sql/v2" - "github.com/iden3/go-schema-processor/v2/verifiable" - "github.com/iden3/iden3comm/v2" - "github.com/iden3/iden3comm/v2/packers" - "github.com/iden3/iden3comm/v2/protocol" - proofHttp "github.com/iden3/merkletree-proof/http" - - "github.com/polygonid/sh-id-platform/internal/common" - "github.com/polygonid/sh-id-platform/internal/core/ports" - "github.com/polygonid/sh-id-platform/internal/log" - client "github.com/polygonid/sh-id-platform/pkg/http" -) - -const ( - defaultRevocationTime = 30 - stateChildrenLength = 3 - contractPartsLength = 2 -) - -// ErrIdentityDoesNotExist - identity does not exist -var ErrIdentityDoesNotExist = errors.New("identity does not exist") - -// StateStore TBD -type StateStore interface { - GetLatestStateByID(ctx context.Context, addr ethCommon.Address, id *big.Int) (abi.IStateStateInfo, error) -} - -type onChainStatusService interface { - GetRevocationStatus(ctx context.Context, state *big.Int, nonce uint64, did *w3c.DID, address ethCommon.Address) (abiOnchain.IOnchainCredentialStatusResolverCredentialStatus, error) -} - -// Revocation TBD -type Revocation struct { - stateService ports.StateService - onChainStatusService onChainStatusService - contract ethCommon.Address -} - -// NewRevocationService returns the Revocation struct -func NewRevocationService(contract ethCommon.Address, stateService ports.StateService, onChainStatusService onChainStatusService) *Revocation { - return &Revocation{ - contract: contract, - stateService: stateService, - onChainStatusService: onChainStatusService, - } -} - -// Status returns the current revocation status -func (r *Revocation) Status(ctx context.Context, credStatus interface{}, issuerDID *w3c.DID, issuerData *verifiable.IssuerData) (*verifiable.RevocationStatus, error) { - status, err := convertCredentialStatus(credStatus) - if err != nil { - log.Error(ctx, "failed convert credential status", "error", err) - return nil, err - } - switch status.Type { - case verifiable.Iden3ReverseSparseMerkleTreeProof: - return r.getRevocationStatusFromRHS(ctx, issuerDID, status, issuerData) - case verifiable.SparseMerkleTreeProof: - return getRevocationProofFromIssuer(ctx, status.ID) - case verifiable.Iden3commRevocationStatusV1: - return getRevocationStatusFromAgent(ctx, issuerDID.String(), - issuerDID.String(), status.ID, status.RevocationNonce) - case verifiable.Iden3OnchainSparseMerkleTreeProof2023: - return r.getRevocationStatusFromOnchainCredStatusResolver(ctx, issuerDID, status) - default: - return nil, fmt.Errorf("%s type not supported", status.Type) - } -} - -func convertCredentialStatus(credStatus interface{}) (verifiable.CredentialStatus, error) { - status, ok := credStatus.(verifiable.CredentialStatus) - if ok { - return status, nil - } - pointedStatus, ok := credStatus.(*verifiable.CredentialStatus) - if ok { - return *pointedStatus, nil - } - _, ok = credStatus.(map[string]interface{}) - if ok { - b, err := json.Marshal(credStatus) - if err != nil { - return verifiable.CredentialStatus{}, err - } - var status verifiable.CredentialStatus - err = json.Unmarshal(b, &status) - if err != nil { - return verifiable.CredentialStatus{}, err - } - return status, nil - } - - return verifiable.CredentialStatus{}, errors.New("failed cast credential status to verifiable.CredentialStatus") -} - -func getRevocationStatusFromAgent(ctx context.Context, from, to, endpoint string, nonce uint64) (*verifiable.RevocationStatus, error) { - pkg := iden3comm.NewPackageManager() - if err := pkg.RegisterPackers(&packers.PlainMessagePacker{}); err != nil { - return nil, err - } - - revocationBody := protocol.RevocationStatusRequestMessageBody{ - RevocationNonce: nonce, - } - rawBody, err := json.Marshal(revocationBody) - if err != nil { - return nil, err - } - - msg := iden3comm.BasicMessage{ - ID: uuid.New().String(), - ThreadID: uuid.New().String(), - From: from, - To: to, - Type: protocol.RevocationStatusRequestMessageType, - Body: rawBody, - } - bytesMsg, err := json.Marshal(msg) - if err != nil { - return nil, err - } - - iden3commMsg, err := pkg.Pack(packers.MediaTypePlainMessage, bytesMsg, nil) - if err != nil { - return nil, err - } - - resp, err := http.DefaultClient.Post(endpoint, "application/json", bytes.NewBuffer(iden3commMsg)) - if err != nil { - return nil, err - } - defer func() { - if err := resp.Body.Close(); err != nil { - log.Warn(ctx, "failed to close response body: %s", err) - } - }() - - if resp.StatusCode != http.StatusOK { - return nil, fmt.Errorf("bad status code: %d", resp.StatusCode) - } - - b, err := io.ReadAll(resp.Body) - if err != nil { - return nil, err - } - basicMessage, _, err := pkg.Unpack(b) - if err != nil { - return nil, err - } - - if basicMessage.Type != protocol.RevocationStatusResponseMessageType { - return nil, fmt.Errorf("unexpected message type: %s", basicMessage.Type) - } - - var revocationStatus protocol.RevocationStatusResponseMessageBody - if err := json.Unmarshal(basicMessage.Body, &revocationStatus); err != nil { - return nil, err - } - - return &revocationStatus.RevocationStatus, nil -} - -func getRevocationProofFromIssuer(ctx context.Context, url string) (*verifiable.RevocationStatus, error) { - b, err := client.NewClient(*http.DefaultClient).Get(ctx, url) - if err != nil { - return nil, err - } - - rs := &verifiable.RevocationStatus{} - if err := json.Unmarshal(b, rs); err != nil { - return nil, err - } - return rs, nil -} - -func getNonRevocationProofFromRHS(ctx context.Context, rhsURL string, data, issuerRoot *merkletree.Hash) (*verifiable.RevocationStatus, error) { - rhsCli := proofHttp.ReverseHashCli{ - URL: rhsURL, - HTTPTimeout: time.Second * defaultRevocationTime, - } - - treeRoots, err := rhsCli.GetNode(ctx, issuerRoot) - if err != nil { - return nil, err - } - if len(treeRoots.Children) != stateChildrenLength { - return nil, fmt.Errorf("state should has tree children") - } - - var ( - s = issuerRoot.Hex() - CTR = treeRoots.Children[0].Hex() - RTR = treeRoots.Children[1].Hex() - RoTR = treeRoots.Children[2].Hex() - ) - - rtrHashed, err := merkletree.NewHashFromString(RTR) - if err != nil { - return nil, err - } - nonRevProof, err := rhsCli.GenerateProof(ctx, rtrHashed, data) - if err != nil { - return nil, fmt.Errorf("failed generate proof for root '%s' and element '%s': %s", - issuerRoot, data, err) - } - - return &verifiable.RevocationStatus{ - Issuer: verifiable.TreeState{ - State: &s, - ClaimsTreeRoot: &CTR, - RevocationTreeRoot: &RTR, - RootOfRoots: &RoTR, - }, - MTP: *nonRevProof, - }, nil -} - -func (r *Revocation) getRevocationStatusFromRHS(ctx context.Context, issuerDID *w3c.DID, status verifiable.CredentialStatus, issuerData *verifiable.IssuerData) (*verifiable.RevocationStatus, error) { - latestStateInfo, err := r.stateService.GetLatestStateByDID(ctx, issuerDID) - if err != nil && strings.Contains(err.Error(), ErrIdentityDoesNotExist.Error()) { - - currentState, err := extractState(status.ID) - if err != nil { - log.Error(ctx, "failed extract state from rhs id", "error", err) - return nil, err - } - if currentState == "" { - return getRevocationStatusFromIssuerData(issuerDID, issuerData) - } else { - latestStateInfo.State, err = getGenesisState(issuerDID, currentState) - if err != nil { - return nil, fmt.Errorf("failed get genesis state for issuer '%s'", issuerDID) - } - } - - } else if err != nil { - return nil, fmt.Errorf("failed get latest state by did '%s'", issuerDID.String()) - } - - hashedRevNonce, err := merkletree.NewHashFromBigInt(big.NewInt(int64(status.RevocationNonce))) - if err != nil { - return nil, fmt.Errorf("failed calculate mt hash for revocation nonce '%d': '%s'", - status.RevocationNonce, err) - } - - hashedIssuerState, err := merkletree.NewHashFromBigInt(latestStateInfo.State) - if err != nil { - return nil, fmt.Errorf("failed calcilate mt hash for issuer state '%s': '%s'", - latestStateInfo.State, err) - } - - u := strings.Split(status.ID, "/node") - rs, err := getNonRevocationProofFromRHS(ctx, u[0], hashedRevNonce, hashedIssuerState) - if err != nil && status.StatusIssuer.Type == verifiable.SparseMerkleTreeProof { - // try to get proof from issuer - log.Warn(ctx, "failed build revocation status from enabled RHS. Then try to fetch from issuer. RHS error: %v", err) - revocStatus, err := getRevocationProofFromIssuer(ctx, status.StatusIssuer.ID) - if err != nil { - return nil, err - } - return revocStatus, nil - } - return rs, nil -} - -func extractState(id string) (string, error) { - rhsULR, err := url.Parse(id) - if err != nil { - return "", fmt.Errorf("invalid rhs id filed '%s'", id) - } - params, err := url.ParseQuery(rhsULR.RawQuery) - if err != nil { - return "", fmt.Errorf("invalid rhs params '%s'", rhsULR.RawQuery) - } - return params.Get("state"), nil -} - -func getRevocationStatusFromIssuerData(did *w3c.DID, issuerData *verifiable.IssuerData) (*verifiable.RevocationStatus, error) { - if issuerData == nil || issuerData.State.Value == nil { - return nil, errors.New("issuer data state is empty. is not possible verify revocation status") - } - h, err := merkletree.NewHashFromHex(*issuerData.State.Value) - if err != nil { - return nil, fmt.Errorf("failed parse hex '%s'", *issuerData.State.Value) - } - err = common.CheckGenesisStateDID(did, h.BigInt()) - if err != nil { - return nil, fmt.Errorf("failed check genesis state for issuer '%s'", did) - } - - return &verifiable.RevocationStatus{ - Issuer: verifiable.TreeState{ - State: issuerData.State.Value, - RootOfRoots: issuerData.State.RootOfRoots, - ClaimsTreeRoot: issuerData.State.ClaimsTreeRoot, - RevocationTreeRoot: issuerData.State.RevocationTreeRoot, - }, - MTP: merkletree.Proof{Existence: false}, - }, nil -} - -func getGenesisState(did *w3c.DID, currentState string) (*big.Int, error) { - h, err := merkletree.NewHashFromHex(currentState) - if err != nil { - return nil, fmt.Errorf("failed parse hex '%s'", currentState) - } - err = common.CheckGenesisStateDID(did, h.BigInt()) - if err != nil { - return nil, fmt.Errorf("failed check genesis state for issuer '%s'", did) - } - return h.BigInt(), nil -} - -func (r *Revocation) getRevocationStatusFromOnchainCredStatusResolver(ctx context.Context, issuerDID *w3c.DID, status verifiable.CredentialStatus) (*verifiable.RevocationStatus, error) { - issuerID, err := core.IDFromDID(*issuerDID) - if err != nil { - return nil, fmt.Errorf("failed get issuer id from '%s'", issuerDID) - } - - onchainRevStatus, err := newOnchainRevStatusFromURI(status.ID) - if err != nil { - return nil, err - } - - if onchainRevStatus.revNonce != nil && *onchainRevStatus.revNonce != status.RevocationNonce { - return nil, fmt.Errorf("revocationNonce is not equal to the one in OnChainCredentialStatus ID {%d} {%d}", onchainRevStatus.revNonce, status.RevocationNonce) - } - - // get latest state from contract - var stateToProof *big.Int - latestStateInfo, err := r.stateService.GetLatestStateByDID(ctx, issuerDID) - //nolint:gocritic //reason: work with errors - if err != nil && strings.Contains(err.Error(), ErrIdentityDoesNotExist.Error()) { - if onchainRevStatus.state == nil { - return nil, errors.New(`latest state not found and state parameter is not present in credentialStatus.id`) - } - err = common.CheckGenesisStateDID(issuerDID, onchainRevStatus.state) - if err != nil { - return nil, err - } - stateToProof = onchainRevStatus.state - - } else if err != nil { - return nil, fmt.Errorf("failed get latest state by id '%s'", issuerID) - } else { - stateToProof = latestStateInfo.State - } - - rs, err := r.onChainStatusService.GetRevocationStatus( - ctx, stateToProof, status.RevocationNonce, issuerDID, onchainRevStatus.contractAddress, - ) - if err != nil { - return nil, errors.New("failed get revocation status from onchain cred status resolver") - } - - smProof, err := common.SmartContractProofToMtProofAdapter(common.SmartContractProof{ - Root: rs.Mtp.Root, - Existence: rs.Mtp.Existence, - Siblings: rs.Mtp.Siblings, - Index: rs.Mtp.Index, - Value: rs.Mtp.Value, - AuxExistence: rs.Mtp.AuxExistence, - AuxIndex: rs.Mtp.AuxIndex, - AuxValue: rs.Mtp.AuxValue, - }) - if err != nil { - log.Error(ctx, "failed convert smart contract proof to merkle tree proof", "error", err) - return nil, err - } - - state, err := merkletree.NewHashFromBigInt(rs.Issuer.State) - if err != nil { - log.Error(ctx, "failed convert state to merkle tree hash", "error", err) - return nil, err - } - stateHex := state.Hex() - ctr, err := merkletree.NewHashFromBigInt(rs.Issuer.ClaimsTreeRoot) - if err != nil { - return nil, err - } - ctrHex := ctr.Hex() - - rtr, err := merkletree.NewHashFromBigInt(rs.Issuer.RevocationTreeRoot) - if err != nil { - log.Error(ctx, "failed convert revocation tree root to merkle tree hash", "error", err) - return nil, err - } - rtrHex := rtr.Hex() - - ror, err := merkletree.NewHashFromBigInt(rs.Issuer.RootOfRoots) - if err != nil { - log.Error(ctx, "failed convert root of roots to merkle tree hash", "error", err) - return nil, err - } - rorHex := ror.Hex() - - return &verifiable.RevocationStatus{ - Issuer: verifiable.TreeState{ - State: &stateHex, - ClaimsTreeRoot: &ctrHex, - RevocationTreeRoot: &rtrHex, - RootOfRoots: &rorHex, - }, - MTP: *smProof, - }, nil -} - -type onchainRevStatus struct { - contractAddress ethCommon.Address - revNonce *uint64 - state *big.Int -} - -func newOnchainRevStatusFromURI(id string) (onchainRevStatus, error) { - var s onchainRevStatus - - uri, err := url.Parse(id) - if err != nil { - return s, errors.New("OnChainCredentialStatus ID is not a valid URI") - } - - contract := uri.Query().Get("contractAddress") - if contract == "" { - return s, errors.New("OnChainCredentialStatus contract address is empty") - } - - contractParts := strings.Split(contract, ":") - if len(contractParts) != contractPartsLength { - return s, errors.New( - "OnChainCredentialStatus contract address is not valid") - } - if !ethCommon.IsHexAddress(contractParts[1]) { - return s, errors.New( - "OnChainCredentialStatus incorrect contract address") - } - s.contractAddress = ethCommon.HexToAddress(contractParts[1]) - - revocationNonce := uri.Query().Get("revocationNonce") - // revnonce may be nil if params is absent in query - if revocationNonce != "" { - n, err := strconv.ParseUint(revocationNonce, 10, 64) - if err != nil { - return s, errors.New("revocationNonce is not a number in OnChainCredentialStatus ID") - } - s.revNonce = &n - } - // state may be nil if params is absent in query - stateParam := uri.Query().Get("state") - if stateParam == "" { - s.state = nil - } else { - stateHash, err := merkletree.NewHashFromHex(stateParam) - if err != nil { - return s, err - } - s.state = stateHash.BigInt() - } - - return s, nil -} diff --git a/pkg/protocol/packagemanager.go b/pkg/protocol/packagemanager.go index 35dc29846..f19f01c7a 100644 --- a/pkg/protocol/packagemanager.go +++ b/pkg/protocol/packagemanager.go @@ -1,23 +1,19 @@ package protocol import ( - "context" "fmt" - "math/big" "github.com/iden3/contracts-abi/state/go/abi" "github.com/iden3/go-circuits/v2" - "github.com/iden3/go-iden3-core/v2/w3c" "github.com/iden3/go-jwz/v2" "github.com/iden3/iden3comm/v2" "github.com/iden3/iden3comm/v2/packers" - "github.com/polygonid/sh-id-platform/internal/core/ports" "github.com/polygonid/sh-id-platform/pkg/loaders" ) // InitPackageManager initializes the iden3comm package manager -func InitPackageManager(ctx context.Context, stateContract *abi.State, zkProofService ports.ProofService, circuitsPath string) (*iden3comm.PackageManager, error) { +func InitPackageManager(stateContract *abi.State, circuitsPath string) (*iden3comm.PackageManager, error) { circuitsLoaderService := loaders.NewCircuits(circuitsPath) authV2Set, err := circuitsLoaderService.Load(circuits.AuthV2CircuitID) @@ -25,27 +21,11 @@ func InitPackageManager(ctx context.Context, stateContract *abi.State, zkProofSe return nil, fmt.Errorf("failed upload circuits files: %w", err) } - provers := make(map[jwz.ProvingMethodAlg]packers.ProvingParams) - pParams := packers.ProvingParams{ - DataPreparer: prepareAuthInputs(ctx, zkProofService), - ProvingKey: authV2Set.ProofKey, - Wasm: authV2Set.Wasm, - } - provers[jwz.AuthV2Groth16Alg] = pParams - verifications := make(map[jwz.ProvingMethodAlg]packers.VerificationParams) - verifications[jwz.AuthV2Groth16Alg] = packers.NewVerificationParams(authV2Set.VerificationKey, - stateVerificationHandler(stateContract)) - - zkpPackerV2 := packers.NewZKPPacker( - provers, - verifications, - ) - - // TODO: Why jwsPacker is not defined here? + verifications[jwz.AuthV2Groth16Alg] = packers.NewVerificationParams(authV2Set.VerificationKey, stateVerificationHandler(stateContract)) + zkpPackerV2 := packers.NewZKPPacker(nil, verifications) packageManager := iden3comm.NewPackageManager() - err = packageManager.RegisterPackers(zkpPackerV2, &packers.PlainMessagePacker{}) if err != nil { return nil, err @@ -53,16 +33,3 @@ func InitPackageManager(ctx context.Context, stateContract *abi.State, zkProofSe return packageManager, err } - -func prepareAuthInputs(ctx context.Context, proofService ports.ProofService) packers.DataPreparerHandlerFunc { - return func(hash []byte, id *w3c.DID, circuitID circuits.CircuitID) ([]byte, error) { - q := ports.Query{} - q.CircuitID = string(circuitID) - q.Challenge = new(big.Int).SetBytes(hash) - circuitInputs, _, err := proofService.PrepareInputs(ctx, id, q) - if err != nil { - return nil, err - } - return circuitInputs, nil - } -} From 1d3cdf738cabf8f252fbcfc1338463cc7e1bf728 Mon Sep 17 00:00:00 2001 From: Martin Saporiti Date: Wed, 29 May 2024 07:41:00 -0300 Subject: [PATCH 11/52] chore: update agent endpoint in api ui --- internal/api_ui/server.go | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) diff --git a/internal/api_ui/server.go b/internal/api_ui/server.go index 75a0a7c41..133a99360 100644 --- a/internal/api_ui/server.go +++ b/internal/api_ui/server.go @@ -14,8 +14,6 @@ import ( "github.com/iden3/go-iden3-core/v2/w3c" "github.com/iden3/go-schema-processor/v2/verifiable" "github.com/iden3/iden3comm/v2" - "github.com/iden3/iden3comm/v2/packers" - "github.com/polygonid/sh-id-platform/internal/common" "github.com/polygonid/sh-id-platform/internal/config" "github.com/polygonid/sh-id-platform/internal/core/domain" @@ -709,7 +707,7 @@ func (s *Server) Agent(ctx context.Context, request AgentRequestObject) (AgentRe log.Debug(ctx, "agent empty request") return Agent400JSONResponse{N400JSONResponse{"cannot proceed with an empty request"}}, nil } - basicMessage, err := s.packageManager.UnpackWithType(packers.MediaTypeZKPMessage, []byte(*request.Body)) + basicMessage, _, err := s.packageManager.Unpack([]byte(*request.Body)) if err != nil { log.Debug(ctx, "agent bad request", "err", err, "body", *request.Body) return Agent400JSONResponse{N400JSONResponse{"cannot proceed with the given request"}}, nil From e1f10def8c1579226d3fc75a35cd6cfa95c8104d Mon Sep 17 00:00:00 2001 From: Martin Saporiti Date: Wed, 29 May 2024 08:21:51 -0300 Subject: [PATCH 12/52] fix: linter --- internal/api_ui/server.go | 1 + 1 file changed, 1 insertion(+) diff --git a/internal/api_ui/server.go b/internal/api_ui/server.go index 133a99360..24e11c1d2 100644 --- a/internal/api_ui/server.go +++ b/internal/api_ui/server.go @@ -14,6 +14,7 @@ import ( "github.com/iden3/go-iden3-core/v2/w3c" "github.com/iden3/go-schema-processor/v2/verifiable" "github.com/iden3/iden3comm/v2" + "github.com/polygonid/sh-id-platform/internal/common" "github.com/polygonid/sh-id-platform/internal/config" "github.com/polygonid/sh-id-platform/internal/core/domain" From fdbebde4d311a506ee9a5b98d37d4383688bbce8 Mon Sep 17 00:00:00 2001 From: Martin Saporiti Date: Wed, 29 May 2024 09:49:17 -0300 Subject: [PATCH 13/52] chore: improve rev status resolves --- cmd/issuer_initializer/main.go | 2 +- internal/api/main_test.go | 2 +- internal/api/server_test.go | 16 ++++---- internal/api_ui/main_test.go | 2 +- internal/api_ui/server_test.go | 38 +++++++++---------- internal/config/config.go | 6 +-- internal/config/credential_status.go | 14 ++----- internal/core/services/tests/identity_test.go | 2 +- internal/core/services/tests/link_test.go | 2 +- internal/core/services/tests/main_test.go | 2 +- .../core/services/tests/notification_test.go | 2 +- ...everse_sparse_merkletree_proof_resolver.go | 4 +- .../iden3_revocation_status_v1.go | 2 +- .../revocation_status/resolver_test.go | 24 ++++++------ .../sparse_merkletree_proof_resolver.go | 4 +- pkg/credentials/revocation_status/utils.go | 9 +---- 16 files changed, 60 insertions(+), 71 deletions(-) diff --git a/cmd/issuer_initializer/main.go b/cmd/issuer_initializer/main.go index db4f367fb..02e4959d6 100644 --- a/cmd/issuer_initializer/main.go +++ b/cmd/issuer_initializer/main.go @@ -144,7 +144,7 @@ func main() { }, keyStore) // this is needed to create the did with the correct auth core claim revocation status URL - cfg.CredentialStatus.DirectStatus.URL = cfg.APIUI.ServerURL + cfg.CredentialStatus.Iden3CommAgentStatus.URL = cfg.APIUI.ServerURL rhsFactory := reverse_hash.NewFactory(cfg.CredentialStatus.RHS.GetURL(), ethConn, common.HexToAddress(cfg.CredentialStatus.OnchainTreeStore.SupportedTreeStoreContract), reverse_hash.DefaultRHSTimeOut) revocationStatusResolver := revocation_status.NewRevocationStatusResolver(cfg.CredentialStatus) cfg.CredentialStatus.SingleIssuer = true diff --git a/internal/api/main_test.go b/internal/api/main_test.go index 9f14a8d4b..7cbffd565 100644 --- a/internal/api/main_test.go +++ b/internal/api/main_test.go @@ -103,7 +103,7 @@ func TestMain(m *testing.M) { cfg.CredentialStatus = config.CredentialStatus{ RHSMode: "None", - DirectStatus: config.DirectStatus{ + Iden3CommAgentStatus: config.Iden3CommAgentStatus{ URL: "http://localhost:3001", }, } diff --git a/internal/api/server_test.go b/internal/api/server_test.go index d247e38de..55429ba61 100644 --- a/internal/api/server_test.go +++ b/internal/api/server_test.go @@ -54,7 +54,7 @@ func TestServer_CreateIdentity(t *testing.T) { revocationStatusResolver := revocation_status.NewRevocationStatusResolver(cfg.CredentialStatus) identityService := services.NewIdentity(keyStore, identityRepo, mtRepo, identityStateRepo, mtService, nil, claimsRepo, revocationRepository, connectionsRepository, storage, nil, nil, pubsub.NewMock(), cfg.CredentialStatus, rhsFactory, revocationStatusResolver) - claimsService := services.NewClaim(claimsRepo, identityService, nil, mtService, identityStateRepo, schemaLoader, storage, cfg.CredentialStatus.DirectStatus.GetURL(), pubsub.NewMock(), ipfsGatewayURL, revocationStatusResolver) + claimsService := services.NewClaim(claimsRepo, identityService, nil, mtService, identityStateRepo, schemaLoader, storage, cfg.CredentialStatus.Iden3CommAgentStatus.GetURL(), pubsub.NewMock(), ipfsGatewayURL, revocationStatusResolver) accountService := services.NewAccountService(cfg.Ethereum, keyStore) server := NewServer(&cfg, identityService, accountService, claimsService, nil, NewPublisherMock(), NewPackageManagerMock(), nil) handler := getHandler(context.Background(), server) @@ -251,7 +251,7 @@ func TestServer_RevokeClaim(t *testing.T) { rhsFactory := reverse_hash.NewFactory(cfg.CredentialStatus.RHS.GetURL(), nil, commonEth.HexToAddress(cfg.CredentialStatus.OnchainTreeStore.SupportedTreeStoreContract), reverse_hash.DefaultRHSTimeOut) identityService := services.NewIdentity(&KMSMock{}, identityRepo, mtRepo, identityStateRepo, mtService, nil, claimsRepo, revocationRepository, connectionsRepository, storage, nil, nil, pubsub.NewMock(), cfg.CredentialStatus, rhsFactory, revocationStatusResolver) - claimsService := services.NewClaim(claimsRepo, identityService, nil, mtService, identityStateRepo, schemaLoader, storage, cfg.CredentialStatus.DirectStatus.GetURL(), pubsub.NewMock(), ipfsGatewayURL, revocationStatusResolver) + claimsService := services.NewClaim(claimsRepo, identityService, nil, mtService, identityStateRepo, schemaLoader, storage, cfg.CredentialStatus.Iden3CommAgentStatus.GetURL(), pubsub.NewMock(), ipfsGatewayURL, revocationStatusResolver) accountService := services.NewAccountService(cfg.Ethereum, keyStore) server := NewServer(&cfg, identityService, accountService, claimsService, nil, NewPublisherMock(), NewPackageManagerMock(), nil) @@ -402,7 +402,7 @@ func TestServer_CreateClaim(t *testing.T) { revocationStatusResolver := revocation_status.NewRevocationStatusResolver(cfg.CredentialStatus) identityService := services.NewIdentity(keyStore, identityRepo, mtRepo, identityStateRepo, mtService, qrService, claimsRepo, revocationRepository, connectionsRepository, storage, nil, nil, pubsub.NewMock(), cfg.CredentialStatus, rhsFactory, revocationStatusResolver) pubSub := pubsub.NewMock() - claimsService := services.NewClaim(claimsRepo, identityService, nil, mtService, identityStateRepo, schemaLoader, storage, cfg.CredentialStatus.DirectStatus.GetURL(), pubSub, ipfsGatewayURL, revocationStatusResolver) + claimsService := services.NewClaim(claimsRepo, identityService, nil, mtService, identityStateRepo, schemaLoader, storage, cfg.CredentialStatus.Iden3CommAgentStatus.GetURL(), pubSub, ipfsGatewayURL, revocationStatusResolver) accountService := services.NewAccountService(cfg.Ethereum, keyStore) server := NewServer(&cfg, identityService, accountService, claimsService, nil, NewPublisherMock(), NewPackageManagerMock(), nil) handler := getHandler(ctx, server) @@ -580,7 +580,7 @@ func TestServer_GetIdentities(t *testing.T) { revocationStatusResolver := revocation_status.NewRevocationStatusResolver(cfg.CredentialStatus) identityService := services.NewIdentity(&KMSMock{}, identityRepo, mtRepo, identityStateRepo, mtService, nil, claimsRepo, revocationRepository, connectionsRepository, storage, nil, nil, pubsub.NewMock(), cfg.CredentialStatus, rhsFactory, revocationStatusResolver) - claimsService := services.NewClaim(claimsRepo, identityService, nil, mtService, identityStateRepo, schemaLoader, storage, cfg.CredentialStatus.DirectStatus.GetURL(), pubsub.NewMock(), ipfsGatewayURL, revocationStatusResolver) + claimsService := services.NewClaim(claimsRepo, identityService, nil, mtService, identityStateRepo, schemaLoader, storage, cfg.CredentialStatus.Iden3CommAgentStatus.GetURL(), pubsub.NewMock(), ipfsGatewayURL, revocationStatusResolver) accountService := services.NewAccountService(cfg.Ethereum, keyStore) server := NewServer(&cfg, identityService, accountService, claimsService, nil, NewPublisherMock(), NewPackageManagerMock(), nil) handler := getHandler(context.Background(), server) @@ -655,7 +655,7 @@ func TestServer_GetClaimQrCode(t *testing.T) { idStr := "did:polygonid:polygon:mumbai:2qPrv5Yx8s1qAmEnPym68LfT7gTbASGampiGU7TseL" idNoClaims := "did:polygonid:polygon:mumbai:2qGjTUuxZKqKS4Q8UmxHUPw55g15QgEVGnj6Wkq8Vk" accountService := services.NewAccountService(cfg.Ethereum, keyStore) - claimsService := services.NewClaim(claimsRepo, identityService, nil, mtService, identityStateRepo, schemaLoader, storage, cfg.CredentialStatus.DirectStatus.GetURL(), pubsub.NewMock(), ipfsGatewayURL, revocationStatusResolver) + claimsService := services.NewClaim(claimsRepo, identityService, nil, mtService, identityStateRepo, schemaLoader, storage, cfg.CredentialStatus.Iden3CommAgentStatus.GetURL(), pubsub.NewMock(), ipfsGatewayURL, revocationStatusResolver) identity := &domain.Identity{ Identifier: idStr, @@ -795,7 +795,7 @@ func TestServer_GetClaim(t *testing.T) { revocationStatusResolver := revocation_status.NewRevocationStatusResolver(cfg.CredentialStatus) rhsFactory := reverse_hash.NewFactory(cfg.CredentialStatus.RHS.GetURL(), nil, commonEth.HexToAddress(cfg.CredentialStatus.OnchainTreeStore.SupportedTreeStoreContract), reverse_hash.DefaultRHSTimeOut) identityService := services.NewIdentity(&KMSMock{}, identityRepo, mtRepo, identityStateRepo, mtService, nil, claimsRepo, revocationRepository, connectionsRepository, storage, nil, nil, pubsub.NewMock(), cfg.CredentialStatus, rhsFactory, revocationStatusResolver) - claimsService := services.NewClaim(claimsRepo, identityService, nil, mtService, identityStateRepo, schemaLoader, storage, cfg.CredentialStatus.DirectStatus.GetURL(), pubsub.NewMock(), ipfsGatewayURL, revocationStatusResolver) + claimsService := services.NewClaim(claimsRepo, identityService, nil, mtService, identityStateRepo, schemaLoader, storage, cfg.CredentialStatus.Iden3CommAgentStatus.GetURL(), pubsub.NewMock(), ipfsGatewayURL, revocationStatusResolver) accountService := services.NewAccountService(cfg.Ethereum, keyStore) server := NewServer(&cfg, identityService, accountService, claimsService, nil, NewPublisherMock(), NewPackageManagerMock(), nil) @@ -969,7 +969,7 @@ func TestServer_GetClaims(t *testing.T) { revocationStatusResolver := revocation_status.NewRevocationStatusResolver(cfg.CredentialStatus) rhsFactory := reverse_hash.NewFactory(cfg.CredentialStatus.RHS.GetURL(), nil, commonEth.HexToAddress(cfg.CredentialStatus.OnchainTreeStore.SupportedTreeStoreContract), reverse_hash.DefaultRHSTimeOut) identityService := services.NewIdentity(keyStore, identityRepo, mtRepo, identityStateRepo, mtService, nil, claimsRepo, revocationRepository, connectionsRepository, storage, nil, nil, pubsub.NewMock(), cfg.CredentialStatus, rhsFactory, revocationStatusResolver) - claimsService := services.NewClaim(claimsRepo, identityService, nil, mtService, identityStateRepo, schemaLoader, storage, cfg.CredentialStatus.DirectStatus.GetURL(), pubsub.NewMock(), ipfsGatewayURL, revocationStatusResolver) + claimsService := services.NewClaim(claimsRepo, identityService, nil, mtService, identityStateRepo, schemaLoader, storage, cfg.CredentialStatus.Iden3CommAgentStatus.GetURL(), pubsub.NewMock(), ipfsGatewayURL, revocationStatusResolver) fixture := tests.NewFixture(storage) @@ -1318,7 +1318,7 @@ func TestServer_GetRevocationStatus(t *testing.T) { identity, err := identityService.Create(ctx, "http://localhost:3001", &ports.DIDCreationOptions{Method: method, Blockchain: blockchain, Network: network, KeyType: BJJ}) assert.NoError(t, err) - claimsService := services.NewClaim(claimsRepo, identityService, nil, mtService, identityStateRepo, schemaLoader, storage, cfg.CredentialStatus.DirectStatus.GetURL(), pubsub.NewMock(), ipfsGatewayURL, revocationStatusResolver) + claimsService := services.NewClaim(claimsRepo, identityService, nil, mtService, identityStateRepo, schemaLoader, storage, cfg.CredentialStatus.Iden3CommAgentStatus.GetURL(), pubsub.NewMock(), ipfsGatewayURL, revocationStatusResolver) accountService := services.NewAccountService(cfg.Ethereum, keyStore) server := NewServer(&cfg, identityService, accountService, claimsService, nil, NewPublisherMock(), NewPackageManagerMock(), nil) handler := getHandler(context.Background(), server) diff --git a/internal/api_ui/main_test.go b/internal/api_ui/main_test.go index babe5b422..ade5ad299 100644 --- a/internal/api_ui/main_test.go +++ b/internal/api_ui/main_test.go @@ -88,7 +88,7 @@ func TestMain(m *testing.M) { cfg.ServerUrl = "https://testing.env/" cfg.CredentialStatus = config.CredentialStatus{ RHSMode: "None", - DirectStatus: config.DirectStatus{ + Iden3CommAgentStatus: config.Iden3CommAgentStatus{ URL: "http://localhost:3001", }, } diff --git a/internal/api_ui/server_test.go b/internal/api_ui/server_test.go index 8b25da1e6..368ddfa83 100644 --- a/internal/api_ui/server_test.go +++ b/internal/api_ui/server_test.go @@ -806,7 +806,7 @@ func TestServer_DeleteConnection(t *testing.T) { rhsFactory := reverse_hash.NewFactory(cfg.CredentialStatus.RHS.URL, nil, commonEth.HexToAddress(cfg.CredentialStatus.OnchainTreeStore.SupportedTreeStoreContract), reverse_hash.DefaultRHSTimeOut) identityService := services.NewIdentity(keyStore, identityRepo, mtRepo, identityStateRepo, mtService, nil, claimsRepo, revocationRepository, connectionsRepository, storage, nil, nil, pubsub.NewMock(), cfg.CredentialStatus, rhsFactory, revocationStatusResolver) - claimsService := services.NewClaim(claimsRepo, identityService, nil, mtService, identityStateRepo, schemaLoader, storage, cfg.CredentialStatus.DirectStatus.GetURL(), pubsub.NewMock(), ipfsGatewayURL, revocationStatusResolver) + claimsService := services.NewClaim(claimsRepo, identityService, nil, mtService, identityStateRepo, schemaLoader, storage, cfg.CredentialStatus.Iden3CommAgentStatus.GetURL(), pubsub.NewMock(), ipfsGatewayURL, revocationStatusResolver) connectionsService := services.NewConnection(connectionsRepository, claimsRepo, storage) iden, err := identityService.Create(ctx, "polygon-test", &ports.DIDCreationOptions{Method: method, Blockchain: blockchain, Network: network, KeyType: BJJ}) @@ -1168,7 +1168,7 @@ func TestServer_CreateCredential(t *testing.T) { rhsFactory := reverse_hash.NewFactory(cfg.CredentialStatus.RHS.URL, nil, commonEth.HexToAddress(cfg.CredentialStatus.OnchainTreeStore.SupportedTreeStoreContract), reverse_hash.DefaultRHSTimeOut) identityService := services.NewIdentity(keyStore, identityRepo, mtRepo, identityStateRepo, mtService, nil, claimsRepo, revocationRepository, connectionsRepository, storage, nil, nil, pubsub.NewMock(), cfg.CredentialStatus, rhsFactory, revocationStatusResolver) pubSub := pubsub.NewMock() - claimsService := services.NewClaim(claimsRepo, identityService, nil, mtService, identityStateRepo, schemaLoader, storage, cfg.CredentialStatus.DirectStatus.GetURL(), pubSub, ipfsGatewayURL, revocationStatusResolver) + claimsService := services.NewClaim(claimsRepo, identityService, nil, mtService, identityStateRepo, schemaLoader, storage, cfg.CredentialStatus.Iden3CommAgentStatus.GetURL(), pubSub, ipfsGatewayURL, revocationStatusResolver) connectionsService := services.NewConnection(connectionsRepository, claimsRepo, storage) iden, err := identityService.Create(ctx, "polygon-test", &ports.DIDCreationOptions{Method: method, Blockchain: blockchain, Network: network, KeyType: BJJ}) require.NoError(t, err) @@ -1447,7 +1447,7 @@ func TestServer_GetCredential(t *testing.T) { revocationStatusResolver := revocation_status.NewRevocationStatusResolver(cfg.CredentialStatus) rhsFactory := reverse_hash.NewFactory(cfg.CredentialStatus.RHS.URL, nil, commonEth.HexToAddress(cfg.CredentialStatus.OnchainTreeStore.SupportedTreeStoreContract), reverse_hash.DefaultRHSTimeOut) identityService := services.NewIdentity(keyStore, identityRepo, mtRepo, identityStateRepo, mtService, nil, claimsRepo, revocationRepository, connectionsRepository, storage, nil, nil, pubsub.NewMock(), cfg.CredentialStatus, rhsFactory, revocationStatusResolver) - claimsService := services.NewClaim(claimsRepo, identityService, nil, mtService, identityStateRepo, schemaLoader, storage, cfg.CredentialStatus.DirectStatus.GetURL(), pubsub.NewMock(), ipfsGatewayURL, revocationStatusResolver) + claimsService := services.NewClaim(claimsRepo, identityService, nil, mtService, identityStateRepo, schemaLoader, storage, cfg.CredentialStatus.Iden3CommAgentStatus.GetURL(), pubsub.NewMock(), ipfsGatewayURL, revocationStatusResolver) connectionsService := services.NewConnection(connectionsRepository, claimsRepo, storage) iden, err := identityService.Create(ctx, "polygon-test", &ports.DIDCreationOptions{Method: method, Blockchain: blockchain, Network: network, KeyType: BJJ}) require.NoError(t, err) @@ -1640,7 +1640,7 @@ func TestServer_GetCredentials(t *testing.T) { rhsFactory := reverse_hash.NewFactory(cfg.CredentialStatus.RHS.URL, nil, commonEth.HexToAddress(cfg.CredentialStatus.OnchainTreeStore.SupportedTreeStoreContract), reverse_hash.DefaultRHSTimeOut) identityService := services.NewIdentity(keyStore, identityRepo, mtRepo, identityStateRepo, mtService, nil, claimsRepo, revocationRepository, connectionsRepository, storage, nil, nil, pubsub.NewMock(), cfg.CredentialStatus, rhsFactory, revocationStatusResolver) - claimsService := services.NewClaim(claimsRepo, identityService, nil, mtService, identityStateRepo, schemaLoader, storage, cfg.CredentialStatus.DirectStatus.GetURL(), pubsub.NewMock(), ipfsGatewayURL, revocationStatusResolver) + claimsService := services.NewClaim(claimsRepo, identityService, nil, mtService, identityStateRepo, schemaLoader, storage, cfg.CredentialStatus.Iden3CommAgentStatus.GetURL(), pubsub.NewMock(), ipfsGatewayURL, revocationStatusResolver) schemaService := services.NewSchema(schemaRepository, schemaLoader) connectionsService := services.NewConnection(connectionsRepository, claimsRepo, storage) iden, err := identityService.Create(ctx, "polygon-test", &ports.DIDCreationOptions{Method: method, Blockchain: blockchain, Network: network, KeyType: BJJ}) @@ -2108,7 +2108,7 @@ func TestServer_GetCredentialQrCode(t *testing.T) { revocationStatusResolver := revocation_status.NewRevocationStatusResolver(cfg.CredentialStatus) rhsFactory := reverse_hash.NewFactory(cfg.CredentialStatus.RHS.URL, nil, commonEth.HexToAddress(cfg.CredentialStatus.OnchainTreeStore.SupportedTreeStoreContract), reverse_hash.DefaultRHSTimeOut) identityService := services.NewIdentity(keyStore, identityRepo, mtRepo, identityStateRepo, mtService, qrService, claimsRepo, revocationRepository, connectionsRepository, storage, nil, nil, pubsub.NewMock(), cfg.CredentialStatus, rhsFactory, revocationStatusResolver) - claimsService := services.NewClaim(claimsRepo, identityService, qrService, mtService, identityStateRepo, schemaLoader, storage, cfg.CredentialStatus.DirectStatus.GetURL(), pubsub.NewMock(), ipfsGatewayURL, revocationStatusResolver) + claimsService := services.NewClaim(claimsRepo, identityService, qrService, mtService, identityStateRepo, schemaLoader, storage, cfg.CredentialStatus.Iden3CommAgentStatus.GetURL(), pubsub.NewMock(), ipfsGatewayURL, revocationStatusResolver) connectionsService := services.NewConnection(connectionsRepository, claimsRepo, storage) iden, err := identityService.Create(ctx, "polygon-test", &ports.DIDCreationOptions{Method: method, Blockchain: blockchain, Network: network, KeyType: BJJ}) require.NoError(t, err) @@ -2262,7 +2262,7 @@ func TestServer_GetConnection(t *testing.T) { rhsFactory := reverse_hash.NewFactory(cfg.CredentialStatus.RHS.URL, nil, commonEth.HexToAddress(cfg.CredentialStatus.OnchainTreeStore.SupportedTreeStoreContract), reverse_hash.DefaultRHSTimeOut) revocationStatusResolver := revocation_status.NewRevocationStatusResolver(cfg.CredentialStatus) identityService := services.NewIdentity(keyStore, identityRepo, mtRepo, identityStateRepo, mtService, nil, claimsRepo, revocationRepository, connectionsRepository, storage, nil, nil, pubsub.NewMock(), cfg.CredentialStatus, rhsFactory, revocationStatusResolver) - claimsService := services.NewClaim(claimsRepo, identityService, nil, mtService, identityStateRepo, schemaLoader, storage, cfg.CredentialStatus.DirectStatus.GetURL(), pubsub.NewMock(), ipfsGatewayURL, revocationStatusResolver) + claimsService := services.NewClaim(claimsRepo, identityService, nil, mtService, identityStateRepo, schemaLoader, storage, cfg.CredentialStatus.Iden3CommAgentStatus.GetURL(), pubsub.NewMock(), ipfsGatewayURL, revocationStatusResolver) connectionsService := services.NewConnection(connectionsRepository, claimsRepo, storage) iden, err := identityService.Create(ctx, "polygon-test", &ports.DIDCreationOptions{Method: method, Blockchain: blockchain, Network: network, KeyType: BJJ}) @@ -2447,7 +2447,7 @@ func TestServer_GetConnections(t *testing.T) { revocationStatusResolver := revocation_status.NewRevocationStatusResolver(cfg.CredentialStatus) rhsFactory := reverse_hash.NewFactory(cfg.CredentialStatus.RHS.URL, nil, commonEth.HexToAddress(cfg.CredentialStatus.OnchainTreeStore.SupportedTreeStoreContract), reverse_hash.DefaultRHSTimeOut) identityService := services.NewIdentity(keyStore, identityRepo, mtRepo, identityStateRepo, mtService, nil, claimsRepo, revocationRepository, connectionsRepository, storage, nil, nil, pubsub.NewMock(), cfg.CredentialStatus, rhsFactory, revocationStatusResolver) - claimsService := services.NewClaim(claimsRepo, identityService, nil, mtService, identityStateRepo, schemaLoader, storage, cfg.CredentialStatus.DirectStatus.GetURL(), pubsub.NewMock(), ipfsGatewayURL, revocationStatusResolver) + claimsService := services.NewClaim(claimsRepo, identityService, nil, mtService, identityStateRepo, schemaLoader, storage, cfg.CredentialStatus.Iden3CommAgentStatus.GetURL(), pubsub.NewMock(), ipfsGatewayURL, revocationStatusResolver) connectionsService := services.NewConnection(connectionsRepository, claimsRepo, storage) iden, err := identityService.Create(ctx, "polygon-test", &ports.DIDCreationOptions{Method: method, Blockchain: blockchain, Network: network, KeyType: BJJ}) @@ -3125,7 +3125,7 @@ func TestServer_RevokeCredential(t *testing.T) { revocationStatusResolver := revocation_status.NewRevocationStatusResolver(cfg.CredentialStatus) rhsFactory := reverse_hash.NewFactory(cfg.CredentialStatus.RHS.URL, nil, commonEth.HexToAddress(cfg.CredentialStatus.OnchainTreeStore.SupportedTreeStoreContract), reverse_hash.DefaultRHSTimeOut) identityService := services.NewIdentity(&KMSMock{}, identityRepo, mtRepo, identityStateRepo, mtService, nil, claimsRepo, revocationRepository, connectionsRepository, storage, nil, nil, pubsub.NewMock(), cfg.CredentialStatus, rhsFactory, revocationStatusResolver) - claimsService := services.NewClaim(claimsRepo, identityService, nil, mtService, identityStateRepo, schemaLoader, storage, cfg.CredentialStatus.DirectStatus.GetURL(), pubsub.NewMock(), ipfsGatewayURL, revocationStatusResolver) + claimsService := services.NewClaim(claimsRepo, identityService, nil, mtService, identityStateRepo, schemaLoader, storage, cfg.CredentialStatus.Iden3CommAgentStatus.GetURL(), pubsub.NewMock(), ipfsGatewayURL, revocationStatusResolver) fixture := tests.NewFixture(storage) connectionsService := services.NewConnection(connectionsRepository, claimsRepo, storage) @@ -3266,7 +3266,7 @@ func TestServer_CreateLink(t *testing.T) { rhsFactory := reverse_hash.NewFactory(cfg.CredentialStatus.RHS.URL, nil, commonEth.HexToAddress(cfg.CredentialStatus.OnchainTreeStore.SupportedTreeStoreContract), reverse_hash.DefaultRHSTimeOut) identityService := services.NewIdentity(keyStore, identityRepo, mtRepo, identityStateRepo, mtService, nil, claimsRepo, revocationRepository, connectionsRepository, storage, nil, nil, pubsub.NewMock(), cfg.CredentialStatus, rhsFactory, revocationStatusResolver) pubSub := pubsub.NewMock() - claimsService := services.NewClaim(claimsRepo, identityService, nil, mtService, identityStateRepo, schemaLoader, storage, cfg.CredentialStatus.DirectStatus.GetURL(), pubSub, ipfsGatewayURL, revocationStatusResolver) + claimsService := services.NewClaim(claimsRepo, identityService, nil, mtService, identityStateRepo, schemaLoader, storage, cfg.CredentialStatus.Iden3CommAgentStatus.GetURL(), pubSub, ipfsGatewayURL, revocationStatusResolver) connectionsService := services.NewConnection(connectionsRepository, claimsRepo, storage) linkService := services.NewLinkService(storage, claimsService, nil, claimsRepo, linkRepository, schemaRespository, schemaLoader, sessionRepository, pubSub, ipfsGatewayURL) iden, err := identityService.Create(ctx, "polygon-test", &ports.DIDCreationOptions{Method: method, Blockchain: blockchain, Network: network, KeyType: BJJ}) @@ -3491,7 +3491,7 @@ func TestServer_ActivateLink(t *testing.T) { revocationStatusResolver := revocation_status.NewRevocationStatusResolver(cfg.CredentialStatus) rhsFactory := reverse_hash.NewFactory(cfg.CredentialStatus.RHS.URL, nil, commonEth.HexToAddress(cfg.CredentialStatus.OnchainTreeStore.SupportedTreeStoreContract), reverse_hash.DefaultRHSTimeOut) identityService := services.NewIdentity(keyStore, identityRepo, mtRepo, identityStateRepo, mtService, nil, claimsRepo, revocationRepository, connectionsRepository, storage, nil, nil, pubsub.NewMock(), cfg.CredentialStatus, rhsFactory, revocationStatusResolver) - claimsService := services.NewClaim(claimsRepo, identityService, nil, mtService, identityStateRepo, schemaLoader, storage, cfg.CredentialStatus.DirectStatus.GetURL(), pubsub.NewMock(), ipfsGatewayURL, revocationStatusResolver) + claimsService := services.NewClaim(claimsRepo, identityService, nil, mtService, identityStateRepo, schemaLoader, storage, cfg.CredentialStatus.Iden3CommAgentStatus.GetURL(), pubsub.NewMock(), ipfsGatewayURL, revocationStatusResolver) connectionsService := services.NewConnection(connectionsRepository, claimsRepo, storage) linkService := services.NewLinkService(storage, claimsService, nil, claimsRepo, linkRepository, schemaRepository, schemaLoader, sessionRepository, pubsub.NewMock(), ipfsGatewayURL) iden, err := identityService.Create(ctx, "polygon-test", &ports.DIDCreationOptions{Method: method, Blockchain: blockchain, Network: network, KeyType: BJJ}) @@ -3640,7 +3640,7 @@ func TestServer_GetLink(t *testing.T) { revocationStatusResolver := revocation_status.NewRevocationStatusResolver(cfg.CredentialStatus) rhsFactory := reverse_hash.NewFactory(cfg.CredentialStatus.RHS.URL, nil, commonEth.HexToAddress(cfg.CredentialStatus.OnchainTreeStore.SupportedTreeStoreContract), reverse_hash.DefaultRHSTimeOut) identityService := services.NewIdentity(keyStore, identityRepo, mtRepo, identityStateRepo, mtService, nil, claimsRepo, revocationRepository, connectionsRepository, storage, nil, nil, pubsub.NewMock(), cfg.CredentialStatus, rhsFactory, revocationStatusResolver) - claimsService := services.NewClaim(claimsRepo, identityService, nil, mtService, identityStateRepo, schemaLoader, storage, cfg.CredentialStatus.DirectStatus.GetURL(), pubsub.NewMock(), ipfsGatewayURL, revocationStatusResolver) + claimsService := services.NewClaim(claimsRepo, identityService, nil, mtService, identityStateRepo, schemaLoader, storage, cfg.CredentialStatus.Iden3CommAgentStatus.GetURL(), pubsub.NewMock(), ipfsGatewayURL, revocationStatusResolver) connectionsService := services.NewConnection(connectionsRepository, claimsRepo, storage) linkService := services.NewLinkService(storage, claimsService, nil, claimsRepo, linkRepository, schemaRepository, schemaLoader, sessionRepository, pubsub.NewMock(), ipfsGatewayURL) iden, err := identityService.Create(ctx, "polygon-test", &ports.DIDCreationOptions{Method: method, Blockchain: blockchain, Network: network, KeyType: BJJ}) @@ -3816,7 +3816,7 @@ func TestServer_GetAllLinks(t *testing.T) { revocationStatusResolver := revocation_status.NewRevocationStatusResolver(cfg.CredentialStatus) rhsFactory := reverse_hash.NewFactory(cfg.CredentialStatus.RHS.URL, nil, commonEth.HexToAddress(cfg.CredentialStatus.OnchainTreeStore.SupportedTreeStoreContract), reverse_hash.DefaultRHSTimeOut) identityService := services.NewIdentity(keyStore, identityRepo, mtRepo, identityStateRepo, mtService, nil, claimsRepo, revocationRepository, connectionsRepository, storage, nil, nil, pubsub.NewMock(), cfg.CredentialStatus, rhsFactory, revocationStatusResolver) - claimsService := services.NewClaim(claimsRepo, identityService, nil, mtService, identityStateRepo, schemaLoader, storage, cfg.CredentialStatus.DirectStatus.GetURL(), pubsub.NewMock(), ipfsGatewayURL, revocationStatusResolver) + claimsService := services.NewClaim(claimsRepo, identityService, nil, mtService, identityStateRepo, schemaLoader, storage, cfg.CredentialStatus.Iden3CommAgentStatus.GetURL(), pubsub.NewMock(), ipfsGatewayURL, revocationStatusResolver) connectionsService := services.NewConnection(connectionsRepository, claimsRepo, storage) linkService := services.NewLinkService(storage, claimsService, nil, claimsRepo, linkRepository, schemaRepository, schemaLoader, sessionRepository, pubsub.NewMock(), ipfsGatewayURL) iden, err := identityService.Create(ctx, "polygon-test", &ports.DIDCreationOptions{Method: method, Blockchain: blockchain, Network: network, KeyType: BJJ}) @@ -4050,7 +4050,7 @@ func TestServer_DeleteLink(t *testing.T) { revocationStatusResolver := revocation_status.NewRevocationStatusResolver(cfg.CredentialStatus) rhsFactory := reverse_hash.NewFactory(cfg.CredentialStatus.RHS.URL, nil, commonEth.HexToAddress(cfg.CredentialStatus.OnchainTreeStore.SupportedTreeStoreContract), reverse_hash.DefaultRHSTimeOut) identityService := services.NewIdentity(keyStore, identityRepo, mtRepo, identityStateRepo, mtService, nil, claimsRepo, revocationRepository, connectionsRepository, storage, nil, nil, pubsub.NewMock(), cfg.CredentialStatus, rhsFactory, revocationStatusResolver) - claimsService := services.NewClaim(claimsRepo, identityService, nil, mtService, identityStateRepo, schemaLoader, storage, cfg.CredentialStatus.DirectStatus.GetURL(), pubsub.NewMock(), ipfsGatewayURL, revocationStatusResolver) + claimsService := services.NewClaim(claimsRepo, identityService, nil, mtService, identityStateRepo, schemaLoader, storage, cfg.CredentialStatus.Iden3CommAgentStatus.GetURL(), pubsub.NewMock(), ipfsGatewayURL, revocationStatusResolver) connectionsService := services.NewConnection(connectionsRepository, claimsRepo, storage) linkService := services.NewLinkService(storage, claimsService, nil, claimsRepo, linkRepository, schemaRepository, schemaLoader, sessionRepository, pubsub.NewMock(), ipfsGatewayURL) iden, err := identityService.Create(ctx, "polygon-test", &ports.DIDCreationOptions{Method: method, Blockchain: blockchain, Network: network, KeyType: BJJ}) @@ -4165,7 +4165,7 @@ func TestServer_DeleteLinkForDifferentDID(t *testing.T) { revocationStatusResolver := revocation_status.NewRevocationStatusResolver(cfg.CredentialStatus) rhsFactory := reverse_hash.NewFactory(cfg.CredentialStatus.RHS.URL, nil, commonEth.HexToAddress(cfg.CredentialStatus.OnchainTreeStore.SupportedTreeStoreContract), reverse_hash.DefaultRHSTimeOut) identityService := services.NewIdentity(keyStore, identityRepo, mtRepo, identityStateRepo, mtService, nil, claimsRepo, revocationRepository, connectionsRepository, storage, nil, nil, pubsub.NewMock(), cfg.CredentialStatus, rhsFactory, revocationStatusResolver) - claimsService := services.NewClaim(claimsRepo, identityService, nil, mtService, identityStateRepo, schemaLoader, storage, cfg.CredentialStatus.DirectStatus.GetURL(), pubsub.NewMock(), ipfsGatewayURL, revocationStatusResolver) + claimsService := services.NewClaim(claimsRepo, identityService, nil, mtService, identityStateRepo, schemaLoader, storage, cfg.CredentialStatus.Iden3CommAgentStatus.GetURL(), pubsub.NewMock(), ipfsGatewayURL, revocationStatusResolver) connectionsService := services.NewConnection(connectionsRepository, claimsRepo, storage) linkService := services.NewLinkService(storage, claimsService, nil, claimsRepo, linkRepository, schemaRepository, schemaLoader, sessionRepository, pubsub.NewMock(), ipfsGatewayURL) iden, err := identityService.Create(ctx, "polygon-test", &ports.DIDCreationOptions{Method: method, Blockchain: blockchain, Network: network, KeyType: BJJ}) @@ -4278,7 +4278,7 @@ func TestServer_CreateLinkQRCode(t *testing.T) { revocationStatusResolver := revocation_status.NewRevocationStatusResolver(cfg.CredentialStatus) rhsFactory := reverse_hash.NewFactory(cfg.CredentialStatus.RHS.URL, nil, commonEth.HexToAddress(cfg.CredentialStatus.OnchainTreeStore.SupportedTreeStoreContract), reverse_hash.DefaultRHSTimeOut) identityService := services.NewIdentity(keyStore, identityRepo, mtRepo, identityStateRepo, mtService, qrService, claimsRepo, revocationRepository, connectionsRepository, storage, nil, nil, pubsub.NewMock(), cfg.CredentialStatus, rhsFactory, revocationStatusResolver) - claimsService := services.NewClaim(claimsRepo, identityService, nil, mtService, identityStateRepo, schemaLoader, storage, cfg.CredentialStatus.DirectStatus.GetURL(), pubsub.NewMock(), ipfsGatewayURL, revocationStatusResolver) + claimsService := services.NewClaim(claimsRepo, identityService, nil, mtService, identityStateRepo, schemaLoader, storage, cfg.CredentialStatus.Iden3CommAgentStatus.GetURL(), pubsub.NewMock(), ipfsGatewayURL, revocationStatusResolver) connectionsService := services.NewConnection(connectionsRepository, claimsRepo, storage) linkService := services.NewLinkService(storage, claimsService, qrService, claimsRepo, linkRepository, schemaRepository, schemaLoader, sessionRepository, pubsub.NewMock(), ipfsGatewayURL) iden, err := identityService.Create(ctx, "polygon-test", &ports.DIDCreationOptions{Method: method, Blockchain: blockchain, Network: network, KeyType: BJJ}) @@ -4431,7 +4431,7 @@ func TestServer_GetLinkQRCode(t *testing.T) { rhsFactory := reverse_hash.NewFactory(cfg.CredentialStatus.RHS.URL, nil, commonEth.HexToAddress(cfg.CredentialStatus.OnchainTreeStore.SupportedTreeStoreContract), reverse_hash.DefaultRHSTimeOut) qrService := services.NewQrStoreService(cachex) identityService := services.NewIdentity(keyStore, identityRepo, mtRepo, identityStateRepo, mtService, qrService, claimsRepo, revocationRepository, connectionsRepository, storage, nil, nil, pubsub.NewMock(), cfg.CredentialStatus, rhsFactory, revocationStatusResolver) - claimsService := services.NewClaim(claimsRepo, identityService, qrService, mtService, identityStateRepo, schemaLoader, storage, cfg.CredentialStatus.DirectStatus.GetURL(), pubsub.NewMock(), ipfsGatewayURL, revocationStatusResolver) + claimsService := services.NewClaim(claimsRepo, identityService, qrService, mtService, identityStateRepo, schemaLoader, storage, cfg.CredentialStatus.Iden3CommAgentStatus.GetURL(), pubsub.NewMock(), ipfsGatewayURL, revocationStatusResolver) connectionsService := services.NewConnection(connectionsRepository, claimsRepo, storage) linkService := services.NewLinkService(storage, claimsService, qrService, claimsRepo, linkRepository, schemaRepository, schemaLoader, sessionRepository, pubsub.NewMock(), ipfsGatewayURL) iden, err := identityService.Create(ctx, "polygon-test", &ports.DIDCreationOptions{Method: method, Blockchain: blockchain, Network: network, KeyType: BJJ}) @@ -4612,7 +4612,7 @@ func TestServer_GetStateStatus(t *testing.T) { revocationStatusResolver := revocation_status.NewRevocationStatusResolver(cfg.CredentialStatus) rhsFactory := reverse_hash.NewFactory(cfg.CredentialStatus.RHS.URL, nil, commonEth.HexToAddress(cfg.CredentialStatus.OnchainTreeStore.SupportedTreeStoreContract), reverse_hash.DefaultRHSTimeOut) identityService := services.NewIdentity(keyStore, identityRepo, mtRepo, identityStateRepo, mtService, nil, claimsRepo, revocationRepository, connectionsRepository, storage, nil, nil, pubsub.NewMock(), cfg.CredentialStatus, rhsFactory, revocationStatusResolver) - claimsService := services.NewClaim(claimsRepo, identityService, nil, mtService, identityStateRepo, schemaLoader, storage, cfg.CredentialStatus.DirectStatus.GetURL(), pubsub.NewMock(), ipfsGatewayURL, revocationStatusResolver) + claimsService := services.NewClaim(claimsRepo, identityService, nil, mtService, identityStateRepo, schemaLoader, storage, cfg.CredentialStatus.Iden3CommAgentStatus.GetURL(), pubsub.NewMock(), ipfsGatewayURL, revocationStatusResolver) connectionsService := services.NewConnection(connectionsRepository, claimsRepo, storage) schema := "https://raw.githubusercontent.com/iden3/claim-schema-vocab/main/schemas/json/KYCAgeCredential-v3.json" credentialSubject := map[string]any{ @@ -4761,7 +4761,7 @@ func TestServer_GetStateTransactions(t *testing.T) { revocationStatusResolver := revocation_status.NewRevocationStatusResolver(cfg.CredentialStatus) rhsFactory := reverse_hash.NewFactory(cfg.CredentialStatus.RHS.URL, nil, commonEth.HexToAddress(cfg.CredentialStatus.OnchainTreeStore.SupportedTreeStoreContract), reverse_hash.DefaultRHSTimeOut) identityService := services.NewIdentity(keyStore, identityRepo, mtRepo, identityStateRepo, mtService, nil, claimsRepo, revocationRepository, connectionsRepository, storage, nil, nil, pubsub.NewMock(), cfg.CredentialStatus, rhsFactory, revocationStatusResolver) - claimsService := services.NewClaim(claimsRepo, identityService, nil, mtService, identityStateRepo, schemaLoader, storage, cfg.CredentialStatus.DirectStatus.GetURL(), pubsub.NewMock(), ipfsGatewayURL, revocationStatusResolver) + claimsService := services.NewClaim(claimsRepo, identityService, nil, mtService, identityStateRepo, schemaLoader, storage, cfg.CredentialStatus.Iden3CommAgentStatus.GetURL(), pubsub.NewMock(), ipfsGatewayURL, revocationStatusResolver) connectionsService := services.NewConnection(connectionsRepository, claimsRepo, storage) iden, err := identityService.Create(ctx, "polygon-test", &ports.DIDCreationOptions{Method: method, Blockchain: blockchain, Network: network, KeyType: BJJ}) require.NoError(t, err) @@ -4848,7 +4848,7 @@ func TestServer_GetRevocationStatus(t *testing.T) { rhsFactory := reverse_hash.NewFactory(cfg.CredentialStatus.RHS.URL, nil, commonEth.HexToAddress(cfg.CredentialStatus.OnchainTreeStore.SupportedTreeStoreContract), reverse_hash.DefaultRHSTimeOut) identityService := services.NewIdentity(keyStore, identityRepo, mtRepo, identityStateRepo, mtService, nil, claimsRepo, revocationRepository, connectionsRepository, storage, nil, nil, pubsub.NewMock(), cfg.CredentialStatus, rhsFactory, revocationStatusResolver) pubSub := pubsub.NewMock() - claimsService := services.NewClaim(claimsRepo, identityService, nil, mtService, identityStateRepo, schemaLoader, storage, cfg.CredentialStatus.DirectStatus.GetURL(), pubSub, ipfsGatewayURL, revocationStatusResolver) + claimsService := services.NewClaim(claimsRepo, identityService, nil, mtService, identityStateRepo, schemaLoader, storage, cfg.CredentialStatus.Iden3CommAgentStatus.GetURL(), pubSub, ipfsGatewayURL, revocationStatusResolver) connectionsService := services.NewConnection(connectionsRepository, claimsRepo, storage) iden, err := identityService.Create(ctx, "polygon-test", &ports.DIDCreationOptions{Method: method, Blockchain: blockchain, Network: network, KeyType: BJJ}) require.NoError(t, err) diff --git a/internal/config/config.go b/internal/config/config.go index ebd94d436..1a19aca0d 100644 --- a/internal/config/config.go +++ b/internal/config/config.go @@ -264,7 +264,7 @@ func (c *Configuration) sanitizeCredentialStatus(_ context.Context, host string) } if c.CredentialStatus.RHSMode == none { - c.CredentialStatus.DirectStatus.URL = host + c.CredentialStatus.Iden3CommAgentStatus.URL = host c.CredentialStatus.CredentialStatusType = iden3commRevocationStatusV1 } @@ -273,7 +273,7 @@ func (c *Configuration) sanitizeCredentialStatus(_ context.Context, host string) return fmt.Errorf("ISSUER_CREDENTIAL_STATUS_RHS_URL value is missing") } c.CredentialStatus.CredentialStatusType = iden3ReverseSparseMerkleTreeProof - c.CredentialStatus.DirectStatus.URL = host + c.CredentialStatus.Iden3CommAgentStatus.URL = host } if c.CredentialStatus.RHSMode == onChain { @@ -473,7 +473,7 @@ func bindEnv() { _ = viper.BindEnv("Ethereum.InternalTransferAmountWei", "ISSUER_INTERNAL_TRANSFER_AMOUNT_WEI") _ = viper.BindEnv("Ethereum.TransferAccountKeyPath", "ISSUER_ETHEREUM_TRANSFER_ACCOUNT_KEY_PATH") - _ = viper.BindEnv("CredentialStatus.DirectStatus.URL", "ISSUER_CREDENTIAL_STATUS_DIRECT_URL") + _ = viper.BindEnv("CredentialStatus.Iden3CommAgentStatus.URL", "ISSUER_CREDENTIAL_STATUS_DIRECT_URL") _ = viper.BindEnv("CredentialStatus.RHS.URL", "ISSUER_CREDENTIAL_STATUS_RHS_URL") _ = viper.BindEnv("CredentialStatus.OnchainTreeStore.SupportedTreeStoreContract", "ISSUER_CREDENTIAL_STATUS_ONCHAIN_TREE_STORE_SUPPORTED_CONTRACT") _ = viper.BindEnv("CredentialStatus.OnchainTreeStore.PublishingKeyPath", "ISSUER_CREDENTIAL_STATUS_PUBLISHING_KEY_PATH") diff --git a/internal/config/credential_status.go b/internal/config/credential_status.go index 15e7c2c6d..8d6e87114 100644 --- a/internal/config/credential_status.go +++ b/internal/config/credential_status.go @@ -1,7 +1,6 @@ package config import ( - "fmt" "strings" ) @@ -20,7 +19,7 @@ type RHSMode string // CredentialStatus is the type of credential status type CredentialStatus struct { - DirectStatus DirectStatus + Iden3CommAgentStatus Iden3CommAgentStatus RHS RHS OnchainTreeStore OnchainTreeStore `mapstructure:"OnchainTreeStore"` RHSMode RHSMode `tip:"Reverse hash service mode (OffChain, OnChain, Mixed, None)"` @@ -28,21 +27,16 @@ type CredentialStatus struct { CredentialStatusType string `mapstructure:"CredentialStatusType" default:"Iden3commRevocationStatusV1"` } -// DirectStatus is the type of direct status -type DirectStatus struct { +// Iden3CommAgentStatus is the type of direct status +type Iden3CommAgentStatus struct { URL string `mapstructure:"URL"` } // GetURL returns the URL of the direct status -func (r *DirectStatus) GetURL() string { +func (r *Iden3CommAgentStatus) GetURL() string { return strings.TrimSuffix(r.URL, "/") } -// GetAgentURL returns the URL of the agent endpoint -func (r *DirectStatus) GetAgentURL() string { - return fmt.Sprintf("%s/v1/agent", strings.TrimSuffix(r.URL, "/")) -} - // RHS is the type of RHS type RHS struct { URL string `mapstructure:"URL"` diff --git a/internal/core/services/tests/identity_test.go b/internal/core/services/tests/identity_test.go index c527bf507..43b0c1e55 100644 --- a/internal/core/services/tests/identity_test.go +++ b/internal/core/services/tests/identity_test.go @@ -41,7 +41,7 @@ func Test_identity_UpdateState(t *testing.T) { rhsFactory := reverse_hash.NewFactory(cfg.CredentialStatus.RHS.URL, nil, commonEth.HexToAddress(cfg.CredentialStatus.OnchainTreeStore.SupportedTreeStoreContract), reverse_hash.DefaultRHSTimeOut) revocationStatusResolver := revocation_status.NewRevocationStatusResolver(cfg.CredentialStatus) identityService := services.NewIdentity(keyStore, identityRepo, mtRepo, identityStateRepo, mtService, nil, claimsRepo, revocationRepository, connectionsRepository, storage, nil, nil, pubsub.NewMock(), cfg.CredentialStatus, rhsFactory, revocationStatusResolver) - claimsService := services.NewClaim(claimsRepo, identityService, nil, mtService, identityStateRepo, docLoader, storage, cfg.CredentialStatus.DirectStatus.GetURL(), pubsub.NewMock(), ipfsGateway, revocationStatusResolver) + claimsService := services.NewClaim(claimsRepo, identityService, nil, mtService, identityStateRepo, docLoader, storage, cfg.CredentialStatus.Iden3CommAgentStatus.GetURL(), pubsub.NewMock(), ipfsGateway, revocationStatusResolver) identity, err := identityService.Create(ctx, "polygon-test", &ports.DIDCreationOptions{Method: method, Blockchain: blockchain, Network: network, KeyType: BJJ}) require.NoError(t, err) diff --git a/internal/core/services/tests/link_test.go b/internal/core/services/tests/link_test.go index f33c179a8..96aaf076c 100644 --- a/internal/core/services/tests/link_test.go +++ b/internal/core/services/tests/link_test.go @@ -39,7 +39,7 @@ func Test_link_issueClaim(t *testing.T) { identityService := services.NewIdentity(keyStore, identityRepo, mtRepo, identityStateRepo, mtService, nil, claimsRepo, revocationRepository, connectionsRepository, storage, nil, nil, pubsub.NewMock(), cfg.CredentialStatus, rhsFactory, revocationStatusResolver) sessionRepository := repositories.NewSessionCached(cachex) schemaService := services.NewSchema(schemaRepository, docLoader) - claimsService := services.NewClaim(claimsRepo, identityService, nil, mtService, identityStateRepo, docLoader, storage, cfg.CredentialStatus.DirectStatus.GetURL(), pubsub.NewMock(), ipfsGateway, revocationStatusResolver) + claimsService := services.NewClaim(claimsRepo, identityService, nil, mtService, identityStateRepo, docLoader, storage, cfg.CredentialStatus.Iden3CommAgentStatus.GetURL(), pubsub.NewMock(), ipfsGateway, revocationStatusResolver) identity, err := identityService.Create(ctx, "polygon-test", &ports.DIDCreationOptions{Method: method, Blockchain: blockchain, Network: network, KeyType: BJJ}) assert.NoError(t, err) diff --git a/internal/core/services/tests/main_test.go b/internal/core/services/tests/main_test.go index 667214014..a0bac0440 100644 --- a/internal/core/services/tests/main_test.go +++ b/internal/core/services/tests/main_test.go @@ -94,7 +94,7 @@ func TestMain(m *testing.M) { cfg.CredentialStatus = config.CredentialStatus{ RHSMode: "None", - DirectStatus: config.DirectStatus{ + Iden3CommAgentStatus: config.Iden3CommAgentStatus{ URL: "http://localhost:3001", }, } diff --git a/internal/core/services/tests/notification_test.go b/internal/core/services/tests/notification_test.go index ae717950f..71ed3472a 100644 --- a/internal/core/services/tests/notification_test.go +++ b/internal/core/services/tests/notification_test.go @@ -41,7 +41,7 @@ func TestNotification_SendNotification(t *testing.T) { rhsFactory := reverse_hash.NewFactory(cfg.CredentialStatus.RHS.URL, nil, commonEth.HexToAddress(cfg.CredentialStatus.OnchainTreeStore.SupportedTreeStoreContract), reverse_hash.DefaultRHSTimeOut) revocationStatusResolver := revocation_status.NewRevocationStatusResolver(cfg.CredentialStatus) identityService := services.NewIdentity(keyStore, identityRepo, mtRepo, identityStateRepo, mtService, nil, claimsRepo, revocationRepository, connectionsRepository, storage, nil, nil, pubsub.NewMock(), cfg.CredentialStatus, rhsFactory, revocationStatusResolver) - credentialsService := services.NewClaim(claimsRepo, identityService, nil, mtService, identityStateRepo, docLoader, storage, cfg.CredentialStatus.DirectStatus.GetURL(), pubsub.NewMock(), ipfsGateway, revocationStatusResolver) + credentialsService := services.NewClaim(claimsRepo, identityService, nil, mtService, identityStateRepo, docLoader, storage, cfg.CredentialStatus.Iden3CommAgentStatus.GetURL(), pubsub.NewMock(), ipfsGateway, revocationStatusResolver) connectionsService := services.NewConnection(connectionsRepository, claimsRepo, storage) iden, err := identityService.Create(ctx, "polygon-test", &ports.DIDCreationOptions{Method: method, Blockchain: blockchain, Network: network, KeyType: BJJ}) require.NoError(t, err) diff --git a/pkg/credentials/revocation_status/iden3_reverse_sparse_merkletree_proof_resolver.go b/pkg/credentials/revocation_status/iden3_reverse_sparse_merkletree_proof_resolver.go index 49f12d57e..4b208b763 100644 --- a/pkg/credentials/revocation_status/iden3_reverse_sparse_merkletree_proof_resolver.go +++ b/pkg/credentials/revocation_status/iden3_reverse_sparse_merkletree_proof_resolver.go @@ -15,8 +15,8 @@ func (r *iden3ReverseSparseMerkleTreeProofResolver) resolve(credentialStatusSett Type: verifiable.Iden3ReverseSparseMerkleTreeProof, RevocationNonce: nonce, StatusIssuer: &verifiable.CredentialStatus{ - ID: buildDirectRevocationURL(credentialStatusSettings.DirectStatus.GetURL(), issuerDID.String(), nonce, credentialStatusSettings.SingleIssuer), - Type: verifiable.SparseMerkleTreeProof, + ID: buildDirectRevocationURL(credentialStatusSettings.Iden3CommAgentStatus.GetURL()), + Type: verifiable.Iden3commRevocationStatusV1, RevocationNonce: nonce, }, } diff --git a/pkg/credentials/revocation_status/iden3_revocation_status_v1.go b/pkg/credentials/revocation_status/iden3_revocation_status_v1.go index 47d13f983..9b29226e3 100644 --- a/pkg/credentials/revocation_status/iden3_revocation_status_v1.go +++ b/pkg/credentials/revocation_status/iden3_revocation_status_v1.go @@ -11,7 +11,7 @@ type iden3CommRevocationStatusV1Resolver struct{} func (r *iden3CommRevocationStatusV1Resolver) resolve(credentialStatusSettings config.CredentialStatus, issuerDID w3c.DID, nonce uint64, issuerState string) *verifiable.CredentialStatus { return &verifiable.CredentialStatus{ - ID: credentialStatusSettings.DirectStatus.GetAgentURL(), + ID: buildDirectRevocationURL(credentialStatusSettings.Iden3CommAgentStatus.GetURL()), Type: verifiable.Iden3commRevocationStatusV1, RevocationNonce: nonce, } diff --git a/pkg/credentials/revocation_status/resolver_test.go b/pkg/credentials/revocation_status/resolver_test.go index 699614ac3..9779ac2ca 100644 --- a/pkg/credentials/revocation_status/resolver_test.go +++ b/pkg/credentials/revocation_status/resolver_test.go @@ -35,7 +35,7 @@ func TestRevocationStatusResolver_GetCredentialRevocationStatus(t *testing.T) { name: "SparseMerkleTreeProof for single issuer", credentialStatusSettings: config.CredentialStatus{ RHSMode: config.RHSMode("none"), - DirectStatus: config.DirectStatus{ + Iden3CommAgentStatus: config.Iden3CommAgentStatus{ URL: "https://issuernode", }, SingleIssuer: true, @@ -47,7 +47,7 @@ func TestRevocationStatusResolver_GetCredentialRevocationStatus(t *testing.T) { err: nil, CredentialStatus: &verifiable.CredentialStatus{ Type: verifiable.SparseMerkleTreeProof, - ID: "https://issuernode/v1/credentials/revocation/status/12345", + ID: "https://issuernode/v1/agent", RevocationNonce: 12345, }, }, @@ -56,7 +56,7 @@ func TestRevocationStatusResolver_GetCredentialRevocationStatus(t *testing.T) { name: "SparseMerkleTreeProof for multiples issuers", credentialStatusSettings: config.CredentialStatus{ RHSMode: config.RHSMode("none"), - DirectStatus: config.DirectStatus{ + Iden3CommAgentStatus: config.Iden3CommAgentStatus{ URL: "https://issuernode", }, SingleIssuer: false, @@ -68,7 +68,7 @@ func TestRevocationStatusResolver_GetCredentialRevocationStatus(t *testing.T) { err: nil, CredentialStatus: &verifiable.CredentialStatus{ Type: verifiable.SparseMerkleTreeProof, - ID: "https://issuernode/v1/did%3Apolygonid%3Apolygon%3Amumbai%3A2qFbNk3Vz7Uy3ryq6zjwkC7p7RbLTfRpMsy6axjxeG/claims/revocation/status/12345", + ID: "https://issuernode/v1/agent", RevocationNonce: 12345, }, }, @@ -80,7 +80,7 @@ func TestRevocationStatusResolver_GetCredentialRevocationStatus(t *testing.T) { RHS: config.RHS{ URL: "https://rhs", }, - DirectStatus: config.DirectStatus{ + Iden3CommAgentStatus: config.Iden3CommAgentStatus{ URL: "https://issuernode", }, SingleIssuer: true, @@ -95,8 +95,8 @@ func TestRevocationStatusResolver_GetCredentialRevocationStatus(t *testing.T) { ID: "https://rhs/node?state=issuer-state", RevocationNonce: 12345, StatusIssuer: &verifiable.CredentialStatus{ - Type: verifiable.SparseMerkleTreeProof, - ID: "https://issuernode/v1/credentials/revocation/status/12345", + Type: verifiable.Iden3commRevocationStatusV1, + ID: "https://issuernode/v1/agent", RevocationNonce: 12345, }, }, @@ -109,7 +109,7 @@ func TestRevocationStatusResolver_GetCredentialRevocationStatus(t *testing.T) { RHS: config.RHS{ URL: "https://rhs", }, - DirectStatus: config.DirectStatus{ + Iden3CommAgentStatus: config.Iden3CommAgentStatus{ URL: "https://issuernode", }, SingleIssuer: false, @@ -124,8 +124,8 @@ func TestRevocationStatusResolver_GetCredentialRevocationStatus(t *testing.T) { ID: "https://rhs/node?state=issuer-state", RevocationNonce: 12345, StatusIssuer: &verifiable.CredentialStatus{ - Type: verifiable.SparseMerkleTreeProof, - ID: "https://issuernode/v1/did%3Apolygonid%3Apolygon%3Amumbai%3A2qFbNk3Vz7Uy3ryq6zjwkC7p7RbLTfRpMsy6axjxeG/claims/revocation/status/12345", + Type: verifiable.Iden3commRevocationStatusV1, + ID: "https://issuernode/v1/agent", RevocationNonce: 12345, }, }, @@ -138,7 +138,7 @@ func TestRevocationStatusResolver_GetCredentialRevocationStatus(t *testing.T) { RHS: config.RHS{ URL: "https://rhs", }, - DirectStatus: config.DirectStatus{ + Iden3CommAgentStatus: config.Iden3CommAgentStatus{ URL: "https://issuernode", }, SingleIssuer: false, @@ -167,7 +167,7 @@ func TestRevocationStatusResolver_GetCredentialRevocationStatus(t *testing.T) { RHS: config.RHS{ URL: "https://rhs", }, - DirectStatus: config.DirectStatus{ + Iden3CommAgentStatus: config.Iden3CommAgentStatus{ URL: "https://issuernode", }, SingleIssuer: false, diff --git a/pkg/credentials/revocation_status/sparse_merkletree_proof_resolver.go b/pkg/credentials/revocation_status/sparse_merkletree_proof_resolver.go index b64f1817f..43a9b402c 100644 --- a/pkg/credentials/revocation_status/sparse_merkletree_proof_resolver.go +++ b/pkg/credentials/revocation_status/sparse_merkletree_proof_resolver.go @@ -9,9 +9,9 @@ import ( type sparseMerkleTreeProofResolver struct{} -func (r *sparseMerkleTreeProofResolver) resolve(credentialStatusSettings config.CredentialStatus, issuerDID w3c.DID, nonce uint64, issuerState string) *verifiable.CredentialStatus { +func (r *sparseMerkleTreeProofResolver) resolve(credentialStatusSettings config.CredentialStatus, _ w3c.DID, nonce uint64, _ string) *verifiable.CredentialStatus { return &verifiable.CredentialStatus{ - ID: buildDirectRevocationURL(credentialStatusSettings.DirectStatus.GetURL(), issuerDID.String(), nonce, credentialStatusSettings.SingleIssuer), + ID: buildDirectRevocationURL(credentialStatusSettings.Iden3CommAgentStatus.GetURL()), Type: verifiable.SparseMerkleTreeProof, RevocationNonce: nonce, } diff --git a/pkg/credentials/revocation_status/utils.go b/pkg/credentials/revocation_status/utils.go index 2a5324ed5..3dbf0b670 100644 --- a/pkg/credentials/revocation_status/utils.go +++ b/pkg/credentials/revocation_status/utils.go @@ -2,7 +2,6 @@ package revocation_status import ( "fmt" - "net/url" ethcommon "github.com/ethereum/go-ethereum/common" "github.com/iden3/go-iden3-core/v2/w3c" @@ -15,12 +14,8 @@ func buildRHSRevocationURL(host, issuerState string) string { return fmt.Sprintf("%s/node?state=%s", host, issuerState) } -func buildDirectRevocationURL(host, issuerDID string, nonce uint64, singleIssuer bool) string { - if singleIssuer { - return fmt.Sprintf("%s/v1/credentials/revocation/status/%d", - host, nonce) - } - return fmt.Sprintf("%s/v1/%s/claims/revocation/status/%d", host, url.QueryEscape(issuerDID), nonce) +func buildDirectRevocationURL(host string) string { + return fmt.Sprintf("%s/v1/agent", host) } func buildIden3OnchainSMTProofURL(issuerDID w3c.DID, nonce uint64, contractAddress ethcommon.Address, chainID string, stateHex string) string { From 3a5e44e4557f07e31bec74ad7b0c83dae74881bb Mon Sep 17 00:00:00 2001 From: Martin Saporiti Date: Wed, 29 May 2024 15:15:45 -0300 Subject: [PATCH 14/52] chore: remove sparseMerkleTreeProof --- cmd/issuer_initializer/main.go | 3 +- internal/api/server.go | 4 +- internal/api/server_test.go | 2 +- internal/api_ui/server.go | 4 +- internal/api_ui/server_test.go | 34 +++++++-------- internal/config/credential_status.go | 7 ++-- internal/core/services/tests/identity_test.go | 14 +++---- internal/core/services/tests/link_test.go | 4 +- ...everse_sparse_merkletree_proof_resolver.go | 4 +- .../iden3_revocation_status_v1.go | 4 +- pkg/credentials/revocation_status/resolver.go | 1 - .../revocation_status/resolver_test.go | 42 ------------------- .../sparse_merkletree_proof_resolver.go | 18 -------- pkg/credentials/revocation_status/utils.go | 4 -- 14 files changed, 42 insertions(+), 103 deletions(-) delete mode 100644 pkg/credentials/revocation_status/sparse_merkletree_proof_resolver.go diff --git a/cmd/issuer_initializer/main.go b/cmd/issuer_initializer/main.go index 02e4959d6..6ca778004 100644 --- a/cmd/issuer_initializer/main.go +++ b/cmd/issuer_initializer/main.go @@ -12,7 +12,6 @@ import ( "github.com/ethereum/go-ethereum/ethclient" vault "github.com/hashicorp/vault/api" core "github.com/iden3/go-iden3-core/v2" - "github.com/iden3/go-schema-processor/v2/verifiable" "github.com/polygonid/sh-id-platform/internal/buildinfo" "github.com/polygonid/sh-id-platform/internal/config" @@ -155,7 +154,7 @@ func main() { Network: core.NetworkID(cfg.APIUI.IdentityNetwork), Blockchain: core.Blockchain(cfg.APIUI.IdentityBlockchain), KeyType: kms.KeyType(cfg.APIUI.KeyType), - AuthBJJCredentialStatus: verifiable.CredentialStatusType(cfg.CredentialStatus.CredentialStatusType), + AuthBJJCredentialStatus: cfg.CredentialStatus.CredentialStatusType, } identity, err := identityService.Create(ctx, cfg.APIUI.ServerURL, didCreationOptions) diff --git a/internal/api/server.go b/internal/api/server.go index a026cb94e..0d0a4b23e 100644 --- a/internal/api/server.go +++ b/internal/api/server.go @@ -100,7 +100,7 @@ func (s *Server) CreateIdentity(ctx context.Context, request CreateIdentityReque Network: core.NetworkID(network), Blockchain: core.Blockchain(blockchain), KeyType: kms.KeyType(keyType), - AuthBJJCredentialStatus: verifiable.CredentialStatusType(s.cfg.CredentialStatus.CredentialStatusType), + AuthBJJCredentialStatus: s.cfg.CredentialStatus.CredentialStatusType, }) if err != nil { if errors.Is(err, services.ErrWrongDIDMetada) { @@ -160,7 +160,7 @@ func (s *Server) CreateClaim(ctx context.Context, request CreateClaimRequestObje expiration = common.ToPointer(time.Unix(*request.Body.Expiration, 0)) } - req := ports.NewCreateClaimRequest(did, request.Body.CredentialSchema, request.Body.CredentialSubject, expiration, request.Body.Type, request.Body.Version, request.Body.SubjectPosition, request.Body.MerklizedRootPosition, common.ToPointer(true), common.ToPointer(true), nil, false, verifiable.CredentialStatusType(s.cfg.CredentialStatus.CredentialStatusType), toVerifiableRefreshService(request.Body.RefreshService), request.Body.RevNonce, + req := ports.NewCreateClaimRequest(did, request.Body.CredentialSchema, request.Body.CredentialSubject, expiration, request.Body.Type, request.Body.Version, request.Body.SubjectPosition, request.Body.MerklizedRootPosition, common.ToPointer(true), common.ToPointer(true), nil, false, s.cfg.CredentialStatus.CredentialStatusType, toVerifiableRefreshService(request.Body.RefreshService), request.Body.RevNonce, toVerifiableDisplayMethod(request.Body.DisplayMethod)) resp, err := s.claimService.Save(ctx, req) diff --git a/internal/api/server_test.go b/internal/api/server_test.go index 55429ba61..aaa765a68 100644 --- a/internal/api/server_test.go +++ b/internal/api/server_test.go @@ -1333,7 +1333,7 @@ func TestServer_GetRevocationStatus(t *testing.T) { typeC := "KYCAgeCredential" merklizedRootPosition := "value" - claim, err := claimsService.Save(ctx, ports.NewCreateClaimRequest(did, schema, credentialSubject, common.ToPointer(time.Now()), typeC, nil, nil, &merklizedRootPosition, common.ToPointer(true), common.ToPointer(true), nil, false, verifiable.SparseMerkleTreeProof, nil, nil, nil)) + claim, err := claimsService.Save(ctx, ports.NewCreateClaimRequest(did, schema, credentialSubject, common.ToPointer(time.Now()), typeC, nil, nil, &merklizedRootPosition, common.ToPointer(true), common.ToPointer(true), nil, false, verifiable.Iden3commRevocationStatusV1, nil, nil, nil)) assert.NoError(t, err) type expected struct { diff --git a/internal/api_ui/server.go b/internal/api_ui/server.go index 24e11c1d2..49c082185 100644 --- a/internal/api_ui/server.go +++ b/internal/api_ui/server.go @@ -343,7 +343,7 @@ func (s *Server) CreateCredential(ctx context.Context, request CreateCredentialR if request.Body.SignatureProof == nil && request.Body.MtProof == nil { return CreateCredential400JSONResponse{N400JSONResponse{Message: "you must to provide at least one proof type"}}, nil } - req := ports.NewCreateClaimRequest(&s.cfg.APIUI.IssuerDID, request.Body.CredentialSchema, request.Body.CredentialSubject, request.Body.Expiration, request.Body.Type, nil, nil, nil, request.Body.SignatureProof, request.Body.MtProof, nil, true, verifiable.CredentialStatusType(s.cfg.CredentialStatus.CredentialStatusType), toVerifiableRefreshService(request.Body.RefreshService), nil, + req := ports.NewCreateClaimRequest(&s.cfg.APIUI.IssuerDID, request.Body.CredentialSchema, request.Body.CredentialSubject, request.Body.Expiration, request.Body.Type, nil, nil, nil, request.Body.SignatureProof, request.Body.MtProof, nil, true, s.cfg.CredentialStatus.CredentialStatusType, toVerifiableRefreshService(request.Body.RefreshService), nil, toDisplayMethodService(request.Body.DisplayMethod)) resp, err := s.claimService.Save(ctx, req) if err != nil { @@ -670,7 +670,7 @@ func (s *Server) CreateLinkQrCodeCallback(ctx context.Context, request CreateLin return CreateLinkQrCodeCallback500JSONResponse{}, nil } - err = s.linkService.IssueClaim(ctx, request.Params.SessionID.String(), s.cfg.APIUI.IssuerDID, *userDID, request.Params.LinkID, s.cfg.APIUI.ServerURL, verifiable.CredentialStatusType(s.cfg.CredentialStatus.CredentialStatusType)) + err = s.linkService.IssueClaim(ctx, request.Params.SessionID.String(), s.cfg.APIUI.IssuerDID, *userDID, request.Params.LinkID, s.cfg.APIUI.ServerURL, s.cfg.CredentialStatus.CredentialStatusType) if err != nil { log.Debug(ctx, "error issuing the claim", "error", err) return CreateLinkQrCodeCallback500JSONResponse{}, nil diff --git a/internal/api_ui/server_test.go b/internal/api_ui/server_test.go index 368ddfa83..b3ab78a2b 100644 --- a/internal/api_ui/server_test.go +++ b/internal/api_ui/server_test.go @@ -1465,13 +1465,13 @@ func TestServer_GetCredential(t *testing.T) { typeC := "KYCAgeCredential" merklizedRootPosition := "index" schema := "https://raw.githubusercontent.com/iden3/claim-schema-vocab/main/schemas/json/KYCAgeCredential-v3.json" - createdClaim1, err := claimsService.Save(ctx, ports.NewCreateClaimRequest(did, schema, credentialSubject, nil, typeC, nil, nil, &merklizedRootPosition, common.ToPointer(true), common.ToPointer(true), nil, false, verifiable.SparseMerkleTreeProof, nil, nil, nil)) + createdClaim1, err := claimsService.Save(ctx, ports.NewCreateClaimRequest(did, schema, credentialSubject, nil, typeC, nil, nil, &merklizedRootPosition, common.ToPointer(true), common.ToPointer(true), nil, false, verifiable.Iden3commRevocationStatusV1, nil, nil, nil)) require.NoError(t, err) - createdClaim2, err := claimsService.Save(ctx, ports.NewCreateClaimRequest(did, schema, credentialSubject, nil, typeC, nil, nil, &merklizedRootPosition, common.ToPointer(true), common.ToPointer(false), nil, false, verifiable.SparseMerkleTreeProof, nil, nil, nil)) + createdClaim2, err := claimsService.Save(ctx, ports.NewCreateClaimRequest(did, schema, credentialSubject, nil, typeC, nil, nil, &merklizedRootPosition, common.ToPointer(true), common.ToPointer(false), nil, false, verifiable.Iden3commRevocationStatusV1, nil, nil, nil)) require.NoError(t, err) - createdClaim3, err := claimsService.Save(ctx, ports.NewCreateClaimRequest(did, schema, credentialSubject, nil, typeC, nil, nil, &merklizedRootPosition, common.ToPointer(false), common.ToPointer(true), nil, false, verifiable.SparseMerkleTreeProof, nil, nil, nil)) + createdClaim3, err := claimsService.Save(ctx, ports.NewCreateClaimRequest(did, schema, credentialSubject, nil, typeC, nil, nil, &merklizedRootPosition, common.ToPointer(false), common.ToPointer(true), nil, false, verifiable.Iden3commRevocationStatusV1, nil, nil, nil)) require.NoError(t, err) handler := getHandler(ctx, server) @@ -1665,19 +1665,19 @@ func TestServer_GetCredentials(t *testing.T) { _, err = schemaService.ImportSchema(ctx, *did, iReq) require.NoError(t, err) // Never expires - _, err = claimsService.Save(ctx, ports.NewCreateClaimRequest(did, schemaURL, credentialSubject, nil, typeC, nil, nil, &merklizedRootPosition, common.ToPointer(true), common.ToPointer(true), nil, false, verifiable.SparseMerkleTreeProof, nil, nil, nil)) + _, err = claimsService.Save(ctx, ports.NewCreateClaimRequest(did, schemaURL, credentialSubject, nil, typeC, nil, nil, &merklizedRootPosition, common.ToPointer(true), common.ToPointer(true), nil, false, verifiable.Iden3commRevocationStatusV1, nil, nil, nil)) require.NoError(t, err) // Expires in future - _, err = claimsService.Save(ctx, ports.NewCreateClaimRequest(did, schemaURL, credentialSubject, &future, typeC, nil, nil, &merklizedRootPosition, common.ToPointer(true), common.ToPointer(false), nil, false, verifiable.SparseMerkleTreeProof, nil, nil, nil)) + _, err = claimsService.Save(ctx, ports.NewCreateClaimRequest(did, schemaURL, credentialSubject, &future, typeC, nil, nil, &merklizedRootPosition, common.ToPointer(true), common.ToPointer(false), nil, false, verifiable.Iden3commRevocationStatusV1, nil, nil, nil)) require.NoError(t, err) // Expired - claim, err := claimsService.Save(ctx, ports.NewCreateClaimRequest(did, schemaURL, credentialSubject, &past, typeC, nil, nil, &merklizedRootPosition, common.ToPointer(true), common.ToPointer(false), nil, false, verifiable.SparseMerkleTreeProof, nil, nil, nil)) + claim, err := claimsService.Save(ctx, ports.NewCreateClaimRequest(did, schemaURL, credentialSubject, &past, typeC, nil, nil, &merklizedRootPosition, common.ToPointer(true), common.ToPointer(false), nil, false, verifiable.Iden3commRevocationStatusV1, nil, nil, nil)) require.NoError(t, err) // non expired, but revoked - revoked, err := claimsService.Save(ctx, ports.NewCreateClaimRequest(did, schemaURL, credentialSubject, &future, typeC, nil, nil, &merklizedRootPosition, common.ToPointer(false), common.ToPointer(true), nil, false, verifiable.SparseMerkleTreeProof, nil, nil, nil)) + revoked, err := claimsService.Save(ctx, ports.NewCreateClaimRequest(did, schemaURL, credentialSubject, &future, typeC, nil, nil, &merklizedRootPosition, common.ToPointer(false), common.ToPointer(true), nil, false, verifiable.Iden3commRevocationStatusV1, nil, nil, nil)) require.NoError(t, err) id, err := w3c.ParseDID(*revoked.Identifier) @@ -2127,9 +2127,9 @@ func TestServer_GetCredentialQrCode(t *testing.T) { typeC := "KYCAgeCredential" merklizedRootPosition := "index" schema := "https://raw.githubusercontent.com/iden3/claim-schema-vocab/main/schemas/json/KYCAgeCredential-v3.json" - createdSIGClaim, err := claimsService.Save(ctx, ports.NewCreateClaimRequest(did, schema, credentialSubject, nil, typeC, nil, nil, &merklizedRootPosition, common.ToPointer(true), common.ToPointer(false), nil, false, verifiable.SparseMerkleTreeProof, nil, nil, nil)) + createdSIGClaim, err := claimsService.Save(ctx, ports.NewCreateClaimRequest(did, schema, credentialSubject, nil, typeC, nil, nil, &merklizedRootPosition, common.ToPointer(true), common.ToPointer(false), nil, false, verifiable.Iden3commRevocationStatusV1, nil, nil, nil)) require.NoError(t, err) - createdMTPClaim, err := claimsService.Save(ctx, ports.NewCreateClaimRequest(did, schema, credentialSubject, nil, typeC, nil, nil, &merklizedRootPosition, common.ToPointer(false), common.ToPointer(true), nil, false, verifiable.SparseMerkleTreeProof, nil, nil, nil)) + createdMTPClaim, err := claimsService.Save(ctx, ports.NewCreateClaimRequest(did, schema, credentialSubject, nil, typeC, nil, nil, &merklizedRootPosition, common.ToPointer(false), common.ToPointer(true), nil, false, verifiable.Iden3commRevocationStatusV1, nil, nil, nil)) require.NoError(t, err) type expected struct { @@ -2486,9 +2486,9 @@ func TestServer_GetConnections(t *testing.T) { } merklizedRootPosition := "index" - _, err = claimsService.Save(ctx, ports.NewCreateClaimRequest(did, schemaURL, credentialSubject, nil, schemaType, nil, nil, &merklizedRootPosition, common.ToPointer(true), common.ToPointer(true), nil, false, verifiable.SparseMerkleTreeProof, nil, nil, nil)) + _, err = claimsService.Save(ctx, ports.NewCreateClaimRequest(did, schemaURL, credentialSubject, nil, schemaType, nil, nil, &merklizedRootPosition, common.ToPointer(true), common.ToPointer(true), nil, false, verifiable.Iden3commRevocationStatusV1, nil, nil, nil)) require.NoError(t, err) - _, err = claimsService.Save(ctx, ports.NewCreateClaimRequest(did, schemaURL, credentialSubject2, nil, schemaType, nil, nil, &merklizedRootPosition, common.ToPointer(true), common.ToPointer(true), nil, false, verifiable.SparseMerkleTreeProof, nil, nil, nil)) + _, err = claimsService.Save(ctx, ports.NewCreateClaimRequest(did, schemaURL, credentialSubject2, nil, schemaType, nil, nil, &merklizedRootPosition, common.ToPointer(true), common.ToPointer(true), nil, false, verifiable.Iden3commRevocationStatusV1, nil, nil, nil)) require.NoError(t, err) usrDID, err := w3c.ParseDID("did:polygonid:polygon:mumbai:2qE1BZ7gcmEoP2KppvFPCZqyzyb5tK9T6Gec5HFANQ") @@ -3715,7 +3715,7 @@ func TestServer_GetLink(t *testing.T) { SchemaType: link.Schema.Type, SchemaUrl: link.Schema.URL, Status: LinkStatusActive, - ProofTypes: []string{"SparseMerkleTreeProof", "BJJSignature2021"}, + ProofTypes: []string{"Iden3commRevocationStatusV1", "BJJSignature2021"}, CreatedAt: TimeUTC(link.CreatedAt), SchemaHash: string(hash), CredentialExpiration: common.ToPointer(TimeUTC(tomorrow)), @@ -3738,7 +3738,7 @@ func TestServer_GetLink(t *testing.T) { SchemaType: linkExpired.Schema.Type, SchemaUrl: linkExpired.Schema.URL, Status: LinkStatusExceeded, - ProofTypes: []string{"SparseMerkleTreeProof", "BJJSignature2021"}, + ProofTypes: []string{"Iden3commRevocationStatusV1", "BJJSignature2021"}, CredentialExpiration: nil, }, }, @@ -4636,7 +4636,7 @@ func TestServer_GetStateStatus(t *testing.T) { } serverWithSignatureClaim := NewServer(cfg1, identityService, claimsService, NewSchemaMock(), connectionsService, NewLinkMock(), nil, NewPublisherMock(), NewPackageManagerMock(), nil) - _, err = claimsService.Save(ctx, ports.NewCreateClaimRequest(didSignatureClaim, schema, credentialSubject, nil, typeC, nil, nil, &merklizedRootPosition, common.ToPointer(true), common.ToPointer(false), nil, true, verifiable.SparseMerkleTreeProof, nil, nil, nil)) + _, err = claimsService.Save(ctx, ports.NewCreateClaimRequest(didSignatureClaim, schema, credentialSubject, nil, typeC, nil, nil, &merklizedRootPosition, common.ToPointer(true), common.ToPointer(false), nil, true, verifiable.Iden3commRevocationStatusV1, nil, nil, nil)) require.NoError(t, err) handlerWithSignatureClaim := getHandler(ctx, serverWithSignatureClaim) @@ -4652,7 +4652,7 @@ func TestServer_GetStateStatus(t *testing.T) { }, } serverWithMTPClaim := NewServer(cfgWithMTPClaim, identityService, claimsService, NewSchemaMock(), connectionsService, NewLinkMock(), nil, NewPublisherMock(), NewPackageManagerMock(), nil) - _, err = claimsService.Save(ctx, ports.NewCreateClaimRequest(didWithMTPClaim, schema, credentialSubject, nil, typeC, nil, nil, &merklizedRootPosition, common.ToPointer(true), common.ToPointer(true), nil, true, verifiable.SparseMerkleTreeProof, nil, nil, nil)) + _, err = claimsService.Save(ctx, ports.NewCreateClaimRequest(didWithMTPClaim, schema, credentialSubject, nil, typeC, nil, nil, &merklizedRootPosition, common.ToPointer(true), common.ToPointer(true), nil, true, verifiable.Iden3commRevocationStatusV1, nil, nil, nil)) require.NoError(t, err) handlerWithMTPClaim := getHandler(ctx, serverWithMTPClaim) @@ -4668,7 +4668,7 @@ func TestServer_GetStateStatus(t *testing.T) { }, } serverWithRevokedClaim := NewServer(cfgWithRevokedClaim, identityService, claimsService, NewSchemaMock(), connectionsService, NewLinkMock(), nil, NewPublisherMock(), NewPackageManagerMock(), nil) - cred, err := claimsService.Save(ctx, ports.NewCreateClaimRequest(didWithRevokedClaim, schema, credentialSubject, nil, typeC, nil, nil, &merklizedRootPosition, common.ToPointer(true), common.ToPointer(false), nil, true, verifiable.SparseMerkleTreeProof, nil, nil, nil)) + cred, err := claimsService.Save(ctx, ports.NewCreateClaimRequest(didWithRevokedClaim, schema, credentialSubject, nil, typeC, nil, nil, &merklizedRootPosition, common.ToPointer(true), common.ToPointer(false), nil, true, verifiable.Iden3commRevocationStatusV1, nil, nil, nil)) require.NoError(t, err) require.NoError(t, claimsService.Revoke(ctx, cfgWithRevokedClaim.APIUI.IssuerDID, uint64(cred.RevNonce), "not valid")) handlerWithRevokedClaim := getHandler(ctx, serverWithRevokedClaim) @@ -4867,7 +4867,7 @@ func TestServer_GetRevocationStatus(t *testing.T) { typeC := "KYCAgeCredential" merklizedRootPosition := "index" schema := "https://raw.githubusercontent.com/iden3/claim-schema-vocab/main/schemas/json/KYCAgeCredential-v3.json" - createdCredential, err := claimsService.Save(ctx, ports.NewCreateClaimRequest(did, schema, credentialSubject, nil, typeC, nil, nil, &merklizedRootPosition, common.ToPointer(true), common.ToPointer(true), nil, false, verifiable.SparseMerkleTreeProof, nil, nil, nil)) + createdCredential, err := claimsService.Save(ctx, ports.NewCreateClaimRequest(did, schema, credentialSubject, nil, typeC, nil, nil, &merklizedRootPosition, common.ToPointer(true), common.ToPointer(true), nil, false, verifiable.Iden3commRevocationStatusV1, nil, nil, nil)) require.NoError(t, err) handler := getHandler(ctx, server) diff --git a/internal/config/credential_status.go b/internal/config/credential_status.go index 8d6e87114..1291e973c 100644 --- a/internal/config/credential_status.go +++ b/internal/config/credential_status.go @@ -2,11 +2,12 @@ package config import ( "strings" + + "github.com/iden3/go-schema-processor/v2/verifiable" ) const ( - sparseMerkleTreeProof = "SparseMerkleTreeProof" - iden3commRevocationStatusV1 = "Iden3commRevocationStatusV1.0" + iden3commRevocationStatusV1 = verifiable.Iden3commRevocationStatusV1 iden3ReverseSparseMerkleTreeProof = "Iden3ReverseSparseMerkleTreeProof" iden3OnchainSparseMerkleTreeProof2023 = "Iden3OnchainSparseMerkleTreeProof2023" onChain = "OnChain" @@ -24,7 +25,7 @@ type CredentialStatus struct { OnchainTreeStore OnchainTreeStore `mapstructure:"OnchainTreeStore"` RHSMode RHSMode `tip:"Reverse hash service mode (OffChain, OnChain, Mixed, None)"` SingleIssuer bool - CredentialStatusType string `mapstructure:"CredentialStatusType" default:"Iden3commRevocationStatusV1"` + CredentialStatusType verifiable.CredentialStatusType `mapstructure:"CredentialStatusType" default:"Iden3commRevocationStatusV1"` } // Iden3CommAgentStatus is the type of direct status diff --git a/internal/core/services/tests/identity_test.go b/internal/core/services/tests/identity_test.go index 43b0c1e55..2e4c62cd8 100644 --- a/internal/core/services/tests/identity_test.go +++ b/internal/core/services/tests/identity_test.go @@ -60,7 +60,7 @@ func Test_identity_UpdateState(t *testing.T) { _, err = claimsService.Save(ctx, ports.NewCreateClaimRequest(did, schema, credentialSubject, common.ToPointer(time.Now()), typeC, nil, nil, &merklizedRootPosition, common.ToPointer(true), common.ToPointer(true), nil, false, - verifiable.SparseMerkleTreeProof, nil, nil, nil)) + verifiable.Iden3commRevocationStatusV1, nil, nil, nil)) assert.NoError(t, err) previousStateIdentity, _ := identityStateRepo.GetLatestStateByIdentifier(ctx, storage.Pgx, did) @@ -82,7 +82,7 @@ func Test_identity_UpdateState(t *testing.T) { _, err = claimsService.Save(ctx, ports.NewCreateClaimRequest(did, schema, credentialSubject, common.ToPointer(time.Now()), typeC, nil, nil, &merklizedRootPosition, common.ToPointer(false), common.ToPointer(true), nil, false, - verifiable.SparseMerkleTreeProof, nil, nil, nil)) + verifiable.Iden3commRevocationStatusV1, nil, nil, nil)) assert.NoError(t, err) previousStateIdentity, _ := identityStateRepo.GetLatestStateByIdentifier(ctx, storage.Pgx, did) @@ -104,7 +104,7 @@ func Test_identity_UpdateState(t *testing.T) { claim, err := claimsService.Save(ctx, ports.NewCreateClaimRequest(did, schema, credentialSubject, common.ToPointer(time.Now()), typeC, nil, nil, &merklizedRootPosition, common.ToPointer(false), common.ToPointer(true), nil, false, - verifiable.SparseMerkleTreeProof, nil, nil, nil)) + verifiable.Iden3commRevocationStatusV1, nil, nil, nil)) assert.NoError(t, err) previousStateIdentity, _ := identityStateRepo.GetLatestStateByIdentifier(ctx, storage.Pgx, did) @@ -130,7 +130,7 @@ func Test_identity_UpdateState(t *testing.T) { claimMTP, err := claimsService.Save(ctx, ports.NewCreateClaimRequest(did, schema, credentialSubject, common.ToPointer(time.Now()), typeC, nil, nil, &merklizedRootPosition, common.ToPointer(false), common.ToPointer(true), nil, false, - verifiable.SparseMerkleTreeProof, nil, nil, nil)) + verifiable.Iden3commRevocationStatusV1, nil, nil, nil)) assert.NoError(t, err) previousStateIdentity, _ := identityStateRepo.GetLatestStateByIdentifier(ctx, storage.Pgx, did) @@ -152,7 +152,7 @@ func Test_identity_UpdateState(t *testing.T) { claimSIG, err := claimsService.Save(ctx, ports.NewCreateClaimRequest(did, schema, credentialSubject, common.ToPointer(time.Now()), typeC, nil, nil, &merklizedRootPosition, common.ToPointer(true), common.ToPointer(false), nil, false, - verifiable.SparseMerkleTreeProof, nil, nil, nil)) + verifiable.Iden3commRevocationStatusV1, nil, nil, nil)) assert.NoError(t, err) _, err = identityService.UpdateState(ctx, *did) @@ -179,7 +179,7 @@ func Test_identity_UpdateState(t *testing.T) { _, err = claimsService.Save(ctx, ports.NewCreateClaimRequest(did, schema, credentialSubject, common.ToPointer(time.Now()), typeC, nil, nil, &merklizedRootPosition, common.ToPointer(true), common.ToPointer(false), nil, false, - verifiable.SparseMerkleTreeProof, nil, nil, nil)) + verifiable.Iden3commRevocationStatusV1, nil, nil, nil)) assert.NoError(t, err) _, err = identityStateRepo.GetLatestStateByIdentifier(ctx, storage.Pgx, did) @@ -194,7 +194,7 @@ func Test_identity_UpdateState(t *testing.T) { claim, err := claimsService.Save(ctx, ports.NewCreateClaimRequest(did, schema, credentialSubject, common.ToPointer(time.Now()), typeC, nil, nil, &merklizedRootPosition, common.ToPointer(true), common.ToPointer(false), nil, false, - verifiable.SparseMerkleTreeProof, nil, nil, nil)) + verifiable.Iden3commRevocationStatusV1, nil, nil, nil)) assert.NoError(t, err) _, err = identityStateRepo.GetLatestStateByIdentifier(ctx, storage.Pgx, did) diff --git a/internal/core/services/tests/link_test.go b/internal/core/services/tests/link_test.go index 96aaf076c..1d1de11cb 100644 --- a/internal/core/services/tests/link_test.go +++ b/internal/core/services/tests/link_test.go @@ -67,7 +67,7 @@ func Test_link_issueClaim(t *testing.T) { typeC := "KYCAgeCredential" merklizedRootPosition := "index" - _, err = claimsService.Save(context.Background(), ports.NewCreateClaimRequest(did, schemaUrl, credentialSubject, common.ToPointer(time.Now()), typeC, nil, nil, &merklizedRootPosition, common.ToPointer(true), common.ToPointer(true), nil, false, verifiable.SparseMerkleTreeProof, nil, nil, nil)) + _, err = claimsService.Save(context.Background(), ports.NewCreateClaimRequest(did, schemaUrl, credentialSubject, common.ToPointer(time.Now()), typeC, nil, nil, &merklizedRootPosition, common.ToPointer(true), common.ToPointer(true), nil, false, verifiable.Iden3commRevocationStatusV1, nil, nil, nil)) assert.NoError(t, err) linkRepository := repositories.NewLink(*storage) @@ -152,7 +152,7 @@ func Test_link_issueClaim(t *testing.T) { } { t.Run(tc.name, func(t *testing.T) { sessionID := uuid.New().String() - err := linkService.IssueClaim(ctx, sessionID, tc.did, tc.userDID, tc.LinkID, "host_url", verifiable.SparseMerkleTreeProof) + err := linkService.IssueClaim(ctx, sessionID, tc.did, tc.userDID, tc.LinkID, "host_url", verifiable.Iden3commRevocationStatusV1) if tc.expected.err != nil { assert.Error(t, err) assert.Equal(t, tc.expected.err, err) diff --git a/pkg/credentials/revocation_status/iden3_reverse_sparse_merkletree_proof_resolver.go b/pkg/credentials/revocation_status/iden3_reverse_sparse_merkletree_proof_resolver.go index 4b208b763..965b3dec9 100644 --- a/pkg/credentials/revocation_status/iden3_reverse_sparse_merkletree_proof_resolver.go +++ b/pkg/credentials/revocation_status/iden3_reverse_sparse_merkletree_proof_resolver.go @@ -1,6 +1,8 @@ package revocation_status import ( + "fmt" + "github.com/iden3/go-iden3-core/v2/w3c" "github.com/iden3/go-schema-processor/v2/verifiable" @@ -15,7 +17,7 @@ func (r *iden3ReverseSparseMerkleTreeProofResolver) resolve(credentialStatusSett Type: verifiable.Iden3ReverseSparseMerkleTreeProof, RevocationNonce: nonce, StatusIssuer: &verifiable.CredentialStatus{ - ID: buildDirectRevocationURL(credentialStatusSettings.Iden3CommAgentStatus.GetURL()), + ID: fmt.Sprintf("%s/v1/agent", credentialStatusSettings.Iden3CommAgentStatus.GetURL()), Type: verifiable.Iden3commRevocationStatusV1, RevocationNonce: nonce, }, diff --git a/pkg/credentials/revocation_status/iden3_revocation_status_v1.go b/pkg/credentials/revocation_status/iden3_revocation_status_v1.go index 9b29226e3..76a89cb7a 100644 --- a/pkg/credentials/revocation_status/iden3_revocation_status_v1.go +++ b/pkg/credentials/revocation_status/iden3_revocation_status_v1.go @@ -1,6 +1,8 @@ package revocation_status import ( + "fmt" + "github.com/iden3/go-iden3-core/v2/w3c" "github.com/iden3/go-schema-processor/v2/verifiable" @@ -11,7 +13,7 @@ type iden3CommRevocationStatusV1Resolver struct{} func (r *iden3CommRevocationStatusV1Resolver) resolve(credentialStatusSettings config.CredentialStatus, issuerDID w3c.DID, nonce uint64, issuerState string) *verifiable.CredentialStatus { return &verifiable.CredentialStatus{ - ID: buildDirectRevocationURL(credentialStatusSettings.Iden3CommAgentStatus.GetURL()), + ID: fmt.Sprintf("%s/v1/agent", credentialStatusSettings.Iden3CommAgentStatus.GetURL()), Type: verifiable.Iden3commRevocationStatusV1, RevocationNonce: nonce, } diff --git a/pkg/credentials/revocation_status/resolver.go b/pkg/credentials/revocation_status/resolver.go index 5401ebc67..15d7d8e14 100644 --- a/pkg/credentials/revocation_status/resolver.go +++ b/pkg/credentials/revocation_status/resolver.go @@ -26,7 +26,6 @@ type RevocationStatusResolver struct { func NewRevocationStatusResolver(credentialStatusSettings config.CredentialStatus) *RevocationStatusResolver { resolvers := make(map[verifiable.CredentialStatusType]revocationCredentialStatusResolver, resolversLength) resolvers[verifiable.Iden3ReverseSparseMerkleTreeProof] = &iden3ReverseSparseMerkleTreeProofResolver{} - resolvers[verifiable.SparseMerkleTreeProof] = &sparseMerkleTreeProofResolver{} resolvers[verifiable.Iden3commRevocationStatusV1] = &iden3CommRevocationStatusV1Resolver{} resolvers[verifiable.Iden3OnchainSparseMerkleTreeProof2023] = &iden3OnChainSparseMerkleTreeProof2023Resolver{} return &RevocationStatusResolver{ diff --git a/pkg/credentials/revocation_status/resolver_test.go b/pkg/credentials/revocation_status/resolver_test.go index 9779ac2ca..db5f49795 100644 --- a/pkg/credentials/revocation_status/resolver_test.go +++ b/pkg/credentials/revocation_status/resolver_test.go @@ -31,48 +31,6 @@ func TestRevocationStatusResolver_GetCredentialRevocationStatus(t *testing.T) { } for _, tc := range []testConfig{ - { - name: "SparseMerkleTreeProof for single issuer", - credentialStatusSettings: config.CredentialStatus{ - RHSMode: config.RHSMode("none"), - Iden3CommAgentStatus: config.Iden3CommAgentStatus{ - URL: "https://issuernode", - }, - SingleIssuer: true, - }, - credentialStatusType: verifiable.SparseMerkleTreeProof, - nonce: 12345, - issuerState: "issuer-state", - expected: expected{ - err: nil, - CredentialStatus: &verifiable.CredentialStatus{ - Type: verifiable.SparseMerkleTreeProof, - ID: "https://issuernode/v1/agent", - RevocationNonce: 12345, - }, - }, - }, - { - name: "SparseMerkleTreeProof for multiples issuers", - credentialStatusSettings: config.CredentialStatus{ - RHSMode: config.RHSMode("none"), - Iden3CommAgentStatus: config.Iden3CommAgentStatus{ - URL: "https://issuernode", - }, - SingleIssuer: false, - }, - credentialStatusType: verifiable.SparseMerkleTreeProof, - nonce: 12345, - issuerState: "issuer-state", - expected: expected{ - err: nil, - CredentialStatus: &verifiable.CredentialStatus{ - Type: verifiable.SparseMerkleTreeProof, - ID: "https://issuernode/v1/agent", - RevocationNonce: 12345, - }, - }, - }, { name: "Iden3ReverseSparseMerkleTreeProof for single issuer", credentialStatusSettings: config.CredentialStatus{ diff --git a/pkg/credentials/revocation_status/sparse_merkletree_proof_resolver.go b/pkg/credentials/revocation_status/sparse_merkletree_proof_resolver.go deleted file mode 100644 index 43a9b402c..000000000 --- a/pkg/credentials/revocation_status/sparse_merkletree_proof_resolver.go +++ /dev/null @@ -1,18 +0,0 @@ -package revocation_status - -import ( - "github.com/iden3/go-iden3-core/v2/w3c" - "github.com/iden3/go-schema-processor/v2/verifiable" - - "github.com/polygonid/sh-id-platform/internal/config" -) - -type sparseMerkleTreeProofResolver struct{} - -func (r *sparseMerkleTreeProofResolver) resolve(credentialStatusSettings config.CredentialStatus, _ w3c.DID, nonce uint64, _ string) *verifiable.CredentialStatus { - return &verifiable.CredentialStatus{ - ID: buildDirectRevocationURL(credentialStatusSettings.Iden3CommAgentStatus.GetURL()), - Type: verifiable.SparseMerkleTreeProof, - RevocationNonce: nonce, - } -} diff --git a/pkg/credentials/revocation_status/utils.go b/pkg/credentials/revocation_status/utils.go index 3dbf0b670..77b253fa1 100644 --- a/pkg/credentials/revocation_status/utils.go +++ b/pkg/credentials/revocation_status/utils.go @@ -14,10 +14,6 @@ func buildRHSRevocationURL(host, issuerState string) string { return fmt.Sprintf("%s/node?state=%s", host, issuerState) } -func buildDirectRevocationURL(host string) string { - return fmt.Sprintf("%s/v1/agent", host) -} - func buildIden3OnchainSMTProofURL(issuerDID w3c.DID, nonce uint64, contractAddress ethcommon.Address, chainID string, stateHex string) string { return fmt.Sprintf("%s/credentialStatus?revocationNonce=%v&contractAddress=%s:%s&state=%s", issuerDID.String(), nonce, chainID, contractAddress.Hex(), stateHex) } From e21f60e2f205fcde099ae1cb66acff0fd8956b3a Mon Sep 17 00:00:00 2001 From: vbasiuk Date: Mon, 3 Jun 2024 16:25:29 +0300 Subject: [PATCH 15/52] rm check 'root doesn't exist' for no-transit state contract --- pkg/protocol/verify.go | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/pkg/protocol/verify.go b/pkg/protocol/verify.go index 8325687f6..65757f7b6 100644 --- a/pkg/protocol/verify.go +++ b/pkg/protocol/verify.go @@ -46,9 +46,9 @@ func authV2CircuitStateVerification(contract *abi.State, pubsignals []string) er if err != nil { return err } - if (big.NewInt(0)).Cmp(globalStateInfo.CreatedAtTimestamp) == 0 { - return errors.Errorf("root %s doesn't exist in smart contract", globalState.String()) - } + // if (big.NewInt(0)).Cmp(globalStateInfo.CreatedAtTimestamp) == 0 { + // return errors.Errorf("root %s doesn't exist in smart contract", globalState.String()) + // } if globalState.Cmp(globalStateInfo.Root) != 0 { return errors.Errorf("invalid global state info in the smart contract, expected root %s, got %s", globalState.String(), globalStateInfo.Root.String()) } From b8c8ef25bae5c8542971ea8b103af14b727e0ae2 Mon Sep 17 00:00:00 2001 From: vbasiuk Date: Tue, 4 Jun 2024 14:11:54 +0300 Subject: [PATCH 16/52] remove comment --- pkg/protocol/verify.go | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) diff --git a/pkg/protocol/verify.go b/pkg/protocol/verify.go index 65757f7b6..0d617e11b 100644 --- a/pkg/protocol/verify.go +++ b/pkg/protocol/verify.go @@ -46,9 +46,7 @@ func authV2CircuitStateVerification(contract *abi.State, pubsignals []string) er if err != nil { return err } - // if (big.NewInt(0)).Cmp(globalStateInfo.CreatedAtTimestamp) == 0 { - // return errors.Errorf("root %s doesn't exist in smart contract", globalState.String()) - // } + if globalState.Cmp(globalStateInfo.Root) != 0 { return errors.Errorf("invalid global state info in the smart contract, expected root %s, got %s", globalState.String(), globalStateInfo.Root.String()) } From 73f24d045da1779323cd2b49be99d964e3af5779 Mon Sep 17 00:00:00 2001 From: yushihang Date: Tue, 4 Jun 2024 21:53:36 +0800 Subject: [PATCH 17/52] add separate error variable for setLink() (#642) * add separate error variable for setLink() * typo fix --- internal/core/services/link.go | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/internal/core/services/link.go b/internal/core/services/link.go index 76aaac6aa..5edaf3581 100644 --- a/internal/core/services/link.go +++ b/internal/core/services/link.go @@ -229,10 +229,10 @@ func (ls *Link) IssueClaim(ctx context.Context, sessionID string, issuerDID w3c. } if err := ls.validate(ctx, link); err != nil { - err := ls.sessionManager.SetLink(ctx, linkState.CredentialStateCacheKey(linkID.String(), sessionID), *linkState.NewStateError(err)) - if err != nil { - log.Error(ctx, "cannot set the sate", "err", err) - return err + setLinkError := ls.sessionManager.SetLink(ctx, linkState.CredentialStateCacheKey(linkID.String(), sessionID), *linkState.NewStateError(err)) + if setLinkError != nil { + log.Error(ctx, "cannot set the state", "err", setLinkError) + return setLinkError } return err From 2b9007c6d887d71815a32f435788e3e97eeb7297 Mon Sep 17 00:00:00 2001 From: yushihang Date: Tue, 4 Jun 2024 21:54:22 +0800 Subject: [PATCH 18/52] Added a possible missing return statement for handling errors in authClaim.GetCredentialStatus(). (#641) --- internal/core/services/claims.go | 1 + 1 file changed, 1 insertion(+) diff --git a/internal/core/services/claims.go b/internal/core/services/claims.go index 5ed45b479..c6d5819ae 100644 --- a/internal/core/services/claims.go +++ b/internal/core/services/claims.go @@ -230,6 +230,7 @@ func (c *claim) CreateCredential(ctx context.Context, req *ports.CreateClaimRequ authCs, err := authClaim.GetCredentialStatus() if err != nil { log.Error(ctx, "cannot get the auth claim credential status", "err", err) + return nil, err } proof.IssuerData.CredentialStatus = authCs From 043b42b441f067816fbbfcc25cf2943ec7b31e0b Mon Sep 17 00:00:00 2001 From: blech Date: Wed, 12 Jun 2024 16:24:11 +0200 Subject: [PATCH 19/52] add new branding --- README.md | 28 ++-- api/spec.html | 2 +- api_ui/spec.html | 2 +- k8s/helm/readme.md | 4 +- ui/README.md | 4 +- ui/index.html | 2 +- ui/package.json | 2 +- ui/public/favicon.png | Bin 2980 -> 1297 bytes ui/public/fonts/Matter-Regular.woff | Bin 0 -> 34052 bytes ui/public/fonts/Matter-Regular.woff2 | Bin 0 -> 31396 bytes ui/public/fonts/ModernEra-Regular.woff | Bin 35528 -> 0 bytes ui/public/fonts/ModernEra-Regular.woff2 | Bin 28632 -> 0 bytes ui/public/images/illustration-explainer.svg | 143 +++++++++--------- ui/src/assets/polygonid-logo.svg | 19 --- ui/src/assets/privado-id-logo.svg | 16 ++ .../connections/ConnectionsTable.tsx | 4 +- .../connections/CredentialsTable.tsx | 4 +- .../credentials/CredentialIssuedQR.tsx | 2 +- .../credentials/CredentialLinkQR.tsx | 2 +- .../credentials/CredentialsTable.tsx | 4 +- ui/src/components/credentials/LinksTable.tsx | 4 +- .../components/issuer-state/IssuerState.tsx | 4 +- ui/src/components/schemas/Schemas.tsx | 2 +- ui/src/components/schemas/SchemasTable.tsx | 4 +- ui/src/components/shared/LogoLink.tsx | 2 +- ui/src/components/shared/NoResults.tsx | 2 +- ui/src/styles/index.scss | 83 ++++++++-- ui/src/styles/theme.ts | 54 +++++-- ui/src/styles/variables.module.scss | 17 ++- 29 files changed, 251 insertions(+), 159 deletions(-) create mode 100644 ui/public/fonts/Matter-Regular.woff create mode 100644 ui/public/fonts/Matter-Regular.woff2 delete mode 100644 ui/public/fonts/ModernEra-Regular.woff delete mode 100644 ui/public/fonts/ModernEra-Regular.woff2 delete mode 100644 ui/src/assets/polygonid-logo.svg create mode 100644 ui/src/assets/privado-id-logo.svg diff --git a/README.md b/README.md index 6af4e115b..eaf80c7ab 100644 --- a/README.md +++ b/README.md @@ -1,9 +1,9 @@ -# Polygon ID Issuer Node +# Privado iD Issuer Node [![Checks](https://github.com/0xPolygonID/sh-id-platform/actions/workflows/checks.yml/badge.svg)](https://github.com/0xPolygonID/sh-id-platform/actions/workflows/checks.yml) [![golangci-lint](https://github.com/0xPolygonID/sh-id-platform/actions/workflows/golangci-lint.yml/badge.svg)](https://github.com/0xPolygonID/sh-id-platform/actions/workflows/golangci-lint.yml) -Streamline the **Verifiable Credentials issuance** process with the user-friendly API and UI of the Issuer Node within the Polygon ID ecosystem. The on-premise (self-hosted) Issuer Node, seamlessly integrated with a robust suite of tools including the mobile Wallet, Schema Builder, and Credential Marketplace, guarantees a frictionless experience for effortlessly issuing and verifying credentials. +Streamline the **Verifiable Credentials issuance** process with the user-friendly API and UI of the Issuer Node within the Privado iD ecosystem. The on-premise (self-hosted) Issuer Node, seamlessly integrated with a robust suite of tools including the mobile Wallet, Schema Builder, and Credential Marketplace, guarantees a frictionless experience for effortlessly issuing and verifying credentials. ![Triagle-of-trust](docs/assets/img/triangle-of-trust.png) @@ -21,14 +21,18 @@ Streamline the **Verifiable Credentials issuance** process with the user-friendl ## Table of Contents -- [Quick Start Installation](#quick-start-installation) - - [Prerequisites](#Prerequisites) - - [Issuer Node Api](#issuer-node-api) +- [Privado iD Issuer Node](#privado-id-issuer-node) + - [Table of Contents](#table-of-contents) + - [Quick Start Installation](#quick-start-installation) + - [Prerequisites](#prerequisites) + - [Issuer Node API](#issuer-node-api) + - [Deploy Issuer Node Infrastructure](#deploy-issuer-node-infrastructure) + - [Run Issuer Node API](#run-issuer-node-api) - [Issuer Node UI](#issuer-node-ui) -- [Quick Start Demo](#quick-start-demo) -- [Documentation](#documentation) -- [Tools](#tools) -- [License](#license) + - [Quick Start Demo](#quick-start-demo) + - [Documentation](#documentation) + - [Tools](#tools) + - [License](#license) ## Quick Start Installation > [!NOTE] @@ -215,7 +219,7 @@ This [Quick Start Demo](https://devs.polygonid.com/docs/quick-start-demo/) will ## Documentation * [Issuer Node resources](https://devs.polygonid.com/docs/category/issuer/) -* [Polygon ID core concepts](https://devs.polygonid.com/docs/introduction/) +* [Privado iD core concepts](https://devs.polygonid.com/docs/introduction/) ## Tools > [!WARNING] @@ -225,8 +229,8 @@ This [Quick Start Demo](https://devs.polygonid.com/docs/quick-start-demo/) will * [Schema Builder](https://schema-builder.polygonid.me/) - Create your custom schemas to issue VC. * [Demo Issuer UI](https://user-ui:password-ui@issuer-ui.polygonid.me/) - Test our Issuer Node UI. * [Verifier Demo](https://verifier-demo.polygonid.me/) - Verify your VCs. -* [Polygon ID Android Mobile App](https://play.google.com/store/apps/details?id=com.polygonid.wallet&hl=en&gl=US) -* [Polygon ID IOS Mobile App](https://apps.apple.com/us/app/polygon-id/id1629870183) +* [Privado iD Android Mobile App](https://play.google.com/store/apps/details?id=com.polygonid.wallet&hl=en&gl=US) +* [Privado iD IOS Mobile App](https://apps.apple.com/us/app/polygon-id/id1629870183) * [Marketplace](https://marketplace.polygonid.me/) - Explore credentials submitted by trusted issuers. ## License diff --git a/api/spec.html b/api/spec.html index fb8d694bd..f7930d28f 100644 --- a/api/spec.html +++ b/api/spec.html @@ -1,7 +1,7 @@ - Polygon ID - Self Hosted Issuer + Privado iD - Self Hosted Issuer diff --git a/api_ui/spec.html b/api_ui/spec.html index 3eb6d3aae..3a4e52203 100644 --- a/api_ui/spec.html +++ b/api_ui/spec.html @@ -1,7 +1,7 @@ - Polygon ID - Self Hosted Issuer - UI API + Privado iD - Self Hosted Issuer - UI API diff --git a/k8s/helm/readme.md b/k8s/helm/readme.md index ce69d44a6..e4acb5f33 100644 --- a/k8s/helm/readme.md +++ b/k8s/helm/readme.md @@ -1,7 +1,7 @@ # Overview -This is a helm chart for deploying Polygon ID issuer node on Kubernetes. -To learn more about Polygon ID issuer, see [this](https://0xpolygonid.github.io/tutorials/issuer/issuer-overview). +This is a helm chart for deploying Privado iD issuer node on Kubernetes. +To learn more about Privado iD issuer, see [this](https://0xpolygonid.github.io/tutorials/issuer/issuer-overview). ## Architecture diff --git a/ui/README.md b/ui/README.md index 8056ce521..dcd954767 100644 --- a/ui/README.md +++ b/ui/README.md @@ -1,6 +1,6 @@ -# Polygon ID Issuer Node UI +# Privado iD Issuer Node UI -The frontend application of the [Polygon ID Issuer Node](../README.md). +The frontend application of the [Privado iD Issuer Node](../README.md). ## Installation diff --git a/ui/index.html b/ui/index.html index 05e442157..935fb53e0 100644 --- a/ui/index.html +++ b/ui/index.html @@ -4,7 +4,7 @@ - Polygon ID Issuer UI + Privado iD Issuer UI diff --git a/ui/package.json b/ui/package.json index 8aca71d60..65949eb11 100644 --- a/ui/package.json +++ b/ui/package.json @@ -5,7 +5,7 @@ "ajv": "^8.12.0", "ajv-formats": "^2.1.1", "ajv-formats-draft2019": "^1.6.1", - "antd": "^5.11.1", + "antd": "^5.18.0", "axios": "^1.6.1", "copy-to-clipboard": "^3.3.3", "dayjs": "^1.11.10", diff --git a/ui/public/favicon.png b/ui/public/favicon.png index 0241e231dcf04f6aa201513be7c52367075c9496..3eef5e541b8bbd1704ce83b0c002bc9db334476f 100644 GIT binary patch delta 1284 zcmV+f1^fD>7m*4!iBL{Q4GJ0x0000DNk~Le0000;0000;2nGNE09Ea?M*si-32;bR za{vGf6951U69E94oEVWdAAbaPK~L0cY_>t_{;?%eQ|&s4H3Sd7tAz4j)pMvgpe$A^MCsF>fiM6-y&^!u8)S_+)CTWU(mY7>cSsY?;qUOPk+z9+D{!u2{OpT2PL}n z;X2*?>0aHr9ZJx9XGSAu^7?{D_m${M@LpVJ*Z!Aibc-I-{~5@d*LU)*Y%A%OGWf3!{}z_ot9_*WqE+NoQV6vhPM z!$#ru>OXY%mw*4rB=~Y#mAJSV5p+jo8Vzbx?yf%|(?CuVrO8+c(jkd&Is~Q3q$DGP z5Q=pe8Xce{F)7K2pdr;y(UFAoNn=Wqu`2fN$=4&L+m~=yt^|^PQytcJFeYfv`>)Wx zPj;xZoPX;yh_088#qWC=9cloS5IGpjGtPQgNU8-5j}ElG)SX&EXm_U1@1}N1rGFsEIecZWk-JDzCkWNblpN5#<%I+o zKa!)#i1#T)B^82Dr4Y*7iB?aerv+hjjwq$G5U5Mf2?~F^0WnFGm|Bbq(w*;(a;<(P zWN36Nz5K>NAO?5H;@+c9!3%QwP7=TPNeP}{$sRcxf_*-Ol(a&QhF}vE;R{+OM?QpC?N|6i1$qHrVv7=|v`Q*fs|{!>Go4j8X{1AcCW-^Yk+|~dYeG@${0PU4stUwA&&rF5SJZFySGyS0000 literal 2980 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 S02>1;5&!@I000310001%y`k9v diff --git a/ui/public/fonts/ModernEra-Regular.woff2 b/ui/public/fonts/ModernEra-Regular.woff2 deleted file mode 100644 index 2581de0e30c2e7299c2cede69b0108737d93f2b9..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 28632 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 diff --git a/ui/public/images/illustration-explainer.svg b/ui/public/images/illustration-explainer.svg index a0c1dee43..d71e0cb89 100644 --- a/ui/public/images/illustration-explainer.svg +++ b/ui/public/images/illustration-explainer.svg @@ -1,65 +1,70 @@ - - - - - - + + + + + + + - - - + + + - - - - - - - - - - - - - - - - - - - + + + + + + + + + + + + + + + + + + + - - - + + + - - - + + + - + - + - - - + + + - + + + + + - + - + @@ -70,49 +75,49 @@ - - - + + + - + - + - - - + + + - + - - - + + + - - - + + + - - - + + + - - - + + + - - - + + + - - - + + + diff --git a/ui/src/assets/polygonid-logo.svg b/ui/src/assets/polygonid-logo.svg deleted file mode 100644 index 6cee55d86..000000000 --- a/ui/src/assets/polygonid-logo.svg +++ /dev/null @@ -1,19 +0,0 @@ - - - - - - - - - - - - - - - - - - - diff --git a/ui/src/assets/privado-id-logo.svg b/ui/src/assets/privado-id-logo.svg new file mode 100644 index 000000000..54efa5e23 --- /dev/null +++ b/ui/src/assets/privado-id-logo.svg @@ -0,0 +1,16 @@ + + + + + + + + + + + + + + + + diff --git a/ui/src/components/connections/ConnectionsTable.tsx b/ui/src/components/connections/ConnectionsTable.tsx index 6eab513ea..5e6f0748c 100644 --- a/ui/src/components/connections/ConnectionsTable.tsx +++ b/ui/src/components/connections/ConnectionsTable.tsx @@ -264,7 +264,7 @@ export function ConnectionsTable() { - } size={48} /> + } size={48} /> No connections @@ -327,7 +327,7 @@ export function ConnectionsTable() { - {connectionsList.length} + {connectionsList.length} } diff --git a/ui/src/components/connections/CredentialsTable.tsx b/ui/src/components/connections/CredentialsTable.tsx index 6a1683707..d3e23060f 100644 --- a/ui/src/components/connections/CredentialsTable.tsx +++ b/ui/src/components/connections/CredentialsTable.tsx @@ -232,7 +232,7 @@ export function CredentialsTable({ userID }: { userID: string }) { - } size={48} /> + } size={48} /> No {credentialStatus !== "all" && credentialStatus} credentials issued @@ -279,7 +279,7 @@ export function CredentialsTable({ userID }: { userID: string }) { - {credentialsList.length} + {credentialsList.length} {showDefaultContent && credentialStatus === "all" ? ( diff --git a/ui/src/components/credentials/CredentialIssuedQR.tsx b/ui/src/components/credentials/CredentialIssuedQR.tsx index a6e4e142e..12e0955fb 100644 --- a/ui/src/components/credentials/CredentialIssuedQR.tsx +++ b/ui/src/components/credentials/CredentialIssuedQR.tsx @@ -71,7 +71,7 @@ export function CredentialIssuedQR() { qrCodeLink={issuedQRCodeLink.qrCode} qrCodeRaw={issuedQRCodeRaw.qrCode} schemaType={issuedQRCodeLink.schemaType} - subTitle="Scan the QR code with your Polygon ID wallet to add the credential." + subTitle="Scan the QR code with your Privado iD wallet to add the credential." /> ); } diff --git a/ui/src/components/credentials/CredentialLinkQR.tsx b/ui/src/components/credentials/CredentialLinkQR.tsx index 761654017..923b498c8 100644 --- a/ui/src/components/credentials/CredentialLinkQR.tsx +++ b/ui/src/components/credentials/CredentialLinkQR.tsx @@ -244,7 +244,7 @@ export function CredentialLinkQR() { schemaType={authQRCode.data.linkDetail.schemaType} subTitle={ <> - Scan the QR code with your Polygon ID wallet to accept it. + Scan the QR code with your Privado iD wallet to accept it.
{PUSH_NOTIFICATIONS_REMINDER} diff --git a/ui/src/components/credentials/CredentialsTable.tsx b/ui/src/components/credentials/CredentialsTable.tsx index 971b82447..f8446b38f 100644 --- a/ui/src/components/credentials/CredentialsTable.tsx +++ b/ui/src/components/credentials/CredentialsTable.tsx @@ -327,7 +327,7 @@ export function CredentialsTable() { - } size={48} /> + } size={48} /> No credentials @@ -395,7 +395,7 @@ export function CredentialsTable() { - {paginationTotal} + {paginationTotal} {(!showDefaultContent || credentialStatus !== "all") && ( diff --git a/ui/src/components/credentials/LinksTable.tsx b/ui/src/components/credentials/LinksTable.tsx index 1561180bb..c286e2674 100644 --- a/ui/src/components/credentials/LinksTable.tsx +++ b/ui/src/components/credentials/LinksTable.tsx @@ -334,7 +334,7 @@ export function LinksTable() { - } size={48} /> + } size={48} /> No links @@ -388,7 +388,7 @@ export function LinksTable() { - {linksList.length} + {linksList.length} {(!showDefaultContent || status !== undefined) && ( diff --git a/ui/src/components/issuer-state/IssuerState.tsx b/ui/src/components/issuer-state/IssuerState.tsx index b762117c9..cabb61b6a 100644 --- a/ui/src/components/issuer-state/IssuerState.tsx +++ b/ui/src/components/issuer-state/IssuerState.tsx @@ -228,7 +228,7 @@ export function IssuerState() { - } size={48} /> + } size={48} /> No transactions @@ -268,7 +268,7 @@ export function IssuerState() { - {transactionsList.length} + {transactionsList.length} } diff --git a/ui/src/components/schemas/Schemas.tsx b/ui/src/components/schemas/Schemas.tsx index 42e6e0083..f8b4b1d25 100644 --- a/ui/src/components/schemas/Schemas.tsx +++ b/ui/src/components/schemas/Schemas.tsx @@ -28,7 +28,7 @@ export function Schemas() { Explore a wide range of existing schemas or create custom schemas using
{" "} - Polygon ID's schema explorer and builder. + Privado iD's schema explorer and builder. )} diff --git a/ui/src/components/schemas/SchemasTable.tsx b/ui/src/components/schemas/SchemasTable.tsx index b27ad58e9..0bc4a5438 100644 --- a/ui/src/components/schemas/SchemasTable.tsx +++ b/ui/src/components/schemas/SchemasTable.tsx @@ -174,7 +174,7 @@ export function SchemasTable() { - } size={48} /> + } size={48} /> No schemas @@ -224,7 +224,7 @@ export function SchemasTable() { - {schemaList.length} + {schemaList.length} } diff --git a/ui/src/components/shared/LogoLink.tsx b/ui/src/components/shared/LogoLink.tsx index 679638f72..e5edebf5e 100644 --- a/ui/src/components/shared/LogoLink.tsx +++ b/ui/src/components/shared/LogoLink.tsx @@ -1,6 +1,6 @@ import { Link } from "react-router-dom"; -import IconLogo from "src/assets/polygonid-logo.svg?react"; +import IconLogo from "src/assets/privado-id-logo.svg?react"; import { ROOT_PATH } from "src/utils/constants"; export function LogoLink() { diff --git a/ui/src/components/shared/NoResults.tsx b/ui/src/components/shared/NoResults.tsx index 5c7389f77..ed7092d00 100644 --- a/ui/src/components/shared/NoResults.tsx +++ b/ui/src/components/shared/NoResults.tsx @@ -5,7 +5,7 @@ import SearchIcon from "src/assets/icons/search-lg.svg?react"; export function NoResults({ searchQuery }: { searchQuery: string | null }) { return ( - } size={48} /> + } size={48} /> No results found diff --git a/ui/src/styles/index.scss b/ui/src/styles/index.scss index 788cb098b..36edb56da 100644 --- a/ui/src/styles/index.scss +++ b/ui/src/styles/index.scss @@ -1,13 +1,13 @@ @import "variables.module"; @font-face { - font-family: ModernEra-Regular; + font-family: Matter-Regular; font-style: normal; font-weight: normal; src: - local("ModernEra-Regular"), - url("/fonts/ModernEra-Regular.woff2") format("woff2"), - url("/fonts/ModernEra-Regular.woff") format("woff"); + local("Matter-Regular"), + url("/fonts/Matter-Regular.woff2") format("woff2"), + url("/fonts/Matter-Regular.woff") format("woff"); } /* OVERRIDES */ @@ -80,8 +80,8 @@ } &.selected { - border: 1px solid $primary-color; - background: $bg-light; + border: 1px solid $selected-color; + background: $success-bg; } .ant-card-type-inner { @@ -115,12 +115,12 @@ } } -.avatar-color-cyan { - background-color: $cyan-bg; - color: $cyan-color; +.avatar-color-icon { + background-color: $icon-bg; + color: $icon-color; path { - stroke: $cyan-color; + stroke: $icon-color; } } @@ -252,8 +252,10 @@ } .ant-tag { - font-weight: bold; - padding-top: 2px; + padding: 2px 10px; + border-radius: 16px; + border: 0; + background-color: $tag-bg; &.ant-tag-success { background-color: $tag-bg-success; @@ -281,6 +283,63 @@ padding-inline-end: 24px; } +.ant-btn-primary { + border: 1px solid #54db06; + + &:not(:disabled .ant-btn-disable) { + &:hover { + color: $text-color; + } + + &:active { + border: 1px solid #74f526; + color: $text-color; + background: $primary-color; + box-shadow: 0 0 0 4px #dfffc7; + } + } +} + +.ant-radio-wrapper .ant-radio-checked .ant-radio-inner { + background-color: $success-bg; + border-color: $selected-color; +} + +.ant-radio-wrapper .ant-radio-checked .ant-radio-inner::after { + background-color: $selected-color; +} + +.ant-checkbox-wrapper { + .ant-checkbox-checked .ant-checkbox-inner { + border-color: $selected-color; + } + + &:not(.ant-checkbox:not(.ant-checkbox-wrapper-disabled)):hover .ant-checkbox-inner { + border-color: $selected-color; + } +} + +.ant-checkbox:not(.ant-checkbox-disabled):hover .ant-checkbox-inner { + border-color: $selected-color; +} + +.ant-input-number-outlined:hover { + border-color: $selected-color; +} + +.ant-input-number .ant-input-number-handler:hover { + .ant-input-number-handler-up-inner { + color: $selected-color; + } + .ant-input-number-handler-down-inner { + color: $selected-color; + } +} + +.ant-typography.ant-typography-secondary { + color: $text-color-secondary; +} + /* CUSTOM */ .background-grey { diff --git a/ui/src/styles/theme.ts b/ui/src/styles/theme.ts index db5d7e59d..6f846a064 100644 --- a/ui/src/styles/theme.ts +++ b/ui/src/styles/theme.ts @@ -8,13 +8,14 @@ type StyleVariables = { avatarBg: string; bgLight: string; borderColor: string; - cyanBg: string; - cyanColor: string; dividerColor: string; errorBg: string; errorColor: string; + iconBg: string; + iconColor: string; primaryBg: string; primaryColor: string; + successBg: string; successColor: string; tagBg: string; tagBgSuccess: string; @@ -29,13 +30,14 @@ const parsedStyleVariables = getStrictParser()( avatarBg: z.string(), bgLight: z.string(), borderColor: z.string(), - cyanBg: z.string(), - cyanColor: z.string(), dividerColor: z.string(), errorBg: z.string(), errorColor: z.string(), + iconBg: z.string(), + iconColor: z.string(), primaryBg: z.string(), primaryColor: z.string(), + successBg: z.string(), successColor: z.string(), tagBg: z.string(), tagBgSuccess: z.string(), @@ -48,8 +50,10 @@ const parsedStyleVariables = getStrictParser()( const { avatarBg, + borderColor, errorColor, primaryColor, + successBg, successColor, tagBg, tagColor, @@ -61,22 +65,41 @@ const { export const theme: ThemeConfig = { components: { Avatar: { colorBgBase: avatarBg }, - Button: { controlHeight: 40, paddingContentHorizontal: 16 }, - Card: { fontWeightStrong: 500 }, - Checkbox: { borderRadius: 6, size: 20 }, + Button: { + colorBgContainerDisabled: successBg, + colorPrimaryBg: primaryColor, + colorPrimaryHover: "#74F526", + controlHeight: 40, + defaultHoverBorderColor: successColor, + defaultHoverColor: successColor, + paddingContentHorizontal: 16, + primaryColor: textColor, + }, + Card: { + colorBgBase: successColor, + fontWeightStrong: 500, + }, + Checkbox: { borderRadius: 6, colorPrimary: successBg, colorWhite: "#3AB000", size: 20 }, DatePicker: { controlHeight: 40 }, Form: { fontSize: 14 }, Input: { controlHeight: 40 }, InputNumber: { controlHeight: 40 }, Layout: { bodyBg: "white", headerBg: "white", siderBg: "white" }, Menu: { + colorBgBase: "transparent", + horizontalItemSelectedColor: successColor, + itemActiveBg: "transparent", + itemBg: "transparent", + itemColor: textColorSecondary, itemHoverBg: "white", - itemHoverColor: primaryColor, + itemHoverColor: successColor, + itemSelectedBg: successBg, + itemSelectedColor: successColor, subMenuItemBg: "white", }, Message: { fontSize: 18 }, Radio: { controlHeight: 40, size: 20 }, - Select: { controlHeight: 40 }, + Select: { colorBorder: successColor, controlHeight: 40 }, Table: { fontSize: 14, fontWeightStrong: 400 }, Tag: { colorBgBase: tagBg, @@ -84,21 +107,24 @@ export const theme: ThemeConfig = { }, Typography: { colorWarning: textColorWarning, + fontSize: 14, }, }, token: { borderRadius: 8, colorError: errorColor, - colorInfo: primaryColor, - colorLink: primaryColor, - colorLinkActive: primaryColor, - colorLinkHover: primaryColor, + colorInfo: tagColor, + colorInfoBorder: borderColor, + colorLink: successColor, + colorLinkActive: successColor, + colorLinkHover: successColor, colorPrimary: primaryColor, + colorPrimaryText: textColor, colorSuccess: successColor, colorText: textColor, colorTextLabel: tagColor, colorTextSecondary: textColorSecondary, - fontFamily: "ModernEra-Regular", + fontFamily: "Matter-Regular", fontSize: 16, fontSizeHeading2: 32, fontSizeSM: 14, diff --git a/ui/src/styles/variables.module.scss b/ui/src/styles/variables.module.scss index bab776b0e..66ded2dd5 100644 --- a/ui/src/styles/variables.module.scss +++ b/ui/src/styles/variables.module.scss @@ -1,28 +1,29 @@ $avatar-bg: #2c374e; $bg-light: #f9fafb; $border-color: #d0d5dd; -$cyan-bg: #cff9fe; -$cyan-color: #088ab2; +$icon-bg: #f2f4f7; +$icon-color: #475467; $divider-color: #eaecf0; $error-bg: #fecfcf; $error-color: #b20808; $primary-bg: #f4ebff; -$primary-color: #7f56d9; -$success-bg: #d1fadf; -$success-color: #027a48; +$primary-color: #9afe5b; +$success-bg: #f1ffe5; +$success-color: #2f8507; $tag-bg: #f2f4f7; $tag-bg-success: #ecfdf3; $tag-color: #344054; -$text-color: #101828; +$text-color: #131313; $text-color-secondary: #667085; $text-color-warning: #b54708; +$selected-color: #3ab000; :export { avatarBg: $avatar-bg; bgLight: $bg-light; borderColor: $border-color; - cyanBg: $cyan-bg; - cyanColor: $cyan-color; + iconBg: $icon-bg; + iconColor: $icon-color; dividerColor: $divider-color; errorBg: $error-bg; errorColor: $error-color; From 9e1d24f48ec260fbd2fb5e97fe92ee08f54f2728 Mon Sep 17 00:00:00 2001 From: blech Date: Wed, 12 Jun 2024 16:39:10 +0200 Subject: [PATCH 20/52] add checkbox style --- ui/src/styles/theme.ts | 13 ++++++++++++- 1 file changed, 12 insertions(+), 1 deletion(-) diff --git a/ui/src/styles/theme.ts b/ui/src/styles/theme.ts index 6f846a064..a4fe0af00 100644 --- a/ui/src/styles/theme.ts +++ b/ui/src/styles/theme.ts @@ -50,6 +50,7 @@ const parsedStyleVariables = getStrictParser()( const { avatarBg, + bgLight, borderColor, errorColor, primaryColor, @@ -98,9 +99,19 @@ export const theme: ThemeConfig = { subMenuItemBg: "white", }, Message: { fontSize: 18 }, - Radio: { controlHeight: 40, size: 20 }, + Radio: { + buttonCheckedBg: bgLight, + colorPrimary: successColor, + colorPrimaryHover: successColor, + controlHeight: 40, + size: 20, + }, Select: { colorBorder: successColor, controlHeight: 40 }, Table: { fontSize: 14, fontWeightStrong: 400 }, + Tabs: { + colorPrimary: successColor, + itemHoverColor: successColor, + }, Tag: { colorBgBase: tagBg, colorTextBase: tagColor, From 96362b7dd78a56ab1dc98508014cfc8dad3bec5b Mon Sep 17 00:00:00 2001 From: blech Date: Thu, 13 Jun 2024 13:30:52 +0200 Subject: [PATCH 21/52] change brand name to capital I --- README.md | 12 ++-- api/spec.html | 2 +- api_ui/spec.html | 2 +- k8s/helm/readme.md | 4 +- ui/README.md | 4 +- ui/index.html | 2 +- ui/playwright-report/index.html | 69 +++++++++++++++++++ .../credentials/CredentialIssuedQR.tsx | 2 +- ui/src/components/schemas/Schemas.tsx | 2 +- 9 files changed, 84 insertions(+), 15 deletions(-) create mode 100644 ui/playwright-report/index.html diff --git a/README.md b/README.md index eaf80c7ab..ba453d12e 100644 --- a/README.md +++ b/README.md @@ -1,9 +1,9 @@ -# Privado iD Issuer Node +# Privado ID Issuer Node [![Checks](https://github.com/0xPolygonID/sh-id-platform/actions/workflows/checks.yml/badge.svg)](https://github.com/0xPolygonID/sh-id-platform/actions/workflows/checks.yml) [![golangci-lint](https://github.com/0xPolygonID/sh-id-platform/actions/workflows/golangci-lint.yml/badge.svg)](https://github.com/0xPolygonID/sh-id-platform/actions/workflows/golangci-lint.yml) -Streamline the **Verifiable Credentials issuance** process with the user-friendly API and UI of the Issuer Node within the Privado iD ecosystem. The on-premise (self-hosted) Issuer Node, seamlessly integrated with a robust suite of tools including the mobile Wallet, Schema Builder, and Credential Marketplace, guarantees a frictionless experience for effortlessly issuing and verifying credentials. +Streamline the **Verifiable Credentials issuance** process with the user-friendly API and UI of the Issuer Node within the Privado ID ecosystem. The on-premise (self-hosted) Issuer Node, seamlessly integrated with a robust suite of tools including the mobile Wallet, Schema Builder, and Credential Marketplace, guarantees a frictionless experience for effortlessly issuing and verifying credentials. ![Triagle-of-trust](docs/assets/img/triangle-of-trust.png) @@ -21,7 +21,7 @@ Streamline the **Verifiable Credentials issuance** process with the user-friendl ## Table of Contents -- [Privado iD Issuer Node](#privado-id-issuer-node) +- [Privado ID Issuer Node](#privado-id-issuer-node) - [Table of Contents](#table-of-contents) - [Quick Start Installation](#quick-start-installation) - [Prerequisites](#prerequisites) @@ -219,7 +219,7 @@ This [Quick Start Demo](https://devs.polygonid.com/docs/quick-start-demo/) will ## Documentation * [Issuer Node resources](https://devs.polygonid.com/docs/category/issuer/) -* [Privado iD core concepts](https://devs.polygonid.com/docs/introduction/) +* [Privado ID core concepts](https://devs.polygonid.com/docs/introduction/) ## Tools > [!WARNING] @@ -229,8 +229,8 @@ This [Quick Start Demo](https://devs.polygonid.com/docs/quick-start-demo/) will * [Schema Builder](https://schema-builder.polygonid.me/) - Create your custom schemas to issue VC. * [Demo Issuer UI](https://user-ui:password-ui@issuer-ui.polygonid.me/) - Test our Issuer Node UI. * [Verifier Demo](https://verifier-demo.polygonid.me/) - Verify your VCs. -* [Privado iD Android Mobile App](https://play.google.com/store/apps/details?id=com.polygonid.wallet&hl=en&gl=US) -* [Privado iD IOS Mobile App](https://apps.apple.com/us/app/polygon-id/id1629870183) +* [Poylgon ID Android Mobile App](https://play.google.com/store/apps/details?id=com.polygonid.wallet&hl=en&gl=US) +* [Polygon ID IOS Mobile App](https://apps.apple.com/us/app/polygon-id/id1629870183) * [Marketplace](https://marketplace.polygonid.me/) - Explore credentials submitted by trusted issuers. ## License diff --git a/api/spec.html b/api/spec.html index f7930d28f..d6b5d0a5e 100644 --- a/api/spec.html +++ b/api/spec.html @@ -1,7 +1,7 @@ - Privado iD - Self Hosted Issuer + Privado ID - Self Hosted Issuer diff --git a/api_ui/spec.html b/api_ui/spec.html index 3a4e52203..94a626d40 100644 --- a/api_ui/spec.html +++ b/api_ui/spec.html @@ -1,7 +1,7 @@ - Privado iD - Self Hosted Issuer - UI API + Privado ID - Self Hosted Issuer - UI API diff --git a/k8s/helm/readme.md b/k8s/helm/readme.md index e4acb5f33..748abd3cb 100644 --- a/k8s/helm/readme.md +++ b/k8s/helm/readme.md @@ -1,7 +1,7 @@ # Overview -This is a helm chart for deploying Privado iD issuer node on Kubernetes. -To learn more about Privado iD issuer, see [this](https://0xpolygonid.github.io/tutorials/issuer/issuer-overview). +This is a helm chart for deploying Privado ID issuer node on Kubernetes. +To learn more about Privado ID issuer, see [this](https://0xpolygonid.github.io/tutorials/issuer/issuer-overview). ## Architecture diff --git a/ui/README.md b/ui/README.md index dcd954767..f3ad6da4f 100644 --- a/ui/README.md +++ b/ui/README.md @@ -1,6 +1,6 @@ -# Privado iD Issuer Node UI +# Privado ID Issuer Node UI -The frontend application of the [Privado iD Issuer Node](../README.md). +The frontend application of the [Privado ID Issuer Node](../README.md). ## Installation diff --git a/ui/index.html b/ui/index.html index 935fb53e0..4074b1e6d 100644 --- a/ui/index.html +++ b/ui/index.html @@ -4,7 +4,7 @@ - Privado iD Issuer UI + Privado ID Issuer UI diff --git a/ui/playwright-report/index.html b/ui/playwright-report/index.html new file mode 100644 index 000000000..cf3961c19 --- /dev/null +++ b/ui/playwright-report/index.html @@ -0,0 +1,69 @@ + + + + + + + + + Playwright Test Report + + + + +
+ + + + \ No newline at end of file diff --git a/ui/src/components/credentials/CredentialIssuedQR.tsx b/ui/src/components/credentials/CredentialIssuedQR.tsx index 12e0955fb..a6e4e142e 100644 --- a/ui/src/components/credentials/CredentialIssuedQR.tsx +++ b/ui/src/components/credentials/CredentialIssuedQR.tsx @@ -71,7 +71,7 @@ export function CredentialIssuedQR() { qrCodeLink={issuedQRCodeLink.qrCode} qrCodeRaw={issuedQRCodeRaw.qrCode} schemaType={issuedQRCodeLink.schemaType} - subTitle="Scan the QR code with your Privado iD wallet to add the credential." + subTitle="Scan the QR code with your Polygon ID wallet to add the credential." /> ); } diff --git a/ui/src/components/schemas/Schemas.tsx b/ui/src/components/schemas/Schemas.tsx index f8b4b1d25..53965d291 100644 --- a/ui/src/components/schemas/Schemas.tsx +++ b/ui/src/components/schemas/Schemas.tsx @@ -28,7 +28,7 @@ export function Schemas() { Explore a wide range of existing schemas or create custom schemas using {" "} - Privado iD's schema explorer and builder. + Privado ID's schema explorer and builder. )} From 95055086ef29fe349f3ca5b539221282d1a79e2b Mon Sep 17 00:00:00 2001 From: blech Date: Thu, 13 Jun 2024 14:02:01 +0200 Subject: [PATCH 22/52] use current wallet name --- ui/src/components/credentials/CredentialLinkQR.tsx | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/ui/src/components/credentials/CredentialLinkQR.tsx b/ui/src/components/credentials/CredentialLinkQR.tsx index 923b498c8..761654017 100644 --- a/ui/src/components/credentials/CredentialLinkQR.tsx +++ b/ui/src/components/credentials/CredentialLinkQR.tsx @@ -244,7 +244,7 @@ export function CredentialLinkQR() { schemaType={authQRCode.data.linkDetail.schemaType} subTitle={ <> - Scan the QR code with your Privado iD wallet to accept it. + Scan the QR code with your Polygon ID wallet to accept it.
{PUSH_NOTIFICATIONS_REMINDER} From 83481a66497c79ee1842412e6e40c231c000e470 Mon Sep 17 00:00:00 2001 From: Martin Saporiti Date: Fri, 14 Jun 2024 12:14:21 -0300 Subject: [PATCH 23/52] chore: add deploy to demo --- .github/workflows/demo_deploy_backend.yml | 70 +++++++++++++++++++++++ .github/workflows/demo_deploy_ui.yml | 61 ++++++++++++++++++++ 2 files changed, 131 insertions(+) create mode 100644 .github/workflows/demo_deploy_backend.yml create mode 100644 .github/workflows/demo_deploy_ui.yml diff --git a/.github/workflows/demo_deploy_backend.yml b/.github/workflows/demo_deploy_backend.yml new file mode 100644 index 000000000..266c8fe43 --- /dev/null +++ b/.github/workflows/demo_deploy_backend.yml @@ -0,0 +1,70 @@ +name: Deploy Issuer Node Backend to Testing AWS Environment + +on: + workflow_run: + workflows: ["Checks"] + branches: ["main"] + types: + - completed + +env: + AWS_ACCOUNT_ID: ${{ secrets.TEST_AWS_ACCOUNT_ID }} + AWS_DEFAULT_REGION: ${{ secrets.AWS_REGION }} + ECR_REPOSITORY: issuer_node_backend_demo + +jobs: + build-backend: + name: Build and push latest image to AWS Testing Environment + permissions: + id-token: write + contents: write + if: ${{ github.event.workflow_run.conclusion == 'success' }} + runs-on: ubuntu-latest + + steps: + - name: Checkout code + uses: actions/checkout@v3 + - uses: actions/setup-go@v3 + with: + go-version: "1.20" + - uses: actions/cache@v3 + with: + path: | + ~/go/pkg/mod + ~/.cache/go-build + key: ${{ runner.os }}-go-${{ hashFiles('**/go.sum') }} + restore-keys: | + ${{ runner.os }}-go- + + - name: Create .env-api + run: | + touch .env-api + + - run: make build/docker + + - name: Configure AWS credentials + uses: aws-actions/configure-aws-credentials@v1-node16 + with: + aws-region: ${{ env.AWS_DEFAULT_REGION }} + role-to-assume: arn:aws:iam::${{ env.AWS_ACCOUNT_ID }}:role/PolygonIDActionsRole + role-session-name: GitHubActionsSession + + - name: Login to Amazon ECR + uses: aws-actions/amazon-ecr-login@v1 + id: login-ecr + + - name: Get version + run: echo "::set-output name=VERSION::$(git rev-parse --short HEAD)" + id: version + + - name: Tag and push image + env: + ECR_REGISTRY: ${{ steps.login-ecr.outputs.registry }} + ECR_REPOSITORY: ${{ env.ECR_REPOSITORY }} + IMAGE_TAG: ${{ steps.version.outputs.VERSION }} + run: | + docker tag issuer/api:${{ env.IMAGE_TAG }} ${{ env.ECR_REGISTRY }}/${{ env.ECR_REPOSITORY }}:${{ env.IMAGE_TAG }} + docker push ${{ env.ECR_REGISTRY }}/${{ env.ECR_REPOSITORY }}:${{ env.IMAGE_TAG }} + + docker tag issuer/api:${{ env.IMAGE_TAG }} ${{ env.ECR_REGISTRY }}/${{ env.ECR_REPOSITORY }}:latest + docker push ${{ env.ECR_REGISTRY }}/${{ env.ECR_REPOSITORY }}:latest \ No newline at end of file diff --git a/.github/workflows/demo_deploy_ui.yml b/.github/workflows/demo_deploy_ui.yml new file mode 100644 index 000000000..72ae3a331 --- /dev/null +++ b/.github/workflows/demo_deploy_ui.yml @@ -0,0 +1,61 @@ +name: Deploy Issuer Node UI to Testing AWS Environment + +on: + push: + branches: + - main + +env: + AWS_ACCOUNT_ID: ${{ secrets.TEST_AWS_ACCOUNT_ID }} + AWS_DEFAULT_REGION: ${{ secrets.AWS_REGION }} + ECR_REPOSITORY: issuer_node_ui_demo + +jobs: + deploy: + name: Build and Deploy UI to Testing AWS Environment + runs-on: ubuntu-latest + permissions: + id-token: write + contents: write + steps: + - name: Checkout + uses: actions/checkout@v2 + + - uses: actions/setup-node@v2 + with: + node-version: 16 + + - name: Configure AWS credentials + uses: aws-actions/configure-aws-credentials@v1-node16 + with: + aws-region: ${{ env.AWS_DEFAULT_REGION }} + role-to-assume: arn:aws:iam::${{ env.AWS_ACCOUNT_ID }}:role/PolygonIDActionsRole + role-session-name: GitHubActionsSession + + - name: Login to Amazon ECR + uses: aws-actions/amazon-ecr-login@v1 + id: login-ecr + + - name: Get version + run: echo "::set-output name=VERSION::$(git rev-parse --short HEAD)" + id: version + + - name: build ui docker image + working-directory: ./ui + env: + IMAGE_TAG: ${{ steps.version.outputs.VERSION }} + run: | + docker build -t polygonid/issuernode_ui:${{ env.IMAGE_TAG }} . + + + - name: Tag and push image + env: + ECR_REGISTRY: ${{ steps.login-ecr.outputs.registry }} + ECR_REPOSITORY: ${{ env.ECR_REPOSITORY }} + IMAGE_TAG: ${{ steps.version.outputs.VERSION }} + run: | + docker tag polygonid/issuernode_ui:${{ env.IMAGE_TAG }} ${{ env.ECR_REGISTRY }}/${{ env.ECR_REPOSITORY }}:${{ env.IMAGE_TAG }} + docker push ${{ env.ECR_REGISTRY }}/${{ env.ECR_REPOSITORY }}:${{ env.IMAGE_TAG }} + + docker tag polygonid/issuernode_ui:${{ env.IMAGE_TAG }} ${{ env.ECR_REGISTRY }}/${{ env.ECR_REPOSITORY }}:latest + docker push ${{ env.ECR_REGISTRY }}/${{ env.ECR_REPOSITORY }}:latest \ No newline at end of file From 2daa50edc044c28002aaa7daa886b757e14f073a Mon Sep 17 00:00:00 2001 From: Martin Saporiti Date: Fri, 14 Jun 2024 16:58:17 -0300 Subject: [PATCH 24/52] chore: add ui insecure option --- .env-ui.sample | 1 + ui/deployment/nginx_insecure.conf | 58 +++++++++++++++++++++++++++++++ ui/scripts/deploy.sh | 13 +++++-- 3 files changed, 69 insertions(+), 3 deletions(-) create mode 100644 ui/deployment/nginx_insecure.conf diff --git a/.env-ui.sample b/.env-ui.sample index 6f6e4f30e..804fc1bdf 100644 --- a/.env-ui.sample +++ b/.env-ui.sample @@ -5,3 +5,4 @@ ISSUER_UI_BUILD_TAG= ISSUER_UI_WARNING_MESSAGE= ISSUER_UI_IPFS_GATEWAY_URL=https://ipfs.io ISSUER_UI_SCHEMA_EXPLORER_AND_BUILDER_URL=https://schema-builder.polygonid.me +ISSUER_UI_INSECURE=false \ No newline at end of file diff --git a/ui/deployment/nginx_insecure.conf b/ui/deployment/nginx_insecure.conf new file mode 100644 index 000000000..764842d1b --- /dev/null +++ b/ui/deployment/nginx_insecure.conf @@ -0,0 +1,58 @@ +server { + listen 80; + server_name localhost; + + location /health { + access_log off; + add_header 'Content-Type' 'application/json'; + return 200 '{"status":"ok"}'; + } + + location ~* "^/credentials/scan-(issued|link)/[0-9a-f]{8}\b-[0-9a-f]{4}\b-[0-9a-f]{4}\b-[0-9a-f]{4}\b-[0-9a-f]{12}" { + auth_basic "off"; + root /usr/share/nginx/html; + index index.html; + try_files $uri /index.html =404; + include uwsgi_params; + } + + location /assets { + auth_basic "off"; + root /usr/share/nginx/html; + try_files $uri /index.html =404; + include uwsgi_params; + } + + location /favicon.png { + auth_basic "off"; + root /usr/share/nginx/html; + try_files $uri /index.html =404; + include uwsgi_params; + } + + location /images { + auth_basic "off"; + root /usr/share/nginx/html; + try_files $uri /index.html =404; + include uwsgi_params; + } + + location /fonts { + auth_basic "off"; + root /usr/share/nginx/html; + try_files $uri /index.html =404; + include uwsgi_params; + } + + location / { + root /usr/share/nginx/html; + index index.html; + # Redirect all requests to index.html + try_files $uri /index.html =404; + } + + error_page 500 502 503 504 /50x.html; + location = /50x.html { + root /usr/share/nginx/html; + } +} diff --git a/ui/scripts/deploy.sh b/ui/scripts/deploy.sh index ab81d01e7..28c30de12 100755 --- a/ui/scripts/deploy.sh +++ b/ui/scripts/deploy.sh @@ -21,11 +21,18 @@ echo "VITE_SCHEMA_EXPLORER_AND_BUILDER_URL=$ISSUER_UI_SCHEMA_EXPLORER_AND_BUILDE cd /app && npm run build # Copy nginx config -cp deployment/nginx.conf /etc/nginx/conf.d/default.conf echo $ISSUER_UI_AUTH_USERNAME echo $ISSUER_UI_AUTH_PASSWORD -htpasswd -c -b /etc/nginx/.htpasswd $ISSUER_UI_AUTH_USERNAME $ISSUER_UI_AUTH_PASSWORD -cat /etc/nginx/.htpasswd + +# shellcheck disable=SC2039 +if [ "${ISSUER_UI_INSECURE}" == "true" ]; then + cp deployment/nginx_insecure.conf /etc/nginx/conf.d/default.conf +else + cp deployment/nginx.conf /etc/nginx/conf.d/default.conf + htpasswd -c -b /etc/nginx/.htpasswd $ISSUER_UI_AUTH_USERNAME $ISSUER_UI_AUTH_PASSWORD + cat /etc/nginx/.htpasswd +fi + # Copy app dist cp -r /app/dist/. /usr/share/nginx/html From b756599f253c1594e3992f09b96269f73adf3cae Mon Sep 17 00:00:00 2001 From: Ilya Date: Mon, 17 Jun 2024 12:40:33 +0300 Subject: [PATCH 25/52] enable/disable auto publishing to onchain rhs; validate agent message media type --- Makefile | 4 + cmd/issuer_initializer/main.go | 2 +- cmd/notifications/main.go | 4 +- cmd/pending_publisher/main.go | 4 +- cmd/platform/main.go | 4 +- cmd/platform_ui/main.go | 4 +- internal/api/main_test.go | 2 + internal/api/server.go | 4 +- internal/api/server_test.go | 32 ++-- internal/api_ui/main_test.go | 2 + internal/api_ui/server.go | 4 +- internal/api_ui/server_test.go | 90 +++++------ internal/config/config.go | 10 +- internal/config/credential_status.go | 2 +- internal/core/ports/claims_service.go | 3 +- internal/core/ports/mediatype_manager.go | 8 + internal/core/services/claims.go | 13 +- internal/core/services/identity.go | 98 +++++++----- internal/core/services/mediatype_manager.go | 48 ++++++ .../core/services/mediatype_manager_test.go | 145 ++++++++++++++++++ internal/core/services/tests/identity_test.go | 6 +- internal/core/services/tests/link_test.go | 4 +- internal/core/services/tests/main_test.go | 2 + .../core/services/tests/notification_test.go | 4 +- 24 files changed, 372 insertions(+), 127 deletions(-) create mode 100644 internal/core/ports/mediatype_manager.go create mode 100644 internal/core/services/mediatype_manager.go create mode 100644 internal/core/services/mediatype_manager_test.go diff --git a/Makefile b/Makefile index 53fcf8544..16125dbe7 100644 --- a/Makefile +++ b/Makefile @@ -142,6 +142,10 @@ db/migrate: $(BIN)/install-goose $(BIN)/godotenv $(BIN)/platformid-migrate ## In lint: $(BIN)/golangci-lint $(BIN)/golangci-lint run +.PHONY: lint-fix +lint-fix: $(BIN)/golangci-lint + $(BIN)/golangci-lint run --fix + # usage: make private_key=xxx add-private-key .PHONY: add-private-key add-private-key: diff --git a/cmd/issuer_initializer/main.go b/cmd/issuer_initializer/main.go index 6ca778004..53dbe12fb 100644 --- a/cmd/issuer_initializer/main.go +++ b/cmd/issuer_initializer/main.go @@ -147,7 +147,7 @@ func main() { rhsFactory := reverse_hash.NewFactory(cfg.CredentialStatus.RHS.GetURL(), ethConn, common.HexToAddress(cfg.CredentialStatus.OnchainTreeStore.SupportedTreeStoreContract), reverse_hash.DefaultRHSTimeOut) revocationStatusResolver := revocation_status.NewRevocationStatusResolver(cfg.CredentialStatus) cfg.CredentialStatus.SingleIssuer = true - identityService := services.NewIdentity(keyStore, identityRepository, mtRepository, identityStateRepository, mtService, nil, claimsRepository, nil, nil, storage, nil, nil, nil, cfg.CredentialStatus, rhsFactory, revocationStatusResolver) + identityService := services.NewIdentity(keyStore, identityRepository, mtRepository, identityStateRepository, mtService, nil, claimsRepository, nil, nil, storage, nil, nil, nil, cfg.CredentialStatus, rhsFactory, revocationStatusResolver, *cfg.AutoPublishingToOnChainRHS) didCreationOptions := &ports.DIDCreationOptions{ Method: core.DIDMethod(cfg.APIUI.IdentityMethod), diff --git a/cmd/notifications/main.go b/cmd/notifications/main.go index b235ba5a7..693935351 100644 --- a/cmd/notifications/main.go +++ b/cmd/notifications/main.go @@ -179,8 +179,8 @@ func newCredentialsService(ctx context.Context, cfg *config.Configuration, stora mtService := services.NewIdentityMerkleTrees(mtRepository) qrService := services.NewQrStoreService(cachex) - identityService := services.NewIdentity(keyStore, identityRepository, mtRepository, identityStateRepository, mtService, qrService, claimsRepository, revocationRepository, nil, storage, nil, nil, ps, cfg.CredentialStatus, rhsFactory, revocationStatusResolver) - claimsService := services.NewClaim(claimsRepository, identityService, qrService, mtService, identityStateRepository, schemaLoader, storage, cfg.APIUI.ServerURL, ps, cfg.IPFS.GatewayURL, revocationStatusResolver) + identityService := services.NewIdentity(keyStore, identityRepository, mtRepository, identityStateRepository, mtService, qrService, claimsRepository, revocationRepository, nil, storage, nil, nil, ps, cfg.CredentialStatus, rhsFactory, revocationStatusResolver, *cfg.AutoPublishingToOnChainRHS) + claimsService := services.NewClaim(claimsRepository, identityService, qrService, mtService, identityStateRepository, schemaLoader, storage, cfg.APIUI.ServerURL, ps, cfg.IPFS.GatewayURL, revocationStatusResolver, &services.DefaultMediaTypeManager) return claimsService, nil } diff --git a/cmd/pending_publisher/main.go b/cmd/pending_publisher/main.go index 844c9c81d..6799d4d69 100644 --- a/cmd/pending_publisher/main.go +++ b/cmd/pending_publisher/main.go @@ -160,8 +160,8 @@ func main() { rhsFactory := reverse_hash.NewFactory(cfg.CredentialStatus.RHS.GetURL(), cl, common.HexToAddress(cfg.CredentialStatus.OnchainTreeStore.SupportedTreeStoreContract), reverse_hash.DefaultRHSTimeOut) revocationStatusResolver := revocation_status.NewRevocationStatusResolver(cfg.CredentialStatus) - identityService := services.NewIdentity(keyStore, identityRepo, mtRepo, identityStateRepo, mtService, qrService, claimsRepo, revocationRepository, connectionsRepository, storage, nil, nil, pubsub.NewMock(), cfg.CredentialStatus, rhsFactory, revocationStatusResolver) - claimsService := services.NewClaim(claimsRepo, identityService, qrService, mtService, identityStateRepo, schemaLoader, storage, cfg.APIUI.ServerURL, ps, cfg.IPFS.GatewayURL, revocationStatusResolver) + identityService := services.NewIdentity(keyStore, identityRepo, mtRepo, identityStateRepo, mtService, qrService, claimsRepo, revocationRepository, connectionsRepository, storage, nil, nil, pubsub.NewMock(), cfg.CredentialStatus, rhsFactory, revocationStatusResolver, *cfg.AutoPublishingToOnChainRHS) + claimsService := services.NewClaim(claimsRepo, identityService, qrService, mtService, identityStateRepo, schemaLoader, storage, cfg.APIUI.ServerURL, ps, cfg.IPFS.GatewayURL, revocationStatusResolver, &services.DefaultMediaTypeManager) circuitsLoaderService := circuitLoaders.NewCircuits(cfg.Circuit.Path) proofService := initProofService(ctx, cfg, circuitsLoaderService) diff --git a/cmd/platform/main.go b/cmd/platform/main.go index 649052168..88942b011 100644 --- a/cmd/platform/main.go +++ b/cmd/platform/main.go @@ -142,8 +142,8 @@ func main() { cfg.CredentialStatus.SingleIssuer = false revocationStatusResolver := revocation_status.NewRevocationStatusResolver(cfg.CredentialStatus) - identityService := services.NewIdentity(keyStore, identityRepository, mtRepository, identityStateRepository, mtService, qrService, claimsRepository, revocationRepository, nil, storage, nil, nil, ps, cfg.CredentialStatus, rhsFactory, revocationStatusResolver) - claimsService := services.NewClaim(claimsRepository, identityService, qrService, mtService, identityStateRepository, schemaLoader, storage, cfg.ServerUrl, ps, cfg.IPFS.GatewayURL, revocationStatusResolver) + identityService := services.NewIdentity(keyStore, identityRepository, mtRepository, identityStateRepository, mtService, qrService, claimsRepository, revocationRepository, nil, storage, nil, nil, ps, cfg.CredentialStatus, rhsFactory, revocationStatusResolver, *cfg.AutoPublishingToOnChainRHS) + claimsService := services.NewClaim(claimsRepository, identityService, qrService, mtService, identityStateRepository, schemaLoader, storage, cfg.ServerUrl, ps, cfg.IPFS.GatewayURL, revocationStatusResolver, &services.DefaultMediaTypeManager) proofService := gateways.NewProver(ctx, cfg, circuitsLoaderService) transactionService, err := gateways.NewTransaction(ethereumClient, cfg.Ethereum.ConfirmationBlockCount) diff --git a/cmd/platform_ui/main.go b/cmd/platform_ui/main.go index 3c600c2cb..5f41eef49 100644 --- a/cmd/platform_ui/main.go +++ b/cmd/platform_ui/main.go @@ -174,9 +174,9 @@ func main() { cfg.CredentialStatus.SingleIssuer = true revocationStatusResolver := revocation_status.NewRevocationStatusResolver(cfg.CredentialStatus) - identityService := services.NewIdentity(keyStore, identityRepository, mtRepository, identityStateRepository, mtService, qrService, claimsRepository, revocationRepository, connectionsRepository, storage, verifier, sessionRepository, ps, cfg.CredentialStatus, rhsFactory, revocationStatusResolver) + identityService := services.NewIdentity(keyStore, identityRepository, mtRepository, identityStateRepository, mtService, qrService, claimsRepository, revocationRepository, connectionsRepository, storage, verifier, sessionRepository, ps, cfg.CredentialStatus, rhsFactory, revocationStatusResolver, *cfg.AutoPublishingToOnChainRHS) schemaService := services.NewSchema(schemaRepository, schemaLoader) - claimsService := services.NewClaim(claimsRepository, identityService, qrService, mtService, identityStateRepository, schemaLoader, storage, cfg.APIUI.ServerURL, ps, cfg.IPFS.GatewayURL, revocationStatusResolver) + claimsService := services.NewClaim(claimsRepository, identityService, qrService, mtService, identityStateRepository, schemaLoader, storage, cfg.APIUI.ServerURL, ps, cfg.IPFS.GatewayURL, revocationStatusResolver, &services.DefaultMediaTypeManager) connectionsService := services.NewConnection(connectionsRepository, claimsRepository, storage) linkService := services.NewLinkService(storage, claimsService, qrService, claimsRepository, linkRepository, schemaRepository, schemaLoader, sessionRepository, ps, cfg.IPFS.GatewayURL) diff --git a/internal/api/main_test.go b/internal/api/main_test.go index 7cbffd565..ac1bad0d2 100644 --- a/internal/api/main_test.go +++ b/internal/api/main_test.go @@ -12,6 +12,7 @@ import ( "github.com/iden3/iden3comm/v2" "github.com/piprate/json-gold/ld" + "github.com/polygonid/sh-id-platform/internal/common" "github.com/polygonid/sh-id-platform/internal/config" "github.com/polygonid/sh-id-platform/internal/core/ports" "github.com/polygonid/sh-id-platform/internal/db" @@ -107,6 +108,7 @@ func TestMain(m *testing.M) { URL: "http://localhost:3001", }, } + cfg.AutoPublishingToOnChainRHS = common.ToPointer[bool](true) m.Run() } diff --git a/internal/api/server.go b/internal/api/server.go index 0d0a4b23e..734642ff3 100644 --- a/internal/api/server.go +++ b/internal/api/server.go @@ -408,7 +408,7 @@ func (s *Server) Agent(ctx context.Context, request AgentRequestObject) (AgentRe return Agent400JSONResponse{N400JSONResponse{"cannot proceed with an empty request"}}, nil } - basicMessage, _, err := s.packageManager.Unpack([]byte(*request.Body)) + basicMessage, mediatype, err := s.packageManager.Unpack([]byte(*request.Body)) if err != nil { log.Debug(ctx, "agent bad request", "err", err, "body", *request.Body) return Agent400JSONResponse{N400JSONResponse{"cannot proceed with the given request"}}, nil @@ -420,7 +420,7 @@ func (s *Server) Agent(ctx context.Context, request AgentRequestObject) (AgentRe return Agent400JSONResponse{N400JSONResponse{err.Error()}}, nil } - agent, err := s.claimService.Agent(ctx, req) + agent, err := s.claimService.Agent(ctx, req, mediatype) if err != nil { log.Error(ctx, "agent error", "err", err) return Agent400JSONResponse{N400JSONResponse{err.Error()}}, nil diff --git a/internal/api/server_test.go b/internal/api/server_test.go index aaa765a68..73642a479 100644 --- a/internal/api/server_test.go +++ b/internal/api/server_test.go @@ -52,9 +52,9 @@ func TestServer_CreateIdentity(t *testing.T) { rhsFactory := reverse_hash.NewFactory(cfg.CredentialStatus.RHS.GetURL(), nil, commonEth.HexToAddress(cfg.CredentialStatus.OnchainTreeStore.SupportedTreeStoreContract), reverse_hash.DefaultRHSTimeOut) revocationStatusResolver := revocation_status.NewRevocationStatusResolver(cfg.CredentialStatus) - identityService := services.NewIdentity(keyStore, identityRepo, mtRepo, identityStateRepo, mtService, nil, claimsRepo, revocationRepository, connectionsRepository, storage, nil, nil, pubsub.NewMock(), cfg.CredentialStatus, rhsFactory, revocationStatusResolver) + identityService := services.NewIdentity(keyStore, identityRepo, mtRepo, identityStateRepo, mtService, nil, claimsRepo, revocationRepository, connectionsRepository, storage, nil, nil, pubsub.NewMock(), cfg.CredentialStatus, rhsFactory, revocationStatusResolver, *cfg.AutoPublishingToOnChainRHS) - claimsService := services.NewClaim(claimsRepo, identityService, nil, mtService, identityStateRepo, schemaLoader, storage, cfg.CredentialStatus.Iden3CommAgentStatus.GetURL(), pubsub.NewMock(), ipfsGatewayURL, revocationStatusResolver) + claimsService := services.NewClaim(claimsRepo, identityService, nil, mtService, identityStateRepo, schemaLoader, storage, cfg.CredentialStatus.Iden3CommAgentStatus.GetURL(), pubsub.NewMock(), ipfsGatewayURL, revocationStatusResolver, &services.DefaultMediaTypeManager) accountService := services.NewAccountService(cfg.Ethereum, keyStore) server := NewServer(&cfg, identityService, accountService, claimsService, nil, NewPublisherMock(), NewPackageManagerMock(), nil) handler := getHandler(context.Background(), server) @@ -249,9 +249,9 @@ func TestServer_RevokeClaim(t *testing.T) { connectionsRepository := repositories.NewConnections() revocationStatusResolver := revocation_status.NewRevocationStatusResolver(cfg.CredentialStatus) rhsFactory := reverse_hash.NewFactory(cfg.CredentialStatus.RHS.GetURL(), nil, commonEth.HexToAddress(cfg.CredentialStatus.OnchainTreeStore.SupportedTreeStoreContract), reverse_hash.DefaultRHSTimeOut) - identityService := services.NewIdentity(&KMSMock{}, identityRepo, mtRepo, identityStateRepo, mtService, nil, claimsRepo, revocationRepository, connectionsRepository, storage, nil, nil, pubsub.NewMock(), cfg.CredentialStatus, rhsFactory, revocationStatusResolver) + identityService := services.NewIdentity(&KMSMock{}, identityRepo, mtRepo, identityStateRepo, mtService, nil, claimsRepo, revocationRepository, connectionsRepository, storage, nil, nil, pubsub.NewMock(), cfg.CredentialStatus, rhsFactory, revocationStatusResolver, *cfg.AutoPublishingToOnChainRHS) - claimsService := services.NewClaim(claimsRepo, identityService, nil, mtService, identityStateRepo, schemaLoader, storage, cfg.CredentialStatus.Iden3CommAgentStatus.GetURL(), pubsub.NewMock(), ipfsGatewayURL, revocationStatusResolver) + claimsService := services.NewClaim(claimsRepo, identityService, nil, mtService, identityStateRepo, schemaLoader, storage, cfg.CredentialStatus.Iden3CommAgentStatus.GetURL(), pubsub.NewMock(), ipfsGatewayURL, revocationStatusResolver, &services.DefaultMediaTypeManager) accountService := services.NewAccountService(cfg.Ethereum, keyStore) server := NewServer(&cfg, identityService, accountService, claimsService, nil, NewPublisherMock(), NewPackageManagerMock(), nil) @@ -400,9 +400,9 @@ func TestServer_CreateClaim(t *testing.T) { rhsFactory := reverse_hash.NewFactory(cfg.CredentialStatus.RHS.GetURL(), nil, commonEth.HexToAddress(cfg.CredentialStatus.OnchainTreeStore.SupportedTreeStoreContract), reverse_hash.DefaultRHSTimeOut) revocationStatusResolver := revocation_status.NewRevocationStatusResolver(cfg.CredentialStatus) - identityService := services.NewIdentity(keyStore, identityRepo, mtRepo, identityStateRepo, mtService, qrService, claimsRepo, revocationRepository, connectionsRepository, storage, nil, nil, pubsub.NewMock(), cfg.CredentialStatus, rhsFactory, revocationStatusResolver) + identityService := services.NewIdentity(keyStore, identityRepo, mtRepo, identityStateRepo, mtService, qrService, claimsRepo, revocationRepository, connectionsRepository, storage, nil, nil, pubsub.NewMock(), cfg.CredentialStatus, rhsFactory, revocationStatusResolver, *cfg.AutoPublishingToOnChainRHS) pubSub := pubsub.NewMock() - claimsService := services.NewClaim(claimsRepo, identityService, nil, mtService, identityStateRepo, schemaLoader, storage, cfg.CredentialStatus.Iden3CommAgentStatus.GetURL(), pubSub, ipfsGatewayURL, revocationStatusResolver) + claimsService := services.NewClaim(claimsRepo, identityService, nil, mtService, identityStateRepo, schemaLoader, storage, cfg.CredentialStatus.Iden3CommAgentStatus.GetURL(), pubSub, ipfsGatewayURL, revocationStatusResolver, &services.DefaultMediaTypeManager) accountService := services.NewAccountService(cfg.Ethereum, keyStore) server := NewServer(&cfg, identityService, accountService, claimsService, nil, NewPublisherMock(), NewPackageManagerMock(), nil) handler := getHandler(ctx, server) @@ -578,9 +578,9 @@ func TestServer_GetIdentities(t *testing.T) { connectionsRepository := repositories.NewConnections() rhsFactory := reverse_hash.NewFactory(cfg.CredentialStatus.RHS.GetURL(), nil, commonEth.HexToAddress(cfg.CredentialStatus.OnchainTreeStore.SupportedTreeStoreContract), reverse_hash.DefaultRHSTimeOut) revocationStatusResolver := revocation_status.NewRevocationStatusResolver(cfg.CredentialStatus) - identityService := services.NewIdentity(&KMSMock{}, identityRepo, mtRepo, identityStateRepo, mtService, nil, claimsRepo, revocationRepository, connectionsRepository, storage, nil, nil, pubsub.NewMock(), cfg.CredentialStatus, rhsFactory, revocationStatusResolver) + identityService := services.NewIdentity(&KMSMock{}, identityRepo, mtRepo, identityStateRepo, mtService, nil, claimsRepo, revocationRepository, connectionsRepository, storage, nil, nil, pubsub.NewMock(), cfg.CredentialStatus, rhsFactory, revocationStatusResolver, *cfg.AutoPublishingToOnChainRHS) - claimsService := services.NewClaim(claimsRepo, identityService, nil, mtService, identityStateRepo, schemaLoader, storage, cfg.CredentialStatus.Iden3CommAgentStatus.GetURL(), pubsub.NewMock(), ipfsGatewayURL, revocationStatusResolver) + claimsService := services.NewClaim(claimsRepo, identityService, nil, mtService, identityStateRepo, schemaLoader, storage, cfg.CredentialStatus.Iden3CommAgentStatus.GetURL(), pubsub.NewMock(), ipfsGatewayURL, revocationStatusResolver, &services.DefaultMediaTypeManager) accountService := services.NewAccountService(cfg.Ethereum, keyStore) server := NewServer(&cfg, identityService, accountService, claimsService, nil, NewPublisherMock(), NewPackageManagerMock(), nil) handler := getHandler(context.Background(), server) @@ -650,12 +650,12 @@ func TestServer_GetClaimQrCode(t *testing.T) { connectionsRepository := repositories.NewConnections() revocationStatusResolver := revocation_status.NewRevocationStatusResolver(cfg.CredentialStatus) rhsFactory := reverse_hash.NewFactory(cfg.CredentialStatus.RHS.GetURL(), nil, commonEth.HexToAddress(cfg.CredentialStatus.OnchainTreeStore.SupportedTreeStoreContract), reverse_hash.DefaultRHSTimeOut) - identityService := services.NewIdentity(&KMSMock{}, identityRepo, mtRepo, identityStateRepo, mtService, nil, claimsRepo, revocationRepository, connectionsRepository, storage, nil, nil, pubsub.NewMock(), cfg.CredentialStatus, rhsFactory, revocationStatusResolver) + identityService := services.NewIdentity(&KMSMock{}, identityRepo, mtRepo, identityStateRepo, mtService, nil, claimsRepo, revocationRepository, connectionsRepository, storage, nil, nil, pubsub.NewMock(), cfg.CredentialStatus, rhsFactory, revocationStatusResolver, *cfg.AutoPublishingToOnChainRHS) idStr := "did:polygonid:polygon:mumbai:2qPrv5Yx8s1qAmEnPym68LfT7gTbASGampiGU7TseL" idNoClaims := "did:polygonid:polygon:mumbai:2qGjTUuxZKqKS4Q8UmxHUPw55g15QgEVGnj6Wkq8Vk" accountService := services.NewAccountService(cfg.Ethereum, keyStore) - claimsService := services.NewClaim(claimsRepo, identityService, nil, mtService, identityStateRepo, schemaLoader, storage, cfg.CredentialStatus.Iden3CommAgentStatus.GetURL(), pubsub.NewMock(), ipfsGatewayURL, revocationStatusResolver) + claimsService := services.NewClaim(claimsRepo, identityService, nil, mtService, identityStateRepo, schemaLoader, storage, cfg.CredentialStatus.Iden3CommAgentStatus.GetURL(), pubsub.NewMock(), ipfsGatewayURL, revocationStatusResolver, &services.DefaultMediaTypeManager) identity := &domain.Identity{ Identifier: idStr, @@ -794,8 +794,8 @@ func TestServer_GetClaim(t *testing.T) { connectionsRepository := repositories.NewConnections() revocationStatusResolver := revocation_status.NewRevocationStatusResolver(cfg.CredentialStatus) rhsFactory := reverse_hash.NewFactory(cfg.CredentialStatus.RHS.GetURL(), nil, commonEth.HexToAddress(cfg.CredentialStatus.OnchainTreeStore.SupportedTreeStoreContract), reverse_hash.DefaultRHSTimeOut) - identityService := services.NewIdentity(&KMSMock{}, identityRepo, mtRepo, identityStateRepo, mtService, nil, claimsRepo, revocationRepository, connectionsRepository, storage, nil, nil, pubsub.NewMock(), cfg.CredentialStatus, rhsFactory, revocationStatusResolver) - claimsService := services.NewClaim(claimsRepo, identityService, nil, mtService, identityStateRepo, schemaLoader, storage, cfg.CredentialStatus.Iden3CommAgentStatus.GetURL(), pubsub.NewMock(), ipfsGatewayURL, revocationStatusResolver) + identityService := services.NewIdentity(&KMSMock{}, identityRepo, mtRepo, identityStateRepo, mtService, nil, claimsRepo, revocationRepository, connectionsRepository, storage, nil, nil, pubsub.NewMock(), cfg.CredentialStatus, rhsFactory, revocationStatusResolver, *cfg.AutoPublishingToOnChainRHS) + claimsService := services.NewClaim(claimsRepo, identityService, nil, mtService, identityStateRepo, schemaLoader, storage, cfg.CredentialStatus.Iden3CommAgentStatus.GetURL(), pubsub.NewMock(), ipfsGatewayURL, revocationStatusResolver, &services.DefaultMediaTypeManager) accountService := services.NewAccountService(cfg.Ethereum, keyStore) server := NewServer(&cfg, identityService, accountService, claimsService, nil, NewPublisherMock(), NewPackageManagerMock(), nil) @@ -968,8 +968,8 @@ func TestServer_GetClaims(t *testing.T) { connectionsRepository := repositories.NewConnections() revocationStatusResolver := revocation_status.NewRevocationStatusResolver(cfg.CredentialStatus) rhsFactory := reverse_hash.NewFactory(cfg.CredentialStatus.RHS.GetURL(), nil, commonEth.HexToAddress(cfg.CredentialStatus.OnchainTreeStore.SupportedTreeStoreContract), reverse_hash.DefaultRHSTimeOut) - identityService := services.NewIdentity(keyStore, identityRepo, mtRepo, identityStateRepo, mtService, nil, claimsRepo, revocationRepository, connectionsRepository, storage, nil, nil, pubsub.NewMock(), cfg.CredentialStatus, rhsFactory, revocationStatusResolver) - claimsService := services.NewClaim(claimsRepo, identityService, nil, mtService, identityStateRepo, schemaLoader, storage, cfg.CredentialStatus.Iden3CommAgentStatus.GetURL(), pubsub.NewMock(), ipfsGatewayURL, revocationStatusResolver) + identityService := services.NewIdentity(keyStore, identityRepo, mtRepo, identityStateRepo, mtService, nil, claimsRepo, revocationRepository, connectionsRepository, storage, nil, nil, pubsub.NewMock(), cfg.CredentialStatus, rhsFactory, revocationStatusResolver, *cfg.AutoPublishingToOnChainRHS) + claimsService := services.NewClaim(claimsRepo, identityService, nil, mtService, identityStateRepo, schemaLoader, storage, cfg.CredentialStatus.Iden3CommAgentStatus.GetURL(), pubsub.NewMock(), ipfsGatewayURL, revocationStatusResolver, &services.DefaultMediaTypeManager) fixture := tests.NewFixture(storage) @@ -1314,11 +1314,11 @@ func TestServer_GetRevocationStatus(t *testing.T) { connectionsRepository := repositories.NewConnections() revocationStatusResolver := revocation_status.NewRevocationStatusResolver(cfg.CredentialStatus) rhsFactory := reverse_hash.NewFactory(cfg.CredentialStatus.RHS.GetURL(), nil, commonEth.HexToAddress(cfg.CredentialStatus.OnchainTreeStore.SupportedTreeStoreContract), reverse_hash.DefaultRHSTimeOut) - identityService := services.NewIdentity(keyStore, identityRepo, mtRepo, identityStateRepo, mtService, nil, claimsRepo, revocationRepository, connectionsRepository, storage, nil, nil, pubsub.NewMock(), cfg.CredentialStatus, rhsFactory, revocationStatusResolver) + identityService := services.NewIdentity(keyStore, identityRepo, mtRepo, identityStateRepo, mtService, nil, claimsRepo, revocationRepository, connectionsRepository, storage, nil, nil, pubsub.NewMock(), cfg.CredentialStatus, rhsFactory, revocationStatusResolver, *cfg.AutoPublishingToOnChainRHS) identity, err := identityService.Create(ctx, "http://localhost:3001", &ports.DIDCreationOptions{Method: method, Blockchain: blockchain, Network: network, KeyType: BJJ}) assert.NoError(t, err) - claimsService := services.NewClaim(claimsRepo, identityService, nil, mtService, identityStateRepo, schemaLoader, storage, cfg.CredentialStatus.Iden3CommAgentStatus.GetURL(), pubsub.NewMock(), ipfsGatewayURL, revocationStatusResolver) + claimsService := services.NewClaim(claimsRepo, identityService, nil, mtService, identityStateRepo, schemaLoader, storage, cfg.CredentialStatus.Iden3CommAgentStatus.GetURL(), pubsub.NewMock(), ipfsGatewayURL, revocationStatusResolver, &services.DefaultMediaTypeManager) accountService := services.NewAccountService(cfg.Ethereum, keyStore) server := NewServer(&cfg, identityService, accountService, claimsService, nil, NewPublisherMock(), NewPackageManagerMock(), nil) handler := getHandler(context.Background(), server) diff --git a/internal/api_ui/main_test.go b/internal/api_ui/main_test.go index ade5ad299..fc8a053a6 100644 --- a/internal/api_ui/main_test.go +++ b/internal/api_ui/main_test.go @@ -15,6 +15,7 @@ import ( "github.com/stretchr/testify/assert" "github.com/stretchr/testify/require" + "github.com/polygonid/sh-id-platform/internal/common" "github.com/polygonid/sh-id-platform/internal/config" "github.com/polygonid/sh-id-platform/internal/core/ports" "github.com/polygonid/sh-id-platform/internal/db" @@ -92,6 +93,7 @@ func TestMain(m *testing.M) { URL: "http://localhost:3001", }, } + cfg.AutoPublishingToOnChainRHS = common.ToPointer[bool](true) schemaLoader = loader.NewDocumentLoader(ipfsGatewayURL) diff --git a/internal/api_ui/server.go b/internal/api_ui/server.go index 49c082185..154673e9a 100644 --- a/internal/api_ui/server.go +++ b/internal/api_ui/server.go @@ -708,7 +708,7 @@ func (s *Server) Agent(ctx context.Context, request AgentRequestObject) (AgentRe log.Debug(ctx, "agent empty request") return Agent400JSONResponse{N400JSONResponse{"cannot proceed with an empty request"}}, nil } - basicMessage, _, err := s.packageManager.Unpack([]byte(*request.Body)) + basicMessage, mediatype, err := s.packageManager.Unpack([]byte(*request.Body)) if err != nil { log.Debug(ctx, "agent bad request", "err", err, "body", *request.Body) return Agent400JSONResponse{N400JSONResponse{"cannot proceed with the given request"}}, nil @@ -720,7 +720,7 @@ func (s *Server) Agent(ctx context.Context, request AgentRequestObject) (AgentRe return Agent400JSONResponse{N400JSONResponse{err.Error()}}, nil } - agent, err := s.claimService.Agent(ctx, req) + agent, err := s.claimService.Agent(ctx, req, mediatype) if err != nil { log.Error(ctx, "agent error", "err", err) return Agent400JSONResponse{N400JSONResponse{err.Error()}}, nil diff --git a/internal/api_ui/server_test.go b/internal/api_ui/server_test.go index b3ab78a2b..31a52cd65 100644 --- a/internal/api_ui/server_test.go +++ b/internal/api_ui/server_test.go @@ -47,9 +47,9 @@ func TestServer_CheckStatus(t *testing.T) { connectionsRepository := repositories.NewConnections() revocationStatusResolver := revocation_status.NewRevocationStatusResolver(cfg.CredentialStatus) rhsFactory := reverse_hash.NewFactory(cfg.CredentialStatus.RHS.URL, nil, commonEth.HexToAddress(cfg.CredentialStatus.OnchainTreeStore.SupportedTreeStoreContract), reverse_hash.DefaultRHSTimeOut) - identityService := services.NewIdentity(&KMSMock{}, identityRepo, mtRepo, identityStateRepo, mtService, nil, claimsRepo, revocationRepository, connectionsRepository, storage, nil, nil, pubsub.NewMock(), cfg.CredentialStatus, rhsFactory, revocationStatusResolver) + identityService := services.NewIdentity(&KMSMock{}, identityRepo, mtRepo, identityStateRepo, mtService, nil, claimsRepo, revocationRepository, connectionsRepository, storage, nil, nil, pubsub.NewMock(), cfg.CredentialStatus, rhsFactory, revocationStatusResolver, *cfg.AutoPublishingToOnChainRHS) schemaService := services.NewSchema(repositories.NewSchema(*storage), schemaLoader) - claimsService := services.NewClaim(claimsRepo, identityService, nil, mtService, identityStateRepo, schemaLoader, storage, "http://localhost", pubsub.NewMock(), ipfsGatewayURL, revocationStatusResolver) + claimsService := services.NewClaim(claimsRepo, identityService, nil, mtService, identityStateRepo, schemaLoader, storage, "http://localhost", pubsub.NewMock(), ipfsGatewayURL, revocationStatusResolver, &services.DefaultMediaTypeManager) server := NewServer(&cfg, identityService, claimsService, schemaService, NewConnectionsMock(), NewLinkMock(), nil, NewPublisherMock(), NewPackageManagerMock(), &health.Status{}) handler := getHandler(context.Background(), server) @@ -230,7 +230,7 @@ func TestServer_AuthQRCode(t *testing.T) { sessionRepository := repositories.NewSessionCached(cachex) revocationStatusResolver := revocation_status.NewRevocationStatusResolver(cfg.CredentialStatus) rhsFactory := reverse_hash.NewFactory(cfg.CredentialStatus.RHS.URL, nil, commonEth.HexToAddress(cfg.CredentialStatus.OnchainTreeStore.SupportedTreeStoreContract), reverse_hash.DefaultRHSTimeOut) - identityService := services.NewIdentity(&KMSMock{}, identityRepo, mtRepo, identityStateRepo, mtService, qrService, claimsRepo, revocationRepository, connectionsRepository, storage, nil, sessionRepository, pubsub.NewMock(), cfg.CredentialStatus, rhsFactory, revocationStatusResolver) + identityService := services.NewIdentity(&KMSMock{}, identityRepo, mtRepo, identityStateRepo, mtService, qrService, claimsRepo, revocationRepository, connectionsRepository, storage, nil, sessionRepository, pubsub.NewMock(), cfg.CredentialStatus, rhsFactory, revocationStatusResolver, *cfg.AutoPublishingToOnChainRHS) server := NewServer(&cfg, identityService, NewClaimsMock(), NewSchemaMock(), NewConnectionsMock(), NewLinkMock(), qrService, NewPublisherMock(), NewPackageManagerMock(), nil) issuerDID, err := w3c.ParseDID("did:polygonid:polygon:mumbai:2qE1BZ7gcmEoP2KppvFPCZqyzyb5tK9T6Gec5HFANQ") require.NoError(t, err) @@ -804,9 +804,9 @@ func TestServer_DeleteConnection(t *testing.T) { connectionsRepository := repositories.NewConnections() revocationStatusResolver := revocation_status.NewRevocationStatusResolver(cfg.CredentialStatus) rhsFactory := reverse_hash.NewFactory(cfg.CredentialStatus.RHS.URL, nil, commonEth.HexToAddress(cfg.CredentialStatus.OnchainTreeStore.SupportedTreeStoreContract), reverse_hash.DefaultRHSTimeOut) - identityService := services.NewIdentity(keyStore, identityRepo, mtRepo, identityStateRepo, mtService, nil, claimsRepo, revocationRepository, connectionsRepository, storage, nil, nil, pubsub.NewMock(), cfg.CredentialStatus, rhsFactory, revocationStatusResolver) + identityService := services.NewIdentity(keyStore, identityRepo, mtRepo, identityStateRepo, mtService, nil, claimsRepo, revocationRepository, connectionsRepository, storage, nil, nil, pubsub.NewMock(), cfg.CredentialStatus, rhsFactory, revocationStatusResolver, *cfg.AutoPublishingToOnChainRHS) - claimsService := services.NewClaim(claimsRepo, identityService, nil, mtService, identityStateRepo, schemaLoader, storage, cfg.CredentialStatus.Iden3CommAgentStatus.GetURL(), pubsub.NewMock(), ipfsGatewayURL, revocationStatusResolver) + claimsService := services.NewClaim(claimsRepo, identityService, nil, mtService, identityStateRepo, schemaLoader, storage, cfg.CredentialStatus.Iden3CommAgentStatus.GetURL(), pubsub.NewMock(), ipfsGatewayURL, revocationStatusResolver, &services.DefaultMediaTypeManager) connectionsService := services.NewConnection(connectionsRepository, claimsRepo, storage) iden, err := identityService.Create(ctx, "polygon-test", &ports.DIDCreationOptions{Method: method, Blockchain: blockchain, Network: network, KeyType: BJJ}) @@ -1055,8 +1055,8 @@ func TestServer_RevokeConnectionCredentials(t *testing.T) { connectionsRepository := repositories.NewConnections() revocationStatusResolver := revocation_status.NewRevocationStatusResolver(cfg.CredentialStatus) rhsFactory := reverse_hash.NewFactory(cfg.CredentialStatus.RHS.URL, nil, commonEth.HexToAddress(cfg.CredentialStatus.OnchainTreeStore.SupportedTreeStoreContract), reverse_hash.DefaultRHSTimeOut) - identityService := services.NewIdentity(keyStore, identityRepo, mtRepo, identityStateRepo, mtService, nil, claimsRepo, revocationRepository, connectionsRepository, storage, nil, nil, pubsub.NewMock(), cfg.CredentialStatus, rhsFactory, revocationStatusResolver) - claimsService := services.NewClaim(claimsRepo, identityService, nil, mtService, identityStateRepo, schemaLoader, storage, "http://localhost", pubsub.NewMock(), ipfsGatewayURL, revocationStatusResolver) + identityService := services.NewIdentity(keyStore, identityRepo, mtRepo, identityStateRepo, mtService, nil, claimsRepo, revocationRepository, connectionsRepository, storage, nil, nil, pubsub.NewMock(), cfg.CredentialStatus, rhsFactory, revocationStatusResolver, *cfg.AutoPublishingToOnChainRHS) + claimsService := services.NewClaim(claimsRepo, identityService, nil, mtService, identityStateRepo, schemaLoader, storage, "http://localhost", pubsub.NewMock(), ipfsGatewayURL, revocationStatusResolver, &services.DefaultMediaTypeManager) connectionsService := services.NewConnection(connectionsRepository, claimsRepo, storage) iden, err := identityService.Create(ctx, "polygon-test", &ports.DIDCreationOptions{Method: method, Blockchain: blockchain, Network: network, KeyType: BJJ}) @@ -1166,9 +1166,9 @@ func TestServer_CreateCredential(t *testing.T) { connectionsRepository := repositories.NewConnections() revocationStatusResolver := revocation_status.NewRevocationStatusResolver(cfg.CredentialStatus) rhsFactory := reverse_hash.NewFactory(cfg.CredentialStatus.RHS.URL, nil, commonEth.HexToAddress(cfg.CredentialStatus.OnchainTreeStore.SupportedTreeStoreContract), reverse_hash.DefaultRHSTimeOut) - identityService := services.NewIdentity(keyStore, identityRepo, mtRepo, identityStateRepo, mtService, nil, claimsRepo, revocationRepository, connectionsRepository, storage, nil, nil, pubsub.NewMock(), cfg.CredentialStatus, rhsFactory, revocationStatusResolver) + identityService := services.NewIdentity(keyStore, identityRepo, mtRepo, identityStateRepo, mtService, nil, claimsRepo, revocationRepository, connectionsRepository, storage, nil, nil, pubsub.NewMock(), cfg.CredentialStatus, rhsFactory, revocationStatusResolver, *cfg.AutoPublishingToOnChainRHS) pubSub := pubsub.NewMock() - claimsService := services.NewClaim(claimsRepo, identityService, nil, mtService, identityStateRepo, schemaLoader, storage, cfg.CredentialStatus.Iden3CommAgentStatus.GetURL(), pubSub, ipfsGatewayURL, revocationStatusResolver) + claimsService := services.NewClaim(claimsRepo, identityService, nil, mtService, identityStateRepo, schemaLoader, storage, cfg.CredentialStatus.Iden3CommAgentStatus.GetURL(), pubSub, ipfsGatewayURL, revocationStatusResolver, &services.DefaultMediaTypeManager) connectionsService := services.NewConnection(connectionsRepository, claimsRepo, storage) iden, err := identityService.Create(ctx, "polygon-test", &ports.DIDCreationOptions{Method: method, Blockchain: blockchain, Network: network, KeyType: BJJ}) require.NoError(t, err) @@ -1343,8 +1343,8 @@ func TestServer_DeleteCredential(t *testing.T) { connectionsRepository := repositories.NewConnections() revocationStatusResolver := revocation_status.NewRevocationStatusResolver(cfg.CredentialStatus) rhsFactory := reverse_hash.NewFactory(cfg.CredentialStatus.RHS.URL, nil, commonEth.HexToAddress(cfg.CredentialStatus.OnchainTreeStore.SupportedTreeStoreContract), reverse_hash.DefaultRHSTimeOut) - identityService := services.NewIdentity(keyStore, identityRepo, mtRepo, identityStateRepo, mtService, nil, claimsRepo, revocationRepository, connectionsRepository, storage, nil, nil, pubsub.NewMock(), cfg.CredentialStatus, rhsFactory, revocationStatusResolver) - claimsService := services.NewClaim(claimsRepo, identityService, nil, mtService, identityStateRepo, schemaLoader, storage, "http://localhost", pubsub.NewMock(), ipfsGatewayURL, revocationStatusResolver) + identityService := services.NewIdentity(keyStore, identityRepo, mtRepo, identityStateRepo, mtService, nil, claimsRepo, revocationRepository, connectionsRepository, storage, nil, nil, pubsub.NewMock(), cfg.CredentialStatus, rhsFactory, revocationStatusResolver, *cfg.AutoPublishingToOnChainRHS) + claimsService := services.NewClaim(claimsRepo, identityService, nil, mtService, identityStateRepo, schemaLoader, storage, "http://localhost", pubsub.NewMock(), ipfsGatewayURL, revocationStatusResolver, &services.DefaultMediaTypeManager) server := NewServer(&cfg, NewIdentityMock(), claimsService, NewSchemaMock(), NewConnectionsMock(), NewLinkMock(), nil, NewPublisherMock(), NewPackageManagerMock(), nil) handler := getHandler(context.Background(), server) @@ -1446,8 +1446,8 @@ func TestServer_GetCredential(t *testing.T) { connectionsRepository := repositories.NewConnections() revocationStatusResolver := revocation_status.NewRevocationStatusResolver(cfg.CredentialStatus) rhsFactory := reverse_hash.NewFactory(cfg.CredentialStatus.RHS.URL, nil, commonEth.HexToAddress(cfg.CredentialStatus.OnchainTreeStore.SupportedTreeStoreContract), reverse_hash.DefaultRHSTimeOut) - identityService := services.NewIdentity(keyStore, identityRepo, mtRepo, identityStateRepo, mtService, nil, claimsRepo, revocationRepository, connectionsRepository, storage, nil, nil, pubsub.NewMock(), cfg.CredentialStatus, rhsFactory, revocationStatusResolver) - claimsService := services.NewClaim(claimsRepo, identityService, nil, mtService, identityStateRepo, schemaLoader, storage, cfg.CredentialStatus.Iden3CommAgentStatus.GetURL(), pubsub.NewMock(), ipfsGatewayURL, revocationStatusResolver) + identityService := services.NewIdentity(keyStore, identityRepo, mtRepo, identityStateRepo, mtService, nil, claimsRepo, revocationRepository, connectionsRepository, storage, nil, nil, pubsub.NewMock(), cfg.CredentialStatus, rhsFactory, revocationStatusResolver, *cfg.AutoPublishingToOnChainRHS) + claimsService := services.NewClaim(claimsRepo, identityService, nil, mtService, identityStateRepo, schemaLoader, storage, cfg.CredentialStatus.Iden3CommAgentStatus.GetURL(), pubsub.NewMock(), ipfsGatewayURL, revocationStatusResolver, &services.DefaultMediaTypeManager) connectionsService := services.NewConnection(connectionsRepository, claimsRepo, storage) iden, err := identityService.Create(ctx, "polygon-test", &ports.DIDCreationOptions{Method: method, Blockchain: blockchain, Network: network, KeyType: BJJ}) require.NoError(t, err) @@ -1638,9 +1638,9 @@ func TestServer_GetCredentials(t *testing.T) { connectionsRepository := repositories.NewConnections() revocationStatusResolver := revocation_status.NewRevocationStatusResolver(cfg.CredentialStatus) rhsFactory := reverse_hash.NewFactory(cfg.CredentialStatus.RHS.URL, nil, commonEth.HexToAddress(cfg.CredentialStatus.OnchainTreeStore.SupportedTreeStoreContract), reverse_hash.DefaultRHSTimeOut) - identityService := services.NewIdentity(keyStore, identityRepo, mtRepo, identityStateRepo, mtService, nil, claimsRepo, revocationRepository, connectionsRepository, storage, nil, nil, pubsub.NewMock(), cfg.CredentialStatus, rhsFactory, revocationStatusResolver) + identityService := services.NewIdentity(keyStore, identityRepo, mtRepo, identityStateRepo, mtService, nil, claimsRepo, revocationRepository, connectionsRepository, storage, nil, nil, pubsub.NewMock(), cfg.CredentialStatus, rhsFactory, revocationStatusResolver, *cfg.AutoPublishingToOnChainRHS) - claimsService := services.NewClaim(claimsRepo, identityService, nil, mtService, identityStateRepo, schemaLoader, storage, cfg.CredentialStatus.Iden3CommAgentStatus.GetURL(), pubsub.NewMock(), ipfsGatewayURL, revocationStatusResolver) + claimsService := services.NewClaim(claimsRepo, identityService, nil, mtService, identityStateRepo, schemaLoader, storage, cfg.CredentialStatus.Iden3CommAgentStatus.GetURL(), pubsub.NewMock(), ipfsGatewayURL, revocationStatusResolver, &services.DefaultMediaTypeManager) schemaService := services.NewSchema(schemaRepository, schemaLoader) connectionsService := services.NewConnection(connectionsRepository, claimsRepo, storage) iden, err := identityService.Create(ctx, "polygon-test", &ports.DIDCreationOptions{Method: method, Blockchain: blockchain, Network: network, KeyType: BJJ}) @@ -2107,8 +2107,8 @@ func TestServer_GetCredentialQrCode(t *testing.T) { connectionsRepository := repositories.NewConnections() revocationStatusResolver := revocation_status.NewRevocationStatusResolver(cfg.CredentialStatus) rhsFactory := reverse_hash.NewFactory(cfg.CredentialStatus.RHS.URL, nil, commonEth.HexToAddress(cfg.CredentialStatus.OnchainTreeStore.SupportedTreeStoreContract), reverse_hash.DefaultRHSTimeOut) - identityService := services.NewIdentity(keyStore, identityRepo, mtRepo, identityStateRepo, mtService, qrService, claimsRepo, revocationRepository, connectionsRepository, storage, nil, nil, pubsub.NewMock(), cfg.CredentialStatus, rhsFactory, revocationStatusResolver) - claimsService := services.NewClaim(claimsRepo, identityService, qrService, mtService, identityStateRepo, schemaLoader, storage, cfg.CredentialStatus.Iden3CommAgentStatus.GetURL(), pubsub.NewMock(), ipfsGatewayURL, revocationStatusResolver) + identityService := services.NewIdentity(keyStore, identityRepo, mtRepo, identityStateRepo, mtService, qrService, claimsRepo, revocationRepository, connectionsRepository, storage, nil, nil, pubsub.NewMock(), cfg.CredentialStatus, rhsFactory, revocationStatusResolver, *cfg.AutoPublishingToOnChainRHS) + claimsService := services.NewClaim(claimsRepo, identityService, qrService, mtService, identityStateRepo, schemaLoader, storage, cfg.CredentialStatus.Iden3CommAgentStatus.GetURL(), pubsub.NewMock(), ipfsGatewayURL, revocationStatusResolver, &services.DefaultMediaTypeManager) connectionsService := services.NewConnection(connectionsRepository, claimsRepo, storage) iden, err := identityService.Create(ctx, "polygon-test", &ports.DIDCreationOptions{Method: method, Blockchain: blockchain, Network: network, KeyType: BJJ}) require.NoError(t, err) @@ -2261,8 +2261,8 @@ func TestServer_GetConnection(t *testing.T) { connectionsRepository := repositories.NewConnections() rhsFactory := reverse_hash.NewFactory(cfg.CredentialStatus.RHS.URL, nil, commonEth.HexToAddress(cfg.CredentialStatus.OnchainTreeStore.SupportedTreeStoreContract), reverse_hash.DefaultRHSTimeOut) revocationStatusResolver := revocation_status.NewRevocationStatusResolver(cfg.CredentialStatus) - identityService := services.NewIdentity(keyStore, identityRepo, mtRepo, identityStateRepo, mtService, nil, claimsRepo, revocationRepository, connectionsRepository, storage, nil, nil, pubsub.NewMock(), cfg.CredentialStatus, rhsFactory, revocationStatusResolver) - claimsService := services.NewClaim(claimsRepo, identityService, nil, mtService, identityStateRepo, schemaLoader, storage, cfg.CredentialStatus.Iden3CommAgentStatus.GetURL(), pubsub.NewMock(), ipfsGatewayURL, revocationStatusResolver) + identityService := services.NewIdentity(keyStore, identityRepo, mtRepo, identityStateRepo, mtService, nil, claimsRepo, revocationRepository, connectionsRepository, storage, nil, nil, pubsub.NewMock(), cfg.CredentialStatus, rhsFactory, revocationStatusResolver, *cfg.AutoPublishingToOnChainRHS) + claimsService := services.NewClaim(claimsRepo, identityService, nil, mtService, identityStateRepo, schemaLoader, storage, cfg.CredentialStatus.Iden3CommAgentStatus.GetURL(), pubsub.NewMock(), ipfsGatewayURL, revocationStatusResolver, &services.DefaultMediaTypeManager) connectionsService := services.NewConnection(connectionsRepository, claimsRepo, storage) iden, err := identityService.Create(ctx, "polygon-test", &ports.DIDCreationOptions{Method: method, Blockchain: blockchain, Network: network, KeyType: BJJ}) @@ -2446,8 +2446,8 @@ func TestServer_GetConnections(t *testing.T) { connectionsRepository := repositories.NewConnections() revocationStatusResolver := revocation_status.NewRevocationStatusResolver(cfg.CredentialStatus) rhsFactory := reverse_hash.NewFactory(cfg.CredentialStatus.RHS.URL, nil, commonEth.HexToAddress(cfg.CredentialStatus.OnchainTreeStore.SupportedTreeStoreContract), reverse_hash.DefaultRHSTimeOut) - identityService := services.NewIdentity(keyStore, identityRepo, mtRepo, identityStateRepo, mtService, nil, claimsRepo, revocationRepository, connectionsRepository, storage, nil, nil, pubsub.NewMock(), cfg.CredentialStatus, rhsFactory, revocationStatusResolver) - claimsService := services.NewClaim(claimsRepo, identityService, nil, mtService, identityStateRepo, schemaLoader, storage, cfg.CredentialStatus.Iden3CommAgentStatus.GetURL(), pubsub.NewMock(), ipfsGatewayURL, revocationStatusResolver) + identityService := services.NewIdentity(keyStore, identityRepo, mtRepo, identityStateRepo, mtService, nil, claimsRepo, revocationRepository, connectionsRepository, storage, nil, nil, pubsub.NewMock(), cfg.CredentialStatus, rhsFactory, revocationStatusResolver, *cfg.AutoPublishingToOnChainRHS) + claimsService := services.NewClaim(claimsRepo, identityService, nil, mtService, identityStateRepo, schemaLoader, storage, cfg.CredentialStatus.Iden3CommAgentStatus.GetURL(), pubsub.NewMock(), ipfsGatewayURL, revocationStatusResolver, &services.DefaultMediaTypeManager) connectionsService := services.NewConnection(connectionsRepository, claimsRepo, storage) iden, err := identityService.Create(ctx, "polygon-test", &ports.DIDCreationOptions{Method: method, Blockchain: blockchain, Network: network, KeyType: BJJ}) @@ -3124,8 +3124,8 @@ func TestServer_RevokeCredential(t *testing.T) { connectionsRepository := repositories.NewConnections() revocationStatusResolver := revocation_status.NewRevocationStatusResolver(cfg.CredentialStatus) rhsFactory := reverse_hash.NewFactory(cfg.CredentialStatus.RHS.URL, nil, commonEth.HexToAddress(cfg.CredentialStatus.OnchainTreeStore.SupportedTreeStoreContract), reverse_hash.DefaultRHSTimeOut) - identityService := services.NewIdentity(&KMSMock{}, identityRepo, mtRepo, identityStateRepo, mtService, nil, claimsRepo, revocationRepository, connectionsRepository, storage, nil, nil, pubsub.NewMock(), cfg.CredentialStatus, rhsFactory, revocationStatusResolver) - claimsService := services.NewClaim(claimsRepo, identityService, nil, mtService, identityStateRepo, schemaLoader, storage, cfg.CredentialStatus.Iden3CommAgentStatus.GetURL(), pubsub.NewMock(), ipfsGatewayURL, revocationStatusResolver) + identityService := services.NewIdentity(&KMSMock{}, identityRepo, mtRepo, identityStateRepo, mtService, nil, claimsRepo, revocationRepository, connectionsRepository, storage, nil, nil, pubsub.NewMock(), cfg.CredentialStatus, rhsFactory, revocationStatusResolver, *cfg.AutoPublishingToOnChainRHS) + claimsService := services.NewClaim(claimsRepo, identityService, nil, mtService, identityStateRepo, schemaLoader, storage, cfg.CredentialStatus.Iden3CommAgentStatus.GetURL(), pubsub.NewMock(), ipfsGatewayURL, revocationStatusResolver, &services.DefaultMediaTypeManager) fixture := tests.NewFixture(storage) connectionsService := services.NewConnection(connectionsRepository, claimsRepo, storage) @@ -3264,9 +3264,9 @@ func TestServer_CreateLink(t *testing.T) { sessionRepository := repositories.NewSessionCached(cachex) revocationStatusResolver := revocation_status.NewRevocationStatusResolver(cfg.CredentialStatus) rhsFactory := reverse_hash.NewFactory(cfg.CredentialStatus.RHS.URL, nil, commonEth.HexToAddress(cfg.CredentialStatus.OnchainTreeStore.SupportedTreeStoreContract), reverse_hash.DefaultRHSTimeOut) - identityService := services.NewIdentity(keyStore, identityRepo, mtRepo, identityStateRepo, mtService, nil, claimsRepo, revocationRepository, connectionsRepository, storage, nil, nil, pubsub.NewMock(), cfg.CredentialStatus, rhsFactory, revocationStatusResolver) + identityService := services.NewIdentity(keyStore, identityRepo, mtRepo, identityStateRepo, mtService, nil, claimsRepo, revocationRepository, connectionsRepository, storage, nil, nil, pubsub.NewMock(), cfg.CredentialStatus, rhsFactory, revocationStatusResolver, *cfg.AutoPublishingToOnChainRHS) pubSub := pubsub.NewMock() - claimsService := services.NewClaim(claimsRepo, identityService, nil, mtService, identityStateRepo, schemaLoader, storage, cfg.CredentialStatus.Iden3CommAgentStatus.GetURL(), pubSub, ipfsGatewayURL, revocationStatusResolver) + claimsService := services.NewClaim(claimsRepo, identityService, nil, mtService, identityStateRepo, schemaLoader, storage, cfg.CredentialStatus.Iden3CommAgentStatus.GetURL(), pubSub, ipfsGatewayURL, revocationStatusResolver, &services.DefaultMediaTypeManager) connectionsService := services.NewConnection(connectionsRepository, claimsRepo, storage) linkService := services.NewLinkService(storage, claimsService, nil, claimsRepo, linkRepository, schemaRespository, schemaLoader, sessionRepository, pubSub, ipfsGatewayURL) iden, err := identityService.Create(ctx, "polygon-test", &ports.DIDCreationOptions{Method: method, Blockchain: blockchain, Network: network, KeyType: BJJ}) @@ -3490,8 +3490,8 @@ func TestServer_ActivateLink(t *testing.T) { sessionRepository := repositories.NewSessionCached(cachex) revocationStatusResolver := revocation_status.NewRevocationStatusResolver(cfg.CredentialStatus) rhsFactory := reverse_hash.NewFactory(cfg.CredentialStatus.RHS.URL, nil, commonEth.HexToAddress(cfg.CredentialStatus.OnchainTreeStore.SupportedTreeStoreContract), reverse_hash.DefaultRHSTimeOut) - identityService := services.NewIdentity(keyStore, identityRepo, mtRepo, identityStateRepo, mtService, nil, claimsRepo, revocationRepository, connectionsRepository, storage, nil, nil, pubsub.NewMock(), cfg.CredentialStatus, rhsFactory, revocationStatusResolver) - claimsService := services.NewClaim(claimsRepo, identityService, nil, mtService, identityStateRepo, schemaLoader, storage, cfg.CredentialStatus.Iden3CommAgentStatus.GetURL(), pubsub.NewMock(), ipfsGatewayURL, revocationStatusResolver) + identityService := services.NewIdentity(keyStore, identityRepo, mtRepo, identityStateRepo, mtService, nil, claimsRepo, revocationRepository, connectionsRepository, storage, nil, nil, pubsub.NewMock(), cfg.CredentialStatus, rhsFactory, revocationStatusResolver, *cfg.AutoPublishingToOnChainRHS) + claimsService := services.NewClaim(claimsRepo, identityService, nil, mtService, identityStateRepo, schemaLoader, storage, cfg.CredentialStatus.Iden3CommAgentStatus.GetURL(), pubsub.NewMock(), ipfsGatewayURL, revocationStatusResolver, &services.DefaultMediaTypeManager) connectionsService := services.NewConnection(connectionsRepository, claimsRepo, storage) linkService := services.NewLinkService(storage, claimsService, nil, claimsRepo, linkRepository, schemaRepository, schemaLoader, sessionRepository, pubsub.NewMock(), ipfsGatewayURL) iden, err := identityService.Create(ctx, "polygon-test", &ports.DIDCreationOptions{Method: method, Blockchain: blockchain, Network: network, KeyType: BJJ}) @@ -3639,8 +3639,8 @@ func TestServer_GetLink(t *testing.T) { sessionRepository := repositories.NewSessionCached(cachex) revocationStatusResolver := revocation_status.NewRevocationStatusResolver(cfg.CredentialStatus) rhsFactory := reverse_hash.NewFactory(cfg.CredentialStatus.RHS.URL, nil, commonEth.HexToAddress(cfg.CredentialStatus.OnchainTreeStore.SupportedTreeStoreContract), reverse_hash.DefaultRHSTimeOut) - identityService := services.NewIdentity(keyStore, identityRepo, mtRepo, identityStateRepo, mtService, nil, claimsRepo, revocationRepository, connectionsRepository, storage, nil, nil, pubsub.NewMock(), cfg.CredentialStatus, rhsFactory, revocationStatusResolver) - claimsService := services.NewClaim(claimsRepo, identityService, nil, mtService, identityStateRepo, schemaLoader, storage, cfg.CredentialStatus.Iden3CommAgentStatus.GetURL(), pubsub.NewMock(), ipfsGatewayURL, revocationStatusResolver) + identityService := services.NewIdentity(keyStore, identityRepo, mtRepo, identityStateRepo, mtService, nil, claimsRepo, revocationRepository, connectionsRepository, storage, nil, nil, pubsub.NewMock(), cfg.CredentialStatus, rhsFactory, revocationStatusResolver, *cfg.AutoPublishingToOnChainRHS) + claimsService := services.NewClaim(claimsRepo, identityService, nil, mtService, identityStateRepo, schemaLoader, storage, cfg.CredentialStatus.Iden3CommAgentStatus.GetURL(), pubsub.NewMock(), ipfsGatewayURL, revocationStatusResolver, &services.DefaultMediaTypeManager) connectionsService := services.NewConnection(connectionsRepository, claimsRepo, storage) linkService := services.NewLinkService(storage, claimsService, nil, claimsRepo, linkRepository, schemaRepository, schemaLoader, sessionRepository, pubsub.NewMock(), ipfsGatewayURL) iden, err := identityService.Create(ctx, "polygon-test", &ports.DIDCreationOptions{Method: method, Blockchain: blockchain, Network: network, KeyType: BJJ}) @@ -3815,8 +3815,8 @@ func TestServer_GetAllLinks(t *testing.T) { sessionRepository := repositories.NewSessionCached(cachex) revocationStatusResolver := revocation_status.NewRevocationStatusResolver(cfg.CredentialStatus) rhsFactory := reverse_hash.NewFactory(cfg.CredentialStatus.RHS.URL, nil, commonEth.HexToAddress(cfg.CredentialStatus.OnchainTreeStore.SupportedTreeStoreContract), reverse_hash.DefaultRHSTimeOut) - identityService := services.NewIdentity(keyStore, identityRepo, mtRepo, identityStateRepo, mtService, nil, claimsRepo, revocationRepository, connectionsRepository, storage, nil, nil, pubsub.NewMock(), cfg.CredentialStatus, rhsFactory, revocationStatusResolver) - claimsService := services.NewClaim(claimsRepo, identityService, nil, mtService, identityStateRepo, schemaLoader, storage, cfg.CredentialStatus.Iden3CommAgentStatus.GetURL(), pubsub.NewMock(), ipfsGatewayURL, revocationStatusResolver) + identityService := services.NewIdentity(keyStore, identityRepo, mtRepo, identityStateRepo, mtService, nil, claimsRepo, revocationRepository, connectionsRepository, storage, nil, nil, pubsub.NewMock(), cfg.CredentialStatus, rhsFactory, revocationStatusResolver, *cfg.AutoPublishingToOnChainRHS) + claimsService := services.NewClaim(claimsRepo, identityService, nil, mtService, identityStateRepo, schemaLoader, storage, cfg.CredentialStatus.Iden3CommAgentStatus.GetURL(), pubsub.NewMock(), ipfsGatewayURL, revocationStatusResolver, &services.DefaultMediaTypeManager) connectionsService := services.NewConnection(connectionsRepository, claimsRepo, storage) linkService := services.NewLinkService(storage, claimsService, nil, claimsRepo, linkRepository, schemaRepository, schemaLoader, sessionRepository, pubsub.NewMock(), ipfsGatewayURL) iden, err := identityService.Create(ctx, "polygon-test", &ports.DIDCreationOptions{Method: method, Blockchain: blockchain, Network: network, KeyType: BJJ}) @@ -4049,8 +4049,8 @@ func TestServer_DeleteLink(t *testing.T) { sessionRepository := repositories.NewSessionCached(cachex) revocationStatusResolver := revocation_status.NewRevocationStatusResolver(cfg.CredentialStatus) rhsFactory := reverse_hash.NewFactory(cfg.CredentialStatus.RHS.URL, nil, commonEth.HexToAddress(cfg.CredentialStatus.OnchainTreeStore.SupportedTreeStoreContract), reverse_hash.DefaultRHSTimeOut) - identityService := services.NewIdentity(keyStore, identityRepo, mtRepo, identityStateRepo, mtService, nil, claimsRepo, revocationRepository, connectionsRepository, storage, nil, nil, pubsub.NewMock(), cfg.CredentialStatus, rhsFactory, revocationStatusResolver) - claimsService := services.NewClaim(claimsRepo, identityService, nil, mtService, identityStateRepo, schemaLoader, storage, cfg.CredentialStatus.Iden3CommAgentStatus.GetURL(), pubsub.NewMock(), ipfsGatewayURL, revocationStatusResolver) + identityService := services.NewIdentity(keyStore, identityRepo, mtRepo, identityStateRepo, mtService, nil, claimsRepo, revocationRepository, connectionsRepository, storage, nil, nil, pubsub.NewMock(), cfg.CredentialStatus, rhsFactory, revocationStatusResolver, *cfg.AutoPublishingToOnChainRHS) + claimsService := services.NewClaim(claimsRepo, identityService, nil, mtService, identityStateRepo, schemaLoader, storage, cfg.CredentialStatus.Iden3CommAgentStatus.GetURL(), pubsub.NewMock(), ipfsGatewayURL, revocationStatusResolver, &services.DefaultMediaTypeManager) connectionsService := services.NewConnection(connectionsRepository, claimsRepo, storage) linkService := services.NewLinkService(storage, claimsService, nil, claimsRepo, linkRepository, schemaRepository, schemaLoader, sessionRepository, pubsub.NewMock(), ipfsGatewayURL) iden, err := identityService.Create(ctx, "polygon-test", &ports.DIDCreationOptions{Method: method, Blockchain: blockchain, Network: network, KeyType: BJJ}) @@ -4164,8 +4164,8 @@ func TestServer_DeleteLinkForDifferentDID(t *testing.T) { sessionRepository := repositories.NewSessionCached(cachex) revocationStatusResolver := revocation_status.NewRevocationStatusResolver(cfg.CredentialStatus) rhsFactory := reverse_hash.NewFactory(cfg.CredentialStatus.RHS.URL, nil, commonEth.HexToAddress(cfg.CredentialStatus.OnchainTreeStore.SupportedTreeStoreContract), reverse_hash.DefaultRHSTimeOut) - identityService := services.NewIdentity(keyStore, identityRepo, mtRepo, identityStateRepo, mtService, nil, claimsRepo, revocationRepository, connectionsRepository, storage, nil, nil, pubsub.NewMock(), cfg.CredentialStatus, rhsFactory, revocationStatusResolver) - claimsService := services.NewClaim(claimsRepo, identityService, nil, mtService, identityStateRepo, schemaLoader, storage, cfg.CredentialStatus.Iden3CommAgentStatus.GetURL(), pubsub.NewMock(), ipfsGatewayURL, revocationStatusResolver) + identityService := services.NewIdentity(keyStore, identityRepo, mtRepo, identityStateRepo, mtService, nil, claimsRepo, revocationRepository, connectionsRepository, storage, nil, nil, pubsub.NewMock(), cfg.CredentialStatus, rhsFactory, revocationStatusResolver, *cfg.AutoPublishingToOnChainRHS) + claimsService := services.NewClaim(claimsRepo, identityService, nil, mtService, identityStateRepo, schemaLoader, storage, cfg.CredentialStatus.Iden3CommAgentStatus.GetURL(), pubsub.NewMock(), ipfsGatewayURL, revocationStatusResolver, &services.DefaultMediaTypeManager) connectionsService := services.NewConnection(connectionsRepository, claimsRepo, storage) linkService := services.NewLinkService(storage, claimsService, nil, claimsRepo, linkRepository, schemaRepository, schemaLoader, sessionRepository, pubsub.NewMock(), ipfsGatewayURL) iden, err := identityService.Create(ctx, "polygon-test", &ports.DIDCreationOptions{Method: method, Blockchain: blockchain, Network: network, KeyType: BJJ}) @@ -4277,8 +4277,8 @@ func TestServer_CreateLinkQRCode(t *testing.T) { sessionRepository := repositories.NewSessionCached(cachex) revocationStatusResolver := revocation_status.NewRevocationStatusResolver(cfg.CredentialStatus) rhsFactory := reverse_hash.NewFactory(cfg.CredentialStatus.RHS.URL, nil, commonEth.HexToAddress(cfg.CredentialStatus.OnchainTreeStore.SupportedTreeStoreContract), reverse_hash.DefaultRHSTimeOut) - identityService := services.NewIdentity(keyStore, identityRepo, mtRepo, identityStateRepo, mtService, qrService, claimsRepo, revocationRepository, connectionsRepository, storage, nil, nil, pubsub.NewMock(), cfg.CredentialStatus, rhsFactory, revocationStatusResolver) - claimsService := services.NewClaim(claimsRepo, identityService, nil, mtService, identityStateRepo, schemaLoader, storage, cfg.CredentialStatus.Iden3CommAgentStatus.GetURL(), pubsub.NewMock(), ipfsGatewayURL, revocationStatusResolver) + identityService := services.NewIdentity(keyStore, identityRepo, mtRepo, identityStateRepo, mtService, qrService, claimsRepo, revocationRepository, connectionsRepository, storage, nil, nil, pubsub.NewMock(), cfg.CredentialStatus, rhsFactory, revocationStatusResolver, *cfg.AutoPublishingToOnChainRHS) + claimsService := services.NewClaim(claimsRepo, identityService, nil, mtService, identityStateRepo, schemaLoader, storage, cfg.CredentialStatus.Iden3CommAgentStatus.GetURL(), pubsub.NewMock(), ipfsGatewayURL, revocationStatusResolver, &services.DefaultMediaTypeManager) connectionsService := services.NewConnection(connectionsRepository, claimsRepo, storage) linkService := services.NewLinkService(storage, claimsService, qrService, claimsRepo, linkRepository, schemaRepository, schemaLoader, sessionRepository, pubsub.NewMock(), ipfsGatewayURL) iden, err := identityService.Create(ctx, "polygon-test", &ports.DIDCreationOptions{Method: method, Blockchain: blockchain, Network: network, KeyType: BJJ}) @@ -4430,8 +4430,8 @@ func TestServer_GetLinkQRCode(t *testing.T) { revocationStatusResolver := revocation_status.NewRevocationStatusResolver(cfg.CredentialStatus) rhsFactory := reverse_hash.NewFactory(cfg.CredentialStatus.RHS.URL, nil, commonEth.HexToAddress(cfg.CredentialStatus.OnchainTreeStore.SupportedTreeStoreContract), reverse_hash.DefaultRHSTimeOut) qrService := services.NewQrStoreService(cachex) - identityService := services.NewIdentity(keyStore, identityRepo, mtRepo, identityStateRepo, mtService, qrService, claimsRepo, revocationRepository, connectionsRepository, storage, nil, nil, pubsub.NewMock(), cfg.CredentialStatus, rhsFactory, revocationStatusResolver) - claimsService := services.NewClaim(claimsRepo, identityService, qrService, mtService, identityStateRepo, schemaLoader, storage, cfg.CredentialStatus.Iden3CommAgentStatus.GetURL(), pubsub.NewMock(), ipfsGatewayURL, revocationStatusResolver) + identityService := services.NewIdentity(keyStore, identityRepo, mtRepo, identityStateRepo, mtService, qrService, claimsRepo, revocationRepository, connectionsRepository, storage, nil, nil, pubsub.NewMock(), cfg.CredentialStatus, rhsFactory, revocationStatusResolver, *cfg.AutoPublishingToOnChainRHS) + claimsService := services.NewClaim(claimsRepo, identityService, qrService, mtService, identityStateRepo, schemaLoader, storage, cfg.CredentialStatus.Iden3CommAgentStatus.GetURL(), pubsub.NewMock(), ipfsGatewayURL, revocationStatusResolver, &services.DefaultMediaTypeManager) connectionsService := services.NewConnection(connectionsRepository, claimsRepo, storage) linkService := services.NewLinkService(storage, claimsService, qrService, claimsRepo, linkRepository, schemaRepository, schemaLoader, sessionRepository, pubsub.NewMock(), ipfsGatewayURL) iden, err := identityService.Create(ctx, "polygon-test", &ports.DIDCreationOptions{Method: method, Blockchain: blockchain, Network: network, KeyType: BJJ}) @@ -4611,8 +4611,8 @@ func TestServer_GetStateStatus(t *testing.T) { connectionsRepository := repositories.NewConnections() revocationStatusResolver := revocation_status.NewRevocationStatusResolver(cfg.CredentialStatus) rhsFactory := reverse_hash.NewFactory(cfg.CredentialStatus.RHS.URL, nil, commonEth.HexToAddress(cfg.CredentialStatus.OnchainTreeStore.SupportedTreeStoreContract), reverse_hash.DefaultRHSTimeOut) - identityService := services.NewIdentity(keyStore, identityRepo, mtRepo, identityStateRepo, mtService, nil, claimsRepo, revocationRepository, connectionsRepository, storage, nil, nil, pubsub.NewMock(), cfg.CredentialStatus, rhsFactory, revocationStatusResolver) - claimsService := services.NewClaim(claimsRepo, identityService, nil, mtService, identityStateRepo, schemaLoader, storage, cfg.CredentialStatus.Iden3CommAgentStatus.GetURL(), pubsub.NewMock(), ipfsGatewayURL, revocationStatusResolver) + identityService := services.NewIdentity(keyStore, identityRepo, mtRepo, identityStateRepo, mtService, nil, claimsRepo, revocationRepository, connectionsRepository, storage, nil, nil, pubsub.NewMock(), cfg.CredentialStatus, rhsFactory, revocationStatusResolver, *cfg.AutoPublishingToOnChainRHS) + claimsService := services.NewClaim(claimsRepo, identityService, nil, mtService, identityStateRepo, schemaLoader, storage, cfg.CredentialStatus.Iden3CommAgentStatus.GetURL(), pubsub.NewMock(), ipfsGatewayURL, revocationStatusResolver, &services.DefaultMediaTypeManager) connectionsService := services.NewConnection(connectionsRepository, claimsRepo, storage) schema := "https://raw.githubusercontent.com/iden3/claim-schema-vocab/main/schemas/json/KYCAgeCredential-v3.json" credentialSubject := map[string]any{ @@ -4760,8 +4760,8 @@ func TestServer_GetStateTransactions(t *testing.T) { connectionsRepository := repositories.NewConnections() revocationStatusResolver := revocation_status.NewRevocationStatusResolver(cfg.CredentialStatus) rhsFactory := reverse_hash.NewFactory(cfg.CredentialStatus.RHS.URL, nil, commonEth.HexToAddress(cfg.CredentialStatus.OnchainTreeStore.SupportedTreeStoreContract), reverse_hash.DefaultRHSTimeOut) - identityService := services.NewIdentity(keyStore, identityRepo, mtRepo, identityStateRepo, mtService, nil, claimsRepo, revocationRepository, connectionsRepository, storage, nil, nil, pubsub.NewMock(), cfg.CredentialStatus, rhsFactory, revocationStatusResolver) - claimsService := services.NewClaim(claimsRepo, identityService, nil, mtService, identityStateRepo, schemaLoader, storage, cfg.CredentialStatus.Iden3CommAgentStatus.GetURL(), pubsub.NewMock(), ipfsGatewayURL, revocationStatusResolver) + identityService := services.NewIdentity(keyStore, identityRepo, mtRepo, identityStateRepo, mtService, nil, claimsRepo, revocationRepository, connectionsRepository, storage, nil, nil, pubsub.NewMock(), cfg.CredentialStatus, rhsFactory, revocationStatusResolver, *cfg.AutoPublishingToOnChainRHS) + claimsService := services.NewClaim(claimsRepo, identityService, nil, mtService, identityStateRepo, schemaLoader, storage, cfg.CredentialStatus.Iden3CommAgentStatus.GetURL(), pubsub.NewMock(), ipfsGatewayURL, revocationStatusResolver, &services.DefaultMediaTypeManager) connectionsService := services.NewConnection(connectionsRepository, claimsRepo, storage) iden, err := identityService.Create(ctx, "polygon-test", &ports.DIDCreationOptions{Method: method, Blockchain: blockchain, Network: network, KeyType: BJJ}) require.NoError(t, err) @@ -4846,9 +4846,9 @@ func TestServer_GetRevocationStatus(t *testing.T) { connectionsRepository := repositories.NewConnections() revocationStatusResolver := revocation_status.NewRevocationStatusResolver(cfg.CredentialStatus) rhsFactory := reverse_hash.NewFactory(cfg.CredentialStatus.RHS.URL, nil, commonEth.HexToAddress(cfg.CredentialStatus.OnchainTreeStore.SupportedTreeStoreContract), reverse_hash.DefaultRHSTimeOut) - identityService := services.NewIdentity(keyStore, identityRepo, mtRepo, identityStateRepo, mtService, nil, claimsRepo, revocationRepository, connectionsRepository, storage, nil, nil, pubsub.NewMock(), cfg.CredentialStatus, rhsFactory, revocationStatusResolver) + identityService := services.NewIdentity(keyStore, identityRepo, mtRepo, identityStateRepo, mtService, nil, claimsRepo, revocationRepository, connectionsRepository, storage, nil, nil, pubsub.NewMock(), cfg.CredentialStatus, rhsFactory, revocationStatusResolver, *cfg.AutoPublishingToOnChainRHS) pubSub := pubsub.NewMock() - claimsService := services.NewClaim(claimsRepo, identityService, nil, mtService, identityStateRepo, schemaLoader, storage, cfg.CredentialStatus.Iden3CommAgentStatus.GetURL(), pubSub, ipfsGatewayURL, revocationStatusResolver) + claimsService := services.NewClaim(claimsRepo, identityService, nil, mtService, identityStateRepo, schemaLoader, storage, cfg.CredentialStatus.Iden3CommAgentStatus.GetURL(), pubSub, ipfsGatewayURL, revocationStatusResolver, &services.DefaultMediaTypeManager) connectionsService := services.NewConnection(connectionsRepository, claimsRepo, storage) iden, err := identityService.Create(ctx, "polygon-test", &ports.DIDCreationOptions{Method: method, Blockchain: blockchain, Network: network, KeyType: BJJ}) require.NoError(t, err) diff --git a/internal/config/config.go b/internal/config/config.go index 1a19aca0d..96b713e55 100644 --- a/internal/config/config.go +++ b/internal/config/config.go @@ -50,6 +50,7 @@ type Configuration struct { VaultUserPassAuthPassword string CredentialStatus CredentialStatus `mapstructure:"CredentialStatus"` CustomDIDMethods []CustomDIDMethods `mapstructure:"-"` + AutoPublishingToOnChainRHS *bool `mapstructure:"AutoPublishingToOnChainRHS"` } // Database has the database configuration @@ -507,10 +508,12 @@ func bindEnv() { _ = viper.BindEnv("ISSUER_CUSTOM_DID_METHODS") + _ = viper.BindEnv("AutoPublishingToOnChainRHS", "ISSUER_AUTO_PUBLISHING_TO_ON_CHAIN_RHS") + viper.AutomaticEnv() } -// nolint:gocyclo +// nolint:gocyclo,gocognit func checkEnvVars(ctx context.Context, cfg *Configuration) { if cfg.IPFS.GatewayURL == "" { log.Warn(ctx, "ISSUER_IPFS_GATEWAY_URL value is missing, using default value: "+ipfsGateway) @@ -626,6 +629,11 @@ func checkEnvVars(ctx context.Context, cfg *Configuration) { cfg.SchemaCache = common.ToPointer(false) } + if cfg.AutoPublishingToOnChainRHS == nil { + log.Info(ctx, "AutoPublishingToOnChainRHS is missing and the server set up it as true") + cfg.AutoPublishingToOnChainRHS = common.ToPointer(true) + } + if cfg.CredentialStatus.RHSMode == "" { log.Info(ctx, "ISSUER_CREDENTIAL_STATUS_RHS_MODE value is missing and the server set up it as None") cfg.CredentialStatus.RHSMode = "None" diff --git a/internal/config/credential_status.go b/internal/config/credential_status.go index 1291e973c..2440598e1 100644 --- a/internal/config/credential_status.go +++ b/internal/config/credential_status.go @@ -23,7 +23,7 @@ type CredentialStatus struct { Iden3CommAgentStatus Iden3CommAgentStatus RHS RHS OnchainTreeStore OnchainTreeStore `mapstructure:"OnchainTreeStore"` - RHSMode RHSMode `tip:"Reverse hash service mode (OffChain, OnChain, Mixed, None)"` + RHSMode RHSMode `tip:"Reverse hash service mode (OffChain, OnChain, None)"` SingleIssuer bool CredentialStatusType verifiable.CredentialStatusType `mapstructure:"CredentialStatusType" default:"Iden3commRevocationStatusV1"` } diff --git a/internal/core/ports/claims_service.go b/internal/core/ports/claims_service.go index fe2d39b4c..f894d8f9f 100644 --- a/internal/core/ports/claims_service.go +++ b/internal/core/ports/claims_service.go @@ -9,6 +9,7 @@ import ( "github.com/google/uuid" "github.com/iden3/go-iden3-core/v2/w3c" "github.com/iden3/go-schema-processor/v2/verifiable" + "github.com/iden3/iden3comm/v2" comm "github.com/iden3/iden3comm/v2" "github.com/iden3/iden3comm/v2/protocol" @@ -217,7 +218,7 @@ type ClaimsService interface { GetRevocationStatus(ctx context.Context, issuerDID w3c.DID, nonce uint64) (*verifiable.RevocationStatus, error) GetByID(ctx context.Context, issID *w3c.DID, id uuid.UUID) (*domain.Claim, error) GetCredentialQrCode(ctx context.Context, issID *w3c.DID, id uuid.UUID, hostURL string) (*GetCredentialQrCodeResponse, error) - Agent(ctx context.Context, req *AgentRequest) (*domain.Agent, error) + Agent(ctx context.Context, req *AgentRequest, mediatype iden3comm.MediaType) (*domain.Agent, error) GetAuthClaim(ctx context.Context, did *w3c.DID) (*domain.Claim, error) GetAuthClaimForPublishing(ctx context.Context, did *w3c.DID, state string) (*domain.Claim, error) UpdateClaimsMTPAndState(ctx context.Context, currentState *domain.IdentityState) error diff --git a/internal/core/ports/mediatype_manager.go b/internal/core/ports/mediatype_manager.go new file mode 100644 index 000000000..fc8c83405 --- /dev/null +++ b/internal/core/ports/mediatype_manager.go @@ -0,0 +1,8 @@ +package ports + +import "github.com/iden3/iden3comm/v2" + +// MediatypeManager - Define the interface for media type manager +type MediatypeManager interface { + AllowMediaType(protoclMessage iden3comm.ProtocolMessage, mediaType iden3comm.MediaType) bool +} diff --git a/internal/core/services/claims.go b/internal/core/services/claims.go index c6d5819ae..5a044a30b 100644 --- a/internal/core/services/claims.go +++ b/internal/core/services/claims.go @@ -17,6 +17,7 @@ import ( "github.com/iden3/go-schema-processor/v2/merklize" "github.com/iden3/go-schema-processor/v2/processor" "github.com/iden3/go-schema-processor/v2/verifiable" + "github.com/iden3/iden3comm/v2" "github.com/iden3/iden3comm/v2/packers" "github.com/iden3/iden3comm/v2/protocol" shell "github.com/ipfs/go-ipfs-api" @@ -67,10 +68,11 @@ type claim struct { publisher pubsub.Publisher ipfsClient *shell.Shell revocationStatusResolver *revocation_status.RevocationStatusResolver + mediatypeManager ports.MediatypeManager } // NewClaim creates a new claim service -func NewClaim(repo ports.ClaimsRepository, idenSrv ports.IdentityService, qrService ports.QrStoreService, mtService ports.MtService, identityStateRepository ports.IdentityStateRepository, ld loader.DocumentLoader, storage *db.Storage, host string, ps pubsub.Publisher, ipfsGatewayURL string, revocationStatusResolver *revocation_status.RevocationStatusResolver) ports.ClaimsService { +func NewClaim(repo ports.ClaimsRepository, idenSrv ports.IdentityService, qrService ports.QrStoreService, mtService ports.MtService, identityStateRepository ports.IdentityStateRepository, ld loader.DocumentLoader, storage *db.Storage, host string, ps pubsub.Publisher, ipfsGatewayURL string, revocationStatusResolver *revocation_status.RevocationStatusResolver, mediatypeManager ports.MediatypeManager) ports.ClaimsService { s := &claim{ host: host, icRepo: repo, @@ -82,6 +84,7 @@ func NewClaim(repo ports.ClaimsRepository, idenSrv ports.IdentityService, qrServ loader: ld, publisher: ps, revocationStatusResolver: revocationStatusResolver, + mediatypeManager: mediatypeManager, } if ipfsGatewayURL != "" { s.ipfsClient = shell.NewShell(ipfsGatewayURL) @@ -365,7 +368,13 @@ func (c *claim) GetCredentialQrCode(ctx context.Context, issID *w3c.DID, id uuid }, nil } -func (c *claim) Agent(ctx context.Context, req *ports.AgentRequest) (*domain.Agent, error) { +func (c *claim) Agent(ctx context.Context, req *ports.AgentRequest, mediatype iden3comm.MediaType) (*domain.Agent, error) { + if !c.mediatypeManager.AllowMediaType(req.Type, mediatype) { + err := fmt.Errorf("unsupported media type '%s' for message type '%s'", req.Typ, req.Type) + log.Error(ctx, "agent: unsupported media type", "err", err) + return nil, err + } + exists, err := c.identitySrv.Exists(ctx, *req.IssuerDID) if err != nil { log.Error(ctx, "loading issuer identity", "err", err, "issuerDID", req.IssuerDID) diff --git a/internal/core/services/identity.go b/internal/core/services/identity.go index a66306a1f..46b1c5867 100644 --- a/internal/core/services/identity.go +++ b/internal/core/services/identity.go @@ -73,34 +73,36 @@ type identity struct { kms kms.KMSType verifier *auth.Verifier - ignoreRHSErrors bool - pubsub pubsub.Publisher - revocationStatusResolver *revocation_status.RevocationStatusResolver - credentialStatusSettings config.CredentialStatus - rhsFactory reverse_hash.Factory + ignoreRHSErrors bool + pubsub pubsub.Publisher + revocationStatusResolver *revocation_status.RevocationStatusResolver + credentialStatusSettings config.CredentialStatus + rhsFactory reverse_hash.Factory + autoPublishingToOnChainRHS bool } // NewIdentity creates a new identity // nolint -func NewIdentity(kms kms.KMSType, identityRepository ports.IndentityRepository, imtRepository ports.IdentityMerkleTreeRepository, identityStateRepository ports.IdentityStateRepository, mtservice ports.MtService, qrService ports.QrStoreService, claimsRepository ports.ClaimsRepository, revocationRepository ports.RevocationRepository, connectionsRepository ports.ConnectionsRepository, storage *db.Storage, verifier *auth.Verifier, sessionRepository ports.SessionRepository, ps pubsub.Client, credentialStatusSettings config.CredentialStatus, rhsFactory reverse_hash.Factory, revocationStatusResolver *revocation_status.RevocationStatusResolver) ports.IdentityService { +func NewIdentity(kms kms.KMSType, identityRepository ports.IndentityRepository, imtRepository ports.IdentityMerkleTreeRepository, identityStateRepository ports.IdentityStateRepository, mtservice ports.MtService, qrService ports.QrStoreService, claimsRepository ports.ClaimsRepository, revocationRepository ports.RevocationRepository, connectionsRepository ports.ConnectionsRepository, storage *db.Storage, verifier *auth.Verifier, sessionRepository ports.SessionRepository, ps pubsub.Client, credentialStatusSettings config.CredentialStatus, rhsFactory reverse_hash.Factory, revocationStatusResolver *revocation_status.RevocationStatusResolver, autoPublishingToOnChainRHS bool) ports.IdentityService { return &identity{ - identityRepository: identityRepository, - imtRepository: imtRepository, - identityStateRepository: identityStateRepository, - claimsRepository: claimsRepository, - revocationRepository: revocationRepository, - connectionsRepository: connectionsRepository, - sessionManager: sessionRepository, - storage: storage, - mtService: mtservice, - qrService: qrService, - kms: kms, - ignoreRHSErrors: false, - verifier: verifier, - pubsub: ps, - credentialStatusSettings: credentialStatusSettings, - rhsFactory: rhsFactory, - revocationStatusResolver: revocationStatusResolver, + identityRepository: identityRepository, + imtRepository: imtRepository, + identityStateRepository: identityStateRepository, + claimsRepository: claimsRepository, + revocationRepository: revocationRepository, + connectionsRepository: connectionsRepository, + sessionManager: sessionRepository, + storage: storage, + mtService: mtservice, + qrService: qrService, + kms: kms, + ignoreRHSErrors: false, + verifier: verifier, + pubsub: ps, + credentialStatusSettings: credentialStatusSettings, + rhsFactory: rhsFactory, + revocationStatusResolver: revocationStatusResolver, + autoPublishingToOnChainRHS: autoPublishingToOnChainRHS, } } @@ -735,30 +737,44 @@ func (i *identity) createIdentity(ctx context.Context, tx db.Querier, hostURL st return nil, nil, fmt.Errorf("can't save identity: %w", err) } - rhsPublishers, err := i.rhsFactory.BuildPublishers(ctx, reverse_hash.RHSMode(i.credentialStatusSettings.RHSMode), &kms.KeyID{ - Type: kms.KeyTypeEthereum, - ID: i.credentialStatusSettings.OnchainTreeStore.PublishingKeyPath, - }) + rhsMode := reverse_hash.RHSMode(i.credentialStatusSettings.RHSMode) + rhsPublishers, err := i.rhsFactory.BuildPublishers( + ctx, + rhsMode, + &kms.KeyID{ + Type: kms.KeyTypeEthereum, + ID: i.credentialStatusSettings.OnchainTreeStore.PublishingKeyPath, + }) if err != nil { return nil, nil, fmt.Errorf("can't create RHS publisher: %w", err) } if len(rhsPublishers) > 0 { - log.Info(ctx, "publishing state to RHS", "publishers", len(rhsPublishers)) - for _, rhsPublisher := range rhsPublishers { - err := rhsPublisher.PublishNodesToRHS(ctx, []mtproof.Node{ - { - Hash: identity.State.TreeState().State, - Children: []*merkletree.Hash{ - claimsTree.Root(), - &merkletree.HashZero, - &merkletree.HashZero, + if rhsMode == reverse_hash.RHSModeOnChain && !i.autoPublishingToOnChainRHS { + log.Info(ctx, ` + state info (hashes): + root: '%s', + ClaimsTreeRoot: '%s', + RevocationsTreeRoot: '%s', + RootOfRootsTreeRoot: '%s', + `, identity.State.TreeState().State, claimsTree.Root(), &merkletree.HashZero, &merkletree.HashZero) + } else { + log.Info(ctx, "publishing state to RHS", "publishers", len(rhsPublishers)) + for _, rhsPublisher := range rhsPublishers { + err := rhsPublisher.PublishNodesToRHS(ctx, []mtproof.Node{ + { + Hash: identity.State.TreeState().State, + Children: []*merkletree.Hash{ + claimsTree.Root(), + &merkletree.HashZero, + &merkletree.HashZero, + }, }, - }, - }) - if err != nil { - log.Error(ctx, "publishing state to RHS", "err", err) - return nil, nil, err + }) + if err != nil { + log.Error(ctx, "publishing state to RHS", "err", err) + return nil, nil, err + } } } } diff --git a/internal/core/services/mediatype_manager.go b/internal/core/services/mediatype_manager.go new file mode 100644 index 000000000..8b0801b52 --- /dev/null +++ b/internal/core/services/mediatype_manager.go @@ -0,0 +1,48 @@ +package services + +import ( + "github.com/iden3/iden3comm/v2" + "github.com/iden3/iden3comm/v2/packers" + "github.com/iden3/iden3comm/v2/protocol" +) + +// DefaultMediaTypeManager default media type manager +var DefaultMediaTypeManager = NewMediaTypeManager( + map[iden3comm.ProtocolMessage][]string{ + protocol.CredentialFetchRequestMessageType: {string(packers.MediaTypeZKPMessage)}, + protocol.RevocationStatusRequestMessageType: {"*"}, + }, + true, +) + +// MediaTypeManager manages the list of allowed media types for the protocol message type +// if strictMode is true, then all messages that do not exist in the allowed list will be rejected +type MediaTypeManager struct { + strictMode bool + allowList map[iden3comm.ProtocolMessage][]string +} + +// NewMediaTypeManager create instance of MediaTypeManager +func NewMediaTypeManager(allowList map[iden3comm.ProtocolMessage][]string, strictMode bool) MediaTypeManager { + return MediaTypeManager{ + strictMode: strictMode, + allowList: allowList, + } +} + +// AllowMediaType check if the protocol message supports the mediaType type +func (m *MediaTypeManager) AllowMediaType( + protoclMessage iden3comm.ProtocolMessage, + mediaType iden3comm.MediaType, +) bool { + al, ok := m.allowList[protoclMessage] + if !ok { + return !m.strictMode + } + for _, v := range al { + if v == "*" || v == string(mediaType) { + return true + } + } + return false +} diff --git a/internal/core/services/mediatype_manager_test.go b/internal/core/services/mediatype_manager_test.go new file mode 100644 index 000000000..0de4305a4 --- /dev/null +++ b/internal/core/services/mediatype_manager_test.go @@ -0,0 +1,145 @@ +package services_test + +import ( + "testing" + + "github.com/iden3/iden3comm/v2" + "github.com/iden3/iden3comm/v2/packers" + "github.com/iden3/iden3comm/v2/protocol" + "github.com/stretchr/testify/require" + + "github.com/polygonid/sh-id-platform/internal/core/services" +) + +func TestMediatypeManager_AllowList(t *testing.T) { + type testcase struct { + name string + allowList map[iden3comm.ProtocolMessage][]string + targetProtocolMessage iden3comm.ProtocolMessage + targetMediatype iden3comm.MediaType + expected bool + strictMode bool + } + testcases := []testcase{ + { + name: "strictMode = true. Protocol message not in the allow list", + allowList: map[iden3comm.ProtocolMessage][]string{ + protocol.RevocationStatusRequestMessageType: {"*"}, + }, + targetProtocolMessage: protocol.CredentialFetchRequestMessageType, + targetMediatype: packers.MediaTypeZKPMessage, + expected: false, + strictMode: true, + }, + { + name: "strictMode = false. Protocol message not in the allow list", + allowList: map[iden3comm.ProtocolMessage][]string{ + protocol.RevocationStatusRequestMessageType: {"*"}, + }, + targetProtocolMessage: protocol.CredentialFetchRequestMessageType, + targetMediatype: packers.MediaTypeZKPMessage, + expected: true, + strictMode: false, + }, + { + name: "Protocol message on the allow list with '*'", + allowList: map[iden3comm.ProtocolMessage][]string{ + protocol.CredentialFetchRequestMessageType: {"*"}, + }, + targetProtocolMessage: protocol.CredentialFetchRequestMessageType, + targetMediatype: packers.MediaTypePlainMessage, + expected: true, + strictMode: true, + }, + { + name: "Protocol message on the allow list with allow media type", + allowList: map[iden3comm.ProtocolMessage][]string{ + protocol.CredentialFetchRequestMessageType: {string(packers.MediaTypeZKPMessage)}, + }, + targetProtocolMessage: protocol.CredentialFetchRequestMessageType, + targetMediatype: packers.MediaTypeZKPMessage, + expected: true, + strictMode: true, + }, + { + name: "Protocol message on the allow list with NOT allow media type", + allowList: map[iden3comm.ProtocolMessage][]string{ + protocol.CredentialFetchRequestMessageType: {string(packers.MediaTypeZKPMessage)}, + }, + targetProtocolMessage: protocol.CredentialFetchRequestMessageType, + targetMediatype: packers.MediaTypePlainMessage, + expected: false, + strictMode: true, + }, + { + name: "strictMode = true. Empty allow list", + allowList: map[iden3comm.ProtocolMessage][]string{}, + targetProtocolMessage: protocol.CredentialFetchRequestMessageType, + targetMediatype: packers.MediaTypePlainMessage, + expected: false, + strictMode: true, + }, + { + name: "strictMode = false. Empty allow list", + allowList: map[iden3comm.ProtocolMessage][]string{}, + targetProtocolMessage: protocol.CredentialFetchRequestMessageType, + targetMediatype: packers.MediaTypePlainMessage, + expected: true, + strictMode: false, + }, + } + + for _, tt := range testcases { + t.Run(tt.name, func(t *testing.T) { + mdm := services.NewMediaTypeManager( + tt.allowList, tt.strictMode, + ) + actual := mdm.AllowMediaType( + tt.targetProtocolMessage, tt.targetMediatype, + ) + require.Equal(t, tt.expected, actual) + }) + } +} + +func TestMediatypeManager_DefaultPacker(t *testing.T) { + type testcase struct { + name string + targetProtocolMessage iden3comm.ProtocolMessage + targetMediatype iden3comm.MediaType + expected bool + } + testcases := []testcase{ + { + name: "call CredentialFetchRequestMessageType with MediaTypePlainMessage", + targetProtocolMessage: protocol.CredentialFetchRequestMessageType, + targetMediatype: packers.MediaTypePlainMessage, + expected: false, + }, + { + name: "call CredentialFetchRequestMessageType with MediaTypeZKPMessage", + targetProtocolMessage: protocol.CredentialFetchRequestMessageType, + targetMediatype: packers.MediaTypeZKPMessage, + expected: true, + }, + { + name: "call RevocationStatusRequestMessageType with MediaTypePlainMessage", + targetProtocolMessage: protocol.RevocationStatusRequestMessageType, + targetMediatype: packers.MediaTypePlainMessage, + expected: true, + }, + { + name: "call RevocationStatusRequestMessageType with MediaTypeZKPMessage", + targetProtocolMessage: protocol.RevocationStatusRequestMessageType, + targetMediatype: packers.MediaTypeZKPMessage, + expected: true, + }, + } + + for _, tt := range testcases { + t.Run(tt.name, func(t *testing.T) { + actual := services.DefaultMediaTypeManager.AllowMediaType(tt.targetProtocolMessage, tt.targetMediatype) + require.Equal(t, tt.expected, actual) + }) + } +} diff --git a/internal/core/services/tests/identity_test.go b/internal/core/services/tests/identity_test.go index 2e4c62cd8..5a63e2e6e 100644 --- a/internal/core/services/tests/identity_test.go +++ b/internal/core/services/tests/identity_test.go @@ -40,8 +40,8 @@ func Test_identity_UpdateState(t *testing.T) { connectionsRepository := repositories.NewConnections() rhsFactory := reverse_hash.NewFactory(cfg.CredentialStatus.RHS.URL, nil, commonEth.HexToAddress(cfg.CredentialStatus.OnchainTreeStore.SupportedTreeStoreContract), reverse_hash.DefaultRHSTimeOut) revocationStatusResolver := revocation_status.NewRevocationStatusResolver(cfg.CredentialStatus) - identityService := services.NewIdentity(keyStore, identityRepo, mtRepo, identityStateRepo, mtService, nil, claimsRepo, revocationRepository, connectionsRepository, storage, nil, nil, pubsub.NewMock(), cfg.CredentialStatus, rhsFactory, revocationStatusResolver) - claimsService := services.NewClaim(claimsRepo, identityService, nil, mtService, identityStateRepo, docLoader, storage, cfg.CredentialStatus.Iden3CommAgentStatus.GetURL(), pubsub.NewMock(), ipfsGateway, revocationStatusResolver) + identityService := services.NewIdentity(keyStore, identityRepo, mtRepo, identityStateRepo, mtService, nil, claimsRepo, revocationRepository, connectionsRepository, storage, nil, nil, pubsub.NewMock(), cfg.CredentialStatus, rhsFactory, revocationStatusResolver, *cfg.AutoPublishingToOnChainRHS) + claimsService := services.NewClaim(claimsRepo, identityService, nil, mtService, identityStateRepo, docLoader, storage, cfg.CredentialStatus.Iden3CommAgentStatus.GetURL(), pubsub.NewMock(), ipfsGateway, revocationStatusResolver, &services.DefaultMediaTypeManager) identity, err := identityService.Create(ctx, "polygon-test", &ports.DIDCreationOptions{Method: method, Blockchain: blockchain, Network: network, KeyType: BJJ}) require.NoError(t, err) @@ -219,7 +219,7 @@ func Test_identity_GetByDID(t *testing.T) { connectionsRepository := repositories.NewConnections() rhsFactory := reverse_hash.NewFactory(cfg.CredentialStatus.RHS.URL, nil, commonEth.HexToAddress(cfg.CredentialStatus.OnchainTreeStore.SupportedTreeStoreContract), reverse_hash.DefaultRHSTimeOut) revocationStatusResolver := revocation_status.NewRevocationStatusResolver(cfg.CredentialStatus) - identityService := services.NewIdentity(keyStore, identityRepo, mtRepo, identityStateRepo, mtService, nil, claimsRepo, revocationRepository, connectionsRepository, storage, nil, nil, pubsub.NewMock(), cfg.CredentialStatus, rhsFactory, revocationStatusResolver) + identityService := services.NewIdentity(keyStore, identityRepo, mtRepo, identityStateRepo, mtService, nil, claimsRepo, revocationRepository, connectionsRepository, storage, nil, nil, pubsub.NewMock(), cfg.CredentialStatus, rhsFactory, revocationStatusResolver, *cfg.AutoPublishingToOnChainRHS) identity, err := identityService.Create(ctx, "polygon-test", &ports.DIDCreationOptions{Method: method, Blockchain: blockchain, Network: network, KeyType: BJJ}) assert.NoError(t, err) diff --git a/internal/core/services/tests/link_test.go b/internal/core/services/tests/link_test.go index 1d1de11cb..0b110f761 100644 --- a/internal/core/services/tests/link_test.go +++ b/internal/core/services/tests/link_test.go @@ -36,10 +36,10 @@ func Test_link_issueClaim(t *testing.T) { connectionsRepository := repositories.NewConnections() rhsFactory := reverse_hash.NewFactory(cfg.CredentialStatus.RHS.URL, nil, commonEth.HexToAddress(cfg.CredentialStatus.OnchainTreeStore.SupportedTreeStoreContract), reverse_hash.DefaultRHSTimeOut) revocationStatusResolver := revocation_status.NewRevocationStatusResolver(cfg.CredentialStatus) - identityService := services.NewIdentity(keyStore, identityRepo, mtRepo, identityStateRepo, mtService, nil, claimsRepo, revocationRepository, connectionsRepository, storage, nil, nil, pubsub.NewMock(), cfg.CredentialStatus, rhsFactory, revocationStatusResolver) + identityService := services.NewIdentity(keyStore, identityRepo, mtRepo, identityStateRepo, mtService, nil, claimsRepo, revocationRepository, connectionsRepository, storage, nil, nil, pubsub.NewMock(), cfg.CredentialStatus, rhsFactory, revocationStatusResolver, *cfg.AutoPublishingToOnChainRHS) sessionRepository := repositories.NewSessionCached(cachex) schemaService := services.NewSchema(schemaRepository, docLoader) - claimsService := services.NewClaim(claimsRepo, identityService, nil, mtService, identityStateRepo, docLoader, storage, cfg.CredentialStatus.Iden3CommAgentStatus.GetURL(), pubsub.NewMock(), ipfsGateway, revocationStatusResolver) + claimsService := services.NewClaim(claimsRepo, identityService, nil, mtService, identityStateRepo, docLoader, storage, cfg.CredentialStatus.Iden3CommAgentStatus.GetURL(), pubsub.NewMock(), ipfsGateway, revocationStatusResolver, &services.DefaultMediaTypeManager) identity, err := identityService.Create(ctx, "polygon-test", &ports.DIDCreationOptions{Method: method, Blockchain: blockchain, Network: network, KeyType: BJJ}) assert.NoError(t, err) diff --git a/internal/core/services/tests/main_test.go b/internal/core/services/tests/main_test.go index a0bac0440..3e9be27c7 100644 --- a/internal/core/services/tests/main_test.go +++ b/internal/core/services/tests/main_test.go @@ -7,6 +7,7 @@ import ( "github.com/hashicorp/vault/api" + "github.com/polygonid/sh-id-platform/internal/common" "github.com/polygonid/sh-id-platform/internal/config" "github.com/polygonid/sh-id-platform/internal/db" "github.com/polygonid/sh-id-platform/internal/db/tests" @@ -92,6 +93,7 @@ func TestMain(m *testing.M) { docLoader = loader.NewDocumentLoader(ipfsGatewayURL) + cfg.AutoPublishingToOnChainRHS = common.ToPointer[bool](true) cfg.CredentialStatus = config.CredentialStatus{ RHSMode: "None", Iden3CommAgentStatus: config.Iden3CommAgentStatus{ diff --git a/internal/core/services/tests/notification_test.go b/internal/core/services/tests/notification_test.go index 71ed3472a..78e2aec30 100644 --- a/internal/core/services/tests/notification_test.go +++ b/internal/core/services/tests/notification_test.go @@ -40,8 +40,8 @@ func TestNotification_SendNotification(t *testing.T) { connectionsRepository := repositories.NewConnections() rhsFactory := reverse_hash.NewFactory(cfg.CredentialStatus.RHS.URL, nil, commonEth.HexToAddress(cfg.CredentialStatus.OnchainTreeStore.SupportedTreeStoreContract), reverse_hash.DefaultRHSTimeOut) revocationStatusResolver := revocation_status.NewRevocationStatusResolver(cfg.CredentialStatus) - identityService := services.NewIdentity(keyStore, identityRepo, mtRepo, identityStateRepo, mtService, nil, claimsRepo, revocationRepository, connectionsRepository, storage, nil, nil, pubsub.NewMock(), cfg.CredentialStatus, rhsFactory, revocationStatusResolver) - credentialsService := services.NewClaim(claimsRepo, identityService, nil, mtService, identityStateRepo, docLoader, storage, cfg.CredentialStatus.Iden3CommAgentStatus.GetURL(), pubsub.NewMock(), ipfsGateway, revocationStatusResolver) + identityService := services.NewIdentity(keyStore, identityRepo, mtRepo, identityStateRepo, mtService, nil, claimsRepo, revocationRepository, connectionsRepository, storage, nil, nil, pubsub.NewMock(), cfg.CredentialStatus, rhsFactory, revocationStatusResolver, *cfg.AutoPublishingToOnChainRHS) + credentialsService := services.NewClaim(claimsRepo, identityService, nil, mtService, identityStateRepo, docLoader, storage, cfg.CredentialStatus.Iden3CommAgentStatus.GetURL(), pubsub.NewMock(), ipfsGateway, revocationStatusResolver, &services.DefaultMediaTypeManager) connectionsService := services.NewConnection(connectionsRepository, claimsRepo, storage) iden, err := identityService.Create(ctx, "polygon-test", &ports.DIDCreationOptions{Method: method, Blockchain: blockchain, Network: network, KeyType: BJJ}) require.NoError(t, err) From c314c16ad5bc16d7727329d4cbc5584269c07d13 Mon Sep 17 00:00:00 2001 From: Roderik van der Veer Date: Mon, 17 Jun 2024 13:38:27 +0200 Subject: [PATCH 26/52] fix: invisible characters (#671) --- k8s/helm/values.yaml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/k8s/helm/values.yaml b/k8s/helm/values.yaml index 74fd7a223..0d261de1b 100644 --- a/k8s/helm/values.yaml +++ b/k8s/helm/values.yaml @@ -204,7 +204,7 @@ uiIssuerNode: issuerApiUiIssuerName: my issuer k8s issuerUiAuthUsername: user-ui issuerUiBlockExplorerUrlMumbai: https://mumbai.polygonscan.com - issuerUiBlockExplorerUrlAmoy: https://www.oklink.com/amoy‍ + issuerUiBlockExplorerUrlAmoy: https://www.oklink.com/amoy issuerUiBlockExplorerUrlMain: https://polygonscan.com/ issuerUiIpfsGatewayUrl: https://ipfs.io issuerApiUiName: issuer-node-ui-configmap From 15f1183010a6b6fdcf68246b69e1018c757cbc23 Mon Sep 17 00:00:00 2001 From: Ilya Date: Mon, 17 Jun 2024 15:19:22 +0300 Subject: [PATCH 27/52] to common code style --- internal/core/services/identity.go | 14 +++++++------- internal/core/services/mediatype_manager.go | 5 +---- 2 files changed, 8 insertions(+), 11 deletions(-) diff --git a/internal/core/services/identity.go b/internal/core/services/identity.go index 46b1c5867..c15d8502d 100644 --- a/internal/core/services/identity.go +++ b/internal/core/services/identity.go @@ -751,13 +751,13 @@ func (i *identity) createIdentity(ctx context.Context, tx db.Querier, hostURL st if len(rhsPublishers) > 0 { if rhsMode == reverse_hash.RHSModeOnChain && !i.autoPublishingToOnChainRHS { - log.Info(ctx, ` - state info (hashes): - root: '%s', - ClaimsTreeRoot: '%s', - RevocationsTreeRoot: '%s', - RootOfRootsTreeRoot: '%s', - `, identity.State.TreeState().State, claimsTree.Root(), &merkletree.HashZero, &merkletree.HashZero) + log.Info(ctx, + "state info (bigints):", + "root:", identity.State.TreeState().State.BigInt().String(), + "claimsTreeRoot:", claimsTree.Root().BigInt().String(), + "revocationsTreeRoot:", merkletree.HashZero.BigInt().String(), + "rootOfRootsTreeRoot:", merkletree.HashZero.BigInt().String(), + ) } else { log.Info(ctx, "publishing state to RHS", "publishers", len(rhsPublishers)) for _, rhsPublisher := range rhsPublishers { diff --git a/internal/core/services/mediatype_manager.go b/internal/core/services/mediatype_manager.go index 8b0801b52..4e19157d4 100644 --- a/internal/core/services/mediatype_manager.go +++ b/internal/core/services/mediatype_manager.go @@ -31,10 +31,7 @@ func NewMediaTypeManager(allowList map[iden3comm.ProtocolMessage][]string, stric } // AllowMediaType check if the protocol message supports the mediaType type -func (m *MediaTypeManager) AllowMediaType( - protoclMessage iden3comm.ProtocolMessage, - mediaType iden3comm.MediaType, -) bool { +func (m *MediaTypeManager) AllowMediaType(protoclMessage iden3comm.ProtocolMessage, mediaType iden3comm.MediaType) bool { al, ok := m.allowList[protoclMessage] if !ok { return !m.strictMode From c1e1773cbd4718acc8dbe6d4a4e22923bfd673e3 Mon Sep 17 00:00:00 2001 From: Ilya Date: Thu, 20 Jun 2024 17:22:12 +0300 Subject: [PATCH 28/52] support flag to disable mediatype checker --- cmd/notifications/main.go | 14 +- cmd/pending_publisher/main.go | 14 +- cmd/platform/main.go | 15 +- cmd/platform_ui/main.go | 15 +- internal/api/server_test.go | 91 +++++- internal/api_ui/server_test.go | 264 ++++++++++++++++-- internal/config/config.go | 15 + internal/core/services/mediatype_manager.go | 21 +- .../core/services/mediatype_manager_test.go | 61 ++-- internal/core/services/tests/identity_test.go | 15 +- internal/core/services/tests/link_test.go | 15 +- .../core/services/tests/notification_test.go | 15 +- pkg/protocol/verify.go | 53 ++-- 13 files changed, 486 insertions(+), 122 deletions(-) diff --git a/cmd/notifications/main.go b/cmd/notifications/main.go index 693935351..4bb8f6d87 100644 --- a/cmd/notifications/main.go +++ b/cmd/notifications/main.go @@ -12,6 +12,9 @@ import ( "github.com/ethereum/go-ethereum/common" "github.com/ethereum/go-ethereum/ethclient" vault "github.com/hashicorp/vault/api" + "github.com/iden3/iden3comm/v2" + "github.com/iden3/iden3comm/v2/packers" + "github.com/iden3/iden3comm/v2/protocol" "github.com/polygonid/sh-id-platform/internal/buildinfo" "github.com/polygonid/sh-id-platform/internal/config" @@ -179,8 +182,17 @@ func newCredentialsService(ctx context.Context, cfg *config.Configuration, stora mtService := services.NewIdentityMerkleTrees(mtRepository) qrService := services.NewQrStoreService(cachex) + mediaTypeManager := services.NewMediaTypeManager( + map[iden3comm.ProtocolMessage][]string{ + protocol.CredentialFetchRequestMessageType: {string(packers.MediaTypeZKPMessage)}, + protocol.RevocationStatusRequestMessageType: {"*"}, + }, + *cfg.MediaTypeManager.StrictMode, + cfg.MediaTypeManager.Disable, + ) + identityService := services.NewIdentity(keyStore, identityRepository, mtRepository, identityStateRepository, mtService, qrService, claimsRepository, revocationRepository, nil, storage, nil, nil, ps, cfg.CredentialStatus, rhsFactory, revocationStatusResolver, *cfg.AutoPublishingToOnChainRHS) - claimsService := services.NewClaim(claimsRepository, identityService, qrService, mtService, identityStateRepository, schemaLoader, storage, cfg.APIUI.ServerURL, ps, cfg.IPFS.GatewayURL, revocationStatusResolver, &services.DefaultMediaTypeManager) + claimsService := services.NewClaim(claimsRepository, identityService, qrService, mtService, identityStateRepository, schemaLoader, storage, cfg.APIUI.ServerURL, ps, cfg.IPFS.GatewayURL, revocationStatusResolver, mediaTypeManager) return claimsService, nil } diff --git a/cmd/pending_publisher/main.go b/cmd/pending_publisher/main.go index 6799d4d69..ffb060912 100644 --- a/cmd/pending_publisher/main.go +++ b/cmd/pending_publisher/main.go @@ -12,6 +12,9 @@ import ( "github.com/ethereum/go-ethereum/common" "github.com/ethereum/go-ethereum/ethclient" vault "github.com/hashicorp/vault/api" + "github.com/iden3/iden3comm/v2" + "github.com/iden3/iden3comm/v2/packers" + "github.com/iden3/iden3comm/v2/protocol" "github.com/polygonid/sh-id-platform/internal/buildinfo" "github.com/polygonid/sh-id-platform/internal/config" @@ -160,8 +163,17 @@ func main() { rhsFactory := reverse_hash.NewFactory(cfg.CredentialStatus.RHS.GetURL(), cl, common.HexToAddress(cfg.CredentialStatus.OnchainTreeStore.SupportedTreeStoreContract), reverse_hash.DefaultRHSTimeOut) revocationStatusResolver := revocation_status.NewRevocationStatusResolver(cfg.CredentialStatus) + mediaTypeManager := services.NewMediaTypeManager( + map[iden3comm.ProtocolMessage][]string{ + protocol.CredentialFetchRequestMessageType: {string(packers.MediaTypeZKPMessage)}, + protocol.RevocationStatusRequestMessageType: {"*"}, + }, + *cfg.MediaTypeManager.StrictMode, + cfg.MediaTypeManager.Disable, + ) + identityService := services.NewIdentity(keyStore, identityRepo, mtRepo, identityStateRepo, mtService, qrService, claimsRepo, revocationRepository, connectionsRepository, storage, nil, nil, pubsub.NewMock(), cfg.CredentialStatus, rhsFactory, revocationStatusResolver, *cfg.AutoPublishingToOnChainRHS) - claimsService := services.NewClaim(claimsRepo, identityService, qrService, mtService, identityStateRepo, schemaLoader, storage, cfg.APIUI.ServerURL, ps, cfg.IPFS.GatewayURL, revocationStatusResolver, &services.DefaultMediaTypeManager) + claimsService := services.NewClaim(claimsRepo, identityService, qrService, mtService, identityStateRepo, schemaLoader, storage, cfg.APIUI.ServerURL, ps, cfg.IPFS.GatewayURL, revocationStatusResolver, mediaTypeManager) circuitsLoaderService := circuitLoaders.NewCircuits(cfg.Circuit.Path) proofService := initProofService(ctx, cfg, circuitsLoaderService) diff --git a/cmd/platform/main.go b/cmd/platform/main.go index 88942b011..0e8c7eaab 100644 --- a/cmd/platform/main.go +++ b/cmd/platform/main.go @@ -14,6 +14,9 @@ import ( "github.com/go-chi/cors" redis2 "github.com/go-redis/redis/v8" vault "github.com/hashicorp/vault/api" + "github.com/iden3/iden3comm/v2" + "github.com/iden3/iden3comm/v2/packers" + iden3commProtocol "github.com/iden3/iden3comm/v2/protocol" "github.com/polygonid/sh-id-platform/internal/api" "github.com/polygonid/sh-id-platform/internal/buildinfo" @@ -141,9 +144,19 @@ func main() { qrService := services.NewQrStoreService(cachex) cfg.CredentialStatus.SingleIssuer = false + + mediaTypeManager := services.NewMediaTypeManager( + map[iden3comm.ProtocolMessage][]string{ + iden3commProtocol.CredentialFetchRequestMessageType: {string(packers.MediaTypeZKPMessage)}, + iden3commProtocol.RevocationStatusRequestMessageType: {"*"}, + }, + *cfg.MediaTypeManager.StrictMode, + cfg.MediaTypeManager.Disable, + ) + revocationStatusResolver := revocation_status.NewRevocationStatusResolver(cfg.CredentialStatus) identityService := services.NewIdentity(keyStore, identityRepository, mtRepository, identityStateRepository, mtService, qrService, claimsRepository, revocationRepository, nil, storage, nil, nil, ps, cfg.CredentialStatus, rhsFactory, revocationStatusResolver, *cfg.AutoPublishingToOnChainRHS) - claimsService := services.NewClaim(claimsRepository, identityService, qrService, mtService, identityStateRepository, schemaLoader, storage, cfg.ServerUrl, ps, cfg.IPFS.GatewayURL, revocationStatusResolver, &services.DefaultMediaTypeManager) + claimsService := services.NewClaim(claimsRepository, identityService, qrService, mtService, identityStateRepository, schemaLoader, storage, cfg.ServerUrl, ps, cfg.IPFS.GatewayURL, revocationStatusResolver, mediaTypeManager) proofService := gateways.NewProver(ctx, cfg, circuitsLoaderService) transactionService, err := gateways.NewTransaction(ethereumClient, cfg.Ethereum.ConfirmationBlockCount) diff --git a/cmd/platform_ui/main.go b/cmd/platform_ui/main.go index 5f41eef49..f2b573e4d 100644 --- a/cmd/platform_ui/main.go +++ b/cmd/platform_ui/main.go @@ -20,6 +20,9 @@ import ( "github.com/iden3/go-iden3-auth/v2/pubsignals" "github.com/iden3/go-iden3-auth/v2/state" "github.com/iden3/go-iden3-core/v2/w3c" + "github.com/iden3/iden3comm/v2" + "github.com/iden3/iden3comm/v2/packers" + iden3commProtocol "github.com/iden3/iden3comm/v2/protocol" "github.com/polygonid/sh-id-platform/internal/api_ui" "github.com/polygonid/sh-id-platform/internal/buildinfo" @@ -173,10 +176,20 @@ func main() { qrService := services.NewQrStoreService(cachex) cfg.CredentialStatus.SingleIssuer = true + + mediaTypeManager := services.NewMediaTypeManager( + map[iden3comm.ProtocolMessage][]string{ + iden3commProtocol.CredentialFetchRequestMessageType: {string(packers.MediaTypeZKPMessage)}, + iden3commProtocol.RevocationStatusRequestMessageType: {"*"}, + }, + *cfg.MediaTypeManager.StrictMode, + cfg.MediaTypeManager.Disable, + ) + revocationStatusResolver := revocation_status.NewRevocationStatusResolver(cfg.CredentialStatus) identityService := services.NewIdentity(keyStore, identityRepository, mtRepository, identityStateRepository, mtService, qrService, claimsRepository, revocationRepository, connectionsRepository, storage, verifier, sessionRepository, ps, cfg.CredentialStatus, rhsFactory, revocationStatusResolver, *cfg.AutoPublishingToOnChainRHS) schemaService := services.NewSchema(schemaRepository, schemaLoader) - claimsService := services.NewClaim(claimsRepository, identityService, qrService, mtService, identityStateRepository, schemaLoader, storage, cfg.APIUI.ServerURL, ps, cfg.IPFS.GatewayURL, revocationStatusResolver, &services.DefaultMediaTypeManager) + claimsService := services.NewClaim(claimsRepository, identityService, qrService, mtService, identityStateRepository, schemaLoader, storage, cfg.APIUI.ServerURL, ps, cfg.IPFS.GatewayURL, revocationStatusResolver, mediaTypeManager) connectionsService := services.NewConnection(connectionsRepository, claimsRepository, storage) linkService := services.NewLinkService(storage, claimsService, qrService, claimsRepository, linkRepository, schemaRepository, schemaLoader, sessionRepository, ps, cfg.IPFS.GatewayURL) diff --git a/internal/api/server_test.go b/internal/api/server_test.go index 73642a479..aa3686fc4 100644 --- a/internal/api/server_test.go +++ b/internal/api/server_test.go @@ -16,6 +16,7 @@ import ( core "github.com/iden3/go-iden3-core/v2" "github.com/iden3/go-iden3-core/v2/w3c" "github.com/iden3/go-schema-processor/v2/verifiable" + "github.com/iden3/iden3comm/v2" "github.com/iden3/iden3comm/v2/packers" "github.com/iden3/iden3comm/v2/protocol" "github.com/mitchellh/mapstructure" @@ -54,7 +55,15 @@ func TestServer_CreateIdentity(t *testing.T) { revocationStatusResolver := revocation_status.NewRevocationStatusResolver(cfg.CredentialStatus) identityService := services.NewIdentity(keyStore, identityRepo, mtRepo, identityStateRepo, mtService, nil, claimsRepo, revocationRepository, connectionsRepository, storage, nil, nil, pubsub.NewMock(), cfg.CredentialStatus, rhsFactory, revocationStatusResolver, *cfg.AutoPublishingToOnChainRHS) - claimsService := services.NewClaim(claimsRepo, identityService, nil, mtService, identityStateRepo, schemaLoader, storage, cfg.CredentialStatus.Iden3CommAgentStatus.GetURL(), pubsub.NewMock(), ipfsGatewayURL, revocationStatusResolver, &services.DefaultMediaTypeManager) + mediaTypeManager := services.NewMediaTypeManager( + map[iden3comm.ProtocolMessage][]string{ + protocol.CredentialFetchRequestMessageType: {string(packers.MediaTypeZKPMessage)}, + protocol.RevocationStatusRequestMessageType: {"*"}, + }, + true, + false, + ) + claimsService := services.NewClaim(claimsRepo, identityService, nil, mtService, identityStateRepo, schemaLoader, storage, cfg.CredentialStatus.Iden3CommAgentStatus.GetURL(), pubsub.NewMock(), ipfsGatewayURL, revocationStatusResolver, mediaTypeManager) accountService := services.NewAccountService(cfg.Ethereum, keyStore) server := NewServer(&cfg, identityService, accountService, claimsService, nil, NewPublisherMock(), NewPackageManagerMock(), nil) handler := getHandler(context.Background(), server) @@ -251,7 +260,15 @@ func TestServer_RevokeClaim(t *testing.T) { rhsFactory := reverse_hash.NewFactory(cfg.CredentialStatus.RHS.GetURL(), nil, commonEth.HexToAddress(cfg.CredentialStatus.OnchainTreeStore.SupportedTreeStoreContract), reverse_hash.DefaultRHSTimeOut) identityService := services.NewIdentity(&KMSMock{}, identityRepo, mtRepo, identityStateRepo, mtService, nil, claimsRepo, revocationRepository, connectionsRepository, storage, nil, nil, pubsub.NewMock(), cfg.CredentialStatus, rhsFactory, revocationStatusResolver, *cfg.AutoPublishingToOnChainRHS) - claimsService := services.NewClaim(claimsRepo, identityService, nil, mtService, identityStateRepo, schemaLoader, storage, cfg.CredentialStatus.Iden3CommAgentStatus.GetURL(), pubsub.NewMock(), ipfsGatewayURL, revocationStatusResolver, &services.DefaultMediaTypeManager) + mediaTypeManager := services.NewMediaTypeManager( + map[iden3comm.ProtocolMessage][]string{ + protocol.CredentialFetchRequestMessageType: {string(packers.MediaTypeZKPMessage)}, + protocol.RevocationStatusRequestMessageType: {"*"}, + }, + true, + false, + ) + claimsService := services.NewClaim(claimsRepo, identityService, nil, mtService, identityStateRepo, schemaLoader, storage, cfg.CredentialStatus.Iden3CommAgentStatus.GetURL(), pubsub.NewMock(), ipfsGatewayURL, revocationStatusResolver, mediaTypeManager) accountService := services.NewAccountService(cfg.Ethereum, keyStore) server := NewServer(&cfg, identityService, accountService, claimsService, nil, NewPublisherMock(), NewPackageManagerMock(), nil) @@ -398,11 +415,20 @@ func TestServer_CreateClaim(t *testing.T) { revocationRepository := repositories.NewRevocation() connectionsRepository := repositories.NewConnections() + mediaTypeManager := services.NewMediaTypeManager( + map[iden3comm.ProtocolMessage][]string{ + protocol.CredentialFetchRequestMessageType: {string(packers.MediaTypeZKPMessage)}, + protocol.RevocationStatusRequestMessageType: {"*"}, + }, + true, + false, + ) + rhsFactory := reverse_hash.NewFactory(cfg.CredentialStatus.RHS.GetURL(), nil, commonEth.HexToAddress(cfg.CredentialStatus.OnchainTreeStore.SupportedTreeStoreContract), reverse_hash.DefaultRHSTimeOut) revocationStatusResolver := revocation_status.NewRevocationStatusResolver(cfg.CredentialStatus) identityService := services.NewIdentity(keyStore, identityRepo, mtRepo, identityStateRepo, mtService, qrService, claimsRepo, revocationRepository, connectionsRepository, storage, nil, nil, pubsub.NewMock(), cfg.CredentialStatus, rhsFactory, revocationStatusResolver, *cfg.AutoPublishingToOnChainRHS) pubSub := pubsub.NewMock() - claimsService := services.NewClaim(claimsRepo, identityService, nil, mtService, identityStateRepo, schemaLoader, storage, cfg.CredentialStatus.Iden3CommAgentStatus.GetURL(), pubSub, ipfsGatewayURL, revocationStatusResolver, &services.DefaultMediaTypeManager) + claimsService := services.NewClaim(claimsRepo, identityService, nil, mtService, identityStateRepo, schemaLoader, storage, cfg.CredentialStatus.Iden3CommAgentStatus.GetURL(), pubSub, ipfsGatewayURL, revocationStatusResolver, mediaTypeManager) accountService := services.NewAccountService(cfg.Ethereum, keyStore) server := NewServer(&cfg, identityService, accountService, claimsService, nil, NewPublisherMock(), NewPackageManagerMock(), nil) handler := getHandler(ctx, server) @@ -580,7 +606,16 @@ func TestServer_GetIdentities(t *testing.T) { revocationStatusResolver := revocation_status.NewRevocationStatusResolver(cfg.CredentialStatus) identityService := services.NewIdentity(&KMSMock{}, identityRepo, mtRepo, identityStateRepo, mtService, nil, claimsRepo, revocationRepository, connectionsRepository, storage, nil, nil, pubsub.NewMock(), cfg.CredentialStatus, rhsFactory, revocationStatusResolver, *cfg.AutoPublishingToOnChainRHS) - claimsService := services.NewClaim(claimsRepo, identityService, nil, mtService, identityStateRepo, schemaLoader, storage, cfg.CredentialStatus.Iden3CommAgentStatus.GetURL(), pubsub.NewMock(), ipfsGatewayURL, revocationStatusResolver, &services.DefaultMediaTypeManager) + mediaTypeManager := services.NewMediaTypeManager( + map[iden3comm.ProtocolMessage][]string{ + protocol.CredentialFetchRequestMessageType: {string(packers.MediaTypeZKPMessage)}, + protocol.RevocationStatusRequestMessageType: {"*"}, + }, + true, + false, + ) + + claimsService := services.NewClaim(claimsRepo, identityService, nil, mtService, identityStateRepo, schemaLoader, storage, cfg.CredentialStatus.Iden3CommAgentStatus.GetURL(), pubsub.NewMock(), ipfsGatewayURL, revocationStatusResolver, mediaTypeManager) accountService := services.NewAccountService(cfg.Ethereum, keyStore) server := NewServer(&cfg, identityService, accountService, claimsService, nil, NewPublisherMock(), NewPackageManagerMock(), nil) handler := getHandler(context.Background(), server) @@ -655,7 +690,17 @@ func TestServer_GetClaimQrCode(t *testing.T) { idStr := "did:polygonid:polygon:mumbai:2qPrv5Yx8s1qAmEnPym68LfT7gTbASGampiGU7TseL" idNoClaims := "did:polygonid:polygon:mumbai:2qGjTUuxZKqKS4Q8UmxHUPw55g15QgEVGnj6Wkq8Vk" accountService := services.NewAccountService(cfg.Ethereum, keyStore) - claimsService := services.NewClaim(claimsRepo, identityService, nil, mtService, identityStateRepo, schemaLoader, storage, cfg.CredentialStatus.Iden3CommAgentStatus.GetURL(), pubsub.NewMock(), ipfsGatewayURL, revocationStatusResolver, &services.DefaultMediaTypeManager) + + mediaTypeManager := services.NewMediaTypeManager( + map[iden3comm.ProtocolMessage][]string{ + protocol.CredentialFetchRequestMessageType: {string(packers.MediaTypeZKPMessage)}, + protocol.RevocationStatusRequestMessageType: {"*"}, + }, + true, + false, + ) + + claimsService := services.NewClaim(claimsRepo, identityService, nil, mtService, identityStateRepo, schemaLoader, storage, cfg.CredentialStatus.Iden3CommAgentStatus.GetURL(), pubsub.NewMock(), ipfsGatewayURL, revocationStatusResolver, mediaTypeManager) identity := &domain.Identity{ Identifier: idStr, @@ -795,7 +840,17 @@ func TestServer_GetClaim(t *testing.T) { revocationStatusResolver := revocation_status.NewRevocationStatusResolver(cfg.CredentialStatus) rhsFactory := reverse_hash.NewFactory(cfg.CredentialStatus.RHS.GetURL(), nil, commonEth.HexToAddress(cfg.CredentialStatus.OnchainTreeStore.SupportedTreeStoreContract), reverse_hash.DefaultRHSTimeOut) identityService := services.NewIdentity(&KMSMock{}, identityRepo, mtRepo, identityStateRepo, mtService, nil, claimsRepo, revocationRepository, connectionsRepository, storage, nil, nil, pubsub.NewMock(), cfg.CredentialStatus, rhsFactory, revocationStatusResolver, *cfg.AutoPublishingToOnChainRHS) - claimsService := services.NewClaim(claimsRepo, identityService, nil, mtService, identityStateRepo, schemaLoader, storage, cfg.CredentialStatus.Iden3CommAgentStatus.GetURL(), pubsub.NewMock(), ipfsGatewayURL, revocationStatusResolver, &services.DefaultMediaTypeManager) + + mediaTypeManager := services.NewMediaTypeManager( + map[iden3comm.ProtocolMessage][]string{ + protocol.CredentialFetchRequestMessageType: {string(packers.MediaTypeZKPMessage)}, + protocol.RevocationStatusRequestMessageType: {"*"}, + }, + true, + false, + ) + + claimsService := services.NewClaim(claimsRepo, identityService, nil, mtService, identityStateRepo, schemaLoader, storage, cfg.CredentialStatus.Iden3CommAgentStatus.GetURL(), pubsub.NewMock(), ipfsGatewayURL, revocationStatusResolver, mediaTypeManager) accountService := services.NewAccountService(cfg.Ethereum, keyStore) server := NewServer(&cfg, identityService, accountService, claimsService, nil, NewPublisherMock(), NewPackageManagerMock(), nil) @@ -969,7 +1024,17 @@ func TestServer_GetClaims(t *testing.T) { revocationStatusResolver := revocation_status.NewRevocationStatusResolver(cfg.CredentialStatus) rhsFactory := reverse_hash.NewFactory(cfg.CredentialStatus.RHS.GetURL(), nil, commonEth.HexToAddress(cfg.CredentialStatus.OnchainTreeStore.SupportedTreeStoreContract), reverse_hash.DefaultRHSTimeOut) identityService := services.NewIdentity(keyStore, identityRepo, mtRepo, identityStateRepo, mtService, nil, claimsRepo, revocationRepository, connectionsRepository, storage, nil, nil, pubsub.NewMock(), cfg.CredentialStatus, rhsFactory, revocationStatusResolver, *cfg.AutoPublishingToOnChainRHS) - claimsService := services.NewClaim(claimsRepo, identityService, nil, mtService, identityStateRepo, schemaLoader, storage, cfg.CredentialStatus.Iden3CommAgentStatus.GetURL(), pubsub.NewMock(), ipfsGatewayURL, revocationStatusResolver, &services.DefaultMediaTypeManager) + + mediaTypeManager := services.NewMediaTypeManager( + map[iden3comm.ProtocolMessage][]string{ + protocol.CredentialFetchRequestMessageType: {string(packers.MediaTypeZKPMessage)}, + protocol.RevocationStatusRequestMessageType: {"*"}, + }, + true, + false, + ) + + claimsService := services.NewClaim(claimsRepo, identityService, nil, mtService, identityStateRepo, schemaLoader, storage, cfg.CredentialStatus.Iden3CommAgentStatus.GetURL(), pubsub.NewMock(), ipfsGatewayURL, revocationStatusResolver, mediaTypeManager) fixture := tests.NewFixture(storage) @@ -1318,7 +1383,17 @@ func TestServer_GetRevocationStatus(t *testing.T) { identity, err := identityService.Create(ctx, "http://localhost:3001", &ports.DIDCreationOptions{Method: method, Blockchain: blockchain, Network: network, KeyType: BJJ}) assert.NoError(t, err) - claimsService := services.NewClaim(claimsRepo, identityService, nil, mtService, identityStateRepo, schemaLoader, storage, cfg.CredentialStatus.Iden3CommAgentStatus.GetURL(), pubsub.NewMock(), ipfsGatewayURL, revocationStatusResolver, &services.DefaultMediaTypeManager) + + mediaTypeManager := services.NewMediaTypeManager( + map[iden3comm.ProtocolMessage][]string{ + protocol.CredentialFetchRequestMessageType: {string(packers.MediaTypeZKPMessage)}, + protocol.RevocationStatusRequestMessageType: {"*"}, + }, + true, + false, + ) + + claimsService := services.NewClaim(claimsRepo, identityService, nil, mtService, identityStateRepo, schemaLoader, storage, cfg.CredentialStatus.Iden3CommAgentStatus.GetURL(), pubsub.NewMock(), ipfsGatewayURL, revocationStatusResolver, mediaTypeManager) accountService := services.NewAccountService(cfg.Ethereum, keyStore) server := NewServer(&cfg, identityService, accountService, claimsService, nil, NewPublisherMock(), NewPackageManagerMock(), nil) handler := getHandler(context.Background(), server) diff --git a/internal/api_ui/server_test.go b/internal/api_ui/server_test.go index 31a52cd65..d64396f36 100644 --- a/internal/api_ui/server_test.go +++ b/internal/api_ui/server_test.go @@ -17,6 +17,8 @@ import ( "github.com/google/uuid" "github.com/iden3/go-iden3-core/v2/w3c" "github.com/iden3/go-schema-processor/v2/verifiable" + "github.com/iden3/iden3comm/v2" + "github.com/iden3/iden3comm/v2/packers" "github.com/iden3/iden3comm/v2/protocol" "github.com/mitchellh/mapstructure" "github.com/stretchr/testify/assert" @@ -49,7 +51,17 @@ func TestServer_CheckStatus(t *testing.T) { rhsFactory := reverse_hash.NewFactory(cfg.CredentialStatus.RHS.URL, nil, commonEth.HexToAddress(cfg.CredentialStatus.OnchainTreeStore.SupportedTreeStoreContract), reverse_hash.DefaultRHSTimeOut) identityService := services.NewIdentity(&KMSMock{}, identityRepo, mtRepo, identityStateRepo, mtService, nil, claimsRepo, revocationRepository, connectionsRepository, storage, nil, nil, pubsub.NewMock(), cfg.CredentialStatus, rhsFactory, revocationStatusResolver, *cfg.AutoPublishingToOnChainRHS) schemaService := services.NewSchema(repositories.NewSchema(*storage), schemaLoader) - claimsService := services.NewClaim(claimsRepo, identityService, nil, mtService, identityStateRepo, schemaLoader, storage, "http://localhost", pubsub.NewMock(), ipfsGatewayURL, revocationStatusResolver, &services.DefaultMediaTypeManager) + + mediaTypeManager := services.NewMediaTypeManager( + map[iden3comm.ProtocolMessage][]string{ + protocol.CredentialFetchRequestMessageType: {string(packers.MediaTypeZKPMessage)}, + protocol.RevocationStatusRequestMessageType: {"*"}, + }, + true, + false, + ) + + claimsService := services.NewClaim(claimsRepo, identityService, nil, mtService, identityStateRepo, schemaLoader, storage, "http://localhost", pubsub.NewMock(), ipfsGatewayURL, revocationStatusResolver, mediaTypeManager) server := NewServer(&cfg, identityService, claimsService, schemaService, NewConnectionsMock(), NewLinkMock(), nil, NewPublisherMock(), NewPackageManagerMock(), &health.Status{}) handler := getHandler(context.Background(), server) @@ -806,7 +818,16 @@ func TestServer_DeleteConnection(t *testing.T) { rhsFactory := reverse_hash.NewFactory(cfg.CredentialStatus.RHS.URL, nil, commonEth.HexToAddress(cfg.CredentialStatus.OnchainTreeStore.SupportedTreeStoreContract), reverse_hash.DefaultRHSTimeOut) identityService := services.NewIdentity(keyStore, identityRepo, mtRepo, identityStateRepo, mtService, nil, claimsRepo, revocationRepository, connectionsRepository, storage, nil, nil, pubsub.NewMock(), cfg.CredentialStatus, rhsFactory, revocationStatusResolver, *cfg.AutoPublishingToOnChainRHS) - claimsService := services.NewClaim(claimsRepo, identityService, nil, mtService, identityStateRepo, schemaLoader, storage, cfg.CredentialStatus.Iden3CommAgentStatus.GetURL(), pubsub.NewMock(), ipfsGatewayURL, revocationStatusResolver, &services.DefaultMediaTypeManager) + mediaTypeManager := services.NewMediaTypeManager( + map[iden3comm.ProtocolMessage][]string{ + protocol.CredentialFetchRequestMessageType: {string(packers.MediaTypeZKPMessage)}, + protocol.RevocationStatusRequestMessageType: {"*"}, + }, + true, + false, + ) + + claimsService := services.NewClaim(claimsRepo, identityService, nil, mtService, identityStateRepo, schemaLoader, storage, cfg.CredentialStatus.Iden3CommAgentStatus.GetURL(), pubsub.NewMock(), ipfsGatewayURL, revocationStatusResolver, mediaTypeManager) connectionsService := services.NewConnection(connectionsRepository, claimsRepo, storage) iden, err := identityService.Create(ctx, "polygon-test", &ports.DIDCreationOptions{Method: method, Blockchain: blockchain, Network: network, KeyType: BJJ}) @@ -1056,7 +1077,17 @@ func TestServer_RevokeConnectionCredentials(t *testing.T) { revocationStatusResolver := revocation_status.NewRevocationStatusResolver(cfg.CredentialStatus) rhsFactory := reverse_hash.NewFactory(cfg.CredentialStatus.RHS.URL, nil, commonEth.HexToAddress(cfg.CredentialStatus.OnchainTreeStore.SupportedTreeStoreContract), reverse_hash.DefaultRHSTimeOut) identityService := services.NewIdentity(keyStore, identityRepo, mtRepo, identityStateRepo, mtService, nil, claimsRepo, revocationRepository, connectionsRepository, storage, nil, nil, pubsub.NewMock(), cfg.CredentialStatus, rhsFactory, revocationStatusResolver, *cfg.AutoPublishingToOnChainRHS) - claimsService := services.NewClaim(claimsRepo, identityService, nil, mtService, identityStateRepo, schemaLoader, storage, "http://localhost", pubsub.NewMock(), ipfsGatewayURL, revocationStatusResolver, &services.DefaultMediaTypeManager) + + mediaTypeManager := services.NewMediaTypeManager( + map[iden3comm.ProtocolMessage][]string{ + protocol.CredentialFetchRequestMessageType: {string(packers.MediaTypeZKPMessage)}, + protocol.RevocationStatusRequestMessageType: {"*"}, + }, + true, + false, + ) + + claimsService := services.NewClaim(claimsRepo, identityService, nil, mtService, identityStateRepo, schemaLoader, storage, "http://localhost", pubsub.NewMock(), ipfsGatewayURL, revocationStatusResolver, mediaTypeManager) connectionsService := services.NewConnection(connectionsRepository, claimsRepo, storage) iden, err := identityService.Create(ctx, "polygon-test", &ports.DIDCreationOptions{Method: method, Blockchain: blockchain, Network: network, KeyType: BJJ}) @@ -1168,7 +1199,17 @@ func TestServer_CreateCredential(t *testing.T) { rhsFactory := reverse_hash.NewFactory(cfg.CredentialStatus.RHS.URL, nil, commonEth.HexToAddress(cfg.CredentialStatus.OnchainTreeStore.SupportedTreeStoreContract), reverse_hash.DefaultRHSTimeOut) identityService := services.NewIdentity(keyStore, identityRepo, mtRepo, identityStateRepo, mtService, nil, claimsRepo, revocationRepository, connectionsRepository, storage, nil, nil, pubsub.NewMock(), cfg.CredentialStatus, rhsFactory, revocationStatusResolver, *cfg.AutoPublishingToOnChainRHS) pubSub := pubsub.NewMock() - claimsService := services.NewClaim(claimsRepo, identityService, nil, mtService, identityStateRepo, schemaLoader, storage, cfg.CredentialStatus.Iden3CommAgentStatus.GetURL(), pubSub, ipfsGatewayURL, revocationStatusResolver, &services.DefaultMediaTypeManager) + + mediaTypeManager := services.NewMediaTypeManager( + map[iden3comm.ProtocolMessage][]string{ + protocol.CredentialFetchRequestMessageType: {string(packers.MediaTypeZKPMessage)}, + protocol.RevocationStatusRequestMessageType: {"*"}, + }, + true, + false, + ) + + claimsService := services.NewClaim(claimsRepo, identityService, nil, mtService, identityStateRepo, schemaLoader, storage, cfg.CredentialStatus.Iden3CommAgentStatus.GetURL(), pubSub, ipfsGatewayURL, revocationStatusResolver, mediaTypeManager) connectionsService := services.NewConnection(connectionsRepository, claimsRepo, storage) iden, err := identityService.Create(ctx, "polygon-test", &ports.DIDCreationOptions{Method: method, Blockchain: blockchain, Network: network, KeyType: BJJ}) require.NoError(t, err) @@ -1344,7 +1385,17 @@ func TestServer_DeleteCredential(t *testing.T) { revocationStatusResolver := revocation_status.NewRevocationStatusResolver(cfg.CredentialStatus) rhsFactory := reverse_hash.NewFactory(cfg.CredentialStatus.RHS.URL, nil, commonEth.HexToAddress(cfg.CredentialStatus.OnchainTreeStore.SupportedTreeStoreContract), reverse_hash.DefaultRHSTimeOut) identityService := services.NewIdentity(keyStore, identityRepo, mtRepo, identityStateRepo, mtService, nil, claimsRepo, revocationRepository, connectionsRepository, storage, nil, nil, pubsub.NewMock(), cfg.CredentialStatus, rhsFactory, revocationStatusResolver, *cfg.AutoPublishingToOnChainRHS) - claimsService := services.NewClaim(claimsRepo, identityService, nil, mtService, identityStateRepo, schemaLoader, storage, "http://localhost", pubsub.NewMock(), ipfsGatewayURL, revocationStatusResolver, &services.DefaultMediaTypeManager) + + mediaTypeManager := services.NewMediaTypeManager( + map[iden3comm.ProtocolMessage][]string{ + protocol.CredentialFetchRequestMessageType: {string(packers.MediaTypeZKPMessage)}, + protocol.RevocationStatusRequestMessageType: {"*"}, + }, + true, + false, + ) + + claimsService := services.NewClaim(claimsRepo, identityService, nil, mtService, identityStateRepo, schemaLoader, storage, "http://localhost", pubsub.NewMock(), ipfsGatewayURL, revocationStatusResolver, mediaTypeManager) server := NewServer(&cfg, NewIdentityMock(), claimsService, NewSchemaMock(), NewConnectionsMock(), NewLinkMock(), nil, NewPublisherMock(), NewPackageManagerMock(), nil) handler := getHandler(context.Background(), server) @@ -1447,7 +1498,17 @@ func TestServer_GetCredential(t *testing.T) { revocationStatusResolver := revocation_status.NewRevocationStatusResolver(cfg.CredentialStatus) rhsFactory := reverse_hash.NewFactory(cfg.CredentialStatus.RHS.URL, nil, commonEth.HexToAddress(cfg.CredentialStatus.OnchainTreeStore.SupportedTreeStoreContract), reverse_hash.DefaultRHSTimeOut) identityService := services.NewIdentity(keyStore, identityRepo, mtRepo, identityStateRepo, mtService, nil, claimsRepo, revocationRepository, connectionsRepository, storage, nil, nil, pubsub.NewMock(), cfg.CredentialStatus, rhsFactory, revocationStatusResolver, *cfg.AutoPublishingToOnChainRHS) - claimsService := services.NewClaim(claimsRepo, identityService, nil, mtService, identityStateRepo, schemaLoader, storage, cfg.CredentialStatus.Iden3CommAgentStatus.GetURL(), pubsub.NewMock(), ipfsGatewayURL, revocationStatusResolver, &services.DefaultMediaTypeManager) + + mediaTypeManager := services.NewMediaTypeManager( + map[iden3comm.ProtocolMessage][]string{ + protocol.CredentialFetchRequestMessageType: {string(packers.MediaTypeZKPMessage)}, + protocol.RevocationStatusRequestMessageType: {"*"}, + }, + true, + false, + ) + + claimsService := services.NewClaim(claimsRepo, identityService, nil, mtService, identityStateRepo, schemaLoader, storage, cfg.CredentialStatus.Iden3CommAgentStatus.GetURL(), pubsub.NewMock(), ipfsGatewayURL, revocationStatusResolver, mediaTypeManager) connectionsService := services.NewConnection(connectionsRepository, claimsRepo, storage) iden, err := identityService.Create(ctx, "polygon-test", &ports.DIDCreationOptions{Method: method, Blockchain: blockchain, Network: network, KeyType: BJJ}) require.NoError(t, err) @@ -1640,7 +1701,16 @@ func TestServer_GetCredentials(t *testing.T) { rhsFactory := reverse_hash.NewFactory(cfg.CredentialStatus.RHS.URL, nil, commonEth.HexToAddress(cfg.CredentialStatus.OnchainTreeStore.SupportedTreeStoreContract), reverse_hash.DefaultRHSTimeOut) identityService := services.NewIdentity(keyStore, identityRepo, mtRepo, identityStateRepo, mtService, nil, claimsRepo, revocationRepository, connectionsRepository, storage, nil, nil, pubsub.NewMock(), cfg.CredentialStatus, rhsFactory, revocationStatusResolver, *cfg.AutoPublishingToOnChainRHS) - claimsService := services.NewClaim(claimsRepo, identityService, nil, mtService, identityStateRepo, schemaLoader, storage, cfg.CredentialStatus.Iden3CommAgentStatus.GetURL(), pubsub.NewMock(), ipfsGatewayURL, revocationStatusResolver, &services.DefaultMediaTypeManager) + mediaTypeManager := services.NewMediaTypeManager( + map[iden3comm.ProtocolMessage][]string{ + protocol.CredentialFetchRequestMessageType: {string(packers.MediaTypeZKPMessage)}, + protocol.RevocationStatusRequestMessageType: {"*"}, + }, + true, + false, + ) + + claimsService := services.NewClaim(claimsRepo, identityService, nil, mtService, identityStateRepo, schemaLoader, storage, cfg.CredentialStatus.Iden3CommAgentStatus.GetURL(), pubsub.NewMock(), ipfsGatewayURL, revocationStatusResolver, mediaTypeManager) schemaService := services.NewSchema(schemaRepository, schemaLoader) connectionsService := services.NewConnection(connectionsRepository, claimsRepo, storage) iden, err := identityService.Create(ctx, "polygon-test", &ports.DIDCreationOptions{Method: method, Blockchain: blockchain, Network: network, KeyType: BJJ}) @@ -2108,7 +2178,17 @@ func TestServer_GetCredentialQrCode(t *testing.T) { revocationStatusResolver := revocation_status.NewRevocationStatusResolver(cfg.CredentialStatus) rhsFactory := reverse_hash.NewFactory(cfg.CredentialStatus.RHS.URL, nil, commonEth.HexToAddress(cfg.CredentialStatus.OnchainTreeStore.SupportedTreeStoreContract), reverse_hash.DefaultRHSTimeOut) identityService := services.NewIdentity(keyStore, identityRepo, mtRepo, identityStateRepo, mtService, qrService, claimsRepo, revocationRepository, connectionsRepository, storage, nil, nil, pubsub.NewMock(), cfg.CredentialStatus, rhsFactory, revocationStatusResolver, *cfg.AutoPublishingToOnChainRHS) - claimsService := services.NewClaim(claimsRepo, identityService, qrService, mtService, identityStateRepo, schemaLoader, storage, cfg.CredentialStatus.Iden3CommAgentStatus.GetURL(), pubsub.NewMock(), ipfsGatewayURL, revocationStatusResolver, &services.DefaultMediaTypeManager) + + mediaTypeManager := services.NewMediaTypeManager( + map[iden3comm.ProtocolMessage][]string{ + protocol.CredentialFetchRequestMessageType: {string(packers.MediaTypeZKPMessage)}, + protocol.RevocationStatusRequestMessageType: {"*"}, + }, + true, + false, + ) + + claimsService := services.NewClaim(claimsRepo, identityService, qrService, mtService, identityStateRepo, schemaLoader, storage, cfg.CredentialStatus.Iden3CommAgentStatus.GetURL(), pubsub.NewMock(), ipfsGatewayURL, revocationStatusResolver, mediaTypeManager) connectionsService := services.NewConnection(connectionsRepository, claimsRepo, storage) iden, err := identityService.Create(ctx, "polygon-test", &ports.DIDCreationOptions{Method: method, Blockchain: blockchain, Network: network, KeyType: BJJ}) require.NoError(t, err) @@ -2262,7 +2342,17 @@ func TestServer_GetConnection(t *testing.T) { rhsFactory := reverse_hash.NewFactory(cfg.CredentialStatus.RHS.URL, nil, commonEth.HexToAddress(cfg.CredentialStatus.OnchainTreeStore.SupportedTreeStoreContract), reverse_hash.DefaultRHSTimeOut) revocationStatusResolver := revocation_status.NewRevocationStatusResolver(cfg.CredentialStatus) identityService := services.NewIdentity(keyStore, identityRepo, mtRepo, identityStateRepo, mtService, nil, claimsRepo, revocationRepository, connectionsRepository, storage, nil, nil, pubsub.NewMock(), cfg.CredentialStatus, rhsFactory, revocationStatusResolver, *cfg.AutoPublishingToOnChainRHS) - claimsService := services.NewClaim(claimsRepo, identityService, nil, mtService, identityStateRepo, schemaLoader, storage, cfg.CredentialStatus.Iden3CommAgentStatus.GetURL(), pubsub.NewMock(), ipfsGatewayURL, revocationStatusResolver, &services.DefaultMediaTypeManager) + + mediaTypeManager := services.NewMediaTypeManager( + map[iden3comm.ProtocolMessage][]string{ + protocol.CredentialFetchRequestMessageType: {string(packers.MediaTypeZKPMessage)}, + protocol.RevocationStatusRequestMessageType: {"*"}, + }, + true, + false, + ) + + claimsService := services.NewClaim(claimsRepo, identityService, nil, mtService, identityStateRepo, schemaLoader, storage, cfg.CredentialStatus.Iden3CommAgentStatus.GetURL(), pubsub.NewMock(), ipfsGatewayURL, revocationStatusResolver, mediaTypeManager) connectionsService := services.NewConnection(connectionsRepository, claimsRepo, storage) iden, err := identityService.Create(ctx, "polygon-test", &ports.DIDCreationOptions{Method: method, Blockchain: blockchain, Network: network, KeyType: BJJ}) @@ -2447,7 +2537,17 @@ func TestServer_GetConnections(t *testing.T) { revocationStatusResolver := revocation_status.NewRevocationStatusResolver(cfg.CredentialStatus) rhsFactory := reverse_hash.NewFactory(cfg.CredentialStatus.RHS.URL, nil, commonEth.HexToAddress(cfg.CredentialStatus.OnchainTreeStore.SupportedTreeStoreContract), reverse_hash.DefaultRHSTimeOut) identityService := services.NewIdentity(keyStore, identityRepo, mtRepo, identityStateRepo, mtService, nil, claimsRepo, revocationRepository, connectionsRepository, storage, nil, nil, pubsub.NewMock(), cfg.CredentialStatus, rhsFactory, revocationStatusResolver, *cfg.AutoPublishingToOnChainRHS) - claimsService := services.NewClaim(claimsRepo, identityService, nil, mtService, identityStateRepo, schemaLoader, storage, cfg.CredentialStatus.Iden3CommAgentStatus.GetURL(), pubsub.NewMock(), ipfsGatewayURL, revocationStatusResolver, &services.DefaultMediaTypeManager) + + mediaTypeManager := services.NewMediaTypeManager( + map[iden3comm.ProtocolMessage][]string{ + protocol.CredentialFetchRequestMessageType: {string(packers.MediaTypeZKPMessage)}, + protocol.RevocationStatusRequestMessageType: {"*"}, + }, + true, + false, + ) + + claimsService := services.NewClaim(claimsRepo, identityService, nil, mtService, identityStateRepo, schemaLoader, storage, cfg.CredentialStatus.Iden3CommAgentStatus.GetURL(), pubsub.NewMock(), ipfsGatewayURL, revocationStatusResolver, mediaTypeManager) connectionsService := services.NewConnection(connectionsRepository, claimsRepo, storage) iden, err := identityService.Create(ctx, "polygon-test", &ports.DIDCreationOptions{Method: method, Blockchain: blockchain, Network: network, KeyType: BJJ}) @@ -3125,7 +3225,17 @@ func TestServer_RevokeCredential(t *testing.T) { revocationStatusResolver := revocation_status.NewRevocationStatusResolver(cfg.CredentialStatus) rhsFactory := reverse_hash.NewFactory(cfg.CredentialStatus.RHS.URL, nil, commonEth.HexToAddress(cfg.CredentialStatus.OnchainTreeStore.SupportedTreeStoreContract), reverse_hash.DefaultRHSTimeOut) identityService := services.NewIdentity(&KMSMock{}, identityRepo, mtRepo, identityStateRepo, mtService, nil, claimsRepo, revocationRepository, connectionsRepository, storage, nil, nil, pubsub.NewMock(), cfg.CredentialStatus, rhsFactory, revocationStatusResolver, *cfg.AutoPublishingToOnChainRHS) - claimsService := services.NewClaim(claimsRepo, identityService, nil, mtService, identityStateRepo, schemaLoader, storage, cfg.CredentialStatus.Iden3CommAgentStatus.GetURL(), pubsub.NewMock(), ipfsGatewayURL, revocationStatusResolver, &services.DefaultMediaTypeManager) + + mediaTypeManager := services.NewMediaTypeManager( + map[iden3comm.ProtocolMessage][]string{ + protocol.CredentialFetchRequestMessageType: {string(packers.MediaTypeZKPMessage)}, + protocol.RevocationStatusRequestMessageType: {"*"}, + }, + true, + false, + ) + + claimsService := services.NewClaim(claimsRepo, identityService, nil, mtService, identityStateRepo, schemaLoader, storage, cfg.CredentialStatus.Iden3CommAgentStatus.GetURL(), pubsub.NewMock(), ipfsGatewayURL, revocationStatusResolver, mediaTypeManager) fixture := tests.NewFixture(storage) connectionsService := services.NewConnection(connectionsRepository, claimsRepo, storage) @@ -3266,7 +3376,17 @@ func TestServer_CreateLink(t *testing.T) { rhsFactory := reverse_hash.NewFactory(cfg.CredentialStatus.RHS.URL, nil, commonEth.HexToAddress(cfg.CredentialStatus.OnchainTreeStore.SupportedTreeStoreContract), reverse_hash.DefaultRHSTimeOut) identityService := services.NewIdentity(keyStore, identityRepo, mtRepo, identityStateRepo, mtService, nil, claimsRepo, revocationRepository, connectionsRepository, storage, nil, nil, pubsub.NewMock(), cfg.CredentialStatus, rhsFactory, revocationStatusResolver, *cfg.AutoPublishingToOnChainRHS) pubSub := pubsub.NewMock() - claimsService := services.NewClaim(claimsRepo, identityService, nil, mtService, identityStateRepo, schemaLoader, storage, cfg.CredentialStatus.Iden3CommAgentStatus.GetURL(), pubSub, ipfsGatewayURL, revocationStatusResolver, &services.DefaultMediaTypeManager) + + mediaTypeManager := services.NewMediaTypeManager( + map[iden3comm.ProtocolMessage][]string{ + protocol.CredentialFetchRequestMessageType: {string(packers.MediaTypeZKPMessage)}, + protocol.RevocationStatusRequestMessageType: {"*"}, + }, + true, + false, + ) + + claimsService := services.NewClaim(claimsRepo, identityService, nil, mtService, identityStateRepo, schemaLoader, storage, cfg.CredentialStatus.Iden3CommAgentStatus.GetURL(), pubSub, ipfsGatewayURL, revocationStatusResolver, mediaTypeManager) connectionsService := services.NewConnection(connectionsRepository, claimsRepo, storage) linkService := services.NewLinkService(storage, claimsService, nil, claimsRepo, linkRepository, schemaRespository, schemaLoader, sessionRepository, pubSub, ipfsGatewayURL) iden, err := identityService.Create(ctx, "polygon-test", &ports.DIDCreationOptions{Method: method, Blockchain: blockchain, Network: network, KeyType: BJJ}) @@ -3491,7 +3611,17 @@ func TestServer_ActivateLink(t *testing.T) { revocationStatusResolver := revocation_status.NewRevocationStatusResolver(cfg.CredentialStatus) rhsFactory := reverse_hash.NewFactory(cfg.CredentialStatus.RHS.URL, nil, commonEth.HexToAddress(cfg.CredentialStatus.OnchainTreeStore.SupportedTreeStoreContract), reverse_hash.DefaultRHSTimeOut) identityService := services.NewIdentity(keyStore, identityRepo, mtRepo, identityStateRepo, mtService, nil, claimsRepo, revocationRepository, connectionsRepository, storage, nil, nil, pubsub.NewMock(), cfg.CredentialStatus, rhsFactory, revocationStatusResolver, *cfg.AutoPublishingToOnChainRHS) - claimsService := services.NewClaim(claimsRepo, identityService, nil, mtService, identityStateRepo, schemaLoader, storage, cfg.CredentialStatus.Iden3CommAgentStatus.GetURL(), pubsub.NewMock(), ipfsGatewayURL, revocationStatusResolver, &services.DefaultMediaTypeManager) + + mediaTypeManager := services.NewMediaTypeManager( + map[iden3comm.ProtocolMessage][]string{ + protocol.CredentialFetchRequestMessageType: {string(packers.MediaTypeZKPMessage)}, + protocol.RevocationStatusRequestMessageType: {"*"}, + }, + true, + false, + ) + + claimsService := services.NewClaim(claimsRepo, identityService, nil, mtService, identityStateRepo, schemaLoader, storage, cfg.CredentialStatus.Iden3CommAgentStatus.GetURL(), pubsub.NewMock(), ipfsGatewayURL, revocationStatusResolver, mediaTypeManager) connectionsService := services.NewConnection(connectionsRepository, claimsRepo, storage) linkService := services.NewLinkService(storage, claimsService, nil, claimsRepo, linkRepository, schemaRepository, schemaLoader, sessionRepository, pubsub.NewMock(), ipfsGatewayURL) iden, err := identityService.Create(ctx, "polygon-test", &ports.DIDCreationOptions{Method: method, Blockchain: blockchain, Network: network, KeyType: BJJ}) @@ -3640,7 +3770,17 @@ func TestServer_GetLink(t *testing.T) { revocationStatusResolver := revocation_status.NewRevocationStatusResolver(cfg.CredentialStatus) rhsFactory := reverse_hash.NewFactory(cfg.CredentialStatus.RHS.URL, nil, commonEth.HexToAddress(cfg.CredentialStatus.OnchainTreeStore.SupportedTreeStoreContract), reverse_hash.DefaultRHSTimeOut) identityService := services.NewIdentity(keyStore, identityRepo, mtRepo, identityStateRepo, mtService, nil, claimsRepo, revocationRepository, connectionsRepository, storage, nil, nil, pubsub.NewMock(), cfg.CredentialStatus, rhsFactory, revocationStatusResolver, *cfg.AutoPublishingToOnChainRHS) - claimsService := services.NewClaim(claimsRepo, identityService, nil, mtService, identityStateRepo, schemaLoader, storage, cfg.CredentialStatus.Iden3CommAgentStatus.GetURL(), pubsub.NewMock(), ipfsGatewayURL, revocationStatusResolver, &services.DefaultMediaTypeManager) + + mediaTypeManager := services.NewMediaTypeManager( + map[iden3comm.ProtocolMessage][]string{ + protocol.CredentialFetchRequestMessageType: {string(packers.MediaTypeZKPMessage)}, + protocol.RevocationStatusRequestMessageType: {"*"}, + }, + true, + false, + ) + + claimsService := services.NewClaim(claimsRepo, identityService, nil, mtService, identityStateRepo, schemaLoader, storage, cfg.CredentialStatus.Iden3CommAgentStatus.GetURL(), pubsub.NewMock(), ipfsGatewayURL, revocationStatusResolver, mediaTypeManager) connectionsService := services.NewConnection(connectionsRepository, claimsRepo, storage) linkService := services.NewLinkService(storage, claimsService, nil, claimsRepo, linkRepository, schemaRepository, schemaLoader, sessionRepository, pubsub.NewMock(), ipfsGatewayURL) iden, err := identityService.Create(ctx, "polygon-test", &ports.DIDCreationOptions{Method: method, Blockchain: blockchain, Network: network, KeyType: BJJ}) @@ -3816,7 +3956,17 @@ func TestServer_GetAllLinks(t *testing.T) { revocationStatusResolver := revocation_status.NewRevocationStatusResolver(cfg.CredentialStatus) rhsFactory := reverse_hash.NewFactory(cfg.CredentialStatus.RHS.URL, nil, commonEth.HexToAddress(cfg.CredentialStatus.OnchainTreeStore.SupportedTreeStoreContract), reverse_hash.DefaultRHSTimeOut) identityService := services.NewIdentity(keyStore, identityRepo, mtRepo, identityStateRepo, mtService, nil, claimsRepo, revocationRepository, connectionsRepository, storage, nil, nil, pubsub.NewMock(), cfg.CredentialStatus, rhsFactory, revocationStatusResolver, *cfg.AutoPublishingToOnChainRHS) - claimsService := services.NewClaim(claimsRepo, identityService, nil, mtService, identityStateRepo, schemaLoader, storage, cfg.CredentialStatus.Iden3CommAgentStatus.GetURL(), pubsub.NewMock(), ipfsGatewayURL, revocationStatusResolver, &services.DefaultMediaTypeManager) + + mediaTypeManager := services.NewMediaTypeManager( + map[iden3comm.ProtocolMessage][]string{ + protocol.CredentialFetchRequestMessageType: {string(packers.MediaTypeZKPMessage)}, + protocol.RevocationStatusRequestMessageType: {"*"}, + }, + true, + false, + ) + + claimsService := services.NewClaim(claimsRepo, identityService, nil, mtService, identityStateRepo, schemaLoader, storage, cfg.CredentialStatus.Iden3CommAgentStatus.GetURL(), pubsub.NewMock(), ipfsGatewayURL, revocationStatusResolver, mediaTypeManager) connectionsService := services.NewConnection(connectionsRepository, claimsRepo, storage) linkService := services.NewLinkService(storage, claimsService, nil, claimsRepo, linkRepository, schemaRepository, schemaLoader, sessionRepository, pubsub.NewMock(), ipfsGatewayURL) iden, err := identityService.Create(ctx, "polygon-test", &ports.DIDCreationOptions{Method: method, Blockchain: blockchain, Network: network, KeyType: BJJ}) @@ -4050,7 +4200,17 @@ func TestServer_DeleteLink(t *testing.T) { revocationStatusResolver := revocation_status.NewRevocationStatusResolver(cfg.CredentialStatus) rhsFactory := reverse_hash.NewFactory(cfg.CredentialStatus.RHS.URL, nil, commonEth.HexToAddress(cfg.CredentialStatus.OnchainTreeStore.SupportedTreeStoreContract), reverse_hash.DefaultRHSTimeOut) identityService := services.NewIdentity(keyStore, identityRepo, mtRepo, identityStateRepo, mtService, nil, claimsRepo, revocationRepository, connectionsRepository, storage, nil, nil, pubsub.NewMock(), cfg.CredentialStatus, rhsFactory, revocationStatusResolver, *cfg.AutoPublishingToOnChainRHS) - claimsService := services.NewClaim(claimsRepo, identityService, nil, mtService, identityStateRepo, schemaLoader, storage, cfg.CredentialStatus.Iden3CommAgentStatus.GetURL(), pubsub.NewMock(), ipfsGatewayURL, revocationStatusResolver, &services.DefaultMediaTypeManager) + + mediaTypeManager := services.NewMediaTypeManager( + map[iden3comm.ProtocolMessage][]string{ + protocol.CredentialFetchRequestMessageType: {string(packers.MediaTypeZKPMessage)}, + protocol.RevocationStatusRequestMessageType: {"*"}, + }, + true, + false, + ) + + claimsService := services.NewClaim(claimsRepo, identityService, nil, mtService, identityStateRepo, schemaLoader, storage, cfg.CredentialStatus.Iden3CommAgentStatus.GetURL(), pubsub.NewMock(), ipfsGatewayURL, revocationStatusResolver, mediaTypeManager) connectionsService := services.NewConnection(connectionsRepository, claimsRepo, storage) linkService := services.NewLinkService(storage, claimsService, nil, claimsRepo, linkRepository, schemaRepository, schemaLoader, sessionRepository, pubsub.NewMock(), ipfsGatewayURL) iden, err := identityService.Create(ctx, "polygon-test", &ports.DIDCreationOptions{Method: method, Blockchain: blockchain, Network: network, KeyType: BJJ}) @@ -4165,7 +4325,17 @@ func TestServer_DeleteLinkForDifferentDID(t *testing.T) { revocationStatusResolver := revocation_status.NewRevocationStatusResolver(cfg.CredentialStatus) rhsFactory := reverse_hash.NewFactory(cfg.CredentialStatus.RHS.URL, nil, commonEth.HexToAddress(cfg.CredentialStatus.OnchainTreeStore.SupportedTreeStoreContract), reverse_hash.DefaultRHSTimeOut) identityService := services.NewIdentity(keyStore, identityRepo, mtRepo, identityStateRepo, mtService, nil, claimsRepo, revocationRepository, connectionsRepository, storage, nil, nil, pubsub.NewMock(), cfg.CredentialStatus, rhsFactory, revocationStatusResolver, *cfg.AutoPublishingToOnChainRHS) - claimsService := services.NewClaim(claimsRepo, identityService, nil, mtService, identityStateRepo, schemaLoader, storage, cfg.CredentialStatus.Iden3CommAgentStatus.GetURL(), pubsub.NewMock(), ipfsGatewayURL, revocationStatusResolver, &services.DefaultMediaTypeManager) + + mediaTypeManager := services.NewMediaTypeManager( + map[iden3comm.ProtocolMessage][]string{ + protocol.CredentialFetchRequestMessageType: {string(packers.MediaTypeZKPMessage)}, + protocol.RevocationStatusRequestMessageType: {"*"}, + }, + true, + false, + ) + + claimsService := services.NewClaim(claimsRepo, identityService, nil, mtService, identityStateRepo, schemaLoader, storage, cfg.CredentialStatus.Iden3CommAgentStatus.GetURL(), pubsub.NewMock(), ipfsGatewayURL, revocationStatusResolver, mediaTypeManager) connectionsService := services.NewConnection(connectionsRepository, claimsRepo, storage) linkService := services.NewLinkService(storage, claimsService, nil, claimsRepo, linkRepository, schemaRepository, schemaLoader, sessionRepository, pubsub.NewMock(), ipfsGatewayURL) iden, err := identityService.Create(ctx, "polygon-test", &ports.DIDCreationOptions{Method: method, Blockchain: blockchain, Network: network, KeyType: BJJ}) @@ -4278,7 +4448,17 @@ func TestServer_CreateLinkQRCode(t *testing.T) { revocationStatusResolver := revocation_status.NewRevocationStatusResolver(cfg.CredentialStatus) rhsFactory := reverse_hash.NewFactory(cfg.CredentialStatus.RHS.URL, nil, commonEth.HexToAddress(cfg.CredentialStatus.OnchainTreeStore.SupportedTreeStoreContract), reverse_hash.DefaultRHSTimeOut) identityService := services.NewIdentity(keyStore, identityRepo, mtRepo, identityStateRepo, mtService, qrService, claimsRepo, revocationRepository, connectionsRepository, storage, nil, nil, pubsub.NewMock(), cfg.CredentialStatus, rhsFactory, revocationStatusResolver, *cfg.AutoPublishingToOnChainRHS) - claimsService := services.NewClaim(claimsRepo, identityService, nil, mtService, identityStateRepo, schemaLoader, storage, cfg.CredentialStatus.Iden3CommAgentStatus.GetURL(), pubsub.NewMock(), ipfsGatewayURL, revocationStatusResolver, &services.DefaultMediaTypeManager) + + mediaTypeManager := services.NewMediaTypeManager( + map[iden3comm.ProtocolMessage][]string{ + protocol.CredentialFetchRequestMessageType: {string(packers.MediaTypeZKPMessage)}, + protocol.RevocationStatusRequestMessageType: {"*"}, + }, + true, + false, + ) + + claimsService := services.NewClaim(claimsRepo, identityService, nil, mtService, identityStateRepo, schemaLoader, storage, cfg.CredentialStatus.Iden3CommAgentStatus.GetURL(), pubsub.NewMock(), ipfsGatewayURL, revocationStatusResolver, mediaTypeManager) connectionsService := services.NewConnection(connectionsRepository, claimsRepo, storage) linkService := services.NewLinkService(storage, claimsService, qrService, claimsRepo, linkRepository, schemaRepository, schemaLoader, sessionRepository, pubsub.NewMock(), ipfsGatewayURL) iden, err := identityService.Create(ctx, "polygon-test", &ports.DIDCreationOptions{Method: method, Blockchain: blockchain, Network: network, KeyType: BJJ}) @@ -4431,7 +4611,17 @@ func TestServer_GetLinkQRCode(t *testing.T) { rhsFactory := reverse_hash.NewFactory(cfg.CredentialStatus.RHS.URL, nil, commonEth.HexToAddress(cfg.CredentialStatus.OnchainTreeStore.SupportedTreeStoreContract), reverse_hash.DefaultRHSTimeOut) qrService := services.NewQrStoreService(cachex) identityService := services.NewIdentity(keyStore, identityRepo, mtRepo, identityStateRepo, mtService, qrService, claimsRepo, revocationRepository, connectionsRepository, storage, nil, nil, pubsub.NewMock(), cfg.CredentialStatus, rhsFactory, revocationStatusResolver, *cfg.AutoPublishingToOnChainRHS) - claimsService := services.NewClaim(claimsRepo, identityService, qrService, mtService, identityStateRepo, schemaLoader, storage, cfg.CredentialStatus.Iden3CommAgentStatus.GetURL(), pubsub.NewMock(), ipfsGatewayURL, revocationStatusResolver, &services.DefaultMediaTypeManager) + + mediaTypeManager := services.NewMediaTypeManager( + map[iden3comm.ProtocolMessage][]string{ + protocol.CredentialFetchRequestMessageType: {string(packers.MediaTypeZKPMessage)}, + protocol.RevocationStatusRequestMessageType: {"*"}, + }, + true, + false, + ) + + claimsService := services.NewClaim(claimsRepo, identityService, qrService, mtService, identityStateRepo, schemaLoader, storage, cfg.CredentialStatus.Iden3CommAgentStatus.GetURL(), pubsub.NewMock(), ipfsGatewayURL, revocationStatusResolver, mediaTypeManager) connectionsService := services.NewConnection(connectionsRepository, claimsRepo, storage) linkService := services.NewLinkService(storage, claimsService, qrService, claimsRepo, linkRepository, schemaRepository, schemaLoader, sessionRepository, pubsub.NewMock(), ipfsGatewayURL) iden, err := identityService.Create(ctx, "polygon-test", &ports.DIDCreationOptions{Method: method, Blockchain: blockchain, Network: network, KeyType: BJJ}) @@ -4612,7 +4802,17 @@ func TestServer_GetStateStatus(t *testing.T) { revocationStatusResolver := revocation_status.NewRevocationStatusResolver(cfg.CredentialStatus) rhsFactory := reverse_hash.NewFactory(cfg.CredentialStatus.RHS.URL, nil, commonEth.HexToAddress(cfg.CredentialStatus.OnchainTreeStore.SupportedTreeStoreContract), reverse_hash.DefaultRHSTimeOut) identityService := services.NewIdentity(keyStore, identityRepo, mtRepo, identityStateRepo, mtService, nil, claimsRepo, revocationRepository, connectionsRepository, storage, nil, nil, pubsub.NewMock(), cfg.CredentialStatus, rhsFactory, revocationStatusResolver, *cfg.AutoPublishingToOnChainRHS) - claimsService := services.NewClaim(claimsRepo, identityService, nil, mtService, identityStateRepo, schemaLoader, storage, cfg.CredentialStatus.Iden3CommAgentStatus.GetURL(), pubsub.NewMock(), ipfsGatewayURL, revocationStatusResolver, &services.DefaultMediaTypeManager) + + mediaTypeManager := services.NewMediaTypeManager( + map[iden3comm.ProtocolMessage][]string{ + protocol.CredentialFetchRequestMessageType: {string(packers.MediaTypeZKPMessage)}, + protocol.RevocationStatusRequestMessageType: {"*"}, + }, + true, + false, + ) + + claimsService := services.NewClaim(claimsRepo, identityService, nil, mtService, identityStateRepo, schemaLoader, storage, cfg.CredentialStatus.Iden3CommAgentStatus.GetURL(), pubsub.NewMock(), ipfsGatewayURL, revocationStatusResolver, mediaTypeManager) connectionsService := services.NewConnection(connectionsRepository, claimsRepo, storage) schema := "https://raw.githubusercontent.com/iden3/claim-schema-vocab/main/schemas/json/KYCAgeCredential-v3.json" credentialSubject := map[string]any{ @@ -4761,7 +4961,17 @@ func TestServer_GetStateTransactions(t *testing.T) { revocationStatusResolver := revocation_status.NewRevocationStatusResolver(cfg.CredentialStatus) rhsFactory := reverse_hash.NewFactory(cfg.CredentialStatus.RHS.URL, nil, commonEth.HexToAddress(cfg.CredentialStatus.OnchainTreeStore.SupportedTreeStoreContract), reverse_hash.DefaultRHSTimeOut) identityService := services.NewIdentity(keyStore, identityRepo, mtRepo, identityStateRepo, mtService, nil, claimsRepo, revocationRepository, connectionsRepository, storage, nil, nil, pubsub.NewMock(), cfg.CredentialStatus, rhsFactory, revocationStatusResolver, *cfg.AutoPublishingToOnChainRHS) - claimsService := services.NewClaim(claimsRepo, identityService, nil, mtService, identityStateRepo, schemaLoader, storage, cfg.CredentialStatus.Iden3CommAgentStatus.GetURL(), pubsub.NewMock(), ipfsGatewayURL, revocationStatusResolver, &services.DefaultMediaTypeManager) + + mediaTypeManager := services.NewMediaTypeManager( + map[iden3comm.ProtocolMessage][]string{ + protocol.CredentialFetchRequestMessageType: {string(packers.MediaTypeZKPMessage)}, + protocol.RevocationStatusRequestMessageType: {"*"}, + }, + true, + false, + ) + + claimsService := services.NewClaim(claimsRepo, identityService, nil, mtService, identityStateRepo, schemaLoader, storage, cfg.CredentialStatus.Iden3CommAgentStatus.GetURL(), pubsub.NewMock(), ipfsGatewayURL, revocationStatusResolver, mediaTypeManager) connectionsService := services.NewConnection(connectionsRepository, claimsRepo, storage) iden, err := identityService.Create(ctx, "polygon-test", &ports.DIDCreationOptions{Method: method, Blockchain: blockchain, Network: network, KeyType: BJJ}) require.NoError(t, err) @@ -4848,7 +5058,17 @@ func TestServer_GetRevocationStatus(t *testing.T) { rhsFactory := reverse_hash.NewFactory(cfg.CredentialStatus.RHS.URL, nil, commonEth.HexToAddress(cfg.CredentialStatus.OnchainTreeStore.SupportedTreeStoreContract), reverse_hash.DefaultRHSTimeOut) identityService := services.NewIdentity(keyStore, identityRepo, mtRepo, identityStateRepo, mtService, nil, claimsRepo, revocationRepository, connectionsRepository, storage, nil, nil, pubsub.NewMock(), cfg.CredentialStatus, rhsFactory, revocationStatusResolver, *cfg.AutoPublishingToOnChainRHS) pubSub := pubsub.NewMock() - claimsService := services.NewClaim(claimsRepo, identityService, nil, mtService, identityStateRepo, schemaLoader, storage, cfg.CredentialStatus.Iden3CommAgentStatus.GetURL(), pubSub, ipfsGatewayURL, revocationStatusResolver, &services.DefaultMediaTypeManager) + + mediaTypeManager := services.NewMediaTypeManager( + map[iden3comm.ProtocolMessage][]string{ + protocol.CredentialFetchRequestMessageType: {string(packers.MediaTypeZKPMessage)}, + protocol.RevocationStatusRequestMessageType: {"*"}, + }, + true, + false, + ) + + claimsService := services.NewClaim(claimsRepo, identityService, nil, mtService, identityStateRepo, schemaLoader, storage, cfg.CredentialStatus.Iden3CommAgentStatus.GetURL(), pubSub, ipfsGatewayURL, revocationStatusResolver, mediaTypeManager) connectionsService := services.NewConnection(connectionsRepository, claimsRepo, storage) iden, err := identityService.Create(ctx, "polygon-test", &ports.DIDCreationOptions{Method: method, Blockchain: blockchain, Network: network, KeyType: BJJ}) require.NoError(t, err) diff --git a/internal/config/config.go b/internal/config/config.go index 96b713e55..02ff36743 100644 --- a/internal/config/config.go +++ b/internal/config/config.go @@ -51,6 +51,7 @@ type Configuration struct { CredentialStatus CredentialStatus `mapstructure:"CredentialStatus"` CustomDIDMethods []CustomDIDMethods `mapstructure:"-"` AutoPublishingToOnChainRHS *bool `mapstructure:"AutoPublishingToOnChainRHS"` + MediaTypeManager MediaTypeManager `mapstructure:"MediaTypeManager"` } // Database has the database configuration @@ -201,6 +202,12 @@ type APIUIAuth struct { Password string `mapstructure:"Password" tip:"Server UI API Basic auth password"` } +// MediaTypeManager enables or disables the media types manager +type MediaTypeManager struct { + StrictMode *bool `mapstructure:"StrictMode" tip:"Enable/Disable strict mode"` + Disable bool `mapstructure:"Disable" tip:"Enable/Disable media type manager"` +} + // Sanitize perform some basic checks and sanitizations in the configuration. // Returns true if config is acceptable, error otherwise. func (c *Configuration) Sanitize(ctx context.Context) error { @@ -510,6 +517,9 @@ func bindEnv() { _ = viper.BindEnv("AutoPublishingToOnChainRHS", "ISSUER_AUTO_PUBLISHING_TO_ON_CHAIN_RHS") + _ = viper.BindEnv("MediaTypeManager.StrictMode", "ISSUER_MEDIA_TYPE_MANAGER_STRICT_MODE") + _ = viper.BindEnv("MediaTypeManager.Disable", "ISSUER_MEDIA_TYPE_MANAGER_DISABLE") + viper.AutomaticEnv() } @@ -634,6 +644,11 @@ func checkEnvVars(ctx context.Context, cfg *Configuration) { cfg.AutoPublishingToOnChainRHS = common.ToPointer(true) } + if cfg.MediaTypeManager.StrictMode == nil { + log.Info(ctx, "ISSUER_MEDIA_TYPE_MANAGER_STRICT_MODE is missing and the server set up it as true") + cfg.MediaTypeManager.StrictMode = common.ToPointer(true) + } + if cfg.CredentialStatus.RHSMode == "" { log.Info(ctx, "ISSUER_CREDENTIAL_STATUS_RHS_MODE value is missing and the server set up it as None") cfg.CredentialStatus.RHSMode = "None" diff --git a/internal/core/services/mediatype_manager.go b/internal/core/services/mediatype_manager.go index 4e19157d4..59d9bc08f 100644 --- a/internal/core/services/mediatype_manager.go +++ b/internal/core/services/mediatype_manager.go @@ -2,36 +2,31 @@ package services import ( "github.com/iden3/iden3comm/v2" - "github.com/iden3/iden3comm/v2/packers" - "github.com/iden3/iden3comm/v2/protocol" -) - -// DefaultMediaTypeManager default media type manager -var DefaultMediaTypeManager = NewMediaTypeManager( - map[iden3comm.ProtocolMessage][]string{ - protocol.CredentialFetchRequestMessageType: {string(packers.MediaTypeZKPMessage)}, - protocol.RevocationStatusRequestMessageType: {"*"}, - }, - true, ) // MediaTypeManager manages the list of allowed media types for the protocol message type // if strictMode is true, then all messages that do not exist in the allowed list will be rejected type MediaTypeManager struct { strictMode bool + disable bool allowList map[iden3comm.ProtocolMessage][]string } // NewMediaTypeManager create instance of MediaTypeManager -func NewMediaTypeManager(allowList map[iden3comm.ProtocolMessage][]string, strictMode bool) MediaTypeManager { - return MediaTypeManager{ +func NewMediaTypeManager(allowList map[iden3comm.ProtocolMessage][]string, strictMode, disable bool) *MediaTypeManager { + return &MediaTypeManager{ strictMode: strictMode, + disable: disable, allowList: allowList, } } // AllowMediaType check if the protocol message supports the mediaType type func (m *MediaTypeManager) AllowMediaType(protoclMessage iden3comm.ProtocolMessage, mediaType iden3comm.MediaType) bool { + if m.disable { + return true + } + al, ok := m.allowList[protoclMessage] if !ok { return !m.strictMode diff --git a/internal/core/services/mediatype_manager_test.go b/internal/core/services/mediatype_manager_test.go index 0de4305a4..7b1c5b84f 100644 --- a/internal/core/services/mediatype_manager_test.go +++ b/internal/core/services/mediatype_manager_test.go @@ -19,6 +19,7 @@ func TestMediatypeManager_AllowList(t *testing.T) { targetMediatype iden3comm.MediaType expected bool strictMode bool + disable bool } testcases := []testcase{ { @@ -30,6 +31,7 @@ func TestMediatypeManager_AllowList(t *testing.T) { targetMediatype: packers.MediaTypeZKPMessage, expected: false, strictMode: true, + disable: false, }, { name: "strictMode = false. Protocol message not in the allow list", @@ -40,6 +42,7 @@ func TestMediatypeManager_AllowList(t *testing.T) { targetMediatype: packers.MediaTypeZKPMessage, expected: true, strictMode: false, + disable: false, }, { name: "Protocol message on the allow list with '*'", @@ -50,6 +53,7 @@ func TestMediatypeManager_AllowList(t *testing.T) { targetMediatype: packers.MediaTypePlainMessage, expected: true, strictMode: true, + disable: false, }, { name: "Protocol message on the allow list with allow media type", @@ -60,6 +64,7 @@ func TestMediatypeManager_AllowList(t *testing.T) { targetMediatype: packers.MediaTypeZKPMessage, expected: true, strictMode: true, + disable: false, }, { name: "Protocol message on the allow list with NOT allow media type", @@ -70,6 +75,7 @@ func TestMediatypeManager_AllowList(t *testing.T) { targetMediatype: packers.MediaTypePlainMessage, expected: false, strictMode: true, + disable: false, }, { name: "strictMode = true. Empty allow list", @@ -78,6 +84,7 @@ func TestMediatypeManager_AllowList(t *testing.T) { targetMediatype: packers.MediaTypePlainMessage, expected: false, strictMode: true, + disable: false, }, { name: "strictMode = false. Empty allow list", @@ -86,59 +93,27 @@ func TestMediatypeManager_AllowList(t *testing.T) { targetMediatype: packers.MediaTypePlainMessage, expected: true, strictMode: false, + disable: false, }, - } - - for _, tt := range testcases { - t.Run(tt.name, func(t *testing.T) { - mdm := services.NewMediaTypeManager( - tt.allowList, tt.strictMode, - ) - actual := mdm.AllowMediaType( - tt.targetProtocolMessage, tt.targetMediatype, - ) - require.Equal(t, tt.expected, actual) - }) - } -} - -func TestMediatypeManager_DefaultPacker(t *testing.T) { - type testcase struct { - name string - targetProtocolMessage iden3comm.ProtocolMessage - targetMediatype iden3comm.MediaType - expected bool - } - testcases := []testcase{ { - name: "call CredentialFetchRequestMessageType with MediaTypePlainMessage", - targetProtocolMessage: protocol.CredentialFetchRequestMessageType, - targetMediatype: packers.MediaTypePlainMessage, - expected: false, - }, - { - name: "call CredentialFetchRequestMessageType with MediaTypeZKPMessage", + name: "strictMode = true. Disable = true", + allowList: map[iden3comm.ProtocolMessage][]string{}, targetProtocolMessage: protocol.CredentialFetchRequestMessageType, - targetMediatype: packers.MediaTypeZKPMessage, - expected: true, - }, - { - name: "call RevocationStatusRequestMessageType with MediaTypePlainMessage", - targetProtocolMessage: protocol.RevocationStatusRequestMessageType, targetMediatype: packers.MediaTypePlainMessage, expected: true, - }, - { - name: "call RevocationStatusRequestMessageType with MediaTypeZKPMessage", - targetProtocolMessage: protocol.RevocationStatusRequestMessageType, - targetMediatype: packers.MediaTypeZKPMessage, - expected: true, + strictMode: true, + disable: true, }, } for _, tt := range testcases { t.Run(tt.name, func(t *testing.T) { - actual := services.DefaultMediaTypeManager.AllowMediaType(tt.targetProtocolMessage, tt.targetMediatype) + mdm := services.NewMediaTypeManager( + tt.allowList, tt.strictMode, tt.disable, + ) + actual := mdm.AllowMediaType( + tt.targetProtocolMessage, tt.targetMediatype, + ) require.Equal(t, tt.expected, actual) }) } diff --git a/internal/core/services/tests/identity_test.go b/internal/core/services/tests/identity_test.go index 5a63e2e6e..b04cd67c7 100644 --- a/internal/core/services/tests/identity_test.go +++ b/internal/core/services/tests/identity_test.go @@ -8,6 +8,9 @@ import ( commonEth "github.com/ethereum/go-ethereum/common" "github.com/iden3/go-iden3-core/v2/w3c" "github.com/iden3/go-schema-processor/v2/verifiable" + "github.com/iden3/iden3comm/v2" + "github.com/iden3/iden3comm/v2/packers" + "github.com/iden3/iden3comm/v2/protocol" "github.com/stretchr/testify/assert" "github.com/stretchr/testify/require" @@ -41,7 +44,17 @@ func Test_identity_UpdateState(t *testing.T) { rhsFactory := reverse_hash.NewFactory(cfg.CredentialStatus.RHS.URL, nil, commonEth.HexToAddress(cfg.CredentialStatus.OnchainTreeStore.SupportedTreeStoreContract), reverse_hash.DefaultRHSTimeOut) revocationStatusResolver := revocation_status.NewRevocationStatusResolver(cfg.CredentialStatus) identityService := services.NewIdentity(keyStore, identityRepo, mtRepo, identityStateRepo, mtService, nil, claimsRepo, revocationRepository, connectionsRepository, storage, nil, nil, pubsub.NewMock(), cfg.CredentialStatus, rhsFactory, revocationStatusResolver, *cfg.AutoPublishingToOnChainRHS) - claimsService := services.NewClaim(claimsRepo, identityService, nil, mtService, identityStateRepo, docLoader, storage, cfg.CredentialStatus.Iden3CommAgentStatus.GetURL(), pubsub.NewMock(), ipfsGateway, revocationStatusResolver, &services.DefaultMediaTypeManager) + + mediaTypeManager := services.NewMediaTypeManager( + map[iden3comm.ProtocolMessage][]string{ + protocol.CredentialFetchRequestMessageType: {string(packers.MediaTypeZKPMessage)}, + protocol.RevocationStatusRequestMessageType: {"*"}, + }, + true, + false, + ) + + claimsService := services.NewClaim(claimsRepo, identityService, nil, mtService, identityStateRepo, docLoader, storage, cfg.CredentialStatus.Iden3CommAgentStatus.GetURL(), pubsub.NewMock(), ipfsGateway, revocationStatusResolver, mediaTypeManager) identity, err := identityService.Create(ctx, "polygon-test", &ports.DIDCreationOptions{Method: method, Blockchain: blockchain, Network: network, KeyType: BJJ}) require.NoError(t, err) diff --git a/internal/core/services/tests/link_test.go b/internal/core/services/tests/link_test.go index 0b110f761..660cc0b78 100644 --- a/internal/core/services/tests/link_test.go +++ b/internal/core/services/tests/link_test.go @@ -10,6 +10,9 @@ import ( "github.com/google/uuid" "github.com/iden3/go-iden3-core/v2/w3c" "github.com/iden3/go-schema-processor/v2/verifiable" + "github.com/iden3/iden3comm/v2" + "github.com/iden3/iden3comm/v2/packers" + "github.com/iden3/iden3comm/v2/protocol" "github.com/stretchr/testify/assert" "github.com/stretchr/testify/require" @@ -39,7 +42,17 @@ func Test_link_issueClaim(t *testing.T) { identityService := services.NewIdentity(keyStore, identityRepo, mtRepo, identityStateRepo, mtService, nil, claimsRepo, revocationRepository, connectionsRepository, storage, nil, nil, pubsub.NewMock(), cfg.CredentialStatus, rhsFactory, revocationStatusResolver, *cfg.AutoPublishingToOnChainRHS) sessionRepository := repositories.NewSessionCached(cachex) schemaService := services.NewSchema(schemaRepository, docLoader) - claimsService := services.NewClaim(claimsRepo, identityService, nil, mtService, identityStateRepo, docLoader, storage, cfg.CredentialStatus.Iden3CommAgentStatus.GetURL(), pubsub.NewMock(), ipfsGateway, revocationStatusResolver, &services.DefaultMediaTypeManager) + + mediaTypeManager := services.NewMediaTypeManager( + map[iden3comm.ProtocolMessage][]string{ + protocol.CredentialFetchRequestMessageType: {string(packers.MediaTypeZKPMessage)}, + protocol.RevocationStatusRequestMessageType: {"*"}, + }, + true, + false, + ) + + claimsService := services.NewClaim(claimsRepo, identityService, nil, mtService, identityStateRepo, docLoader, storage, cfg.CredentialStatus.Iden3CommAgentStatus.GetURL(), pubsub.NewMock(), ipfsGateway, revocationStatusResolver, mediaTypeManager) identity, err := identityService.Create(ctx, "polygon-test", &ports.DIDCreationOptions{Method: method, Blockchain: blockchain, Network: network, KeyType: BJJ}) assert.NoError(t, err) diff --git a/internal/core/services/tests/notification_test.go b/internal/core/services/tests/notification_test.go index 78e2aec30..f7c444fa1 100644 --- a/internal/core/services/tests/notification_test.go +++ b/internal/core/services/tests/notification_test.go @@ -7,6 +7,9 @@ import ( commonEth "github.com/ethereum/go-ethereum/common" "github.com/google/uuid" "github.com/iden3/go-iden3-core/v2/w3c" + "github.com/iden3/iden3comm/v2" + "github.com/iden3/iden3comm/v2/packers" + "github.com/iden3/iden3comm/v2/protocol" "github.com/stretchr/testify/assert" "github.com/stretchr/testify/require" @@ -41,7 +44,17 @@ func TestNotification_SendNotification(t *testing.T) { rhsFactory := reverse_hash.NewFactory(cfg.CredentialStatus.RHS.URL, nil, commonEth.HexToAddress(cfg.CredentialStatus.OnchainTreeStore.SupportedTreeStoreContract), reverse_hash.DefaultRHSTimeOut) revocationStatusResolver := revocation_status.NewRevocationStatusResolver(cfg.CredentialStatus) identityService := services.NewIdentity(keyStore, identityRepo, mtRepo, identityStateRepo, mtService, nil, claimsRepo, revocationRepository, connectionsRepository, storage, nil, nil, pubsub.NewMock(), cfg.CredentialStatus, rhsFactory, revocationStatusResolver, *cfg.AutoPublishingToOnChainRHS) - credentialsService := services.NewClaim(claimsRepo, identityService, nil, mtService, identityStateRepo, docLoader, storage, cfg.CredentialStatus.Iden3CommAgentStatus.GetURL(), pubsub.NewMock(), ipfsGateway, revocationStatusResolver, &services.DefaultMediaTypeManager) + + mediaTypeManager := services.NewMediaTypeManager( + map[iden3comm.ProtocolMessage][]string{ + protocol.CredentialFetchRequestMessageType: {string(packers.MediaTypeZKPMessage)}, + protocol.RevocationStatusRequestMessageType: {"*"}, + }, + true, + false, + ) + + credentialsService := services.NewClaim(claimsRepo, identityService, nil, mtService, identityStateRepo, docLoader, storage, cfg.CredentialStatus.Iden3CommAgentStatus.GetURL(), pubsub.NewMock(), ipfsGateway, revocationStatusResolver, mediaTypeManager) connectionsService := services.NewConnection(connectionsRepository, claimsRepo, storage) iden, err := identityService.Create(ctx, "polygon-test", &ports.DIDCreationOptions{Method: method, Blockchain: blockchain, Network: network, KeyType: BJJ}) require.NoError(t, err) diff --git a/pkg/protocol/verify.go b/pkg/protocol/verify.go index 0d617e11b..354d3e510 100644 --- a/pkg/protocol/verify.go +++ b/pkg/protocol/verify.go @@ -1,11 +1,6 @@ package protocol import ( - "encoding/json" - "math/big" - "time" - - "github.com/ethereum/go-ethereum/accounts/abi/bind" "github.com/iden3/contracts-abi/state/go/abi" "github.com/iden3/go-circuits/v2" "github.com/iden3/iden3comm/v2/packers" @@ -30,30 +25,30 @@ func stateVerificationHandler(ethStateContract *abi.State) packers.VerificationH // authV2CircuitStateVerification `authV2` circuit state verification func authV2CircuitStateVerification(contract *abi.State, pubsignals []string) error { - bytePubsig, err := json.Marshal(pubsignals) - if err != nil { - return err - } - - authPubSignals := circuits.AuthV2PubSignals{} - err = authPubSignals.PubSignalsUnmarshal(bytePubsig) - if err != nil { - return err - } - - globalState := authPubSignals.GISTRoot.BigInt() - globalStateInfo, err := contract.GetGISTRootInfo(&bind.CallOpts{}, globalState) - if err != nil { - return err - } - - if globalState.Cmp(globalStateInfo.Root) != 0 { - return errors.Errorf("invalid global state info in the smart contract, expected root %s, got %s", globalState.String(), globalStateInfo.Root.String()) - } - - if (big.NewInt(0)).Cmp(globalStateInfo.ReplacedByRoot) != 0 && time.Since(time.Unix(globalStateInfo.ReplacedAtTimestamp.Int64(), 0)) > time.Minute*15 { - return errors.Errorf("global state is too old, replaced timestamp is %v", globalStateInfo.ReplacedAtTimestamp.Int64()) - } + // bytePubsig, err := json.Marshal(pubsignals) + // if err != nil { + // return err + // } + + // authPubSignals := circuits.AuthV2PubSignals{} + // err = authPubSignals.PubSignalsUnmarshal(bytePubsig) + // if err != nil { + // return err + // } + + // globalState := authPubSignals.GISTRoot.BigInt() + // globalStateInfo, err := contract.GetGISTRootInfo(&bind.CallOpts{}, globalState) + // if err != nil { + // return err + // } + + // if globalState.Cmp(globalStateInfo.Root) != 0 { + // return errors.Errorf("invalid global state info in the smart contract, expected root %s, got %s", globalState.String(), globalStateInfo.Root.String()) + // } + + // if (big.NewInt(0)).Cmp(globalStateInfo.ReplacedByRoot) != 0 && time.Since(time.Unix(globalStateInfo.ReplacedAtTimestamp.Int64(), 0)) > time.Minute*15 { + // return errors.Errorf("global state is too old, replaced timestamp is %v", globalStateInfo.ReplacedAtTimestamp.Int64()) + // } return nil } From 19055f8f4c704dd6b7b21342350d81511b54e403 Mon Sep 17 00:00:00 2001 From: Ilya Date: Thu, 20 Jun 2024 19:23:39 +0300 Subject: [PATCH 29/52] change disable flag to enabled; remove strict mode --- cmd/notifications/main.go | 3 +- cmd/pending_publisher/main.go | 3 +- cmd/platform/main.go | 3 +- cmd/platform_ui/main.go | 3 +- internal/api/server_test.go | 8 -- internal/api_ui/server_test.go | 22 ------ internal/config/config.go | 12 ++- internal/core/services/mediatype_manager.go | 16 ++-- .../core/services/mediatype_manager_test.go | 77 ++++++------------- internal/core/services/tests/identity_test.go | 1 - internal/core/services/tests/link_test.go | 1 - .../core/services/tests/notification_test.go | 1 - pkg/protocol/verify.go | 53 +++++++------ 13 files changed, 67 insertions(+), 136 deletions(-) diff --git a/cmd/notifications/main.go b/cmd/notifications/main.go index 4bb8f6d87..d55ada7ce 100644 --- a/cmd/notifications/main.go +++ b/cmd/notifications/main.go @@ -187,8 +187,7 @@ func newCredentialsService(ctx context.Context, cfg *config.Configuration, stora protocol.CredentialFetchRequestMessageType: {string(packers.MediaTypeZKPMessage)}, protocol.RevocationStatusRequestMessageType: {"*"}, }, - *cfg.MediaTypeManager.StrictMode, - cfg.MediaTypeManager.Disable, + *cfg.MediaTypeManager.Enabled, ) identityService := services.NewIdentity(keyStore, identityRepository, mtRepository, identityStateRepository, mtService, qrService, claimsRepository, revocationRepository, nil, storage, nil, nil, ps, cfg.CredentialStatus, rhsFactory, revocationStatusResolver, *cfg.AutoPublishingToOnChainRHS) diff --git a/cmd/pending_publisher/main.go b/cmd/pending_publisher/main.go index ffb060912..2490b5a23 100644 --- a/cmd/pending_publisher/main.go +++ b/cmd/pending_publisher/main.go @@ -168,8 +168,7 @@ func main() { protocol.CredentialFetchRequestMessageType: {string(packers.MediaTypeZKPMessage)}, protocol.RevocationStatusRequestMessageType: {"*"}, }, - *cfg.MediaTypeManager.StrictMode, - cfg.MediaTypeManager.Disable, + *cfg.MediaTypeManager.Enabled, ) identityService := services.NewIdentity(keyStore, identityRepo, mtRepo, identityStateRepo, mtService, qrService, claimsRepo, revocationRepository, connectionsRepository, storage, nil, nil, pubsub.NewMock(), cfg.CredentialStatus, rhsFactory, revocationStatusResolver, *cfg.AutoPublishingToOnChainRHS) diff --git a/cmd/platform/main.go b/cmd/platform/main.go index 0e8c7eaab..ed432fc13 100644 --- a/cmd/platform/main.go +++ b/cmd/platform/main.go @@ -150,8 +150,7 @@ func main() { iden3commProtocol.CredentialFetchRequestMessageType: {string(packers.MediaTypeZKPMessage)}, iden3commProtocol.RevocationStatusRequestMessageType: {"*"}, }, - *cfg.MediaTypeManager.StrictMode, - cfg.MediaTypeManager.Disable, + *cfg.MediaTypeManager.Enabled, ) revocationStatusResolver := revocation_status.NewRevocationStatusResolver(cfg.CredentialStatus) diff --git a/cmd/platform_ui/main.go b/cmd/platform_ui/main.go index f2b573e4d..1f1a91c85 100644 --- a/cmd/platform_ui/main.go +++ b/cmd/platform_ui/main.go @@ -182,8 +182,7 @@ func main() { iden3commProtocol.CredentialFetchRequestMessageType: {string(packers.MediaTypeZKPMessage)}, iden3commProtocol.RevocationStatusRequestMessageType: {"*"}, }, - *cfg.MediaTypeManager.StrictMode, - cfg.MediaTypeManager.Disable, + *cfg.MediaTypeManager.Enabled, ) revocationStatusResolver := revocation_status.NewRevocationStatusResolver(cfg.CredentialStatus) diff --git a/internal/api/server_test.go b/internal/api/server_test.go index aa3686fc4..29243219f 100644 --- a/internal/api/server_test.go +++ b/internal/api/server_test.go @@ -61,7 +61,6 @@ func TestServer_CreateIdentity(t *testing.T) { protocol.RevocationStatusRequestMessageType: {"*"}, }, true, - false, ) claimsService := services.NewClaim(claimsRepo, identityService, nil, mtService, identityStateRepo, schemaLoader, storage, cfg.CredentialStatus.Iden3CommAgentStatus.GetURL(), pubsub.NewMock(), ipfsGatewayURL, revocationStatusResolver, mediaTypeManager) accountService := services.NewAccountService(cfg.Ethereum, keyStore) @@ -266,7 +265,6 @@ func TestServer_RevokeClaim(t *testing.T) { protocol.RevocationStatusRequestMessageType: {"*"}, }, true, - false, ) claimsService := services.NewClaim(claimsRepo, identityService, nil, mtService, identityStateRepo, schemaLoader, storage, cfg.CredentialStatus.Iden3CommAgentStatus.GetURL(), pubsub.NewMock(), ipfsGatewayURL, revocationStatusResolver, mediaTypeManager) accountService := services.NewAccountService(cfg.Ethereum, keyStore) @@ -421,7 +419,6 @@ func TestServer_CreateClaim(t *testing.T) { protocol.RevocationStatusRequestMessageType: {"*"}, }, true, - false, ) rhsFactory := reverse_hash.NewFactory(cfg.CredentialStatus.RHS.GetURL(), nil, commonEth.HexToAddress(cfg.CredentialStatus.OnchainTreeStore.SupportedTreeStoreContract), reverse_hash.DefaultRHSTimeOut) @@ -612,7 +609,6 @@ func TestServer_GetIdentities(t *testing.T) { protocol.RevocationStatusRequestMessageType: {"*"}, }, true, - false, ) claimsService := services.NewClaim(claimsRepo, identityService, nil, mtService, identityStateRepo, schemaLoader, storage, cfg.CredentialStatus.Iden3CommAgentStatus.GetURL(), pubsub.NewMock(), ipfsGatewayURL, revocationStatusResolver, mediaTypeManager) @@ -697,7 +693,6 @@ func TestServer_GetClaimQrCode(t *testing.T) { protocol.RevocationStatusRequestMessageType: {"*"}, }, true, - false, ) claimsService := services.NewClaim(claimsRepo, identityService, nil, mtService, identityStateRepo, schemaLoader, storage, cfg.CredentialStatus.Iden3CommAgentStatus.GetURL(), pubsub.NewMock(), ipfsGatewayURL, revocationStatusResolver, mediaTypeManager) @@ -847,7 +842,6 @@ func TestServer_GetClaim(t *testing.T) { protocol.RevocationStatusRequestMessageType: {"*"}, }, true, - false, ) claimsService := services.NewClaim(claimsRepo, identityService, nil, mtService, identityStateRepo, schemaLoader, storage, cfg.CredentialStatus.Iden3CommAgentStatus.GetURL(), pubsub.NewMock(), ipfsGatewayURL, revocationStatusResolver, mediaTypeManager) @@ -1031,7 +1025,6 @@ func TestServer_GetClaims(t *testing.T) { protocol.RevocationStatusRequestMessageType: {"*"}, }, true, - false, ) claimsService := services.NewClaim(claimsRepo, identityService, nil, mtService, identityStateRepo, schemaLoader, storage, cfg.CredentialStatus.Iden3CommAgentStatus.GetURL(), pubsub.NewMock(), ipfsGatewayURL, revocationStatusResolver, mediaTypeManager) @@ -1390,7 +1383,6 @@ func TestServer_GetRevocationStatus(t *testing.T) { protocol.RevocationStatusRequestMessageType: {"*"}, }, true, - false, ) claimsService := services.NewClaim(claimsRepo, identityService, nil, mtService, identityStateRepo, schemaLoader, storage, cfg.CredentialStatus.Iden3CommAgentStatus.GetURL(), pubsub.NewMock(), ipfsGatewayURL, revocationStatusResolver, mediaTypeManager) diff --git a/internal/api_ui/server_test.go b/internal/api_ui/server_test.go index d64396f36..43162084d 100644 --- a/internal/api_ui/server_test.go +++ b/internal/api_ui/server_test.go @@ -58,7 +58,6 @@ func TestServer_CheckStatus(t *testing.T) { protocol.RevocationStatusRequestMessageType: {"*"}, }, true, - false, ) claimsService := services.NewClaim(claimsRepo, identityService, nil, mtService, identityStateRepo, schemaLoader, storage, "http://localhost", pubsub.NewMock(), ipfsGatewayURL, revocationStatusResolver, mediaTypeManager) @@ -824,7 +823,6 @@ func TestServer_DeleteConnection(t *testing.T) { protocol.RevocationStatusRequestMessageType: {"*"}, }, true, - false, ) claimsService := services.NewClaim(claimsRepo, identityService, nil, mtService, identityStateRepo, schemaLoader, storage, cfg.CredentialStatus.Iden3CommAgentStatus.GetURL(), pubsub.NewMock(), ipfsGatewayURL, revocationStatusResolver, mediaTypeManager) @@ -1084,7 +1082,6 @@ func TestServer_RevokeConnectionCredentials(t *testing.T) { protocol.RevocationStatusRequestMessageType: {"*"}, }, true, - false, ) claimsService := services.NewClaim(claimsRepo, identityService, nil, mtService, identityStateRepo, schemaLoader, storage, "http://localhost", pubsub.NewMock(), ipfsGatewayURL, revocationStatusResolver, mediaTypeManager) @@ -1206,7 +1203,6 @@ func TestServer_CreateCredential(t *testing.T) { protocol.RevocationStatusRequestMessageType: {"*"}, }, true, - false, ) claimsService := services.NewClaim(claimsRepo, identityService, nil, mtService, identityStateRepo, schemaLoader, storage, cfg.CredentialStatus.Iden3CommAgentStatus.GetURL(), pubSub, ipfsGatewayURL, revocationStatusResolver, mediaTypeManager) @@ -1392,7 +1388,6 @@ func TestServer_DeleteCredential(t *testing.T) { protocol.RevocationStatusRequestMessageType: {"*"}, }, true, - false, ) claimsService := services.NewClaim(claimsRepo, identityService, nil, mtService, identityStateRepo, schemaLoader, storage, "http://localhost", pubsub.NewMock(), ipfsGatewayURL, revocationStatusResolver, mediaTypeManager) @@ -1505,7 +1500,6 @@ func TestServer_GetCredential(t *testing.T) { protocol.RevocationStatusRequestMessageType: {"*"}, }, true, - false, ) claimsService := services.NewClaim(claimsRepo, identityService, nil, mtService, identityStateRepo, schemaLoader, storage, cfg.CredentialStatus.Iden3CommAgentStatus.GetURL(), pubsub.NewMock(), ipfsGatewayURL, revocationStatusResolver, mediaTypeManager) @@ -1707,7 +1701,6 @@ func TestServer_GetCredentials(t *testing.T) { protocol.RevocationStatusRequestMessageType: {"*"}, }, true, - false, ) claimsService := services.NewClaim(claimsRepo, identityService, nil, mtService, identityStateRepo, schemaLoader, storage, cfg.CredentialStatus.Iden3CommAgentStatus.GetURL(), pubsub.NewMock(), ipfsGatewayURL, revocationStatusResolver, mediaTypeManager) @@ -2185,7 +2178,6 @@ func TestServer_GetCredentialQrCode(t *testing.T) { protocol.RevocationStatusRequestMessageType: {"*"}, }, true, - false, ) claimsService := services.NewClaim(claimsRepo, identityService, qrService, mtService, identityStateRepo, schemaLoader, storage, cfg.CredentialStatus.Iden3CommAgentStatus.GetURL(), pubsub.NewMock(), ipfsGatewayURL, revocationStatusResolver, mediaTypeManager) @@ -2349,7 +2341,6 @@ func TestServer_GetConnection(t *testing.T) { protocol.RevocationStatusRequestMessageType: {"*"}, }, true, - false, ) claimsService := services.NewClaim(claimsRepo, identityService, nil, mtService, identityStateRepo, schemaLoader, storage, cfg.CredentialStatus.Iden3CommAgentStatus.GetURL(), pubsub.NewMock(), ipfsGatewayURL, revocationStatusResolver, mediaTypeManager) @@ -2544,7 +2535,6 @@ func TestServer_GetConnections(t *testing.T) { protocol.RevocationStatusRequestMessageType: {"*"}, }, true, - false, ) claimsService := services.NewClaim(claimsRepo, identityService, nil, mtService, identityStateRepo, schemaLoader, storage, cfg.CredentialStatus.Iden3CommAgentStatus.GetURL(), pubsub.NewMock(), ipfsGatewayURL, revocationStatusResolver, mediaTypeManager) @@ -3232,7 +3222,6 @@ func TestServer_RevokeCredential(t *testing.T) { protocol.RevocationStatusRequestMessageType: {"*"}, }, true, - false, ) claimsService := services.NewClaim(claimsRepo, identityService, nil, mtService, identityStateRepo, schemaLoader, storage, cfg.CredentialStatus.Iden3CommAgentStatus.GetURL(), pubsub.NewMock(), ipfsGatewayURL, revocationStatusResolver, mediaTypeManager) @@ -3383,7 +3372,6 @@ func TestServer_CreateLink(t *testing.T) { protocol.RevocationStatusRequestMessageType: {"*"}, }, true, - false, ) claimsService := services.NewClaim(claimsRepo, identityService, nil, mtService, identityStateRepo, schemaLoader, storage, cfg.CredentialStatus.Iden3CommAgentStatus.GetURL(), pubSub, ipfsGatewayURL, revocationStatusResolver, mediaTypeManager) @@ -3618,7 +3606,6 @@ func TestServer_ActivateLink(t *testing.T) { protocol.RevocationStatusRequestMessageType: {"*"}, }, true, - false, ) claimsService := services.NewClaim(claimsRepo, identityService, nil, mtService, identityStateRepo, schemaLoader, storage, cfg.CredentialStatus.Iden3CommAgentStatus.GetURL(), pubsub.NewMock(), ipfsGatewayURL, revocationStatusResolver, mediaTypeManager) @@ -3777,7 +3764,6 @@ func TestServer_GetLink(t *testing.T) { protocol.RevocationStatusRequestMessageType: {"*"}, }, true, - false, ) claimsService := services.NewClaim(claimsRepo, identityService, nil, mtService, identityStateRepo, schemaLoader, storage, cfg.CredentialStatus.Iden3CommAgentStatus.GetURL(), pubsub.NewMock(), ipfsGatewayURL, revocationStatusResolver, mediaTypeManager) @@ -3963,7 +3949,6 @@ func TestServer_GetAllLinks(t *testing.T) { protocol.RevocationStatusRequestMessageType: {"*"}, }, true, - false, ) claimsService := services.NewClaim(claimsRepo, identityService, nil, mtService, identityStateRepo, schemaLoader, storage, cfg.CredentialStatus.Iden3CommAgentStatus.GetURL(), pubsub.NewMock(), ipfsGatewayURL, revocationStatusResolver, mediaTypeManager) @@ -4207,7 +4192,6 @@ func TestServer_DeleteLink(t *testing.T) { protocol.RevocationStatusRequestMessageType: {"*"}, }, true, - false, ) claimsService := services.NewClaim(claimsRepo, identityService, nil, mtService, identityStateRepo, schemaLoader, storage, cfg.CredentialStatus.Iden3CommAgentStatus.GetURL(), pubsub.NewMock(), ipfsGatewayURL, revocationStatusResolver, mediaTypeManager) @@ -4332,7 +4316,6 @@ func TestServer_DeleteLinkForDifferentDID(t *testing.T) { protocol.RevocationStatusRequestMessageType: {"*"}, }, true, - false, ) claimsService := services.NewClaim(claimsRepo, identityService, nil, mtService, identityStateRepo, schemaLoader, storage, cfg.CredentialStatus.Iden3CommAgentStatus.GetURL(), pubsub.NewMock(), ipfsGatewayURL, revocationStatusResolver, mediaTypeManager) @@ -4455,7 +4438,6 @@ func TestServer_CreateLinkQRCode(t *testing.T) { protocol.RevocationStatusRequestMessageType: {"*"}, }, true, - false, ) claimsService := services.NewClaim(claimsRepo, identityService, nil, mtService, identityStateRepo, schemaLoader, storage, cfg.CredentialStatus.Iden3CommAgentStatus.GetURL(), pubsub.NewMock(), ipfsGatewayURL, revocationStatusResolver, mediaTypeManager) @@ -4618,7 +4600,6 @@ func TestServer_GetLinkQRCode(t *testing.T) { protocol.RevocationStatusRequestMessageType: {"*"}, }, true, - false, ) claimsService := services.NewClaim(claimsRepo, identityService, qrService, mtService, identityStateRepo, schemaLoader, storage, cfg.CredentialStatus.Iden3CommAgentStatus.GetURL(), pubsub.NewMock(), ipfsGatewayURL, revocationStatusResolver, mediaTypeManager) @@ -4809,7 +4790,6 @@ func TestServer_GetStateStatus(t *testing.T) { protocol.RevocationStatusRequestMessageType: {"*"}, }, true, - false, ) claimsService := services.NewClaim(claimsRepo, identityService, nil, mtService, identityStateRepo, schemaLoader, storage, cfg.CredentialStatus.Iden3CommAgentStatus.GetURL(), pubsub.NewMock(), ipfsGatewayURL, revocationStatusResolver, mediaTypeManager) @@ -4968,7 +4948,6 @@ func TestServer_GetStateTransactions(t *testing.T) { protocol.RevocationStatusRequestMessageType: {"*"}, }, true, - false, ) claimsService := services.NewClaim(claimsRepo, identityService, nil, mtService, identityStateRepo, schemaLoader, storage, cfg.CredentialStatus.Iden3CommAgentStatus.GetURL(), pubsub.NewMock(), ipfsGatewayURL, revocationStatusResolver, mediaTypeManager) @@ -5065,7 +5044,6 @@ func TestServer_GetRevocationStatus(t *testing.T) { protocol.RevocationStatusRequestMessageType: {"*"}, }, true, - false, ) claimsService := services.NewClaim(claimsRepo, identityService, nil, mtService, identityStateRepo, schemaLoader, storage, cfg.CredentialStatus.Iden3CommAgentStatus.GetURL(), pubSub, ipfsGatewayURL, revocationStatusResolver, mediaTypeManager) diff --git a/internal/config/config.go b/internal/config/config.go index 02ff36743..700f73bfb 100644 --- a/internal/config/config.go +++ b/internal/config/config.go @@ -204,8 +204,7 @@ type APIUIAuth struct { // MediaTypeManager enables or disables the media types manager type MediaTypeManager struct { - StrictMode *bool `mapstructure:"StrictMode" tip:"Enable/Disable strict mode"` - Disable bool `mapstructure:"Disable" tip:"Enable/Disable media type manager"` + Enabled *bool `mapstructure:"Enabled" tip:"Enable or disable the media type manager"` } // Sanitize perform some basic checks and sanitizations in the configuration. @@ -517,8 +516,7 @@ func bindEnv() { _ = viper.BindEnv("AutoPublishingToOnChainRHS", "ISSUER_AUTO_PUBLISHING_TO_ON_CHAIN_RHS") - _ = viper.BindEnv("MediaTypeManager.StrictMode", "ISSUER_MEDIA_TYPE_MANAGER_STRICT_MODE") - _ = viper.BindEnv("MediaTypeManager.Disable", "ISSUER_MEDIA_TYPE_MANAGER_DISABLE") + _ = viper.BindEnv("MediaTypeManager.Enabled", "ISSUER_MEDIA_TYPE_MANAGER_ENABLED") viper.AutomaticEnv() } @@ -644,9 +642,9 @@ func checkEnvVars(ctx context.Context, cfg *Configuration) { cfg.AutoPublishingToOnChainRHS = common.ToPointer(true) } - if cfg.MediaTypeManager.StrictMode == nil { - log.Info(ctx, "ISSUER_MEDIA_TYPE_MANAGER_STRICT_MODE is missing and the server set up it as true") - cfg.MediaTypeManager.StrictMode = common.ToPointer(true) + if cfg.MediaTypeManager.Enabled == nil { + log.Info(ctx, "ISSUER_MEDIA_TYPE_MANAGER_ENABLED is missing and the server set up it as true") + cfg.MediaTypeManager.Enabled = common.ToPointer(true) } if cfg.CredentialStatus.RHSMode == "" { diff --git a/internal/core/services/mediatype_manager.go b/internal/core/services/mediatype_manager.go index 59d9bc08f..975f5ee02 100644 --- a/internal/core/services/mediatype_manager.go +++ b/internal/core/services/mediatype_manager.go @@ -7,29 +7,27 @@ import ( // MediaTypeManager manages the list of allowed media types for the protocol message type // if strictMode is true, then all messages that do not exist in the allowed list will be rejected type MediaTypeManager struct { - strictMode bool - disable bool - allowList map[iden3comm.ProtocolMessage][]string + enabled bool + allowList map[iden3comm.ProtocolMessage][]string } // NewMediaTypeManager create instance of MediaTypeManager -func NewMediaTypeManager(allowList map[iden3comm.ProtocolMessage][]string, strictMode, disable bool) *MediaTypeManager { +func NewMediaTypeManager(allowList map[iden3comm.ProtocolMessage][]string, enabled bool) *MediaTypeManager { return &MediaTypeManager{ - strictMode: strictMode, - disable: disable, - allowList: allowList, + enabled: enabled, + allowList: allowList, } } // AllowMediaType check if the protocol message supports the mediaType type func (m *MediaTypeManager) AllowMediaType(protoclMessage iden3comm.ProtocolMessage, mediaType iden3comm.MediaType) bool { - if m.disable { + if !m.enabled { return true } al, ok := m.allowList[protoclMessage] if !ok { - return !m.strictMode + return false } for _, v := range al { if v == "*" || v == string(mediaType) { diff --git a/internal/core/services/mediatype_manager_test.go b/internal/core/services/mediatype_manager_test.go index 7b1c5b84f..5c8dac902 100644 --- a/internal/core/services/mediatype_manager_test.go +++ b/internal/core/services/mediatype_manager_test.go @@ -18,98 +18,65 @@ func TestMediatypeManager_AllowList(t *testing.T) { targetProtocolMessage iden3comm.ProtocolMessage targetMediatype iden3comm.MediaType expected bool - strictMode bool - disable bool + enabled bool } testcases := []testcase{ { - name: "strictMode = true. Protocol message not in the allow list", + name: "AllowList enabled. Type in the list", allowList: map[iden3comm.ProtocolMessage][]string{ - protocol.RevocationStatusRequestMessageType: {"*"}, - }, - targetProtocolMessage: protocol.CredentialFetchRequestMessageType, - targetMediatype: packers.MediaTypeZKPMessage, - expected: false, - strictMode: true, - disable: false, - }, - { - name: "strictMode = false. Protocol message not in the allow list", - allowList: map[iden3comm.ProtocolMessage][]string{ - protocol.RevocationStatusRequestMessageType: {"*"}, + protocol.CredentialFetchRequestMessageType: {string(packers.MediaTypeZKPMessage)}, }, targetProtocolMessage: protocol.CredentialFetchRequestMessageType, targetMediatype: packers.MediaTypeZKPMessage, expected: true, - strictMode: false, - disable: false, + enabled: true, }, { - name: "Protocol message on the allow list with '*'", + name: "AllowList enabled. Type in the list with wildcard", allowList: map[iden3comm.ProtocolMessage][]string{ protocol.CredentialFetchRequestMessageType: {"*"}, }, targetProtocolMessage: protocol.CredentialFetchRequestMessageType, - targetMediatype: packers.MediaTypePlainMessage, + targetMediatype: packers.MediaTypeZKPMessage, expected: true, - strictMode: true, - disable: false, + enabled: true, }, { - name: "Protocol message on the allow list with allow media type", + name: "AllowList enabled. Type not in the list", allowList: map[iden3comm.ProtocolMessage][]string{ - protocol.CredentialFetchRequestMessageType: {string(packers.MediaTypeZKPMessage)}, + protocol.RevocationStatusRequestMessageType: {"*"}, }, targetProtocolMessage: protocol.CredentialFetchRequestMessageType, targetMediatype: packers.MediaTypeZKPMessage, - expected: true, - strictMode: true, - disable: false, + expected: false, + enabled: true, }, { - name: "Protocol message on the allow list with NOT allow media type", + name: "AllowList enabled. Type does not exist", allowList: map[iden3comm.ProtocolMessage][]string{ - protocol.CredentialFetchRequestMessageType: {string(packers.MediaTypeZKPMessage)}, + protocol.CredentialFetchRequestMessageType: {string(packers.MediaTypePlainMessage)}, }, targetProtocolMessage: protocol.CredentialFetchRequestMessageType, - targetMediatype: packers.MediaTypePlainMessage, - expected: false, - strictMode: true, - disable: false, - }, - { - name: "strictMode = true. Empty allow list", - allowList: map[iden3comm.ProtocolMessage][]string{}, - targetProtocolMessage: protocol.CredentialFetchRequestMessageType, - targetMediatype: packers.MediaTypePlainMessage, + targetMediatype: packers.MediaTypeZKPMessage, expected: false, - strictMode: true, - disable: false, + enabled: true, }, { - name: "strictMode = false. Empty allow list", - allowList: map[iden3comm.ProtocolMessage][]string{}, - targetProtocolMessage: protocol.CredentialFetchRequestMessageType, - targetMediatype: packers.MediaTypePlainMessage, - expected: true, - strictMode: false, - disable: false, - }, - { - name: "strictMode = true. Disable = true", - allowList: map[iden3comm.ProtocolMessage][]string{}, + name: "AllowList disabled. Type does not exist", + allowList: map[iden3comm.ProtocolMessage][]string{ + protocol.CredentialFetchRequestMessageType: {string(packers.MediaTypePlainMessage)}, + }, targetProtocolMessage: protocol.CredentialFetchRequestMessageType, - targetMediatype: packers.MediaTypePlainMessage, + targetMediatype: packers.MediaTypeZKPMessage, expected: true, - strictMode: true, - disable: true, + enabled: false, }, } for _, tt := range testcases { t.Run(tt.name, func(t *testing.T) { mdm := services.NewMediaTypeManager( - tt.allowList, tt.strictMode, tt.disable, + tt.allowList, tt.enabled, ) actual := mdm.AllowMediaType( tt.targetProtocolMessage, tt.targetMediatype, diff --git a/internal/core/services/tests/identity_test.go b/internal/core/services/tests/identity_test.go index b04cd67c7..011f3f0ec 100644 --- a/internal/core/services/tests/identity_test.go +++ b/internal/core/services/tests/identity_test.go @@ -51,7 +51,6 @@ func Test_identity_UpdateState(t *testing.T) { protocol.RevocationStatusRequestMessageType: {"*"}, }, true, - false, ) claimsService := services.NewClaim(claimsRepo, identityService, nil, mtService, identityStateRepo, docLoader, storage, cfg.CredentialStatus.Iden3CommAgentStatus.GetURL(), pubsub.NewMock(), ipfsGateway, revocationStatusResolver, mediaTypeManager) diff --git a/internal/core/services/tests/link_test.go b/internal/core/services/tests/link_test.go index 660cc0b78..3a7c5adb8 100644 --- a/internal/core/services/tests/link_test.go +++ b/internal/core/services/tests/link_test.go @@ -49,7 +49,6 @@ func Test_link_issueClaim(t *testing.T) { protocol.RevocationStatusRequestMessageType: {"*"}, }, true, - false, ) claimsService := services.NewClaim(claimsRepo, identityService, nil, mtService, identityStateRepo, docLoader, storage, cfg.CredentialStatus.Iden3CommAgentStatus.GetURL(), pubsub.NewMock(), ipfsGateway, revocationStatusResolver, mediaTypeManager) diff --git a/internal/core/services/tests/notification_test.go b/internal/core/services/tests/notification_test.go index f7c444fa1..a128c4459 100644 --- a/internal/core/services/tests/notification_test.go +++ b/internal/core/services/tests/notification_test.go @@ -51,7 +51,6 @@ func TestNotification_SendNotification(t *testing.T) { protocol.RevocationStatusRequestMessageType: {"*"}, }, true, - false, ) credentialsService := services.NewClaim(claimsRepo, identityService, nil, mtService, identityStateRepo, docLoader, storage, cfg.CredentialStatus.Iden3CommAgentStatus.GetURL(), pubsub.NewMock(), ipfsGateway, revocationStatusResolver, mediaTypeManager) diff --git a/pkg/protocol/verify.go b/pkg/protocol/verify.go index 354d3e510..0d617e11b 100644 --- a/pkg/protocol/verify.go +++ b/pkg/protocol/verify.go @@ -1,6 +1,11 @@ package protocol import ( + "encoding/json" + "math/big" + "time" + + "github.com/ethereum/go-ethereum/accounts/abi/bind" "github.com/iden3/contracts-abi/state/go/abi" "github.com/iden3/go-circuits/v2" "github.com/iden3/iden3comm/v2/packers" @@ -25,30 +30,30 @@ func stateVerificationHandler(ethStateContract *abi.State) packers.VerificationH // authV2CircuitStateVerification `authV2` circuit state verification func authV2CircuitStateVerification(contract *abi.State, pubsignals []string) error { - // bytePubsig, err := json.Marshal(pubsignals) - // if err != nil { - // return err - // } - - // authPubSignals := circuits.AuthV2PubSignals{} - // err = authPubSignals.PubSignalsUnmarshal(bytePubsig) - // if err != nil { - // return err - // } - - // globalState := authPubSignals.GISTRoot.BigInt() - // globalStateInfo, err := contract.GetGISTRootInfo(&bind.CallOpts{}, globalState) - // if err != nil { - // return err - // } - - // if globalState.Cmp(globalStateInfo.Root) != 0 { - // return errors.Errorf("invalid global state info in the smart contract, expected root %s, got %s", globalState.String(), globalStateInfo.Root.String()) - // } - - // if (big.NewInt(0)).Cmp(globalStateInfo.ReplacedByRoot) != 0 && time.Since(time.Unix(globalStateInfo.ReplacedAtTimestamp.Int64(), 0)) > time.Minute*15 { - // return errors.Errorf("global state is too old, replaced timestamp is %v", globalStateInfo.ReplacedAtTimestamp.Int64()) - // } + bytePubsig, err := json.Marshal(pubsignals) + if err != nil { + return err + } + + authPubSignals := circuits.AuthV2PubSignals{} + err = authPubSignals.PubSignalsUnmarshal(bytePubsig) + if err != nil { + return err + } + + globalState := authPubSignals.GISTRoot.BigInt() + globalStateInfo, err := contract.GetGISTRootInfo(&bind.CallOpts{}, globalState) + if err != nil { + return err + } + + if globalState.Cmp(globalStateInfo.Root) != 0 { + return errors.Errorf("invalid global state info in the smart contract, expected root %s, got %s", globalState.String(), globalStateInfo.Root.String()) + } + + if (big.NewInt(0)).Cmp(globalStateInfo.ReplacedByRoot) != 0 && time.Since(time.Unix(globalStateInfo.ReplacedAtTimestamp.Int64(), 0)) > time.Minute*15 { + return errors.Errorf("global state is too old, replaced timestamp is %v", globalStateInfo.ReplacedAtTimestamp.Int64()) + } return nil } From 45f39f240d073835fcb5ad22d7ee2c18eb5d3e29 Mon Sep 17 00:00:00 2001 From: Martin Saporiti Date: Thu, 20 Jun 2024 13:25:29 -0300 Subject: [PATCH 30/52] fix: naming --- .github/workflows/demo_deploy_backend.yml | 4 ++-- .github/workflows/demo_deploy_ui.yml | 4 ++-- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/.github/workflows/demo_deploy_backend.yml b/.github/workflows/demo_deploy_backend.yml index 266c8fe43..991158c71 100644 --- a/.github/workflows/demo_deploy_backend.yml +++ b/.github/workflows/demo_deploy_backend.yml @@ -1,4 +1,4 @@ -name: Deploy Issuer Node Backend to Testing AWS Environment +name: Deploy Issuer Node Backend to Demo AWS Environment on: workflow_run: @@ -14,7 +14,7 @@ env: jobs: build-backend: - name: Build and push latest image to AWS Testing Environment + name: Build and push latest image to AWS Demo Environment permissions: id-token: write contents: write diff --git a/.github/workflows/demo_deploy_ui.yml b/.github/workflows/demo_deploy_ui.yml index 72ae3a331..121f549ed 100644 --- a/.github/workflows/demo_deploy_ui.yml +++ b/.github/workflows/demo_deploy_ui.yml @@ -1,4 +1,4 @@ -name: Deploy Issuer Node UI to Testing AWS Environment +name: Deploy Issuer Node UI to Demo AWS Environment on: push: @@ -12,7 +12,7 @@ env: jobs: deploy: - name: Build and Deploy UI to Testing AWS Environment + name: Build and Deploy UI to Demo AWS Environment runs-on: ubuntu-latest permissions: id-token: write From fbdcb0cfd77d1ecfe9bc4e4caea4d2cbc3b056db Mon Sep 17 00:00:00 2001 From: Ilya Date: Thu, 20 Jun 2024 19:34:57 +0300 Subject: [PATCH 31/52] clear code --- internal/core/services/claims.go | 2 +- internal/core/services/identity.go | 40 +++++++++++------------------- 2 files changed, 16 insertions(+), 26 deletions(-) diff --git a/internal/core/services/claims.go b/internal/core/services/claims.go index 5a044a30b..243970374 100644 --- a/internal/core/services/claims.go +++ b/internal/core/services/claims.go @@ -370,7 +370,7 @@ func (c *claim) GetCredentialQrCode(ctx context.Context, issID *w3c.DID, id uuid func (c *claim) Agent(ctx context.Context, req *ports.AgentRequest, mediatype iden3comm.MediaType) (*domain.Agent, error) { if !c.mediatypeManager.AllowMediaType(req.Type, mediatype) { - err := fmt.Errorf("unsupported media type '%s' for message type '%s'", req.Typ, req.Type) + err := fmt.Errorf("unsupported media type '%s' for message type '%s'", mediatype, req.Type) log.Error(ctx, "agent: unsupported media type", "err", err) return nil, err } diff --git a/internal/core/services/identity.go b/internal/core/services/identity.go index c15d8502d..bbfde530d 100644 --- a/internal/core/services/identity.go +++ b/internal/core/services/identity.go @@ -749,32 +749,22 @@ func (i *identity) createIdentity(ctx context.Context, tx db.Querier, hostURL st return nil, nil, fmt.Errorf("can't create RHS publisher: %w", err) } - if len(rhsPublishers) > 0 { - if rhsMode == reverse_hash.RHSModeOnChain && !i.autoPublishingToOnChainRHS { - log.Info(ctx, - "state info (bigints):", - "root:", identity.State.TreeState().State.BigInt().String(), - "claimsTreeRoot:", claimsTree.Root().BigInt().String(), - "revocationsTreeRoot:", merkletree.HashZero.BigInt().String(), - "rootOfRootsTreeRoot:", merkletree.HashZero.BigInt().String(), - ) - } else { - log.Info(ctx, "publishing state to RHS", "publishers", len(rhsPublishers)) - for _, rhsPublisher := range rhsPublishers { - err := rhsPublisher.PublishNodesToRHS(ctx, []mtproof.Node{ - { - Hash: identity.State.TreeState().State, - Children: []*merkletree.Hash{ - claimsTree.Root(), - &merkletree.HashZero, - &merkletree.HashZero, - }, + if len(rhsPublishers) > 0 && !(rhsMode == reverse_hash.RHSModeOnChain && !i.autoPublishingToOnChainRHS) { + log.Info(ctx, "publishing state to RHS", "publishers", len(rhsPublishers)) + for _, rhsPublisher := range rhsPublishers { + err := rhsPublisher.PublishNodesToRHS(ctx, []mtproof.Node{ + { + Hash: identity.State.TreeState().State, + Children: []*merkletree.Hash{ + claimsTree.Root(), + &merkletree.HashZero, + &merkletree.HashZero, }, - }) - if err != nil { - log.Error(ctx, "publishing state to RHS", "err", err) - return nil, nil, err - } + }, + }) + if err != nil { + log.Error(ctx, "publishing state to RHS", "err", err) + return nil, nil, err } } } From 5a580c9f73188294ee3415aa978a126b26462a84 Mon Sep 17 00:00:00 2001 From: Ilya Date: Thu, 20 Jun 2024 20:37:32 +0300 Subject: [PATCH 32/52] add new envs in sample --- .env-issuer.sample | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/.env-issuer.sample b/.env-issuer.sample index d2b3b9a90..cf340c54d 100644 --- a/.env-issuer.sample +++ b/.env-issuer.sample @@ -46,4 +46,8 @@ ISSUER_CREDENTIAL_STATUS_ONCHAIN_TREE_STORE_SUPPORTED_CONTRACT=0x3d3763eC0a50CE1 ISSUER_CREDENTIAL_STATUS_RHS_URL=http://localhost:3001 ISSUER_CREDENTIAL_STATUS_PUBLISHING_KEY_PATH=pbkey ISSUER_CREDENTIAL_STATUS_RHS_MODE=None -ISSUER_CREDENTIAL_STATUS_RHS_CHAIN_ID=<80002 | 80001 | 137> \ No newline at end of file +ISSUER_CREDENTIAL_STATUS_RHS_CHAIN_ID=<80002 | 80001 | 137> + +ISSUER_MEDIA_TYPE_MANAGER_ENABLED=true + +ISSUER_AUTO_PUBLISHING_TO_ON_CHAIN_RHS=true From c2fe2c9410fc55b9cba36b087172f791d5ca781f Mon Sep 17 00:00:00 2001 From: Ilya Date: Fri, 21 Jun 2024 11:20:30 +0300 Subject: [PATCH 33/52] remove auth publishing flag --- cmd/issuer_initializer/main.go | 2 +- cmd/notifications/main.go | 2 +- cmd/pending_publisher/main.go | 2 +- cmd/platform/main.go | 2 +- cmd/platform_ui/main.go | 2 +- internal/api/main_test.go | 3 -- internal/api/server_test.go | 16 +++--- internal/api_ui/main_test.go | 3 -- internal/api_ui/server_test.go | 46 ++++++++--------- internal/config/config.go | 8 --- internal/core/services/identity.go | 50 +++++++++---------- internal/core/services/tests/identity_test.go | 4 +- internal/core/services/tests/link_test.go | 2 +- internal/core/services/tests/main_test.go | 2 - .../core/services/tests/notification_test.go | 2 +- 15 files changed, 64 insertions(+), 82 deletions(-) diff --git a/cmd/issuer_initializer/main.go b/cmd/issuer_initializer/main.go index 53dbe12fb..6ca778004 100644 --- a/cmd/issuer_initializer/main.go +++ b/cmd/issuer_initializer/main.go @@ -147,7 +147,7 @@ func main() { rhsFactory := reverse_hash.NewFactory(cfg.CredentialStatus.RHS.GetURL(), ethConn, common.HexToAddress(cfg.CredentialStatus.OnchainTreeStore.SupportedTreeStoreContract), reverse_hash.DefaultRHSTimeOut) revocationStatusResolver := revocation_status.NewRevocationStatusResolver(cfg.CredentialStatus) cfg.CredentialStatus.SingleIssuer = true - identityService := services.NewIdentity(keyStore, identityRepository, mtRepository, identityStateRepository, mtService, nil, claimsRepository, nil, nil, storage, nil, nil, nil, cfg.CredentialStatus, rhsFactory, revocationStatusResolver, *cfg.AutoPublishingToOnChainRHS) + identityService := services.NewIdentity(keyStore, identityRepository, mtRepository, identityStateRepository, mtService, nil, claimsRepository, nil, nil, storage, nil, nil, nil, cfg.CredentialStatus, rhsFactory, revocationStatusResolver) didCreationOptions := &ports.DIDCreationOptions{ Method: core.DIDMethod(cfg.APIUI.IdentityMethod), diff --git a/cmd/notifications/main.go b/cmd/notifications/main.go index d55ada7ce..0dbb299cf 100644 --- a/cmd/notifications/main.go +++ b/cmd/notifications/main.go @@ -190,7 +190,7 @@ func newCredentialsService(ctx context.Context, cfg *config.Configuration, stora *cfg.MediaTypeManager.Enabled, ) - identityService := services.NewIdentity(keyStore, identityRepository, mtRepository, identityStateRepository, mtService, qrService, claimsRepository, revocationRepository, nil, storage, nil, nil, ps, cfg.CredentialStatus, rhsFactory, revocationStatusResolver, *cfg.AutoPublishingToOnChainRHS) + identityService := services.NewIdentity(keyStore, identityRepository, mtRepository, identityStateRepository, mtService, qrService, claimsRepository, revocationRepository, nil, storage, nil, nil, ps, cfg.CredentialStatus, rhsFactory, revocationStatusResolver) claimsService := services.NewClaim(claimsRepository, identityService, qrService, mtService, identityStateRepository, schemaLoader, storage, cfg.APIUI.ServerURL, ps, cfg.IPFS.GatewayURL, revocationStatusResolver, mediaTypeManager) return claimsService, nil diff --git a/cmd/pending_publisher/main.go b/cmd/pending_publisher/main.go index 2490b5a23..9f6eff001 100644 --- a/cmd/pending_publisher/main.go +++ b/cmd/pending_publisher/main.go @@ -171,7 +171,7 @@ func main() { *cfg.MediaTypeManager.Enabled, ) - identityService := services.NewIdentity(keyStore, identityRepo, mtRepo, identityStateRepo, mtService, qrService, claimsRepo, revocationRepository, connectionsRepository, storage, nil, nil, pubsub.NewMock(), cfg.CredentialStatus, rhsFactory, revocationStatusResolver, *cfg.AutoPublishingToOnChainRHS) + identityService := services.NewIdentity(keyStore, identityRepo, mtRepo, identityStateRepo, mtService, qrService, claimsRepo, revocationRepository, connectionsRepository, storage, nil, nil, pubsub.NewMock(), cfg.CredentialStatus, rhsFactory, revocationStatusResolver) claimsService := services.NewClaim(claimsRepo, identityService, qrService, mtService, identityStateRepo, schemaLoader, storage, cfg.APIUI.ServerURL, ps, cfg.IPFS.GatewayURL, revocationStatusResolver, mediaTypeManager) circuitsLoaderService := circuitLoaders.NewCircuits(cfg.Circuit.Path) diff --git a/cmd/platform/main.go b/cmd/platform/main.go index ed432fc13..e08f1d9c6 100644 --- a/cmd/platform/main.go +++ b/cmd/platform/main.go @@ -154,7 +154,7 @@ func main() { ) revocationStatusResolver := revocation_status.NewRevocationStatusResolver(cfg.CredentialStatus) - identityService := services.NewIdentity(keyStore, identityRepository, mtRepository, identityStateRepository, mtService, qrService, claimsRepository, revocationRepository, nil, storage, nil, nil, ps, cfg.CredentialStatus, rhsFactory, revocationStatusResolver, *cfg.AutoPublishingToOnChainRHS) + identityService := services.NewIdentity(keyStore, identityRepository, mtRepository, identityStateRepository, mtService, qrService, claimsRepository, revocationRepository, nil, storage, nil, nil, ps, cfg.CredentialStatus, rhsFactory, revocationStatusResolver) claimsService := services.NewClaim(claimsRepository, identityService, qrService, mtService, identityStateRepository, schemaLoader, storage, cfg.ServerUrl, ps, cfg.IPFS.GatewayURL, revocationStatusResolver, mediaTypeManager) proofService := gateways.NewProver(ctx, cfg, circuitsLoaderService) diff --git a/cmd/platform_ui/main.go b/cmd/platform_ui/main.go index 1f1a91c85..2d8eb1948 100644 --- a/cmd/platform_ui/main.go +++ b/cmd/platform_ui/main.go @@ -186,7 +186,7 @@ func main() { ) revocationStatusResolver := revocation_status.NewRevocationStatusResolver(cfg.CredentialStatus) - identityService := services.NewIdentity(keyStore, identityRepository, mtRepository, identityStateRepository, mtService, qrService, claimsRepository, revocationRepository, connectionsRepository, storage, verifier, sessionRepository, ps, cfg.CredentialStatus, rhsFactory, revocationStatusResolver, *cfg.AutoPublishingToOnChainRHS) + identityService := services.NewIdentity(keyStore, identityRepository, mtRepository, identityStateRepository, mtService, qrService, claimsRepository, revocationRepository, connectionsRepository, storage, verifier, sessionRepository, ps, cfg.CredentialStatus, rhsFactory, revocationStatusResolver) schemaService := services.NewSchema(schemaRepository, schemaLoader) claimsService := services.NewClaim(claimsRepository, identityService, qrService, mtService, identityStateRepository, schemaLoader, storage, cfg.APIUI.ServerURL, ps, cfg.IPFS.GatewayURL, revocationStatusResolver, mediaTypeManager) connectionsService := services.NewConnection(connectionsRepository, claimsRepository, storage) diff --git a/internal/api/main_test.go b/internal/api/main_test.go index ac1bad0d2..fd59a0d4a 100644 --- a/internal/api/main_test.go +++ b/internal/api/main_test.go @@ -12,7 +12,6 @@ import ( "github.com/iden3/iden3comm/v2" "github.com/piprate/json-gold/ld" - "github.com/polygonid/sh-id-platform/internal/common" "github.com/polygonid/sh-id-platform/internal/config" "github.com/polygonid/sh-id-platform/internal/core/ports" "github.com/polygonid/sh-id-platform/internal/db" @@ -108,8 +107,6 @@ func TestMain(m *testing.M) { URL: "http://localhost:3001", }, } - cfg.AutoPublishingToOnChainRHS = common.ToPointer[bool](true) - m.Run() } diff --git a/internal/api/server_test.go b/internal/api/server_test.go index 29243219f..769efbd38 100644 --- a/internal/api/server_test.go +++ b/internal/api/server_test.go @@ -53,7 +53,7 @@ func TestServer_CreateIdentity(t *testing.T) { rhsFactory := reverse_hash.NewFactory(cfg.CredentialStatus.RHS.GetURL(), nil, commonEth.HexToAddress(cfg.CredentialStatus.OnchainTreeStore.SupportedTreeStoreContract), reverse_hash.DefaultRHSTimeOut) revocationStatusResolver := revocation_status.NewRevocationStatusResolver(cfg.CredentialStatus) - identityService := services.NewIdentity(keyStore, identityRepo, mtRepo, identityStateRepo, mtService, nil, claimsRepo, revocationRepository, connectionsRepository, storage, nil, nil, pubsub.NewMock(), cfg.CredentialStatus, rhsFactory, revocationStatusResolver, *cfg.AutoPublishingToOnChainRHS) + identityService := services.NewIdentity(keyStore, identityRepo, mtRepo, identityStateRepo, mtService, nil, claimsRepo, revocationRepository, connectionsRepository, storage, nil, nil, pubsub.NewMock(), cfg.CredentialStatus, rhsFactory, revocationStatusResolver) mediaTypeManager := services.NewMediaTypeManager( map[iden3comm.ProtocolMessage][]string{ @@ -257,7 +257,7 @@ func TestServer_RevokeClaim(t *testing.T) { connectionsRepository := repositories.NewConnections() revocationStatusResolver := revocation_status.NewRevocationStatusResolver(cfg.CredentialStatus) rhsFactory := reverse_hash.NewFactory(cfg.CredentialStatus.RHS.GetURL(), nil, commonEth.HexToAddress(cfg.CredentialStatus.OnchainTreeStore.SupportedTreeStoreContract), reverse_hash.DefaultRHSTimeOut) - identityService := services.NewIdentity(&KMSMock{}, identityRepo, mtRepo, identityStateRepo, mtService, nil, claimsRepo, revocationRepository, connectionsRepository, storage, nil, nil, pubsub.NewMock(), cfg.CredentialStatus, rhsFactory, revocationStatusResolver, *cfg.AutoPublishingToOnChainRHS) + identityService := services.NewIdentity(&KMSMock{}, identityRepo, mtRepo, identityStateRepo, mtService, nil, claimsRepo, revocationRepository, connectionsRepository, storage, nil, nil, pubsub.NewMock(), cfg.CredentialStatus, rhsFactory, revocationStatusResolver) mediaTypeManager := services.NewMediaTypeManager( map[iden3comm.ProtocolMessage][]string{ @@ -423,7 +423,7 @@ func TestServer_CreateClaim(t *testing.T) { rhsFactory := reverse_hash.NewFactory(cfg.CredentialStatus.RHS.GetURL(), nil, commonEth.HexToAddress(cfg.CredentialStatus.OnchainTreeStore.SupportedTreeStoreContract), reverse_hash.DefaultRHSTimeOut) revocationStatusResolver := revocation_status.NewRevocationStatusResolver(cfg.CredentialStatus) - identityService := services.NewIdentity(keyStore, identityRepo, mtRepo, identityStateRepo, mtService, qrService, claimsRepo, revocationRepository, connectionsRepository, storage, nil, nil, pubsub.NewMock(), cfg.CredentialStatus, rhsFactory, revocationStatusResolver, *cfg.AutoPublishingToOnChainRHS) + identityService := services.NewIdentity(keyStore, identityRepo, mtRepo, identityStateRepo, mtService, qrService, claimsRepo, revocationRepository, connectionsRepository, storage, nil, nil, pubsub.NewMock(), cfg.CredentialStatus, rhsFactory, revocationStatusResolver) pubSub := pubsub.NewMock() claimsService := services.NewClaim(claimsRepo, identityService, nil, mtService, identityStateRepo, schemaLoader, storage, cfg.CredentialStatus.Iden3CommAgentStatus.GetURL(), pubSub, ipfsGatewayURL, revocationStatusResolver, mediaTypeManager) accountService := services.NewAccountService(cfg.Ethereum, keyStore) @@ -601,7 +601,7 @@ func TestServer_GetIdentities(t *testing.T) { connectionsRepository := repositories.NewConnections() rhsFactory := reverse_hash.NewFactory(cfg.CredentialStatus.RHS.GetURL(), nil, commonEth.HexToAddress(cfg.CredentialStatus.OnchainTreeStore.SupportedTreeStoreContract), reverse_hash.DefaultRHSTimeOut) revocationStatusResolver := revocation_status.NewRevocationStatusResolver(cfg.CredentialStatus) - identityService := services.NewIdentity(&KMSMock{}, identityRepo, mtRepo, identityStateRepo, mtService, nil, claimsRepo, revocationRepository, connectionsRepository, storage, nil, nil, pubsub.NewMock(), cfg.CredentialStatus, rhsFactory, revocationStatusResolver, *cfg.AutoPublishingToOnChainRHS) + identityService := services.NewIdentity(&KMSMock{}, identityRepo, mtRepo, identityStateRepo, mtService, nil, claimsRepo, revocationRepository, connectionsRepository, storage, nil, nil, pubsub.NewMock(), cfg.CredentialStatus, rhsFactory, revocationStatusResolver) mediaTypeManager := services.NewMediaTypeManager( map[iden3comm.ProtocolMessage][]string{ @@ -681,7 +681,7 @@ func TestServer_GetClaimQrCode(t *testing.T) { connectionsRepository := repositories.NewConnections() revocationStatusResolver := revocation_status.NewRevocationStatusResolver(cfg.CredentialStatus) rhsFactory := reverse_hash.NewFactory(cfg.CredentialStatus.RHS.GetURL(), nil, commonEth.HexToAddress(cfg.CredentialStatus.OnchainTreeStore.SupportedTreeStoreContract), reverse_hash.DefaultRHSTimeOut) - identityService := services.NewIdentity(&KMSMock{}, identityRepo, mtRepo, identityStateRepo, mtService, nil, claimsRepo, revocationRepository, connectionsRepository, storage, nil, nil, pubsub.NewMock(), cfg.CredentialStatus, rhsFactory, revocationStatusResolver, *cfg.AutoPublishingToOnChainRHS) + identityService := services.NewIdentity(&KMSMock{}, identityRepo, mtRepo, identityStateRepo, mtService, nil, claimsRepo, revocationRepository, connectionsRepository, storage, nil, nil, pubsub.NewMock(), cfg.CredentialStatus, rhsFactory, revocationStatusResolver) idStr := "did:polygonid:polygon:mumbai:2qPrv5Yx8s1qAmEnPym68LfT7gTbASGampiGU7TseL" idNoClaims := "did:polygonid:polygon:mumbai:2qGjTUuxZKqKS4Q8UmxHUPw55g15QgEVGnj6Wkq8Vk" @@ -834,7 +834,7 @@ func TestServer_GetClaim(t *testing.T) { connectionsRepository := repositories.NewConnections() revocationStatusResolver := revocation_status.NewRevocationStatusResolver(cfg.CredentialStatus) rhsFactory := reverse_hash.NewFactory(cfg.CredentialStatus.RHS.GetURL(), nil, commonEth.HexToAddress(cfg.CredentialStatus.OnchainTreeStore.SupportedTreeStoreContract), reverse_hash.DefaultRHSTimeOut) - identityService := services.NewIdentity(&KMSMock{}, identityRepo, mtRepo, identityStateRepo, mtService, nil, claimsRepo, revocationRepository, connectionsRepository, storage, nil, nil, pubsub.NewMock(), cfg.CredentialStatus, rhsFactory, revocationStatusResolver, *cfg.AutoPublishingToOnChainRHS) + identityService := services.NewIdentity(&KMSMock{}, identityRepo, mtRepo, identityStateRepo, mtService, nil, claimsRepo, revocationRepository, connectionsRepository, storage, nil, nil, pubsub.NewMock(), cfg.CredentialStatus, rhsFactory, revocationStatusResolver) mediaTypeManager := services.NewMediaTypeManager( map[iden3comm.ProtocolMessage][]string{ @@ -1017,7 +1017,7 @@ func TestServer_GetClaims(t *testing.T) { connectionsRepository := repositories.NewConnections() revocationStatusResolver := revocation_status.NewRevocationStatusResolver(cfg.CredentialStatus) rhsFactory := reverse_hash.NewFactory(cfg.CredentialStatus.RHS.GetURL(), nil, commonEth.HexToAddress(cfg.CredentialStatus.OnchainTreeStore.SupportedTreeStoreContract), reverse_hash.DefaultRHSTimeOut) - identityService := services.NewIdentity(keyStore, identityRepo, mtRepo, identityStateRepo, mtService, nil, claimsRepo, revocationRepository, connectionsRepository, storage, nil, nil, pubsub.NewMock(), cfg.CredentialStatus, rhsFactory, revocationStatusResolver, *cfg.AutoPublishingToOnChainRHS) + identityService := services.NewIdentity(keyStore, identityRepo, mtRepo, identityStateRepo, mtService, nil, claimsRepo, revocationRepository, connectionsRepository, storage, nil, nil, pubsub.NewMock(), cfg.CredentialStatus, rhsFactory, revocationStatusResolver) mediaTypeManager := services.NewMediaTypeManager( map[iden3comm.ProtocolMessage][]string{ @@ -1372,7 +1372,7 @@ func TestServer_GetRevocationStatus(t *testing.T) { connectionsRepository := repositories.NewConnections() revocationStatusResolver := revocation_status.NewRevocationStatusResolver(cfg.CredentialStatus) rhsFactory := reverse_hash.NewFactory(cfg.CredentialStatus.RHS.GetURL(), nil, commonEth.HexToAddress(cfg.CredentialStatus.OnchainTreeStore.SupportedTreeStoreContract), reverse_hash.DefaultRHSTimeOut) - identityService := services.NewIdentity(keyStore, identityRepo, mtRepo, identityStateRepo, mtService, nil, claimsRepo, revocationRepository, connectionsRepository, storage, nil, nil, pubsub.NewMock(), cfg.CredentialStatus, rhsFactory, revocationStatusResolver, *cfg.AutoPublishingToOnChainRHS) + identityService := services.NewIdentity(keyStore, identityRepo, mtRepo, identityStateRepo, mtService, nil, claimsRepo, revocationRepository, connectionsRepository, storage, nil, nil, pubsub.NewMock(), cfg.CredentialStatus, rhsFactory, revocationStatusResolver) identity, err := identityService.Create(ctx, "http://localhost:3001", &ports.DIDCreationOptions{Method: method, Blockchain: blockchain, Network: network, KeyType: BJJ}) assert.NoError(t, err) diff --git a/internal/api_ui/main_test.go b/internal/api_ui/main_test.go index fc8a053a6..d93c596ea 100644 --- a/internal/api_ui/main_test.go +++ b/internal/api_ui/main_test.go @@ -15,7 +15,6 @@ import ( "github.com/stretchr/testify/assert" "github.com/stretchr/testify/require" - "github.com/polygonid/sh-id-platform/internal/common" "github.com/polygonid/sh-id-platform/internal/config" "github.com/polygonid/sh-id-platform/internal/core/ports" "github.com/polygonid/sh-id-platform/internal/db" @@ -93,8 +92,6 @@ func TestMain(m *testing.M) { URL: "http://localhost:3001", }, } - cfg.AutoPublishingToOnChainRHS = common.ToPointer[bool](true) - schemaLoader = loader.NewDocumentLoader(ipfsGatewayURL) m.Run() diff --git a/internal/api_ui/server_test.go b/internal/api_ui/server_test.go index 43162084d..dbc945847 100644 --- a/internal/api_ui/server_test.go +++ b/internal/api_ui/server_test.go @@ -49,7 +49,7 @@ func TestServer_CheckStatus(t *testing.T) { connectionsRepository := repositories.NewConnections() revocationStatusResolver := revocation_status.NewRevocationStatusResolver(cfg.CredentialStatus) rhsFactory := reverse_hash.NewFactory(cfg.CredentialStatus.RHS.URL, nil, commonEth.HexToAddress(cfg.CredentialStatus.OnchainTreeStore.SupportedTreeStoreContract), reverse_hash.DefaultRHSTimeOut) - identityService := services.NewIdentity(&KMSMock{}, identityRepo, mtRepo, identityStateRepo, mtService, nil, claimsRepo, revocationRepository, connectionsRepository, storage, nil, nil, pubsub.NewMock(), cfg.CredentialStatus, rhsFactory, revocationStatusResolver, *cfg.AutoPublishingToOnChainRHS) + identityService := services.NewIdentity(&KMSMock{}, identityRepo, mtRepo, identityStateRepo, mtService, nil, claimsRepo, revocationRepository, connectionsRepository, storage, nil, nil, pubsub.NewMock(), cfg.CredentialStatus, rhsFactory, revocationStatusResolver) schemaService := services.NewSchema(repositories.NewSchema(*storage), schemaLoader) mediaTypeManager := services.NewMediaTypeManager( @@ -241,7 +241,7 @@ func TestServer_AuthQRCode(t *testing.T) { sessionRepository := repositories.NewSessionCached(cachex) revocationStatusResolver := revocation_status.NewRevocationStatusResolver(cfg.CredentialStatus) rhsFactory := reverse_hash.NewFactory(cfg.CredentialStatus.RHS.URL, nil, commonEth.HexToAddress(cfg.CredentialStatus.OnchainTreeStore.SupportedTreeStoreContract), reverse_hash.DefaultRHSTimeOut) - identityService := services.NewIdentity(&KMSMock{}, identityRepo, mtRepo, identityStateRepo, mtService, qrService, claimsRepo, revocationRepository, connectionsRepository, storage, nil, sessionRepository, pubsub.NewMock(), cfg.CredentialStatus, rhsFactory, revocationStatusResolver, *cfg.AutoPublishingToOnChainRHS) + identityService := services.NewIdentity(&KMSMock{}, identityRepo, mtRepo, identityStateRepo, mtService, qrService, claimsRepo, revocationRepository, connectionsRepository, storage, nil, sessionRepository, pubsub.NewMock(), cfg.CredentialStatus, rhsFactory, revocationStatusResolver) server := NewServer(&cfg, identityService, NewClaimsMock(), NewSchemaMock(), NewConnectionsMock(), NewLinkMock(), qrService, NewPublisherMock(), NewPackageManagerMock(), nil) issuerDID, err := w3c.ParseDID("did:polygonid:polygon:mumbai:2qE1BZ7gcmEoP2KppvFPCZqyzyb5tK9T6Gec5HFANQ") require.NoError(t, err) @@ -815,7 +815,7 @@ func TestServer_DeleteConnection(t *testing.T) { connectionsRepository := repositories.NewConnections() revocationStatusResolver := revocation_status.NewRevocationStatusResolver(cfg.CredentialStatus) rhsFactory := reverse_hash.NewFactory(cfg.CredentialStatus.RHS.URL, nil, commonEth.HexToAddress(cfg.CredentialStatus.OnchainTreeStore.SupportedTreeStoreContract), reverse_hash.DefaultRHSTimeOut) - identityService := services.NewIdentity(keyStore, identityRepo, mtRepo, identityStateRepo, mtService, nil, claimsRepo, revocationRepository, connectionsRepository, storage, nil, nil, pubsub.NewMock(), cfg.CredentialStatus, rhsFactory, revocationStatusResolver, *cfg.AutoPublishingToOnChainRHS) + identityService := services.NewIdentity(keyStore, identityRepo, mtRepo, identityStateRepo, mtService, nil, claimsRepo, revocationRepository, connectionsRepository, storage, nil, nil, pubsub.NewMock(), cfg.CredentialStatus, rhsFactory, revocationStatusResolver) mediaTypeManager := services.NewMediaTypeManager( map[iden3comm.ProtocolMessage][]string{ @@ -1074,7 +1074,7 @@ func TestServer_RevokeConnectionCredentials(t *testing.T) { connectionsRepository := repositories.NewConnections() revocationStatusResolver := revocation_status.NewRevocationStatusResolver(cfg.CredentialStatus) rhsFactory := reverse_hash.NewFactory(cfg.CredentialStatus.RHS.URL, nil, commonEth.HexToAddress(cfg.CredentialStatus.OnchainTreeStore.SupportedTreeStoreContract), reverse_hash.DefaultRHSTimeOut) - identityService := services.NewIdentity(keyStore, identityRepo, mtRepo, identityStateRepo, mtService, nil, claimsRepo, revocationRepository, connectionsRepository, storage, nil, nil, pubsub.NewMock(), cfg.CredentialStatus, rhsFactory, revocationStatusResolver, *cfg.AutoPublishingToOnChainRHS) + identityService := services.NewIdentity(keyStore, identityRepo, mtRepo, identityStateRepo, mtService, nil, claimsRepo, revocationRepository, connectionsRepository, storage, nil, nil, pubsub.NewMock(), cfg.CredentialStatus, rhsFactory, revocationStatusResolver) mediaTypeManager := services.NewMediaTypeManager( map[iden3comm.ProtocolMessage][]string{ @@ -1194,7 +1194,7 @@ func TestServer_CreateCredential(t *testing.T) { connectionsRepository := repositories.NewConnections() revocationStatusResolver := revocation_status.NewRevocationStatusResolver(cfg.CredentialStatus) rhsFactory := reverse_hash.NewFactory(cfg.CredentialStatus.RHS.URL, nil, commonEth.HexToAddress(cfg.CredentialStatus.OnchainTreeStore.SupportedTreeStoreContract), reverse_hash.DefaultRHSTimeOut) - identityService := services.NewIdentity(keyStore, identityRepo, mtRepo, identityStateRepo, mtService, nil, claimsRepo, revocationRepository, connectionsRepository, storage, nil, nil, pubsub.NewMock(), cfg.CredentialStatus, rhsFactory, revocationStatusResolver, *cfg.AutoPublishingToOnChainRHS) + identityService := services.NewIdentity(keyStore, identityRepo, mtRepo, identityStateRepo, mtService, nil, claimsRepo, revocationRepository, connectionsRepository, storage, nil, nil, pubsub.NewMock(), cfg.CredentialStatus, rhsFactory, revocationStatusResolver) pubSub := pubsub.NewMock() mediaTypeManager := services.NewMediaTypeManager( @@ -1380,7 +1380,7 @@ func TestServer_DeleteCredential(t *testing.T) { connectionsRepository := repositories.NewConnections() revocationStatusResolver := revocation_status.NewRevocationStatusResolver(cfg.CredentialStatus) rhsFactory := reverse_hash.NewFactory(cfg.CredentialStatus.RHS.URL, nil, commonEth.HexToAddress(cfg.CredentialStatus.OnchainTreeStore.SupportedTreeStoreContract), reverse_hash.DefaultRHSTimeOut) - identityService := services.NewIdentity(keyStore, identityRepo, mtRepo, identityStateRepo, mtService, nil, claimsRepo, revocationRepository, connectionsRepository, storage, nil, nil, pubsub.NewMock(), cfg.CredentialStatus, rhsFactory, revocationStatusResolver, *cfg.AutoPublishingToOnChainRHS) + identityService := services.NewIdentity(keyStore, identityRepo, mtRepo, identityStateRepo, mtService, nil, claimsRepo, revocationRepository, connectionsRepository, storage, nil, nil, pubsub.NewMock(), cfg.CredentialStatus, rhsFactory, revocationStatusResolver) mediaTypeManager := services.NewMediaTypeManager( map[iden3comm.ProtocolMessage][]string{ @@ -1492,7 +1492,7 @@ func TestServer_GetCredential(t *testing.T) { connectionsRepository := repositories.NewConnections() revocationStatusResolver := revocation_status.NewRevocationStatusResolver(cfg.CredentialStatus) rhsFactory := reverse_hash.NewFactory(cfg.CredentialStatus.RHS.URL, nil, commonEth.HexToAddress(cfg.CredentialStatus.OnchainTreeStore.SupportedTreeStoreContract), reverse_hash.DefaultRHSTimeOut) - identityService := services.NewIdentity(keyStore, identityRepo, mtRepo, identityStateRepo, mtService, nil, claimsRepo, revocationRepository, connectionsRepository, storage, nil, nil, pubsub.NewMock(), cfg.CredentialStatus, rhsFactory, revocationStatusResolver, *cfg.AutoPublishingToOnChainRHS) + identityService := services.NewIdentity(keyStore, identityRepo, mtRepo, identityStateRepo, mtService, nil, claimsRepo, revocationRepository, connectionsRepository, storage, nil, nil, pubsub.NewMock(), cfg.CredentialStatus, rhsFactory, revocationStatusResolver) mediaTypeManager := services.NewMediaTypeManager( map[iden3comm.ProtocolMessage][]string{ @@ -1693,7 +1693,7 @@ func TestServer_GetCredentials(t *testing.T) { connectionsRepository := repositories.NewConnections() revocationStatusResolver := revocation_status.NewRevocationStatusResolver(cfg.CredentialStatus) rhsFactory := reverse_hash.NewFactory(cfg.CredentialStatus.RHS.URL, nil, commonEth.HexToAddress(cfg.CredentialStatus.OnchainTreeStore.SupportedTreeStoreContract), reverse_hash.DefaultRHSTimeOut) - identityService := services.NewIdentity(keyStore, identityRepo, mtRepo, identityStateRepo, mtService, nil, claimsRepo, revocationRepository, connectionsRepository, storage, nil, nil, pubsub.NewMock(), cfg.CredentialStatus, rhsFactory, revocationStatusResolver, *cfg.AutoPublishingToOnChainRHS) + identityService := services.NewIdentity(keyStore, identityRepo, mtRepo, identityStateRepo, mtService, nil, claimsRepo, revocationRepository, connectionsRepository, storage, nil, nil, pubsub.NewMock(), cfg.CredentialStatus, rhsFactory, revocationStatusResolver) mediaTypeManager := services.NewMediaTypeManager( map[iden3comm.ProtocolMessage][]string{ @@ -2170,7 +2170,7 @@ func TestServer_GetCredentialQrCode(t *testing.T) { connectionsRepository := repositories.NewConnections() revocationStatusResolver := revocation_status.NewRevocationStatusResolver(cfg.CredentialStatus) rhsFactory := reverse_hash.NewFactory(cfg.CredentialStatus.RHS.URL, nil, commonEth.HexToAddress(cfg.CredentialStatus.OnchainTreeStore.SupportedTreeStoreContract), reverse_hash.DefaultRHSTimeOut) - identityService := services.NewIdentity(keyStore, identityRepo, mtRepo, identityStateRepo, mtService, qrService, claimsRepo, revocationRepository, connectionsRepository, storage, nil, nil, pubsub.NewMock(), cfg.CredentialStatus, rhsFactory, revocationStatusResolver, *cfg.AutoPublishingToOnChainRHS) + identityService := services.NewIdentity(keyStore, identityRepo, mtRepo, identityStateRepo, mtService, qrService, claimsRepo, revocationRepository, connectionsRepository, storage, nil, nil, pubsub.NewMock(), cfg.CredentialStatus, rhsFactory, revocationStatusResolver) mediaTypeManager := services.NewMediaTypeManager( map[iden3comm.ProtocolMessage][]string{ @@ -2333,7 +2333,7 @@ func TestServer_GetConnection(t *testing.T) { connectionsRepository := repositories.NewConnections() rhsFactory := reverse_hash.NewFactory(cfg.CredentialStatus.RHS.URL, nil, commonEth.HexToAddress(cfg.CredentialStatus.OnchainTreeStore.SupportedTreeStoreContract), reverse_hash.DefaultRHSTimeOut) revocationStatusResolver := revocation_status.NewRevocationStatusResolver(cfg.CredentialStatus) - identityService := services.NewIdentity(keyStore, identityRepo, mtRepo, identityStateRepo, mtService, nil, claimsRepo, revocationRepository, connectionsRepository, storage, nil, nil, pubsub.NewMock(), cfg.CredentialStatus, rhsFactory, revocationStatusResolver, *cfg.AutoPublishingToOnChainRHS) + identityService := services.NewIdentity(keyStore, identityRepo, mtRepo, identityStateRepo, mtService, nil, claimsRepo, revocationRepository, connectionsRepository, storage, nil, nil, pubsub.NewMock(), cfg.CredentialStatus, rhsFactory, revocationStatusResolver) mediaTypeManager := services.NewMediaTypeManager( map[iden3comm.ProtocolMessage][]string{ @@ -2527,7 +2527,7 @@ func TestServer_GetConnections(t *testing.T) { connectionsRepository := repositories.NewConnections() revocationStatusResolver := revocation_status.NewRevocationStatusResolver(cfg.CredentialStatus) rhsFactory := reverse_hash.NewFactory(cfg.CredentialStatus.RHS.URL, nil, commonEth.HexToAddress(cfg.CredentialStatus.OnchainTreeStore.SupportedTreeStoreContract), reverse_hash.DefaultRHSTimeOut) - identityService := services.NewIdentity(keyStore, identityRepo, mtRepo, identityStateRepo, mtService, nil, claimsRepo, revocationRepository, connectionsRepository, storage, nil, nil, pubsub.NewMock(), cfg.CredentialStatus, rhsFactory, revocationStatusResolver, *cfg.AutoPublishingToOnChainRHS) + identityService := services.NewIdentity(keyStore, identityRepo, mtRepo, identityStateRepo, mtService, nil, claimsRepo, revocationRepository, connectionsRepository, storage, nil, nil, pubsub.NewMock(), cfg.CredentialStatus, rhsFactory, revocationStatusResolver) mediaTypeManager := services.NewMediaTypeManager( map[iden3comm.ProtocolMessage][]string{ @@ -3214,7 +3214,7 @@ func TestServer_RevokeCredential(t *testing.T) { connectionsRepository := repositories.NewConnections() revocationStatusResolver := revocation_status.NewRevocationStatusResolver(cfg.CredentialStatus) rhsFactory := reverse_hash.NewFactory(cfg.CredentialStatus.RHS.URL, nil, commonEth.HexToAddress(cfg.CredentialStatus.OnchainTreeStore.SupportedTreeStoreContract), reverse_hash.DefaultRHSTimeOut) - identityService := services.NewIdentity(&KMSMock{}, identityRepo, mtRepo, identityStateRepo, mtService, nil, claimsRepo, revocationRepository, connectionsRepository, storage, nil, nil, pubsub.NewMock(), cfg.CredentialStatus, rhsFactory, revocationStatusResolver, *cfg.AutoPublishingToOnChainRHS) + identityService := services.NewIdentity(&KMSMock{}, identityRepo, mtRepo, identityStateRepo, mtService, nil, claimsRepo, revocationRepository, connectionsRepository, storage, nil, nil, pubsub.NewMock(), cfg.CredentialStatus, rhsFactory, revocationStatusResolver) mediaTypeManager := services.NewMediaTypeManager( map[iden3comm.ProtocolMessage][]string{ @@ -3363,7 +3363,7 @@ func TestServer_CreateLink(t *testing.T) { sessionRepository := repositories.NewSessionCached(cachex) revocationStatusResolver := revocation_status.NewRevocationStatusResolver(cfg.CredentialStatus) rhsFactory := reverse_hash.NewFactory(cfg.CredentialStatus.RHS.URL, nil, commonEth.HexToAddress(cfg.CredentialStatus.OnchainTreeStore.SupportedTreeStoreContract), reverse_hash.DefaultRHSTimeOut) - identityService := services.NewIdentity(keyStore, identityRepo, mtRepo, identityStateRepo, mtService, nil, claimsRepo, revocationRepository, connectionsRepository, storage, nil, nil, pubsub.NewMock(), cfg.CredentialStatus, rhsFactory, revocationStatusResolver, *cfg.AutoPublishingToOnChainRHS) + identityService := services.NewIdentity(keyStore, identityRepo, mtRepo, identityStateRepo, mtService, nil, claimsRepo, revocationRepository, connectionsRepository, storage, nil, nil, pubsub.NewMock(), cfg.CredentialStatus, rhsFactory, revocationStatusResolver) pubSub := pubsub.NewMock() mediaTypeManager := services.NewMediaTypeManager( @@ -3598,7 +3598,7 @@ func TestServer_ActivateLink(t *testing.T) { sessionRepository := repositories.NewSessionCached(cachex) revocationStatusResolver := revocation_status.NewRevocationStatusResolver(cfg.CredentialStatus) rhsFactory := reverse_hash.NewFactory(cfg.CredentialStatus.RHS.URL, nil, commonEth.HexToAddress(cfg.CredentialStatus.OnchainTreeStore.SupportedTreeStoreContract), reverse_hash.DefaultRHSTimeOut) - identityService := services.NewIdentity(keyStore, identityRepo, mtRepo, identityStateRepo, mtService, nil, claimsRepo, revocationRepository, connectionsRepository, storage, nil, nil, pubsub.NewMock(), cfg.CredentialStatus, rhsFactory, revocationStatusResolver, *cfg.AutoPublishingToOnChainRHS) + identityService := services.NewIdentity(keyStore, identityRepo, mtRepo, identityStateRepo, mtService, nil, claimsRepo, revocationRepository, connectionsRepository, storage, nil, nil, pubsub.NewMock(), cfg.CredentialStatus, rhsFactory, revocationStatusResolver) mediaTypeManager := services.NewMediaTypeManager( map[iden3comm.ProtocolMessage][]string{ @@ -3756,7 +3756,7 @@ func TestServer_GetLink(t *testing.T) { sessionRepository := repositories.NewSessionCached(cachex) revocationStatusResolver := revocation_status.NewRevocationStatusResolver(cfg.CredentialStatus) rhsFactory := reverse_hash.NewFactory(cfg.CredentialStatus.RHS.URL, nil, commonEth.HexToAddress(cfg.CredentialStatus.OnchainTreeStore.SupportedTreeStoreContract), reverse_hash.DefaultRHSTimeOut) - identityService := services.NewIdentity(keyStore, identityRepo, mtRepo, identityStateRepo, mtService, nil, claimsRepo, revocationRepository, connectionsRepository, storage, nil, nil, pubsub.NewMock(), cfg.CredentialStatus, rhsFactory, revocationStatusResolver, *cfg.AutoPublishingToOnChainRHS) + identityService := services.NewIdentity(keyStore, identityRepo, mtRepo, identityStateRepo, mtService, nil, claimsRepo, revocationRepository, connectionsRepository, storage, nil, nil, pubsub.NewMock(), cfg.CredentialStatus, rhsFactory, revocationStatusResolver) mediaTypeManager := services.NewMediaTypeManager( map[iden3comm.ProtocolMessage][]string{ @@ -3941,7 +3941,7 @@ func TestServer_GetAllLinks(t *testing.T) { sessionRepository := repositories.NewSessionCached(cachex) revocationStatusResolver := revocation_status.NewRevocationStatusResolver(cfg.CredentialStatus) rhsFactory := reverse_hash.NewFactory(cfg.CredentialStatus.RHS.URL, nil, commonEth.HexToAddress(cfg.CredentialStatus.OnchainTreeStore.SupportedTreeStoreContract), reverse_hash.DefaultRHSTimeOut) - identityService := services.NewIdentity(keyStore, identityRepo, mtRepo, identityStateRepo, mtService, nil, claimsRepo, revocationRepository, connectionsRepository, storage, nil, nil, pubsub.NewMock(), cfg.CredentialStatus, rhsFactory, revocationStatusResolver, *cfg.AutoPublishingToOnChainRHS) + identityService := services.NewIdentity(keyStore, identityRepo, mtRepo, identityStateRepo, mtService, nil, claimsRepo, revocationRepository, connectionsRepository, storage, nil, nil, pubsub.NewMock(), cfg.CredentialStatus, rhsFactory, revocationStatusResolver) mediaTypeManager := services.NewMediaTypeManager( map[iden3comm.ProtocolMessage][]string{ @@ -4184,7 +4184,7 @@ func TestServer_DeleteLink(t *testing.T) { sessionRepository := repositories.NewSessionCached(cachex) revocationStatusResolver := revocation_status.NewRevocationStatusResolver(cfg.CredentialStatus) rhsFactory := reverse_hash.NewFactory(cfg.CredentialStatus.RHS.URL, nil, commonEth.HexToAddress(cfg.CredentialStatus.OnchainTreeStore.SupportedTreeStoreContract), reverse_hash.DefaultRHSTimeOut) - identityService := services.NewIdentity(keyStore, identityRepo, mtRepo, identityStateRepo, mtService, nil, claimsRepo, revocationRepository, connectionsRepository, storage, nil, nil, pubsub.NewMock(), cfg.CredentialStatus, rhsFactory, revocationStatusResolver, *cfg.AutoPublishingToOnChainRHS) + identityService := services.NewIdentity(keyStore, identityRepo, mtRepo, identityStateRepo, mtService, nil, claimsRepo, revocationRepository, connectionsRepository, storage, nil, nil, pubsub.NewMock(), cfg.CredentialStatus, rhsFactory, revocationStatusResolver) mediaTypeManager := services.NewMediaTypeManager( map[iden3comm.ProtocolMessage][]string{ @@ -4308,7 +4308,7 @@ func TestServer_DeleteLinkForDifferentDID(t *testing.T) { sessionRepository := repositories.NewSessionCached(cachex) revocationStatusResolver := revocation_status.NewRevocationStatusResolver(cfg.CredentialStatus) rhsFactory := reverse_hash.NewFactory(cfg.CredentialStatus.RHS.URL, nil, commonEth.HexToAddress(cfg.CredentialStatus.OnchainTreeStore.SupportedTreeStoreContract), reverse_hash.DefaultRHSTimeOut) - identityService := services.NewIdentity(keyStore, identityRepo, mtRepo, identityStateRepo, mtService, nil, claimsRepo, revocationRepository, connectionsRepository, storage, nil, nil, pubsub.NewMock(), cfg.CredentialStatus, rhsFactory, revocationStatusResolver, *cfg.AutoPublishingToOnChainRHS) + identityService := services.NewIdentity(keyStore, identityRepo, mtRepo, identityStateRepo, mtService, nil, claimsRepo, revocationRepository, connectionsRepository, storage, nil, nil, pubsub.NewMock(), cfg.CredentialStatus, rhsFactory, revocationStatusResolver) mediaTypeManager := services.NewMediaTypeManager( map[iden3comm.ProtocolMessage][]string{ @@ -4430,7 +4430,7 @@ func TestServer_CreateLinkQRCode(t *testing.T) { sessionRepository := repositories.NewSessionCached(cachex) revocationStatusResolver := revocation_status.NewRevocationStatusResolver(cfg.CredentialStatus) rhsFactory := reverse_hash.NewFactory(cfg.CredentialStatus.RHS.URL, nil, commonEth.HexToAddress(cfg.CredentialStatus.OnchainTreeStore.SupportedTreeStoreContract), reverse_hash.DefaultRHSTimeOut) - identityService := services.NewIdentity(keyStore, identityRepo, mtRepo, identityStateRepo, mtService, qrService, claimsRepo, revocationRepository, connectionsRepository, storage, nil, nil, pubsub.NewMock(), cfg.CredentialStatus, rhsFactory, revocationStatusResolver, *cfg.AutoPublishingToOnChainRHS) + identityService := services.NewIdentity(keyStore, identityRepo, mtRepo, identityStateRepo, mtService, qrService, claimsRepo, revocationRepository, connectionsRepository, storage, nil, nil, pubsub.NewMock(), cfg.CredentialStatus, rhsFactory, revocationStatusResolver) mediaTypeManager := services.NewMediaTypeManager( map[iden3comm.ProtocolMessage][]string{ @@ -4592,7 +4592,7 @@ func TestServer_GetLinkQRCode(t *testing.T) { revocationStatusResolver := revocation_status.NewRevocationStatusResolver(cfg.CredentialStatus) rhsFactory := reverse_hash.NewFactory(cfg.CredentialStatus.RHS.URL, nil, commonEth.HexToAddress(cfg.CredentialStatus.OnchainTreeStore.SupportedTreeStoreContract), reverse_hash.DefaultRHSTimeOut) qrService := services.NewQrStoreService(cachex) - identityService := services.NewIdentity(keyStore, identityRepo, mtRepo, identityStateRepo, mtService, qrService, claimsRepo, revocationRepository, connectionsRepository, storage, nil, nil, pubsub.NewMock(), cfg.CredentialStatus, rhsFactory, revocationStatusResolver, *cfg.AutoPublishingToOnChainRHS) + identityService := services.NewIdentity(keyStore, identityRepo, mtRepo, identityStateRepo, mtService, qrService, claimsRepo, revocationRepository, connectionsRepository, storage, nil, nil, pubsub.NewMock(), cfg.CredentialStatus, rhsFactory, revocationStatusResolver) mediaTypeManager := services.NewMediaTypeManager( map[iden3comm.ProtocolMessage][]string{ @@ -4782,7 +4782,7 @@ func TestServer_GetStateStatus(t *testing.T) { connectionsRepository := repositories.NewConnections() revocationStatusResolver := revocation_status.NewRevocationStatusResolver(cfg.CredentialStatus) rhsFactory := reverse_hash.NewFactory(cfg.CredentialStatus.RHS.URL, nil, commonEth.HexToAddress(cfg.CredentialStatus.OnchainTreeStore.SupportedTreeStoreContract), reverse_hash.DefaultRHSTimeOut) - identityService := services.NewIdentity(keyStore, identityRepo, mtRepo, identityStateRepo, mtService, nil, claimsRepo, revocationRepository, connectionsRepository, storage, nil, nil, pubsub.NewMock(), cfg.CredentialStatus, rhsFactory, revocationStatusResolver, *cfg.AutoPublishingToOnChainRHS) + identityService := services.NewIdentity(keyStore, identityRepo, mtRepo, identityStateRepo, mtService, nil, claimsRepo, revocationRepository, connectionsRepository, storage, nil, nil, pubsub.NewMock(), cfg.CredentialStatus, rhsFactory, revocationStatusResolver) mediaTypeManager := services.NewMediaTypeManager( map[iden3comm.ProtocolMessage][]string{ @@ -4940,7 +4940,7 @@ func TestServer_GetStateTransactions(t *testing.T) { connectionsRepository := repositories.NewConnections() revocationStatusResolver := revocation_status.NewRevocationStatusResolver(cfg.CredentialStatus) rhsFactory := reverse_hash.NewFactory(cfg.CredentialStatus.RHS.URL, nil, commonEth.HexToAddress(cfg.CredentialStatus.OnchainTreeStore.SupportedTreeStoreContract), reverse_hash.DefaultRHSTimeOut) - identityService := services.NewIdentity(keyStore, identityRepo, mtRepo, identityStateRepo, mtService, nil, claimsRepo, revocationRepository, connectionsRepository, storage, nil, nil, pubsub.NewMock(), cfg.CredentialStatus, rhsFactory, revocationStatusResolver, *cfg.AutoPublishingToOnChainRHS) + identityService := services.NewIdentity(keyStore, identityRepo, mtRepo, identityStateRepo, mtService, nil, claimsRepo, revocationRepository, connectionsRepository, storage, nil, nil, pubsub.NewMock(), cfg.CredentialStatus, rhsFactory, revocationStatusResolver) mediaTypeManager := services.NewMediaTypeManager( map[iden3comm.ProtocolMessage][]string{ @@ -5035,7 +5035,7 @@ func TestServer_GetRevocationStatus(t *testing.T) { connectionsRepository := repositories.NewConnections() revocationStatusResolver := revocation_status.NewRevocationStatusResolver(cfg.CredentialStatus) rhsFactory := reverse_hash.NewFactory(cfg.CredentialStatus.RHS.URL, nil, commonEth.HexToAddress(cfg.CredentialStatus.OnchainTreeStore.SupportedTreeStoreContract), reverse_hash.DefaultRHSTimeOut) - identityService := services.NewIdentity(keyStore, identityRepo, mtRepo, identityStateRepo, mtService, nil, claimsRepo, revocationRepository, connectionsRepository, storage, nil, nil, pubsub.NewMock(), cfg.CredentialStatus, rhsFactory, revocationStatusResolver, *cfg.AutoPublishingToOnChainRHS) + identityService := services.NewIdentity(keyStore, identityRepo, mtRepo, identityStateRepo, mtService, nil, claimsRepo, revocationRepository, connectionsRepository, storage, nil, nil, pubsub.NewMock(), cfg.CredentialStatus, rhsFactory, revocationStatusResolver) pubSub := pubsub.NewMock() mediaTypeManager := services.NewMediaTypeManager( diff --git a/internal/config/config.go b/internal/config/config.go index 700f73bfb..f4945c844 100644 --- a/internal/config/config.go +++ b/internal/config/config.go @@ -50,7 +50,6 @@ type Configuration struct { VaultUserPassAuthPassword string CredentialStatus CredentialStatus `mapstructure:"CredentialStatus"` CustomDIDMethods []CustomDIDMethods `mapstructure:"-"` - AutoPublishingToOnChainRHS *bool `mapstructure:"AutoPublishingToOnChainRHS"` MediaTypeManager MediaTypeManager `mapstructure:"MediaTypeManager"` } @@ -514,8 +513,6 @@ func bindEnv() { _ = viper.BindEnv("ISSUER_CUSTOM_DID_METHODS") - _ = viper.BindEnv("AutoPublishingToOnChainRHS", "ISSUER_AUTO_PUBLISHING_TO_ON_CHAIN_RHS") - _ = viper.BindEnv("MediaTypeManager.Enabled", "ISSUER_MEDIA_TYPE_MANAGER_ENABLED") viper.AutomaticEnv() @@ -637,11 +634,6 @@ func checkEnvVars(ctx context.Context, cfg *Configuration) { cfg.SchemaCache = common.ToPointer(false) } - if cfg.AutoPublishingToOnChainRHS == nil { - log.Info(ctx, "AutoPublishingToOnChainRHS is missing and the server set up it as true") - cfg.AutoPublishingToOnChainRHS = common.ToPointer(true) - } - if cfg.MediaTypeManager.Enabled == nil { log.Info(ctx, "ISSUER_MEDIA_TYPE_MANAGER_ENABLED is missing and the server set up it as true") cfg.MediaTypeManager.Enabled = common.ToPointer(true) diff --git a/internal/core/services/identity.go b/internal/core/services/identity.go index bbfde530d..ced8c10d5 100644 --- a/internal/core/services/identity.go +++ b/internal/core/services/identity.go @@ -73,36 +73,34 @@ type identity struct { kms kms.KMSType verifier *auth.Verifier - ignoreRHSErrors bool - pubsub pubsub.Publisher - revocationStatusResolver *revocation_status.RevocationStatusResolver - credentialStatusSettings config.CredentialStatus - rhsFactory reverse_hash.Factory - autoPublishingToOnChainRHS bool + ignoreRHSErrors bool + pubsub pubsub.Publisher + revocationStatusResolver *revocation_status.RevocationStatusResolver + credentialStatusSettings config.CredentialStatus + rhsFactory reverse_hash.Factory } // NewIdentity creates a new identity // nolint -func NewIdentity(kms kms.KMSType, identityRepository ports.IndentityRepository, imtRepository ports.IdentityMerkleTreeRepository, identityStateRepository ports.IdentityStateRepository, mtservice ports.MtService, qrService ports.QrStoreService, claimsRepository ports.ClaimsRepository, revocationRepository ports.RevocationRepository, connectionsRepository ports.ConnectionsRepository, storage *db.Storage, verifier *auth.Verifier, sessionRepository ports.SessionRepository, ps pubsub.Client, credentialStatusSettings config.CredentialStatus, rhsFactory reverse_hash.Factory, revocationStatusResolver *revocation_status.RevocationStatusResolver, autoPublishingToOnChainRHS bool) ports.IdentityService { +func NewIdentity(kms kms.KMSType, identityRepository ports.IndentityRepository, imtRepository ports.IdentityMerkleTreeRepository, identityStateRepository ports.IdentityStateRepository, mtservice ports.MtService, qrService ports.QrStoreService, claimsRepository ports.ClaimsRepository, revocationRepository ports.RevocationRepository, connectionsRepository ports.ConnectionsRepository, storage *db.Storage, verifier *auth.Verifier, sessionRepository ports.SessionRepository, ps pubsub.Client, credentialStatusSettings config.CredentialStatus, rhsFactory reverse_hash.Factory, revocationStatusResolver *revocation_status.RevocationStatusResolver) ports.IdentityService { return &identity{ - identityRepository: identityRepository, - imtRepository: imtRepository, - identityStateRepository: identityStateRepository, - claimsRepository: claimsRepository, - revocationRepository: revocationRepository, - connectionsRepository: connectionsRepository, - sessionManager: sessionRepository, - storage: storage, - mtService: mtservice, - qrService: qrService, - kms: kms, - ignoreRHSErrors: false, - verifier: verifier, - pubsub: ps, - credentialStatusSettings: credentialStatusSettings, - rhsFactory: rhsFactory, - revocationStatusResolver: revocationStatusResolver, - autoPublishingToOnChainRHS: autoPublishingToOnChainRHS, + identityRepository: identityRepository, + imtRepository: imtRepository, + identityStateRepository: identityStateRepository, + claimsRepository: claimsRepository, + revocationRepository: revocationRepository, + connectionsRepository: connectionsRepository, + sessionManager: sessionRepository, + storage: storage, + mtService: mtservice, + qrService: qrService, + kms: kms, + ignoreRHSErrors: false, + verifier: verifier, + pubsub: ps, + credentialStatusSettings: credentialStatusSettings, + rhsFactory: rhsFactory, + revocationStatusResolver: revocationStatusResolver, } } @@ -749,7 +747,7 @@ func (i *identity) createIdentity(ctx context.Context, tx db.Querier, hostURL st return nil, nil, fmt.Errorf("can't create RHS publisher: %w", err) } - if len(rhsPublishers) > 0 && !(rhsMode == reverse_hash.RHSModeOnChain && !i.autoPublishingToOnChainRHS) { + if len(rhsPublishers) > 0 { log.Info(ctx, "publishing state to RHS", "publishers", len(rhsPublishers)) for _, rhsPublisher := range rhsPublishers { err := rhsPublisher.PublishNodesToRHS(ctx, []mtproof.Node{ diff --git a/internal/core/services/tests/identity_test.go b/internal/core/services/tests/identity_test.go index 011f3f0ec..598aa7e08 100644 --- a/internal/core/services/tests/identity_test.go +++ b/internal/core/services/tests/identity_test.go @@ -43,7 +43,7 @@ func Test_identity_UpdateState(t *testing.T) { connectionsRepository := repositories.NewConnections() rhsFactory := reverse_hash.NewFactory(cfg.CredentialStatus.RHS.URL, nil, commonEth.HexToAddress(cfg.CredentialStatus.OnchainTreeStore.SupportedTreeStoreContract), reverse_hash.DefaultRHSTimeOut) revocationStatusResolver := revocation_status.NewRevocationStatusResolver(cfg.CredentialStatus) - identityService := services.NewIdentity(keyStore, identityRepo, mtRepo, identityStateRepo, mtService, nil, claimsRepo, revocationRepository, connectionsRepository, storage, nil, nil, pubsub.NewMock(), cfg.CredentialStatus, rhsFactory, revocationStatusResolver, *cfg.AutoPublishingToOnChainRHS) + identityService := services.NewIdentity(keyStore, identityRepo, mtRepo, identityStateRepo, mtService, nil, claimsRepo, revocationRepository, connectionsRepository, storage, nil, nil, pubsub.NewMock(), cfg.CredentialStatus, rhsFactory, revocationStatusResolver) mediaTypeManager := services.NewMediaTypeManager( map[iden3comm.ProtocolMessage][]string{ @@ -231,7 +231,7 @@ func Test_identity_GetByDID(t *testing.T) { connectionsRepository := repositories.NewConnections() rhsFactory := reverse_hash.NewFactory(cfg.CredentialStatus.RHS.URL, nil, commonEth.HexToAddress(cfg.CredentialStatus.OnchainTreeStore.SupportedTreeStoreContract), reverse_hash.DefaultRHSTimeOut) revocationStatusResolver := revocation_status.NewRevocationStatusResolver(cfg.CredentialStatus) - identityService := services.NewIdentity(keyStore, identityRepo, mtRepo, identityStateRepo, mtService, nil, claimsRepo, revocationRepository, connectionsRepository, storage, nil, nil, pubsub.NewMock(), cfg.CredentialStatus, rhsFactory, revocationStatusResolver, *cfg.AutoPublishingToOnChainRHS) + identityService := services.NewIdentity(keyStore, identityRepo, mtRepo, identityStateRepo, mtService, nil, claimsRepo, revocationRepository, connectionsRepository, storage, nil, nil, pubsub.NewMock(), cfg.CredentialStatus, rhsFactory, revocationStatusResolver) identity, err := identityService.Create(ctx, "polygon-test", &ports.DIDCreationOptions{Method: method, Blockchain: blockchain, Network: network, KeyType: BJJ}) assert.NoError(t, err) diff --git a/internal/core/services/tests/link_test.go b/internal/core/services/tests/link_test.go index 3a7c5adb8..be3c8b606 100644 --- a/internal/core/services/tests/link_test.go +++ b/internal/core/services/tests/link_test.go @@ -39,7 +39,7 @@ func Test_link_issueClaim(t *testing.T) { connectionsRepository := repositories.NewConnections() rhsFactory := reverse_hash.NewFactory(cfg.CredentialStatus.RHS.URL, nil, commonEth.HexToAddress(cfg.CredentialStatus.OnchainTreeStore.SupportedTreeStoreContract), reverse_hash.DefaultRHSTimeOut) revocationStatusResolver := revocation_status.NewRevocationStatusResolver(cfg.CredentialStatus) - identityService := services.NewIdentity(keyStore, identityRepo, mtRepo, identityStateRepo, mtService, nil, claimsRepo, revocationRepository, connectionsRepository, storage, nil, nil, pubsub.NewMock(), cfg.CredentialStatus, rhsFactory, revocationStatusResolver, *cfg.AutoPublishingToOnChainRHS) + identityService := services.NewIdentity(keyStore, identityRepo, mtRepo, identityStateRepo, mtService, nil, claimsRepo, revocationRepository, connectionsRepository, storage, nil, nil, pubsub.NewMock(), cfg.CredentialStatus, rhsFactory, revocationStatusResolver) sessionRepository := repositories.NewSessionCached(cachex) schemaService := services.NewSchema(schemaRepository, docLoader) diff --git a/internal/core/services/tests/main_test.go b/internal/core/services/tests/main_test.go index 3e9be27c7..a0bac0440 100644 --- a/internal/core/services/tests/main_test.go +++ b/internal/core/services/tests/main_test.go @@ -7,7 +7,6 @@ import ( "github.com/hashicorp/vault/api" - "github.com/polygonid/sh-id-platform/internal/common" "github.com/polygonid/sh-id-platform/internal/config" "github.com/polygonid/sh-id-platform/internal/db" "github.com/polygonid/sh-id-platform/internal/db/tests" @@ -93,7 +92,6 @@ func TestMain(m *testing.M) { docLoader = loader.NewDocumentLoader(ipfsGatewayURL) - cfg.AutoPublishingToOnChainRHS = common.ToPointer[bool](true) cfg.CredentialStatus = config.CredentialStatus{ RHSMode: "None", Iden3CommAgentStatus: config.Iden3CommAgentStatus{ diff --git a/internal/core/services/tests/notification_test.go b/internal/core/services/tests/notification_test.go index a128c4459..4e221ddce 100644 --- a/internal/core/services/tests/notification_test.go +++ b/internal/core/services/tests/notification_test.go @@ -43,7 +43,7 @@ func TestNotification_SendNotification(t *testing.T) { connectionsRepository := repositories.NewConnections() rhsFactory := reverse_hash.NewFactory(cfg.CredentialStatus.RHS.URL, nil, commonEth.HexToAddress(cfg.CredentialStatus.OnchainTreeStore.SupportedTreeStoreContract), reverse_hash.DefaultRHSTimeOut) revocationStatusResolver := revocation_status.NewRevocationStatusResolver(cfg.CredentialStatus) - identityService := services.NewIdentity(keyStore, identityRepo, mtRepo, identityStateRepo, mtService, nil, claimsRepo, revocationRepository, connectionsRepository, storage, nil, nil, pubsub.NewMock(), cfg.CredentialStatus, rhsFactory, revocationStatusResolver, *cfg.AutoPublishingToOnChainRHS) + identityService := services.NewIdentity(keyStore, identityRepo, mtRepo, identityStateRepo, mtService, nil, claimsRepo, revocationRepository, connectionsRepository, storage, nil, nil, pubsub.NewMock(), cfg.CredentialStatus, rhsFactory, revocationStatusResolver) mediaTypeManager := services.NewMediaTypeManager( map[iden3comm.ProtocolMessage][]string{ From 20e73f10821f797e0f232de4f03e441d7f992a73 Mon Sep 17 00:00:00 2001 From: vbasiuk Date: Fri, 21 Jun 2024 11:25:22 +0300 Subject: [PATCH 34/52] update packages --- go.mod | 14 +++++++------- go.sum | 28 ++++++++++++++-------------- 2 files changed, 21 insertions(+), 21 deletions(-) diff --git a/go.mod b/go.mod index afa5c4e17..e60c35bd0 100644 --- a/go.mod +++ b/go.mod @@ -18,11 +18,11 @@ require ( github.com/hashicorp/vault/api/auth/userpass v0.5.0 github.com/iden3/contracts-abi/onchain-credential-status-resolver/go/abi v0.0.0-20231116131043-966af42c9b58 github.com/iden3/contracts-abi/state/go/abi v1.0.2-0.20231006071010-f511d08ca36f - github.com/iden3/go-circuits/v2 v2.2.0 - github.com/iden3/go-iden3-auth/v2 v2.2.2 - github.com/iden3/go-iden3-core/v2 v2.1.0 + github.com/iden3/go-circuits/v2 v2.3.0 + github.com/iden3/go-iden3-auth/v2 v2.4.1 + github.com/iden3/go-iden3-core/v2 v2.2.0 github.com/iden3/go-iden3-crypto v0.0.16 - github.com/iden3/go-jwz/v2 v2.0.2 + github.com/iden3/go-jwz/v2 v2.1.1 github.com/iden3/go-merkletree-sql/db/pgx/v2 v2.0.5 github.com/iden3/go-merkletree-sql/v2 v2.0.6 github.com/iden3/go-rapidsnark/prover v0.0.10 @@ -30,9 +30,9 @@ require ( github.com/iden3/go-rapidsnark/witness/v2 v2.0.0 github.com/iden3/go-rapidsnark/witness/wazero v0.0.0-20230524142950-0986cf057d4e github.com/iden3/go-schema-processor v1.3.1 - github.com/iden3/go-schema-processor/v2 v2.3.3 - github.com/iden3/iden3comm/v2 v2.3.2 - github.com/iden3/merkletree-proof v0.0.4 + github.com/iden3/go-schema-processor/v2 v2.4.0 + github.com/iden3/iden3comm/v2 v2.5.1 + github.com/iden3/merkletree-proof v0.2.0 github.com/ipfs/go-ipfs-api v0.7.0 github.com/jackc/pgconn v1.14.1 github.com/jackc/pgtype v1.14.0 diff --git a/go.sum b/go.sum index 90c706b38..bf47f8ef7 100644 --- a/go.sum +++ b/go.sum @@ -529,18 +529,18 @@ github.com/iden3/contracts-abi/rhs-storage/go/abi v0.0.0-20231006141557-7d13ef7e github.com/iden3/contracts-abi/rhs-storage/go/abi v0.0.0-20231006141557-7d13ef7e3c48/go.mod h1:kJmVPMk4HfWyl2kcta34aad/K4TAfCwB29xX9PsR7LQ= github.com/iden3/contracts-abi/state/go/abi v1.0.2-0.20231006071010-f511d08ca36f h1:aTYEBIh802oWF6B3jhXf5F7UVGxfPJG70shYkRXzb+s= github.com/iden3/contracts-abi/state/go/abi v1.0.2-0.20231006071010-f511d08ca36f/go.mod h1:TxgIrXCvxms3sbOdsy8kTvffUCIpEEifNy0fSXdkU4w= -github.com/iden3/go-circuits/v2 v2.2.0 h1:qJeySVPG9vxZwJyL/CsvXdUhccWOctXQUYGnyX5p2Kc= -github.com/iden3/go-circuits/v2 v2.2.0/go.mod h1:1LET+T8i9Rkfx+RNj2BBHKAPGDODEWWwSEFjR6g3h6c= -github.com/iden3/go-iden3-auth/v2 v2.2.2 h1:4uA+m5H2OvhfOsMJaeXaCjciV2sHypvHgGHewZfXB58= -github.com/iden3/go-iden3-auth/v2 v2.2.2/go.mod h1:1ytFvnSnuNK2m9BoVrgYJoLNH919Bg2pt68pFelcJcM= +github.com/iden3/go-circuits/v2 v2.3.0 h1:xzDVuq4JkTgtz+AjatquuPgGVbOxRpcWMhUOcWEZJN4= +github.com/iden3/go-circuits/v2 v2.3.0/go.mod h1:APhXQaRQr4txd+u0Y7liBjN/Wnox0d31wR40LkXywAE= +github.com/iden3/go-iden3-auth/v2 v2.4.1 h1:hJxoTKsaxDxyN2hMWE2smSJkWXI0T+mIySjl4o4QPYc= +github.com/iden3/go-iden3-auth/v2 v2.4.1/go.mod h1:YFqVZ2s8oPyx64UI/rBRqeziQu86rH7OJ5RGAPZrdY0= github.com/iden3/go-iden3-core v1.0.2 h1:HwNDFeqcUv4ybZj5tH+58JKWKarn/qqBpNCqTLxGP0Y= github.com/iden3/go-iden3-core v1.0.2/go.mod h1:X4PjlJG8OsEQEsSbzzYqqAk2olYGZ2nuGqiUPyEYjOo= -github.com/iden3/go-iden3-core/v2 v2.1.0 h1:R1s7Tj3tIx5lDy8S7OJrSNuxXIFeRzWRmTBaQoQHJps= -github.com/iden3/go-iden3-core/v2 v2.1.0/go.mod h1:L9PxhWPvoS9qTb3inEkZBm1RpjHBt+VTwvxssdzbAdw= +github.com/iden3/go-iden3-core/v2 v2.2.0 h1:PcMSxJRLAoJausj1gKstzgt25HS18K+IHLaSPeI9p8Q= +github.com/iden3/go-iden3-core/v2 v2.2.0/go.mod h1:L9PxhWPvoS9qTb3inEkZBm1RpjHBt+VTwvxssdzbAdw= github.com/iden3/go-iden3-crypto v0.0.16 h1:zN867xiz6HgErXVIV/6WyteGcOukE9gybYTorBMEdsk= github.com/iden3/go-iden3-crypto v0.0.16/go.mod h1:dLpM4vEPJ3nDHzhWFXDjzkn1qHoBeOT/3UEhXsEsP3E= -github.com/iden3/go-jwz/v2 v2.0.2 h1:yx56x1TZcObeuj6cvX715Jd7QTxnCpHwbETKWCPJmhw= -github.com/iden3/go-jwz/v2 v2.0.2/go.mod h1:B1r6wJpPhIiuZTmgicNoogr7XD/VS3jZu9U519GwWz4= +github.com/iden3/go-jwz/v2 v2.1.1 h1:6274wip59HAi9GkKewG0kKj/WBJeT6T4B+IotQM8IrY= +github.com/iden3/go-jwz/v2 v2.1.1/go.mod h1:1mEhNrtAO4eACWZeg9k6T0CxadN4XUkj/dfWUBk3exE= github.com/iden3/go-merkletree-sql/db/pgx/v2 v2.0.5 h1:CKry110riXxBu1bM9vhdPia37tlbqoKYg0s0dwGA4l4= github.com/iden3/go-merkletree-sql/db/pgx/v2 v2.0.5/go.mod h1:J17cXiT4pBP/c5FWN4nv0J7q2yT9I8JSzUfdIKyZIj4= github.com/iden3/go-merkletree-sql/v2 v2.0.6 h1:vsVDImnvnHf7Ggr45ptFOXJyWNA/8IwVQO1jzRLUlY8= @@ -557,12 +557,12 @@ github.com/iden3/go-rapidsnark/witness/wazero v0.0.0-20230524142950-0986cf057d4e github.com/iden3/go-rapidsnark/witness/wazero v0.0.0-20230524142950-0986cf057d4e/go.mod h1:UEBifEzw62T6VzIHJeHuUgeLg2U/J9ttf7hOwQEqnYk= github.com/iden3/go-schema-processor v1.3.1 h1:LJfFInfYGMOp0bTKKC17R8q4XI+VtqhFLPTEqnOIvlM= github.com/iden3/go-schema-processor v1.3.1/go.mod h1:NwJ1nuGdRlCFaN1/V6mS0AOAdvpLcGf4KKq0mluLG7U= -github.com/iden3/go-schema-processor/v2 v2.3.3 h1:GfChxMZHG4miA3p/5rLIrM7TGmKu/oAAXgLloYTBHSI= -github.com/iden3/go-schema-processor/v2 v2.3.3/go.mod h1:8y/R0iQpYhyhRQ3sL4F5Aja3+1T68M6uwGQdC4pQ4X0= -github.com/iden3/iden3comm/v2 v2.3.2 h1:ulD0oI/+qsEmnHVELWrxdLNvQOOWr/JLVMFXzEVbr5E= -github.com/iden3/iden3comm/v2 v2.3.2/go.mod h1:HVdSjre4og+kdJ5Cqe2b3Dt2ccOogOdfyWwKaUSAelw= -github.com/iden3/merkletree-proof v0.0.4 h1:o1XXws6zb7+BBDQYXlo0GPUH+jUY3+GxkT88U1C4Sb8= -github.com/iden3/merkletree-proof v0.0.4/go.mod h1:D49CVDG/tshMiZuDCxWjGJoNplRg9y9XIlg9/eMSYOc= +github.com/iden3/go-schema-processor/v2 v2.4.0 h1:SlyWHTBKeS6P7asDvGKA9R2nWxwqOdeMRirU3TnDLyM= +github.com/iden3/go-schema-processor/v2 v2.4.0/go.mod h1:eBtILnPjh4wnsAg3LWnvcZlGG+5IkAJaRqhVBnDjerg= +github.com/iden3/iden3comm/v2 v2.5.1 h1:Tp0jRa91r96fBREKOa7aXckusfrqyWfosTHJi+8g+nw= +github.com/iden3/iden3comm/v2 v2.5.1/go.mod h1:j9Vh4b2azIc7J7g0WzHV54z7MpYmq89KkvxsVyBkjIE= +github.com/iden3/merkletree-proof v0.2.0 h1:fU3n8RYN4jfvha+lItOU/A7V2el340N2fVEs5O2U4ek= +github.com/iden3/merkletree-proof v0.2.0/go.mod h1:If/NNihcdvx7RSvlOqR5yhM37/HT2IhzIKmYaN2GitM= github.com/imdario/mergo v0.3.16 h1:wwQJbIsHYGMUyLSPrEq1CT16AhnhNJQ51+4fdHUnCl4= github.com/imdario/mergo v0.3.16/go.mod h1:WBLT9ZmE3lPoWsEzCh9LPo3TiwVN+ZKEjmz+hD27ysY= github.com/inconshreveable/mousetrap v1.1.0 h1:wN+x4NVGpMsO7ErUn/mUI3vEoE6Jt13X2s0bqwp9tc8= From 13d28295844e247493823823486f5b155e180e90 Mon Sep 17 00:00:00 2001 From: vbasiuk Date: Fri, 21 Jun 2024 14:04:09 +0300 Subject: [PATCH 35/52] fix build --- go.mod | 2 +- go.sum | 2 ++ pkg/reverse_hash/factory.go | 2 +- 3 files changed, 4 insertions(+), 2 deletions(-) diff --git a/go.mod b/go.mod index e60c35bd0..e18ba404b 100644 --- a/go.mod +++ b/go.mod @@ -4,7 +4,7 @@ go 1.21 require ( github.com/alicebob/miniredis/v2 v2.31.1 - github.com/deepmap/oapi-codegen v1.16.2 + github.com/deepmap/oapi-codegen v1.16.3 github.com/ethereum/go-ethereum v1.13.14 github.com/getkin/kin-openapi v0.123.0 github.com/go-chi/chi/v5 v5.0.11 diff --git a/go.sum b/go.sum index bf47f8ef7..25b48716d 100644 --- a/go.sum +++ b/go.sum @@ -217,6 +217,8 @@ github.com/decred/dcrd/dcrec/secp256k1/v4 v4.3.0 h1:rpfIENRNNilwHwZeG5+P150SMrnN github.com/decred/dcrd/dcrec/secp256k1/v4 v4.3.0/go.mod h1:v57UDF4pDQJcEfFUCRop3lJL149eHGSe9Jvczhzjo/0= github.com/deepmap/oapi-codegen v1.16.2 h1:xGHx0dNqYfy9gE8a7AVgVM8Sd5oF9SEgePzP+UPAUXI= github.com/deepmap/oapi-codegen v1.16.2/go.mod h1:rdYoEA2GE+riuZ91DvpmBX9hJbQpuY9wchXpfQ3n+ho= +github.com/deepmap/oapi-codegen v1.16.3 h1:GT9G86SbQtT1r8ZB+4Cybi9VGdu1P5ieNvNdEoCSbrA= +github.com/deepmap/oapi-codegen v1.16.3/go.mod h1:JD6ErqeX0nYnhdciLc61Konj3NBASREMlkHOgHn8WAM= github.com/denis-tingaikin/go-header v0.4.3 h1:tEaZKAlqql6SKCY++utLmkPLd6K8IBM20Ha7UVm+mtU= github.com/denis-tingaikin/go-header v0.4.3/go.mod h1:0wOCWuN71D5qIgE2nz9KrKmuYBAC2Mra5RassOIQ2/c= github.com/dgryski/go-rendezvous v0.0.0-20200823014737-9f7001d12a5f h1:lO4WD4F/rVNCu3HqELle0jiPLLBs70cWOduZpkS1E78= diff --git a/pkg/reverse_hash/factory.go b/pkg/reverse_hash/factory.go index 1689ad7d5..a93c3cfb5 100644 --- a/pkg/reverse_hash/factory.go +++ b/pkg/reverse_hash/factory.go @@ -85,7 +85,7 @@ func (f *Factory) initOnChainRHSCli(ctx context.Context, kmsKey *kms.KeyID) (pro if err != nil { return nil, err } - cli, err := proofEth.NewReverseHashCli(f.onChainTreeStoreContract, f.ethClient.GetEthereumClient(), txOpts, f.responseTimeout) + cli, err := proofEth.NewReverseHashCli(f.ethClient.GetEthereumClient(), f.onChainTreeStoreContract, txOpts.From, txOpts.Signer) if err != nil { return nil, err } From a5943506eb89a9749b9da4e7b259e1ccd2c73496 Mon Sep 17 00:00:00 2001 From: Martin Saporiti Date: Fri, 21 Jun 2024 13:59:48 -0300 Subject: [PATCH 36/52] chore: add custom did methods --- k8s/helm/readme.md | 7 +++++-- k8s/helm/templates/_helpers.tpl | 6 ++++++ k8s/helm/templates/issuer-node-api-configmap.yaml | 2 ++ k8s/helm/templates/issuer-node-api-deployment.yaml | 2 +- k8s/helm/templates/issuer-node-api-ui-deployment.yaml | 2 +- k8s/helm/templates/issuer-node-notifications.yaml | 2 +- k8s/helm/templates/issuer-node-pending-publisher.yaml | 2 +- k8s/helm/templates/issuer-node-ui-deployment.yaml | 1 + k8s/helm/templates/postgres-deployment.yaml | 2 +- k8s/helm/templates/redis-deployment.yaml | 2 +- k8s/helm/templates/vault-deployment.yaml | 2 +- k8s/helm/values.yaml | 3 ++- 12 files changed, 23 insertions(+), 10 deletions(-) diff --git a/k8s/helm/readme.md b/k8s/helm/readme.md index ce69d44a6..357757143 100644 --- a/k8s/helm/readme.md +++ b/k8s/helm/readme.md @@ -39,6 +39,7 @@ export INGRESS_ENABLED=true # If this value is false export VAULT_PWD=password # Vault password. export RHS_MODE=None # Reverse Hash Service mode. Options: None, OnChain, OffChain export RHS_URL="https://reverse-hash-service.com" # Reverse Hash Service URL. Required if RHS_MODE is OffChain +export ISSUER_CUSTOM_DID_METHODS='[{"blockchain":"camino","network":"columbus","networkFlag":"0b10000011","chainID":501}]' # Custom DID methods ``` ## Install the helm chart with ingress and domain names @@ -59,7 +60,8 @@ helm install "$APP_INSTANCE_NAME" . \ --set privateKey="$PRIVATE_KEY" \ --set vaultpwd="$VAULT_PWD" \ --set rhsMode="$RHS_MODE" \ ---set rhsUrl="$RHS_URL" +--set rhsUrl="$RHS_URL" \ +--set issuerCustomDidMethods="$ISSUER_CUSTOM_DID_METHODS" ``` In the code above, the PUBLIC_IP is not provided because is not needed when the ingress is enabled. @@ -82,7 +84,8 @@ helm install "$APP_INSTANCE_NAME" . \ --set privateKey="$PRIVATE_KEY" \ --set vaultpwd="$VAULT_PWD" \ --set rhsMode="$RHS_MODE" \ ---set rhsUrl="$RHS_URL" +--set rhsUrl="$RHS_URL" \ +--set issuerCustomDidMethods="$ISSUER_CUSTOM_DID_METHODS" ``` In the code above, the publicIP is provided because is needed when the ingress is not enabled. In this case `$APP_DOMAIN`, `$UI_DOMAIN` and `$API_DOMAIN` are not used. diff --git a/k8s/helm/templates/_helpers.tpl b/k8s/helm/templates/_helpers.tpl index cd7201ba1..42d343528 100644 --- a/k8s/helm/templates/_helpers.tpl +++ b/k8s/helm/templates/_helpers.tpl @@ -278,3 +278,9 @@ Define custom service selectorLabels for vault {{- define "polygon-id-issuer.vaultIssuerNode.Labels" -}} app: {{ .Values.vaultIssuerNode.service.selector }} {{- end }} + + + +{{- define "helpers.serviceAccountName" -}} +{{- printf "%s-%s%s" .Release.Name .Release.Namespace "-service-account" -}} +{{- end -}} \ No newline at end of file diff --git a/k8s/helm/templates/issuer-node-api-configmap.yaml b/k8s/helm/templates/issuer-node-api-configmap.yaml index 1d3abf7bb..849aeb97e 100644 --- a/k8s/helm/templates/issuer-node-api-configmap.yaml +++ b/k8s/helm/templates/issuer-node-api-configmap.yaml @@ -48,6 +48,8 @@ data: ISSUER_CREDENTIAL_STATUS_RHS_CHAIN_ID : {{ include "helpers.api-rsh-chain-id" . | nindent 4 }} ISSUER_CREDENTIAL_STATUS_ONCHAIN_TREE_STORE_SUPPORTED_CONTRACT : {{ include "helpers.api-rsh-contract" . | nindent 4 }} ISSUER_IPFS_GATEWAY_URL : {{ .Values.apiIssuerNode.configMap.issuerIpfsGatewayUrl | quote }} + ISSUER_CUSTOM_DID_METHODS : {{ .Values.issuerCustomDidMethods | toJson | quote }} + \ No newline at end of file diff --git a/k8s/helm/templates/issuer-node-api-deployment.yaml b/k8s/helm/templates/issuer-node-api-deployment.yaml index e413ca47d..552a00be7 100644 --- a/k8s/helm/templates/issuer-node-api-deployment.yaml +++ b/k8s/helm/templates/issuer-node-api-deployment.yaml @@ -17,7 +17,7 @@ spec: {{- include "polygon-id-issuer.apiIssuerNode.Labels" . | nindent 8 }} {{- include "polygon-id-issuer.selectorLabels" . | nindent 8 }} spec: - serviceAccountName: issuer-node-service-account + serviceAccountName: {{ include "helpers.serviceAccountName" . }} containers: - name: {{ .Values.apiIssuerNode.deployment.containerName }} image: {{ .Values.issuernode_repository_image }}:{{ .Values.issuernode_repository_tag }} diff --git a/k8s/helm/templates/issuer-node-api-ui-deployment.yaml b/k8s/helm/templates/issuer-node-api-ui-deployment.yaml index f736d6feb..8f00bda58 100644 --- a/k8s/helm/templates/issuer-node-api-ui-deployment.yaml +++ b/k8s/helm/templates/issuer-node-api-ui-deployment.yaml @@ -17,7 +17,7 @@ spec: {{- include "polygon-id-issuer.apiUiIssuerNode.Labels" . | nindent 8 }} {{- include "polygon-id-issuer.selectorLabels" . | nindent 8 }} spec: - serviceAccountName: issuer-node-service-account + serviceAccountName: {{ include "helpers.serviceAccountName" . }} initContainers: - name: {{ .Values.apiUiIssuerNode.deployment.init.containerName }} image: {{ .Values.issuernode_repository_image }}:{{ .Values.issuernode_repository_tag }} diff --git a/k8s/helm/templates/issuer-node-notifications.yaml b/k8s/helm/templates/issuer-node-notifications.yaml index 71124c72a..0febae3a3 100644 --- a/k8s/helm/templates/issuer-node-notifications.yaml +++ b/k8s/helm/templates/issuer-node-notifications.yaml @@ -17,7 +17,7 @@ spec: {{- include "polygon-id-issuer.notificationsIssuerNode.Labels" . | nindent 8 }} {{- include "polygon-id-issuer.selectorLabels" . | nindent 8 }} spec: - serviceAccountName: issuer-node-service-account + serviceAccountName: {{ include "helpers.serviceAccountName" . }} containers: - name: {{ .Values.notificationsIssuerNode.deployment.containerName }} image: {{ .Values.issuernode_repository_image }}:{{ .Values.issuernode_repository_tag }} diff --git a/k8s/helm/templates/issuer-node-pending-publisher.yaml b/k8s/helm/templates/issuer-node-pending-publisher.yaml index 539202600..6ef63dae9 100644 --- a/k8s/helm/templates/issuer-node-pending-publisher.yaml +++ b/k8s/helm/templates/issuer-node-pending-publisher.yaml @@ -17,7 +17,7 @@ spec: {{- include "polygon-id-issuer.pendingPublisherIssuerNode.Labels" . | nindent 8 }} {{- include "polygon-id-issuer.selectorLabels" . | nindent 8 }} spec: - serviceAccountName: issuer-node-service-account + serviceAccountName: {{ include "helpers.serviceAccountName" . }} containers: - name: {{ .Values.pendingPublisherIssuerNode.deployment.containerName }} image: {{ .Values.issuernode_repository_image }}:{{ .Values.issuernode_repository_tag }} diff --git a/k8s/helm/templates/issuer-node-ui-deployment.yaml b/k8s/helm/templates/issuer-node-ui-deployment.yaml index 097e95b1d..fc6a0d162 100644 --- a/k8s/helm/templates/issuer-node-ui-deployment.yaml +++ b/k8s/helm/templates/issuer-node-ui-deployment.yaml @@ -17,6 +17,7 @@ spec: {{- include "polygon-id-issuer.uiIssuerNode.Labels" . | nindent 8 }} {{- include "polygon-id-issuer.selectorLabels" . | nindent 8 }} spec: + serviceAccountName: {{ include "helpers.serviceAccountName" . }} containers: - name: {{ .Values.uiIssuerNode.deployment.containerName }} image: {{ .Values.issuernode_ui_repository_image }}:{{ .Values.issuernode_ui_repository_tag }} diff --git a/k8s/helm/templates/postgres-deployment.yaml b/k8s/helm/templates/postgres-deployment.yaml index 0c20e79ca..7e6e423dd 100644 --- a/k8s/helm/templates/postgres-deployment.yaml +++ b/k8s/helm/templates/postgres-deployment.yaml @@ -17,7 +17,7 @@ spec: {{- include "polygon-id-issuer.postgresIssuerNode.Labels" . | nindent 8 }} {{- include "polygon-id-issuer.selectorLabels" . | nindent 8 }} spec: - serviceAccountName: issuer-node-service-account + serviceAccountName: {{ include "helpers.serviceAccountName" . }} containers: - name: {{ .Values.postgresIssuerNode.deployment.containerName }} image: {{ .Values.postgresIssuerNode.deployment.image.repository }}:{{ .Values.postgresIssuerNode.deployment.image.tag }} diff --git a/k8s/helm/templates/redis-deployment.yaml b/k8s/helm/templates/redis-deployment.yaml index d65bfbf11..370c3d905 100644 --- a/k8s/helm/templates/redis-deployment.yaml +++ b/k8s/helm/templates/redis-deployment.yaml @@ -17,7 +17,7 @@ spec: {{- include "polygon-id-issuer.redisIssuerNode.Labels" . | nindent 8 }} {{- include "polygon-id-issuer.selectorLabels" . | nindent 8 }} spec: - serviceAccountName: issuer-node-service-account + serviceAccountName: {{ include "helpers.serviceAccountName" . }} containers: - name: {{ .Values.redisIssuerNode.deployment.containerName }} image: {{ .Values.redisIssuerNode.deployment.image.repository }}:{{ .Values.redisIssuerNode.deployment.image.tag }} diff --git a/k8s/helm/templates/vault-deployment.yaml b/k8s/helm/templates/vault-deployment.yaml index 767ede10b..ffbf8306b 100644 --- a/k8s/helm/templates/vault-deployment.yaml +++ b/k8s/helm/templates/vault-deployment.yaml @@ -18,7 +18,7 @@ spec: {{- include "polygon-id-issuer.vaultIssuerNode.Labels" . | nindent 8 }} {{- include "polygon-id-issuer.selectorLabels" . | nindent 8 }} spec: - serviceAccountName: issuer-node-service-account + serviceAccountName: {{ include "helpers.serviceAccountName" . }} containers: - name: {{ .Values.vaultIssuerNode.deployment.containerName }} securityContext: diff --git a/k8s/helm/values.yaml b/k8s/helm/values.yaml index 0d261de1b..4d3146aa8 100644 --- a/k8s/helm/values.yaml +++ b/k8s/helm/values.yaml @@ -208,7 +208,7 @@ uiIssuerNode: issuerUiBlockExplorerUrlMain: https://polygonscan.com/ issuerUiIpfsGatewayUrl: https://ipfs.io issuerApiUiName: issuer-node-ui-configmap - issuerUiSchemaExplorerAndBuilderUrl: https://schema-builder.polygonid.me + issuerUiSchemaExplorerAndBuilderUrl: https://tools.privado.id postgresIssuerNode: deployment: @@ -475,3 +475,4 @@ issuerKeyType: BJJ rhsMode: None rhsUrl: nil +issuerCustomDidMethods: "" From 63443c60bb815d0691e7a9f369a8f4d1dacd21e4 Mon Sep 17 00:00:00 2001 From: Martin Saporiti Date: Mon, 24 Jun 2024 08:35:18 -0300 Subject: [PATCH 37/52] chore: add helm ui insecure option --- infrastructure/local/docker-compose-infra.yml | 2 +- k8s/helm/readme.md | 4 +++- k8s/helm/templates/issuer-node-ui-configmap.yaml | 3 ++- k8s/helm/values.yaml | 1 + 4 files changed, 7 insertions(+), 3 deletions(-) diff --git a/infrastructure/local/docker-compose-infra.yml b/infrastructure/local/docker-compose-infra.yml index d5950f0f3..f3c085e6c 100644 --- a/infrastructure/local/docker-compose-infra.yml +++ b/infrastructure/local/docker-compose-infra.yml @@ -76,7 +76,7 @@ services: "--spider", "--proxy", "off", - "http://localhost:8200/v1/sys/health?standbyok=true", + "http://vault:8200/v1/sys/health?standbyok=true", ] interval: 10s timeout: 3s diff --git a/k8s/helm/readme.md b/k8s/helm/readme.md index 357757143..90ea0a4ef 100644 --- a/k8s/helm/readme.md +++ b/k8s/helm/readme.md @@ -33,6 +33,7 @@ export PRIVATE_KEY='YOUR PRIVATE KEY' # Private key of the wal export PUBLIC_IP='YOUR PUBLIC IP' # Provide the PUBLIC IP if you have any otherwise leave this field. export MAINNET=false # Specify if the network is main, if this value is false issuer node will use amoy export UIPASSWORD="my ui password" # Password for user: ui-user. This password is used when the user visit the ui. +export UI_INSECURE=true # Set as true if the ui doesn't require basic auth. If this value true UIPASSWORD can be blank export ISSUERNAME="My Issuer" # Issuer Name. This value is shown in the UI export ISSUER_ETHERUM_URL="https://polygon-amoy.XXXX" # Blockchain RPC. export INGRESS_ENABLED=true # If this value is false you must provide a STATIC_IP @@ -61,7 +62,8 @@ helm install "$APP_INSTANCE_NAME" . \ --set vaultpwd="$VAULT_PWD" \ --set rhsMode="$RHS_MODE" \ --set rhsUrl="$RHS_URL" \ ---set issuerCustomDidMethods="$ISSUER_CUSTOM_DID_METHODS" +--set-json issuerCustomDidMethods="$ISSUER_CUSTOM_DID_METHODS" \ +--set issuerUiInsecure=$UI_INSECURE ``` In the code above, the PUBLIC_IP is not provided because is not needed when the ingress is enabled. diff --git a/k8s/helm/templates/issuer-node-ui-configmap.yaml b/k8s/helm/templates/issuer-node-ui-configmap.yaml index b201df838..5a71be8a9 100644 --- a/k8s/helm/templates/issuer-node-ui-configmap.yaml +++ b/k8s/helm/templates/issuer-node-ui-configmap.yaml @@ -14,4 +14,5 @@ data: ISSUER_API_UI_AUTH_PASSWORD: {{ .Values.uiIssuerNode.configMap.issuerApiUiAuthPassword }} ISSUER_API_UI_ISSUER_NAME: {{ .Values.issuerName }} ISSUER_UI_IPFS_GATEWAY_URL: {{ .Values.uiIssuerNode.configMap.issuerUiIpfsGatewayUrl }} - ISSUER_UI_SCHEMA_EXPLORER_AND_BUILDER_URL: {{ .Values.uiIssuerNode.configMap.issuerUiSchemaExplorerAndBuilderUrl }} \ No newline at end of file + ISSUER_UI_SCHEMA_EXPLORER_AND_BUILDER_URL: {{ .Values.uiIssuerNode.configMap.issuerUiSchemaExplorerAndBuilderUrl }} + ISSUER_UI_INSECURE: {{ .Values.issuerUiInsecure | quote }} \ No newline at end of file diff --git a/k8s/helm/values.yaml b/k8s/helm/values.yaml index 4d3146aa8..56ef21c1a 100644 --- a/k8s/helm/values.yaml +++ b/k8s/helm/values.yaml @@ -464,6 +464,7 @@ issuerEthereumUrl: https://polygon-amoy.g.alchemy.com/v2/ mainnet: false publicIP: nil uiPassword: password +issuerUiInsecure: false issuerName: "My Issuer!" ingressEnabled: false privateKey: metamask private key From f9e6bb07f8714075eda10fe78d84785d59e5b0b7 Mon Sep 17 00:00:00 2001 From: x1m3 Date: Tue, 25 Jun 2024 16:55:22 +0200 Subject: [PATCH 38/52] chore: update openapi-codegen library --- Makefile | 3 +-- api/api.yaml | 2 +- api_ui/api.yaml | 2 +- go.mod | 14 +++++++------- go.sum | 31 ++++++++++++++----------------- internal/api/api.gen.go | 2 +- internal/api_ui/api.gen.go | 6 +++--- tools.go | 2 +- 8 files changed, 29 insertions(+), 33 deletions(-) diff --git a/Makefile b/Makefile index 16125dbe7..f9b2dbb7e 100644 --- a/Makefile +++ b/Makefile @@ -46,8 +46,7 @@ test-race: $(GO) test -v --race ./... $(BIN)/oapi-codegen: tools.go go.mod go.sum ## install code generator for API files. - go get github.com/deepmap/oapi-codegen/cmd/oapi-codegen - $(GO) install github.com/deepmap/oapi-codegen/v2/cmd/oapi-codegen + $(GO) install github.com/oapi-codegen/oapi-codegen/v2/cmd/oapi-codegen@latest .PHONY: api api: $(BIN)/oapi-codegen diff --git a/api/api.yaml b/api/api.yaml index 46c93a13a..63ff59321 100644 --- a/api/api.yaml +++ b/api/api.yaml @@ -1,4 +1,4 @@ -openapi: 3.1.0 +openapi: 3.0.0 info: title: Polygon ID - Issuer description: | diff --git a/api_ui/api.yaml b/api_ui/api.yaml index 2ebe3b36d..da98abf34 100644 --- a/api_ui/api.yaml +++ b/api_ui/api.yaml @@ -1,4 +1,4 @@ -openapi: 3.1.0 +openapi: 3.0.0 info: title: Polygon ID - Issuer - UI API description: | diff --git a/go.mod b/go.mod index afa5c4e17..7f396c138 100644 --- a/go.mod +++ b/go.mod @@ -4,9 +4,8 @@ go 1.21 require ( github.com/alicebob/miniredis/v2 v2.31.1 - github.com/deepmap/oapi-codegen v1.16.2 github.com/ethereum/go-ethereum v1.13.14 - github.com/getkin/kin-openapi v0.123.0 + github.com/getkin/kin-openapi v0.124.0 github.com/go-chi/chi/v5 v5.0.11 github.com/go-chi/cors v1.2.1 github.com/go-redis/cache/v8 v8.4.4 @@ -43,6 +42,7 @@ require ( github.com/lib/pq v1.10.9 github.com/mitchellh/mapstructure v1.5.0 github.com/mr-tron/base58 v1.2.0 + github.com/oapi-codegen/oapi-codegen/v2 v2.3.0 github.com/oapi-codegen/runtime v1.1.1 github.com/patrickmn/go-cache v2.1.0+incompatible github.com/piprate/json-gold v0.5.1-0.20230111113000-6ddbe6e6f19f @@ -50,7 +50,7 @@ require ( github.com/pressly/goose/v3 v3.17.0 github.com/spf13/viper v1.18.2 github.com/stretchr/testify v1.9.0 - golang.org/x/crypto v0.22.0 + golang.org/x/crypto v0.23.0 golang.org/x/exp v0.0.0-20240409090435-93d18d7e34b8 ) @@ -324,12 +324,12 @@ require ( go.uber.org/zap v1.27.0 // indirect golang.org/x/exp/typeparams v0.0.0-20231219180239-dc181d75b848 // indirect golang.org/x/mod v0.17.0 // indirect - golang.org/x/net v0.24.0 // indirect + golang.org/x/net v0.25.0 // indirect golang.org/x/sync v0.7.0 // indirect - golang.org/x/sys v0.19.0 // indirect - golang.org/x/text v0.14.0 // indirect + golang.org/x/sys v0.20.0 // indirect + golang.org/x/text v0.15.0 // indirect golang.org/x/time v0.5.0 // indirect - golang.org/x/tools v0.20.0 // indirect + golang.org/x/tools v0.21.0 // indirect google.golang.org/protobuf v1.33.0 // indirect gopkg.in/go-jose/go-jose.v2 v2.6.3 // indirect gopkg.in/ini.v1 v1.67.0 // indirect diff --git a/go.sum b/go.sum index 90c706b38..e9875cc22 100644 --- a/go.sum +++ b/go.sum @@ -215,8 +215,6 @@ github.com/decred/dcrd/crypto/blake256 v1.0.1 h1:7PltbUIQB7u/FfZ39+DGa/ShuMyJ5il github.com/decred/dcrd/crypto/blake256 v1.0.1/go.mod h1:2OfgNZ5wDpcsFmHmCK5gZTPcCXqlm2ArzUIkw9czNJo= github.com/decred/dcrd/dcrec/secp256k1/v4 v4.3.0 h1:rpfIENRNNilwHwZeG5+P150SMrnNEcHYvcCuK6dPZSg= github.com/decred/dcrd/dcrec/secp256k1/v4 v4.3.0/go.mod h1:v57UDF4pDQJcEfFUCRop3lJL149eHGSe9Jvczhzjo/0= -github.com/deepmap/oapi-codegen v1.16.2 h1:xGHx0dNqYfy9gE8a7AVgVM8Sd5oF9SEgePzP+UPAUXI= -github.com/deepmap/oapi-codegen v1.16.2/go.mod h1:rdYoEA2GE+riuZ91DvpmBX9hJbQpuY9wchXpfQ3n+ho= github.com/denis-tingaikin/go-header v0.4.3 h1:tEaZKAlqql6SKCY++utLmkPLd6K8IBM20Ha7UVm+mtU= github.com/denis-tingaikin/go-header v0.4.3/go.mod h1:0wOCWuN71D5qIgE2nz9KrKmuYBAC2Mra5RassOIQ2/c= github.com/dgryski/go-rendezvous v0.0.0-20200823014737-9f7001d12a5f h1:lO4WD4F/rVNCu3HqELle0jiPLLBs70cWOduZpkS1E78= @@ -270,8 +268,8 @@ github.com/gballet/go-libpcsclite v0.0.0-20190607065134-2772fd86a8ff h1:tY80oXqG github.com/gballet/go-libpcsclite v0.0.0-20190607065134-2772fd86a8ff/go.mod h1:x7DCsMOv1taUwEWCzT4cmDeAkigA5/QCwUodaVOe8Ww= github.com/gballet/go-verkle v0.1.1-0.20231031103413-a67434b50f46 h1:BAIP2GihuqhwdILrV+7GJel5lyPV3u1+PgzrWLc0TkE= github.com/gballet/go-verkle v0.1.1-0.20231031103413-a67434b50f46/go.mod h1:QNpY22eby74jVhqH4WhDLDwxc/vqsern6pW+u2kbkpc= -github.com/getkin/kin-openapi v0.123.0 h1:zIik0mRwFNLyvtXK274Q6ut+dPh6nlxBp0x7mNrPhs8= -github.com/getkin/kin-openapi v0.123.0/go.mod h1:wb1aSZA/iWmorQP9KTAS/phLj/t17B5jT7+fS8ed9NM= +github.com/getkin/kin-openapi v0.124.0 h1:VSFNMB9C9rTKBnQ/fpyDU8ytMTr4dWI9QovSKj9kz/M= +github.com/getkin/kin-openapi v0.124.0/go.mod h1:wb1aSZA/iWmorQP9KTAS/phLj/t17B5jT7+fS8ed9NM= github.com/getsentry/sentry-go v0.25.0 h1:q6Eo+hS+yoJlTO3uu/azhQadsD8V+jQn2D8VvX1eOyI= github.com/getsentry/sentry-go v0.25.0/go.mod h1:lc76E2QywIyW8WuBnwl8Lc4bkmQH4+w1gwTf25trprY= github.com/ghostiam/protogetter v0.3.4 h1:5SZ+lZSNmNkSbGVSF9hUHhv/b7ELF9Rwchoq7btYo6c= @@ -358,7 +356,6 @@ github.com/gofrs/uuid v4.0.0+incompatible/go.mod h1:b2aQJv3Z4Fp6yNu3cdSllBxTCLRx github.com/gogo/protobuf v1.1.1/go.mod h1:r8qH/GZQm5c6nD/R0oafs1akxWv10x8SbQlK7atdtwQ= github.com/gogo/protobuf v1.3.2 h1:Ov1cvc58UF3b5XjBnZv7+opcTcQFZebYjWzi34vdm4Q= github.com/gogo/protobuf v1.3.2/go.mod h1:P1XiOD3dCwIKUDQYPy72D8LYyHL2YPYrpS2s69NZV8Q= -github.com/golang-jwt/jwt v3.2.2+incompatible h1:IfV12K8xAKAnZqdXVzCZ+TOjboZ2keLg81eXfW3O+oY= github.com/golang-jwt/jwt/v4 v4.5.0 h1:7cYmW1XlMY7h7ii7UhUyChSgS5wUJEnm9uZVTGqOWzg= github.com/golang-jwt/jwt/v4 v4.5.0/go.mod h1:m21LjoU+eqJr34lmDMbreY2eSTRJ1cv77w39/MY0Ch0= github.com/golang/glog v0.0.0-20160126235308-23def4e6c14b/go.mod h1:SBH7ygxi8pfUlaOkMMuAQtPIUF8ecWP5IEl/CR7VP2Q= @@ -828,6 +825,8 @@ github.com/nunnatsa/ginkgolinter v0.15.2/go.mod h1:oYxE7dt1vZI8cK2rZOs3RgTaBN2vg github.com/nxadm/tail v1.4.4/go.mod h1:kenIhsEOeOJmVchQTgglprH7qJGnHDVpk1VPCcaMI8A= github.com/nxadm/tail v1.4.8 h1:nPr65rt6Y5JFSKQO7qToXr7pePgD6Gwiw05lkbyAQTE= github.com/nxadm/tail v1.4.8/go.mod h1:+ncqLTQzXmGhMZNUePPaPqPvBxHAIsmXswZKocGu+AU= +github.com/oapi-codegen/oapi-codegen/v2 v2.3.0 h1:rICjNsHbPP1LttefanBPnwsSwl09SqhCO7Ee623qR84= +github.com/oapi-codegen/oapi-codegen/v2 v2.3.0/go.mod h1:4k+cJeSq5ntkwlcpQSxLxICCxQzCL772o30PxdibRt4= github.com/oapi-codegen/runtime v1.1.1 h1:EXLHh0DXIJnWhdRPN2w4MXAzFyE4CskzhNLUmtpMYro= github.com/oapi-codegen/runtime v1.1.1/go.mod h1:SK9X900oXmPWilYR5/WKPzt3Kqxn/uS/+lbpREv+eCg= github.com/olekukonko/tablewriter v0.0.5 h1:P2Ga83D34wi1o9J6Wh1mRuqd4mF/x/lgBS7N7AbDhec= @@ -1170,8 +1169,8 @@ golang.org/x/crypto v0.0.0-20210711020723-a769d52b0f97/go.mod h1:GvvjBRRGRdwPK5y golang.org/x/crypto v0.0.0-20210921155107-089bfa567519/go.mod h1:GvvjBRRGRdwPK5ydBHafDWAxML/pGHZbMvKqRZ5+Abc= golang.org/x/crypto v0.1.0/go.mod h1:RecgLatLF4+eUMCP1PoPZQb+cVrJcOPbHkTkbkB9sbw= golang.org/x/crypto v0.6.0/go.mod h1:OFC/31mSvZgRz0V1QTNCzfAI1aIRzbiufJtkMIlEp58= -golang.org/x/crypto v0.22.0 h1:g1v0xeRhjcugydODzvb3mEM9SQ0HGp9s/nh3COQ/C30= -golang.org/x/crypto v0.22.0/go.mod h1:vr6Su+7cTlO45qkww3VDJlzDn0ctJvRgYbC2NvXHt+M= +golang.org/x/crypto v0.23.0 h1:dIJU/v2J8Mdglj/8rJ6UUOM3Zc9zLZxVZwwxMooUSAI= +golang.org/x/crypto v0.23.0/go.mod h1:CKFgDieR+mRhux2Lsu27y0fO304Db0wZe70UKqHu0v8= golang.org/x/exp v0.0.0-20190121172915-509febef88a4/go.mod h1:CJ0aWSM057203Lf6IL+f9T1iT9GByDxfZKAQTCR3kQA= golang.org/x/exp v0.0.0-20190306152737-a1d7652674e8/go.mod h1:CJ0aWSM057203Lf6IL+f9T1iT9GByDxfZKAQTCR3kQA= golang.org/x/exp v0.0.0-20190510132918-efd6b22b2522/go.mod h1:ZjyILWgesfNpC6sMxTJOJm9Kp84zZh5NQWvqDGG3Qr8= @@ -1200,8 +1199,6 @@ golang.org/x/lint v0.0.0-20190930215403-16217165b5de/go.mod h1:6SW0HCj/g11FgYtHl golang.org/x/lint v0.0.0-20191125180803-fdd1cda4f05f/go.mod h1:5qLYkcX4OjUUV8bRuDixDT3tpyyb+LUpUlRWLxfhWrs= golang.org/x/lint v0.0.0-20200130185559-910be7a94367/go.mod h1:3xt1FjdF8hUf6vQPIChWIBhFzV8gjjsPE/fR3IyQdNY= golang.org/x/lint v0.0.0-20200302205851-738671d3881b/go.mod h1:3xt1FjdF8hUf6vQPIChWIBhFzV8gjjsPE/fR3IyQdNY= -golang.org/x/lint v0.0.0-20210508222113-6edffad5e616 h1:VLliZ0d+/avPrXXH+OakdXhpJuEoBZuwh1m2j7U6Iug= -golang.org/x/lint v0.0.0-20210508222113-6edffad5e616/go.mod h1:3xt1FjdF8hUf6vQPIChWIBhFzV8gjjsPE/fR3IyQdNY= golang.org/x/mobile v0.0.0-20190312151609-d3739f865fa6/go.mod h1:z+o9i4GpDbdi3rU15maQ/Ox0txvL9dWGYEHz965HBQE= golang.org/x/mobile v0.0.0-20190719004257-d2bd2a29d028/go.mod h1:E/iHnbuqvinMTCcRqshq8CkpyQDoeVncDDYHnLhea+o= golang.org/x/mod v0.0.0-20190513183733-4bf6d317e70e/go.mod h1:mXi4GBBbnImb6dmsKGUJ2LatrhH/nqhxcFungHvyanc= @@ -1264,8 +1261,8 @@ golang.org/x/net v0.2.0/go.mod h1:KqCZLdyyvdV855qA2rE3GC2aiw5xGR5TEjj8smXukLY= golang.org/x/net v0.5.0/go.mod h1:DivGGAXEgPSlEBzxGzZI+ZLohi+xUj054jfeKui00ws= golang.org/x/net v0.6.0/go.mod h1:2Tu9+aMcznHK/AK1HMvgo6xiTLG5rD5rZLDS+rp2Bjs= golang.org/x/net v0.7.0/go.mod h1:2Tu9+aMcznHK/AK1HMvgo6xiTLG5rD5rZLDS+rp2Bjs= -golang.org/x/net v0.24.0 h1:1PcaxkF854Fu3+lvBIx5SYn9wRlBzzcnHZSiaFFAb0w= -golang.org/x/net v0.24.0/go.mod h1:2Q7sJY5mzlzWjKtYUEXSlBWCdyaioyXzRB2RtU8KVE8= +golang.org/x/net v0.25.0 h1:d/OCCoBEUq33pjydKrGQhw7IlUPI2Oylr+8qLx49kac= +golang.org/x/net v0.25.0/go.mod h1:JkAGAh7GEvH74S6FOH42FLoXpXbE/aqXSrIQjXgsiwM= golang.org/x/oauth2 v0.0.0-20180821212333-d2e6202438be/go.mod h1:N/0e6XlmueqKjAGxoOufVs8QHGRruUQn6yWY3a++T0U= golang.org/x/oauth2 v0.0.0-20190226205417-e64efc72b421/go.mod h1:gOpvHmFTYa4IltrdGE7lF6nIHvwfUNPOp7c8zoXwtLw= golang.org/x/oauth2 v0.0.0-20190604053449-0f29369cfe45/go.mod h1:gOpvHmFTYa4IltrdGE7lF6nIHvwfUNPOp7c8zoXwtLw= @@ -1357,8 +1354,8 @@ golang.org/x/sys v0.4.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.5.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.6.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.14.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA= -golang.org/x/sys v0.19.0 h1:q5f1RH2jigJ1MoAWp2KTp3gm5zAGFUTarQZ5U386+4o= -golang.org/x/sys v0.19.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA= +golang.org/x/sys v0.20.0 h1:Od9JTbYCk261bKm4M/mw7AklTlFYIa0bIp9BgSm1S8Y= +golang.org/x/sys v0.20.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA= golang.org/x/term v0.0.0-20201117132131-f5c789dd3221/go.mod h1:Nr5EML6q2oocZ2LXRh80K7BxOlk5/8JxuGnuhpl+muw= golang.org/x/term v0.0.0-20201126162022-7de9c90e9dd1/go.mod h1:bj7SfCRtBDWHUb9snDiAeCFNEtKQo2Wmx5Cou7ajbmo= golang.org/x/term v0.0.0-20210927222741-03fcf44c2211/go.mod h1:jbD1KX2456YbFQfuXm/mYQcufACuNUgVhRMnK/tPxf8= @@ -1377,8 +1374,8 @@ golang.org/x/text v0.3.7/go.mod h1:u+2+/6zg+i71rQMx5EYifcz6MCKuco9NR6JIITiCfzQ= golang.org/x/text v0.4.0/go.mod h1:mrYo+phRRbMaCq/xk9113O4dZlRixOauAjOtrjsXDZ8= golang.org/x/text v0.6.0/go.mod h1:mrYo+phRRbMaCq/xk9113O4dZlRixOauAjOtrjsXDZ8= golang.org/x/text v0.7.0/go.mod h1:mrYo+phRRbMaCq/xk9113O4dZlRixOauAjOtrjsXDZ8= -golang.org/x/text v0.14.0 h1:ScX5w1eTa3QqT8oi6+ziP7dTV1S2+ALU0bI+0zXKWiQ= -golang.org/x/text v0.14.0/go.mod h1:18ZOQIKpY8NJVqYksKHtTdi31H5itFRjB5/qKTNYzSU= +golang.org/x/text v0.15.0 h1:h1V/4gjBv8v9cjcR6+AR5+/cIYK5N/WAgiv4xlsEtAk= +golang.org/x/text v0.15.0/go.mod h1:18ZOQIKpY8NJVqYksKHtTdi31H5itFRjB5/qKTNYzSU= golang.org/x/time v0.0.0-20181108054448-85acf8d2951c/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ= golang.org/x/time v0.0.0-20190308202827-9d24e82272b4/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ= golang.org/x/time v0.0.0-20191024005414-555d28b269f0/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ= @@ -1455,8 +1452,8 @@ golang.org/x/tools v0.2.0/go.mod h1:y4OqIKeOV/fWJetJ8bXPU1sEVniLMIyDAZWeHdV+NTA= golang.org/x/tools v0.3.0/go.mod h1:/rWhSS2+zyEVwoJf8YAX6L2f0ntZ7Kn/mGgAWcipA5k= golang.org/x/tools v0.5.0/go.mod h1:N+Kgy78s5I24c24dU8OfWNEotWjutIs8SnJvn5IDq+k= golang.org/x/tools v0.6.0/go.mod h1:Xwgl3UAJ/d3gWutnCtw505GrjyAbvKui8lOU390QaIU= -golang.org/x/tools v0.20.0 h1:hz/CVckiOxybQvFw6h7b/q80NTr9IUQb4s1IIzW7KNY= -golang.org/x/tools v0.20.0/go.mod h1:WvitBU7JJf6A4jOdg4S1tviW9bhUxkgeCui/0JHctQg= +golang.org/x/tools v0.21.0 h1:qc0xYgIbsSDt9EyWz05J5wfa7LOVW0YTLOXrqdLAWIw= +golang.org/x/tools v0.21.0/go.mod h1:aiJjzUbINMkxbQROHiO6hDPo2LHcIPhhQsa9DLh0yGk= golang.org/x/xerrors v0.0.0-20190410155217-1f06c39b4373/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= golang.org/x/xerrors v0.0.0-20190513163551-3ee3066db522/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= golang.org/x/xerrors v0.0.0-20190717185122-a985d3407aa7/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= diff --git a/internal/api/api.gen.go b/internal/api/api.gen.go index a09192c20..738855e98 100644 --- a/internal/api/api.gen.go +++ b/internal/api/api.gen.go @@ -1,6 +1,6 @@ // Package api provides primitives to interact with the openapi HTTP API. // -// Code generated by github.com/deepmap/oapi-codegen/v2 version v2.1.0 DO NOT EDIT. +// Code generated by github.com/oapi-codegen/oapi-codegen/v2 version v2.3.0 DO NOT EDIT. package api import ( diff --git a/internal/api_ui/api.gen.go b/internal/api_ui/api.gen.go index d12ab7b63..ae13370dc 100644 --- a/internal/api_ui/api.gen.go +++ b/internal/api_ui/api.gen.go @@ -1,6 +1,6 @@ // Package api_ui provides primitives to interact with the openapi HTTP API. // -// Code generated by github.com/deepmap/oapi-codegen/v2 version v2.1.0 DO NOT EDIT. +// Code generated by github.com/oapi-codegen/oapi-codegen/v2 version v2.3.0 DO NOT EDIT. package api_ui import ( @@ -432,7 +432,7 @@ type AuthCallbackParams struct { type AuthQRCodeParams struct { // Type Type: // * `link` - (default value) Return a QR code with a link redirection to the raw content. Easier to scan. - // * `raw` - Return the raw QR code. (default value) + // * `raw` - Return the raw QR code. Type *AuthQRCodeParamsType `form:"type,omitempty" json:"type,omitempty"` } @@ -537,7 +537,7 @@ type GetLinkQRCodeParams struct { type GetCredentialQrCodeParams struct { // Type Type: // * `link` - (default value) Return a QR code with a link redirection to the raw content. Easier to scan. - // * `raw` - Return the raw QR code. (default value) + // * `raw` - Return the raw QR code. Type *GetCredentialQrCodeParamsType `form:"type,omitempty" json:"type,omitempty"` } diff --git a/tools.go b/tools.go index 97c4237f1..68376e525 100644 --- a/tools.go +++ b/tools.go @@ -4,7 +4,7 @@ package tools import ( - _ "github.com/deepmap/oapi-codegen/cmd/oapi-codegen" _ "github.com/golangci/golangci-lint/cmd/golangci-lint" _ "github.com/joho/godotenv/cmd/godotenv" + _ "github.com/oapi-codegen/oapi-codegen/v2/cmd/oapi-codegen" ) From b3242634592b183c13c623c4bd04b50641294527 Mon Sep 17 00:00:00 2001 From: Martin Saporiti Date: Tue, 25 Jun 2024 15:04:57 -0300 Subject: [PATCH 39/52] chore: add proofs to create claim endpoint --- api/api.yaml | 7 +++ internal/api/api.gen.go | 32 ++++++---- internal/api/server.go | 23 ++++++- internal/api/server_test.go | 26 +++++++- internal/api_ui/server.go | 12 +++- internal/api_ui/server_test.go | 61 ++++++++++++++----- internal/core/ports/claims_service.go | 21 +++---- internal/core/services/link.go | 9 ++- internal/core/services/tests/identity_test.go | 14 ++--- internal/core/services/tests/link_test.go | 2 +- 10 files changed, 155 insertions(+), 52 deletions(-) diff --git a/api/api.yaml b/api/api.yaml index 63ff59321..f6cee32e1 100644 --- a/api/api.yaml +++ b/api/api.yaml @@ -675,6 +675,13 @@ components: $ref: '#/components/schemas/RefreshService' displayMethod: $ref: '#/components/schemas/DisplayMethod' + proofs: + type: array + items: + type: string + x-omitempty: false + example: "[ BJJSignatureProof2021, Iden3SparseMerkleTreeProof]" + enum: [ BJJSignatureProof2021, Iden3SparseMerkleTreeProof] example: credentialSchema: "https://raw.githubusercontent.com/iden3/claim-schema-vocab/main/schemas/json/KYCAgeCredential-v3.json" type: "KYCAgeCredential" diff --git a/internal/api/api.gen.go b/internal/api/api.gen.go index 738855e98..f4196fc3b 100644 --- a/internal/api/api.gen.go +++ b/internal/api/api.gen.go @@ -21,6 +21,12 @@ const ( BasicAuthScopes = "basicAuth.Scopes" ) +// Defines values for CreateClaimRequestProofs. +const ( + BJJSignatureProof2021 CreateClaimRequestProofs = "BJJSignatureProof2021" + Iden3SparseMerkleTreeProof CreateClaimRequestProofs = "Iden3SparseMerkleTreeProof" +) + // Defines values for CreateIdentityRequestDidMetadataType. const ( BJJ CreateIdentityRequestDidMetadataType = "BJJ" @@ -53,17 +59,21 @@ type Config = []KeyValue // CreateClaimRequest defines model for CreateClaimRequest. type CreateClaimRequest struct { - CredentialSchema string `json:"credentialSchema"` - CredentialSubject map[string]interface{} `json:"credentialSubject"` - DisplayMethod *DisplayMethod `json:"displayMethod,omitempty"` - Expiration *int64 `json:"expiration,omitempty"` - MerklizedRootPosition *string `json:"merklizedRootPosition,omitempty"` - RefreshService *RefreshService `json:"refreshService,omitempty"` - RevNonce *uint64 `json:"revNonce,omitempty"` - SubjectPosition *string `json:"subjectPosition,omitempty"` - Type string `json:"type"` - Version *uint32 `json:"version,omitempty"` -} + CredentialSchema string `json:"credentialSchema"` + CredentialSubject map[string]interface{} `json:"credentialSubject"` + DisplayMethod *DisplayMethod `json:"displayMethod,omitempty"` + Expiration *int64 `json:"expiration,omitempty"` + MerklizedRootPosition *string `json:"merklizedRootPosition,omitempty"` + Proofs *[]CreateClaimRequestProofs `json:"proofs,omitempty"` + RefreshService *RefreshService `json:"refreshService,omitempty"` + RevNonce *uint64 `json:"revNonce,omitempty"` + SubjectPosition *string `json:"subjectPosition,omitempty"` + Type string `json:"type"` + Version *uint32 `json:"version,omitempty"` +} + +// CreateClaimRequestProofs defines model for CreateClaimRequest.Proofs. +type CreateClaimRequestProofs string // CreateClaimResponse defines model for CreateClaimResponse. type CreateClaimResponse struct { diff --git a/internal/api/server.go b/internal/api/server.go index 734642ff3..72d0ddb94 100644 --- a/internal/api/server.go +++ b/internal/api/server.go @@ -151,6 +151,9 @@ func (s *Server) CreateIdentity(ctx context.Context, request CreateIdentityReque // CreateClaim is claim creation controller func (s *Server) CreateClaim(ctx context.Context, request CreateClaimRequestObject) (CreateClaimResponseObject, error) { + const BJJSignatureProof2021 = "BJJSignatureProof2021" + const Iden3SparseMerkleTreeProof = "Iden3SparseMerkleTreeProof" + did, err := w3c.ParseDID(request.Identifier) if err != nil { return CreateClaim400JSONResponse{N400JSONResponse{Message: err.Error()}}, nil @@ -160,7 +163,25 @@ func (s *Server) CreateClaim(ctx context.Context, request CreateClaimRequestObje expiration = common.ToPointer(time.Unix(*request.Body.Expiration, 0)) } - req := ports.NewCreateClaimRequest(did, request.Body.CredentialSchema, request.Body.CredentialSubject, expiration, request.Body.Type, request.Body.Version, request.Body.SubjectPosition, request.Body.MerklizedRootPosition, common.ToPointer(true), common.ToPointer(true), nil, false, s.cfg.CredentialStatus.CredentialStatusType, toVerifiableRefreshService(request.Body.RefreshService), request.Body.RevNonce, + claimRequestProofs := ports.ClaimRequestProofs{} + if request.Body.Proofs == nil { + claimRequestProofs.BJJSignatureProof2021 = true + claimRequestProofs.Iden3SparseMerkleTreeProof = true + } else { + for _, proof := range *request.Body.Proofs { + if string(proof) == BJJSignatureProof2021 { + claimRequestProofs.BJJSignatureProof2021 = true + continue + } + if string(proof) == Iden3SparseMerkleTreeProof { + claimRequestProofs.Iden3SparseMerkleTreeProof = true + continue + } + return CreateClaim400JSONResponse{N400JSONResponse{Message: fmt.Sprintf("unsupported proof type: %s", proof)}}, nil + } + } + + req := ports.NewCreateClaimRequest(did, request.Body.CredentialSchema, request.Body.CredentialSubject, expiration, request.Body.Type, request.Body.Version, request.Body.SubjectPosition, request.Body.MerklizedRootPosition, claimRequestProofs, nil, false, s.cfg.CredentialStatus.CredentialStatusType, toVerifiableRefreshService(request.Body.RefreshService), request.Body.RevNonce, toVerifiableDisplayMethod(request.Body.DisplayMethod)) resp, err := s.claimService.Save(ctx, req) diff --git a/internal/api/server_test.go b/internal/api/server_test.go index 769efbd38..aa7e31f71 100644 --- a/internal/api/server_test.go +++ b/internal/api/server_test.go @@ -556,6 +556,26 @@ func TestServer_CreateClaim(t *testing.T) { httpCode: http.StatusUnprocessableEntity, }, }, + { + name: "Wrong proof type", + auth: authOk, + did: did, + body: CreateClaimRequest{ + CredentialSchema: "http://www.wrong.url/cannot/get/the/credential", + Type: "KYCAgeCredential", + CredentialSubject: map[string]any{ + "id": "did:polygonid:polygon:mumbai:2qE1BZ7gcmEoP2KppvFPCZqyzyb5tK9T6Gec5HFANQ", + "birthday": 19960424, + "documentType": 2, + }, + Expiration: common.ToPointer(time.Now().Unix()), + Proofs: &[]CreateClaimRequestProofs{"wrong proof"}, + }, + expected: expected{ + response: CreateClaim400JSONResponse{N400JSONResponse{Message: "unsupported proof type: wrong proof"}}, + httpCode: http.StatusBadRequest, + }, + }, } { t.Run(tc.name, func(t *testing.T) { pubSub.Clear(event.CreateCredentialEvent) @@ -1400,7 +1420,11 @@ func TestServer_GetRevocationStatus(t *testing.T) { typeC := "KYCAgeCredential" merklizedRootPosition := "value" - claim, err := claimsService.Save(ctx, ports.NewCreateClaimRequest(did, schema, credentialSubject, common.ToPointer(time.Now()), typeC, nil, nil, &merklizedRootPosition, common.ToPointer(true), common.ToPointer(true), nil, false, verifiable.Iden3commRevocationStatusV1, nil, nil, nil)) + claimRequestProofs := ports.ClaimRequestProofs{ + BJJSignatureProof2021: true, + Iden3SparseMerkleTreeProof: true, + } + claim, err := claimsService.Save(ctx, ports.NewCreateClaimRequest(did, schema, credentialSubject, common.ToPointer(time.Now()), typeC, nil, nil, &merklizedRootPosition, claimRequestProofs, nil, false, verifiable.Iden3commRevocationStatusV1, nil, nil, nil)) assert.NoError(t, err) type expected struct { diff --git a/internal/api_ui/server.go b/internal/api_ui/server.go index 154673e9a..99f08a5ac 100644 --- a/internal/api_ui/server.go +++ b/internal/api_ui/server.go @@ -343,7 +343,17 @@ func (s *Server) CreateCredential(ctx context.Context, request CreateCredentialR if request.Body.SignatureProof == nil && request.Body.MtProof == nil { return CreateCredential400JSONResponse{N400JSONResponse{Message: "you must to provide at least one proof type"}}, nil } - req := ports.NewCreateClaimRequest(&s.cfg.APIUI.IssuerDID, request.Body.CredentialSchema, request.Body.CredentialSubject, request.Body.Expiration, request.Body.Type, nil, nil, nil, request.Body.SignatureProof, request.Body.MtProof, nil, true, s.cfg.CredentialStatus.CredentialStatusType, toVerifiableRefreshService(request.Body.RefreshService), nil, + + claimRequestProofs := ports.ClaimRequestProofs{} + if request.Body.SignatureProof != nil && *request.Body.SignatureProof { + claimRequestProofs.BJJSignatureProof2021 = true + } + + if request.Body.MtProof != nil && *request.Body.MtProof { + claimRequestProofs.Iden3SparseMerkleTreeProof = true + } + + req := ports.NewCreateClaimRequest(&s.cfg.APIUI.IssuerDID, request.Body.CredentialSchema, request.Body.CredentialSubject, request.Body.Expiration, request.Body.Type, nil, nil, nil, claimRequestProofs, nil, true, s.cfg.CredentialStatus.CredentialStatusType, toVerifiableRefreshService(request.Body.RefreshService), nil, toDisplayMethodService(request.Body.DisplayMethod)) resp, err := s.claimService.Save(ctx, req) if err != nil { diff --git a/internal/api_ui/server_test.go b/internal/api_ui/server_test.go index dbc945847..d4a48ac2e 100644 --- a/internal/api_ui/server_test.go +++ b/internal/api_ui/server_test.go @@ -1520,13 +1520,29 @@ func TestServer_GetCredential(t *testing.T) { typeC := "KYCAgeCredential" merklizedRootPosition := "index" schema := "https://raw.githubusercontent.com/iden3/claim-schema-vocab/main/schemas/json/KYCAgeCredential-v3.json" - createdClaim1, err := claimsService.Save(ctx, ports.NewCreateClaimRequest(did, schema, credentialSubject, nil, typeC, nil, nil, &merklizedRootPosition, common.ToPointer(true), common.ToPointer(true), nil, false, verifiable.Iden3commRevocationStatusV1, nil, nil, nil)) + + createdClaim1Proofs := ports.ClaimRequestProofs{ + BJJSignatureProof2021: true, + Iden3SparseMerkleTreeProof: true, + } + + createdClaim2Proofs := ports.ClaimRequestProofs{ + BJJSignatureProof2021: true, + Iden3SparseMerkleTreeProof: false, + } + + createdClaim3Proofs := ports.ClaimRequestProofs{ + BJJSignatureProof2021: false, + Iden3SparseMerkleTreeProof: true, + } + + createdClaim1, err := claimsService.Save(ctx, ports.NewCreateClaimRequest(did, schema, credentialSubject, nil, typeC, nil, nil, &merklizedRootPosition, createdClaim1Proofs, nil, false, verifiable.Iden3commRevocationStatusV1, nil, nil, nil)) require.NoError(t, err) - createdClaim2, err := claimsService.Save(ctx, ports.NewCreateClaimRequest(did, schema, credentialSubject, nil, typeC, nil, nil, &merklizedRootPosition, common.ToPointer(true), common.ToPointer(false), nil, false, verifiable.Iden3commRevocationStatusV1, nil, nil, nil)) + createdClaim2, err := claimsService.Save(ctx, ports.NewCreateClaimRequest(did, schema, credentialSubject, nil, typeC, nil, nil, &merklizedRootPosition, createdClaim2Proofs, nil, false, verifiable.Iden3commRevocationStatusV1, nil, nil, nil)) require.NoError(t, err) - createdClaim3, err := claimsService.Save(ctx, ports.NewCreateClaimRequest(did, schema, credentialSubject, nil, typeC, nil, nil, &merklizedRootPosition, common.ToPointer(false), common.ToPointer(true), nil, false, verifiable.Iden3commRevocationStatusV1, nil, nil, nil)) + createdClaim3, err := claimsService.Save(ctx, ports.NewCreateClaimRequest(did, schema, credentialSubject, nil, typeC, nil, nil, &merklizedRootPosition, createdClaim3Proofs, nil, false, verifiable.Iden3commRevocationStatusV1, nil, nil, nil)) require.NoError(t, err) handler := getHandler(ctx, server) @@ -1728,19 +1744,22 @@ func TestServer_GetCredentials(t *testing.T) { _, err = schemaService.ImportSchema(ctx, *did, iReq) require.NoError(t, err) // Never expires - _, err = claimsService.Save(ctx, ports.NewCreateClaimRequest(did, schemaURL, credentialSubject, nil, typeC, nil, nil, &merklizedRootPosition, common.ToPointer(true), common.ToPointer(true), nil, false, verifiable.Iden3commRevocationStatusV1, nil, nil, nil)) + _, err = claimsService.Save(ctx, ports.NewCreateClaimRequest(did, schemaURL, credentialSubject, nil, typeC, nil, nil, &merklizedRootPosition, ports.ClaimRequestProofs{BJJSignatureProof2021: true, Iden3SparseMerkleTreeProof: true}, + nil, false, verifiable.Iden3commRevocationStatusV1, nil, nil, nil)) require.NoError(t, err) // Expires in future - _, err = claimsService.Save(ctx, ports.NewCreateClaimRequest(did, schemaURL, credentialSubject, &future, typeC, nil, nil, &merklizedRootPosition, common.ToPointer(true), common.ToPointer(false), nil, false, verifiable.Iden3commRevocationStatusV1, nil, nil, nil)) + _, err = claimsService.Save(ctx, ports.NewCreateClaimRequest(did, schemaURL, credentialSubject, &future, typeC, nil, nil, &merklizedRootPosition, ports.ClaimRequestProofs{BJJSignatureProof2021: true, Iden3SparseMerkleTreeProof: false}, nil, false, verifiable.Iden3commRevocationStatusV1, nil, nil, nil)) require.NoError(t, err) // Expired - claim, err := claimsService.Save(ctx, ports.NewCreateClaimRequest(did, schemaURL, credentialSubject, &past, typeC, nil, nil, &merklizedRootPosition, common.ToPointer(true), common.ToPointer(false), nil, false, verifiable.Iden3commRevocationStatusV1, nil, nil, nil)) + claim, err := claimsService.Save(ctx, ports.NewCreateClaimRequest(did, schemaURL, credentialSubject, &past, typeC, nil, nil, &merklizedRootPosition, ports.ClaimRequestProofs{BJJSignatureProof2021: true, Iden3SparseMerkleTreeProof: false}, nil, false, verifiable.Iden3commRevocationStatusV1, nil, nil, nil)) require.NoError(t, err) // non expired, but revoked - revoked, err := claimsService.Save(ctx, ports.NewCreateClaimRequest(did, schemaURL, credentialSubject, &future, typeC, nil, nil, &merklizedRootPosition, common.ToPointer(false), common.ToPointer(true), nil, false, verifiable.Iden3commRevocationStatusV1, nil, nil, nil)) + revoked, err := claimsService.Save(ctx, ports.NewCreateClaimRequest(did, schemaURL, credentialSubject, &future, typeC, nil, nil, &merklizedRootPosition, + ports.ClaimRequestProofs{BJJSignatureProof2021: false, Iden3SparseMerkleTreeProof: true}, + nil, false, verifiable.Iden3commRevocationStatusV1, nil, nil, nil)) require.NoError(t, err) id, err := w3c.ParseDID(*revoked.Identifier) @@ -2199,9 +2218,20 @@ func TestServer_GetCredentialQrCode(t *testing.T) { typeC := "KYCAgeCredential" merklizedRootPosition := "index" schema := "https://raw.githubusercontent.com/iden3/claim-schema-vocab/main/schemas/json/KYCAgeCredential-v3.json" - createdSIGClaim, err := claimsService.Save(ctx, ports.NewCreateClaimRequest(did, schema, credentialSubject, nil, typeC, nil, nil, &merklizedRootPosition, common.ToPointer(true), common.ToPointer(false), nil, false, verifiable.Iden3commRevocationStatusV1, nil, nil, nil)) + + createdSIGClaimProofs := ports.ClaimRequestProofs{ + BJJSignatureProof2021: true, + Iden3SparseMerkleTreeProof: false, + } + + createdMTPClaimProofs := ports.ClaimRequestProofs{ + BJJSignatureProof2021: false, + Iden3SparseMerkleTreeProof: true, + } + + createdSIGClaim, err := claimsService.Save(ctx, ports.NewCreateClaimRequest(did, schema, credentialSubject, nil, typeC, nil, nil, &merklizedRootPosition, createdSIGClaimProofs, nil, false, verifiable.Iden3commRevocationStatusV1, nil, nil, nil)) require.NoError(t, err) - createdMTPClaim, err := claimsService.Save(ctx, ports.NewCreateClaimRequest(did, schema, credentialSubject, nil, typeC, nil, nil, &merklizedRootPosition, common.ToPointer(false), common.ToPointer(true), nil, false, verifiable.Iden3commRevocationStatusV1, nil, nil, nil)) + createdMTPClaim, err := claimsService.Save(ctx, ports.NewCreateClaimRequest(did, schema, credentialSubject, nil, typeC, nil, nil, &merklizedRootPosition, createdMTPClaimProofs, nil, false, verifiable.Iden3commRevocationStatusV1, nil, nil, nil)) require.NoError(t, err) type expected struct { @@ -2576,9 +2606,9 @@ func TestServer_GetConnections(t *testing.T) { } merklizedRootPosition := "index" - _, err = claimsService.Save(ctx, ports.NewCreateClaimRequest(did, schemaURL, credentialSubject, nil, schemaType, nil, nil, &merklizedRootPosition, common.ToPointer(true), common.ToPointer(true), nil, false, verifiable.Iden3commRevocationStatusV1, nil, nil, nil)) + _, err = claimsService.Save(ctx, ports.NewCreateClaimRequest(did, schemaURL, credentialSubject, nil, schemaType, nil, nil, &merklizedRootPosition, ports.ClaimRequestProofs{BJJSignatureProof2021: true, Iden3SparseMerkleTreeProof: true}, nil, false, verifiable.Iden3commRevocationStatusV1, nil, nil, nil)) require.NoError(t, err) - _, err = claimsService.Save(ctx, ports.NewCreateClaimRequest(did, schemaURL, credentialSubject2, nil, schemaType, nil, nil, &merklizedRootPosition, common.ToPointer(true), common.ToPointer(true), nil, false, verifiable.Iden3commRevocationStatusV1, nil, nil, nil)) + _, err = claimsService.Save(ctx, ports.NewCreateClaimRequest(did, schemaURL, credentialSubject2, nil, schemaType, nil, nil, &merklizedRootPosition, ports.ClaimRequestProofs{BJJSignatureProof2021: true, Iden3SparseMerkleTreeProof: true}, nil, false, verifiable.Iden3commRevocationStatusV1, nil, nil, nil)) require.NoError(t, err) usrDID, err := w3c.ParseDID("did:polygonid:polygon:mumbai:2qE1BZ7gcmEoP2KppvFPCZqyzyb5tK9T6Gec5HFANQ") @@ -4816,7 +4846,7 @@ func TestServer_GetStateStatus(t *testing.T) { } serverWithSignatureClaim := NewServer(cfg1, identityService, claimsService, NewSchemaMock(), connectionsService, NewLinkMock(), nil, NewPublisherMock(), NewPackageManagerMock(), nil) - _, err = claimsService.Save(ctx, ports.NewCreateClaimRequest(didSignatureClaim, schema, credentialSubject, nil, typeC, nil, nil, &merklizedRootPosition, common.ToPointer(true), common.ToPointer(false), nil, true, verifiable.Iden3commRevocationStatusV1, nil, nil, nil)) + _, err = claimsService.Save(ctx, ports.NewCreateClaimRequest(didSignatureClaim, schema, credentialSubject, nil, typeC, nil, nil, &merklizedRootPosition, ports.ClaimRequestProofs{BJJSignatureProof2021: true, Iden3SparseMerkleTreeProof: false}, nil, true, verifiable.Iden3commRevocationStatusV1, nil, nil, nil)) require.NoError(t, err) handlerWithSignatureClaim := getHandler(ctx, serverWithSignatureClaim) @@ -4832,7 +4862,7 @@ func TestServer_GetStateStatus(t *testing.T) { }, } serverWithMTPClaim := NewServer(cfgWithMTPClaim, identityService, claimsService, NewSchemaMock(), connectionsService, NewLinkMock(), nil, NewPublisherMock(), NewPackageManagerMock(), nil) - _, err = claimsService.Save(ctx, ports.NewCreateClaimRequest(didWithMTPClaim, schema, credentialSubject, nil, typeC, nil, nil, &merklizedRootPosition, common.ToPointer(true), common.ToPointer(true), nil, true, verifiable.Iden3commRevocationStatusV1, nil, nil, nil)) + _, err = claimsService.Save(ctx, ports.NewCreateClaimRequest(didWithMTPClaim, schema, credentialSubject, nil, typeC, nil, nil, &merklizedRootPosition, ports.ClaimRequestProofs{BJJSignatureProof2021: true, Iden3SparseMerkleTreeProof: true}, nil, true, verifiable.Iden3commRevocationStatusV1, nil, nil, nil)) require.NoError(t, err) handlerWithMTPClaim := getHandler(ctx, serverWithMTPClaim) @@ -4848,7 +4878,7 @@ func TestServer_GetStateStatus(t *testing.T) { }, } serverWithRevokedClaim := NewServer(cfgWithRevokedClaim, identityService, claimsService, NewSchemaMock(), connectionsService, NewLinkMock(), nil, NewPublisherMock(), NewPackageManagerMock(), nil) - cred, err := claimsService.Save(ctx, ports.NewCreateClaimRequest(didWithRevokedClaim, schema, credentialSubject, nil, typeC, nil, nil, &merklizedRootPosition, common.ToPointer(true), common.ToPointer(false), nil, true, verifiable.Iden3commRevocationStatusV1, nil, nil, nil)) + cred, err := claimsService.Save(ctx, ports.NewCreateClaimRequest(didWithRevokedClaim, schema, credentialSubject, nil, typeC, nil, nil, &merklizedRootPosition, ports.ClaimRequestProofs{BJJSignatureProof2021: true, Iden3SparseMerkleTreeProof: false}, nil, true, verifiable.Iden3commRevocationStatusV1, nil, nil, nil)) require.NoError(t, err) require.NoError(t, claimsService.Revoke(ctx, cfgWithRevokedClaim.APIUI.IssuerDID, uint64(cred.RevNonce), "not valid")) handlerWithRevokedClaim := getHandler(ctx, serverWithRevokedClaim) @@ -5065,7 +5095,8 @@ func TestServer_GetRevocationStatus(t *testing.T) { typeC := "KYCAgeCredential" merklizedRootPosition := "index" schema := "https://raw.githubusercontent.com/iden3/claim-schema-vocab/main/schemas/json/KYCAgeCredential-v3.json" - createdCredential, err := claimsService.Save(ctx, ports.NewCreateClaimRequest(did, schema, credentialSubject, nil, typeC, nil, nil, &merklizedRootPosition, common.ToPointer(true), common.ToPointer(true), nil, false, verifiable.Iden3commRevocationStatusV1, nil, nil, nil)) + + createdCredential, err := claimsService.Save(ctx, ports.NewCreateClaimRequest(did, schema, credentialSubject, nil, typeC, nil, nil, &merklizedRootPosition, ports.ClaimRequestProofs{BJJSignatureProof2021: true, Iden3SparseMerkleTreeProof: true}, nil, false, verifiable.Iden3commRevocationStatusV1, nil, nil, nil)) require.NoError(t, err) handler := getHandler(ctx, server) diff --git a/internal/core/ports/claims_service.go b/internal/core/ports/claims_service.go index f894d8f9f..47204bd19 100644 --- a/internal/core/ports/claims_service.go +++ b/internal/core/ports/claims_service.go @@ -13,11 +13,16 @@ import ( comm "github.com/iden3/iden3comm/v2" "github.com/iden3/iden3comm/v2/protocol" - "github.com/polygonid/sh-id-platform/internal/common" "github.com/polygonid/sh-id-platform/internal/core/domain" "github.com/polygonid/sh-id-platform/internal/sqltools" ) +// ClaimRequestProofs - defines the proofs that can be requested for a claim +type ClaimRequestProofs struct { + BJJSignatureProof2021 bool + Iden3SparseMerkleTreeProof bool +} + // CreateClaimRequest struct type CreateClaimRequest struct { DID *w3c.DID @@ -112,22 +117,14 @@ func NewClaimsFilter(schemaHash, schemaType, subject, queryField, queryValue *st } // NewCreateClaimRequest returns a new claim object with the given parameters -func NewCreateClaimRequest(did *w3c.DID, credentialSchema string, credentialSubject map[string]any, expiration *time.Time, typ string, cVersion *uint32, subjectPos *string, merklizedRootPosition *string, sigProof *bool, mtProof *bool, linkID *uuid.UUID, singleIssuer bool, credentialStatusType verifiable.CredentialStatusType, refreshService *verifiable.RefreshService, revNonce *uint64, displayMethod *verifiable.DisplayMethod) *CreateClaimRequest { - if sigProof == nil { - sigProof = common.ToPointer(false) - } - - if mtProof == nil { - mtProof = common.ToPointer(false) - } - +func NewCreateClaimRequest(did *w3c.DID, credentialSchema string, credentialSubject map[string]any, expiration *time.Time, typ string, cVersion *uint32, subjectPos *string, merklizedRootPosition *string, claimRequestProofs ClaimRequestProofs, linkID *uuid.UUID, singleIssuer bool, credentialStatusType verifiable.CredentialStatusType, refreshService *verifiable.RefreshService, revNonce *uint64, displayMethod *verifiable.DisplayMethod) *CreateClaimRequest { req := &CreateClaimRequest{ DID: did, Schema: credentialSchema, CredentialSubject: credentialSubject, Type: typ, - SignatureProof: *sigProof, - MTProof: *mtProof, + SignatureProof: claimRequestProofs.BJJSignatureProof2021, + MTProof: claimRequestProofs.Iden3SparseMerkleTreeProof, RefreshService: refreshService, DisplayMethod: displayMethod, } diff --git a/internal/core/services/link.go b/internal/core/services/link.go index 5edaf3581..61f07a0b7 100644 --- a/internal/core/services/link.go +++ b/internal/core/services/link.go @@ -15,7 +15,6 @@ import ( "github.com/iden3/iden3comm/v2/protocol" "github.com/jackc/pgx/v4" - "github.com/polygonid/sh-id-platform/internal/common" "github.com/polygonid/sh-id-platform/internal/core/domain" "github.com/polygonid/sh-id-platform/internal/core/event" "github.com/polygonid/sh-id-platform/internal/core/ports" @@ -246,6 +245,11 @@ func (ls *Link) IssueClaim(ctx context.Context, sessionID string, issuerDID w3c. log.Error(ctx, "cannot fetch the schema", "err", err) return err } + + claimRequestProofs := ports.ClaimRequestProofs{ + BJJSignatureProof2021: link.CredentialSignatureProof, + Iden3SparseMerkleTreeProof: link.CredentialMTPProof, + } if len(issuedByUser) == 0 { link.CredentialSubject["id"] = userDID.String() @@ -255,8 +259,7 @@ func (ls *Link) IssueClaim(ctx context.Context, sessionID string, issuerDID w3c. link.CredentialExpiration, schema.Type, nil, nil, nil, - common.ToPointer(link.CredentialSignatureProof), - common.ToPointer(link.CredentialMTPProof), + claimRequestProofs, &linkID, true, credentialStatusType, diff --git a/internal/core/services/tests/identity_test.go b/internal/core/services/tests/identity_test.go index 598aa7e08..0d080685a 100644 --- a/internal/core/services/tests/identity_test.go +++ b/internal/core/services/tests/identity_test.go @@ -71,7 +71,7 @@ func Test_identity_UpdateState(t *testing.T) { merklizedRootPosition := "index" _, err = claimsService.Save(ctx, ports.NewCreateClaimRequest(did, schema, credentialSubject, common.ToPointer(time.Now()), typeC, nil, nil, &merklizedRootPosition, - common.ToPointer(true), common.ToPointer(true), nil, false, + ports.ClaimRequestProofs{BJJSignatureProof2021: true, Iden3SparseMerkleTreeProof: true}, nil, false, verifiable.Iden3commRevocationStatusV1, nil, nil, nil)) assert.NoError(t, err) @@ -93,7 +93,7 @@ func Test_identity_UpdateState(t *testing.T) { merklizedRootPosition := "index" _, err = claimsService.Save(ctx, ports.NewCreateClaimRequest(did, schema, credentialSubject, common.ToPointer(time.Now()), typeC, nil, nil, &merklizedRootPosition, - common.ToPointer(false), common.ToPointer(true), nil, false, + ports.ClaimRequestProofs{BJJSignatureProof2021: true, Iden3SparseMerkleTreeProof: true}, nil, false, verifiable.Iden3commRevocationStatusV1, nil, nil, nil)) assert.NoError(t, err) @@ -115,7 +115,7 @@ func Test_identity_UpdateState(t *testing.T) { merklizedRootPosition := "index" claim, err := claimsService.Save(ctx, ports.NewCreateClaimRequest(did, schema, credentialSubject, common.ToPointer(time.Now()), typeC, nil, nil, &merklizedRootPosition, - common.ToPointer(false), common.ToPointer(true), nil, false, + ports.ClaimRequestProofs{BJJSignatureProof2021: false, Iden3SparseMerkleTreeProof: true}, nil, false, verifiable.Iden3commRevocationStatusV1, nil, nil, nil)) assert.NoError(t, err) @@ -141,7 +141,7 @@ func Test_identity_UpdateState(t *testing.T) { merklizedRootPosition := "index" claimMTP, err := claimsService.Save(ctx, ports.NewCreateClaimRequest(did, schema, credentialSubject, common.ToPointer(time.Now()), typeC, nil, nil, &merklizedRootPosition, - common.ToPointer(false), common.ToPointer(true), nil, false, + ports.ClaimRequestProofs{BJJSignatureProof2021: false, Iden3SparseMerkleTreeProof: true}, nil, false, verifiable.Iden3commRevocationStatusV1, nil, nil, nil)) assert.NoError(t, err) @@ -163,7 +163,7 @@ func Test_identity_UpdateState(t *testing.T) { claimSIG, err := claimsService.Save(ctx, ports.NewCreateClaimRequest(did, schema, credentialSubject, common.ToPointer(time.Now()), typeC, nil, nil, &merklizedRootPosition, - common.ToPointer(true), common.ToPointer(false), nil, false, + ports.ClaimRequestProofs{BJJSignatureProof2021: true, Iden3SparseMerkleTreeProof: false}, nil, false, verifiable.Iden3commRevocationStatusV1, nil, nil, nil)) assert.NoError(t, err) @@ -190,7 +190,7 @@ func Test_identity_UpdateState(t *testing.T) { merklizedRootPosition := "index" _, err = claimsService.Save(ctx, ports.NewCreateClaimRequest(did, schema, credentialSubject, common.ToPointer(time.Now()), typeC, nil, nil, &merklizedRootPosition, - common.ToPointer(true), common.ToPointer(false), nil, false, + ports.ClaimRequestProofs{BJJSignatureProof2021: true, Iden3SparseMerkleTreeProof: false}, nil, false, verifiable.Iden3commRevocationStatusV1, nil, nil, nil)) assert.NoError(t, err) @@ -205,7 +205,7 @@ func Test_identity_UpdateState(t *testing.T) { merklizedRootPosition := "index" claim, err := claimsService.Save(ctx, ports.NewCreateClaimRequest(did, schema, credentialSubject, common.ToPointer(time.Now()), typeC, nil, nil, &merklizedRootPosition, - common.ToPointer(true), common.ToPointer(false), nil, false, + ports.ClaimRequestProofs{BJJSignatureProof2021: true, Iden3SparseMerkleTreeProof: false}, nil, false, verifiable.Iden3commRevocationStatusV1, nil, nil, nil)) assert.NoError(t, err) diff --git a/internal/core/services/tests/link_test.go b/internal/core/services/tests/link_test.go index be3c8b606..d62de7121 100644 --- a/internal/core/services/tests/link_test.go +++ b/internal/core/services/tests/link_test.go @@ -79,7 +79,7 @@ func Test_link_issueClaim(t *testing.T) { typeC := "KYCAgeCredential" merklizedRootPosition := "index" - _, err = claimsService.Save(context.Background(), ports.NewCreateClaimRequest(did, schemaUrl, credentialSubject, common.ToPointer(time.Now()), typeC, nil, nil, &merklizedRootPosition, common.ToPointer(true), common.ToPointer(true), nil, false, verifiable.Iden3commRevocationStatusV1, nil, nil, nil)) + _, err = claimsService.Save(context.Background(), ports.NewCreateClaimRequest(did, schemaUrl, credentialSubject, common.ToPointer(time.Now()), typeC, nil, nil, &merklizedRootPosition, ports.ClaimRequestProofs{BJJSignatureProof2021: true, Iden3SparseMerkleTreeProof: true}, nil, false, verifiable.Iden3commRevocationStatusV1, nil, nil, nil)) assert.NoError(t, err) linkRepository := repositories.NewLink(*storage) From 2b33e22a6c0b48839ca8528ae7e39ff614998473 Mon Sep 17 00:00:00 2001 From: Martin Saporiti Date: Tue, 25 Jun 2024 15:10:33 -0300 Subject: [PATCH 40/52] fix: tests --- api/api.yaml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/api/api.yaml b/api/api.yaml index f6cee32e1..851264fa7 100644 --- a/api/api.yaml +++ b/api/api.yaml @@ -680,7 +680,7 @@ components: items: type: string x-omitempty: false - example: "[ BJJSignatureProof2021, Iden3SparseMerkleTreeProof]" + example: "BJJSignatureProof2021" enum: [ BJJSignatureProof2021, Iden3SparseMerkleTreeProof] example: credentialSchema: "https://raw.githubusercontent.com/iden3/claim-schema-vocab/main/schemas/json/KYCAgeCredential-v3.json" From bf6679c6bcb44f9982f2665e3bbbdb2b8ed377c3 Mon Sep 17 00:00:00 2001 From: Martin Saporiti Date: Wed, 26 Jun 2024 08:36:51 -0300 Subject: [PATCH 41/52] fix: reuse existing verifiable constants --- api/api.yaml | 4 ++-- internal/api/api.gen.go | 2 +- internal/api/server.go | 7 ++----- 3 files changed, 5 insertions(+), 8 deletions(-) diff --git a/api/api.yaml b/api/api.yaml index 851264fa7..c2554d359 100644 --- a/api/api.yaml +++ b/api/api.yaml @@ -680,8 +680,8 @@ components: items: type: string x-omitempty: false - example: "BJJSignatureProof2021" - enum: [ BJJSignatureProof2021, Iden3SparseMerkleTreeProof] + example: "BJJSignature2021" + enum: [ BJJSignature2021, Iden3SparseMerkleTreeProof] example: credentialSchema: "https://raw.githubusercontent.com/iden3/claim-schema-vocab/main/schemas/json/KYCAgeCredential-v3.json" type: "KYCAgeCredential" diff --git a/internal/api/api.gen.go b/internal/api/api.gen.go index f4196fc3b..86951c7df 100644 --- a/internal/api/api.gen.go +++ b/internal/api/api.gen.go @@ -23,7 +23,7 @@ const ( // Defines values for CreateClaimRequestProofs. const ( - BJJSignatureProof2021 CreateClaimRequestProofs = "BJJSignatureProof2021" + BJJSignature2021 CreateClaimRequestProofs = "BJJSignature2021" Iden3SparseMerkleTreeProof CreateClaimRequestProofs = "Iden3SparseMerkleTreeProof" ) diff --git a/internal/api/server.go b/internal/api/server.go index 72d0ddb94..0b35502e5 100644 --- a/internal/api/server.go +++ b/internal/api/server.go @@ -151,9 +151,6 @@ func (s *Server) CreateIdentity(ctx context.Context, request CreateIdentityReque // CreateClaim is claim creation controller func (s *Server) CreateClaim(ctx context.Context, request CreateClaimRequestObject) (CreateClaimResponseObject, error) { - const BJJSignatureProof2021 = "BJJSignatureProof2021" - const Iden3SparseMerkleTreeProof = "Iden3SparseMerkleTreeProof" - did, err := w3c.ParseDID(request.Identifier) if err != nil { return CreateClaim400JSONResponse{N400JSONResponse{Message: err.Error()}}, nil @@ -169,11 +166,11 @@ func (s *Server) CreateClaim(ctx context.Context, request CreateClaimRequestObje claimRequestProofs.Iden3SparseMerkleTreeProof = true } else { for _, proof := range *request.Body.Proofs { - if string(proof) == BJJSignatureProof2021 { + if string(proof) == string(verifiable.BJJSignatureProofType) { claimRequestProofs.BJJSignatureProof2021 = true continue } - if string(proof) == Iden3SparseMerkleTreeProof { + if string(proof) == string(verifiable.Iden3SparseMerkleTreeProofType) { claimRequestProofs.Iden3SparseMerkleTreeProof = true continue } From 6c462da1f641ee42779e603887a31c339a8bd1eb Mon Sep 17 00:00:00 2001 From: Martin Saporiti Date: Wed, 26 Jun 2024 09:43:02 -0300 Subject: [PATCH 42/52] chore: add more tests --- internal/api/server_test.go | 70 +++++++++++++++++++++++++++++++++++++ 1 file changed, 70 insertions(+) diff --git a/internal/api/server_test.go b/internal/api/server_test.go index aa7e31f71..3c35279bc 100644 --- a/internal/api/server_test.go +++ b/internal/api/server_test.go @@ -476,6 +476,76 @@ func TestServer_CreateClaim(t *testing.T) { createCredentialEventsCount: 1, }, }, + { + name: "Happy path with two proofs", + auth: authOk, + did: did, + body: CreateClaimRequest{ + CredentialSchema: "https://raw.githubusercontent.com/iden3/claim-schema-vocab/main/schemas/json/KYCAgeCredential-v3.json", + Type: "KYCAgeCredential", + CredentialSubject: map[string]any{ + "id": "did:polygonid:polygon:mumbai:2qFDkNkWePjd6URt6kGQX14a7wVKhBZt8bpy7HZJZi", + "birthday": 19960425, + "documentType": 2, + }, + Expiration: common.ToPointer(time.Now().Unix()), + Proofs: &[]CreateClaimRequestProofs{ + "BJJSignature2021", + "Iden3SparseMerkleTreeProof", + }, + }, + expected: expected{ + response: CreateClaim201JSONResponse{}, + httpCode: http.StatusCreated, + createCredentialEventsCount: 1, + }, + }, + { + name: "Happy path with bjjSignature proof", + auth: authOk, + did: did, + body: CreateClaimRequest{ + CredentialSchema: "https://raw.githubusercontent.com/iden3/claim-schema-vocab/main/schemas/json/KYCAgeCredential-v3.json", + Type: "KYCAgeCredential", + CredentialSubject: map[string]any{ + "id": "did:polygonid:polygon:mumbai:2qFDkNkWePjd6URt6kGQX14a7wVKhBZt8bpy7HZJZi", + "birthday": 19960425, + "documentType": 2, + }, + Expiration: common.ToPointer(time.Now().Unix()), + Proofs: &[]CreateClaimRequestProofs{ + "BJJSignature2021", + }, + }, + expected: expected{ + response: CreateClaim201JSONResponse{}, + httpCode: http.StatusCreated, + createCredentialEventsCount: 1, + }, + }, + { + name: "Happy path with Iden3SparseMerkleTreeProof proof", + auth: authOk, + did: did, + body: CreateClaimRequest{ + CredentialSchema: "https://raw.githubusercontent.com/iden3/claim-schema-vocab/main/schemas/json/KYCAgeCredential-v3.json", + Type: "KYCAgeCredential", + CredentialSubject: map[string]any{ + "id": "did:polygonid:polygon:mumbai:2qFDkNkWePjd6URt6kGQX14a7wVKhBZt8bpy7HZJZi", + "birthday": 19960425, + "documentType": 2, + }, + Expiration: common.ToPointer(time.Now().Unix()), + Proofs: &[]CreateClaimRequestProofs{ + "Iden3SparseMerkleTreeProof", + }, + }, + expected: expected{ + response: CreateClaim201JSONResponse{}, + httpCode: http.StatusCreated, + createCredentialEventsCount: 0, + }, + }, { name: "Happy path with ipfs schema", auth: authOk, From 807f2e062520a31e76dca658b3693f5168613a71 Mon Sep 17 00:00:00 2001 From: Martin Saporiti Date: Wed, 26 Jun 2024 10:33:27 -0300 Subject: [PATCH 43/52] chore: improve database migration --- cmd/migrate/main.go | 19 ++++++++++++------- 1 file changed, 12 insertions(+), 7 deletions(-) diff --git a/cmd/migrate/main.go b/cmd/migrate/main.go index 6341b7941..fb63ba12c 100644 --- a/cmd/migrate/main.go +++ b/cmd/migrate/main.go @@ -4,26 +4,31 @@ import ( "context" "os" - "github.com/polygonid/sh-id-platform/internal/config" + "github.com/joho/godotenv" "github.com/polygonid/sh-id-platform/internal/db/schema" "github.com/polygonid/sh-id-platform/internal/log" _ "github.com/lib/pq" ) +const IssuerDatabaseUrl = "ISSUER_DATABASE_URL" + func main() { ctx, cancel := context.WithCancel(context.Background()) defer cancel() - cfg, err := config.Load("") - if err != nil { - log.Error(ctx, "cannot load config", "err", err) + if os.Getenv(IssuerDatabaseUrl) == "" { + err := godotenv.Load(".env-issuer") + if err != nil { + log.Error(ctx, "Error loading .env-issuer file") + } } - log.Config(cfg.Log.Level, cfg.Log.Mode, os.Stdout) - log.Debug(ctx, "database", "url", cfg.Database.URL) + databaseUrl := os.Getenv(IssuerDatabaseUrl) + log.Config(log.LevelDebug, log.LevelDebug, os.Stdout) + log.Debug(ctx, "database", "url", databaseUrl) - if err := schema.Migrate(cfg.Database.URL); err != nil { + if err := schema.Migrate(databaseUrl); err != nil { log.Error(ctx, "error migrating database", "err", err) return } From beff4c3d85e21bbb2bacb73d20808d627f503d5b Mon Sep 17 00:00:00 2001 From: Martin Saporiti Date: Wed, 26 Jun 2024 10:35:48 -0300 Subject: [PATCH 44/52] fix: linter --- cmd/migrate/main.go | 2 ++ 1 file changed, 2 insertions(+) diff --git a/cmd/migrate/main.go b/cmd/migrate/main.go index fb63ba12c..e456a9e3e 100644 --- a/cmd/migrate/main.go +++ b/cmd/migrate/main.go @@ -5,12 +5,14 @@ import ( "os" "github.com/joho/godotenv" + "github.com/polygonid/sh-id-platform/internal/db/schema" "github.com/polygonid/sh-id-platform/internal/log" _ "github.com/lib/pq" ) +// IssuerDatabaseUrl is the environment variable for the issuer database URL const IssuerDatabaseUrl = "ISSUER_DATABASE_URL" func main() { From fd266338a459d6707a85f09754d82caf90b15bb6 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jordi=20Gim=C3=A9nez?= Date: Fri, 28 Jun 2024 18:57:12 +0200 Subject: [PATCH 45/52] feat: Credential VC Id is an URN and not a url (#680) * feat: Return credential ID as URN * chore: linter * chore: Clearest implementation of urn package. --- internal/core/services/claims.go | 20 ++++++------- internal/urn/urn.go | 50 ++++++++++++++++++++++++++++++++ internal/urn/urn_test.go | 36 +++++++++++++++++++++++ 3 files changed, 96 insertions(+), 10 deletions(-) create mode 100644 internal/urn/urn.go create mode 100644 internal/urn/urn_test.go diff --git a/internal/core/services/claims.go b/internal/core/services/claims.go index 243970374..df7c9c283 100644 --- a/internal/core/services/claims.go +++ b/internal/core/services/claims.go @@ -32,6 +32,7 @@ import ( "github.com/polygonid/sh-id-platform/internal/loader" "github.com/polygonid/sh-id-platform/internal/log" "github.com/polygonid/sh-id-platform/internal/repositories" + "github.com/polygonid/sh-id-platform/internal/urn" "github.com/polygonid/sh-id-platform/pkg/credentials/revocation_status" "github.com/polygonid/sh-id-platform/pkg/pubsub" "github.com/polygonid/sh-id-platform/pkg/rand" @@ -652,10 +653,13 @@ func (c *claim) getAgentCredential(ctx context.Context, basicMessage *ports.Agen return nil, fmt.Errorf("invalid credential fetch request body: %w", err) } - claimID, err := uuid.Parse(fetchRequestBody.ID) + claimID, err := urn.UUIDFromURNString(fetchRequestBody.ID) if err != nil { - log.Error(ctx, "wrong claimID in agent request body", "err", err) - return nil, fmt.Errorf("invalid claim ID") + claimID, err = uuid.Parse(fetchRequestBody.ID) + if err != nil { + log.Error(ctx, "wrong claimID in agent request body", "err", err) + return nil, fmt.Errorf("invalid claim ID") + } } claim, err := c.icRepo.GetByIdAndIssuer(ctx, c.storage.Pgx, basicMessage.IssuerDID, claimID) @@ -802,7 +806,7 @@ func (c *claim) newVerifiableCredential(ctx context.Context, claimReq *ports.Cre issuanceDate := time.Now().UTC() return verifiable.W3CCredential{ - ID: c.buildCredentialID(*claimReq.DID, vcID, claimReq.SingleIssuer), + ID: string(c.buildCredentialID(vcID)), Context: credentialCtx, Type: credentialType, Expiration: claimReq.Expiration, @@ -819,10 +823,6 @@ func (c *claim) newVerifiableCredential(ctx context.Context, claimReq *ports.Cre }, nil } -func (c *claim) buildCredentialID(issuerDID w3c.DID, credID uuid.UUID, singleIssuer bool) string { - // TODO: review how to build the credential ID - if singleIssuer { - return fmt.Sprintf("%s/v1/credentials/%s", strings.TrimSuffix(c.host, "/"), credID.String()) - } - return fmt.Sprintf("%s/v1/%s/claims/%s", strings.TrimSuffix(c.host, "/"), issuerDID.String(), credID.String()) +func (c *claim) buildCredentialID(credID uuid.UUID) urn.URN { + return urn.FromUUID(credID) } diff --git a/internal/urn/urn.go b/internal/urn/urn.go new file mode 100644 index 000000000..b6fd782fd --- /dev/null +++ b/internal/urn/urn.go @@ -0,0 +1,50 @@ +package urn + +import ( + "errors" + + "github.com/google/uuid" +) + +// URN represents a Uniform Resource Name. +type URN string + +// FromUUID creates a URN from a UUID. +func FromUUID(uuid uuid.UUID) URN { + return URN("urn:uuid:" + uuid.String()) +} + +// UUID returns the UUID from a URN. It can throw an error to prevent bad constructor calls or urns without uuids +func (u URN) UUID() (uuid.UUID, error) { + if err := u.valid(); err != nil { + return uuid.Nil, err + } + return uuid.Parse(string(u[9:])) +} + +func (u URN) valid() error { + if len(u) < len("urn:uuid:") { + return errors.New("invalid uuid URN length") + } + if u[:9] != "urn:uuid:" { + return errors.New("invalid uuid URN prefix") + } + return nil +} + +// Parse creates a URN from a string. +func Parse(u string) (URN, error) { + if err := URN(u).valid(); err != nil { + return "", err + } + return URN(u), nil +} + +// UUIDFromURNString returns the UUID from a URN string. +func UUIDFromURNString(s string) (uuid.UUID, error) { + urn, err := Parse(s) + if err != nil { + return uuid.Nil, err + } + return urn.UUID() +} diff --git a/internal/urn/urn_test.go b/internal/urn/urn_test.go new file mode 100644 index 000000000..db662452d --- /dev/null +++ b/internal/urn/urn_test.go @@ -0,0 +1,36 @@ +package urn + +import ( + "errors" + "testing" + + "github.com/google/uuid" + "github.com/stretchr/testify/assert" +) + +func TestFromUUID(t *testing.T) { + id := uuid.New() + urn := FromUUID(id) + assert.Equal(t, "urn:uuid:"+id.String(), string(urn)) +} + +func TestUUIDFromURNString(t *testing.T) { + for _, ts := range []struct { + urn string + err error + }{ + {"", errors.New("invalid uuid URN length")}, + {"urn:uuid:", errors.New("invalid UUID length: 0")}, + {"urn:uuid:1234", errors.New("invalid UUID length: 4")}, + {"urn:uuid:123e4567-e89b-12d3-a456-426614174000", nil}, + } { + t.Run(ts.urn, func(t *testing.T) { + u, err := UUIDFromURNString(ts.urn) + if err == nil { + assert.Equal(t, ts.urn[9:], u.String()) + } else { + assert.Equal(t, ts.err.Error(), err.Error()) + } + }) + } +} From 6e3186e9b0a54ccc99eb5a92d0462207fce7223f Mon Sep 17 00:00:00 2001 From: Alex Monso Date: Mon, 1 Jul 2024 19:00:30 +0200 Subject: [PATCH 46/52] Update package-lock --- ui/package-lock.json | 440 ++++++++++++++++++++++--------------------- 1 file changed, 224 insertions(+), 216 deletions(-) diff --git a/ui/package-lock.json b/ui/package-lock.json index 5a1123beb..d9642c5e0 100644 --- a/ui/package-lock.json +++ b/ui/package-lock.json @@ -11,7 +11,7 @@ "ajv": "^8.12.0", "ajv-formats": "^2.1.1", "ajv-formats-draft2019": "^1.6.1", - "antd": "^5.11.1", + "antd": "^5.18.0", "axios": "^1.6.1", "copy-to-clipboard": "^3.3.3", "dayjs": "^1.11.10", @@ -75,23 +75,23 @@ } }, "node_modules/@ant-design/colors": { - "version": "7.0.0", - "resolved": "https://registry.npmjs.org/@ant-design/colors/-/colors-7.0.0.tgz", - "integrity": "sha512-iVm/9PfGCbC0dSMBrz7oiEXZaaGH7ceU40OJEfKmyuzR9R5CRimJYPlRiFtMQGQcbNMea/ePcoIebi4ASGYXtg==", + "version": "7.0.2", + "resolved": "https://registry.npmjs.org/@ant-design/colors/-/colors-7.0.2.tgz", + "integrity": "sha512-7KJkhTiPiLHSu+LmMJnehfJ6242OCxSlR3xHVBecYxnMW8MS/878NXct1GqYARyL59fyeFdKRxXTfvR9SnDgJg==", "dependencies": { - "@ctrl/tinycolor": "^3.4.0" + "@ctrl/tinycolor": "^3.6.1" } }, "node_modules/@ant-design/cssinjs": { - "version": "1.17.2", - "resolved": "https://registry.npmjs.org/@ant-design/cssinjs/-/cssinjs-1.17.2.tgz", - "integrity": "sha512-vu7lnfEx4Mf8MPzZxn506Zen3Nt4fRr2uutwvdCuTCN5IiU0lDdQ0tiJ24/rmB8+pefwjluYsbyzbQSbgfJy+A==", + "version": "1.21.0", + "resolved": "https://registry.npmjs.org/@ant-design/cssinjs/-/cssinjs-1.21.0.tgz", + "integrity": "sha512-gIilraPl+9EoKdYxnupxjHB/Q6IHNRjEXszKbDxZdsgv4sAZ9pjkCq8yanDWNvyfjp4leir2OVAJm0vxwKK8YA==", "dependencies": { "@babel/runtime": "^7.11.1", "@emotion/hash": "^0.8.0", "@emotion/unitless": "^0.7.5", "classnames": "^2.3.1", - "csstype": "^3.0.10", + "csstype": "^3.1.3", "rc-util": "^5.35.0", "stylis": "^4.0.13" }, @@ -101,12 +101,12 @@ } }, "node_modules/@ant-design/icons": { - "version": "5.2.6", - "resolved": "https://registry.npmjs.org/@ant-design/icons/-/icons-5.2.6.tgz", - "integrity": "sha512-4wn0WShF43TrggskBJPRqCD0fcHbzTYjnaoskdiJrVHg86yxoZ8ZUqsXvyn4WUqehRiFKnaclOhqk9w4Ui2KVw==", + "version": "5.3.7", + "resolved": "https://registry.npmjs.org/@ant-design/icons/-/icons-5.3.7.tgz", + "integrity": "sha512-bCPXTAg66f5bdccM4TT21SQBDO1Ek2gho9h3nO9DAKXJP4sq+5VBjrQMSxMVXSB3HyEz+cUbHQ5+6ogxCOpaew==", "dependencies": { "@ant-design/colors": "^7.0.0", - "@ant-design/icons-svg": "^4.3.0", + "@ant-design/icons-svg": "^4.4.0", "@babel/runtime": "^7.11.2", "classnames": "^2.2.6", "rc-util": "^5.31.1" @@ -120,14 +120,14 @@ } }, "node_modules/@ant-design/icons-svg": { - "version": "4.3.1", - "resolved": "https://registry.npmjs.org/@ant-design/icons-svg/-/icons-svg-4.3.1.tgz", - "integrity": "sha512-4QBZg8ccyC6LPIRii7A0bZUk3+lEDCLnhB+FVsflGdcWPPmV+j3fire4AwwoqHV/BibgvBmR9ZIo4s867smv+g==" + "version": "4.4.2", + "resolved": "https://registry.npmjs.org/@ant-design/icons-svg/-/icons-svg-4.4.2.tgz", + "integrity": "sha512-vHbT+zJEVzllwP+CM+ul7reTEfBR0vgxFe7+lREAsAA7YGsYpboiq2sQNeQeRvh09GfQgs/GyFEvZpJ9cLXpXA==" }, "node_modules/@ant-design/react-slick": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/@ant-design/react-slick/-/react-slick-1.0.2.tgz", - "integrity": "sha512-Wj8onxL/T8KQLFFiCA4t8eIRGpRR+UPgOdac2sYzonv+i0n3kXHmvHLLiOYL655DQx2Umii9Y9nNgL7ssu5haQ==", + "version": "1.1.2", + "resolved": "https://registry.npmjs.org/@ant-design/react-slick/-/react-slick-1.1.2.tgz", + "integrity": "sha512-EzlvzE6xQUBrZuuhSAFTdsr4P2bBBHGZwKFemEfq8gIGyIQCxalYfZW/T2ORbtQx5rU69o+WycP3exY/7T1hGA==", "dependencies": { "@babel/runtime": "^7.10.4", "classnames": "^2.2.5", @@ -436,9 +436,9 @@ } }, "node_modules/@babel/runtime": { - "version": "7.23.2", - "resolved": "https://registry.npmjs.org/@babel/runtime/-/runtime-7.23.2.tgz", - "integrity": "sha512-mM8eg4yl5D6i3lu2QKPuPH4FArvJ8KhTofbE7jwMUv9KX5mBvwPAqnV3MlyBNqdp9RyRKP6Yck8TrfYrPvX3bg==", + "version": "7.24.7", + "resolved": "https://registry.npmjs.org/@babel/runtime/-/runtime-7.24.7.tgz", + "integrity": "sha512-UwgBRMjJP+xv857DCngvqXI3Iq6J4v0wXmwc6sapg+zyhbwmQX67LUEFrkK5tbyJ30jGuG3ZvWpBiB9LCy1kWw==", "dependencies": { "regenerator-runtime": "^0.14.0" }, @@ -1208,15 +1208,26 @@ "node": ">= 8" } }, + "node_modules/@rc-component/async-validator": { + "version": "5.0.4", + "resolved": "https://registry.npmjs.org/@rc-component/async-validator/-/async-validator-5.0.4.tgz", + "integrity": "sha512-qgGdcVIF604M9EqjNF0hbUTz42bz/RDtxWdWuU5EQe3hi7M8ob54B6B35rOsvX5eSvIHIzT9iH1R3n+hk3CGfg==", + "dependencies": { + "@babel/runtime": "^7.24.4" + }, + "engines": { + "node": ">=14.x" + } + }, "node_modules/@rc-component/color-picker": { - "version": "1.4.1", - "resolved": "https://registry.npmjs.org/@rc-component/color-picker/-/color-picker-1.4.1.tgz", - "integrity": "sha512-vh5EWqnsayZa/JwUznqDaPJz39jznx/YDbyBuVJntv735tKXKwEUZZb2jYEldOg+NKWZwtALjGMrNeGBmqFoEw==", + "version": "1.5.3", + "resolved": "https://registry.npmjs.org/@rc-component/color-picker/-/color-picker-1.5.3.tgz", + "integrity": "sha512-+tGGH3nLmYXTalVe0L8hSZNs73VTP5ueSHwUlDC77KKRaN7G4DS4wcpG5DTDzdcV/Yas+rzA6UGgIyzd8fS4cw==", "dependencies": { - "@babel/runtime": "^7.10.1", - "@ctrl/tinycolor": "^3.6.0", + "@babel/runtime": "^7.23.6", + "@ctrl/tinycolor": "^3.6.1", "classnames": "^2.2.6", - "rc-util": "^5.30.0" + "rc-util": "^5.38.1" }, "peerDependencies": { "react": ">=16.9.0", @@ -1282,13 +1293,13 @@ } }, "node_modules/@rc-component/tour": { - "version": "1.10.0", - "resolved": "https://registry.npmjs.org/@rc-component/tour/-/tour-1.10.0.tgz", - "integrity": "sha512-voV0BKaTJbewB9LLgAHQ7tAGG7rgDkKQkZo82xw2gIk542hY+o7zwoqdN16oHhIKk7eG/xi+mdXrONT62Dt57A==", + "version": "1.15.0", + "resolved": "https://registry.npmjs.org/@rc-component/tour/-/tour-1.15.0.tgz", + "integrity": "sha512-h6hyILDwL+In9GAgRobwRWihLqqsD7Uft3fZGrJ7L4EiyCoxbnNYwzPXDfz7vNDhWeVyvAWQJj9fJCzpI4+b4g==", "dependencies": { "@babel/runtime": "^7.18.0", "@rc-component/portal": "^1.0.0-9", - "@rc-component/trigger": "^1.3.6", + "@rc-component/trigger": "^2.0.0", "classnames": "^2.3.2", "rc-util": "^5.24.4" }, @@ -1301,9 +1312,9 @@ } }, "node_modules/@rc-component/trigger": { - "version": "1.18.2", - "resolved": "https://registry.npmjs.org/@rc-component/trigger/-/trigger-1.18.2.tgz", - "integrity": "sha512-jRLYgFgjLEPq3MvS87fIhcfuywFSRDaDrYw1FLku7Cm4esszvzTbA0JBsyacAyLrK9rF3TiHFcvoEDMzoD3CTA==", + "version": "2.2.0", + "resolved": "https://registry.npmjs.org/@rc-component/trigger/-/trigger-2.2.0.tgz", + "integrity": "sha512-QarBCji02YE9aRFhZgRZmOpXBj0IZutRippsVBv85sxvG4FGk/vRxwAlkn3MS9zK5mwbETd86mAVg2tKqTkdJA==", "dependencies": { "@babel/runtime": "^7.23.2", "@rc-component/portal": "^1.1.0", @@ -2179,56 +2190,56 @@ } }, "node_modules/antd": { - "version": "5.11.1", - "resolved": "https://registry.npmjs.org/antd/-/antd-5.11.1.tgz", - "integrity": "sha512-X7Gk1TtJtM9goTrmTPVserqcP7crtV2TX/pbxgqyHpMZRrnBy0EI3h4ngrW+zsIAW8/iqpgrYsG/NVUel6xkBA==", - "dependencies": { - "@ant-design/colors": "^7.0.0", - "@ant-design/cssinjs": "^1.17.2", - "@ant-design/icons": "^5.2.6", - "@ant-design/react-slick": "~1.0.2", - "@babel/runtime": "^7.18.3", + "version": "5.18.3", + "resolved": "https://registry.npmjs.org/antd/-/antd-5.18.3.tgz", + "integrity": "sha512-Dm3P8HBxoo/DiR/QZLj5Mk+rQZsSXxCCArSZACHGiklkkjW6klzlebAElOUr9NyDeFX7UnQ6LVk7vznXlnjTqQ==", + "dependencies": { + "@ant-design/colors": "^7.0.2", + "@ant-design/cssinjs": "^1.21.0", + "@ant-design/icons": "^5.3.7", + "@ant-design/react-slick": "~1.1.2", + "@babel/runtime": "^7.24.7", "@ctrl/tinycolor": "^3.6.1", - "@rc-component/color-picker": "~1.4.1", + "@rc-component/color-picker": "~1.5.3", "@rc-component/mutate-observer": "^1.1.0", - "@rc-component/tour": "~1.10.0", - "@rc-component/trigger": "^1.18.1", - "classnames": "^2.3.2", + "@rc-component/tour": "~1.15.0", + "@rc-component/trigger": "^2.2.0", + "classnames": "^2.5.1", "copy-to-clipboard": "^3.3.3", - "dayjs": "^1.11.1", + "dayjs": "^1.11.11", "qrcode.react": "^3.1.0", - "rc-cascader": "~3.20.0", - "rc-checkbox": "~3.1.0", - "rc-collapse": "~3.7.1", - "rc-dialog": "~9.3.4", - "rc-drawer": "~6.5.2", - "rc-dropdown": "~4.1.0", - "rc-field-form": "~1.40.0", - "rc-image": "~7.3.2", - "rc-input": "~1.3.5", - "rc-input-number": "~8.4.0", - "rc-mentions": "~2.9.1", - "rc-menu": "~9.12.2", - "rc-motion": "^2.9.0", - "rc-notification": "~5.3.0", - "rc-pagination": "~3.7.0", - "rc-picker": "~3.14.6", - "rc-progress": "~3.5.1", - "rc-rate": "~2.12.0", + "rc-cascader": "~3.26.0", + "rc-checkbox": "~3.3.0", + "rc-collapse": "~3.7.3", + "rc-dialog": "~9.5.2", + "rc-drawer": "~7.2.0", + "rc-dropdown": "~4.2.0", + "rc-field-form": "~2.2.1", + "rc-image": "~7.9.0", + "rc-input": "~1.5.1", + "rc-input-number": "~9.1.0", + "rc-mentions": "~2.14.0", + "rc-menu": "~9.14.0", + "rc-motion": "^2.9.2", + "rc-notification": "~5.6.0", + "rc-pagination": "~4.0.4", + "rc-picker": "~4.5.0", + "rc-progress": "~4.0.0", + "rc-rate": "~2.13.0", "rc-resize-observer": "^1.4.0", - "rc-segmented": "~2.2.2", - "rc-select": "~14.10.0", - "rc-slider": "~10.4.0", + "rc-segmented": "~2.3.0", + "rc-select": "~14.14.0", + "rc-slider": "~10.6.2", "rc-steps": "~6.0.1", "rc-switch": "~4.1.0", - "rc-table": "~7.35.2", - "rc-tabs": "~12.13.1", - "rc-textarea": "~1.5.2", - "rc-tooltip": "~6.1.2", - "rc-tree": "~5.8.2", - "rc-tree-select": "~5.15.0", - "rc-upload": "~4.3.5", - "rc-util": "^5.38.1", + "rc-table": "~7.45.7", + "rc-tabs": "~15.1.1", + "rc-textarea": "~1.7.0", + "rc-tooltip": "~6.2.0", + "rc-tree": "~5.8.8", + "rc-tree-select": "~5.21.0", + "rc-upload": "~4.5.2", + "rc-util": "^5.43.0", "scroll-into-view-if-needed": "^3.1.0", "throttle-debounce": "^5.0.0" }, @@ -2428,11 +2439,6 @@ "node": ">=8" } }, - "node_modules/async-validator": { - "version": "4.2.5", - "resolved": "https://registry.npmjs.org/async-validator/-/async-validator-4.2.5.tgz", - "integrity": "sha512-7HhHjtERjqlNbZtqNqy2rckN/SpOOlmDliet+lP7k+eKZEjPk3DgyeU9lIXLdeLz0uBbbVp+9Qdow9wJWgwwfg==" - }, "node_modules/asynciterator.prototype": { "version": "1.0.0", "resolved": "https://registry.npmjs.org/asynciterator.prototype/-/asynciterator.prototype-1.0.0.tgz", @@ -2737,9 +2743,9 @@ } }, "node_modules/classnames": { - "version": "2.3.2", - "resolved": "https://registry.npmjs.org/classnames/-/classnames-2.3.2.tgz", - "integrity": "sha512-CSbhY4cFEJRe6/GQzIk5qXZ4Jeg5pcsP7b5peFSDpffpe1cqjASH/n9UTjBwOp6XpMSTwQ8Za2K5V02ueA7Tmw==" + "version": "2.5.1", + "resolved": "https://registry.npmjs.org/classnames/-/classnames-2.5.1.tgz", + "integrity": "sha512-saHYOzhIQs6wy2sVxTM6bUDsQO4F50V9RQ22qBpEdCW+I+/Wmke2HOl6lS6dTpdxVhb88/I6+Hs+438c3lfUow==" }, "node_modules/clean-regexp": { "version": "1.0.0", @@ -2932,9 +2938,9 @@ } }, "node_modules/csstype": { - "version": "3.1.2", - "resolved": "https://registry.npmjs.org/csstype/-/csstype-3.1.2.tgz", - "integrity": "sha512-I7K1Uu0MBPzaFKg4nI5Q7Vs2t+3gWWW648spaF+Rg7pI9ds18Ugn+lvg4SHczUdKlHI5LWBXyqfS8+DufyBsgQ==" + "version": "3.1.3", + "resolved": "https://registry.npmjs.org/csstype/-/csstype-3.1.3.tgz", + "integrity": "sha512-M1uQkMl8rQK/szD0LNhtqxIPLpimGm8sOBwU7lLnCpSbTyY3yeU1Vc7l4KT5zT4s/yOxHH5O7tIuuLOCnLADRw==" }, "node_modules/damerau-levenshtein": { "version": "1.0.8", @@ -2943,9 +2949,9 @@ "dev": true }, "node_modules/dayjs": { - "version": "1.11.10", - "resolved": "https://registry.npmjs.org/dayjs/-/dayjs-1.11.10.tgz", - "integrity": "sha512-vjAczensTgRcqDERK0SR2XMwsF/tSvnvlv6VcF2GIhg6Sx4yOIt/irsr1RDJsKiIyBzJDpCoXiWWq28MqH2cnQ==" + "version": "1.11.11", + "resolved": "https://registry.npmjs.org/dayjs/-/dayjs-1.11.11.tgz", + "integrity": "sha512-okzr3f11N6WuqYtZSvm+F776mB41wRZMhKP+hc34YdW+KmtYYK9iqvHSwo2k9FEH3fhGXvOPV6yz2IcSrfRUDg==" }, "node_modules/debug": { "version": "4.3.4", @@ -6556,14 +6562,14 @@ } }, "node_modules/rc-cascader": { - "version": "3.20.0", - "resolved": "https://registry.npmjs.org/rc-cascader/-/rc-cascader-3.20.0.tgz", - "integrity": "sha512-lkT9EEwOcYdjZ/jvhLoXGzprK1sijT3/Tp4BLxQQcHDZkkOzzwYQC9HgmKoJz0K7CukMfgvO9KqHeBdgE+pELw==", + "version": "3.26.0", + "resolved": "https://registry.npmjs.org/rc-cascader/-/rc-cascader-3.26.0.tgz", + "integrity": "sha512-L1dml383TPSJD1I11YwxuVbmqaJY64psZqFp1ETlgl3LEOwDu76Cyl11fw5dmjJhMlUWwM5dECQfqJgfebhUjg==", "dependencies": { "@babel/runtime": "^7.12.5", "array-tree-filter": "^2.1.0", "classnames": "^2.3.1", - "rc-select": "~14.10.0", + "rc-select": "~14.14.0", "rc-tree": "~5.8.1", "rc-util": "^5.37.0" }, @@ -6573,9 +6579,9 @@ } }, "node_modules/rc-checkbox": { - "version": "3.1.0", - "resolved": "https://registry.npmjs.org/rc-checkbox/-/rc-checkbox-3.1.0.tgz", - "integrity": "sha512-PAwpJFnBa3Ei+5pyqMMXdcKYKNBMS+TvSDiLdDnARnMJHC8ESxwPfm4Ao1gJiKtWLdmGfigascnCpwrHFgoOBQ==", + "version": "3.3.0", + "resolved": "https://registry.npmjs.org/rc-checkbox/-/rc-checkbox-3.3.0.tgz", + "integrity": "sha512-Ih3ZaAcoAiFKJjifzwsGiT/f/quIkxJoklW4yKGho14Olulwn8gN7hOBve0/WGDg5o/l/5mL0w7ff7/YGvefVw==", "dependencies": { "@babel/runtime": "^7.10.1", "classnames": "^2.3.2", @@ -6587,9 +6593,9 @@ } }, "node_modules/rc-collapse": { - "version": "3.7.1", - "resolved": "https://registry.npmjs.org/rc-collapse/-/rc-collapse-3.7.1.tgz", - "integrity": "sha512-N/7ejyiTf3XElNJBBpxqnZBUuMsQWEOPjB2QkfNvZ/Ca54eAvJXuOD1EGbCWCk2m7v/MSxku7mRpdeaLOCd4Gg==", + "version": "3.7.3", + "resolved": "https://registry.npmjs.org/rc-collapse/-/rc-collapse-3.7.3.tgz", + "integrity": "sha512-60FJcdTRn0X5sELF18TANwtVi7FtModq649H11mYF1jh83DniMoM4MqY627sEKRCTm4+WXfGDcB7hY5oW6xhyw==", "dependencies": { "@babel/runtime": "^7.10.1", "classnames": "2.x", @@ -6602,9 +6608,9 @@ } }, "node_modules/rc-dialog": { - "version": "9.3.4", - "resolved": "https://registry.npmjs.org/rc-dialog/-/rc-dialog-9.3.4.tgz", - "integrity": "sha512-975X3018GhR+EjZFbxA2Z57SX5rnu0G0/OxFgMMvZK4/hQWEm3MHaNvP4wXpxYDoJsp+xUvVW+GB9CMMCm81jA==", + "version": "9.5.2", + "resolved": "https://registry.npmjs.org/rc-dialog/-/rc-dialog-9.5.2.tgz", + "integrity": "sha512-qVUjc8JukG+j/pNaHVSRa2GO2/KbV2thm7yO4hepQ902eGdYK913sGkwg/fh9yhKYV1ql3BKIN2xnud3rEXAPw==", "dependencies": { "@babel/runtime": "^7.10.1", "@rc-component/portal": "^1.0.0-8", @@ -6618,15 +6624,15 @@ } }, "node_modules/rc-drawer": { - "version": "6.5.2", - "resolved": "https://registry.npmjs.org/rc-drawer/-/rc-drawer-6.5.2.tgz", - "integrity": "sha512-QckxAnQNdhh4vtmKN0ZwDf3iakO83W9eZcSKWYYTDv4qcD2fHhRAZJJ/OE6v2ZlQ2kSqCJX5gYssF4HJFvsEPQ==", + "version": "7.2.0", + "resolved": "https://registry.npmjs.org/rc-drawer/-/rc-drawer-7.2.0.tgz", + "integrity": "sha512-9lOQ7kBekEJRdEpScHvtmEtXnAsy+NGDXiRWc2ZVC7QXAazNVbeT4EraQKYwCME8BJLa8Bxqxvs5swwyOepRwg==", "dependencies": { - "@babel/runtime": "^7.10.1", + "@babel/runtime": "^7.23.9", "@rc-component/portal": "^1.1.1", "classnames": "^2.2.6", "rc-motion": "^2.6.1", - "rc-util": "^5.36.0" + "rc-util": "^5.38.1" }, "peerDependencies": { "react": ">=16.9.0", @@ -6634,12 +6640,12 @@ } }, "node_modules/rc-dropdown": { - "version": "4.1.0", - "resolved": "https://registry.npmjs.org/rc-dropdown/-/rc-dropdown-4.1.0.tgz", - "integrity": "sha512-VZjMunpBdlVzYpEdJSaV7WM7O0jf8uyDjirxXLZRNZ+tAC+NzD3PXPEtliFwGzVwBBdCmGuSqiS9DWcOLxQ9tw==", + "version": "4.2.0", + "resolved": "https://registry.npmjs.org/rc-dropdown/-/rc-dropdown-4.2.0.tgz", + "integrity": "sha512-odM8Ove+gSh0zU27DUj5cG1gNKg7mLWBYzB5E4nNLrLwBmYEgYP43vHKDGOVZcJSVElQBI0+jTQgjnq0NfLjng==", "dependencies": { "@babel/runtime": "^7.18.3", - "@rc-component/trigger": "^1.7.0", + "@rc-component/trigger": "^2.0.0", "classnames": "^2.2.6", "rc-util": "^5.17.0" }, @@ -6649,12 +6655,12 @@ } }, "node_modules/rc-field-form": { - "version": "1.40.0", - "resolved": "https://registry.npmjs.org/rc-field-form/-/rc-field-form-1.40.0.tgz", - "integrity": "sha512-OM3N01X2BYFGJDJcwpk9/BBtlwgveE7eh2SQAKIxVCt9KVWlODYJ9ypTHQdxchfDbeJKJKxMBFXlLAmyvlgPHg==", + "version": "2.2.1", + "resolved": "https://registry.npmjs.org/rc-field-form/-/rc-field-form-2.2.1.tgz", + "integrity": "sha512-uoNqDoR7A4tn4QTSqoWPAzrR7ZwOK5I+vuZ/qdcHtbKx+ZjEsTg7QXm2wk/jalDiSksAQmATxL0T5LJkRREdIA==", "dependencies": { "@babel/runtime": "^7.18.0", - "async-validator": "^4.1.0", + "@rc-component/async-validator": "^5.0.3", "rc-util": "^5.32.2" }, "engines": { @@ -6666,14 +6672,14 @@ } }, "node_modules/rc-image": { - "version": "7.3.2", - "resolved": "https://registry.npmjs.org/rc-image/-/rc-image-7.3.2.tgz", - "integrity": "sha512-ICEF6SWv9YKhDXxy1vrXcmf0TVvEcQWIww5Yg+f+mn7e4oGX7FNP4+FExwMjNO5UHBEuWrigbGhlCgI6yZZ1jg==", + "version": "7.9.0", + "resolved": "https://registry.npmjs.org/rc-image/-/rc-image-7.9.0.tgz", + "integrity": "sha512-l4zqO5E0quuLMCtdKfBgj4Suv8tIS011F5k1zBBlK25iMjjiNHxA0VeTzGFtUZERSA45gvpXDg8/P6qNLjR25g==", "dependencies": { "@babel/runtime": "^7.11.2", "@rc-component/portal": "^1.0.2", "classnames": "^2.2.6", - "rc-dialog": "~9.3.4", + "rc-dialog": "~9.5.2", "rc-motion": "^2.6.2", "rc-util": "^5.34.1" }, @@ -6683,9 +6689,9 @@ } }, "node_modules/rc-input": { - "version": "1.3.6", - "resolved": "https://registry.npmjs.org/rc-input/-/rc-input-1.3.6.tgz", - "integrity": "sha512-/HjTaKi8/Ts4zNbYaB5oWCquxFyFQO4Co1MnMgoCeGJlpe7k8Eir2HN0a0F9IHDmmo+GYiGgPpz7w/d/krzsJA==", + "version": "1.5.1", + "resolved": "https://registry.npmjs.org/rc-input/-/rc-input-1.5.1.tgz", + "integrity": "sha512-+nOzQJDeIfIpNP/SgY45LXSKbuMlp4Yap2y8c+ZpU7XbLmNzUd6+d5/S75sA/52jsVE6S/AkhkkDEAOjIu7i6g==", "dependencies": { "@babel/runtime": "^7.11.1", "classnames": "^2.2.1", @@ -6697,15 +6703,15 @@ } }, "node_modules/rc-input-number": { - "version": "8.4.0", - "resolved": "https://registry.npmjs.org/rc-input-number/-/rc-input-number-8.4.0.tgz", - "integrity": "sha512-B6rziPOLRmeP7kcS5qbdC5hXvvDHYKV4vUxmahevYx2E6crS2bRi0xLDjhJ0E1HtOWo8rTmaE2EBJAkTCZOLdA==", + "version": "9.1.0", + "resolved": "https://registry.npmjs.org/rc-input-number/-/rc-input-number-9.1.0.tgz", + "integrity": "sha512-NqJ6i25Xn/AgYfVxynlevIhX3FuKlMwIFpucGG1h98SlK32wQwDK0zhN9VY32McOmuaqzftduNYWWooWz8pXQA==", "dependencies": { "@babel/runtime": "^7.10.1", "@rc-component/mini-decimal": "^1.0.1", "classnames": "^2.2.5", - "rc-input": "~1.3.5", - "rc-util": "^5.28.0" + "rc-input": "~1.5.0", + "rc-util": "^5.40.1" }, "peerDependencies": { "react": ">=16.9.0", @@ -6713,16 +6719,16 @@ } }, "node_modules/rc-mentions": { - "version": "2.9.1", - "resolved": "https://registry.npmjs.org/rc-mentions/-/rc-mentions-2.9.1.tgz", - "integrity": "sha512-cZuElWr/5Ws0PXx1uxobxfYh4mqUw2FitfabR62YnWgm+WAfDyXZXqZg5DxXW+M1cgVvntrQgDDd9LrihrXzew==", + "version": "2.14.0", + "resolved": "https://registry.npmjs.org/rc-mentions/-/rc-mentions-2.14.0.tgz", + "integrity": "sha512-qKR59FMuF8PK4ZqsbWX3UuA5P1M/snzyqV6Yt3y1DCFbCEdqUGIBgQp6vEfLCO6Z0RoRFlzXtCeSlBTcDDpg1A==", "dependencies": { "@babel/runtime": "^7.22.5", - "@rc-component/trigger": "^1.5.0", + "@rc-component/trigger": "^2.0.0", "classnames": "^2.2.6", - "rc-input": "~1.3.5", - "rc-menu": "~9.12.0", - "rc-textarea": "~1.5.0", + "rc-input": "~1.5.0", + "rc-menu": "~9.14.0", + "rc-textarea": "~1.7.0", "rc-util": "^5.34.1" }, "peerDependencies": { @@ -6731,12 +6737,12 @@ } }, "node_modules/rc-menu": { - "version": "9.12.2", - "resolved": "https://registry.npmjs.org/rc-menu/-/rc-menu-9.12.2.tgz", - "integrity": "sha512-NzloFH2pRUYmQ3S/YbJAvRkgCZaLvq0sRa5rgJtuIHLfPPprNHNyepeSlT64+dbVqI4qRWL44VN0lUCldCbbfg==", + "version": "9.14.1", + "resolved": "https://registry.npmjs.org/rc-menu/-/rc-menu-9.14.1.tgz", + "integrity": "sha512-5wlRb3M8S4yGlWhSoEYJ7ZVRElyScdcpUHxgiLxkeig1tEdyKrnED3B2fhpN0Rrpdp9jyhnmZR/Lwq2fH5VvDQ==", "dependencies": { "@babel/runtime": "^7.10.1", - "@rc-component/trigger": "^1.17.0", + "@rc-component/trigger": "^2.0.0", "classnames": "2.x", "rc-motion": "^2.4.3", "rc-overflow": "^1.3.1", @@ -6748,13 +6754,13 @@ } }, "node_modules/rc-motion": { - "version": "2.9.0", - "resolved": "https://registry.npmjs.org/rc-motion/-/rc-motion-2.9.0.tgz", - "integrity": "sha512-XIU2+xLkdIr1/h6ohPZXyPBMvOmuyFZQ/T0xnawz+Rh+gh4FINcnZmMT5UTIj6hgI0VLDjTaPeRd+smJeSPqiQ==", + "version": "2.9.2", + "resolved": "https://registry.npmjs.org/rc-motion/-/rc-motion-2.9.2.tgz", + "integrity": "sha512-fUAhHKLDdkAXIDLH0GYwof3raS58dtNUmzLF2MeiR8o6n4thNpSDQhOqQzWE4WfFZDCi9VEN8n7tiB7czREcyw==", "dependencies": { "@babel/runtime": "^7.11.1", "classnames": "^2.2.1", - "rc-util": "^5.21.0" + "rc-util": "^5.43.0" }, "peerDependencies": { "react": ">=16.9.0", @@ -6762,9 +6768,9 @@ } }, "node_modules/rc-notification": { - "version": "5.3.0", - "resolved": "https://registry.npmjs.org/rc-notification/-/rc-notification-5.3.0.tgz", - "integrity": "sha512-WCf0uCOkZ3HGfF0p1H4Sgt7aWfipxORWTPp7o6prA3vxwtWhtug3GfpYls1pnBp4WA+j8vGIi5c2/hQRpGzPcQ==", + "version": "5.6.0", + "resolved": "https://registry.npmjs.org/rc-notification/-/rc-notification-5.6.0.tgz", + "integrity": "sha512-TGQW5T7waOxLwgJG7fXcw8l7AQiFOjaZ7ISF5PrU526nunHRNcTMuzKihQHaF4E/h/KfOCDk3Mv8eqzbu2e28w==", "dependencies": { "@babel/runtime": "^7.10.1", "classnames": "2.x", @@ -6795,13 +6801,13 @@ } }, "node_modules/rc-pagination": { - "version": "3.7.0", - "resolved": "https://registry.npmjs.org/rc-pagination/-/rc-pagination-3.7.0.tgz", - "integrity": "sha512-IxSzKapd13L91/195o1TPkKnCNw8gIR25UP1GCW/7c7n/slhld4npu2j2PB9IWjXm4SssaAaSAt2lscYog7wzg==", + "version": "4.0.4", + "resolved": "https://registry.npmjs.org/rc-pagination/-/rc-pagination-4.0.4.tgz", + "integrity": "sha512-GGrLT4NgG6wgJpT/hHIpL9nELv27A1XbSZzECIuQBQTVSf4xGKxWr6I/jhpRPauYEWEbWVw22ObG6tJQqwJqWQ==", "dependencies": { "@babel/runtime": "^7.10.1", - "classnames": "^2.2.1", - "rc-util": "^5.32.2" + "classnames": "^2.3.2", + "rc-util": "^5.38.0" }, "peerDependencies": { "react": ">=16.9.0", @@ -6809,14 +6815,16 @@ } }, "node_modules/rc-picker": { - "version": "3.14.6", - "resolved": "https://registry.npmjs.org/rc-picker/-/rc-picker-3.14.6.tgz", - "integrity": "sha512-AdKKW0AqMwZsKvIpwUWDUnpuGKZVrbxVTZTNjcO+pViGkjC1EBcjMgxVe8tomOEaIHJL5Gd13vS8Rr3zzxWmag==", + "version": "4.5.0", + "resolved": "https://registry.npmjs.org/rc-picker/-/rc-picker-4.5.0.tgz", + "integrity": "sha512-suqz9bzuhBQlf7u+bZd1bJLPzhXpk12w6AjQ9BTPTiFwexVZgUKViG1KNLyfFvW6tCUZZK0HmCCX7JAyM+JnCg==", "dependencies": { "@babel/runtime": "^7.10.1", - "@rc-component/trigger": "^1.5.0", + "@rc-component/trigger": "^2.0.0", "classnames": "^2.2.1", - "rc-util": "^5.30.0" + "rc-overflow": "^1.3.2", + "rc-resize-observer": "^1.4.0", + "rc-util": "^5.38.1" }, "engines": { "node": ">=8.x" @@ -6845,9 +6853,9 @@ } }, "node_modules/rc-progress": { - "version": "3.5.1", - "resolved": "https://registry.npmjs.org/rc-progress/-/rc-progress-3.5.1.tgz", - "integrity": "sha512-V6Amx6SbLRwPin/oD+k1vbPrO8+9Qf8zW1T8A7o83HdNafEVvAxPV5YsgtKFP+Ud5HghLj33zKOcEHrcrUGkfw==", + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/rc-progress/-/rc-progress-4.0.0.tgz", + "integrity": "sha512-oofVMMafOCokIUIBnZLNcOZFsABaUw8PPrf1/y0ZBvKZNpOiu5h4AO9vv11Sw0p4Hb3D0yGWuEattcQGtNJ/aw==", "dependencies": { "@babel/runtime": "^7.10.1", "classnames": "^2.2.6", @@ -6859,9 +6867,9 @@ } }, "node_modules/rc-rate": { - "version": "2.12.0", - "resolved": "https://registry.npmjs.org/rc-rate/-/rc-rate-2.12.0.tgz", - "integrity": "sha512-g092v5iZCdVzbjdn28FzvWebK2IutoVoiTeqoLTj9WM7SjA/gOJIw5/JFZMRyJYYVe1jLAU2UhAfstIpCNRozg==", + "version": "2.13.0", + "resolved": "https://registry.npmjs.org/rc-rate/-/rc-rate-2.13.0.tgz", + "integrity": "sha512-oxvx1Q5k5wD30sjN5tqAyWTvJfLNNJn7Oq3IeS4HxWfAiC4BOXMITNAsw7u/fzdtO4MS8Ki8uRLOzcnEuoQiAw==", "dependencies": { "@babel/runtime": "^7.10.1", "classnames": "^2.2.5", @@ -6891,9 +6899,9 @@ } }, "node_modules/rc-segmented": { - "version": "2.2.2", - "resolved": "https://registry.npmjs.org/rc-segmented/-/rc-segmented-2.2.2.tgz", - "integrity": "sha512-Mq52M96QdHMsNdE/042ibT5vkcGcD5jxKp7HgPC2SRofpia99P5fkfHy1pEaajLMF/kj0+2Lkq1UZRvqzo9mSA==", + "version": "2.3.0", + "resolved": "https://registry.npmjs.org/rc-segmented/-/rc-segmented-2.3.0.tgz", + "integrity": "sha512-I3FtM5Smua/ESXutFfb8gJ8ZPcvFR+qUgeeGFQHBOvRiRKyAk4aBE5nfqrxXx+h8/vn60DQjOt6i4RNtrbOobg==", "dependencies": { "@babel/runtime": "^7.11.1", "classnames": "^2.2.1", @@ -6906,12 +6914,12 @@ } }, "node_modules/rc-select": { - "version": "14.10.0", - "resolved": "https://registry.npmjs.org/rc-select/-/rc-select-14.10.0.tgz", - "integrity": "sha512-TsIJTYafTTapCA32LLNpx/AD6ntepR1TG8jEVx35NiAAWCPymhUfuca8kRcUNd3WIGVMDcMKn9kkphoxEz+6Ag==", + "version": "14.14.0", + "resolved": "https://registry.npmjs.org/rc-select/-/rc-select-14.14.0.tgz", + "integrity": "sha512-Uo2wulrjoPPRLCPd7zlK4ZFVJxlTN//yp1xWP/U+TUOQCyXrT+Duvq/Si5OzVcmQyWAUSbsplc2OwNNhvbOeKQ==", "dependencies": { "@babel/runtime": "^7.10.1", - "@rc-component/trigger": "^1.5.0", + "@rc-component/trigger": "^2.1.1", "classnames": "2.x", "rc-motion": "^2.0.1", "rc-overflow": "^1.3.1", @@ -6927,13 +6935,13 @@ } }, "node_modules/rc-slider": { - "version": "10.4.0", - "resolved": "https://registry.npmjs.org/rc-slider/-/rc-slider-10.4.0.tgz", - "integrity": "sha512-ZlpWjFhOlEf0w4Ng31avFBkXNNBj60NAcTPaIoiCxBkJ29wOtHSPMqv9PZeEoqmx64bpJkgK7kPa47HG4LPzww==", + "version": "10.6.2", + "resolved": "https://registry.npmjs.org/rc-slider/-/rc-slider-10.6.2.tgz", + "integrity": "sha512-FjkoFjyvUQWcBo1F3RgSglky3ar0+qHLM41PlFVYB4Bj3RD8E/Mv7kqMouLFBU+3aFglMzzctAIWRwajEuueSw==", "dependencies": { "@babel/runtime": "^7.10.1", "classnames": "^2.2.5", - "rc-util": "^5.27.0" + "rc-util": "^5.36.0" }, "engines": { "node": ">=8.x" @@ -6975,16 +6983,16 @@ } }, "node_modules/rc-table": { - "version": "7.35.2", - "resolved": "https://registry.npmjs.org/rc-table/-/rc-table-7.35.2.tgz", - "integrity": "sha512-ZLIZdAEdfen21FI21xt2LDg9chQ7gc5Lpy4nkjWKPDgmQMnH0KJ8JQQzrd3zrEN16xzjiVdHHvRmi1RU8BtgYg==", + "version": "7.45.7", + "resolved": "https://registry.npmjs.org/rc-table/-/rc-table-7.45.7.tgz", + "integrity": "sha512-wi9LetBL1t1csxyGkMB2p3mCiMt+NDexMlPbXHvQFmBBAsMxrgNSAPwUci2zDLUq9m8QdWc1Nh8suvrpy9mXrg==", "dependencies": { "@babel/runtime": "^7.10.1", "@rc-component/context": "^1.4.0", "classnames": "^2.2.5", "rc-resize-observer": "^1.1.0", "rc-util": "^5.37.0", - "rc-virtual-list": "^3.11.1" + "rc-virtual-list": "^3.14.2" }, "engines": { "node": ">=8.x" @@ -6995,14 +7003,14 @@ } }, "node_modules/rc-tabs": { - "version": "12.13.1", - "resolved": "https://registry.npmjs.org/rc-tabs/-/rc-tabs-12.13.1.tgz", - "integrity": "sha512-83u3l2QkO0UznCzdBLEk9WnNcT+imtmDmMT993sUUEOGnNQAmqOdev0XjeqrcvsAMe9CDpAWDFd7L/RZw+LVJQ==", + "version": "15.1.1", + "resolved": "https://registry.npmjs.org/rc-tabs/-/rc-tabs-15.1.1.tgz", + "integrity": "sha512-Tc7bJvpEdkWIVCUL7yQrMNBJY3j44NcyWS48jF/UKMXuUlzaXK+Z/pEL5LjGcTadtPvVmNqA40yv7hmr+tCOAw==", "dependencies": { "@babel/runtime": "^7.11.2", "classnames": "2.x", - "rc-dropdown": "~4.1.0", - "rc-menu": "~9.12.0", + "rc-dropdown": "~4.2.0", + "rc-menu": "~9.14.0", "rc-motion": "^2.6.2", "rc-resize-observer": "^1.0.0", "rc-util": "^5.34.1" @@ -7016,13 +7024,13 @@ } }, "node_modules/rc-textarea": { - "version": "1.5.3", - "resolved": "https://registry.npmjs.org/rc-textarea/-/rc-textarea-1.5.3.tgz", - "integrity": "sha512-oH682ghHx++stFNYrosPRBfwsypywrTXpaD0/5Z8MPkUOnyOQUaY9ueL9tMu6BP1LfsuYQ1VLpg5OtshViLNgA==", + "version": "1.7.0", + "resolved": "https://registry.npmjs.org/rc-textarea/-/rc-textarea-1.7.0.tgz", + "integrity": "sha512-UxizYJkWkmxP3zofXgc487QiGyDmhhheDLLjIWbFtDmiru1ls30KpO8odDaPyqNUIy9ugj5djxTEuezIn6t3Jg==", "dependencies": { "@babel/runtime": "^7.10.1", "classnames": "^2.2.1", - "rc-input": "~1.3.5", + "rc-input": "~1.5.0", "rc-resize-observer": "^1.0.0", "rc-util": "^5.27.0" }, @@ -7032,12 +7040,12 @@ } }, "node_modules/rc-tooltip": { - "version": "6.1.2", - "resolved": "https://registry.npmjs.org/rc-tooltip/-/rc-tooltip-6.1.2.tgz", - "integrity": "sha512-89zwvybvCxGJu3+gGF8w5AXd4HHk6hIN7K0vZbkzjilVaEAIWPqc1fcyeUeP71n3VCcw7pTL9LyFupFbrx8gHw==", + "version": "6.2.0", + "resolved": "https://registry.npmjs.org/rc-tooltip/-/rc-tooltip-6.2.0.tgz", + "integrity": "sha512-iS/3iOAvtDh9GIx1ulY7EFUXUtktFccNLsARo3NPgLf0QW9oT0w3dA9cYWlhqAKmD+uriEwdWz1kH0Qs4zk2Aw==", "dependencies": { "@babel/runtime": "^7.11.2", - "@rc-component/trigger": "^1.18.0", + "@rc-component/trigger": "^2.0.0", "classnames": "^2.3.1" }, "peerDependencies": { @@ -7046,9 +7054,9 @@ } }, "node_modules/rc-tree": { - "version": "5.8.2", - "resolved": "https://registry.npmjs.org/rc-tree/-/rc-tree-5.8.2.tgz", - "integrity": "sha512-xH/fcgLHWTLmrSuNphU8XAqV7CdaOQgm4KywlLGNoTMhDAcNR3GVNP6cZzb0GrKmIZ9yae+QLot/cAgUdPRMzg==", + "version": "5.8.8", + "resolved": "https://registry.npmjs.org/rc-tree/-/rc-tree-5.8.8.tgz", + "integrity": "sha512-S+mCMWo91m5AJqjz3PdzKilGgbFm7fFJRFiTDOcoRbD7UfMOPnerXwMworiga0O2XIo383UoWuEfeHs1WOltag==", "dependencies": { "@babel/runtime": "^7.10.1", "classnames": "2.x", @@ -7065,13 +7073,13 @@ } }, "node_modules/rc-tree-select": { - "version": "5.15.0", - "resolved": "https://registry.npmjs.org/rc-tree-select/-/rc-tree-select-5.15.0.tgz", - "integrity": "sha512-YJHfdO6azFnR0/JuNBZLDptGE4/RGfVeHAafUIYcm2T3RBkL1O8aVqiHvwIyLzdK59ry0NLrByd+3TkfpRM+9Q==", + "version": "5.21.0", + "resolved": "https://registry.npmjs.org/rc-tree-select/-/rc-tree-select-5.21.0.tgz", + "integrity": "sha512-w+9qEu6zh0G3wt9N/hzWNSnqYH1i9mH1Nqxo0caxLRRFXF5yZWYmpCDoDTMdQM1Y4z3Q5yj08qyrPH/d4AtumA==", "dependencies": { "@babel/runtime": "^7.10.1", "classnames": "2.x", - "rc-select": "~14.10.0", + "rc-select": "~14.14.0", "rc-tree": "~5.8.1", "rc-util": "^5.16.1" }, @@ -7081,9 +7089,9 @@ } }, "node_modules/rc-upload": { - "version": "4.3.5", - "resolved": "https://registry.npmjs.org/rc-upload/-/rc-upload-4.3.5.tgz", - "integrity": "sha512-EHlKJbhkgFSQHliTj9v/2K5aEuFwfUQgZARzD7AmAPOneZEPiCNF3n6PEWIuqz9h7oq6FuXgdR67sC5BWFxJbA==", + "version": "4.5.2", + "resolved": "https://registry.npmjs.org/rc-upload/-/rc-upload-4.5.2.tgz", + "integrity": "sha512-QO3ne77DwnAPKFn0bA5qJM81QBjQi0e0NHdkvpFyY73Bea2NfITiotqJqVjHgeYPOJu5lLVR32TNGP084aSoXA==", "dependencies": { "@babel/runtime": "^7.18.3", "classnames": "^2.2.5", @@ -7095,9 +7103,9 @@ } }, "node_modules/rc-util": { - "version": "5.38.1", - "resolved": "https://registry.npmjs.org/rc-util/-/rc-util-5.38.1.tgz", - "integrity": "sha512-e4ZMs7q9XqwTuhIK7zBIVFltUtMSjphuPPQXHoHlzRzNdOwUxDejo0Zls5HYaJfRKNURcsS/ceKVULlhjBrxng==", + "version": "5.43.0", + "resolved": "https://registry.npmjs.org/rc-util/-/rc-util-5.43.0.tgz", + "integrity": "sha512-AzC7KKOXFqAdIBqdGWepL9Xn7cm3vnAmjlHqUnoQaTMZYhM4VlXGLkkHHxj/BZ7Td0+SOPKB4RGPboBVKT9htw==", "dependencies": { "@babel/runtime": "^7.18.3", "react-is": "^18.2.0" @@ -7113,9 +7121,9 @@ "integrity": "sha512-xWGDIW6x921xtzPkhiULtthJHoJvBbF3q26fzloPCK0hsvxtPVelvftw3zjbHWSkR2km9Z+4uxbDDK/6Zw9B8w==" }, "node_modules/rc-virtual-list": { - "version": "3.11.3", - "resolved": "https://registry.npmjs.org/rc-virtual-list/-/rc-virtual-list-3.11.3.tgz", - "integrity": "sha512-tu5UtrMk/AXonHwHxUogdXAWynaXsrx1i6dsgg+lOo/KJSF8oBAcprh1z5J3xgnPJD5hXxTL58F8s8onokdt0Q==", + "version": "3.14.5", + "resolved": "https://registry.npmjs.org/rc-virtual-list/-/rc-virtual-list-3.14.5.tgz", + "integrity": "sha512-ZMOnkCLv2wUN8Jz7yI4XiSLa9THlYvf00LuMhb1JlsQCewuU7ydPuHw1rGVPhe9VZYl/5UqODtNd7QKJ2DMGfg==", "dependencies": { "@babel/runtime": "^7.20.0", "classnames": "^2.2.6", @@ -7126,8 +7134,8 @@ "node": ">=8.x" }, "peerDependencies": { - "react": "*", - "react-dom": "*" + "react": ">=16.9.0", + "react-dom": ">=16.9.0" } }, "node_modules/react": { @@ -8547,9 +8555,9 @@ "dev": true }, "node_modules/stylis": { - "version": "4.3.0", - "resolved": "https://registry.npmjs.org/stylis/-/stylis-4.3.0.tgz", - "integrity": "sha512-E87pIogpwUsUwXw7dNyU4QDjdgVMy52m+XEOPEKUn161cCzWjjhPSQhByfd1CcNvrOLnXQ6OnnZDwnJrz/Z4YQ==" + "version": "4.3.2", + "resolved": "https://registry.npmjs.org/stylis/-/stylis-4.3.2.tgz", + "integrity": "sha512-bhtUjWd/z6ltJiQwg0dUfxEJ+W+jdqQd8TbWLWyeIJHlnsqmGLRFFd8e5mA0AZi/zx90smXRlN66YMTcaSFifg==" }, "node_modules/supports-color": { "version": "5.5.0", @@ -8732,9 +8740,9 @@ "dev": true }, "node_modules/throttle-debounce": { - "version": "5.0.0", - "resolved": "https://registry.npmjs.org/throttle-debounce/-/throttle-debounce-5.0.0.tgz", - "integrity": "sha512-2iQTSgkkc1Zyk0MeVrt/3BvuOXYPl/R8Z0U2xxo9rjwNciaHDG3R+Lm6dh4EeUci49DanvBnuqI6jshoQQRGEg==", + "version": "5.0.2", + "resolved": "https://registry.npmjs.org/throttle-debounce/-/throttle-debounce-5.0.2.tgz", + "integrity": "sha512-B71/4oyj61iNH0KeCamLuE2rmKuTO5byTOSVwECM5FA7TiAiAW+UqTKZ9ERueC4qvgSttUhdmq1mXC3kJqGX7A==", "engines": { "node": ">=12.22" } From 5bc8f41cf69ca1ba3055818fc679f4255ad28a59 Mon Sep 17 00:00:00 2001 From: Alex Monso Date: Mon, 1 Jul 2024 19:00:54 +0200 Subject: [PATCH 47/52] Fix PR feedback --- ui/src/components/shared/Explainer.tsx | 5 +++- ui/src/components/shared/SiderMenu.tsx | 4 +-- ui/src/styles/index.scss | 41 +++++++++++++++++++------- ui/src/styles/variables.module.scss | 5 ++-- ui/src/utils/constants.ts | 4 +-- 5 files changed, 41 insertions(+), 18 deletions(-) diff --git a/ui/src/components/shared/Explainer.tsx b/ui/src/components/shared/Explainer.tsx index f1affde97..bbe3bf3cb 100644 --- a/ui/src/components/shared/Explainer.tsx +++ b/ui/src/components/shared/Explainer.tsx @@ -47,7 +47,10 @@ export function Explainer({ {localStorageKey && ( diff --git a/ui/src/components/shared/SiderMenu.tsx b/ui/src/components/shared/SiderMenu.tsx index e6e0ca02d..f1349b7ff 100644 --- a/ui/src/components/shared/SiderMenu.tsx +++ b/ui/src/components/shared/SiderMenu.tsx @@ -136,9 +136,7 @@ export function SiderMenu({ isAsyncTaskDataAvailable(status) && status.data ? ( {ISSUER_STATE} - - Pending actions - + Pending actions ) : ( ISSUER_STATE diff --git a/ui/src/styles/index.scss b/ui/src/styles/index.scss index 36edb56da..9d4a21acc 100644 --- a/ui/src/styles/index.scss +++ b/ui/src/styles/index.scss @@ -32,6 +32,26 @@ } } +.ant-pagination { + .ant-pagination-item { + &.ant-pagination-item-active { + a { + color: $primary-color-dark; + } + + border-color: $primary-color-dark; + } + } + + .ant-pagination-options { + margin-right: 16px; + + .ant-select-selector { + border-color: $border-color; + } + } +} + .ant-card { .ant-card-head-title { .ant-row-space-between { @@ -55,7 +75,7 @@ } &.explainer { - background-color: $primary-color; + background-color: $primary-color-dark; margin-top: 8px; padding-top: 8px; @@ -80,7 +100,7 @@ } &.selected { - border: 1px solid $selected-color; + border: 1px solid $primary-color-dark; background: $success-bg; } @@ -302,37 +322,38 @@ .ant-radio-wrapper .ant-radio-checked .ant-radio-inner { background-color: $success-bg; - border-color: $selected-color; + border-color: $primary-color-dark; } .ant-radio-wrapper .ant-radio-checked .ant-radio-inner::after { - background-color: $selected-color; + background-color: $primary-color-dark; } .ant-checkbox-wrapper { .ant-checkbox-checked .ant-checkbox-inner { - border-color: $selected-color; + border-color: $primary-color-dark; } &:not(.ant-checkbox:not(.ant-checkbox-wrapper-disabled)):hover .ant-checkbox-inner { - border-color: $selected-color; + border-color: $primary-color-dark; } } .ant-checkbox:not(.ant-checkbox-disabled):hover .ant-checkbox-inner { - border-color: $selected-color; + border-color: $primary-color-dark; } .ant-input-number-outlined:hover { - border-color: $selected-color; + border-color: $primary-color-dark; } .ant-input-number .ant-input-number-handler:hover { .ant-input-number-handler-up-inner { - color: $selected-color; + color: $primary-color-dark; } + .ant-input-number-handler-down-inner { - color: $selected-color; + color: $primary-color-dark; } } diff --git a/ui/src/styles/variables.module.scss b/ui/src/styles/variables.module.scss index 66ded2dd5..a7a4680d6 100644 --- a/ui/src/styles/variables.module.scss +++ b/ui/src/styles/variables.module.scss @@ -7,7 +7,7 @@ $divider-color: #eaecf0; $error-bg: #fecfcf; $error-color: #b20808; $primary-bg: #f4ebff; -$primary-color: #9afe5b; +$primary-color: #93f558; $success-bg: #f1ffe5; $success-color: #2f8507; $tag-bg: #f2f4f7; @@ -16,7 +16,7 @@ $tag-color: #344054; $text-color: #131313; $text-color-secondary: #667085; $text-color-warning: #b54708; -$selected-color: #3ab000; +$primary-color-dark: #2f8507; :export { avatarBg: $avatar-bg; @@ -29,6 +29,7 @@ $selected-color: #3ab000; errorColor: $error-color; primaryBg: $primary-bg; primaryColor: $primary-color; + primaryColorDark: $primary-color-dark; successBg: $success-bg; successColor: $success-color; tagBg: $tag-bg; diff --git a/ui/src/utils/constants.ts b/ui/src/utils/constants.ts index 0775114a4..ae04ee5fe 100644 --- a/ui/src/utils/constants.ts +++ b/ui/src/utils/constants.ts @@ -75,14 +75,14 @@ export const SIDER_WIDTH = 320; export const TOAST_NOTIFICATION_TIMEOUT = 6; -export const DOCS_URL = "https://devs.polygonid.com"; +export const DOCS_URL = "https://docs.privado.id"; export const WALLET_APP_STORE_URL = "https://apps.apple.com/us/app/polygon-id/id1629870183"; export const WALLET_PLAY_STORE_URL = "https://play.google.com/store/apps/details?id=com.polygonid.wallet"; -export const IPFS_PUBLIC_GATEWAY_CHECKER_URL = "https://ipfs.github.io/public-gateway-checker/"; +export const IPFS_PUBLIC_GATEWAY_CHECKER_URL = "https://ipfs.github.io/public-gateway-checker"; export const IPFS_CUSTOM_GATEWAY_KEY = "ipfsGatewayUrl"; From 48bb912588c28b470a649e7e91888488223749cf Mon Sep 17 00:00:00 2001 From: Alex Monso Date: Mon, 1 Jul 2024 19:24:29 +0200 Subject: [PATCH 48/52] Revert most overrides by changing the primary color --- ui/src/styles/index.scss | 59 +++-------------------------- ui/src/styles/variables.module.scss | 6 +-- 2 files changed, 9 insertions(+), 56 deletions(-) diff --git a/ui/src/styles/index.scss b/ui/src/styles/index.scss index 9d4a21acc..7d838e3e5 100644 --- a/ui/src/styles/index.scss +++ b/ui/src/styles/index.scss @@ -33,16 +33,6 @@ } .ant-pagination { - .ant-pagination-item { - &.ant-pagination-item-active { - a { - color: $primary-color-dark; - } - - border-color: $primary-color-dark; - } - } - .ant-pagination-options { margin-right: 16px; @@ -75,7 +65,7 @@ } &.explainer { - background-color: $primary-color-dark; + background-color: $primary-color; margin-top: 8px; padding-top: 8px; @@ -100,8 +90,8 @@ } &.selected { - border: 1px solid $primary-color-dark; - background: $success-bg; + border: 1px solid $primary-color; + background: $bg-light; } .ant-card-type-inner { @@ -307,56 +297,19 @@ border: 1px solid #54db06; &:not(:disabled .ant-btn-disable) { + background: $primary-color-light; + &:hover { color: $text-color; } &:active { - border: 1px solid #74f526; color: $text-color; - background: $primary-color; - box-shadow: 0 0 0 4px #dfffc7; + background: $primary-color-light; } } } -.ant-radio-wrapper .ant-radio-checked .ant-radio-inner { - background-color: $success-bg; - border-color: $primary-color-dark; -} - -.ant-radio-wrapper .ant-radio-checked .ant-radio-inner::after { - background-color: $primary-color-dark; -} - -.ant-checkbox-wrapper { - .ant-checkbox-checked .ant-checkbox-inner { - border-color: $primary-color-dark; - } - - &:not(.ant-checkbox:not(.ant-checkbox-wrapper-disabled)):hover .ant-checkbox-inner { - border-color: $primary-color-dark; - } -} - -.ant-checkbox:not(.ant-checkbox-disabled):hover .ant-checkbox-inner { - border-color: $primary-color-dark; -} - -.ant-input-number-outlined:hover { - border-color: $primary-color-dark; -} - -.ant-input-number .ant-input-number-handler:hover { - .ant-input-number-handler-up-inner { - color: $primary-color-dark; - } - - .ant-input-number-handler-down-inner { - color: $primary-color-dark; - } -} - .ant-typography.ant-typography-secondary { color: $text-color-secondary; } diff --git a/ui/src/styles/variables.module.scss b/ui/src/styles/variables.module.scss index a7a4680d6..fd9dcbe11 100644 --- a/ui/src/styles/variables.module.scss +++ b/ui/src/styles/variables.module.scss @@ -7,7 +7,7 @@ $divider-color: #eaecf0; $error-bg: #fecfcf; $error-color: #b20808; $primary-bg: #f4ebff; -$primary-color: #93f558; +$primary-color: #2f8507; $success-bg: #f1ffe5; $success-color: #2f8507; $tag-bg: #f2f4f7; @@ -16,7 +16,7 @@ $tag-color: #344054; $text-color: #131313; $text-color-secondary: #667085; $text-color-warning: #b54708; -$primary-color-dark: #2f8507; +$primary-color-light: #93f558; :export { avatarBg: $avatar-bg; @@ -29,7 +29,7 @@ $primary-color-dark: #2f8507; errorColor: $error-color; primaryBg: $primary-bg; primaryColor: $primary-color; - primaryColorDark: $primary-color-dark; + primaryColorLight: $primary-color-light; successBg: $success-bg; successColor: $success-color; tagBg: $tag-bg; From 5de8586153b2b05cefa0ef6295e1cc0f605f8867 Mon Sep 17 00:00:00 2001 From: Alex Monso Date: Mon, 1 Jul 2024 19:46:42 +0200 Subject: [PATCH 49/52] Fix PR feedback --- ui/src/styles/index.scss | 10 ++++++++++ ui/src/styles/theme.ts | 29 ++++++++++++++--------------- ui/src/styles/variables.module.scss | 2 ++ 3 files changed, 26 insertions(+), 15 deletions(-) diff --git a/ui/src/styles/index.scss b/ui/src/styles/index.scss index 7d838e3e5..63ffca57a 100644 --- a/ui/src/styles/index.scss +++ b/ui/src/styles/index.scss @@ -110,6 +110,14 @@ } } +.ant-select-dropdown { + .rc-virtual-list { + .ant-select-item-option-selected { + background-color: $selected-bg; + } + } +} + .ant-select-selection-search-input { &.hidden-suffix { .ant-input-suffix { @@ -262,6 +270,7 @@ } .ant-tag { + margin-right: auto; padding: 2px 10px; border-radius: 16px; border: 0; @@ -295,6 +304,7 @@ .ant-btn-primary { border: 1px solid #54db06; + box-shadow: none; &:not(:disabled .ant-btn-disable) { background: $primary-color-light; diff --git a/ui/src/styles/theme.ts b/ui/src/styles/theme.ts index a4fe0af00..2ecf87b4a 100644 --- a/ui/src/styles/theme.ts +++ b/ui/src/styles/theme.ts @@ -71,16 +71,15 @@ export const theme: ThemeConfig = { colorPrimaryBg: primaryColor, colorPrimaryHover: "#74F526", controlHeight: 40, - defaultHoverBorderColor: successColor, - defaultHoverColor: successColor, + defaultHoverBorderColor: primaryColor, + defaultHoverColor: primaryColor, paddingContentHorizontal: 16, primaryColor: textColor, }, Card: { - colorBgBase: successColor, + colorBgBase: primaryColor, fontWeightStrong: 500, }, - Checkbox: { borderRadius: 6, colorPrimary: successBg, colorWhite: "#3AB000", size: 20 }, DatePicker: { controlHeight: 40 }, Form: { fontSize: 14 }, Input: { controlHeight: 40 }, @@ -88,29 +87,29 @@ export const theme: ThemeConfig = { Layout: { bodyBg: "white", headerBg: "white", siderBg: "white" }, Menu: { colorBgBase: "transparent", - horizontalItemSelectedColor: successColor, + horizontalItemSelectedColor: primaryColor, itemActiveBg: "transparent", itemBg: "transparent", itemColor: textColorSecondary, itemHoverBg: "white", - itemHoverColor: successColor, + itemHoverColor: primaryColor, itemSelectedBg: successBg, - itemSelectedColor: successColor, + itemSelectedColor: primaryColor, subMenuItemBg: "white", }, Message: { fontSize: 18 }, Radio: { buttonCheckedBg: bgLight, - colorPrimary: successColor, - colorPrimaryHover: successColor, + colorPrimary: primaryColor, + colorPrimaryHover: primaryColor, controlHeight: 40, size: 20, }, - Select: { colorBorder: successColor, controlHeight: 40 }, + Select: { colorBorder: primaryColor, controlHeight: 40 }, Table: { fontSize: 14, fontWeightStrong: 400 }, Tabs: { - colorPrimary: successColor, - itemHoverColor: successColor, + colorPrimary: primaryColor, + itemHoverColor: primaryColor, }, Tag: { colorBgBase: tagBg, @@ -126,9 +125,9 @@ export const theme: ThemeConfig = { colorError: errorColor, colorInfo: tagColor, colorInfoBorder: borderColor, - colorLink: successColor, - colorLinkActive: successColor, - colorLinkHover: successColor, + colorLink: primaryColor, + colorLinkActive: primaryColor, + colorLinkHover: primaryColor, colorPrimary: primaryColor, colorPrimaryText: textColor, colorSuccess: successColor, diff --git a/ui/src/styles/variables.module.scss b/ui/src/styles/variables.module.scss index fd9dcbe11..01b07f5b2 100644 --- a/ui/src/styles/variables.module.scss +++ b/ui/src/styles/variables.module.scss @@ -9,6 +9,7 @@ $error-color: #b20808; $primary-bg: #f4ebff; $primary-color: #2f8507; $success-bg: #f1ffe5; +$selected-bg: #f1ffe5; $success-color: #2f8507; $tag-bg: #f2f4f7; $tag-bg-success: #ecfdf3; @@ -31,6 +32,7 @@ $primary-color-light: #93f558; primaryColor: $primary-color; primaryColorLight: $primary-color-light; successBg: $success-bg; + selectedBg: $selected-bg; successColor: $success-color; tagBg: $tag-bg; tagBgSuccess: $tag-bg-success; From 454fe409638aa3764ddbfbd33266836b6b89fe25 Mon Sep 17 00:00:00 2001 From: Alex Monso Date: Mon, 1 Jul 2024 19:52:27 +0200 Subject: [PATCH 50/52] Remove playwright-report --- ui/playwright-report/index.html | 69 --------------------------------- 1 file changed, 69 deletions(-) delete mode 100644 ui/playwright-report/index.html diff --git a/ui/playwright-report/index.html b/ui/playwright-report/index.html deleted file mode 100644 index cf3961c19..000000000 --- a/ui/playwright-report/index.html +++ /dev/null @@ -1,69 +0,0 @@ - - - - - - - - - Playwright Test Report - - - - -
- - - - \ No newline at end of file From 2505b91856bd8030406cee37631c7acc99f6ff95 Mon Sep 17 00:00:00 2001 From: Alex Monso Date: Mon, 1 Jul 2024 19:57:11 +0200 Subject: [PATCH 51/52] Revert typo --- README.md | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/README.md b/README.md index ba453d12e..e550f6cd5 100644 --- a/README.md +++ b/README.md @@ -20,7 +20,6 @@ Streamline the **Verifiable Credentials issuance** process with the user-friendl --- ## Table of Contents - - [Privado ID Issuer Node](#privado-id-issuer-node) - [Table of Contents](#table-of-contents) - [Quick Start Installation](#quick-start-installation) @@ -229,7 +228,7 @@ This [Quick Start Demo](https://devs.polygonid.com/docs/quick-start-demo/) will * [Schema Builder](https://schema-builder.polygonid.me/) - Create your custom schemas to issue VC. * [Demo Issuer UI](https://user-ui:password-ui@issuer-ui.polygonid.me/) - Test our Issuer Node UI. * [Verifier Demo](https://verifier-demo.polygonid.me/) - Verify your VCs. -* [Poylgon ID Android Mobile App](https://play.google.com/store/apps/details?id=com.polygonid.wallet&hl=en&gl=US) +* [Polygon ID Android Mobile App](https://play.google.com/store/apps/details?id=com.polygonid.wallet&hl=en&gl=US) * [Polygon ID IOS Mobile App](https://apps.apple.com/us/app/polygon-id/id1629870183) * [Marketplace](https://marketplace.polygonid.me/) - Explore credentials submitted by trusted issuers. From 36a50c42faee83f156fe79a638213e667592131b Mon Sep 17 00:00:00 2001 From: Martin Saporiti Date: Wed, 3 Jul 2024 11:51:39 -0300 Subject: [PATCH 52/52] chore: remove unnecessary checking (#683) --- cmd/pending_publisher/main.go | 8 +------- 1 file changed, 1 insertion(+), 7 deletions(-) diff --git a/cmd/pending_publisher/main.go b/cmd/pending_publisher/main.go index 9f6eff001..90c72e555 100644 --- a/cmd/pending_publisher/main.go +++ b/cmd/pending_publisher/main.go @@ -52,7 +52,7 @@ func main() { log.Config(cfg.Log.Level, cfg.Log.Mode, os.Stdout) - if err := cfg.SanitizeAPIUI(ctx); err != nil { + if err := cfg.Sanitize(ctx); err != nil { log.Error(ctx, "there are errors in the configuration that prevent server to start", "err", err) return } @@ -126,12 +126,6 @@ func main() { panic(err) } - err = config.CheckDID(ctx, cfg, vaultCli) - if err != nil { - log.Error(ctx, "cannot initialize did", "err", err) - return - } - identityRepo := repositories.NewIdentity() claimsRepo := repositories.NewClaims() mtRepo := repositories.NewIdentityMerkleTreeRepository()