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

FMA Portal changes for names, VPs and compliance filtering #45

Open
wants to merge 38 commits into
base: development
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
38 commits
Select commit Hold shift + click to select a range
a317d96
FMA-25 Filter out any non-compliant Gaia-X credentials from the searc…
zoemaas Jan 17, 2023
3068a32
FMA-25 Filter out any non-compliant Gaia-X credentials from the searc…
zoemaas Jan 18, 2023
27cee92
FMA-26 Resolve and return human-readable names to users
zoemaas Jan 19, 2023
e2743b0
Merge branch 'main' of https://github.com/deltaDAO/portal-rws into fe…
zoemaas Jan 19, 2023
a1d63e8
Merge branch 'main' of https://github.com/deltaDAO/portal-rws into fe…
zoemaas Jan 19, 2023
31cfe1b
FMA-25 Filter out any non-compliant Gaia-X credentials from the searc…
zoemaas Jan 19, 2023
98c69f2
FMA-26 Resolve and return human-readable names to users
zoemaas Jan 19, 2023
95ebd50
Merge branch 'feature/FMA-25/query_filter' of github.com:Sphereon/por…
zoemaas Jan 19, 2023
fb78c11
FMA-36 Deploy FMA portal to AKS
zoemaas Jan 24, 2023
b5dc5ba
Merge pull request #44 from deltaDAO/development
moritzkirstein Feb 3, 2023
92ac1ca
FMA-26 Resolve and return human-readable names to users
zoemaas Feb 20, 2023
36ecd63
FMA-26 Resolve and return human-readable names to users
zoemaas Feb 20, 2023
b19b1c0
FMA-26 Resolve and return human-readable names to users
zoemaas Feb 20, 2023
505868a
feat: WIP: added support of VPs (as well as the old version of gx ent…
sksadjad Feb 21, 2023
4f290b4
FMA-47 Create self-description service-offering 'upload' API for FMA …
zoemaas Feb 27, 2023
f85dd69
Merge branch 'feature/FMA-26/owner_author_switch' into feature/FMA-47…
zoemaas Feb 27, 2023
e1f5088
FMA-47 Create self-description service-offering 'upload' API for FMA …
zoemaas Feb 27, 2023
631a7c2
FMA-47 Create self-description service-offering 'upload' API for FMA …
zoemaas Feb 28, 2023
4773961
Merge remote-tracking branch 'sphereon/feature/FMA-26/owner_author_sw…
nklomp Mar 4, 2023
b54cf80
Merge remote-tracking branch 'origin/main' into feature/Sphereon_changes
nklomp Mar 4, 2023
bf1dea3
fix: Fix several issues, like search not using the total results, inc…
nklomp Mar 5, 2023
309a356
FMA-47 Create self-description service-offering 'upload' API for FMA …
zoemaas Mar 6, 2023
ef6ba79
Merge branch 'feature/Sphereon_changes' of github.com:Sphereon/portal…
zoemaas Mar 6, 2023
fa69c7f
FMA-47 Create self-description service-offering 'upload' API for FMA …
zoemaas Mar 6, 2023
3427fe8
FMA-47 Create self-description service-offering 'upload' API for FMA …
zoemaas Mar 6, 2023
e5ad44c
FMA-47 Create self-description service-offering 'upload' API for FMA …
zoemaas Mar 6, 2023
34f080d
FMA-47 Create self-description service-offering 'upload' API for FMA …
zoemaas Mar 6, 2023
a64cc16
FMA-47 Create self-description service-offering 'upload' API for FMA …
zoemaas Mar 6, 2023
5ceb127
FMA-47 Create self-description service-offering 'upload' API for FMA …
zoemaas Mar 7, 2023
2ef7fa4
FMA-47 Create self-description service-offering 'upload' API for FMA …
zoemaas Mar 7, 2023
0ae6cd8
FMA-47 Create self-description service-offering 'upload' API for FMA …
zoemaas Mar 7, 2023
97ba64c
FMA-47 Create self-description service-offering 'upload' API for FMA …
zoemaas Mar 8, 2023
39a0330
FMA-69 Move the Self-Description VP to the bottom of the page
zoemaas Mar 9, 2023
e262a76
FMA-69 Move the Self-Description VP to the bottom of the page
zoemaas Mar 9, 2023
22687de
FMA-69 Move the Self-Description VP to the bottom of the page
zoemaas Mar 10, 2023
2d0d270
FMA-47 Create self-description service-offering 'upload' API for FMA …
zoemaas Mar 10, 2023
d68f42a
Merge pull request #3 from Sphereon/feature/FMA-47/vp-support
zoemaas Mar 10, 2023
2d91438
Merge pull request #4 from Sphereon/feature/FMA-69/ui_improvements
zoemaas Mar 10, 2023
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
7 changes: 7 additions & 0 deletions .dockerignore
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
.cache
.idea
node_modules
public
repo-metadata.json
*/networks-metadata.json
*/@types/apollo
11 changes: 11 additions & 0 deletions Dockerfile
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
FROM node:16.19.0

WORKDIR /usr/src/app

COPY . .

RUN npm install

EXPOSE 8000

ENTRYPOINT ["npm", "run", "start"]
10 changes: 8 additions & 2 deletions address.config.js
Original file line number Diff line number Diff line change
@@ -1,7 +1,13 @@
module.exports = {
whitelists: {
'publicKey.owner': ['0xa98A6eefbAE870b88a9C7A43f4b50066A01c93b6'],
dataToken: ['0x985d3E0134bCE4d82b90d639d5d83627DE687870']
'publicKey.owner': [
'0xDa4fc9E82Ac4E44207a1f74137493D3437D80761',
'0xa98A6eefbAE870b88a9C7A43f4b50066A01c93b6'
],
dataToken: [
'0x0995527d3473b3a98c471f1ed8787acd77fbf009',
'0x985d3E0134bCE4d82b90d639d5d83627DE687870'
]
},
featured: [
{
Expand Down
3 changes: 1 addition & 2 deletions app.config.js
Original file line number Diff line number Diff line change
Expand Up @@ -11,8 +11,7 @@ module.exports = {
process.env.GATSBY_METADATACACHE_URI || 'https://aquarius.delta-dao.com',

complianceUri:
process.env.GATSBY_COMPLIANCE_URI ||
'https://compliance.gaia-x.eu/v2206/api',
process.env.GATSBY_COMPLIANCE_URI || 'https://cs.gx.test.sphereon.com/api',

// List of chainIds which metadata cache queries will return by default.
// This preselects the Chains user preferences.
Expand Down
11 changes: 11 additions & 0 deletions docker-compose.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
services:
delta-dao-portal:
container_name: delta-dao-portal
build:
context: .
dockerfile: Dockerfile
image: vdxcontainerregistry2022051200.azurecr.io/gx-fma-portal:v1.0.0
ports:
- '8000:8000'
volumes:
- $PWD:/usr/src/app
145 changes: 145 additions & 0 deletions src/@types/MetaData.d.ts
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,9 @@ export interface AdditionalInformationMarket extends AdditionalInformation {
consent: {
noPersonalData: boolean
}
compliance: {
gx: boolean
}
}

export interface MetadataMarket extends Metadata {
Expand Down Expand Up @@ -87,3 +90,145 @@ export interface MetadataEditForm {
export interface ServiceMetadataMarket extends ServiceMetadata {
attributes: MetadataMarket
}

export type IVerifiablePresentation = IPresentation & IHasProof

export interface IPresentation {
'@context': ICredentialContextType | ICredentialContextType[]
type: string[]
verifiableCredential: IVerifiableCredential[]
// eslint-disable-next-line camelcase
presentation_submission?: PresentationSubmission
holder?: string
}

export type IVerifiableCredential = ICredential & IHasProof

export interface ICredential {
// If exp is present, the UNIX timestamp MUST be converted to an [XMLSCHEMA11-2] date-time, and MUST be used to set the value of the expirationDate property of credentialSubject of the new JSON object.
expirationDate?: string
// If iss is present, the value MUST be used to set the issuer property of the new credential JSON object or the holder property of the new presentation JSON object.
issuer: string | IIssuer
// If nbf is present, the UNIX timestamp MUST be converted to an [XMLSCHEMA11-2] date-time, and MUST be used to set the value of the issuanceDate property of the new JSON object.
issuanceDate: string
// If sub is present, the value MUST be used to set the value of the id property of credentialSubject of the new credential JSON object.
credentialSubject: ICredentialSubject
// If jti is present, the value MUST be used to set the value of the id property of the new JSON object.
id: string
'@context': ICredentialContextType[] | ICredentialContextType
credentialStatus?: ICredentialStatus
credentialSchema?: undefined | ICredentialSchemaType | ICredentialSchemaType[]
description?: string
name?: string
type: string[]

[x: string]: unknown
}

export interface ICredentialStatus {
id: string
type: string
}

export interface IIssuer {
id: string

[x: string]: unknown
}

export interface ICredentialSubject {
id?: string

[x: string]: unknown
}

export type ICredentialContextType = ICredentialContext | string

export interface ICredentialContext {
name?: string
did?: string
[x: string]: unknown
}

export type ICredentialSchemaType = ICredentialSchema | string

export interface ICredentialSchema {
id: string
type?: string
}

export interface PresentationSubmission {
/**
* A UUID or some other unique ID to identify this Presentation Submission
*/
id: string
/**
* A UUID or some other unique ID to identify this Presentation Definition
*/
// eslint-disable-next-line camelcase
definition_id: string
/**
* List of descriptors of how the claims are being mapped to presentation definition
*/
// eslint-disable-next-line camelcase
descriptor_map: Array<Descriptor>
}

export interface Descriptor {
/**
* ID to identify the descriptor from Presentation Definition Input Descriptor it coresponds to.
*/
id: string
/**
* The path where the verifiable credential is located in the presentation submission json
*/
path: string
// eslint-disable-next-line camelcase
path_nested?: Descriptor
/**
* The Proof or JWT algorith that the proof is in
*/
format: string
}

export interface IHasProof {
proof: IProof
}

export interface IProof {
type: IProofType | string // The proof type
created: string // The ISO8601 date-time string for creation
proofPurpose: IProofPurpose | string // The specific intent for the proof
verificationMethod: string // A set of parameters required to independently verify the proof
challenge?: string // A challenge to protect against replay attacks
domain?: string // A string restricting the (usage of a) proof to the domain and protects against replay attacks
proofValue?: string // One of any number of valid representations of proof values
jws?: string // JWS based proof
nonce?: string // Similar to challenge. A nonce to protect against replay attacks, used in some ZKP proofs
requiredRevealStatements?: string[] // The parts of the proof that must be revealed in a derived proof

[x: string]: string | string[] | undefined
}

export enum IProofPurpose {
verificationMethod = 'verificationMethod',
assertionMethod = 'assertionMethod',
authentication = 'authentication',
keyAgreement = 'keyAgreement',
contractAgreement = 'contactAgreement',
capabilityInvocation = 'capabilityInvocation',
capabilityDelegation = 'capabilityDelegation'
}

export enum IProofType {
Ed25519Signature2018 = 'Ed25519Signature2018',
Ed25519Signature2020 = 'Ed25519Signature2020',
EcdsaSecp256k1Signature2019 = 'EcdsaSecp256k1Signature2019',
EcdsaSecp256k1RecoverySignature2020 = 'EcdsaSecp256k1RecoverySignature2020',
JsonWebSignature2020 = 'JsonWebSignature2020',
RsaSignature2018 = 'RsaSignature2018',
GpgSignature2020 = 'GpgSignature2020',
JcsEd25519Signature2020 = 'JcsEd25519Signature2020',
BbsBlsSignatureProof2020 = 'BbsBlsSignatureProof2020',
BbsBlsBoundSignatureProof2020 = 'BbsBlsBoundSignatureProof2020'
}
49 changes: 49 additions & 0 deletions src/components/atoms/Accordion.module.css
Original file line number Diff line number Diff line change
@@ -0,0 +1,49 @@
input {
display: none;
}

.accordion {
}

.accordion__item {
}

.accordion__item__title {
display: block;
padding: 20px;
cursor: pointer;
border-left: var(--border-teaser);
border-right: var(--border-teaser);
border-bottom: var(--border-teaser);
color: #333;
position: relative;
}

.accordion__item__title:after {
content: '+';
color: #aeaeae;
position: absolute;
right: 20px;
top: 50%;
font-size: 2rem;
line-height: 2rem;
margin-top: -1rem;
font-weight: bold;
}

.accordion__item__title > h4 {
margin-top: auto;
margin-bottom: auto;
}

.accordion__item__content {
margin-top: -1rem;
}

input + .accordion__item__title + .accordion__item__content {
display: none;
}

input:checked + .accordion__item__title + .accordion__item__content {
display: block;
}
33 changes: 33 additions & 0 deletions src/components/atoms/Accordion.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,33 @@
import React from 'react'
import classNames from 'classnames/bind'
import styles from './Accordion.module.css'
import Markdown from './Markdown'

const cx = classNames.bind(styles)
export default function Accordion({
className,
content,
title
}: {
className?: string
content: any
title: string
}) {
const styleClasses = cx({
accordion: true,
[className]: className
})
return (
<div className={styleClasses}>
<div className={styles.accordion__item}>
<input type="checkbox" id="title1" />
<label htmlFor="title1" className={styles.accordion__item__title}>
<h4>{title}</h4>
</label>
<div className={styles.accordion__item__content}>
<Markdown text={content} className={styleClasses.description} />
</div>
</div>
</div>
)
}
5 changes: 3 additions & 2 deletions src/components/atoms/Publisher/index.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@ import React, { ReactElement } from 'react'
import styles from './index.module.css'
import classNames from 'classnames/bind'
import { Link } from 'gatsby'
import { accountTruncate } from '../../../utils/web3'
import { accountTruncate, nameTruncate } from '../../../utils/web3'

const cx = classNames.bind(styles)

Expand All @@ -17,7 +17,8 @@ export default function Publisher({
verifiedServiceProviderName?: string
className?: string
}): ReactElement {
const name = verifiedServiceProviderName || accountTruncate(account)
const name =
nameTruncate(verifiedServiceProviderName, 35) || accountTruncate(account)

const styleClasses = cx({
publisher: true,
Expand Down
17 changes: 15 additions & 2 deletions src/components/molecules/AssetTeaser.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,8 @@ import LinkOpener from '../molecules/LinkOpener'
import { BestPrice } from '../../models/BestPrice'
import Loader from '../atoms/Loader'
import classNames from 'classnames/bind'
import { ServiceMetadataMarket } from '../../@types/MetaData'
import { getLegalName } from '../../utils/metadata'

const cx = classNames.bind(styles)

Expand All @@ -25,8 +27,12 @@ const AssetTeaser: React.FC<AssetTeaserProps> = ({
price,
noPublisher
}: AssetTeaserProps) => {
const { attributes } = ddo.findServiceByType('metadata')
const { attributes } = ddo.findServiceByType(
'metadata'
) as ServiceMetadataMarket
const isCompliant = !!attributes.additionalInformation.compliance?.gx
const { name, type } = attributes.main
const legalName = getLegalName(ddo)
const { dataTokenInfo } = ddo
const isCompute = Boolean(ddo?.findServiceByType('compute'))
const accessType = isCompute ? 'compute' : 'access'
Expand All @@ -41,7 +47,14 @@ const AssetTeaser: React.FC<AssetTeaserProps> = ({
<Dotdotdot clamp={3}>
<h1 className={styles.title}>{name}</h1>
</Dotdotdot>
<Publisher account={owner} minimal className={styles.publisher} />
<Publisher
account={owner}
verifiedServiceProviderName={
isCompliant ? legalName : `${legalName} (unverified)`
}
minimal
className={styles.publisher}
/>
</header>

<AssetType
Expand Down
3 changes: 2 additions & 1 deletion src/components/molecules/FormFields/FilesInput/index.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -34,7 +34,8 @@ export default function FilesInput({
if (field.name === 'serviceSelfDescription') {
setStatus('loading')
const { verified } = await verifyServiceSelfDescription({
body: fileUrl
body: fileUrl,
raw: false
})
const serviceSelfDescription = await getServiceSelfDescription(
fileUrl
Expand Down
20 changes: 15 additions & 5 deletions src/components/molecules/FormFields/ServiceSelfDescription.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -40,11 +40,21 @@ export default function ServiceSelfDescription(
props?.setStatus('loading')

const parsedServiceSelfDescription = JSON.parse(rawServiceSelfDescription)
const signedServiceSelfDescription =
parsedServiceSelfDescription?.complianceCredential
? parsedServiceSelfDescription
: await signServiceSelfDescription(parsedServiceSelfDescription)

let signedServiceSelfDescription
if (
parsedServiceSelfDescription.type &&
Array.isArray(parsedServiceSelfDescription.type) &&
(parsedServiceSelfDescription.type as string[]).indexOf(
'VerifiablePresentation'
) !== -1
) {
signedServiceSelfDescription = parsedServiceSelfDescription
} else {
signedServiceSelfDescription =
parsedServiceSelfDescription?.complianceCredential
? parsedServiceSelfDescription
: await signServiceSelfDescription(parsedServiceSelfDescription)
}
const { verified } = await verifyServiceSelfDescription({
body: signedServiceSelfDescription,
raw: true
Expand Down
Loading