Skip to content

Commit

Permalink
fix: issue import EnvelopedVerifiableCredential (#127)
Browse files Browse the repository at this point in the history
* fix: handle enveloping proof for local storage and import components

Signed-off-by: Nam Hoang <[email protected]>

* fix: test failed on components

* chore: remove the test import configuration

Signed-off-by: Nam Hoang <[email protected]>

* test: update unit test

(cherry picked from commit 18fbd81)

* refactor: import module services

(cherry picked from commit c11f290)

* chore: pass vc api params via props

* refactor: add decodedEnvelopedVC

* refactor: adjust the error message

* test: update unit test

Signed-off-by: Nam Hoang <[email protected]>

* docs: update import and scanning component

Signed-off-by: Nam Hoang <[email protected]>

---------

Signed-off-by: Nam Hoang <[email protected]>
Co-authored-by: Ashley Harwood <[email protected]>
  • Loading branch information
namhoang1604 and ashleythedeveloper authored Oct 28, 2024
1 parent 7ad1b6d commit 31ed1e5
Show file tree
Hide file tree
Showing 50 changed files with 1,382 additions and 376 deletions.
104 changes: 88 additions & 16 deletions app-config.json
Original file line number Diff line number Diff line change
Expand Up @@ -760,7 +760,7 @@
"parameters": [
{
"storageKey": "CherriesFarm_dpps",
"objectKeyPath": "/vc/credentialSubject/productIdentifier/0/identifierValue"
"objectKeyPath": "/decodedEnvelopedVC/credentialSubject/productIdentifier/0/identifierValue"
}
]
}
Expand Down Expand Up @@ -4604,11 +4604,11 @@
"constructData": {
"mappingFields": [
{
"sourcePath": "/vc/credentialSubject/productIdentifier/0/identifierValue",
"sourcePath": "/decodedEnvelopedVC/credentialSubject/productIdentifier/0/identifierValue",
"destinationPath": "/eventID"
},
{
"sourcePath": "/vc/credentialSubject/productIdentifier/0/identifierValue",
"sourcePath": "/decodedEnvelopedVC/credentialSubject/productIdentifier/0/identifierValue",
"destinationPath": "/epcList/index/name"
},
{
Expand Down Expand Up @@ -4748,7 +4748,76 @@
"parameters": [
{
"storageKey": "orchard_facility_transaction_event",
"objectKeyPath": "/vc/credentialSubject/eventID"
"objectKeyPath": "/decodedEnvelopedVC/credentialSubject/eventID"
}
]
}
]
},
{
"name": "Import Credential (QR)",
"id": "import_credential_qr",
"components": [
{
"name": "QRCodeScannerDialogButton",
"type": "EntryData",
"props": {
"style": { "margin": "40px auto", "paddingTop": "40px", "width": "80%" },
"vcOptions": {
"vckitAPIUrl": "http://localhost:3332/agent/routeVerificationCredential",
"headers": {
"Authorization": "Bearer test123"
}
}
}
},
{
"name": "CustomButton",
"type": "Submit",
"props": {}
}
],
"services": [
{
"name": "mergeToLocalStorage",
"parameters": [
{
"storageKey": "CherriesFarm_qr_credential"
}
]
}
]
},
{
"name": "Import Credential (JSON)",
"id": "import_credential_json",
"components": [
{
"name": "ImportButton",
"type": "EntryData",
"props": {
"label": "Import JSON",
"style": { "margin": "40px auto", "paddingTop": "40px", "width": "80%" },
"vcOptions": {
"vckitAPIUrl": "http://localhost:3332/agent/routeVerificationCredential",
"headers": {
"Authorization": "Bearer test123"
}
}
}
},
{
"name": "CustomButton",
"type": "Submit",
"props": {}
}
],
"services": [
{
"name": "mergeToLocalStorage",
"parameters": [
{
"storageKey": "CherriesFarm_json_credential"
}
]
}
Expand Down Expand Up @@ -5502,7 +5571,7 @@
"parameters": [
{
"storageKey": "CherriesFarm_dpps",
"objectKeyPath": "/vc/credentialSubject/productIdentifier/0/identifierValue"
"objectKeyPath": "/decodedEnvelopedVC/credentialSubject/productIdentifier/0/identifierValue"
}
]
}
Expand Down Expand Up @@ -5845,11 +5914,11 @@
"constructData": {
"mappingFields": [
{
"sourcePath": "/vc/credentialSubject/productIdentifier/0/identifierValue",
"sourcePath": "/decodedEnvelopedVC/credentialSubject/productIdentifier/0/identifierValue",
"destinationPath": "/eventID"
},
{
"sourcePath": "/vc/credentialSubject/productIdentifier/0/identifierValue",
"sourcePath": "/decodedEnvelopedVC/credentialSubject/productIdentifier/0/identifierValue",
"destinationPath": "/epcList/index/name"
},
{
Expand Down Expand Up @@ -5989,7 +6058,7 @@
"parameters": [
{
"storageKey": "packhouse_facility_transaction_event",
"objectKeyPath": "/vc/credentialSubject/eventID"
"objectKeyPath": "/decodedEnvelopedVC/credentialSubject/eventID"
}
]
}
Expand Down Expand Up @@ -6743,7 +6812,7 @@
"parameters": [
{
"storageKey": "CherriesFarm_dpps",
"objectKeyPath": "/vc/credentialSubject/productIdentifier/0/identifierValue"
"objectKeyPath": "/decodedEnvelopedVC/credentialSubject/productIdentifier/0/identifierValue"
}
]
}
Expand Down Expand Up @@ -7086,11 +7155,11 @@
"constructData": {
"mappingFields": [
{
"sourcePath": "/vc/credentialSubject/productIdentifier/0/identifierValue",
"sourcePath": "/decodedEnvelopedVC/credentialSubject/productIdentifier/0/identifierValue",
"destinationPath": "/eventID"
},
{
"sourcePath": "/vc/credentialSubject/productIdentifier/0/identifierValue",
"sourcePath": "/decodedEnvelopedVC/credentialSubject/productIdentifier/0/identifierValue",
"destinationPath": "/epcList/index/name"
},
{
Expand Down Expand Up @@ -7230,7 +7299,7 @@
"parameters": [
{
"storageKey": "fumigation_and_freight_forwarding_facility_transaction_event",
"objectKeyPath": "/vc/credentialSubject/eventID"
"objectKeyPath": "/decodedEnvelopedVC/credentialSubject/eventID"
}
]
}
Expand Down Expand Up @@ -7984,7 +8053,7 @@
"parameters": [
{
"storageKey": "CherriesFarm_dpps",
"objectKeyPath": "/vc/credentialSubject/productIdentifier/0/identifierValue"
"objectKeyPath": "/decodedEnvelopedVC/credentialSubject/productIdentifier/0/identifierValue"
}
]
}
Expand Down Expand Up @@ -8327,11 +8396,11 @@
"constructData": {
"mappingFields": [
{
"sourcePath": "/vc/credentialSubject/productIdentifier/0/identifierValue",
"sourcePath": "/decodedEnvelopedVC/credentialSubject/productIdentifier/0/identifierValue",
"destinationPath": "/eventID"
},
{
"sourcePath": "/vc/credentialSubject/productIdentifier/0/identifierValue",
"sourcePath": "/decodedEnvelopedVC/credentialSubject/productIdentifier/0/identifierValue",
"destinationPath": "/epcList/index/name"
},
{
Expand Down Expand Up @@ -8482,6 +8551,9 @@
"type": "application/json",
"href": "http://localhost:3332/agent/routeVerificationCredential",
"hreflang": ["en"],
"apiKey": "test123"
"headers": {
"Authorization": "Bearer test123",
"Content-Type": "application/json"
}
}
}
18 changes: 14 additions & 4 deletions documentation/docs/mock-apps/components/import-button.md
Original file line number Diff line number Diff line change
Expand Up @@ -33,7 +33,17 @@ The ImportButton component is responsible for rendering a button that allows the

### Props

| Property | Required | Description | Type |
| -------- | -------- | ------------------------------- | ------ |
| label | Yes | The label for the import button | String |
| style | No | The style for the component | Object |
| Property | Required | Description | Type |
| --------- | -------- | ----------------------------------------------------------------------------------------------------- | ------ |
| label | Yes | The label for the import button | String |
| style | No | The style for the component | Object |
| type | No | The type of data (should be 'VerifiableCredential' and 'JSON'), the default is 'VerifiableCredential' | String |
| vcOptions | No | The options for the VC data processing | Object |

#### vcOptions

| Property | Required | Description | Type |
| -------------- | -------- | -------------------------------------------------------------------------- | ------ |
| credentialPath | Yes | The path for the credential data | String |
| vckitAPIUrl | No | The URL for the vckit API | String |
| headers | No | The headers for the vckit API, example: { Authorization: "Bearer test123"} | Object |
Original file line number Diff line number Diff line change
Expand Up @@ -32,6 +32,16 @@ The QRCodeScannerDialogButton component is responsible for rendering a button th

### Props

| Property | Required | Description | Type |
| -------- | -------- | --------------------------- | ------ |
| style | No | The style for the component | Object |
| Property | Required | Description | Type |
| --------- | -------- | ----------------------------------------------------------------------------------------------------- | ------ |
| style | No | The style for the component | Object |
| type | No | The type of data (should be 'VerifiableCredential' and 'JSON'), the default is 'VerifiableCredential' | String |
| vcOptions | No | The options for the VC data processing | Object |

#### vcOptions

| Property | Required | Description | Type |
| -------------- | -------- | -------------------------------------------------------------------------- | ------ |
| credentialPath | Yes | The path for the credential data that is fetched from the QR code URL | String |
| vckitAPIUrl | No | The URL for the vckit API | String |
| headers | No | The headers for the vckit API, example: { Authorization: "Bearer test123"} | Object |
117 changes: 105 additions & 12 deletions documentation/docs/mock-apps/components/render-check-list.md
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,6 @@ The RenderCheckList component is responsible for rendering a list of items with
"name": "RenderCheckList",
"type": "EntryData",
"props": {
"requiredFieldPath": "/vc/credentialSubject/eventID",
"checkBoxLabel": "Imported valid json:",
"nestedComponents": [
{
Expand Down Expand Up @@ -48,24 +47,118 @@ The RenderCheckList component is responsible for rendering a list of items with

### Props

| Property | Required | Description | Type |
| ----------------- | -------- | ---------------------------------------------------------- | ------------------------------------------ |
| requiredFieldPath | Yes | The path for the label of the checkbox item | String |
| nestedComponents | Yes | An array of components to be rendered with the loaded data | [Component](/docs/mock-apps/components/)[] |
| checkBoxLabel | Yes | The label for the checkbox list | String |
| style | No | The style for the component | Object |
| Property | Required | Description | Type |
| ----------------- | -------- | ---------------------------------------------------------- | ------------------------------------------ |String |
| nestedComponents | Yes | An array of components to be rendered with the loaded data | [Component](/docs/mock-apps/components/)[] |
| checkBoxLabel | Yes | The label for the checkbox list | String |
| style | No | The style for the component | Object |

## Response Data

The component will return an object with data that is selected by the user from the list of checkboxes. The object will have the following structure:
The data returned by the component will depend on the data type that is imported or scanned by the user. The data will be verified and decoded if it is an enveloped verifiable credential. There are 3 possible cases:

1. If the imported or scanned data type is a `JSON`, the data will be returned without any transformation and have the key as the file name or URL of QRcode.

```json
{
"0123456789": {
// Imported data
"data1.json": {
"foo": "bar" // Imported data
},
"9876543210": {
// Imported data
"data2.json": {
"foo": "bar" // Imported data
}
}
```

2. If the imported or scanned data type is a `VerifiableCredential`, the data will be returned as an object with the key as the file name or URL of QRcode. The imported or scanned VC will be verified based on the `vcOptions` provided in the [Import Button](./import-button) or [QR Code Scanner Dialog Button](./qr-code-scanner-dialog-button) component.

```json
{
"VC1.json": {
"@context": [], // Imported VC
"type": ["VerifiableCredential"]
},
"VC2.json": {
"@context": [], // Imported VC
"type": ["VerifiableCredential"]
}
}
```

3. If the imported or scanned data type is a `VerifiableCredential` and the VC is an enveloped VC, the data will be returned as an object with the key as the file name or URL of QRcode. The imported or scanned VC will be verified and decoded based on the `vcOptions` provided in the [Import Button](./import-button) or [QR Code Scanner Dialog Button](./qr-code-scanner-dialog-button) component. The decoded VC will return the same level path as the original VC.
For example, if the original VC was imported as the whole object of the file, the decoded VC will be returned together with the original VC in an object like below:

```json
// imported VC file
{
"@context": ["https://www.w3.org/ns/credentials/v2"],
"id": "data:application/vc-ld+jwt,jwt",
"type": "EnvelopedVerifiableCredential"
}
```

```json
// return data
{
"VC1.json": {
"vc": {
"@context": ["https://www.w3.org/ns/credentials/v2"],
"id": "data:application/vc-ld+jwt,jwt",
"type": "EnvelopedVerifiableCredential"
},
"decodedEnvelopedVC": {
"@context": ["https://www.w3.org/ns/credentials/v2"],
"type": ["VerifiableCredential"],
"credentialSubject": {
"id": "did:example:123",
"name": "Alice"
}
}
}
}
```

But when imported data has `credentialPath` in `vcOptions`, the decoded VC will be returned with the path specified in `credentialPath` together with the original VC in an object like below:

```json
// vcOptions
{
"credentialPath": "/vc"
}
```

```json
// imported VC file
{
"vc": {
"@context": ["https://www.w3.org/ns/credentials/v2"],
"id": "data:application/vc-ld+jwt,jwt",
"type": "EnvelopedVerifiableCredential"
},
"linkResolver": "https://example.com"
}
```

```json
// return data
{
"VC1.json": {
"vc": {
"vc": {
"@context": ["https://www.w3.org/ns/credentials/v2"],
"id": "data:application/vc-ld+jwt,jwt",
"type": "EnvelopedVerifiableCredential"
},
"decodedEnvelopedVC": {
"@context": ["https://www.w3.org/ns/credentials/v2"],
"type": ["VerifiableCredential"],
"credentialSubject": {
"id": "did:example:123",
"name": "Alice"
}
}
},
"linkResolver": "https://example.com"
}
}
```
Loading

0 comments on commit 31ed1e5

Please sign in to comment.