Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

feat: integrate IDR with mock app #105

Merged
merged 14 commits into from
Sep 24, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -35,6 +35,7 @@ yarn-error.log
testem.log
/typings
.env
minio_data/*

# Yarn
.yarn/*
Expand Down
2,865 changes: 2,865 additions & 0 deletions app-config.acrs.json

Large diffs are not rendered by default.

3,806 changes: 3,768 additions & 38 deletions app-config.json

Large diffs are not rendered by default.

1,232 changes: 1,232 additions & 0 deletions app-config.truff.json

Large diffs are not rendered by default.

72 changes: 71 additions & 1 deletion docker-compose.yml
Original file line number Diff line number Diff line change
Expand Up @@ -47,5 +47,75 @@ services:
- AVAILABLE_BUCKETS=verifiable-credentials,private-verifiable-credentials,epcis-events
- STORAGE_TYPE=local

identity-resolver-service:
# Replace with local or deployed image
image: ghcr.io/pyx-industries/pyx-identity-resolver:latest@sha256:71a02b8b0a2b9c7cc18d33a54060e9af4d543e34bdd6a47c3b3cf4dcadb1711e
ports:
- '3000:3000'
environment:
- OBJECT_STORAGE_ENDPOINT=identity-resolver-service-object-store
- OBJECT_STORAGE_PORT=9000
- OBJECT_STORAGE_USE_SSL=false
- OBJECT_STORAGE_ACCESS_KEY=minioadmin
- OBJECT_STORAGE_SECRET_KEY=minioadmin
- OBJECT_STORAGE_BUCKET_NAME=idr-bucket-1
- OBJECT_STORAGE_PATH_STYLE=true
- IDENTIFIER_PATH=identifiers
- API_KEY=test123
- APP_ENDPOINT=http://localhost:3000
- APP_NAME=IDR-1
- RESOLVER_DOMAIN=http://localhost:3000
- LINK_TYPE_VOC_DOMAIN=http://localhost:3000/voc
- PORT=3000
depends_on:
- identity-resolver-service-object-store

identity-resolver-service-object-store:
image: quay.io/minio/minio:RELEASE.2024-08-17T01-24-54Z-cpuv1
command: server /data --console-address ":9090"
ports:
- '9000:9000'
- '9090:9090'
environment:
- MINIO_ROOT_USER=minioadmin
- MINIO_ROOT_PASSWORD=minioadmin
volumes:
- ./minio_data/identity-resolver-service-object-store:/data

mock-global-gs1-resolver:
# Replace with local or deployed image
image: ghcr.io/pyx-industries/pyx-identity-resolver:latest@sha256:71a02b8b0a2b9c7cc18d33a54060e9af4d543e34bdd6a47c3b3cf4dcadb1711e
ports:
- '3001:3001'
environment:
- OBJECT_STORAGE_ENDPOINT=mock-global-gs1-resolver-object-store
- OBJECT_STORAGE_PORT=9000
- OBJECT_STORAGE_USE_SSL=false
- OBJECT_STORAGE_ACCESS_KEY=minioadmin
- OBJECT_STORAGE_SECRET_KEY=minioadmin
- OBJECT_STORAGE_BUCKET_NAME=idr-bucket-2
- OBJECT_STORAGE_PATH_STYLE=true
- IDENTIFIER_PATH=identifiers
- API_KEY=test456
- APP_ENDPOINT=http://localhost:3001
- APP_NAME=IDR-2
- RESOLVER_DOMAIN=http://localhost:3001
- LINK_TYPE_VOC_DOMAIN=http://localhost:3001/voc
- PORT=3001
depends_on:
- mock-global-gs1-resolver-object-store

mock-global-gs1-resolver-object-store:
image: quay.io/minio/minio:RELEASE.2024-08-17T01-24-54Z-cpuv1
command: server /data --console-address ":9091"
ports:
- '9001:9000'
- '9091:9090'
environment:
- MINIO_ROOT_USER=minioadmin
- MINIO_ROOT_PASSWORD=minioadmin
volumes:
- ./minio_data/mock-global-gs1-resolver-object-store:/data

volumes:
vckit-data:
vckit-data:
25 changes: 14 additions & 11 deletions documentation/docs/mock-apps/common/identify-provider.md
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,8 @@ import Disclaimer from '../.././\_disclaimer.mdx';
<Disclaimer />

## Description
The `Identify Provider` object is a key component in the Mock App system that links scanned identifiers to their corresponding [Identity Resolver Service](/docs/mock-apps/dependent-services/identity-resolution-service), understands how to communicate with such services and encapsulates logic to interpret data retrieved from data carriers.

The `Identify Provider` object is a key component in the Mock App system that links scanned identifiers to their corresponding [Identity Resolver Service](/docs/mock-apps/dependent-services/identity-resolution-service), understands how to communicate with such services and encapsulates logic to interpret data retrieved from data carriers.

It serves three main functions:

Expand All @@ -26,27 +27,29 @@ For instance, when dealing with a Global Trade Item Number (GTIN) from GS1:
The Mock App system can use multiple identify providers, each tailored to a specific identity registrar and service. This modular approach allows the system to work with a variety of identification standards and services.

## Example

```json
{
"identifyProvider": {
"type": "gs1",
"url": "http://localhost:3333/products"
"url": "http://localhost:3333",
"namespace": "gs1"
}
}
```

## Definitions

| Property | Required | Description | Type |
|----------|:--------:|-------------|------|
| type | Yes | The type of identify provider, e.g., "gs1" for GS1 standards. | [ProviderType](/docs/mock-apps/common/identify-provider#provider-types) |
| url | Yes | The URL endpoint for the identify provider service. | String |

| Property | Required | Description | Type |
| --------- | :------: | ------------------------------------------------------------- | ----------------------------------------------------------------------- |
| type | Yes | The type of identify provider, e.g., "gs1" for GS1 standards. | [ProviderType](/docs/mock-apps/common/identify-provider#provider-types) |
| url | Yes | The URL endpoint for the identify provider service. | String |
| namespace | Yes | The namespace for the identify provider. | String |

## Provider Types

| Type | Description |
|------|-------------|
| gs1 | Used for resolving (using the Mock Verified By GS1 Service)/understanding GS1-based identifiers (e.g., GTINs). |
| Type | Description |
| ---- | -------------------------------------------------------------------------------------------------------------- |
| gs1 | Used for resolving (using the Mock Verified By GS1 Service)/understanding GS1-based identifiers (e.g., GTINs). |

**Note**: The available types may be extended in the future to support additional identity providers.
**Note**: The available types may be extended in the future to support additional identity providers.
10 changes: 6 additions & 4 deletions documentation/docs/mock-apps/common/idr.md
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,9 @@ The `IDR` object contains configuration for the [Identity Resolver Service](/doc

## Definition

| Property | Required | Description | Type |
|----------|----------|-------------|------|
| dlrAPIUrl | Yes | URL for the Identity Resolver API | String |
| dlrAPIKey | No | API key for the Identity Resolver | String |
| Property | Required | Description | Type |
| ---------------- | -------- | ----------------------------------- | ------ |
| dlrAPIUrl | Yes | URL for the Identity Resolver API | String |
| dlrAPIKey | No | API key for the Identity Resolver | String |
| namespace | Yes | Namespace for the Identity Resolver | String |
| linkRegisterPath | No | Path to register a link | String |
Original file line number Diff line number Diff line change
Expand Up @@ -64,7 +64,9 @@ P-->>C: Return VC and resolver URL
},
"dlr": {
"dlrAPIUrl": "https://dlr.example.com/api",
"dlrAPIKey": "dlr-api-key-12345"
"dlrAPIKey": "dlr-api-key-12345",
"namespace": "gs1",
"linkRegisterPath": "/api/resolver"
},
"identifierKeyPath": "/parentItem/epc"
}
Expand Down
4 changes: 3 additions & 1 deletion documentation/docs/mock-apps/services/process-dpp.md
Original file line number Diff line number Diff line change
Expand Up @@ -75,7 +75,9 @@ P-->>C: Return VC and resolver URL
},
"dlr": {
"dlrAPIUrl": "https://dlr.example.com",
"dlrAPIKey": "5555555555555"
"dlrAPIKey": "5555555555555",
"namespace": "gs1",
"linkRegisterPath": "/api/resolver"
},
"storage": {
"url": "https://storage.example.com/v1/documents",
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -66,7 +66,9 @@ P-->>C: Return VC and resolver URL
},
"dlr": {
"dlrAPIUrl": "https://dlr.example.com/api",
"dlrAPIKey": "dlr-api-key-12345"
"dlrAPIKey": "dlr-api-key-12345",
"namespace": "gs1",
"linkRegisterPath": "/api/resolver"
},
"identifierKeyPath": "/transactionId",
"localStorageParams": {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -65,7 +65,9 @@ P-->>C: Return EPCIS VC
},
"dlr": {
"dlrAPIUrl": "https://dlr.example.com/api",
"dlrAPIKey": "dlr-api-key-12345"
"dlrAPIKey": "dlr-api-key-12345",
"namespace": "gs1",
"linkRegisterPath": "/api/resolver"
},
"storage": {
"url": "https://storage.example.com/upload",
Expand Down
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
import { allowedIndexKeys } from '@mock-app/services';
import { Box, Container } from '@mui/material';
import { allowedIndexKeys, extractFromElementString } from '@mock-app/services';
import { Box } from '@mui/material';
import JSONPointer from 'jsonpointer';
import { useEffect, useState } from 'react';
import Barcode from 'react-barcode';
Expand All @@ -15,7 +15,7 @@ export const BarcodeGenerator = (props: IBarcodeProps) => {
const pathIndex = props.dataPath.split('/').findIndex((key) => allowedIndexKeys.includes(key));

if (pathIndex === -1) {
setValues(JSONPointer.get(props.data, props.dataPath));
setValues([constructBarcode(JSONPointer.get(props.data, props.dataPath))]);
} else {
const headPath = props.dataPath.split('/').slice(0, pathIndex).join('/');
const tailPath = props.dataPath
Expand All @@ -24,10 +24,46 @@ export const BarcodeGenerator = (props: IBarcodeProps) => {
.join('/');
const array = JSONPointer.get(props.data, headPath);
const values = array.map((item: any) => JSONPointer.get(item, `/${tailPath}`));
setValues(values);
const parsedValues = values.map((item: any) => {
return constructBarcode(item);
});

setValues(parsedValues);
}
}
}, [props.data, props.dataPath]);

const constructBarcode = (data: string) => {
const convertToGS1String = (obj: any) => {
if (typeof obj !== 'object' || obj === null) return '';

let result = '';

// Handle '01' (01) first if it exists
if ('01' in obj) {
let value = obj['01'];
if (!/^\d{12,14}|\d{8}$/.test(value)) throw new Error('Invalid GTIN: ' + value);
value = value.padStart(14, '0');
result += `(01)${value}`;
}

// Handle all other AIs
for (const [ai, value] of Object.entries(obj) as any) {
if (ai === '01') continue; // Skip '01' as it's already handled

if (!/^\d{2,4}$/.test(ai)) throw new Error(`Invalid AI: ${ai}`);

result += `(${ai})${value}`;
}

return result;
};

const aiArray = extractFromElementString(data);

return convertToGS1String(aiArray);
};

return (
<Box display='flex' flexDirection='column' alignItems='center' justifyContent='space-evenly'>
{values.map((item) => {
Expand Down
4 changes: 2 additions & 2 deletions packages/mock-app/src/pages/Scanning.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -22,7 +22,7 @@
try {
setIsLoading(true);

const dlrUrl = await identityProvider.getDlrUrl(scannedCode);
const dlrUrl = await identityProvider.getDlrUrl(scannedCode, appConfig.identifyProvider.namespace);
if (!dlrUrl) {
return toastMessage({ status: Status.error, message: 'There no DLR url' });
}
Expand Down Expand Up @@ -55,7 +55,7 @@
}

goVerifyPage(identityProvider);
}, [scannedCode, identityProvider]);

Check warning on line 58 in packages/mock-app/src/pages/Scanning.tsx

View workflow job for this annotation

GitHub Actions / test_and_build

React Hook React.useEffect has missing dependencies: 'goVerifyPage' and 'isLoading'. Either include them or remove the dependency array

const onScanError = (error: unknown) => {
setIdentityProvider(null);
Expand Down Expand Up @@ -96,7 +96,7 @@
qrbox={{ width: 500, height: 300 }}
disableFlip={false}
useBarCodeDetectorIfSupported={true}
focusMode= 'continuous'
focusMode='continuous'
qrCodeSuccessCallback={onScanResult}
qrCodeErrorCallback={onScanError}
/>
Expand Down
Loading
Loading