From 26eac36888361dbe2ac62a2cf70c19b7e3ac0610 Mon Sep 17 00:00:00 2001 From: Pinank Lakhani Date: Thu, 20 Jul 2023 18:54:58 +0530 Subject: [PATCH 01/26] Veracity & Transparency calculation added --- src/routes/private.ts | 170 ++++++++++++++++++++++++++++++++++++++--- src/utils/constants.ts | 3 + 2 files changed, 164 insertions(+), 9 deletions(-) diff --git a/src/routes/private.ts b/src/routes/private.ts index 6a209d7..787c7b1 100644 --- a/src/routes/private.ts +++ b/src/routes/private.ts @@ -1,16 +1,19 @@ +/* eslint-disable no-case-declarations */ +import axios from 'axios' +import crypto, { X509Certificate } from 'crypto' +import { createHash } from 'crypto' +import { Resolver } from 'did-resolver' import express, { Request, Response } from 'express' +import { check, validationResult } from 'express-validator' +import * as he from 'he' import * as jose from 'jose' import jsonld from 'jsonld' -import crypto from 'crypto' -import axios from 'axios' +import typer from 'media-typer' +import web from 'web-did-resolver' + import { Utils } from '../utils/common-functions' import { AppConst, AppMessages } from '../utils/constants' -import { check, validationResult } from 'express-validator' -import * as he from 'he' -import web from 'web-did-resolver' -import { Resolver } from 'did-resolver' -import typer from 'media-typer' -import { createHash } from 'crypto' + // import { PublisherService } from '../utils/service/publisher.service' export const privateRoute = express.Router() @@ -389,7 +392,7 @@ privateRoute.post( case AppConst.VERIFY_POLICIES[1]: //policy2 console.log(`Executing ${policy} policy...`) - let gxComplianceCheck = await verifyGxCompliance(credentialContent, res) + const gxComplianceCheck = await verifyGxCompliance(credentialContent, res) responseObj.gxCompliance = gxComplianceCheck break @@ -552,3 +555,152 @@ async function verifyGxCompliance(credentialContent: any, res: Response) { return signVerify && integrityCheck } + +privateRoute.post( + '/get/trust-index', + check('participant_json_url').not().isEmpty().trim(), + check('so_json_url').not().isEmpty().trim(), + async (req: Request, res: Response): Promise => { + try { + const { participant_json_url: participantUrl, so_json_url: soUrl } = req.body + let veracityResult + try { + veracityResult = await calcVeracity(participantUrl) + } catch (error) { + res.status(500).json({ + error: 'Error', + message: AppMessages.PARTICIPANT_DID_FETCH_FAILED + }) + return + } + const { veracity, certificateDetails } = veracityResult + let transparency = 1 + try { + transparency = await calcTansperency(soUrl) + console.log('transparency :-', transparency) + } catch (error) { + res.status(500).json({ + error: 'Error', + message: AppMessages.SO_SD_FETCH_FAILED + }) + return + } + + const trustIndex = calcTrustIndex(veracity, transparency) + console.log('trustIndex :-', trustIndex) + + res.status(200).json({ + message: 'Success', + data: { + veracity, + transparency, + trustIndex, + certificateDetails + } + }) + } catch (error) { + console.log(error) + res.status(500).json({ + error: (error as Error).message, + message: AppMessages.PARTICIPANT_VC_FOUND_FAILED + }) + } + } +) + +const calcVeracity = async (participantUrl: any) => { + // get the json document of participant + try { + const participantJson = (await axios.get(participantUrl)).data + if (participantJson && participantJson.verifiableCredential.length) { + const participantVC = participantJson.verifiableCredential[0] + const { + id: holderDID, + proof: { participantVM } + } = participantVC + console.log('holderDID :-', holderDID, participantVM) + const ddo = await Utils.getDDOfromDID(holderDID, resolver) + if (!ddo) { + console.log(`❌ DDO not found for given did: '${holderDID}' in proof`) + return { veracity: 1, certificateDetails: null } + } + // const { + // didDocument: { verificationMethod: verificationMethodArray } + // } = ddo + + // for (let i = 0; i < verificationMethodArray.length; i++) { + // if (verificationMethodArray[i].id === participantVM && verificationMethodArray[i].id === 'JsonWebKey2020') { + const x5u = ddo.didDocument.verificationMethod[0].publicKeyJwk.x5u + + // get the SSL certificates from x5u url + const certificates = (await axios.get(x5u)).data as string + // console.log('certificates :- ', certificates) + + const certArray = certificates.match(/-----BEGIN CERTIFICATE-----[\s\S]*?-----END CERTIFICATE-----/g) + let keypairDepth = 1 + if (certArray?.length) { + keypairDepth = certArray?.length + } + + // getting object of a PEM encoded X509 Certificate. + const certificate = new X509Certificate(certificates) + + const certificateDetails = { + issuer: certificate.issuer, + validFrom: certificate.validFrom, + validTo: certificate.validTo, + subject: certificate.subject + } + + const veracity = +(1 / keypairDepth).toFixed(2) //veracity = 1 / sum(len(keychain)) + return { veracity, certificateDetails } + // } + // } + // return 0 + } else { + console.log(`❌ Verifiable Credential array not found in participant vc`) + return { veracity: 1, certificateDetails: null } + } + } catch (error) { + console.log(`❌ Invalid participant vc url`) + return { veracity: 1, certificateDetails: null } + } +} + +/* + Formula: count(properties) / count(mandatoryproperties) + Provided By Mandatory (gx-service-offering:providedBy) + Aggregation Of Mandatory (gx-service-offering:aggreationOf) + Terms and Conditions Mandatory (gx-service-offering:termsAndConditions) + Policy Mandatory (gx-service-offering:policy) + Data Account Export Mandatory (gx-service-offering:dataExport) + Name Optional (gx-service-offering:name) + Depends On Optional (gx-service-offering:dependsOn) + Data Protection Regime Optional (gx-service-offering:dataProtectionRegime) +*/ +async function calcTansperency(soUrl: any) { + const optionalProps = ['gx-service-offering:name', 'gx-service-offering:dependsOn', 'gx-service-offering:dataProtectionRegime'] + const totalMandatoryProps = 5 + let availOptProps = 0 + try { + // get the json document of service offering + const { + selfDescriptionCredential: { credentialSubject } + } = (await axios.get(soUrl)).data + + for (let index = 0; index < optionalProps.length; index++) { + if (credentialSubject[optionalProps[index]]) { + availOptProps++ + } + } + const tansperency = (totalMandatoryProps + availOptProps) / totalMandatoryProps + return tansperency + } catch (error) { + return 0 + } +} + +function calcTrustIndex(veracity: number, transparency: number) { + const trustIndex = (veracity + transparency) / 2 + return trustIndex +} diff --git a/src/utils/constants.ts b/src/utils/constants.ts index 564333d..1822ef0 100644 --- a/src/utils/constants.ts +++ b/src/utils/constants.ts @@ -27,4 +27,7 @@ export class AppMessages { static readonly CERT_VALIDATION_FAILED = 'Certificates verification failed against the Gaia-x Registry' static readonly PUB_KEY_MISMATCH = 'Public Key from did and SSL certificates do not match' static readonly ONLY_JWS2020 = 'Only JsonWebSignature2020 is supported' + static readonly PARTICIPANT_DID_FETCH_FAILED = 'Participant DID fetching failed' + static readonly PARTICIPANT_VC_FOUND_FAILED = 'Participant VC not found' + static readonly SO_SD_FETCH_FAILED = 'Service offering self description fetching failed' } From 04cbf00f018dd99eaade2a18385bdb21391d5d3c Mon Sep 17 00:00:00 2001 From: Pinank Lakhani Date: Fri, 21 Jul 2023 13:07:15 +0530 Subject: [PATCH 02/26] Parsed issuer and subject details added in response --- env-example | 7 --- src/routes/private.ts | 113 ++++++++++++++++++++++++++++-------------- 2 files changed, 75 insertions(+), 45 deletions(-) delete mode 100644 env-example diff --git a/env-example b/env-example deleted file mode 100644 index a8c0618..0000000 --- a/env-example +++ /dev/null @@ -1,7 +0,0 @@ -PORT=8000 -COMPLIANCE_SERVICE="https://compliance.lab.gaia-x.eu/development/api/credential-offers" -REGISTRY_TRUST_ANCHOR_URL="https://registry.lab.gaia-x.eu/main/api/trustAnchor/chain" -KAFKA_BROKERS=broker.com:20186 -SSL_CA="-----BEGIN CERTIFICATE-----\n...\n-----END CERTIFICATE-----" -SSL_CERTIFICATE="-----BEGIN CERTIFICATE-----\n...\n-----END CERTIFICATE-----" -SSL_KEY="-----BEGIN PRIVATE KEY-----\n...\n-----END PRIVATE KEY-----" \ No newline at end of file diff --git a/src/routes/private.ts b/src/routes/private.ts index 787c7b1..320d2c0 100644 --- a/src/routes/private.ts +++ b/src/routes/private.ts @@ -610,61 +610,57 @@ privateRoute.post( const calcVeracity = async (participantUrl: any) => { // get the json document of participant + let veracity = 1 + let certificateDetails = null try { const participantJson = (await axios.get(participantUrl)).data if (participantJson && participantJson.verifiableCredential.length) { const participantVC = participantJson.verifiableCredential[0] const { id: holderDID, - proof: { participantVM } + proof: { verificationMethod: participantVM } } = participantVC - console.log('holderDID :-', holderDID, participantVM) + console.log(`holderDID :-${holderDID} holderDID :- ${participantVM}`) + const ddo = await Utils.getDDOfromDID(holderDID, resolver) if (!ddo) { console.log(`❌ DDO not found for given did: '${holderDID}' in proof`) - return { veracity: 1, certificateDetails: null } - } - // const { - // didDocument: { verificationMethod: verificationMethodArray } - // } = ddo - - // for (let i = 0; i < verificationMethodArray.length; i++) { - // if (verificationMethodArray[i].id === participantVM && verificationMethodArray[i].id === 'JsonWebKey2020') { - const x5u = ddo.didDocument.verificationMethod[0].publicKeyJwk.x5u - - // get the SSL certificates from x5u url - const certificates = (await axios.get(x5u)).data as string - // console.log('certificates :- ', certificates) - - const certArray = certificates.match(/-----BEGIN CERTIFICATE-----[\s\S]*?-----END CERTIFICATE-----/g) - let keypairDepth = 1 - if (certArray?.length) { - keypairDepth = certArray?.length + return { veracity, certificateDetails } } + const { + didDocument: { verificationMethod: verificationMethodArray } + } = ddo - // getting object of a PEM encoded X509 Certificate. - const certificate = new X509Certificate(certificates) + for (const verificationMethod of verificationMethodArray) { + if (verificationMethod.id === participantVM && verificationMethod.type === 'JsonWebKey2020') { + const x5u = ddo.didDocument.verificationMethod[0].publicKeyJwk.x5u - const certificateDetails = { - issuer: certificate.issuer, - validFrom: certificate.validFrom, - validTo: certificate.validTo, - subject: certificate.subject - } + // get the SSL certificates from x5u url + const certificates = (await axios.get(x5u)).data as string + // console.log('certificates :- ', certificates) - const veracity = +(1 / keypairDepth).toFixed(2) //veracity = 1 / sum(len(keychain)) - return { veracity, certificateDetails } - // } - // } - // return 0 + const certArray = certificates.match(/-----BEGIN CERTIFICATE-----[\s\S]*?-----END CERTIFICATE-----/g) + let keypairDepth = 1 + if (certArray?.length) { + keypairDepth = certArray?.length + } + + // getting object of a PEM encoded X509 Certificate. + const certificate = new X509Certificate(certificates) + certificateDetails = parseCertificate(certificate) + + veracity = +(1 / keypairDepth).toFixed(2) //veracity = 1 / sum(len(keychain)) + break + } + console.log(`❌ Participant proof verification method and did verification method id not matched`) + } } else { console.log(`❌ Verifiable Credential array not found in participant vc`) - return { veracity: 1, certificateDetails: null } } } catch (error) { - console.log(`❌ Invalid participant vc url`) - return { veracity: 1, certificateDetails: null } + console.error(`❌ Invalid participant vc url :- error \n`, error) } + return { veracity, certificateDetails } } /* @@ -678,7 +674,7 @@ const calcVeracity = async (participantUrl: any) => { Depends On Optional (gx-service-offering:dependsOn) Data Protection Regime Optional (gx-service-offering:dataProtectionRegime) */ -async function calcTansperency(soUrl: any) { +const calcTansperency = async (soUrl: any) => { const optionalProps = ['gx-service-offering:name', 'gx-service-offering:dependsOn', 'gx-service-offering:dataProtectionRegime'] const totalMandatoryProps = 5 let availOptProps = 0 @@ -700,7 +696,48 @@ async function calcTansperency(soUrl: any) { } } -function calcTrustIndex(veracity: number, transparency: number) { +const calcTrustIndex = (veracity: number, transparency: number) => { const trustIndex = (veracity + transparency) / 2 return trustIndex } + +const parseCertificate = (certificate: X509Certificate) => { + const issuerFieldsString = certificate.issuer + const issuerFieldsArray = issuerFieldsString.split('\n') + + const extractFieldValue = (fieldArray: string[], fieldName: string) => { + const field = fieldArray.find((line: any) => line.startsWith(`${fieldName}=`)) + if (field) { + return field.slice(fieldName.length + 1) + } + return null + } + // Extract individual fields from the subject string + const subjectFieldsString = certificate.subject + const subjectFieldsArray = subjectFieldsString.split('\n') + const certificateDetails = { + validFrom: certificate.validFrom, + validTo: certificate.validTo, + subject: { + jurisdictionCountry: extractFieldValue(subjectFieldsArray, 'jurisdictionC'), + jurisdictionSate: extractFieldValue(subjectFieldsArray, 'jurisdictionST'), + jurisdictionLocality: extractFieldValue(subjectFieldsArray, 'jurisdictionL'), + businessCategory: extractFieldValue(subjectFieldsArray, 'businessCategory'), + serialNumber: extractFieldValue(subjectFieldsArray, 'serialNumber'), + country: extractFieldValue(subjectFieldsArray, 'C'), + state: extractFieldValue(subjectFieldsArray, 'ST'), + locality: extractFieldValue(subjectFieldsArray, 'L'), + organization: extractFieldValue(subjectFieldsArray, 'O'), + commonName: extractFieldValue(subjectFieldsArray, 'CN') + }, + issuer: { + commonName: extractFieldValue(issuerFieldsArray, 'CN'), + organization: extractFieldValue(issuerFieldsArray, 'O'), + organizationalUnit: extractFieldValue(issuerFieldsArray, 'OU'), + locality: extractFieldValue(issuerFieldsArray, 'L'), + state: extractFieldValue(issuerFieldsArray, 'ST'), + country: extractFieldValue(issuerFieldsArray, 'C') + } + } + return certificateDetails +} From c0613c4b2f4d5060f91497ff88339b5e2e9c2f37 Mon Sep 17 00:00:00 2001 From: Ronak Thacker Date: Wed, 26 Jul 2023 13:27:49 +0530 Subject: [PATCH 03/26] gaia-x api new support wip --- src/routes/private.ts | 43 +++++----- src/swagger.json | 146 ++++++++++++++++++++++++++++++---- src/utils/common-functions.ts | 120 ++++++++++++++++++++++++---- 3 files changed, 254 insertions(+), 55 deletions(-) diff --git a/src/routes/private.ts b/src/routes/private.ts index 2bc9e83..f76aa43 100644 --- a/src/routes/private.ts +++ b/src/routes/private.ts @@ -117,39 +117,34 @@ privateRoute.post( let selfDescription: any = null if (templateId === AppConst.LEGAL_PARTICIPANT) { const { legalName, legalRegistrationType, legalRegistrationNumber, headquarterAddress, legalAddress } = req.body.data - selfDescription = Utils.generateLegalPerson(participantURL, didId, legalName, legalRegistrationType, legalRegistrationNumber, headquarterAddress, legalAddress) + selfDescription = Utils.generateLegalPerson(participantURL, didId, legalName, headquarterAddress, legalAddress) + const regVC = (await Utils.generateRegistrationNumber(axios, didId, legalRegistrationType, legalRegistrationNumber)) + const termsVC = await Utils.generateTermsAndConditions(axios, didId) + selfDescription['verifiableCredential'].push(regVC, termsVC) } else if (templateId === AppConst.SERVICE_OFFER) { const data = JSON.parse(he.decode(JSON.stringify(req.body.data))) const serviceComplianceUrl = tenant ? `https://${domain}/${tenant}/${data.fileName}` : `https://${domain}/.well-known/${data.fileName}` selfDescription = Utils.generateServiceOffer(participantURL, didId, serviceComplianceUrl, data) const { selfDescriptionCredential } = (await axios.get(participantURL)).data - selfDescription.verifiableCredential.push(selfDescriptionCredential.verifiableCredential[0]) + for (let index = 0; index < selfDescriptionCredential.verifiableCredential.length; index++) { + const vc = selfDescriptionCredential.verifiableCredential[index]; + selfDescription.verifiableCredential.push(vc) + } } else { res.status(422).json({ error: `Type Not Supported`, message: AppMessages.DID_VALIDATION }) } - const canonizedSD = await Utils.normalize( - jsonld, - // eslint-disable-next-line - selfDescription['verifiableCredential'][0] - ) - const hash = Utils.sha256(crypto, canonizedSD) - console.log(`📈 Hashed canonized SD ${hash}`) - - const privateKey = (await axios.get(he.decode(privateKeyUrl))).data as string - // const privateKey = process.env.PRIVATE_KEY as string - const proof = await Utils.createProof(jose, didId, AppConst.RSA_ALGO, hash, privateKey) - console.log(proof ? '🔒 SD signed successfully' : '❌ SD signing failed') - const x5uURL = tenant ? `https://${domain}/${tenant}/x509CertificateChain.pem` : `https://${domain}/.well-known/x509CertificateChain.pem` - const certificate = (await axios.get(x5uURL)).data as string - const publicKeyJwk = await Utils.generatePublicJWK(jose, AppConst.RSA_ALGO, certificate, x5uURL) - - const verificationResult = await Utils.verify(jose, proof.jws.replace('..', `.${hash}.`), AppConst.RSA_ALGO, publicKeyJwk, hash) - console.log(verificationResult ? '✅ Verification successful' : '❌ Verification failed') - - selfDescription['verifiableCredential'][0].proof = proof + for (let index = 0; index < selfDescription['verifiableCredential'].length; index++) { + const vc = selfDescription['verifiableCredential'][index] + delete selfDescription['verifiableCredential'][index].proof + // if (!selfDescription['verifiableCredential'][index].hasOwnProperty('proof')) { + const proof = await Utils.generateProof(jsonld, he, axios, jose,crypto, vc, privateKeyUrl, didId, domain, tenant, AppConst.RSA_ALGO) + selfDescription['verifiableCredential'][index].proof = proof + // } + } + console.log(JSON.stringify(selfDescription)) const complianceCredential = (await axios.post(process.env.COMPLIANCE_SERVICE as string, selfDescription)).data // const complianceCredential = {} console.log(complianceCredential ? '🔒 SD signed successfully (compliance service)' : '❌ SD signing failed (compliance service)') @@ -168,7 +163,7 @@ privateRoute.post( if (error.response) { // The request was made and the server responded with a status code // that falls out of the range of 2xx - console.log(error.response.data) + console.log(JSON.stringify(error.response.data)) console.log(error.response.status) console.log(error.response.headers) } else if (error.request) { @@ -217,8 +212,6 @@ privateRoute.post( subjectDid, issuerDid, credentialOffer?.legalName, - credentialOffer?.legalRegistrationType, - credentialOffer?.legalRegistrationNumber, credentialOffer?.headquarterAddress, credentialOffer?.legalAddress ) diff --git a/src/swagger.json b/src/swagger.json index e6e72a4..8d4319e 100644 --- a/src/swagger.json +++ b/src/swagger.json @@ -4,7 +4,6 @@ "title": "REST API for SmartSense Gaia-X Signer Tool", "version": "1.0.0" }, - "schemes": ["http"], "servers": [{ "url": "http://localhost:8000/" }], "paths": { "/createWebDID": { @@ -70,14 +69,13 @@ "examples": { "LegalParticipant": { "value": { - "domain": "dev.smartproof.in", - "tenant": "smart", + "domain": "greenworld.proofsense.in", "templateId": "LegalParticipant", "privateKeyUrl": "https://example.com", "data": { - "legalName": "Smart Proof", - "legalRegistrationType": "taxID", - "legalRegistrationNumber": "0762747721", + "legalName": "Green World", + "legalRegistrationType": "vatID", + "legalRegistrationNumber": "FR79537407926", "headquarterAddress": "BE-BRU", "legalAddress": "BE-BRU" } @@ -130,6 +128,122 @@ } } }, + + "/v1/onBoardToGaiaX": { + "post": { + "summary": "On board to Gaia-X v1", + "description": "Generate Legal Person and Service Offer Credentials", + "requestBody": { + "required": true, + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/OnBoardGaiaXSchemaBody" + }, + "examples": { + "LegalParticipant": { + "value": { + "templateId": "LegalParticipant", + "privateKeyUrl": "https://example.com", + "vcs": [ + { + "@context": ["https://registry.lab.gaia-x.eu/development/api/trusted-shape-registry/v1/shapes/jsonld/participant"], + "type": "gx:legalRegistrationNumber", + "id": "did:web:gaia-x.eu:legalRegistrationNumber.json", + "gx:vatID": "FR79537407926" + }, + { + "@context": [ + "https://www.w3.org/2018/credentials/v1", + "https://w3id.org/security/suites/jws-2020/v1", + "https://registry.lab.gaia-x.eu/development/api/trusted-shape-registry/v1/shapes/jsonld/trustframework#" + ], + "type": ["VerifiableCredential"], + "id": "did:web:dev.smartproof.in", + "issuer": "did:web:dev.smartproof.in", + "issuanceDate": "2023-07-12T08:58:07.859Z", + "credentialSubject": { + "type": "gx:LegalParticipant", + "gx:legalName": "Gaia-X European Association for Data and Cloud AISBL", + "gx:legalRegistrationNumber": { + "id": "https://gaia-x.eu/legalRegistrationNumberVC.json" + }, + "gx:headquarterAddress": { + "gx:countrySubdivisionCode": "BE-BRU" + }, + "gx:legalAddress": { + "gx:countrySubdivisionCode": "BE-BRU" + }, + "id": "https://dev.smartproof.in/.well-known/participant.json" + } + }, + { + "@context": [ + "https://www.w3.org/2018/credentials/v1", + "https://w3id.org/security/suites/jws-2020/v1", + "https://registry.lab.gaia-x.eu/development/api/trusted-shape-registry/v1/shapes/jsonld/trustframework#" + ], + "type": ["VerifiableCredential"], + "id": "did:web:dev.smartproof.in", + "issuer": "did:web:dev.smartproof.in", + "issuanceDate": "2023-07-12T09:11:30.604Z", + "credentialSubject": { + "@context": "https://registry.lab.gaia-x.eu/development/api/trusted-shape-registry/v1/shapes/jsonld/trustframework#", + "type": "gx:GaiaXTermsAndConditions", + "id": "https://dev.smartproof.in/.well-known/did.json", + "gx:termsAndConditions": "The PARTICIPANT signing the Self-Description agrees as follows:\n- to update its descriptions about any changes, be it technical, organizational, or legal - especially but not limited to contractual in regards to the indicated attributes present in the descriptions.\n\nThe keypair used to sign Verifiable Credentials will be revoked where Gaia-X Association becomes aware of any inaccurate statements in regards to the claims which result in a non-compliance with the Trust Framework and policy rules defined in the Policy Rules and Labelling Document (PRLD)." + } + } + ] + } + }, + "ServiceOffering": { + "value": { + "domain": "dev.smartproof.in", + "tenant": "smart", + "templateId": "ServiceOffering", + "privateKeyUrl": "https://example.com", + "data": { + "name": "AWS S3 Service", + "fileName": "s3Service.json", + "description": "Amazon S3 bucket is a public cloud storage resource.", + "policyUrl": "https://aws.amazon.com/privacy/?nc1=f_pr", + "termsAndConditionsUrl": "https://aws.amazon.com/service-terms/", + "termsAndConditionsHash": "4f598faf41fb29a44d63ec413730d55fabd2d249f1976fee1c8eec8003d7f539", + "requestType": "API", + "accessType": "digital", + "formatType": "application/json" + } + } + } + } + } + } + }, + "responses": { + "200": { + "description": "Success", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/SuccessSchemaResponse" + } + } + } + }, + "500": { + "description": "Internal server error", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/ErrorSchemaResponse" + } + } + } + } + } + } + }, "/createVC": { "post": { "summary": "Create verifiable credential", @@ -461,9 +575,9 @@ "jws": "eyJhbGciOiJQUzI1NiIsImI2NCI6ZmFsc2UsImNyaXQiOlsiYjY0Il19..IIhb0E7Zhnh6bj9vuBaKoX2UaR9ZB248HwBPq-1RilmJmHzUQR19556b6XdosXl4WNJ8f0GBnACbUSETYsUOVcEe91YAhqQSF7RYl7-flGmtDsbpKtWR8XXCW7WCBQCQ2-LY0l7bvOy1_92YqiL60JQeo-6HAGb7xXwaREfLI2DD5kRLb7dCd3_UXtIRo9_qTawH4BWCxWT8QjUKcBregNd0derLvyaxGEokJacpQs3jUsFMlqfbpxYhmBpBYP6A3I_Wyzu5CtQNSM7FkKbsR8dsbd0jAU1MuMp4JO4TAIdZ1AgjbyF5vQr6ZSsvISRG1V_GVkNlqhaZVpiHwEQGBw" } } - } - }, - "message": "VP created successfully." + }, + "message": "VP created successfully." + } } } } @@ -790,11 +904,11 @@ "properties": { "domain": { "type": "string", - "example": "dev.smartproof.in" + "example": "gaiaxapi.proofsense.in" }, "tenant": { "type": "string", - "example": "smart" + "example": "Hella" }, "templateId": { "type": "string", @@ -814,11 +928,11 @@ "properties": { "issuerDid": { "type": "string", - "example": "did:web:dev.smartproof.in" + "example": "did:web:gaiaxapi.proofsense.in:Hella" }, "subjectDid": { "type": "string", - "example": "did:web:dev.smartproof.in" + "example": "did:web:gaiaxapi.proofsense.in:Hella" }, "templateId": { @@ -835,15 +949,15 @@ "properties": { "legalName": { "type": "string", - "example": "Smart Proof" + "example": "Hella" }, "legalRegistrationType": { "type": "string", - "example": "taxID" + "example": "vatID" }, "legalRegistrationNumber": { "type": "string", - "example": "0762747721" + "example": "FR79537407926" }, "headquarterAddress": { "type": "string", diff --git a/src/utils/common-functions.ts b/src/utils/common-functions.ts index 6a820db..abc4b8e 100644 --- a/src/utils/common-functions.ts +++ b/src/utils/common-functions.ts @@ -30,21 +30,17 @@ namespace CommonFunctions { return did } - generateLegalPerson( - participantURL: string, - didId: string, - legalName: string, - legalRegistrationType: string, - legalRegistrationNumber: string, - headquarterAddress: string, - legalAddress: string - ): object { + generateLegalPerson(participantURL: string, didId: string, legalName: string, headquarterAddress: string, legalAddress: string): object { const selfDescription = { '@context': 'https://www.w3.org/2018/credentials/v1', type: ['VerifiablePresentation'], verifiableCredential: [ { - '@context': ['https://www.w3.org/2018/credentials/v1', 'https://registry.lab.gaia-x.eu/development/api/trusted-shape-registry/v1/shapes/jsonld/trustframework#'], + '@context': [ + 'https://www.w3.org/2018/credentials/v1', + 'https://w3id.org/security/suites/jws-2020/v1', + 'https://registry.lab.gaia-x.eu/development/api/trusted-shape-registry/v1/shapes/jsonld/trustframework#' + ], type: ['VerifiableCredential'], id: didId, issuer: didId, @@ -54,15 +50,14 @@ namespace CommonFunctions { type: 'gx:LegalParticipant', 'gx:legalName': legalName, 'gx:legalRegistrationNumber': { - [`gx:${legalRegistrationType}`]: legalRegistrationNumber + id: 'https://gaia-x.eu/legalRegistrationNumberVC.json' }, 'gx:headquarterAddress': { 'gx:countrySubdivisionCode': headquarterAddress }, 'gx:legalAddress': { 'gx:countrySubdivisionCode': legalAddress - }, - 'gx-terms-and-conditions:gaiaxTermsAndConditions': '70c1d713215f95191a11d38fe2341faed27d19e083917bc8732ca4fea4976700' + } } } ] @@ -70,6 +65,68 @@ namespace CommonFunctions { return selfDescription } + async generateTermsAndConditions(axios: any, didId: string) { + // const { text } = (await axios.get(`${process.env.REGISTRY_TRUST_ANCHOR_URL as string}/termsAndConditions`)).data + const verifiableCredential = { + '@context': [ + 'https://www.w3.org/2018/credentials/v1', + 'https://w3id.org/security/suites/jws-2020/v1', + 'https://registry.lab.gaia-x.eu/development/api/trusted-shape-registry/v1/shapes/jsonld/trustframework#' + ], + type: ['VerifiableCredential'], + issuanceDate: new Date().toISOString(), + credentialSubject: { + '@context': 'https://registry.lab.gaia-x.eu/development/api/trusted-shape-registry/v1/shapes/jsonld/trustframework#', + type: 'gx:GaiaXTermsAndConditions', + // 'gx:termsAndConditions': text, + 'gx:termsAndConditions': "The PARTICIPANT signing the Self-Description agrees as follows:\n- to update its descriptions about any changes, be it technical, organizational, or legal - especially but not limited to contractual in regards to the indicated attributes present in the descriptions.\n\nThe keypair used to sign Verifiable Credentials will be revoked where Gaia-X Association becomes aware of any inaccurate statements in regards to the claims which result in a non-compliance with the Trust Framework and policy rules defined in the Policy Rules and Labelling Document (PRLD).", + id: didId + }, + issuer: didId, + id: didId + } + return verifiableCredential + } + + async generateRegistrationNumber(axios: any, didId: string, legalRegistrationType: string, legalRegistrationNumber: string) { + try { + // const request = { + // '@context': ['https://registry.lab.gaia-x.eu/development/api/trusted-shape-registry/v1/shapes/jsonld/participant'], + // type: 'gx:legalRegistrationNumber', + // id: 'https://gaia-x.eu/legalRegistrationNumberVC.json', + // [`gx:${legalRegistrationType}`]: legalRegistrationNumber + // } + // const regVC = await axios.post(`${process.env.REGISTRATION_SERVICE as string}`, request) + // return regVC.data + + const regVC = { + '@context': ['https://www.w3.org/2018/credentials/v1', 'https://w3id.org/security/suites/jws-2020/v1'], + type: 'VerifiableCredential', + id: 'https://gaia-x.eu/legalRegistrationNumberVC.json', + issuer: didId, + issuanceDate: new Date().toISOString(), + credentialSubject: { + '@context': 'https://registry.lab.gaia-x.eu/development/api/trusted-shape-registry/v1/shapes/jsonld/trustframework#', + type: 'gx:legalRegistrationNumber', + id: 'https://gaia-x.eu/legalRegistrationNumberVC.json', + [`gx:${legalRegistrationType}`]: legalRegistrationNumber, + 'gx:vatID-countryCode': 'BE' + }, + evidence: [ + { + 'gx:evidenceURL': 'http://ec.europa.eu/taxation_customs/vies/services/checkVatService', + 'gx:executionDate': new Date().toISOString(), + 'gx:evidenceOf': 'gx:vatID' + } + ] + } + return regVC + } catch (error) { + console.log(`❌ RegistrationNumber failed | Error: ${error}`) + return null + } + } + generateServiceOffer(participantURL: string, didId: string, serviceComplianceUrl: string, data: any): object { const { serviceName, description, policyUrl, termsAndConditionsUrl, termsAndConditionsHash, formatType, accessType, requestType } = data const selfDescription = { @@ -107,6 +164,41 @@ namespace CommonFunctions { return selfDescription } + async generateProof( + jsonld: any, + he: any, + axios: any, + jose: any, + crypto: any, + verifiableCredential: any, + privateKeyUrl: string, + didId: string, + domain: string, + tenant: string, + rsaAlso: string + ) { + const canonizedSD = await this.normalize( + jsonld, + // eslint-disable-next-line + verifiableCredential + ) + const hash = this.sha256(crypto, canonizedSD) + console.log(`📈 Hashed canonized SD ${hash}`) + + // const privateKey = (await axios.get(he.decode(privateKeyUrl))).data as string + const privateKey = process.env.PRIVATE_KEY as string + const proof = await this.createProof(jose, didId, rsaAlso, hash, privateKey) + console.log(proof ? '🔒 SD signed successfully' : '❌ SD signing failed') + const x5uURL = tenant ? `https://${domain}/${tenant}/x509CertificateChain.pem` : `https://${domain}/.well-known/x509CertificateChain.pem` + console.log(x5uURL) + const certificate = (await axios.get(x5uURL)).data as string + const publicKeyJwk = await this.generatePublicJWK(jose, rsaAlso, certificate, x5uURL) + + const verificationResult = await this.verify(jose, proof.jws.replace('..', `.${hash}.`), rsaAlso, publicKeyJwk, hash) + console.log(verificationResult ? '✅ Verification successful' : '❌ Verification failed') + return proof + } + async generatePublicJWK(jose: any, algorithm: string, certificate: string, x5uURL: string): Promise { const x509 = await jose.importX509(certificate, algorithm) const publicKeyJwk = await jose.exportJWK(x509) @@ -200,7 +292,7 @@ namespace CommonFunctions { async validateSslFromRegistry(certificates: any, axios: any) { try { certificates = certificates.replace(/\n/gm, '') || undefined - const registryRes = await axios.post(process.env.REGISTRY_TRUST_ANCHOR_URL as string, { certs: certificates }) + const registryRes = await axios.post(`${process.env.REGISTRY_TRUST_ANCHOR_URL as string}/trustAnchor/chain`, { certs: certificates }) return registryRes.status === 200 } catch (error) { console.log(`❌ Validation from registry failed for certificates | error: ${error}`) From f1b6334b39b7a051cfcb69d71a422d81e7ee7c5b Mon Sep 17 00:00:00 2001 From: Ronak Thacker Date: Thu, 27 Jul 2023 15:07:41 +0530 Subject: [PATCH 04/26] feat: registration number api development done --- src/routes/private.ts | 16 ++++---- src/utils/common-functions.ts | 72 ++++++++++++++++++----------------- 2 files changed, 46 insertions(+), 42 deletions(-) diff --git a/src/routes/private.ts b/src/routes/private.ts index f76aa43..e8c617b 100644 --- a/src/routes/private.ts +++ b/src/routes/private.ts @@ -117,9 +117,11 @@ privateRoute.post( let selfDescription: any = null if (templateId === AppConst.LEGAL_PARTICIPANT) { const { legalName, legalRegistrationType, legalRegistrationNumber, headquarterAddress, legalAddress } = req.body.data - selfDescription = Utils.generateLegalPerson(participantURL, didId, legalName, headquarterAddress, legalAddress) - const regVC = (await Utils.generateRegistrationNumber(axios, didId, legalRegistrationType, legalRegistrationNumber)) - const termsVC = await Utils.generateTermsAndConditions(axios, didId) + const legalRegistrationNumberVCUrl = tenant ? `https://${domain}/${tenant}/legalRegistrationNumberVC.json` : `https://${domain}/.well-known/legalRegistrationNumberVC.json` + selfDescription = Utils.generateLegalPerson(participantURL, didId, legalName, headquarterAddress, legalAddress,legalRegistrationNumberVCUrl) + const regVC = (await Utils.generateRegistrationNumber(axios, didId, legalRegistrationType, legalRegistrationNumber,legalRegistrationNumberVCUrl)) + const tandcsURL = tenant ? `https://${domain}/${tenant}/tandcs.json` : `https://${domain}/.well-known/tandcs.json` + const termsVC = await Utils.generateTermsAndConditions(axios, didId,tandcsURL) selfDescription['verifiableCredential'].push(regVC, termsVC) } else if (templateId === AppConst.SERVICE_OFFER) { const data = JSON.parse(he.decode(JSON.stringify(req.body.data))) @@ -138,11 +140,10 @@ privateRoute.post( } for (let index = 0; index < selfDescription['verifiableCredential'].length; index++) { const vc = selfDescription['verifiableCredential'][index] - delete selfDescription['verifiableCredential'][index].proof - // if (!selfDescription['verifiableCredential'][index].hasOwnProperty('proof')) { + if (!selfDescription['verifiableCredential'][index].hasOwnProperty('proof')) { const proof = await Utils.generateProof(jsonld, he, axios, jose,crypto, vc, privateKeyUrl, didId, domain, tenant, AppConst.RSA_ALGO) selfDescription['verifiableCredential'][index].proof = proof - // } + } } console.log(JSON.stringify(selfDescription)) const complianceCredential = (await axios.post(process.env.COMPLIANCE_SERVICE as string, selfDescription)).data @@ -213,7 +214,8 @@ privateRoute.post( issuerDid, credentialOffer?.legalName, credentialOffer?.headquarterAddress, - credentialOffer?.legalAddress + credentialOffer?.legalAddress, + '' ) } // normalise diff --git a/src/utils/common-functions.ts b/src/utils/common-functions.ts index abc4b8e..301ac96 100644 --- a/src/utils/common-functions.ts +++ b/src/utils/common-functions.ts @@ -30,7 +30,7 @@ namespace CommonFunctions { return did } - generateLegalPerson(participantURL: string, didId: string, legalName: string, headquarterAddress: string, legalAddress: string): object { + generateLegalPerson(participantURL: string, didId: string, legalName: string, headquarterAddress: string, legalAddress: string,legalRegistrationNumberVCUrl:string): object { const selfDescription = { '@context': 'https://www.w3.org/2018/credentials/v1', type: ['VerifiablePresentation'], @@ -50,7 +50,7 @@ namespace CommonFunctions { type: 'gx:LegalParticipant', 'gx:legalName': legalName, 'gx:legalRegistrationNumber': { - id: 'https://gaia-x.eu/legalRegistrationNumberVC.json' + id: legalRegistrationNumberVCUrl }, 'gx:headquarterAddress': { 'gx:countrySubdivisionCode': headquarterAddress @@ -65,7 +65,7 @@ namespace CommonFunctions { return selfDescription } - async generateTermsAndConditions(axios: any, didId: string) { + async generateTermsAndConditions(axios: any, didId: string,tandcsURL:string) { // const { text } = (await axios.get(`${process.env.REGISTRY_TRUST_ANCHOR_URL as string}/termsAndConditions`)).data const verifiableCredential = { '@context': [ @@ -80,7 +80,7 @@ namespace CommonFunctions { type: 'gx:GaiaXTermsAndConditions', // 'gx:termsAndConditions': text, 'gx:termsAndConditions': "The PARTICIPANT signing the Self-Description agrees as follows:\n- to update its descriptions about any changes, be it technical, organizational, or legal - especially but not limited to contractual in regards to the indicated attributes present in the descriptions.\n\nThe keypair used to sign Verifiable Credentials will be revoked where Gaia-X Association becomes aware of any inaccurate statements in regards to the claims which result in a non-compliance with the Trust Framework and policy rules defined in the Policy Rules and Labelling Document (PRLD).", - id: didId + id: tandcsURL }, issuer: didId, id: didId @@ -88,39 +88,41 @@ namespace CommonFunctions { return verifiableCredential } - async generateRegistrationNumber(axios: any, didId: string, legalRegistrationType: string, legalRegistrationNumber: string) { + async generateRegistrationNumber(axios: any, didId: string, legalRegistrationType: string, legalRegistrationNumber: string,legalRegistrationNumberVCUrl:string) { try { - // const request = { - // '@context': ['https://registry.lab.gaia-x.eu/development/api/trusted-shape-registry/v1/shapes/jsonld/participant'], - // type: 'gx:legalRegistrationNumber', - // id: 'https://gaia-x.eu/legalRegistrationNumberVC.json', - // [`gx:${legalRegistrationType}`]: legalRegistrationNumber - // } - // const regVC = await axios.post(`${process.env.REGISTRATION_SERVICE as string}`, request) - // return regVC.data - - const regVC = { - '@context': ['https://www.w3.org/2018/credentials/v1', 'https://w3id.org/security/suites/jws-2020/v1'], - type: 'VerifiableCredential', - id: 'https://gaia-x.eu/legalRegistrationNumberVC.json', - issuer: didId, - issuanceDate: new Date().toISOString(), - credentialSubject: { - '@context': 'https://registry.lab.gaia-x.eu/development/api/trusted-shape-registry/v1/shapes/jsonld/trustframework#', - type: 'gx:legalRegistrationNumber', - id: 'https://gaia-x.eu/legalRegistrationNumberVC.json', - [`gx:${legalRegistrationType}`]: legalRegistrationNumber, - 'gx:vatID-countryCode': 'BE' - }, - evidence: [ - { - 'gx:evidenceURL': 'http://ec.europa.eu/taxation_customs/vies/services/checkVatService', - 'gx:executionDate': new Date().toISOString(), - 'gx:evidenceOf': 'gx:vatID' - } - ] + const request = { + '@context': ['https://registry.lab.gaia-x.eu/development/api/trusted-shape-registry/v1/shapes/jsonld/participant'], + type: 'gx:legalRegistrationNumber', + id: legalRegistrationNumberVCUrl, + [`gx:${legalRegistrationType}`]: legalRegistrationNumber } - return regVC + console.log(request) + const regVC = await axios.post(`${process.env.REGISTRATION_SERVICE as string}?vcid=${legalRegistrationNumberVCUrl}`, request) + console.log(JSON.stringify(regVC.data)) + return regVC.data + + // const regVC = { + // '@context': ['https://www.w3.org/2018/credentials/v1', 'https://w3id.org/security/suites/jws-2020/v1'], + // type: 'VerifiableCredential', + // id: didId, + // issuer: didId, + // issuanceDate: new Date().toISOString(), + // credentialSubject: { + // '@context': 'https://registry.lab.gaia-x.eu/development/api/trusted-shape-registry/v1/shapes/jsonld/trustframework#', + // type: 'gx:legalRegistrationNumber', + // id: legalRegistrationNumberVCUrl, + // [`gx:${legalRegistrationType}`]: legalRegistrationNumber, + // 'gx:vatID-countryCode': 'BE' + // }, + // evidence: [ + // { + // 'gx:evidenceURL': 'http://ec.europa.eu/taxation_customs/vies/services/checkVatService', + // 'gx:executionDate': new Date().toISOString(), + // 'gx:evidenceOf': 'gx:vatID' + // } + // ] + // } + // return regVC } catch (error) { console.log(`❌ RegistrationNumber failed | Error: ${error}`) return null From 75ae36f7cc8487472f8e968de086e955bdf89633 Mon Sep 17 00:00:00 2001 From: Ronak Thacker Date: Thu, 27 Jul 2023 15:19:19 +0530 Subject: [PATCH 05/26] feat: registration number api development done --- src/routes/private.ts | 1 - src/utils/common-functions.ts | 29 +++-------------------------- 2 files changed, 3 insertions(+), 27 deletions(-) diff --git a/src/routes/private.ts b/src/routes/private.ts index e8c617b..985474e 100644 --- a/src/routes/private.ts +++ b/src/routes/private.ts @@ -145,7 +145,6 @@ privateRoute.post( selfDescription['verifiableCredential'][index].proof = proof } } - console.log(JSON.stringify(selfDescription)) const complianceCredential = (await axios.post(process.env.COMPLIANCE_SERVICE as string, selfDescription)).data // const complianceCredential = {} console.log(complianceCredential ? '🔒 SD signed successfully (compliance service)' : '❌ SD signing failed (compliance service)') diff --git a/src/utils/common-functions.ts b/src/utils/common-functions.ts index 301ac96..787850b 100644 --- a/src/utils/common-functions.ts +++ b/src/utils/common-functions.ts @@ -98,31 +98,8 @@ namespace CommonFunctions { } console.log(request) const regVC = await axios.post(`${process.env.REGISTRATION_SERVICE as string}?vcid=${legalRegistrationNumberVCUrl}`, request) - console.log(JSON.stringify(regVC.data)) + // console.log(JSON.stringify(regVC.data)) return regVC.data - - // const regVC = { - // '@context': ['https://www.w3.org/2018/credentials/v1', 'https://w3id.org/security/suites/jws-2020/v1'], - // type: 'VerifiableCredential', - // id: didId, - // issuer: didId, - // issuanceDate: new Date().toISOString(), - // credentialSubject: { - // '@context': 'https://registry.lab.gaia-x.eu/development/api/trusted-shape-registry/v1/shapes/jsonld/trustframework#', - // type: 'gx:legalRegistrationNumber', - // id: legalRegistrationNumberVCUrl, - // [`gx:${legalRegistrationType}`]: legalRegistrationNumber, - // 'gx:vatID-countryCode': 'BE' - // }, - // evidence: [ - // { - // 'gx:evidenceURL': 'http://ec.europa.eu/taxation_customs/vies/services/checkVatService', - // 'gx:executionDate': new Date().toISOString(), - // 'gx:evidenceOf': 'gx:vatID' - // } - // ] - // } - // return regVC } catch (error) { console.log(`❌ RegistrationNumber failed | Error: ${error}`) return null @@ -187,8 +164,8 @@ namespace CommonFunctions { const hash = this.sha256(crypto, canonizedSD) console.log(`📈 Hashed canonized SD ${hash}`) - // const privateKey = (await axios.get(he.decode(privateKeyUrl))).data as string - const privateKey = process.env.PRIVATE_KEY as string + const privateKey = (await axios.get(he.decode(privateKeyUrl))).data as string + // const privateKey = process.env.PRIVATE_KEY as string const proof = await this.createProof(jose, didId, rsaAlso, hash, privateKey) console.log(proof ? '🔒 SD signed successfully' : '❌ SD signing failed') const x5uURL = tenant ? `https://${domain}/${tenant}/x509CertificateChain.pem` : `https://${domain}/.well-known/x509CertificateChain.pem` From af83e40d97e0b382e4ba880ab4a7ca36e3bf7bb3 Mon Sep 17 00:00:00 2001 From: Ronak Thacker Date: Wed, 6 Sep 2023 16:01:36 +0530 Subject: [PATCH 06/26] label level-x support --- src/routes/private.ts | 100 ++- src/swagger.json | 1245 +++++++++++++++++++++++++++++++++ src/utils/common-functions.ts | 84 ++- src/utils/constants.ts | 60 ++ 4 files changed, 1477 insertions(+), 12 deletions(-) diff --git a/src/routes/private.ts b/src/routes/private.ts index 985474e..08ceb26 100644 --- a/src/routes/private.ts +++ b/src/routes/private.ts @@ -117,11 +117,13 @@ privateRoute.post( let selfDescription: any = null if (templateId === AppConst.LEGAL_PARTICIPANT) { const { legalName, legalRegistrationType, legalRegistrationNumber, headquarterAddress, legalAddress } = req.body.data - const legalRegistrationNumberVCUrl = tenant ? `https://${domain}/${tenant}/legalRegistrationNumberVC.json` : `https://${domain}/.well-known/legalRegistrationNumberVC.json` - selfDescription = Utils.generateLegalPerson(participantURL, didId, legalName, headquarterAddress, legalAddress,legalRegistrationNumberVCUrl) - const regVC = (await Utils.generateRegistrationNumber(axios, didId, legalRegistrationType, legalRegistrationNumber,legalRegistrationNumberVCUrl)) + const legalRegistrationNumberVCUrl = tenant + ? `https://${domain}/${tenant}/legalRegistrationNumberVC.json` + : `https://${domain}/.well-known/legalRegistrationNumberVC.json` + selfDescription = Utils.generateLegalPerson(participantURL, didId, legalName, headquarterAddress, legalAddress, legalRegistrationNumberVCUrl) + const regVC = await Utils.generateRegistrationNumber(axios, didId, legalRegistrationType, legalRegistrationNumber, legalRegistrationNumberVCUrl) const tandcsURL = tenant ? `https://${domain}/${tenant}/tandcs.json` : `https://${domain}/.well-known/tandcs.json` - const termsVC = await Utils.generateTermsAndConditions(axios, didId,tandcsURL) + const termsVC = await Utils.generateTermsAndConditions(axios, didId, tandcsURL) selfDescription['verifiableCredential'].push(regVC, termsVC) } else if (templateId === AppConst.SERVICE_OFFER) { const data = JSON.parse(he.decode(JSON.stringify(req.body.data))) @@ -129,8 +131,8 @@ privateRoute.post( selfDescription = Utils.generateServiceOffer(participantURL, didId, serviceComplianceUrl, data) const { selfDescriptionCredential } = (await axios.get(participantURL)).data for (let index = 0; index < selfDescriptionCredential.verifiableCredential.length; index++) { - const vc = selfDescriptionCredential.verifiableCredential[index]; - selfDescription.verifiableCredential.push(vc) + const vc = selfDescriptionCredential.verifiableCredential[index] + selfDescription.verifiableCredential.push(vc) } } else { res.status(422).json({ @@ -141,7 +143,7 @@ privateRoute.post( for (let index = 0; index < selfDescription['verifiableCredential'].length; index++) { const vc = selfDescription['verifiableCredential'][index] if (!selfDescription['verifiableCredential'][index].hasOwnProperty('proof')) { - const proof = await Utils.generateProof(jsonld, he, axios, jose,crypto, vc, privateKeyUrl, didId, domain, tenant, AppConst.RSA_ALGO) + const proof = await Utils.generateProof(jsonld, he, axios, jose, crypto, vc, privateKeyUrl, didId, domain, tenant, AppConst.RSA_ALGO) selfDescription['verifiableCredential'][index].proof = proof } } @@ -609,6 +611,90 @@ privateRoute.post( } ) +privateRoute.post( + '/label-level', + check('privateKeyUrl').not().isEmpty().trim().escape(), + check('issuer').not().isEmpty().trim().escape(), + check('verificationMethod').not().isEmpty().trim().escape(), + check('vcs.labelLevel').isObject(), + async (req: Request, res: Response): Promise => { + try { + let { privateKeyUrl } = req.body + const { + verificationMethod, + issuer: issuerDID, + vcs: { labelLevel } + } = req.body + // Get DID document of issuer from issuer DID + const ddo = await Utils.getDDOfromDID(issuerDID, resolver) + if (!ddo) { + console.error(__filename, 'LabelLevel', `❌ DDO not found for given did: '${issuerDID}' in proof`) + res.status(400).json({ + error: `DDO not found for given did: '${issuerDID}' in proof`, + message: AppMessages.VP_FAILED + }) + return + } + + const { credentialSubject: labelLevelCS } = labelLevel + if (!labelLevelCS) { + console.error(__filename, 'LabelLevel', 'labelLevelCS') + res.status(400).json({ + error: AppMessages.VP_FAILED, + message: AppMessages.VP_FAILED + }) + return + } + + // Calculate LabelLevel + const labelLevelResult = await Utils.calcLabelLevel(labelLevelCS) + if (labelLevelResult === '') { + console.error(__filename, 'LabelLevel', 'labelLevelResult') + res.status(400).json({ + error: AppMessages.VP_FAILED, + message: AppMessages.VP_FAILED + }) + return + } + labelLevelCS['gx:labelLevel'] = labelLevelResult + console.debug(__filename, 'LabelLevel', '🔒 labelLevel calculated') + + // Extract certificate url from did document + const { x5u } = await Utils.getPublicKeys(ddo.didDocument) + if (!x5u || x5u == '') { + console.error(__filename, 'LabelLevel', 'x5u') + res.status(400).json({ + error: 'x5u', + message: AppMessages.VP_FAILED + }) + return + } + + // Decrypt private key(received in request) from base64 to raw string + // const privateKey = (await axios.get(he.decode(privateKeyUrl))).data as string + const privateKey = process.env.PRIVATE_KEY as string + // Sign service offering self description with private key(received in request) + const proof = await Utils.addProof(jsonld, axios, jose, crypto, labelLevel, privateKey, verificationMethod, AppConst.RSA_ALGO, x5u) + labelLevel.proof = proof + + const completeSD = { + selfDescriptionCredential: labelLevel, + complianceCredential: {} + } + res.status(200).json({ + data: completeSD, + message: AppMessages.VP_SUCCESS + }) + } catch (error) { + console.error(__filename, 'LabelLevel', `❌ ${AppMessages.VP_FAILED}`) + res.status(500).json({ + error: (error as Error).message, + message: AppMessages.VP_FAILED + }) + } + } +) + const calcVeracity = async (participantUrl: any) => { // get the json document of participant let veracity = 1 diff --git a/src/swagger.json b/src/swagger.json index 8d4319e..99ec8ad 100644 --- a/src/swagger.json +++ b/src/swagger.json @@ -846,6 +846,652 @@ } } } + }, + "/label-level": { + "post": { + "summary": "Label level calculation", + "description": "Calculate label level value", + "requestBody": { + "required": true, + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/ComplineLLSchemaBody" + } + } + } + }, + "responses": { + "200": { + "description": "Success", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/SuccessSchemaResponse" + }, + "examples": { + "serviceOffering": { + "summary": "Sign Service offering SD from compliance service", + "value": { + "data": { + "selfDescriptionCredential": { + "@context": [ + "https://www.w3.org/2018/credentials/v1", + "https://w3id.org/security/suites/jws-2020/v1", + "https://registry.lab.gaia-x.eu/development/api/trusted-shape-registry/v1/shapes/jsonld/trustframework#" + ], + "type": [ + "VerifiableCredential" + ], + "id": "https://wizard.lab.gaia-x.eu/api/credentials/2d37wbGvQzbAQ84yRouh2m2vBKkN8s5AfH9Q75HZRCUQmJW7yAVSNKzjJj6gcjE2mDNDUHCichXWdMH3S2c8AaDLm3kXmf5R8DFPWTYo5iRYkn8kvgU3AjMXc2qTbhuMHCpucKGgT1ZMkcHUygZkt11iD3T8VJNKYwsdk4MGoZwdqoFUuTKVcsXVTBA4ofD1Dtqzjavyng5WUpvJf4gRyfGkMvYYuHCgay8TK8Dayt6Rhcs3r2d1gRCg2UV419S9CpWZGwKQNEXdYbaB2eTiNbQ83KMd4mj1oSJgF7LLDZLJtKJbhwLzR3x35QUqEGevRxnRDKoPdHrEZN7r9TVAmvr9rt7Xq8eB4zGMTza59hisEAUaHsmWQNaVDorqFyZgN5bXswMK1irVQ5SVR9osCCRrKUKkntxfakjmSqapPfveMP39vkgTXfEhsfLUZXGwFcpgLpWxWRn1QLnJY11BVymS7DyaSvbSKotNFQxyV6vghfM2Jetw1mLxU5qsQqDYnDYJjPZQSmkwxjX3yenPVCz6N2ox83tj9AuuQrzg5p2iukNdunDd2QCsHaMEtTq9JVLzXtWs2eZbPkxCBEQwoKTGGVhKu5yxZjCtQGc?vcid=tsandcsVC", + "issuer": "did:web:wizard.lab.gaia-x.eu:api:credentials:2d37wbGvQzbAQ84yRouh2m2vBKkN8s5AfH9Q75HZRCUQmJW7yAVSNKzjJj6gcjE2mDNDUHCichXWdMH3S2c8AaDLm3kXmf5R8DFPWTYo5iRYkn8kvgU3AjMXc2qTbhuMHCpucKGgT1ZMkcHUygZkt11iD3T8VJNKYwsdk4MGoZwdqoFUuTKVcsXVTBA4ofD1Dtqzjavyng5WUpvJf4gRyfGkMvYYuHCgay8TK8Dayt6Rhcs3r2d1gRCg2UV419S9CpWZGwKQNEXdYbaB2eTiNbQ83KMd4mj1oSJgF7LLDZLJtKJbhwLzR3x35QUqEGevRxnRDKoPdHrEZN7r9TVAmvr9rt7Xq8eB4zGMTza59hisEAUaHsmWQNaVDorqFyZgN5bXswMK1irVQ5SVR9osCCRrKUKkntxfakjmSqapPfveMP39vkgTXfEhsfLUZXGwFcpgLpWxWRn1QLnJY11BVymS7DyaSvbSKotNFQxyV6vghfM2Jetw1mLxU5qsQqDYnDYJjPZQSmkwxjX3yenPVCz6N2ox83tj9AuuQrzg5p2iukNdunDd2QCsHaMEtTq9JVLzXtWs2eZbPkxCBEQwoKTGGVhKu5yxZjCtQGc", + "issuanceDate": "2023-07-12T09:11:30.604Z", + "credentialSubject": { + "@context": "https://registry.lab.gaia-x.eu/development/api/trusted-shape-registry/v1/shapes/jsonld/trustframework#", + "type": "gx:ServiceOfferingLabel", + "id": "https://wizard-api.smart-x.smartsenselabs.com/12081064-8878-477e-8092-564a240c69e2/service-offering-label-level.json", + "gx:assignedTo": "https://wizard-api.smart-x.smartsenselabs.com/12081064-8878-477e-8092-564a240c69e2/service_hYfy.json", + "gx:criteria": { + "P1.1.1": { + "evidence": { + "website": "", + "pdf": {}, + "vc": {} + }, + "response": "Confirm", + "reason": "" + }, + "P1.1.2": { + "evidence": { + "website": "", + "pdf": {}, + "vc": {} + }, + "response": "Confirm", + "reason": "" + }, + "P1.1.3": { + "evidence": { + "website": "", + "pdf": {}, + "vc": {} + }, + "response": "Confirm", + "reason": "" + }, + "P1.1.4": { + "evidence": { + "website": "", + "pdf": {}, + "vc": {} + }, + "response": "Confirm", + "reason": "" + }, + "P1.2.1": { + "evidence": { + "website": "", + "pdf": {}, + "vc": {} + }, + "response": "Confirm", + "reason": "" + }, + "P1.2.2": { + "evidence": { + "website": "", + "pdf": {}, + "vc": {} + }, + "response": "Confirm", + "reason": "" + }, + "P1.2.3": { + "evidence": { + "website": "", + "pdf": {}, + "vc": {} + }, + "response": "Confirm", + "reason": "" + }, + "P1.2.4": { + "evidence": { + "website": "", + "pdf": {}, + "vc": {} + }, + "response": "Confirm", + "reason": "" + }, + "P1.2.5": { + "evidence": { + "website": "", + "pdf": {}, + "vc": {} + }, + "response": "Confirm", + "reason": "" + }, + "P1.2.6": { + "evidence": { + "website": "", + "pdf": {}, + "vc": {} + }, + "response": "Confirm", + "reason": "" + }, + "P1.2.7": { + "evidence": { + "website": "", + "pdf": {}, + "vc": {} + }, + "response": "Confirm", + "reason": "" + }, + "P1.2.8": { + "evidence": { + "website": "", + "pdf": {}, + "vc": {} + }, + "response": "Confirm", + "reason": "" + }, + "P1.2.9": { + "evidence": { + "website": "", + "pdf": {}, + "vc": {} + }, + "response": "Confirm", + "reason": "" + }, + "P1.2.10": { + "evidence": { + "website": "", + "pdf": {}, + "vc": {} + }, + "response": "Confirm", + "reason": "" + }, + "P1.3.1": { + "evidence": { + "website": "", + "pdf": {}, + "vc": {} + }, + "response": "Confirm", + "reason": "" + }, + "P1.3.2": { + "evidence": { + "website": "", + "pdf": {}, + "vc": {} + }, + "response": "Confirm", + "reason": "" + }, + "P1.3.3": { + "evidence": { + "website": "", + "pdf": {}, + "vc": {} + }, + "response": "Confirm", + "reason": "" + }, + "P1.3.4": { + "evidence": { + "website": "", + "pdf": {}, + "vc": {} + }, + "response": "Confirm", + "reason": "" + }, + "P1.3.5": { + "evidence": { + "website": "", + "pdf": {}, + "vc": {} + }, + "response": "Confirm", + "reason": "" + }, + "P2.1.1": { + "evidence": { + "website": "", + "pdf": {}, + "vc": {} + }, + "response": "Confirm", + "reason": "" + }, + "P2.1.2": { + "evidence": { + "website": "", + "pdf": {}, + "vc": {} + }, + "response": "Confirm", + "reason": "" + }, + "P2.1.3": { + "evidence": { + "website": "", + "pdf": {}, + "vc": {} + }, + "response": "Confirm", + "reason": "" + }, + "P2.2.1": { + "evidence": { + "website": "", + "pdf": {}, + "vc": {} + }, + "response": "Confirm", + "reason": "" + }, + "P2.2.2": { + "evidence": { + "website": "", + "pdf": {}, + "vc": {} + }, + "response": "Confirm", + "reason": "" + }, + "P2.2.3": { + "evidence": { + "website": "", + "pdf": {}, + "vc": {} + }, + "response": "Confirm", + "reason": "" + }, + "P2.2.4": { + "evidence": { + "website": "", + "pdf": {}, + "vc": {} + }, + "response": "Confirm", + "reason": "" + }, + "P2.2.5": { + "evidence": { + "website": "", + "pdf": {}, + "vc": {} + }, + "response": "Confirm", + "reason": "" + }, + "P2.2.6": { + "evidence": { + "website": "", + "pdf": {}, + "vc": {} + }, + "response": "Confirm", + "reason": "" + }, + "P2.2.7": { + "evidence": { + "website": "", + "pdf": {}, + "vc": {} + }, + "response": "Confirm", + "reason": "" + }, + "P2.3.1": { + "evidence": { + "website": "", + "pdf": {}, + "vc": {} + }, + "response": "Confirm", + "reason": "" + }, + "P2.3.2": { + "evidence": { + "website": "", + "pdf": {}, + "vc": {} + }, + "response": "Confirm", + "reason": "" + }, + "P2.3.3": { + "evidence": { + "website": "", + "pdf": {}, + "vc": {} + }, + "response": "Confirm", + "reason": "" + }, + "P3.1.1": { + "evidence": { + "website": "", + "pdf": {}, + "vc": {} + }, + "response": "Confirm", + "reason": "" + }, + "P3.1.2": { + "evidence": { + "website": "", + "pdf": {}, + "vc": {} + }, + "response": "Confirm", + "reason": "" + }, + "P3.1.3": { + "evidence": { + "website": "", + "pdf": {}, + "vc": {} + }, + "response": "Confirm", + "reason": "" + }, + "P3.1.4": { + "evidence": { + "website": "", + "pdf": {}, + "vc": {} + }, + "response": "Confirm", + "reason": "" + }, + "P3.1.5": { + "evidence": { + "website": "", + "pdf": {}, + "vc": {} + }, + "response": "Confirm", + "reason": "" + }, + "P3.1.6": { + "evidence": { + "website": "", + "pdf": {}, + "vc": {} + }, + "response": "Confirm", + "reason": "" + }, + "P3.1.7": { + "evidence": { + "website": "", + "pdf": {}, + "vc": {} + }, + "response": "Confirm", + "reason": "" + }, + "P3.1.8": { + "evidence": { + "website": "", + "pdf": {}, + "vc": {} + }, + "response": "Confirm", + "reason": "" + }, + "P3.1.9": { + "evidence": { + "website": "", + "pdf": {}, + "vc": {} + }, + "response": "Confirm", + "reason": "" + }, + "P3.1.10": { + "evidence": { + "website": "", + "pdf": {}, + "vc": {} + }, + "response": "Confirm", + "reason": "" + }, + "P3.1.11": { + "evidence": { + "website": "", + "pdf": {}, + "vc": {} + }, + "response": "Confirm", + "reason": "" + }, + "P3.1.12": { + "evidence": { + "website": "", + "pdf": {}, + "vc": {} + }, + "response": "Confirm", + "reason": "" + }, + "P3.1.13": { + "evidence": { + "website": "", + "pdf": {}, + "vc": {} + }, + "response": "Confirm", + "reason": "" + }, + "P3.1.14": { + "evidence": { + "website": "", + "pdf": {}, + "vc": {} + }, + "response": "Confirm", + "reason": "" + }, + "P3.1.15": { + "evidence": { + "website": "", + "pdf": {}, + "vc": {} + }, + "response": "Confirm", + "reason": "" + }, + "P3.1.16": { + "evidence": { + "website": "", + "pdf": {}, + "vc": {} + }, + "response": "Confirm", + "reason": "" + }, + "P3.1.17": { + "evidence": { + "website": "", + "pdf": {}, + "vc": {} + }, + "response": "Confirm", + "reason": "" + }, + "P3.1.18": { + "evidence": { + "website": "", + "pdf": {}, + "vc": {} + }, + "response": "Confirm", + "reason": "" + }, + "P3.1.19": { + "evidence": { + "website": "", + "pdf": {}, + "vc": {} + }, + "response": "Confirm", + "reason": "" + }, + "P3.1.20": { + "evidence": { + "website": "", + "pdf": {}, + "vc": {} + }, + "response": "Confirm", + "reason": "" + }, + "P4.1.1": { + "evidence": { + "website": "", + "pdf": {}, + "vc": {} + }, + "response": "Confirm", + "reason": "" + }, + "P4.1.2": { + "evidence": { + "website": "", + "pdf": {}, + "vc": {} + }, + "response": "Confirm", + "reason": "" + }, + "P5.1.1": { + "evidence": { + "website": "", + "pdf": {}, + "vc": {} + }, + "response": "Confirm", + "reason": "" + }, + "P5.1.2": { + "evidence": { + "website": "", + "pdf": {}, + "vc": {} + }, + "response": "Confirm", + "reason": "" + }, + "P5.1.3": { + "evidence": { + "website": "", + "pdf": {}, + "vc": {} + }, + "response": "Confirm", + "reason": "" + }, + "P5.1.4": { + "evidence": { + "website": "", + "pdf": {}, + "vc": {} + }, + "response": "Confirm", + "reason": "" + }, + "P5.1.5": { + "evidence": { + "website": "", + "pdf": {}, + "vc": {} + }, + "response": "Confirm", + "reason": "" + }, + "P5.1.6": { + "evidence": { + "website": "", + "pdf": {}, + "vc": {} + }, + "response": "Confirm", + "reason": "" + }, + "P5.1.7": { + "evidence": { + "website": "", + "pdf": {}, + "vc": {} + }, + "response": "Confirm", + "reason": "" + }, + "P5.2.1": { + "evidence": { + "website": "", + "pdf": {}, + "vc": {} + }, + "response": "Confirm", + "reason": "" + } + }, + "gx:labelLevel": "L1" + }, + "proof": { + "type": "JsonWebSignature2020", + "created": "2023-09-06T10:28:46.799Z", + "proofPurpose": "assertionMethod", + "verificationMethod": "did:web:casio34.smart-x.smartsenselabs.com", + "jws": "eyJhbGciOiJQUzI1NiIsImI2NCI6ZmFsc2UsImNyaXQiOlsiYjY0Il19..Ir0jfauSoibBKhNLj_hXqz2LwmpjqipEG4P2HAnPrwBX2uy4MgRc4xP7srZ-WvplKdhR1gqHTn4phxZiZAQbxjcTv2X_6H5Cc60BOhkeYFceMwt3u3s39aQjd5ZXINusbzqZcFIqL-3YVrrta0gZ_Hc5fjLJpyYkAo_wULNcRdoFyy8zdZgRRrONQY_9CMQSijevHESseyhxtd3tfveMhmvBcOvhYXhKyj4gW6Q9y3wq-XrDxD8-7pfWovDAbnJoCJJ62dwk3YgeC4jOgoNufYmYspuuBOGiUo7wdE-m0F9HjNCPL_E-QayieXp51oGC--W6S_pY-s1o-wyulTbRVg" + } + }, + "complianceCredential": {} + }, + "message": "VP created successfully." + } + } + } + } + } + }, + "422": { + "description": "Validation Error", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/ErrorSchemaResponse" + } + } + } + }, + "500": { + "description": "Internal server error", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/ErrorSchemaResponse" + } + } + } + } + } + } } }, "components": { @@ -1079,6 +1725,605 @@ } } } + }, + "ComplineLLSchemaBody": { + "required": ["privateKeyUrl", "issuer", "verificationMethod", "vcs"], + "properties": { + "privateKeyUrl": { + "type": "string", + "example": "https://example.com" + }, + "issuer": { + "type": "string", + "example": "did:web:casio34.smart-x.smartsenselabs.com" + }, + "verificationMethod": { + "type": "string", + "example": "did:web:casio34.smart-x.smartsenselabs.com" + }, + "vcs": { + "type": "object", + "example": { + "labelLevel": { + "@context": [ + "https://www.w3.org/2018/credentials/v1", + "https://w3id.org/security/suites/jws-2020/v1", + "https://registry.lab.gaia-x.eu/development/api/trusted-shape-registry/v1/shapes/jsonld/trustframework#" + ], + "type": ["VerifiableCredential"], + "id": "https://wizard.lab.gaia-x.eu/api/credentials/2d37wbGvQzbAQ84yRouh2m2vBKkN8s5AfH9Q75HZRCUQmJW7yAVSNKzjJj6gcjE2mDNDUHCichXWdMH3S2c8AaDLm3kXmf5R8DFPWTYo5iRYkn8kvgU3AjMXc2qTbhuMHCpucKGgT1ZMkcHUygZkt11iD3T8VJNKYwsdk4MGoZwdqoFUuTKVcsXVTBA4ofD1Dtqzjavyng5WUpvJf4gRyfGkMvYYuHCgay8TK8Dayt6Rhcs3r2d1gRCg2UV419S9CpWZGwKQNEXdYbaB2eTiNbQ83KMd4mj1oSJgF7LLDZLJtKJbhwLzR3x35QUqEGevRxnRDKoPdHrEZN7r9TVAmvr9rt7Xq8eB4zGMTza59hisEAUaHsmWQNaVDorqFyZgN5bXswMK1irVQ5SVR9osCCRrKUKkntxfakjmSqapPfveMP39vkgTXfEhsfLUZXGwFcpgLpWxWRn1QLnJY11BVymS7DyaSvbSKotNFQxyV6vghfM2Jetw1mLxU5qsQqDYnDYJjPZQSmkwxjX3yenPVCz6N2ox83tj9AuuQrzg5p2iukNdunDd2QCsHaMEtTq9JVLzXtWs2eZbPkxCBEQwoKTGGVhKu5yxZjCtQGc?vcid=tsandcsVC", + "issuer": "did:web:wizard.lab.gaia-x.eu:api:credentials:2d37wbGvQzbAQ84yRouh2m2vBKkN8s5AfH9Q75HZRCUQmJW7yAVSNKzjJj6gcjE2mDNDUHCichXWdMH3S2c8AaDLm3kXmf5R8DFPWTYo5iRYkn8kvgU3AjMXc2qTbhuMHCpucKGgT1ZMkcHUygZkt11iD3T8VJNKYwsdk4MGoZwdqoFUuTKVcsXVTBA4ofD1Dtqzjavyng5WUpvJf4gRyfGkMvYYuHCgay8TK8Dayt6Rhcs3r2d1gRCg2UV419S9CpWZGwKQNEXdYbaB2eTiNbQ83KMd4mj1oSJgF7LLDZLJtKJbhwLzR3x35QUqEGevRxnRDKoPdHrEZN7r9TVAmvr9rt7Xq8eB4zGMTza59hisEAUaHsmWQNaVDorqFyZgN5bXswMK1irVQ5SVR9osCCRrKUKkntxfakjmSqapPfveMP39vkgTXfEhsfLUZXGwFcpgLpWxWRn1QLnJY11BVymS7DyaSvbSKotNFQxyV6vghfM2Jetw1mLxU5qsQqDYnDYJjPZQSmkwxjX3yenPVCz6N2ox83tj9AuuQrzg5p2iukNdunDd2QCsHaMEtTq9JVLzXtWs2eZbPkxCBEQwoKTGGVhKu5yxZjCtQGc", + "issuanceDate": "2023-07-12T09:11:30.604Z", + "credentialSubject": { + "@context": "https://registry.lab.gaia-x.eu/development/api/trusted-shape-registry/v1/shapes/jsonld/trustframework#", + "type": "gx:ServiceOfferingLabel", + "id": "https://wizard-api.smart-x.smartsenselabs.com/12081064-8878-477e-8092-564a240c69e2/service-offering-label-level.json", + "gx:assignedTo": "https://wizard-api.smart-x.smartsenselabs.com/12081064-8878-477e-8092-564a240c69e2/service_hYfy.json", + "gx:criteria": { + "P1.1.1": { + "evidence": { + "website": "", + "pdf": {}, + "vc": {} + }, + "response": "Confirm", + "reason": "" + }, + "P1.1.2": { + "evidence": { + "website": "", + "pdf": {}, + "vc": {} + }, + "response": "Confirm", + "reason": "" + }, + "P1.1.3": { + "evidence": { + "website": "", + "pdf": {}, + "vc": {} + }, + "response": "Confirm", + "reason": "" + }, + "P1.1.4": { + "evidence": { + "website": "", + "pdf": {}, + "vc": {} + }, + "response": "Confirm", + "reason": "" + }, + "P1.2.1": { + "evidence": { + "website": "", + "pdf": {}, + "vc": {} + }, + "response": "Confirm", + "reason": "" + }, + "P1.2.2": { + "evidence": { + "website": "", + "pdf": {}, + "vc": {} + }, + "response": "Confirm", + "reason": "" + }, + "P1.2.3": { + "evidence": { + "website": "", + "pdf": {}, + "vc": {} + }, + "response": "Confirm", + "reason": "" + }, + "P1.2.4": { + "evidence": { + "website": "", + "pdf": {}, + "vc": {} + }, + "response": "Confirm", + "reason": "" + }, + "P1.2.5": { + "evidence": { + "website": "", + "pdf": {}, + "vc": {} + }, + "response": "Confirm", + "reason": "" + }, + "P1.2.6": { + "evidence": { + "website": "", + "pdf": {}, + "vc": {} + }, + "response": "Confirm", + "reason": "" + }, + "P1.2.7": { + "evidence": { + "website": "", + "pdf": {}, + "vc": {} + }, + "response": "Confirm", + "reason": "" + }, + "P1.2.8": { + "evidence": { + "website": "", + "pdf": {}, + "vc": {} + }, + "response": "Confirm", + "reason": "" + }, + "P1.2.9": { + "evidence": { + "website": "", + "pdf": {}, + "vc": {} + }, + "response": "Confirm", + "reason": "" + }, + "P1.2.10": { + "evidence": { + "website": "", + "pdf": {}, + "vc": {} + }, + "response": "Confirm", + "reason": "" + }, + "P1.3.1": { + "evidence": { + "website": "", + "pdf": {}, + "vc": {} + }, + "response": "Confirm", + "reason": "" + }, + "P1.3.2": { + "evidence": { + "website": "", + "pdf": {}, + "vc": {} + }, + "response": "Confirm", + "reason": "" + }, + "P1.3.3": { + "evidence": { + "website": "", + "pdf": {}, + "vc": {} + }, + "response": "Confirm", + "reason": "" + }, + "P1.3.4": { + "evidence": { + "website": "", + "pdf": {}, + "vc": {} + }, + "response": "Confirm", + "reason": "" + }, + "P1.3.5": { + "evidence": { + "website": "", + "pdf": {}, + "vc": {} + }, + "response": "Confirm", + "reason": "" + }, + "P2.1.1": { + "evidence": { + "website": "", + "pdf": {}, + "vc": {} + }, + "response": "Confirm", + "reason": "" + }, + "P2.1.2": { + "evidence": { + "website": "", + "pdf": {}, + "vc": {} + }, + "response": "Confirm", + "reason": "" + }, + "P2.1.3": { + "evidence": { + "website": "", + "pdf": {}, + "vc": {} + }, + "response": "Confirm", + "reason": "" + }, + "P2.2.1": { + "evidence": { + "website": "", + "pdf": {}, + "vc": {} + }, + "response": "Confirm", + "reason": "" + }, + "P2.2.2": { + "evidence": { + "website": "", + "pdf": {}, + "vc": {} + }, + "response": "Confirm", + "reason": "" + }, + "P2.2.3": { + "evidence": { + "website": "", + "pdf": {}, + "vc": {} + }, + "response": "Confirm", + "reason": "" + }, + "P2.2.4": { + "evidence": { + "website": "", + "pdf": {}, + "vc": {} + }, + "response": "Confirm", + "reason": "" + }, + "P2.2.5": { + "evidence": { + "website": "", + "pdf": {}, + "vc": {} + }, + "response": "Confirm", + "reason": "" + }, + "P2.2.6": { + "evidence": { + "website": "", + "pdf": {}, + "vc": {} + }, + "response": "Confirm", + "reason": "" + }, + "P2.2.7": { + "evidence": { + "website": "", + "pdf": {}, + "vc": {} + }, + "response": "Confirm", + "reason": "" + }, + "P2.3.1": { + "evidence": { + "website": "", + "pdf": {}, + "vc": {} + }, + "response": "Confirm", + "reason": "" + }, + "P2.3.2": { + "evidence": { + "website": "", + "pdf": {}, + "vc": {} + }, + "response": "Confirm", + "reason": "" + }, + "P2.3.3": { + "evidence": { + "website": "", + "pdf": {}, + "vc": {} + }, + "response": "Confirm", + "reason": "" + }, + "P3.1.1": { + "evidence": { + "website": "", + "pdf": {}, + "vc": {} + }, + "response": "Confirm", + "reason": "" + }, + "P3.1.2": { + "evidence": { + "website": "", + "pdf": {}, + "vc": {} + }, + "response": "Confirm", + "reason": "" + }, + "P3.1.3": { + "evidence": { + "website": "", + "pdf": {}, + "vc": {} + }, + "response": "Confirm", + "reason": "" + }, + "P3.1.4": { + "evidence": { + "website": "", + "pdf": {}, + "vc": {} + }, + "response": "Confirm", + "reason": "" + }, + "P3.1.5": { + "evidence": { + "website": "", + "pdf": {}, + "vc": {} + }, + "response": "Confirm", + "reason": "" + }, + "P3.1.6": { + "evidence": { + "website": "", + "pdf": {}, + "vc": {} + }, + "response": "Confirm", + "reason": "" + }, + "P3.1.7": { + "evidence": { + "website": "", + "pdf": {}, + "vc": {} + }, + "response": "Confirm", + "reason": "" + }, + "P3.1.8": { + "evidence": { + "website": "", + "pdf": {}, + "vc": {} + }, + "response": "Confirm", + "reason": "" + }, + "P3.1.9": { + "evidence": { + "website": "", + "pdf": {}, + "vc": {} + }, + "response": "Confirm", + "reason": "" + }, + "P3.1.10": { + "evidence": { + "website": "", + "pdf": {}, + "vc": {} + }, + "response": "Confirm", + "reason": "" + }, + "P3.1.11": { + "evidence": { + "website": "", + "pdf": {}, + "vc": {} + }, + "response": "Confirm", + "reason": "" + }, + "P3.1.12": { + "evidence": { + "website": "", + "pdf": {}, + "vc": {} + }, + "response": "Confirm", + "reason": "" + }, + "P3.1.13": { + "evidence": { + "website": "", + "pdf": {}, + "vc": {} + }, + "response": "Confirm", + "reason": "" + }, + "P3.1.14": { + "evidence": { + "website": "", + "pdf": {}, + "vc": {} + }, + "response": "Confirm", + "reason": "" + }, + "P3.1.15": { + "evidence": { + "website": "", + "pdf": {}, + "vc": {} + }, + "response": "Confirm", + "reason": "" + }, + "P3.1.16": { + "evidence": { + "website": "", + "pdf": {}, + "vc": {} + }, + "response": "Confirm", + "reason": "" + }, + "P3.1.17": { + "evidence": { + "website": "", + "pdf": {}, + "vc": {} + }, + "response": "Confirm", + "reason": "" + }, + "P3.1.18": { + "evidence": { + "website": "", + "pdf": {}, + "vc": {} + }, + "response": "Confirm", + "reason": "" + }, + "P3.1.19": { + "evidence": { + "website": "", + "pdf": {}, + "vc": {} + }, + "response": "Confirm", + "reason": "" + }, + "P3.1.20": { + "evidence": { + "website": "", + "pdf": {}, + "vc": {} + }, + "response": "Confirm", + "reason": "" + }, + "P4.1.1": { + "evidence": { + "website": "", + "pdf": {}, + "vc": {} + }, + "response": "Confirm", + "reason": "" + }, + "P4.1.2": { + "evidence": { + "website": "", + "pdf": {}, + "vc": {} + }, + "response": "Confirm", + "reason": "" + }, + "P5.1.1": { + "evidence": { + "website": "", + "pdf": {}, + "vc": {} + }, + "response": "Confirm", + "reason": "" + }, + "P5.1.2": { + "evidence": { + "website": "", + "pdf": {}, + "vc": {} + }, + "response": "Confirm", + "reason": "" + }, + "P5.1.3": { + "evidence": { + "website": "", + "pdf": {}, + "vc": {} + }, + "response": "Confirm", + "reason": "" + }, + "P5.1.4": { + "evidence": { + "website": "", + "pdf": {}, + "vc": {} + }, + "response": "Confirm", + "reason": "" + }, + "P5.1.5": { + "evidence": { + "website": "", + "pdf": {}, + "vc": {} + }, + "response": "Confirm", + "reason": "" + }, + "P5.1.6": { + "evidence": { + "website": "", + "pdf": {}, + "vc": {} + }, + "response": "Confirm", + "reason": "" + }, + "P5.1.7": { + "evidence": { + "website": "", + "pdf": {}, + "vc": {} + }, + "response": "Confirm", + "reason": "" + }, + "P5.2.1": { + "evidence": { + "website": "", + "pdf": {}, + "vc": {} + }, + "response": "Confirm", + "reason": "" + } + } + } + } + } + } + } } } } diff --git a/src/utils/common-functions.ts b/src/utils/common-functions.ts index 787850b..6ff8b5a 100644 --- a/src/utils/common-functions.ts +++ b/src/utils/common-functions.ts @@ -1,4 +1,6 @@ -import { Service, DidDocument } from '../interface/interface' +import { DidDocument, Service } from '../interface/interface' +import { AppMessages, LABEL_LEVEL_RULE } from './constants' + namespace CommonFunctions { export class Utils { generateDID(didId: string, publicKeyJwk: any, services: Service[]): unknown { @@ -30,7 +32,7 @@ namespace CommonFunctions { return did } - generateLegalPerson(participantURL: string, didId: string, legalName: string, headquarterAddress: string, legalAddress: string,legalRegistrationNumberVCUrl:string): object { + generateLegalPerson(participantURL: string, didId: string, legalName: string, headquarterAddress: string, legalAddress: string, legalRegistrationNumberVCUrl: string): object { const selfDescription = { '@context': 'https://www.w3.org/2018/credentials/v1', type: ['VerifiablePresentation'], @@ -65,7 +67,7 @@ namespace CommonFunctions { return selfDescription } - async generateTermsAndConditions(axios: any, didId: string,tandcsURL:string) { + async generateTermsAndConditions(axios: any, didId: string, tandcsURL: string) { // const { text } = (await axios.get(`${process.env.REGISTRY_TRUST_ANCHOR_URL as string}/termsAndConditions`)).data const verifiableCredential = { '@context': [ @@ -79,7 +81,8 @@ namespace CommonFunctions { '@context': 'https://registry.lab.gaia-x.eu/development/api/trusted-shape-registry/v1/shapes/jsonld/trustframework#', type: 'gx:GaiaXTermsAndConditions', // 'gx:termsAndConditions': text, - 'gx:termsAndConditions': "The PARTICIPANT signing the Self-Description agrees as follows:\n- to update its descriptions about any changes, be it technical, organizational, or legal - especially but not limited to contractual in regards to the indicated attributes present in the descriptions.\n\nThe keypair used to sign Verifiable Credentials will be revoked where Gaia-X Association becomes aware of any inaccurate statements in regards to the claims which result in a non-compliance with the Trust Framework and policy rules defined in the Policy Rules and Labelling Document (PRLD).", + 'gx:termsAndConditions': + 'The PARTICIPANT signing the Self-Description agrees as follows:\n- to update its descriptions about any changes, be it technical, organizational, or legal - especially but not limited to contractual in regards to the indicated attributes present in the descriptions.\n\nThe keypair used to sign Verifiable Credentials will be revoked where Gaia-X Association becomes aware of any inaccurate statements in regards to the claims which result in a non-compliance with the Trust Framework and policy rules defined in the Policy Rules and Labelling Document (PRLD).', id: tandcsURL }, issuer: didId, @@ -88,7 +91,7 @@ namespace CommonFunctions { return verifiableCredential } - async generateRegistrationNumber(axios: any, didId: string, legalRegistrationType: string, legalRegistrationNumber: string,legalRegistrationNumberVCUrl:string) { + async generateRegistrationNumber(axios: any, didId: string, legalRegistrationType: string, legalRegistrationNumber: string, legalRegistrationNumberVCUrl: string) { try { const request = { '@context': ['https://registry.lab.gaia-x.eu/development/api/trusted-shape-registry/v1/shapes/jsonld/participant'], @@ -293,6 +296,77 @@ namespace CommonFunctions { return false } } + + async getPublicKeys(ddo: any) { + const { verificationMethod, id } = ddo + const jwk = verificationMethod.find((method: any) => method.id.startsWith(id)) + if (!jwk) throw new Error(`verificationMethod ${verificationMethod} not found in did document`) + + const { publicKeyJwk } = jwk + if (!publicKeyJwk) throw new Error(`Could not load JWK for ${verificationMethod}`) + + const { x5u } = publicKeyJwk + if (!publicKeyJwk.x5u) throw new Error(`The x5u parameter is expected to be set in the JWK for ${verificationMethod}`) + + return { x5u, publicKeyJwk } + } + + async addProof(jsonld: any, axios: any, jose: any, crypto: any, verifiableCredential: any, privateKey: string, verificationMethod: string, rsaAlso: string, x5uURL: string) { + const canonizedSD = await this.normalize( + jsonld, + // eslint-disable-next-line + verifiableCredential + ) + const hash = this.sha256(crypto, canonizedSD) + console.info(__filename, 'addProof', `📈 Hashed canonized SD ${hash}`, '') + + const proof = await this.createProof(jose, verificationMethod, rsaAlso, hash, privateKey) + console.info(__filename, 'addProof', proof ? '🔒 SD signed successfully' : '❌ SD signing failed', x5uURL) + + const certificate = (await axios.get(x5uURL)).data as string + const publicKeyJwk = await this.generatePublicJWK(jose, rsaAlso, certificate, x5uURL) + + const verificationResult = await this.verify(jose, proof.jws.replace('..', `.${hash}.`), rsaAlso, publicKeyJwk, hash) + console.info(__filename, 'addProof', verificationResult ? '✅ Verification successful' : '❌ Verification failed', '') + return proof + } + + /** + * @formula trust_index = mean(veracity, transparency) + * @dev takes the veracity and transparency as input and calculates trust index + * @param veracity Veracity value + * @param transparency Transparency value + * @returns number - Trust index value + */ + calcLabelLevel = (credentialSubject: any) => { + let resultLabelLevel = '' + + // Label level response by user + const criteria = credentialSubject['gx:criteria'] + + // Constant Rules + for (const labelLevel in LABEL_LEVEL_RULE) { + // Rule of Specific label level + const levelRules = LABEL_LEVEL_RULE[labelLevel] + // Iterate level rules + for (const rulePoint of levelRules) { + // eslint-disable-next-line no-prototype-builtins + if (criteria.hasOwnProperty(rulePoint)) { + const { response } = criteria[rulePoint] + // Loop will break if any single response found not confirmed and will return last label level + if (response !== 'Confirm') { + return resultLabelLevel + } + } else { + console.error(__filename, 'LabelLevel', AppMessages.LABEL_LEVEL_CALC_FAILED_INVALID_KEY + rulePoint, '') + throw new Error(AppMessages.LABEL_LEVEL_CALC_FAILED_INVALID_KEY + rulePoint) + } + } + resultLabelLevel = labelLevel + } + + return resultLabelLevel + } } } diff --git a/src/utils/constants.ts b/src/utils/constants.ts index 1822ef0..9611803 100644 --- a/src/utils/constants.ts +++ b/src/utils/constants.ts @@ -30,4 +30,64 @@ export class AppMessages { static readonly PARTICIPANT_DID_FETCH_FAILED = 'Participant DID fetching failed' static readonly PARTICIPANT_VC_FOUND_FAILED = 'Participant VC not found' static readonly SO_SD_FETCH_FAILED = 'Service offering self description fetching failed' + static readonly LABEL_LEVEL_CALC_FAILED_INVALID_KEY = 'Rule point key not found in criteria json - ' +} + +export const LABEL_LEVEL_RULE: any = { + BC: [ + 'P1.1.1', + 'P1.1.3', + 'P1.1.4', + 'P1.2.1', + 'P1.2.2', + 'P1.2.3', + 'P1.2.4', + 'P1.2.5', + 'P1.2.6', + 'P1.2.7', + 'P1.2.8', + 'P1.2.9', + 'P1.2.10', + 'P1.3.1', + 'P1.3.2', + 'P1.3.3', + 'P1.3.4', + 'P1.3.5', + 'P2.1.2', + 'P2.1.3', + 'P2.2.1', + 'P2.2.2', + 'P2.2.3', + 'P2.2.5', + 'P2.2.6', + 'P2.2.7', + 'P2.3.2', + 'P2.3.3', + 'P3.1.1', + 'P3.1.2', + 'P3.1.3', + 'P3.1.4', + 'P3.1.5', + 'P3.1.6', + 'P3.1.7', + 'P3.1.8', + 'P3.1.9', + 'P3.1.10', + 'P3.1.11', + 'P3.1.12', + 'P3.1.13', + 'P3.1.14', + 'P3.1.15', + 'P3.1.16', + 'P3.1.17', + 'P3.1.18', + 'P3.1.19', + 'P3.1.20', + 'P4.1.1', + 'P4.1.2', + 'P5.2.1' + ], + L1: ['P1.1.2', 'P2.1.1', 'P2.2.4', 'P2.3.1'] + // L2: ['P5.1.1'], + // L3: ['P5.1.2', 'P5.1.3', 'P5.1.4', 'P5.1.5', 'P5.1.6', 'P5.1.7'] } From e6fb2a529d5c908db21e92eae9a77c9a6eb12a1e Mon Sep 17 00:00:00 2001 From: Ronak Thacker Date: Wed, 6 Sep 2023 17:26:11 +0530 Subject: [PATCH 07/26] fix: private key --- src/routes/private.ts | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/routes/private.ts b/src/routes/private.ts index 08ceb26..49b4444 100644 --- a/src/routes/private.ts +++ b/src/routes/private.ts @@ -671,8 +671,8 @@ privateRoute.post( } // Decrypt private key(received in request) from base64 to raw string - // const privateKey = (await axios.get(he.decode(privateKeyUrl))).data as string - const privateKey = process.env.PRIVATE_KEY as string + const privateKey = (await axios.get(he.decode(privateKeyUrl))).data as string + // const privateKey = process.env.PRIVATE_KEY as string // Sign service offering self description with private key(received in request) const proof = await Utils.addProof(jsonld, axios, jose, crypto, labelLevel, privateKey, verificationMethod, AppConst.RSA_ALGO, x5u) labelLevel.proof = proof From 7c734437b887b0e7bb8d5486dd52511f277e0a5d Mon Sep 17 00:00:00 2001 From: Viraj Patva Date: Thu, 23 Nov 2023 15:49:49 +0530 Subject: [PATCH 08/26] feat: Resource Creation added --- src/routes/private.ts | 51 ++++++++++++++++++++++++- src/utils/common-functions.ts | 72 +++++++++++++++++++++++++---------- src/utils/constants.ts | 1 + 3 files changed, 102 insertions(+), 22 deletions(-) diff --git a/src/routes/private.ts b/src/routes/private.ts index 49b4444..06b16fa 100644 --- a/src/routes/private.ts +++ b/src/routes/private.ts @@ -75,12 +75,13 @@ privateRoute.post( .trim() .escape() .matches(/^[a-zA-Z0-9][a-zA-Z0-9-]{0,61}[a-zA-Z0-9](?:\.[a-zA-Z]{2,})+$/), - check('templateId').not().isEmpty().trim().escape().isIn([AppConst.LEGAL_PARTICIPANT, AppConst.SERVICE_OFFER]), + check('templateId').not().isEmpty().trim().escape().isIn([AppConst.LEGAL_PARTICIPANT, AppConst.SERVICE_OFFER, AppConst.RESOURCE_CREATION]), check('privateKeyUrl').not().isEmpty().trim().escape(), check('data').isObject(), async (req: Request, res: Response): Promise => { try { const { domain, tenant, templateId, privateKeyUrl } = req.body + if (templateId === AppConst.LEGAL_PARTICIPANT) { await check('data.legalName').not().isEmpty().trim().escape().run(req) await check('data.legalRegistrationType').not().isEmpty().trim().escape().run(req) @@ -103,7 +104,31 @@ privateRoute.post( .run(req) await check('data.accessType').not().isEmpty().trim().escape().isIn(AppConst.ACCESS_TYPES).run(req) await check('data.requestType').not().isEmpty().trim().escape().isIn(AppConst.REQUEST_TYPES).run(req) + } else if (templateId === AppConst.RESOURCE_CREATION) { + await check('data.name').not().isEmpty().trim().escape().run(req) + await check('data.description').not().isEmpty().trim().escape().run(req) + await check('data.fileName').not().isEmpty().trim().escape().run(req) + await check('data.policyUrl').not().isEmpty().trim().escape().run(req) + await check('data.termsAndConditionsUrl').not().isEmpty().trim().escape().run(req) + await check('data.termsAndConditionsHash').not().isEmpty().trim().escape().run(req) + await check('data.formatType') + .not() + .isEmpty() + .trim() + .escape() + .custom((val) => typer.test(he.decode(val))) + .run(req) + await check('data.accessType').not().isEmpty().trim().escape().isIn(AppConst.ACCESS_TYPES).run(req) + await check('data.requestType').not().isEmpty().trim().escape().isIn(AppConst.REQUEST_TYPES).run(req) + await check('resource.name').not().isEmpty().trim().escape().run(req) + await check('resource.type').not().isEmpty().trim().escape().run(req) + await check('resource.description').not().isEmpty().trim().escape().run(req) + await check('resource.containsPII').not().isEmpty().trim().escape().run(req) + await check('resource.policy').not().isEmpty().trim().escape().run(req) + await check('resource.license').not().isEmpty().trim().escape().run(req) + await check('resource.copyrightOwnedBy').not().isEmpty().trim().escape().run(req) } + const errors = validationResult(req) if (!errors.isEmpty()) { const errorsArr = errors.array() @@ -115,6 +140,7 @@ privateRoute.post( const didId = tenant ? `did:web:${domain}:${tenant}` : `did:web:${domain}` const participantURL = tenant ? `https://${domain}/${tenant}/participant.json` : `https://${domain}/.well-known/participant.json` let selfDescription: any = null + if (templateId === AppConst.LEGAL_PARTICIPANT) { const { legalName, legalRegistrationType, legalRegistrationNumber, headquarterAddress, legalAddress } = req.body.data const legalRegistrationNumberVCUrl = tenant @@ -127,9 +153,23 @@ privateRoute.post( selfDescription['verifiableCredential'].push(regVC, termsVC) } else if (templateId === AppConst.SERVICE_OFFER) { const data = JSON.parse(he.decode(JSON.stringify(req.body.data))) + const serviceComplianceUrl = tenant ? `https://${domain}/${tenant}/${data.fileName}` : `https://${domain}/.well-known/${data.fileName}` selfDescription = Utils.generateServiceOffer(participantURL, didId, serviceComplianceUrl, data) const { selfDescriptionCredential } = (await axios.get(participantURL)).data + + for (let index = 0; index < selfDescriptionCredential.verifiableCredential.length; index++) { + const vc = selfDescriptionCredential.verifiableCredential[index] + selfDescription.verifiableCredential.push(vc) + } + } else if (templateId === AppConst.RESOURCE_CREATION) { + const data = JSON.parse(he.decode(JSON.stringify(req.body.data))) + const resource = JSON.parse(he.decode(JSON.stringify(req.body.resource))) + const serviceComplianceUrl = tenant ? `https://${domain}/${tenant}/${data.fileName}` : `https://${domain}/.well-known/${data.fileName}` + const resourceComplianceUrl = tenant ? `https://${domain}/${tenant}/${data.fileName}` : `https://${domain}/.well-known/${resource.name.replace(/\s/g, '_')}.json` + selfDescription = Utils.generateServiceOffer(participantURL, didId, serviceComplianceUrl, data, resource, resourceComplianceUrl) + const { selfDescriptionCredential } = (await axios.get(participantURL)).data + for (let index = 0; index < selfDescriptionCredential.verifiableCredential.length; index++) { const vc = selfDescriptionCredential.verifiableCredential[index] selfDescription.verifiableCredential.push(vc) @@ -147,7 +187,9 @@ privateRoute.post( selfDescription['verifiableCredential'][index].proof = proof } } + const sd = JSON.stringify(selfDescription) const complianceCredential = (await axios.post(process.env.COMPLIANCE_SERVICE as string, selfDescription)).data + // const complianceCredential = {} console.log(complianceCredential ? '🔒 SD signed successfully (compliance service)' : '❌ SD signing failed (compliance service)') // await publisherService.publishVP(complianceCredential); @@ -230,6 +272,7 @@ privateRoute.post( // retrieve private key const privateKey = (await axios.get(he.decode(privateKeyUrl))).data as string // const privateKey = process.env.PRIVATE_KEY as string + // create proof const proof = await Utils.createProof(jose, issuerDid, AppConst.RSA_ALGO, hash, privateKey) // attach proof to vc @@ -485,7 +528,11 @@ async function verification(credentialContent: any, proof: any, res: Response, c const certificates = (await axios.get(x5u)).data as string if (checkSSLwithRegistry) { // signature check against Gaia-x registry - const registryRes = await Utils.validateSslFromRegistry(certificates, axios) + const registryRes = await Utils.validateSslFromRegistryWithUri(x5u, axios) + if (!registryRes) { + throw new Error('Certificate validation failed') + } + if (!registryRes) { res.status(400).json({ error: `Certificates validation Failed`, diff --git a/src/utils/common-functions.ts b/src/utils/common-functions.ts index 6ff8b5a..c43e56a 100644 --- a/src/utils/common-functions.ts +++ b/src/utils/common-functions.ts @@ -109,9 +109,10 @@ namespace CommonFunctions { } } - generateServiceOffer(participantURL: string, didId: string, serviceComplianceUrl: string, data: any): object { + generateServiceOffer(participantURL: string, didId: string, serviceComplianceUrl: string, data: any, resource?: any, resourceComplianceUrl?: string): object { const { serviceName, description, policyUrl, termsAndConditionsUrl, termsAndConditionsHash, formatType, accessType, requestType } = data - const selfDescription = { + + const selfDescription: any = { '@context': 'https://www.w3.org/2018/credentials/v1', type: ['VerifiablePresentation'], verifiableCredential: [ @@ -121,28 +122,49 @@ namespace CommonFunctions { id: didId, issuer: didId, issuanceDate: new Date().toISOString(), - credentialSubject: { - id: serviceComplianceUrl, - 'gx:name': serviceName, - 'gx:description': description, - type: 'gx:ServiceOffering', - 'gx:providedBy': { - id: participantURL - }, - 'gx:policy': policyUrl, - 'gx:termsAndConditions': { - 'gx:URL': termsAndConditionsUrl, - 'gx:hash': termsAndConditionsHash - }, - 'gx:dataAccountExport': { - 'gx:requestType': requestType, - 'gx:accessType': accessType, - 'gx:formatType': formatType + credentialSubject: [ + { + id: serviceComplianceUrl, + 'gx:name': serviceName, + 'gx:description': description, + type: 'gx:ServiceOffering', + 'gx:providedBy': { + id: participantURL + }, + 'gx:policy': policyUrl, + 'gx:termsAndConditions': { + 'gx:URL': termsAndConditionsUrl, + 'gx:hash': termsAndConditionsHash + }, + 'gx:dataAccountExport': { + 'gx:requestType': requestType, + 'gx:accessType': accessType, + 'gx:formatType': formatType + } } - } + ] } ] } + + if (resource) { + selfDescription.verifiableCredential[0].credentialSubject.push({ + '@id': resourceComplianceUrl, + '@type': resource.type, + 'gx:name': resource.name, + 'gx:description': resource.description, + 'gx:containsPII': resource.containsPII == 'true', + 'gx:policy': resource.policy, + 'gx:license': resource.license, + 'gx:copyrightOwnedBy': resource.copyrightOwnedBy, + 'gx:producedBy': { + '@id': participantURL + }, + 'gx:exposedThrough': { + '@id': serviceComplianceUrl + } + }) + } return selfDescription } @@ -282,6 +304,16 @@ namespace CommonFunctions { } } + async validateSslFromRegistryWithUri(uri: string, axios: any) { + try { + const registryRes = await axios.post(`${process.env.REGISTRY_TRUST_ANCHOR_URL as string}/trustAnchor/chain/file`, { uri: uri }) + const result = registryRes?.data?.result + return result + } catch (error) { + console.error(__filename, 'validateSslFromRegistryWithUri', `❌ Validation from registry failed for certificates | error: ${error}`, '') + return false + } + } async comparePubKeys(certificates: string, publicKeyJwk: any, jose: any) { try { const pk = await jose.importJWK(publicKeyJwk) diff --git a/src/utils/constants.ts b/src/utils/constants.ts index 9611803..e71d21e 100644 --- a/src/utils/constants.ts +++ b/src/utils/constants.ts @@ -2,6 +2,7 @@ export class AppConst { static readonly RSA_ALGO = 'PS256' static readonly LEGAL_PARTICIPANT = 'LegalParticipant' static readonly SERVICE_OFFER = 'ServiceOffering' + static readonly RESOURCE_CREATION = 'ResourceCreation' static readonly FLATTEN_ENCRYPT_ALGORITHM = 'RSA-OAEP-256' static readonly FLATTEN_ENCRYPT_ENCODING = 'A256GCM' static readonly VERIFY_POLICIES = ['checkSignature', 'gxCompliance'] From 8709e114fdf32cd978417cb730b8d3ed74078c82 Mon Sep 17 00:00:00 2001 From: Viraj Patva Date: Thu, 23 Nov 2023 15:54:37 +0530 Subject: [PATCH 09/26] doc: swagger document updated --- src/swagger.json | 2067 +++++++++++++++++++++++----------------------- 1 file changed, 1046 insertions(+), 1021 deletions(-) diff --git a/src/swagger.json b/src/swagger.json index 99ec8ad..72b76e6 100644 --- a/src/swagger.json +++ b/src/swagger.json @@ -99,6 +99,33 @@ "formatType": "application/json" } } + }, + "ResourceCreation": { + "value": { + "domain": "smart99.proofsense.in", + "templateId": "ResourceCreation", + "privateKeyUrl": "https://example.com", + "data": { + "name": "AWS S3 Service", + "fileName": "s3Service.json", + "description": "Amazon S3 bucket is a public cloud storage resource.", + "policyUrl": "https://aws.amazon.com/privacy/?nc1=f_pr", + "termsAndConditionsUrl": "https://aws.amazon.com/service-terms/", + "termsAndConditionsHash": "4f598faf41fb29a44d63ec413730d55fabd2d249f1976fee1c8eec8003d7f539", + "requestType": "API", + "accessType": "digital", + "formatType": "application/json" + }, + "resource": { + "type": "gx:DataResource", + "name": "CES Data Resource", + "description": "Contains GX compliant credentials", + "containsPII": false, + "policy": "default: allow", + "license": "EPL-2.0", + "copyrightOwnedBy": "original owner" + } + } } } } @@ -874,597 +901,595 @@ "summary": "Sign Service offering SD from compliance service", "value": { "data": { - "selfDescriptionCredential": { - "@context": [ - "https://www.w3.org/2018/credentials/v1", - "https://w3id.org/security/suites/jws-2020/v1", - "https://registry.lab.gaia-x.eu/development/api/trusted-shape-registry/v1/shapes/jsonld/trustframework#" - ], - "type": [ - "VerifiableCredential" - ], - "id": "https://wizard.lab.gaia-x.eu/api/credentials/2d37wbGvQzbAQ84yRouh2m2vBKkN8s5AfH9Q75HZRCUQmJW7yAVSNKzjJj6gcjE2mDNDUHCichXWdMH3S2c8AaDLm3kXmf5R8DFPWTYo5iRYkn8kvgU3AjMXc2qTbhuMHCpucKGgT1ZMkcHUygZkt11iD3T8VJNKYwsdk4MGoZwdqoFUuTKVcsXVTBA4ofD1Dtqzjavyng5WUpvJf4gRyfGkMvYYuHCgay8TK8Dayt6Rhcs3r2d1gRCg2UV419S9CpWZGwKQNEXdYbaB2eTiNbQ83KMd4mj1oSJgF7LLDZLJtKJbhwLzR3x35QUqEGevRxnRDKoPdHrEZN7r9TVAmvr9rt7Xq8eB4zGMTza59hisEAUaHsmWQNaVDorqFyZgN5bXswMK1irVQ5SVR9osCCRrKUKkntxfakjmSqapPfveMP39vkgTXfEhsfLUZXGwFcpgLpWxWRn1QLnJY11BVymS7DyaSvbSKotNFQxyV6vghfM2Jetw1mLxU5qsQqDYnDYJjPZQSmkwxjX3yenPVCz6N2ox83tj9AuuQrzg5p2iukNdunDd2QCsHaMEtTq9JVLzXtWs2eZbPkxCBEQwoKTGGVhKu5yxZjCtQGc?vcid=tsandcsVC", - "issuer": "did:web:wizard.lab.gaia-x.eu:api:credentials:2d37wbGvQzbAQ84yRouh2m2vBKkN8s5AfH9Q75HZRCUQmJW7yAVSNKzjJj6gcjE2mDNDUHCichXWdMH3S2c8AaDLm3kXmf5R8DFPWTYo5iRYkn8kvgU3AjMXc2qTbhuMHCpucKGgT1ZMkcHUygZkt11iD3T8VJNKYwsdk4MGoZwdqoFUuTKVcsXVTBA4ofD1Dtqzjavyng5WUpvJf4gRyfGkMvYYuHCgay8TK8Dayt6Rhcs3r2d1gRCg2UV419S9CpWZGwKQNEXdYbaB2eTiNbQ83KMd4mj1oSJgF7LLDZLJtKJbhwLzR3x35QUqEGevRxnRDKoPdHrEZN7r9TVAmvr9rt7Xq8eB4zGMTza59hisEAUaHsmWQNaVDorqFyZgN5bXswMK1irVQ5SVR9osCCRrKUKkntxfakjmSqapPfveMP39vkgTXfEhsfLUZXGwFcpgLpWxWRn1QLnJY11BVymS7DyaSvbSKotNFQxyV6vghfM2Jetw1mLxU5qsQqDYnDYJjPZQSmkwxjX3yenPVCz6N2ox83tj9AuuQrzg5p2iukNdunDd2QCsHaMEtTq9JVLzXtWs2eZbPkxCBEQwoKTGGVhKu5yxZjCtQGc", - "issuanceDate": "2023-07-12T09:11:30.604Z", - "credentialSubject": { - "@context": "https://registry.lab.gaia-x.eu/development/api/trusted-shape-registry/v1/shapes/jsonld/trustframework#", - "type": "gx:ServiceOfferingLabel", - "id": "https://wizard-api.smart-x.smartsenselabs.com/12081064-8878-477e-8092-564a240c69e2/service-offering-label-level.json", - "gx:assignedTo": "https://wizard-api.smart-x.smartsenselabs.com/12081064-8878-477e-8092-564a240c69e2/service_hYfy.json", - "gx:criteria": { - "P1.1.1": { - "evidence": { - "website": "", - "pdf": {}, - "vc": {} - }, - "response": "Confirm", - "reason": "" - }, - "P1.1.2": { - "evidence": { - "website": "", - "pdf": {}, - "vc": {} - }, - "response": "Confirm", - "reason": "" - }, - "P1.1.3": { - "evidence": { - "website": "", - "pdf": {}, - "vc": {} - }, - "response": "Confirm", - "reason": "" - }, - "P1.1.4": { - "evidence": { - "website": "", - "pdf": {}, - "vc": {} - }, - "response": "Confirm", - "reason": "" - }, - "P1.2.1": { - "evidence": { - "website": "", - "pdf": {}, - "vc": {} - }, - "response": "Confirm", - "reason": "" - }, - "P1.2.2": { - "evidence": { - "website": "", - "pdf": {}, - "vc": {} - }, - "response": "Confirm", - "reason": "" - }, - "P1.2.3": { - "evidence": { - "website": "", - "pdf": {}, - "vc": {} - }, - "response": "Confirm", - "reason": "" - }, - "P1.2.4": { - "evidence": { - "website": "", - "pdf": {}, - "vc": {} - }, - "response": "Confirm", - "reason": "" - }, - "P1.2.5": { - "evidence": { - "website": "", - "pdf": {}, - "vc": {} - }, - "response": "Confirm", - "reason": "" - }, - "P1.2.6": { - "evidence": { - "website": "", - "pdf": {}, - "vc": {} - }, - "response": "Confirm", - "reason": "" - }, - "P1.2.7": { - "evidence": { - "website": "", - "pdf": {}, - "vc": {} - }, - "response": "Confirm", - "reason": "" - }, - "P1.2.8": { - "evidence": { - "website": "", - "pdf": {}, - "vc": {} - }, - "response": "Confirm", - "reason": "" - }, - "P1.2.9": { - "evidence": { - "website": "", - "pdf": {}, - "vc": {} - }, - "response": "Confirm", - "reason": "" - }, - "P1.2.10": { - "evidence": { - "website": "", - "pdf": {}, - "vc": {} - }, - "response": "Confirm", - "reason": "" - }, - "P1.3.1": { - "evidence": { - "website": "", - "pdf": {}, - "vc": {} - }, - "response": "Confirm", - "reason": "" - }, - "P1.3.2": { - "evidence": { - "website": "", - "pdf": {}, - "vc": {} - }, - "response": "Confirm", - "reason": "" - }, - "P1.3.3": { - "evidence": { - "website": "", - "pdf": {}, - "vc": {} - }, - "response": "Confirm", - "reason": "" - }, - "P1.3.4": { - "evidence": { - "website": "", - "pdf": {}, - "vc": {} - }, - "response": "Confirm", - "reason": "" - }, - "P1.3.5": { - "evidence": { - "website": "", - "pdf": {}, - "vc": {} - }, - "response": "Confirm", - "reason": "" - }, - "P2.1.1": { - "evidence": { - "website": "", - "pdf": {}, - "vc": {} - }, - "response": "Confirm", - "reason": "" - }, - "P2.1.2": { - "evidence": { - "website": "", - "pdf": {}, - "vc": {} - }, - "response": "Confirm", - "reason": "" - }, - "P2.1.3": { - "evidence": { - "website": "", - "pdf": {}, - "vc": {} - }, - "response": "Confirm", - "reason": "" - }, - "P2.2.1": { - "evidence": { - "website": "", - "pdf": {}, - "vc": {} - }, - "response": "Confirm", - "reason": "" - }, - "P2.2.2": { - "evidence": { - "website": "", - "pdf": {}, - "vc": {} - }, - "response": "Confirm", - "reason": "" - }, - "P2.2.3": { - "evidence": { - "website": "", - "pdf": {}, - "vc": {} - }, - "response": "Confirm", - "reason": "" - }, - "P2.2.4": { - "evidence": { - "website": "", - "pdf": {}, - "vc": {} - }, - "response": "Confirm", - "reason": "" - }, - "P2.2.5": { - "evidence": { - "website": "", - "pdf": {}, - "vc": {} - }, - "response": "Confirm", - "reason": "" - }, - "P2.2.6": { - "evidence": { - "website": "", - "pdf": {}, - "vc": {} - }, - "response": "Confirm", - "reason": "" - }, - "P2.2.7": { - "evidence": { - "website": "", - "pdf": {}, - "vc": {} - }, - "response": "Confirm", - "reason": "" - }, - "P2.3.1": { - "evidence": { - "website": "", - "pdf": {}, - "vc": {} - }, - "response": "Confirm", - "reason": "" - }, - "P2.3.2": { - "evidence": { - "website": "", - "pdf": {}, - "vc": {} - }, - "response": "Confirm", - "reason": "" - }, - "P2.3.3": { - "evidence": { - "website": "", - "pdf": {}, - "vc": {} - }, - "response": "Confirm", - "reason": "" - }, - "P3.1.1": { - "evidence": { - "website": "", - "pdf": {}, - "vc": {} - }, - "response": "Confirm", - "reason": "" - }, - "P3.1.2": { - "evidence": { - "website": "", - "pdf": {}, - "vc": {} - }, - "response": "Confirm", - "reason": "" - }, - "P3.1.3": { - "evidence": { - "website": "", - "pdf": {}, - "vc": {} - }, - "response": "Confirm", - "reason": "" - }, - "P3.1.4": { - "evidence": { - "website": "", - "pdf": {}, - "vc": {} - }, - "response": "Confirm", - "reason": "" - }, - "P3.1.5": { - "evidence": { - "website": "", - "pdf": {}, - "vc": {} - }, - "response": "Confirm", - "reason": "" - }, - "P3.1.6": { - "evidence": { - "website": "", - "pdf": {}, - "vc": {} - }, - "response": "Confirm", - "reason": "" - }, - "P3.1.7": { - "evidence": { - "website": "", - "pdf": {}, - "vc": {} - }, - "response": "Confirm", - "reason": "" - }, - "P3.1.8": { - "evidence": { - "website": "", - "pdf": {}, - "vc": {} - }, - "response": "Confirm", - "reason": "" - }, - "P3.1.9": { - "evidence": { - "website": "", - "pdf": {}, - "vc": {} - }, - "response": "Confirm", - "reason": "" - }, - "P3.1.10": { - "evidence": { - "website": "", - "pdf": {}, - "vc": {} - }, - "response": "Confirm", - "reason": "" - }, - "P3.1.11": { - "evidence": { - "website": "", - "pdf": {}, - "vc": {} - }, - "response": "Confirm", - "reason": "" - }, - "P3.1.12": { - "evidence": { - "website": "", - "pdf": {}, - "vc": {} - }, - "response": "Confirm", - "reason": "" - }, - "P3.1.13": { - "evidence": { - "website": "", - "pdf": {}, - "vc": {} - }, - "response": "Confirm", - "reason": "" - }, - "P3.1.14": { - "evidence": { - "website": "", - "pdf": {}, - "vc": {} - }, - "response": "Confirm", - "reason": "" - }, - "P3.1.15": { - "evidence": { - "website": "", - "pdf": {}, - "vc": {} - }, - "response": "Confirm", - "reason": "" - }, - "P3.1.16": { - "evidence": { - "website": "", - "pdf": {}, - "vc": {} - }, - "response": "Confirm", - "reason": "" - }, - "P3.1.17": { - "evidence": { - "website": "", - "pdf": {}, - "vc": {} - }, - "response": "Confirm", - "reason": "" - }, - "P3.1.18": { - "evidence": { - "website": "", - "pdf": {}, - "vc": {} - }, - "response": "Confirm", - "reason": "" - }, - "P3.1.19": { - "evidence": { - "website": "", - "pdf": {}, - "vc": {} - }, - "response": "Confirm", - "reason": "" - }, - "P3.1.20": { - "evidence": { - "website": "", - "pdf": {}, - "vc": {} - }, - "response": "Confirm", - "reason": "" - }, - "P4.1.1": { - "evidence": { - "website": "", - "pdf": {}, - "vc": {} - }, - "response": "Confirm", - "reason": "" - }, - "P4.1.2": { - "evidence": { - "website": "", - "pdf": {}, - "vc": {} - }, - "response": "Confirm", - "reason": "" - }, - "P5.1.1": { - "evidence": { - "website": "", - "pdf": {}, - "vc": {} - }, - "response": "Confirm", - "reason": "" - }, - "P5.1.2": { - "evidence": { - "website": "", - "pdf": {}, - "vc": {} - }, - "response": "Confirm", - "reason": "" - }, - "P5.1.3": { - "evidence": { - "website": "", - "pdf": {}, - "vc": {} - }, - "response": "Confirm", - "reason": "" - }, - "P5.1.4": { - "evidence": { - "website": "", - "pdf": {}, - "vc": {} - }, - "response": "Confirm", - "reason": "" - }, - "P5.1.5": { - "evidence": { - "website": "", - "pdf": {}, - "vc": {} - }, - "response": "Confirm", - "reason": "" - }, - "P5.1.6": { - "evidence": { - "website": "", - "pdf": {}, - "vc": {} - }, - "response": "Confirm", - "reason": "" - }, - "P5.1.7": { - "evidence": { - "website": "", - "pdf": {}, - "vc": {} - }, - "response": "Confirm", - "reason": "" + "selfDescriptionCredential": { + "@context": [ + "https://www.w3.org/2018/credentials/v1", + "https://w3id.org/security/suites/jws-2020/v1", + "https://registry.lab.gaia-x.eu/development/api/trusted-shape-registry/v1/shapes/jsonld/trustframework#" + ], + "type": ["VerifiableCredential"], + "id": "https://wizard.lab.gaia-x.eu/api/credentials/2d37wbGvQzbAQ84yRouh2m2vBKkN8s5AfH9Q75HZRCUQmJW7yAVSNKzjJj6gcjE2mDNDUHCichXWdMH3S2c8AaDLm3kXmf5R8DFPWTYo5iRYkn8kvgU3AjMXc2qTbhuMHCpucKGgT1ZMkcHUygZkt11iD3T8VJNKYwsdk4MGoZwdqoFUuTKVcsXVTBA4ofD1Dtqzjavyng5WUpvJf4gRyfGkMvYYuHCgay8TK8Dayt6Rhcs3r2d1gRCg2UV419S9CpWZGwKQNEXdYbaB2eTiNbQ83KMd4mj1oSJgF7LLDZLJtKJbhwLzR3x35QUqEGevRxnRDKoPdHrEZN7r9TVAmvr9rt7Xq8eB4zGMTza59hisEAUaHsmWQNaVDorqFyZgN5bXswMK1irVQ5SVR9osCCRrKUKkntxfakjmSqapPfveMP39vkgTXfEhsfLUZXGwFcpgLpWxWRn1QLnJY11BVymS7DyaSvbSKotNFQxyV6vghfM2Jetw1mLxU5qsQqDYnDYJjPZQSmkwxjX3yenPVCz6N2ox83tj9AuuQrzg5p2iukNdunDd2QCsHaMEtTq9JVLzXtWs2eZbPkxCBEQwoKTGGVhKu5yxZjCtQGc?vcid=tsandcsVC", + "issuer": "did:web:wizard.lab.gaia-x.eu:api:credentials:2d37wbGvQzbAQ84yRouh2m2vBKkN8s5AfH9Q75HZRCUQmJW7yAVSNKzjJj6gcjE2mDNDUHCichXWdMH3S2c8AaDLm3kXmf5R8DFPWTYo5iRYkn8kvgU3AjMXc2qTbhuMHCpucKGgT1ZMkcHUygZkt11iD3T8VJNKYwsdk4MGoZwdqoFUuTKVcsXVTBA4ofD1Dtqzjavyng5WUpvJf4gRyfGkMvYYuHCgay8TK8Dayt6Rhcs3r2d1gRCg2UV419S9CpWZGwKQNEXdYbaB2eTiNbQ83KMd4mj1oSJgF7LLDZLJtKJbhwLzR3x35QUqEGevRxnRDKoPdHrEZN7r9TVAmvr9rt7Xq8eB4zGMTza59hisEAUaHsmWQNaVDorqFyZgN5bXswMK1irVQ5SVR9osCCRrKUKkntxfakjmSqapPfveMP39vkgTXfEhsfLUZXGwFcpgLpWxWRn1QLnJY11BVymS7DyaSvbSKotNFQxyV6vghfM2Jetw1mLxU5qsQqDYnDYJjPZQSmkwxjX3yenPVCz6N2ox83tj9AuuQrzg5p2iukNdunDd2QCsHaMEtTq9JVLzXtWs2eZbPkxCBEQwoKTGGVhKu5yxZjCtQGc", + "issuanceDate": "2023-07-12T09:11:30.604Z", + "credentialSubject": { + "@context": "https://registry.lab.gaia-x.eu/development/api/trusted-shape-registry/v1/shapes/jsonld/trustframework#", + "type": "gx:ServiceOfferingLabel", + "id": "https://wizard-api.smart-x.smartsenselabs.com/12081064-8878-477e-8092-564a240c69e2/service-offering-label-level.json", + "gx:assignedTo": "https://wizard-api.smart-x.smartsenselabs.com/12081064-8878-477e-8092-564a240c69e2/service_hYfy.json", + "gx:criteria": { + "P1.1.1": { + "evidence": { + "website": "", + "pdf": {}, + "vc": {} + }, + "response": "Confirm", + "reason": "" + }, + "P1.1.2": { + "evidence": { + "website": "", + "pdf": {}, + "vc": {} + }, + "response": "Confirm", + "reason": "" + }, + "P1.1.3": { + "evidence": { + "website": "", + "pdf": {}, + "vc": {} + }, + "response": "Confirm", + "reason": "" + }, + "P1.1.4": { + "evidence": { + "website": "", + "pdf": {}, + "vc": {} + }, + "response": "Confirm", + "reason": "" + }, + "P1.2.1": { + "evidence": { + "website": "", + "pdf": {}, + "vc": {} + }, + "response": "Confirm", + "reason": "" + }, + "P1.2.2": { + "evidence": { + "website": "", + "pdf": {}, + "vc": {} + }, + "response": "Confirm", + "reason": "" + }, + "P1.2.3": { + "evidence": { + "website": "", + "pdf": {}, + "vc": {} + }, + "response": "Confirm", + "reason": "" + }, + "P1.2.4": { + "evidence": { + "website": "", + "pdf": {}, + "vc": {} + }, + "response": "Confirm", + "reason": "" + }, + "P1.2.5": { + "evidence": { + "website": "", + "pdf": {}, + "vc": {} + }, + "response": "Confirm", + "reason": "" + }, + "P1.2.6": { + "evidence": { + "website": "", + "pdf": {}, + "vc": {} + }, + "response": "Confirm", + "reason": "" + }, + "P1.2.7": { + "evidence": { + "website": "", + "pdf": {}, + "vc": {} + }, + "response": "Confirm", + "reason": "" + }, + "P1.2.8": { + "evidence": { + "website": "", + "pdf": {}, + "vc": {} + }, + "response": "Confirm", + "reason": "" + }, + "P1.2.9": { + "evidence": { + "website": "", + "pdf": {}, + "vc": {} + }, + "response": "Confirm", + "reason": "" + }, + "P1.2.10": { + "evidence": { + "website": "", + "pdf": {}, + "vc": {} + }, + "response": "Confirm", + "reason": "" + }, + "P1.3.1": { + "evidence": { + "website": "", + "pdf": {}, + "vc": {} + }, + "response": "Confirm", + "reason": "" + }, + "P1.3.2": { + "evidence": { + "website": "", + "pdf": {}, + "vc": {} + }, + "response": "Confirm", + "reason": "" + }, + "P1.3.3": { + "evidence": { + "website": "", + "pdf": {}, + "vc": {} + }, + "response": "Confirm", + "reason": "" + }, + "P1.3.4": { + "evidence": { + "website": "", + "pdf": {}, + "vc": {} + }, + "response": "Confirm", + "reason": "" + }, + "P1.3.5": { + "evidence": { + "website": "", + "pdf": {}, + "vc": {} + }, + "response": "Confirm", + "reason": "" + }, + "P2.1.1": { + "evidence": { + "website": "", + "pdf": {}, + "vc": {} + }, + "response": "Confirm", + "reason": "" + }, + "P2.1.2": { + "evidence": { + "website": "", + "pdf": {}, + "vc": {} + }, + "response": "Confirm", + "reason": "" + }, + "P2.1.3": { + "evidence": { + "website": "", + "pdf": {}, + "vc": {} + }, + "response": "Confirm", + "reason": "" + }, + "P2.2.1": { + "evidence": { + "website": "", + "pdf": {}, + "vc": {} + }, + "response": "Confirm", + "reason": "" + }, + "P2.2.2": { + "evidence": { + "website": "", + "pdf": {}, + "vc": {} + }, + "response": "Confirm", + "reason": "" + }, + "P2.2.3": { + "evidence": { + "website": "", + "pdf": {}, + "vc": {} + }, + "response": "Confirm", + "reason": "" + }, + "P2.2.4": { + "evidence": { + "website": "", + "pdf": {}, + "vc": {} + }, + "response": "Confirm", + "reason": "" + }, + "P2.2.5": { + "evidence": { + "website": "", + "pdf": {}, + "vc": {} + }, + "response": "Confirm", + "reason": "" + }, + "P2.2.6": { + "evidence": { + "website": "", + "pdf": {}, + "vc": {} + }, + "response": "Confirm", + "reason": "" + }, + "P2.2.7": { + "evidence": { + "website": "", + "pdf": {}, + "vc": {} + }, + "response": "Confirm", + "reason": "" + }, + "P2.3.1": { + "evidence": { + "website": "", + "pdf": {}, + "vc": {} + }, + "response": "Confirm", + "reason": "" + }, + "P2.3.2": { + "evidence": { + "website": "", + "pdf": {}, + "vc": {} + }, + "response": "Confirm", + "reason": "" + }, + "P2.3.3": { + "evidence": { + "website": "", + "pdf": {}, + "vc": {} + }, + "response": "Confirm", + "reason": "" + }, + "P3.1.1": { + "evidence": { + "website": "", + "pdf": {}, + "vc": {} + }, + "response": "Confirm", + "reason": "" + }, + "P3.1.2": { + "evidence": { + "website": "", + "pdf": {}, + "vc": {} + }, + "response": "Confirm", + "reason": "" + }, + "P3.1.3": { + "evidence": { + "website": "", + "pdf": {}, + "vc": {} + }, + "response": "Confirm", + "reason": "" + }, + "P3.1.4": { + "evidence": { + "website": "", + "pdf": {}, + "vc": {} + }, + "response": "Confirm", + "reason": "" + }, + "P3.1.5": { + "evidence": { + "website": "", + "pdf": {}, + "vc": {} + }, + "response": "Confirm", + "reason": "" + }, + "P3.1.6": { + "evidence": { + "website": "", + "pdf": {}, + "vc": {} + }, + "response": "Confirm", + "reason": "" + }, + "P3.1.7": { + "evidence": { + "website": "", + "pdf": {}, + "vc": {} + }, + "response": "Confirm", + "reason": "" + }, + "P3.1.8": { + "evidence": { + "website": "", + "pdf": {}, + "vc": {} + }, + "response": "Confirm", + "reason": "" + }, + "P3.1.9": { + "evidence": { + "website": "", + "pdf": {}, + "vc": {} + }, + "response": "Confirm", + "reason": "" + }, + "P3.1.10": { + "evidence": { + "website": "", + "pdf": {}, + "vc": {} + }, + "response": "Confirm", + "reason": "" + }, + "P3.1.11": { + "evidence": { + "website": "", + "pdf": {}, + "vc": {} + }, + "response": "Confirm", + "reason": "" + }, + "P3.1.12": { + "evidence": { + "website": "", + "pdf": {}, + "vc": {} + }, + "response": "Confirm", + "reason": "" + }, + "P3.1.13": { + "evidence": { + "website": "", + "pdf": {}, + "vc": {} + }, + "response": "Confirm", + "reason": "" + }, + "P3.1.14": { + "evidence": { + "website": "", + "pdf": {}, + "vc": {} + }, + "response": "Confirm", + "reason": "" + }, + "P3.1.15": { + "evidence": { + "website": "", + "pdf": {}, + "vc": {} + }, + "response": "Confirm", + "reason": "" + }, + "P3.1.16": { + "evidence": { + "website": "", + "pdf": {}, + "vc": {} + }, + "response": "Confirm", + "reason": "" + }, + "P3.1.17": { + "evidence": { + "website": "", + "pdf": {}, + "vc": {} + }, + "response": "Confirm", + "reason": "" + }, + "P3.1.18": { + "evidence": { + "website": "", + "pdf": {}, + "vc": {} + }, + "response": "Confirm", + "reason": "" + }, + "P3.1.19": { + "evidence": { + "website": "", + "pdf": {}, + "vc": {} + }, + "response": "Confirm", + "reason": "" + }, + "P3.1.20": { + "evidence": { + "website": "", + "pdf": {}, + "vc": {} + }, + "response": "Confirm", + "reason": "" + }, + "P4.1.1": { + "evidence": { + "website": "", + "pdf": {}, + "vc": {} + }, + "response": "Confirm", + "reason": "" + }, + "P4.1.2": { + "evidence": { + "website": "", + "pdf": {}, + "vc": {} + }, + "response": "Confirm", + "reason": "" + }, + "P5.1.1": { + "evidence": { + "website": "", + "pdf": {}, + "vc": {} + }, + "response": "Confirm", + "reason": "" + }, + "P5.1.2": { + "evidence": { + "website": "", + "pdf": {}, + "vc": {} + }, + "response": "Confirm", + "reason": "" + }, + "P5.1.3": { + "evidence": { + "website": "", + "pdf": {}, + "vc": {} + }, + "response": "Confirm", + "reason": "" + }, + "P5.1.4": { + "evidence": { + "website": "", + "pdf": {}, + "vc": {} + }, + "response": "Confirm", + "reason": "" + }, + "P5.1.5": { + "evidence": { + "website": "", + "pdf": {}, + "vc": {} + }, + "response": "Confirm", + "reason": "" + }, + "P5.1.6": { + "evidence": { + "website": "", + "pdf": {}, + "vc": {} + }, + "response": "Confirm", + "reason": "" + }, + "P5.1.7": { + "evidence": { + "website": "", + "pdf": {}, + "vc": {} + }, + "response": "Confirm", + "reason": "" + }, + "P5.2.1": { + "evidence": { + "website": "", + "pdf": {}, + "vc": {} + }, + "response": "Confirm", + "reason": "" + } + }, + "gx:labelLevel": "L1" }, - "P5.2.1": { - "evidence": { - "website": "", - "pdf": {}, - "vc": {} - }, - "response": "Confirm", - "reason": "" + "proof": { + "type": "JsonWebSignature2020", + "created": "2023-09-06T10:28:46.799Z", + "proofPurpose": "assertionMethod", + "verificationMethod": "did:web:casio34.smart-x.smartsenselabs.com", + "jws": "eyJhbGciOiJQUzI1NiIsImI2NCI6ZmFsc2UsImNyaXQiOlsiYjY0Il19..Ir0jfauSoibBKhNLj_hXqz2LwmpjqipEG4P2HAnPrwBX2uy4MgRc4xP7srZ-WvplKdhR1gqHTn4phxZiZAQbxjcTv2X_6H5Cc60BOhkeYFceMwt3u3s39aQjd5ZXINusbzqZcFIqL-3YVrrta0gZ_Hc5fjLJpyYkAo_wULNcRdoFyy8zdZgRRrONQY_9CMQSijevHESseyhxtd3tfveMhmvBcOvhYXhKyj4gW6Q9y3wq-XrDxD8-7pfWovDAbnJoCJJ62dwk3YgeC4jOgoNufYmYspuuBOGiUo7wdE-m0F9HjNCPL_E-QayieXp51oGC--W6S_pY-s1o-wyulTbRVg" } - }, - "gx:labelLevel": "L1" }, - "proof": { - "type": "JsonWebSignature2020", - "created": "2023-09-06T10:28:46.799Z", - "proofPurpose": "assertionMethod", - "verificationMethod": "did:web:casio34.smart-x.smartsenselabs.com", - "jws": "eyJhbGciOiJQUzI1NiIsImI2NCI6ZmFsc2UsImNyaXQiOlsiYjY0Il19..Ir0jfauSoibBKhNLj_hXqz2LwmpjqipEG4P2HAnPrwBX2uy4MgRc4xP7srZ-WvplKdhR1gqHTn4phxZiZAQbxjcTv2X_6H5Cc60BOhkeYFceMwt3u3s39aQjd5ZXINusbzqZcFIqL-3YVrrta0gZ_Hc5fjLJpyYkAo_wULNcRdoFyy8zdZgRRrONQY_9CMQSijevHESseyhxtd3tfveMhmvBcOvhYXhKyj4gW6Q9y3wq-XrDxD8-7pfWovDAbnJoCJJ62dwk3YgeC4jOgoNufYmYspuuBOGiUo7wdE-m0F9HjNCPL_E-QayieXp51oGC--W6S_pY-s1o-wyulTbRVg" - } - }, - "complianceCredential": {} + "complianceCredential": {} }, "message": "VP created successfully." - } + } } } } @@ -1761,564 +1786,564 @@ "gx:assignedTo": "https://wizard-api.smart-x.smartsenselabs.com/12081064-8878-477e-8092-564a240c69e2/service_hYfy.json", "gx:criteria": { "P1.1.1": { - "evidence": { - "website": "", - "pdf": {}, - "vc": {} - }, - "response": "Confirm", - "reason": "" + "evidence": { + "website": "", + "pdf": {}, + "vc": {} + }, + "response": "Confirm", + "reason": "" }, "P1.1.2": { - "evidence": { - "website": "", - "pdf": {}, - "vc": {} - }, - "response": "Confirm", - "reason": "" + "evidence": { + "website": "", + "pdf": {}, + "vc": {} + }, + "response": "Confirm", + "reason": "" }, "P1.1.3": { - "evidence": { - "website": "", - "pdf": {}, - "vc": {} - }, - "response": "Confirm", - "reason": "" + "evidence": { + "website": "", + "pdf": {}, + "vc": {} + }, + "response": "Confirm", + "reason": "" }, "P1.1.4": { - "evidence": { - "website": "", - "pdf": {}, - "vc": {} - }, - "response": "Confirm", - "reason": "" + "evidence": { + "website": "", + "pdf": {}, + "vc": {} + }, + "response": "Confirm", + "reason": "" }, "P1.2.1": { - "evidence": { - "website": "", - "pdf": {}, - "vc": {} - }, - "response": "Confirm", - "reason": "" + "evidence": { + "website": "", + "pdf": {}, + "vc": {} + }, + "response": "Confirm", + "reason": "" }, "P1.2.2": { - "evidence": { - "website": "", - "pdf": {}, - "vc": {} - }, - "response": "Confirm", - "reason": "" + "evidence": { + "website": "", + "pdf": {}, + "vc": {} + }, + "response": "Confirm", + "reason": "" }, "P1.2.3": { - "evidence": { - "website": "", - "pdf": {}, - "vc": {} - }, - "response": "Confirm", - "reason": "" + "evidence": { + "website": "", + "pdf": {}, + "vc": {} + }, + "response": "Confirm", + "reason": "" }, "P1.2.4": { - "evidence": { - "website": "", - "pdf": {}, - "vc": {} - }, - "response": "Confirm", - "reason": "" + "evidence": { + "website": "", + "pdf": {}, + "vc": {} + }, + "response": "Confirm", + "reason": "" }, "P1.2.5": { - "evidence": { - "website": "", - "pdf": {}, - "vc": {} - }, - "response": "Confirm", - "reason": "" + "evidence": { + "website": "", + "pdf": {}, + "vc": {} + }, + "response": "Confirm", + "reason": "" }, "P1.2.6": { - "evidence": { - "website": "", - "pdf": {}, - "vc": {} - }, - "response": "Confirm", - "reason": "" + "evidence": { + "website": "", + "pdf": {}, + "vc": {} + }, + "response": "Confirm", + "reason": "" }, "P1.2.7": { - "evidence": { - "website": "", - "pdf": {}, - "vc": {} - }, - "response": "Confirm", - "reason": "" + "evidence": { + "website": "", + "pdf": {}, + "vc": {} + }, + "response": "Confirm", + "reason": "" }, "P1.2.8": { - "evidence": { - "website": "", - "pdf": {}, - "vc": {} - }, - "response": "Confirm", - "reason": "" + "evidence": { + "website": "", + "pdf": {}, + "vc": {} + }, + "response": "Confirm", + "reason": "" }, "P1.2.9": { - "evidence": { - "website": "", - "pdf": {}, - "vc": {} - }, - "response": "Confirm", - "reason": "" + "evidence": { + "website": "", + "pdf": {}, + "vc": {} + }, + "response": "Confirm", + "reason": "" }, "P1.2.10": { - "evidence": { - "website": "", - "pdf": {}, - "vc": {} - }, - "response": "Confirm", - "reason": "" + "evidence": { + "website": "", + "pdf": {}, + "vc": {} + }, + "response": "Confirm", + "reason": "" }, "P1.3.1": { - "evidence": { - "website": "", - "pdf": {}, - "vc": {} - }, - "response": "Confirm", - "reason": "" + "evidence": { + "website": "", + "pdf": {}, + "vc": {} + }, + "response": "Confirm", + "reason": "" }, "P1.3.2": { - "evidence": { - "website": "", - "pdf": {}, - "vc": {} - }, - "response": "Confirm", - "reason": "" + "evidence": { + "website": "", + "pdf": {}, + "vc": {} + }, + "response": "Confirm", + "reason": "" }, "P1.3.3": { - "evidence": { - "website": "", - "pdf": {}, - "vc": {} - }, - "response": "Confirm", - "reason": "" + "evidence": { + "website": "", + "pdf": {}, + "vc": {} + }, + "response": "Confirm", + "reason": "" }, "P1.3.4": { - "evidence": { - "website": "", - "pdf": {}, - "vc": {} - }, - "response": "Confirm", - "reason": "" + "evidence": { + "website": "", + "pdf": {}, + "vc": {} + }, + "response": "Confirm", + "reason": "" }, "P1.3.5": { - "evidence": { - "website": "", - "pdf": {}, - "vc": {} - }, - "response": "Confirm", - "reason": "" + "evidence": { + "website": "", + "pdf": {}, + "vc": {} + }, + "response": "Confirm", + "reason": "" }, "P2.1.1": { - "evidence": { - "website": "", - "pdf": {}, - "vc": {} - }, - "response": "Confirm", - "reason": "" + "evidence": { + "website": "", + "pdf": {}, + "vc": {} + }, + "response": "Confirm", + "reason": "" }, "P2.1.2": { - "evidence": { - "website": "", - "pdf": {}, - "vc": {} - }, - "response": "Confirm", - "reason": "" + "evidence": { + "website": "", + "pdf": {}, + "vc": {} + }, + "response": "Confirm", + "reason": "" }, "P2.1.3": { - "evidence": { - "website": "", - "pdf": {}, - "vc": {} - }, - "response": "Confirm", - "reason": "" + "evidence": { + "website": "", + "pdf": {}, + "vc": {} + }, + "response": "Confirm", + "reason": "" }, "P2.2.1": { - "evidence": { - "website": "", - "pdf": {}, - "vc": {} - }, - "response": "Confirm", - "reason": "" + "evidence": { + "website": "", + "pdf": {}, + "vc": {} + }, + "response": "Confirm", + "reason": "" }, "P2.2.2": { - "evidence": { - "website": "", - "pdf": {}, - "vc": {} - }, - "response": "Confirm", - "reason": "" + "evidence": { + "website": "", + "pdf": {}, + "vc": {} + }, + "response": "Confirm", + "reason": "" }, "P2.2.3": { - "evidence": { - "website": "", - "pdf": {}, - "vc": {} - }, - "response": "Confirm", - "reason": "" + "evidence": { + "website": "", + "pdf": {}, + "vc": {} + }, + "response": "Confirm", + "reason": "" }, "P2.2.4": { - "evidence": { - "website": "", - "pdf": {}, - "vc": {} - }, - "response": "Confirm", - "reason": "" + "evidence": { + "website": "", + "pdf": {}, + "vc": {} + }, + "response": "Confirm", + "reason": "" }, "P2.2.5": { - "evidence": { - "website": "", - "pdf": {}, - "vc": {} - }, - "response": "Confirm", - "reason": "" + "evidence": { + "website": "", + "pdf": {}, + "vc": {} + }, + "response": "Confirm", + "reason": "" }, "P2.2.6": { - "evidence": { - "website": "", - "pdf": {}, - "vc": {} - }, - "response": "Confirm", - "reason": "" + "evidence": { + "website": "", + "pdf": {}, + "vc": {} + }, + "response": "Confirm", + "reason": "" }, "P2.2.7": { - "evidence": { - "website": "", - "pdf": {}, - "vc": {} - }, - "response": "Confirm", - "reason": "" + "evidence": { + "website": "", + "pdf": {}, + "vc": {} + }, + "response": "Confirm", + "reason": "" }, "P2.3.1": { - "evidence": { - "website": "", - "pdf": {}, - "vc": {} - }, - "response": "Confirm", - "reason": "" + "evidence": { + "website": "", + "pdf": {}, + "vc": {} + }, + "response": "Confirm", + "reason": "" }, "P2.3.2": { - "evidence": { - "website": "", - "pdf": {}, - "vc": {} - }, - "response": "Confirm", - "reason": "" + "evidence": { + "website": "", + "pdf": {}, + "vc": {} + }, + "response": "Confirm", + "reason": "" }, "P2.3.3": { - "evidence": { - "website": "", - "pdf": {}, - "vc": {} - }, - "response": "Confirm", - "reason": "" + "evidence": { + "website": "", + "pdf": {}, + "vc": {} + }, + "response": "Confirm", + "reason": "" }, "P3.1.1": { - "evidence": { - "website": "", - "pdf": {}, - "vc": {} - }, - "response": "Confirm", - "reason": "" + "evidence": { + "website": "", + "pdf": {}, + "vc": {} + }, + "response": "Confirm", + "reason": "" }, "P3.1.2": { - "evidence": { - "website": "", - "pdf": {}, - "vc": {} - }, - "response": "Confirm", - "reason": "" + "evidence": { + "website": "", + "pdf": {}, + "vc": {} + }, + "response": "Confirm", + "reason": "" }, "P3.1.3": { - "evidence": { - "website": "", - "pdf": {}, - "vc": {} - }, - "response": "Confirm", - "reason": "" + "evidence": { + "website": "", + "pdf": {}, + "vc": {} + }, + "response": "Confirm", + "reason": "" }, "P3.1.4": { - "evidence": { - "website": "", - "pdf": {}, - "vc": {} - }, - "response": "Confirm", - "reason": "" + "evidence": { + "website": "", + "pdf": {}, + "vc": {} + }, + "response": "Confirm", + "reason": "" }, "P3.1.5": { - "evidence": { - "website": "", - "pdf": {}, - "vc": {} - }, - "response": "Confirm", - "reason": "" + "evidence": { + "website": "", + "pdf": {}, + "vc": {} + }, + "response": "Confirm", + "reason": "" }, "P3.1.6": { - "evidence": { - "website": "", - "pdf": {}, - "vc": {} - }, - "response": "Confirm", - "reason": "" + "evidence": { + "website": "", + "pdf": {}, + "vc": {} + }, + "response": "Confirm", + "reason": "" }, "P3.1.7": { - "evidence": { - "website": "", - "pdf": {}, - "vc": {} - }, - "response": "Confirm", - "reason": "" + "evidence": { + "website": "", + "pdf": {}, + "vc": {} + }, + "response": "Confirm", + "reason": "" }, "P3.1.8": { - "evidence": { - "website": "", - "pdf": {}, - "vc": {} - }, - "response": "Confirm", - "reason": "" + "evidence": { + "website": "", + "pdf": {}, + "vc": {} + }, + "response": "Confirm", + "reason": "" }, "P3.1.9": { - "evidence": { - "website": "", - "pdf": {}, - "vc": {} - }, - "response": "Confirm", - "reason": "" + "evidence": { + "website": "", + "pdf": {}, + "vc": {} + }, + "response": "Confirm", + "reason": "" }, "P3.1.10": { - "evidence": { - "website": "", - "pdf": {}, - "vc": {} - }, - "response": "Confirm", - "reason": "" + "evidence": { + "website": "", + "pdf": {}, + "vc": {} + }, + "response": "Confirm", + "reason": "" }, "P3.1.11": { - "evidence": { - "website": "", - "pdf": {}, - "vc": {} - }, - "response": "Confirm", - "reason": "" + "evidence": { + "website": "", + "pdf": {}, + "vc": {} + }, + "response": "Confirm", + "reason": "" }, "P3.1.12": { - "evidence": { - "website": "", - "pdf": {}, - "vc": {} - }, - "response": "Confirm", - "reason": "" + "evidence": { + "website": "", + "pdf": {}, + "vc": {} + }, + "response": "Confirm", + "reason": "" }, "P3.1.13": { - "evidence": { - "website": "", - "pdf": {}, - "vc": {} - }, - "response": "Confirm", - "reason": "" + "evidence": { + "website": "", + "pdf": {}, + "vc": {} + }, + "response": "Confirm", + "reason": "" }, "P3.1.14": { - "evidence": { - "website": "", - "pdf": {}, - "vc": {} - }, - "response": "Confirm", - "reason": "" + "evidence": { + "website": "", + "pdf": {}, + "vc": {} + }, + "response": "Confirm", + "reason": "" }, "P3.1.15": { - "evidence": { - "website": "", - "pdf": {}, - "vc": {} - }, - "response": "Confirm", - "reason": "" + "evidence": { + "website": "", + "pdf": {}, + "vc": {} + }, + "response": "Confirm", + "reason": "" }, "P3.1.16": { - "evidence": { - "website": "", - "pdf": {}, - "vc": {} - }, - "response": "Confirm", - "reason": "" + "evidence": { + "website": "", + "pdf": {}, + "vc": {} + }, + "response": "Confirm", + "reason": "" }, "P3.1.17": { - "evidence": { - "website": "", - "pdf": {}, - "vc": {} - }, - "response": "Confirm", - "reason": "" + "evidence": { + "website": "", + "pdf": {}, + "vc": {} + }, + "response": "Confirm", + "reason": "" }, "P3.1.18": { - "evidence": { - "website": "", - "pdf": {}, - "vc": {} - }, - "response": "Confirm", - "reason": "" + "evidence": { + "website": "", + "pdf": {}, + "vc": {} + }, + "response": "Confirm", + "reason": "" }, "P3.1.19": { - "evidence": { - "website": "", - "pdf": {}, - "vc": {} - }, - "response": "Confirm", - "reason": "" + "evidence": { + "website": "", + "pdf": {}, + "vc": {} + }, + "response": "Confirm", + "reason": "" }, "P3.1.20": { - "evidence": { - "website": "", - "pdf": {}, - "vc": {} - }, - "response": "Confirm", - "reason": "" + "evidence": { + "website": "", + "pdf": {}, + "vc": {} + }, + "response": "Confirm", + "reason": "" }, "P4.1.1": { - "evidence": { - "website": "", - "pdf": {}, - "vc": {} - }, - "response": "Confirm", - "reason": "" + "evidence": { + "website": "", + "pdf": {}, + "vc": {} + }, + "response": "Confirm", + "reason": "" }, "P4.1.2": { - "evidence": { - "website": "", - "pdf": {}, - "vc": {} - }, - "response": "Confirm", - "reason": "" + "evidence": { + "website": "", + "pdf": {}, + "vc": {} + }, + "response": "Confirm", + "reason": "" }, "P5.1.1": { - "evidence": { - "website": "", - "pdf": {}, - "vc": {} - }, - "response": "Confirm", - "reason": "" + "evidence": { + "website": "", + "pdf": {}, + "vc": {} + }, + "response": "Confirm", + "reason": "" }, "P5.1.2": { - "evidence": { - "website": "", - "pdf": {}, - "vc": {} - }, - "response": "Confirm", - "reason": "" + "evidence": { + "website": "", + "pdf": {}, + "vc": {} + }, + "response": "Confirm", + "reason": "" }, "P5.1.3": { - "evidence": { - "website": "", - "pdf": {}, - "vc": {} - }, - "response": "Confirm", - "reason": "" + "evidence": { + "website": "", + "pdf": {}, + "vc": {} + }, + "response": "Confirm", + "reason": "" }, "P5.1.4": { - "evidence": { - "website": "", - "pdf": {}, - "vc": {} - }, - "response": "Confirm", - "reason": "" + "evidence": { + "website": "", + "pdf": {}, + "vc": {} + }, + "response": "Confirm", + "reason": "" }, "P5.1.5": { - "evidence": { - "website": "", - "pdf": {}, - "vc": {} - }, - "response": "Confirm", - "reason": "" + "evidence": { + "website": "", + "pdf": {}, + "vc": {} + }, + "response": "Confirm", + "reason": "" }, "P5.1.6": { - "evidence": { - "website": "", - "pdf": {}, - "vc": {} - }, - "response": "Confirm", - "reason": "" + "evidence": { + "website": "", + "pdf": {}, + "vc": {} + }, + "response": "Confirm", + "reason": "" }, "P5.1.7": { - "evidence": { - "website": "", - "pdf": {}, - "vc": {} - }, - "response": "Confirm", - "reason": "" + "evidence": { + "website": "", + "pdf": {}, + "vc": {} + }, + "response": "Confirm", + "reason": "" }, "P5.2.1": { - "evidence": { - "website": "", - "pdf": {}, - "vc": {} - }, - "response": "Confirm", - "reason": "" + "evidence": { + "website": "", + "pdf": {}, + "vc": {} + }, + "response": "Confirm", + "reason": "" } - } + } } } } From f982ab2b5fe9f52b646bb0ceddcca00ec2db6fe5 Mon Sep 17 00:00:00 2001 From: Viraj Patva Date: Thu, 23 Nov 2023 16:01:32 +0530 Subject: [PATCH 10/26] fix : w3c url fix --- src/assets/credential.json | 315 ++++++++++++++++++++++++++++++++++ src/assets/jws-2020.json | 78 +++++++++ src/utils/common-functions.ts | 33 +++- src/utils/constants.ts | 6 + 4 files changed, 424 insertions(+), 8 deletions(-) create mode 100644 src/assets/credential.json create mode 100644 src/assets/jws-2020.json diff --git a/src/assets/credential.json b/src/assets/credential.json new file mode 100644 index 0000000..83fa640 --- /dev/null +++ b/src/assets/credential.json @@ -0,0 +1,315 @@ +{ + "@context": { + "@version": 1.1, + "@protected": true, + "id": "@id", + "type": "@type", + "VerifiableCredential": { + "@id": "https://www.w3.org/2018/credentials#VerifiableCredential", + "@context": { + "@version": 1.1, + "@protected": true, + "id": "@id", + "type": "@type", + "cred": "https://www.w3.org/2018/credentials#", + "sec": "https://w3id.org/security#", + "xsd": "http://www.w3.org/2001/XMLSchema#", + "credentialSchema": { + "@id": "cred:credentialSchema", + "@type": "@id", + "@context": { + "@version": 1.1, + "@protected": true, + "id": "@id", + "type": "@type", + "cred": "https://www.w3.org/2018/credentials#", + "JsonSchemaValidator2018": "cred:JsonSchemaValidator2018" + } + }, + "credentialStatus": { + "@id": "cred:credentialStatus", + "@type": "@id" + }, + "credentialSubject": { + "@id": "cred:credentialSubject", + "@type": "@id" + }, + "evidence": { + "@id": "cred:evidence", + "@type": "@id" + }, + "expirationDate": { + "@id": "cred:expirationDate", + "@type": "xsd:dateTime" + }, + "holder": { + "@id": "cred:holder", + "@type": "@id" + }, + "issued": { + "@id": "cred:issued", + "@type": "xsd:dateTime" + }, + "issuer": { + "@id": "cred:issuer", + "@type": "@id" + }, + "issuanceDate": { + "@id": "cred:issuanceDate", + "@type": "xsd:dateTime" + }, + "proof": { + "@id": "sec:proof", + "@type": "@id", + "@container": "@graph" + }, + "refreshService": { + "@id": "cred:refreshService", + "@type": "@id", + "@context": { + "@version": 1.1, + "@protected": true, + "id": "@id", + "type": "@type", + "cred": "https://www.w3.org/2018/credentials#", + "ManualRefreshService2018": "cred:ManualRefreshService2018" + } + }, + "termsOfUse": { + "@id": "cred:termsOfUse", + "@type": "@id" + }, + "validFrom": { + "@id": "cred:validFrom", + "@type": "xsd:dateTime" + }, + "validUntil": { + "@id": "cred:validUntil", + "@type": "xsd:dateTime" + } + } + }, + "VerifiablePresentation": { + "@id": "https://www.w3.org/2018/credentials#VerifiablePresentation", + "@context": { + "@version": 1.1, + "@protected": true, + "id": "@id", + "type": "@type", + "cred": "https://www.w3.org/2018/credentials#", + "sec": "https://w3id.org/security#", + "holder": { + "@id": "cred:holder", + "@type": "@id" + }, + "proof": { + "@id": "sec:proof", + "@type": "@id", + "@container": "@graph" + }, + "verifiableCredential": { + "@id": "cred:verifiableCredential", + "@type": "@id", + "@container": "@graph" + } + } + }, + "EcdsaSecp256k1Signature2019": { + "@id": "https://w3id.org/security#EcdsaSecp256k1Signature2019", + "@context": { + "@version": 1.1, + "@protected": true, + "id": "@id", + "type": "@type", + "sec": "https://w3id.org/security#", + "xsd": "http://www.w3.org/2001/XMLSchema#", + "challenge": "sec:challenge", + "created": { + "@id": "http://purl.org/dc/terms/created", + "@type": "xsd:dateTime" + }, + "domain": "sec:domain", + "expires": { + "@id": "sec:expiration", + "@type": "xsd:dateTime" + }, + "jws": "sec:jws", + "nonce": "sec:nonce", + "proofPurpose": { + "@id": "sec:proofPurpose", + "@type": "@vocab", + "@context": { + "@version": 1.1, + "@protected": true, + "id": "@id", + "type": "@type", + "sec": "https://w3id.org/security#", + "assertionMethod": { + "@id": "sec:assertionMethod", + "@type": "@id", + "@container": "@set" + }, + "authentication": { + "@id": "sec:authenticationMethod", + "@type": "@id", + "@container": "@set" + } + } + }, + "proofValue": "sec:proofValue", + "verificationMethod": { + "@id": "sec:verificationMethod", + "@type": "@id" + } + } + }, + "EcdsaSecp256r1Signature2019": { + "@id": "https://w3id.org/security#EcdsaSecp256r1Signature2019", + "@context": { + "@version": 1.1, + "@protected": true, + "id": "@id", + "type": "@type", + "sec": "https://w3id.org/security#", + "xsd": "http://www.w3.org/2001/XMLSchema#", + "challenge": "sec:challenge", + "created": { + "@id": "http://purl.org/dc/terms/created", + "@type": "xsd:dateTime" + }, + "domain": "sec:domain", + "expires": { + "@id": "sec:expiration", + "@type": "xsd:dateTime" + }, + "jws": "sec:jws", + "nonce": "sec:nonce", + "proofPurpose": { + "@id": "sec:proofPurpose", + "@type": "@vocab", + "@context": { + "@version": 1.1, + "@protected": true, + "id": "@id", + "type": "@type", + "sec": "https://w3id.org/security#", + "assertionMethod": { + "@id": "sec:assertionMethod", + "@type": "@id", + "@container": "@set" + }, + "authentication": { + "@id": "sec:authenticationMethod", + "@type": "@id", + "@container": "@set" + } + } + }, + "proofValue": "sec:proofValue", + "verificationMethod": { + "@id": "sec:verificationMethod", + "@type": "@id" + } + } + }, + "Ed25519Signature2018": { + "@id": "https://w3id.org/security#Ed25519Signature2018", + "@context": { + "@version": 1.1, + "@protected": true, + "id": "@id", + "type": "@type", + "sec": "https://w3id.org/security#", + "xsd": "http://www.w3.org/2001/XMLSchema#", + "challenge": "sec:challenge", + "created": { + "@id": "http://purl.org/dc/terms/created", + "@type": "xsd:dateTime" + }, + "domain": "sec:domain", + "expires": { + "@id": "sec:expiration", + "@type": "xsd:dateTime" + }, + "jws": "sec:jws", + "nonce": "sec:nonce", + "proofPurpose": { + "@id": "sec:proofPurpose", + "@type": "@vocab", + "@context": { + "@version": 1.1, + "@protected": true, + "id": "@id", + "type": "@type", + "sec": "https://w3id.org/security#", + "assertionMethod": { + "@id": "sec:assertionMethod", + "@type": "@id", + "@container": "@set" + }, + "authentication": { + "@id": "sec:authenticationMethod", + "@type": "@id", + "@container": "@set" + } + } + }, + "proofValue": "sec:proofValue", + "verificationMethod": { + "@id": "sec:verificationMethod", + "@type": "@id" + } + } + }, + "RsaSignature2018": { + "@id": "https://w3id.org/security#RsaSignature2018", + "@context": { + "@version": 1.1, + "@protected": true, + "challenge": "sec:challenge", + "created": { + "@id": "http://purl.org/dc/terms/created", + "@type": "xsd:dateTime" + }, + "domain": "sec:domain", + "expires": { + "@id": "sec:expiration", + "@type": "xsd:dateTime" + }, + "jws": "sec:jws", + "nonce": "sec:nonce", + "proofPurpose": { + "@id": "sec:proofPurpose", + "@type": "@vocab", + "@context": { + "@version": 1.1, + "@protected": true, + "id": "@id", + "type": "@type", + "sec": "https://w3id.org/security#", + "assertionMethod": { + "@id": "sec:assertionMethod", + "@type": "@id", + "@container": "@set" + }, + "authentication": { + "@id": "sec:authenticationMethod", + "@type": "@id", + "@container": "@set" + } + } + }, + "proofValue": "sec:proofValue", + "verificationMethod": { + "@id": "sec:verificationMethod", + "@type": "@id" + } + } + }, + "proof": { + "@id": "https://w3id.org/security#proof", + "@type": "@id", + "@container": "@graph" + } + } +} diff --git a/src/assets/jws-2020.json b/src/assets/jws-2020.json new file mode 100644 index 0000000..04e0d5c --- /dev/null +++ b/src/assets/jws-2020.json @@ -0,0 +1,78 @@ +{ + "@context": { + "privateKeyJwk": { + "@id": "https://w3id.org/security#privateKeyJwk", + "@type": "@json" + }, + "JsonWebKey2020": { + "@id": "https://w3id.org/security#JsonWebKey2020", + "@context": { + "@protected": true, + "id": "@id", + "type": "@type", + "publicKeyJwk": { + "@id": "https://w3id.org/security#publicKeyJwk", + "@type": "@json" + } + } + }, + "JsonWebSignature2020": { + "@id": "https://w3id.org/security#JsonWebSignature2020", + "@context": { + "@protected": true, + "id": "@id", + "type": "@type", + "challenge": "https://w3id.org/security#challenge", + "created": { + "@id": "http://purl.org/dc/terms/created", + "@type": "http://www.w3.org/2001/XMLSchema#dateTime" + }, + "domain": "https://w3id.org/security#domain", + "expires": { + "@id": "https://w3id.org/security#expiration", + "@type": "http://www.w3.org/2001/XMLSchema#dateTime" + }, + "jws": "https://w3id.org/security#jws", + "nonce": "https://w3id.org/security#nonce", + "proofPurpose": { + "@id": "https://w3id.org/security#proofPurpose", + "@type": "@vocab", + "@context": { + "@protected": true, + "id": "@id", + "type": "@type", + "assertionMethod": { + "@id": "https://w3id.org/security#assertionMethod", + "@type": "@id", + "@container": "@set" + }, + "authentication": { + "@id": "https://w3id.org/security#authenticationMethod", + "@type": "@id", + "@container": "@set" + }, + "capabilityInvocation": { + "@id": "https://w3id.org/security#capabilityInvocationMethod", + "@type": "@id", + "@container": "@set" + }, + "capabilityDelegation": { + "@id": "https://w3id.org/security#capabilityDelegationMethod", + "@type": "@id", + "@container": "@set" + }, + "keyAgreement": { + "@id": "https://w3id.org/security#keyAgreementMethod", + "@type": "@id", + "@container": "@set" + } + } + }, + "verificationMethod": { + "@id": "https://w3id.org/security#verificationMethod", + "@type": "@id" + } + } + } + } +} diff --git a/src/utils/common-functions.ts b/src/utils/common-functions.ts index c43e56a..8d4459c 100644 --- a/src/utils/common-functions.ts +++ b/src/utils/common-functions.ts @@ -1,5 +1,5 @@ import { DidDocument, Service } from '../interface/interface' -import { AppMessages, LABEL_LEVEL_RULE } from './constants' +import { AppMessages, LABEL_LEVEL_RULE, W3C_CONTEXT } from './constants' namespace CommonFunctions { export class Utils { @@ -44,7 +44,7 @@ namespace CommonFunctions { 'https://registry.lab.gaia-x.eu/development/api/trusted-shape-registry/v1/shapes/jsonld/trustframework#' ], type: ['VerifiableCredential'], - id: didId, + id: participantURL, issuer: didId, issuanceDate: new Date().toISOString(), credentialSubject: { @@ -86,7 +86,7 @@ namespace CommonFunctions { id: tandcsURL }, issuer: didId, - id: didId + id: tandcsURL } return verifiableCredential } @@ -119,7 +119,7 @@ namespace CommonFunctions { { '@context': ['https://www.w3.org/2018/credentials/v1', 'https://registry.lab.gaia-x.eu/development/api/trusted-shape-registry/v1/shapes/jsonld/trustframework#'], type: ['VerifiableCredential'], - id: didId, + id: serviceComplianceUrl, issuer: didId, issuanceDate: new Date().toISOString(), credentialSubject: [ @@ -213,10 +213,27 @@ namespace CommonFunctions { async normalize(jsonld: any, payload: object) { try { - const canonized = await jsonld.canonize(payload, { - algorithm: 'URDNA2015', - format: 'application/n-quads' - }) + const nodeDocumentLoader = jsonld.documentLoaders.node() + const customLoader = async (url: string) => { + if (url in W3C_CONTEXT) { + return { + contextUrl: null, // this is for a context via a link header + document: W3C_CONTEXT[url], // this is the actual document that was loaded + documentUrl: url // this is the actual context URL after redirects + } + } + // call the default documentLoader + return nodeDocumentLoader(url) + } + jsonld.documentLoader = customLoader + const canonized = await jsonld.canonize( + payload, + { + algorithm: 'URDNA2015', + format: 'application/n-quads' + }, + { nodeDocumentLoader: customLoader } + ) if (canonized === '') throw new Error('Canonized SD is empty') return canonized } catch (error) { diff --git a/src/utils/constants.ts b/src/utils/constants.ts index e71d21e..8ec914a 100644 --- a/src/utils/constants.ts +++ b/src/utils/constants.ts @@ -1,3 +1,5 @@ +import W3C_Credential from '../assets/credential.json' +import W3C_JWS from '../assets/jws-2020.json' export class AppConst { static readonly RSA_ALGO = 'PS256' static readonly LEGAL_PARTICIPANT = 'LegalParticipant' @@ -92,3 +94,7 @@ export const LABEL_LEVEL_RULE: any = { // L2: ['P5.1.1'], // L3: ['P5.1.2', 'P5.1.3', 'P5.1.4', 'P5.1.5', 'P5.1.6', 'P5.1.7'] } +export const W3C_CONTEXT: Record = { + 'https://www.w3.org/2018/credentials/v1': W3C_Credential, + 'https://w3id.org/security/suites/jws-2020/v1': W3C_JWS +} From f60ddfd92f1dae4482624b6ae2d8af1b3317d65e Mon Sep 17 00:00:00 2001 From: Viraj Patva Date: Fri, 24 Nov 2023 10:40:44 +0530 Subject: [PATCH 11/26] fix: changed request body --- src/routes/private.ts | 21 +++++++++------------ src/swagger.json | 19 +++++++++---------- src/utils/common-functions.ts | 2 +- 3 files changed, 19 insertions(+), 23 deletions(-) diff --git a/src/routes/private.ts b/src/routes/private.ts index 06b16fa..a513922 100644 --- a/src/routes/private.ts +++ b/src/routes/private.ts @@ -120,15 +120,13 @@ privateRoute.post( .run(req) await check('data.accessType').not().isEmpty().trim().escape().isIn(AppConst.ACCESS_TYPES).run(req) await check('data.requestType').not().isEmpty().trim().escape().isIn(AppConst.REQUEST_TYPES).run(req) - await check('resource.name').not().isEmpty().trim().escape().run(req) - await check('resource.type').not().isEmpty().trim().escape().run(req) - await check('resource.description').not().isEmpty().trim().escape().run(req) - await check('resource.containsPII').not().isEmpty().trim().escape().run(req) - await check('resource.policy').not().isEmpty().trim().escape().run(req) - await check('resource.license').not().isEmpty().trim().escape().run(req) - await check('resource.copyrightOwnedBy').not().isEmpty().trim().escape().run(req) + await check('data.resource.name').not().isEmpty().trim().escape().run(req) + await check('data.resource.description').not().isEmpty().trim().escape().run(req) + await check('data.resource.containsPII').not().isEmpty().trim().escape().run(req) + await check('data.resource.policy').not().isEmpty().trim().escape().run(req) + await check('data.resource.license').not().isEmpty().trim().escape().run(req) + await check('data.resource.copyrightOwnedBy').not().isEmpty().trim().escape().run(req) } - const errors = validationResult(req) if (!errors.isEmpty()) { const errorsArr = errors.array() @@ -164,10 +162,9 @@ privateRoute.post( } } else if (templateId === AppConst.RESOURCE_CREATION) { const data = JSON.parse(he.decode(JSON.stringify(req.body.data))) - const resource = JSON.parse(he.decode(JSON.stringify(req.body.resource))) const serviceComplianceUrl = tenant ? `https://${domain}/${tenant}/${data.fileName}` : `https://${domain}/.well-known/${data.fileName}` - const resourceComplianceUrl = tenant ? `https://${domain}/${tenant}/${data.fileName}` : `https://${domain}/.well-known/${resource.name.replace(/\s/g, '_')}.json` - selfDescription = Utils.generateServiceOffer(participantURL, didId, serviceComplianceUrl, data, resource, resourceComplianceUrl) + const resourceComplianceUrl = tenant ? `https://${domain}/${tenant}/${data.fileName}` : `https://${domain}/.well-known/${data.resource.name.replace(/\s/g, '_')}.json` + selfDescription = Utils.generateServiceOffer(participantURL, didId, serviceComplianceUrl, data, data.resource, resourceComplianceUrl) const { selfDescriptionCredential } = (await axios.get(participantURL)).data for (let index = 0; index < selfDescriptionCredential.verifiableCredential.length; index++) { @@ -187,7 +184,7 @@ privateRoute.post( selfDescription['verifiableCredential'][index].proof = proof } } - const sd = JSON.stringify(selfDescription) + // const sd = JSON.stringify(selfDescription) const complianceCredential = (await axios.post(process.env.COMPLIANCE_SERVICE as string, selfDescription)).data // const complianceCredential = {} diff --git a/src/swagger.json b/src/swagger.json index 72b76e6..1fcf9dc 100644 --- a/src/swagger.json +++ b/src/swagger.json @@ -114,16 +114,15 @@ "termsAndConditionsHash": "4f598faf41fb29a44d63ec413730d55fabd2d249f1976fee1c8eec8003d7f539", "requestType": "API", "accessType": "digital", - "formatType": "application/json" - }, - "resource": { - "type": "gx:DataResource", - "name": "CES Data Resource", - "description": "Contains GX compliant credentials", - "containsPII": false, - "policy": "default: allow", - "license": "EPL-2.0", - "copyrightOwnedBy": "original owner" + "formatType": "application/json", + "resource": { + "name": "CES Data Resource", + "description": "Contains GX compliant credentials", + "containsPII": false, + "policy": "default: allow", + "license": "EPL-2.0", + "copyrightOwnedBy": "original owner" + } } } } diff --git a/src/utils/common-functions.ts b/src/utils/common-functions.ts index 8d4459c..e148c39 100644 --- a/src/utils/common-functions.ts +++ b/src/utils/common-functions.ts @@ -150,7 +150,7 @@ namespace CommonFunctions { if (resource) { selfDescription.verifiableCredential[0].credentialSubject.push({ '@id': resourceComplianceUrl, - '@type': resource.type, + '@type': 'gx:DataResource', 'gx:name': resource.name, 'gx:description': resource.description, 'gx:containsPII': resource.containsPII == 'true', From 45e00ac95b1342f1c714fc7bdfe7c32a4b8a1522 Mon Sep 17 00:00:00 2001 From: Viraj Patva Date: Fri, 24 Nov 2023 10:45:36 +0530 Subject: [PATCH 12/26] fix: template id fixed --- src/swagger.json | 4 ++-- src/utils/constants.ts | 2 +- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/src/swagger.json b/src/swagger.json index 1fcf9dc..cd1e7b9 100644 --- a/src/swagger.json +++ b/src/swagger.json @@ -100,10 +100,10 @@ } } }, - "ResourceCreation": { + "ServiceOfferingWithResource": { "value": { "domain": "smart99.proofsense.in", - "templateId": "ResourceCreation", + "templateId": "ServiceOfferingWithResource", "privateKeyUrl": "https://example.com", "data": { "name": "AWS S3 Service", diff --git a/src/utils/constants.ts b/src/utils/constants.ts index 8ec914a..bc5bfbc 100644 --- a/src/utils/constants.ts +++ b/src/utils/constants.ts @@ -4,7 +4,7 @@ export class AppConst { static readonly RSA_ALGO = 'PS256' static readonly LEGAL_PARTICIPANT = 'LegalParticipant' static readonly SERVICE_OFFER = 'ServiceOffering' - static readonly RESOURCE_CREATION = 'ResourceCreation' + static readonly RESOURCE_CREATION = 'ServiceOfferingWithResource' static readonly FLATTEN_ENCRYPT_ALGORITHM = 'RSA-OAEP-256' static readonly FLATTEN_ENCRYPT_ENCODING = 'A256GCM' static readonly VERIFY_POLICIES = ['checkSignature', 'gxCompliance'] From af8ec8aa082e6a137c42cfdfd61ef8c37dc51e75 Mon Sep 17 00:00:00 2001 From: Viraj Patva Date: Fri, 24 Nov 2023 17:53:46 +0530 Subject: [PATCH 13/26] fix: template key change --- src/routes/private.ts | 44 +++++++++++-------------------------------- src/swagger.json | 2 +- 2 files changed, 12 insertions(+), 34 deletions(-) diff --git a/src/routes/private.ts b/src/routes/private.ts index a513922..fdea350 100644 --- a/src/routes/private.ts +++ b/src/routes/private.ts @@ -104,28 +104,12 @@ privateRoute.post( .run(req) await check('data.accessType').not().isEmpty().trim().escape().isIn(AppConst.ACCESS_TYPES).run(req) await check('data.requestType').not().isEmpty().trim().escape().isIn(AppConst.REQUEST_TYPES).run(req) - } else if (templateId === AppConst.RESOURCE_CREATION) { - await check('data.name').not().isEmpty().trim().escape().run(req) - await check('data.description').not().isEmpty().trim().escape().run(req) - await check('data.fileName').not().isEmpty().trim().escape().run(req) - await check('data.policyUrl').not().isEmpty().trim().escape().run(req) - await check('data.termsAndConditionsUrl').not().isEmpty().trim().escape().run(req) - await check('data.termsAndConditionsHash').not().isEmpty().trim().escape().run(req) - await check('data.formatType') - .not() - .isEmpty() - .trim() - .escape() - .custom((val) => typer.test(he.decode(val))) - .run(req) - await check('data.accessType').not().isEmpty().trim().escape().isIn(AppConst.ACCESS_TYPES).run(req) - await check('data.requestType').not().isEmpty().trim().escape().isIn(AppConst.REQUEST_TYPES).run(req) - await check('data.resource.name').not().isEmpty().trim().escape().run(req) - await check('data.resource.description').not().isEmpty().trim().escape().run(req) - await check('data.resource.containsPII').not().isEmpty().trim().escape().run(req) - await check('data.resource.policy').not().isEmpty().trim().escape().run(req) - await check('data.resource.license').not().isEmpty().trim().escape().run(req) - await check('data.resource.copyrightOwnedBy').not().isEmpty().trim().escape().run(req) + await check('data.resource.name').not().optional().isEmpty().trim().escape().run(req) + await check('data.resource.description').optional().not().isEmpty().trim().escape().run(req) + await check('data.resource.containsPII').optional().not().isEmpty().trim().escape().run(req) + await check('data.resource.policy').optional().not().isEmpty().trim().escape().run(req) + await check('data.resource.license').optional().not().isEmpty().trim().escape().run(req) + await check('data.resource.copyrightOwnedBy').optional().not().isEmpty().trim().escape().run(req) } const errors = validationResult(req) if (!errors.isEmpty()) { @@ -153,18 +137,12 @@ privateRoute.post( const data = JSON.parse(he.decode(JSON.stringify(req.body.data))) const serviceComplianceUrl = tenant ? `https://${domain}/${tenant}/${data.fileName}` : `https://${domain}/.well-known/${data.fileName}` - selfDescription = Utils.generateServiceOffer(participantURL, didId, serviceComplianceUrl, data) - const { selfDescriptionCredential } = (await axios.get(participantURL)).data - - for (let index = 0; index < selfDescriptionCredential.verifiableCredential.length; index++) { - const vc = selfDescriptionCredential.verifiableCredential[index] - selfDescription.verifiableCredential.push(vc) + if (data.resource) { + const resourceComplianceUrl = serviceComplianceUrl + '#1' + selfDescription = Utils.generateServiceOffer(participantURL, didId, serviceComplianceUrl, data, data.resource, resourceComplianceUrl) + } else { + selfDescription = Utils.generateServiceOffer(participantURL, didId, serviceComplianceUrl, data) } - } else if (templateId === AppConst.RESOURCE_CREATION) { - const data = JSON.parse(he.decode(JSON.stringify(req.body.data))) - const serviceComplianceUrl = tenant ? `https://${domain}/${tenant}/${data.fileName}` : `https://${domain}/.well-known/${data.fileName}` - const resourceComplianceUrl = tenant ? `https://${domain}/${tenant}/${data.fileName}` : `https://${domain}/.well-known/${data.resource.name.replace(/\s/g, '_')}.json` - selfDescription = Utils.generateServiceOffer(participantURL, didId, serviceComplianceUrl, data, data.resource, resourceComplianceUrl) const { selfDescriptionCredential } = (await axios.get(participantURL)).data for (let index = 0; index < selfDescriptionCredential.verifiableCredential.length; index++) { diff --git a/src/swagger.json b/src/swagger.json index cd1e7b9..fe67b05 100644 --- a/src/swagger.json +++ b/src/swagger.json @@ -103,7 +103,7 @@ "ServiceOfferingWithResource": { "value": { "domain": "smart99.proofsense.in", - "templateId": "ServiceOfferingWithResource", + "templateId": "ServiceOffering", "privateKeyUrl": "https://example.com", "data": { "name": "AWS S3 Service", From fa8e592df210a9b52df09496571145d971629cd7 Mon Sep 17 00:00:00 2001 From: Viraj Patva Date: Mon, 27 Nov 2023 11:57:56 +0530 Subject: [PATCH 14/26] feat: CES Event Post serivce created --- src/routes/private.ts | 2 +- src/utils/common-functions.ts | 17 +++++++++++++++++ 2 files changed, 18 insertions(+), 1 deletion(-) diff --git a/src/routes/private.ts b/src/routes/private.ts index fdea350..d431e38 100644 --- a/src/routes/private.ts +++ b/src/routes/private.ts @@ -172,7 +172,7 @@ privateRoute.post( selfDescriptionCredential: selfDescription, complianceCredential: complianceCredential } - + Utils.CESCompliance(axios, complianceCredential) res.status(200).json({ data: { verifiableCredential: completeSd }, message: AppMessages.VP_SUCCESS diff --git a/src/utils/common-functions.ts b/src/utils/common-functions.ts index e148c39..952be0a 100644 --- a/src/utils/common-functions.ts +++ b/src/utils/common-functions.ts @@ -416,6 +416,23 @@ namespace CommonFunctions { return resultLabelLevel } + + CESCompliance = async (axios: any, complianceCred: any) => { + try { + const reqBody = { + specversion: '1.0', + type: 'eu.gaia-x.credential', + source: '/mycontext', + time: complianceCred.issuanceDat2, + datacontenttype: 'application/json', + data: complianceCred + } + const response = await axios.post(process.env.CES_COMPLIANCE + '/credentials-events', reqBody) + console.log(response) + } catch (err) { + console.error(err) + } + } } } From 3656731a5cf023b01455c3242db311c303132f89 Mon Sep 17 00:00:00 2001 From: Viraj Patva Date: Mon, 27 Nov 2023 12:00:05 +0530 Subject: [PATCH 15/26] fix : removed unused console.log --- src/utils/common-functions.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/utils/common-functions.ts b/src/utils/common-functions.ts index 952be0a..40a901e 100644 --- a/src/utils/common-functions.ts +++ b/src/utils/common-functions.ts @@ -428,7 +428,7 @@ namespace CommonFunctions { data: complianceCred } const response = await axios.post(process.env.CES_COMPLIANCE + '/credentials-events', reqBody) - console.log(response) + // console.log(response) } catch (err) { console.error(err) } From a123549ddf46c295021fae9678633436e391ab0b Mon Sep 17 00:00:00 2001 From: Viraj Patva Date: Mon, 27 Nov 2023 12:09:18 +0530 Subject: [PATCH 16/26] doc: compliance logs added --- src/utils/common-functions.ts | 10 +++++++--- 1 file changed, 7 insertions(+), 3 deletions(-) diff --git a/src/utils/common-functions.ts b/src/utils/common-functions.ts index 40a901e..69a9a15 100644 --- a/src/utils/common-functions.ts +++ b/src/utils/common-functions.ts @@ -423,14 +423,18 @@ namespace CommonFunctions { specversion: '1.0', type: 'eu.gaia-x.credential', source: '/mycontext', - time: complianceCred.issuanceDat2, + time: complianceCred.issuanceDate, datacontenttype: 'application/json', data: complianceCred } const response = await axios.post(process.env.CES_COMPLIANCE + '/credentials-events', reqBody) - // console.log(response) + if (response == 201) { + console.log('successfully created compliance') + } else { + console.error('❌ error in getting compliance') + } } catch (err) { - console.error(err) + console.error('❌ error in getting compliance', err) } } } From 43429f633628412b80d9676ccc1a02b74ce90cfe Mon Sep 17 00:00:00 2001 From: Viraj Patva Date: Mon, 27 Nov 2023 12:21:55 +0530 Subject: [PATCH 17/26] fix : status code --- src/utils/common-functions.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/utils/common-functions.ts b/src/utils/common-functions.ts index 69a9a15..eda78d1 100644 --- a/src/utils/common-functions.ts +++ b/src/utils/common-functions.ts @@ -428,7 +428,7 @@ namespace CommonFunctions { data: complianceCred } const response = await axios.post(process.env.CES_COMPLIANCE + '/credentials-events', reqBody) - if (response == 201) { + if (response.status == 201) { console.log('successfully created compliance') } else { console.error('❌ error in getting compliance') From 34a26150137396d268c145ab85b75632cbb122f0 Mon Sep 17 00:00:00 2001 From: Ronak Thacker Date: Thu, 7 Dec 2023 09:57:49 +0530 Subject: [PATCH 18/26] feat: url updated --- src/routes/private.ts | 6 ++---- 1 file changed, 2 insertions(+), 4 deletions(-) diff --git a/src/routes/private.ts b/src/routes/private.ts index d431e38..c03da24 100644 --- a/src/routes/private.ts +++ b/src/routes/private.ts @@ -125,12 +125,10 @@ privateRoute.post( if (templateId === AppConst.LEGAL_PARTICIPANT) { const { legalName, legalRegistrationType, legalRegistrationNumber, headquarterAddress, legalAddress } = req.body.data - const legalRegistrationNumberVCUrl = tenant - ? `https://${domain}/${tenant}/legalRegistrationNumberVC.json` - : `https://${domain}/.well-known/legalRegistrationNumberVC.json` + const legalRegistrationNumberVCUrl = participantURL + "#1" selfDescription = Utils.generateLegalPerson(participantURL, didId, legalName, headquarterAddress, legalAddress, legalRegistrationNumberVCUrl) const regVC = await Utils.generateRegistrationNumber(axios, didId, legalRegistrationType, legalRegistrationNumber, legalRegistrationNumberVCUrl) - const tandcsURL = tenant ? `https://${domain}/${tenant}/tandcs.json` : `https://${domain}/.well-known/tandcs.json` + const tandcsURL = participantURL + "#2" const termsVC = await Utils.generateTermsAndConditions(axios, didId, tandcsURL) selfDescription['verifiableCredential'].push(regVC, termsVC) } else if (templateId === AppConst.SERVICE_OFFER) { From 57d3cdf382f2ac9b06bcf541a46250b40ffd9060 Mon Sep 17 00:00:00 2001 From: Ronak Thacker Date: Thu, 7 Dec 2023 10:15:04 +0530 Subject: [PATCH 19/26] log added --- src/routes/private.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/routes/private.ts b/src/routes/private.ts index c03da24..2b0291c 100644 --- a/src/routes/private.ts +++ b/src/routes/private.ts @@ -160,7 +160,7 @@ privateRoute.post( selfDescription['verifiableCredential'][index].proof = proof } } - // const sd = JSON.stringify(selfDescription) + console.log(JSON.stringify(selfDescription)) const complianceCredential = (await axios.post(process.env.COMPLIANCE_SERVICE as string, selfDescription)).data // const complianceCredential = {} From 11ea906e388c85bb312745a4de5053005ef65cd6 Mon Sep 17 00:00:00 2001 From: Ronak Thacker Date: Thu, 7 Dec 2023 10:48:23 +0530 Subject: [PATCH 20/26] fix: legalRegistrationNumberVCUrl --- src/utils/common-functions.ts | 1 + 1 file changed, 1 insertion(+) diff --git a/src/utils/common-functions.ts b/src/utils/common-functions.ts index eda78d1..863a4a9 100644 --- a/src/utils/common-functions.ts +++ b/src/utils/common-functions.ts @@ -93,6 +93,7 @@ namespace CommonFunctions { async generateRegistrationNumber(axios: any, didId: string, legalRegistrationType: string, legalRegistrationNumber: string, legalRegistrationNumberVCUrl: string) { try { + legalRegistrationNumberVCUrl = legalRegistrationNumberVCUrl.replace('#', '%23') const request = { '@context': ['https://registry.lab.gaia-x.eu/development/api/trusted-shape-registry/v1/shapes/jsonld/participant'], type: 'gx:legalRegistrationNumber', From e817b17662290338ace1b938494e47baaacfe6ad Mon Sep 17 00:00:00 2001 From: Ronak Thacker Date: Thu, 7 Dec 2023 11:01:37 +0530 Subject: [PATCH 21/26] fix: legalRegistrationNumberVCUrl --- src/utils/common-functions.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/utils/common-functions.ts b/src/utils/common-functions.ts index 863a4a9..09c7e17 100644 --- a/src/utils/common-functions.ts +++ b/src/utils/common-functions.ts @@ -93,13 +93,13 @@ namespace CommonFunctions { async generateRegistrationNumber(axios: any, didId: string, legalRegistrationType: string, legalRegistrationNumber: string, legalRegistrationNumberVCUrl: string) { try { - legalRegistrationNumberVCUrl = legalRegistrationNumberVCUrl.replace('#', '%23') const request = { '@context': ['https://registry.lab.gaia-x.eu/development/api/trusted-shape-registry/v1/shapes/jsonld/participant'], type: 'gx:legalRegistrationNumber', id: legalRegistrationNumberVCUrl, [`gx:${legalRegistrationType}`]: legalRegistrationNumber } + legalRegistrationNumberVCUrl = legalRegistrationNumberVCUrl.replace('#', '%23') console.log(request) const regVC = await axios.post(`${process.env.REGISTRATION_SERVICE as string}?vcid=${legalRegistrationNumberVCUrl}`, request) // console.log(JSON.stringify(regVC.data)) From 2cabe6e4cbff5f3bbb3d75cb92644df5e50f6ac0 Mon Sep 17 00:00:00 2001 From: Ronak Thacker Date: Thu, 7 Dec 2023 12:05:04 +0530 Subject: [PATCH 22/26] fix: name in service offer --- src/utils/common-functions.ts | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/utils/common-functions.ts b/src/utils/common-functions.ts index 09c7e17..0a1f956 100644 --- a/src/utils/common-functions.ts +++ b/src/utils/common-functions.ts @@ -111,7 +111,7 @@ namespace CommonFunctions { } generateServiceOffer(participantURL: string, didId: string, serviceComplianceUrl: string, data: any, resource?: any, resourceComplianceUrl?: string): object { - const { serviceName, description, policyUrl, termsAndConditionsUrl, termsAndConditionsHash, formatType, accessType, requestType } = data + const { name, description, policyUrl, termsAndConditionsUrl, termsAndConditionsHash, formatType, accessType, requestType } = data const selfDescription: any = { '@context': 'https://www.w3.org/2018/credentials/v1', @@ -126,7 +126,7 @@ namespace CommonFunctions { credentialSubject: [ { id: serviceComplianceUrl, - 'gx:name': serviceName, + 'gx:name': name, 'gx:description': description, type: 'gx:ServiceOffering', 'gx:providedBy': { From 329ce6117035e1dd102aa1a38034ce07bf368edf Mon Sep 17 00:00:00 2001 From: Viraj Patva Date: Wed, 17 Apr 2024 12:16:31 +0530 Subject: [PATCH 23/26] feat: resource changes --- src/utils/common-functions.ts | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/src/utils/common-functions.ts b/src/utils/common-functions.ts index 0a1f956..9e11225 100644 --- a/src/utils/common-functions.ts +++ b/src/utils/common-functions.ts @@ -150,8 +150,8 @@ namespace CommonFunctions { if (resource) { selfDescription.verifiableCredential[0].credentialSubject.push({ - '@id': resourceComplianceUrl, - '@type': 'gx:DataResource', + id: resourceComplianceUrl, + type: 'gx:DataResource', 'gx:name': resource.name, 'gx:description': resource.description, 'gx:containsPII': resource.containsPII == 'true', @@ -159,10 +159,10 @@ namespace CommonFunctions { 'gx:license': resource.license, 'gx:copyrightOwnedBy': resource.copyrightOwnedBy, 'gx:producedBy': { - '@id': participantURL + id: participantURL }, 'gx:exposedThrough': { - '@id': serviceComplianceUrl + id: serviceComplianceUrl } }) } From 9fdeff536b2895a1aae8965fbd052324f22a8aeb Mon Sep 17 00:00:00 2001 From: Viraj Patva Date: Wed, 17 Apr 2024 18:10:38 +0530 Subject: [PATCH 24/26] fix: service endpoint added --- src/utils/common-functions.ts | 10 +++++++++- 1 file changed, 9 insertions(+), 1 deletion(-) diff --git a/src/utils/common-functions.ts b/src/utils/common-functions.ts index 9e11225..d02d7a0 100644 --- a/src/utils/common-functions.ts +++ b/src/utils/common-functions.ts @@ -16,7 +16,7 @@ namespace CommonFunctions { publicKeyJwk: publicKeyJwk } ], - assertionMethod: [`${didId}#JWK2020-RSA`] + assertionMethod: [`${didId}`] } if (services) { for (let index = 0; index < services.length; index++) { @@ -27,6 +27,14 @@ namespace CommonFunctions { service['id'] = `${didId}#${services[index].type.toLocaleLowerCase()}` did.service?.push(service) } + } else { + did['service'] = [ + { + id: `${didId}#credentialregistry`, + serviceEndpoint: 'https://wizard-api.dev.smart-x.smartsenselabs.com/public/policy/evaluate', + type: 'CredentialRegistry' + } + ] } // const data = JSON.stringify(did, null, 2); return did From e3009be3e3fce352fd39164bdf001bbfcc38c6f9 Mon Sep 17 00:00:00 2001 From: Viraj Patva Date: Wed, 17 Apr 2024 20:46:28 +0530 Subject: [PATCH 25/26] feat : policy change --- src/utils/common-functions.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/utils/common-functions.ts b/src/utils/common-functions.ts index d02d7a0..fe0fb0a 100644 --- a/src/utils/common-functions.ts +++ b/src/utils/common-functions.ts @@ -140,7 +140,7 @@ namespace CommonFunctions { 'gx:providedBy': { id: participantURL }, - 'gx:policy': policyUrl, + 'gx:policy': [policyUrl], 'gx:termsAndConditions': { 'gx:URL': termsAndConditionsUrl, 'gx:hash': termsAndConditionsHash From 7709eeb7f3f99fd44beff66b61847702281aa383 Mon Sep 17 00:00:00 2001 From: Viraj Patva Date: Thu, 18 Apr 2024 11:34:26 +0530 Subject: [PATCH 26/26] validation added --- src/utils/common-functions.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/utils/common-functions.ts b/src/utils/common-functions.ts index fe0fb0a..2e089c7 100644 --- a/src/utils/common-functions.ts +++ b/src/utils/common-functions.ts @@ -148,7 +148,7 @@ namespace CommonFunctions { 'gx:dataAccountExport': { 'gx:requestType': requestType, 'gx:accessType': accessType, - 'gx:formatType': formatType + 'gx:formatType': [formatType] } } ]