-
Notifications
You must be signed in to change notification settings - Fork 8
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Feat/DDO to Gaia-X Service Credential (#595)
* feat: add download DDO button * feat: added comments * refactor: extract downloadJSON function, add JSON validation, and make download DDO button visible outside debug mode * feat: created new JSON and added modal for data input * feat: updated JSON, changed modal title, added delete function for credentials, and improved modal styling * fix: resolved issue with button type attribute * fix: fixed createServiceCredential function * fix: format correctly * feat: migrated form to Formik * feat: added validation and placeholder * refactor: updated typing,removed console.log, fix tooltip, cleaned up CSS,merged functions, adjusted validation, added button type, updated output JSON, and modified text fields * refactor: replaced values with placeholders for gx:URL and gx:hash in JSON
- Loading branch information
1 parent
708a065
commit a29df2a
Showing
9 changed files
with
361 additions
and
21 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,45 @@ | ||
{ | ||
"metadata": { | ||
"title": "Metadata", | ||
"fields": [ | ||
{ | ||
"name": "didweb", | ||
"label": "Service Provider DID:WEB ", | ||
"placeholder": "did:web:yourdomain.eu", | ||
"help": "The DID:WEB of the service provider / issuer publishing the Gaia-X Service Credential.", | ||
"required": true | ||
}, | ||
{ | ||
"name": "credentialHostingPath", | ||
"label": "Service Credential Hosting Path ", | ||
"placeholder": "https://yourdomain.eu/.well-known", | ||
"help": "The base path to your public storage of Gaia-X Service Credentials.", | ||
"required": true | ||
}, | ||
{ | ||
"name": "pathToParticipantCredential", | ||
"label": "Service Provider Participant Credential ", | ||
"placeholder": "https://yourdomain.eu/.well-known/participant_vp.json", | ||
"help": "URI of the service provider Gaia-X Participant Credential required to identity the responsible service provider.", | ||
"required": true | ||
}, | ||
{ | ||
"name": "knownDependencyCredentials", | ||
"label": "Known Dependency Credentials", | ||
"placeholder": "https://www.yourdomain.eu/.well-known/2210_gx_service_provider_1.json", | ||
"help": "Contains resolvable links to the Gaia-X service credentials related to this service that can exist independently of it.", | ||
"required": false | ||
}, | ||
{ | ||
"name": "knownAggregatedServiceCredentials", | ||
"label": "Known Aggregated Resource Credentials", | ||
"placeholder": "https://www.yourdomain.eu/.well-known/2210_gx_resource_data_road_condition_7.json", | ||
"help": "Contains resolveable links to Gaia-X Resource and Service Credentials related to this service that can exist independently of it.", | ||
"required": false | ||
} | ||
] | ||
}, | ||
"submission": { | ||
"title": "Submit" | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,24 @@ | ||
import * as Yup from 'yup' | ||
|
||
export const initialValuesAsset = { | ||
didweb: '', | ||
credentialHostingPath: '', | ||
pathToParticipantCredential: '', | ||
knownDependencyCredentials: '', | ||
knownAggregatedServiceCredentials: '' | ||
} | ||
|
||
export const validationAsset = Yup.object().shape({ | ||
didweb: Yup.string() | ||
.matches(/^did:web:/, 'Invalid DID (only did:web is allowed)') | ||
.required('Required'), | ||
credentialHostingPath: Yup.string() | ||
.url('Invalid URL') | ||
.matches(/.*[^/]$/, 'URL must not end with /') | ||
.required('Required'), | ||
pathToParticipantCredential: Yup.string() | ||
.url('Invalid URL') | ||
.required('Required'), | ||
knownDependencyCredentials: Yup.string().optional().url('Invalid URL'), | ||
knownAggregatedServiceCredentials: Yup.string().optional().url('Invalid URL') | ||
}) |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,73 @@ | ||
import { downloadJSON } from '@utils/downloadJSON' | ||
|
||
export interface DDOData { | ||
id: string | ||
services: { timeout: string }[] | ||
} | ||
|
||
interface FormData { | ||
didweb: string | ||
credentialHostingPath: string | ||
pathToParticipantCredential: string | ||
dependencyCredentialsList: { id: string }[] | ||
serviceCredentialList: { id: string }[] | ||
} | ||
|
||
function getDomain(url: string) { | ||
url = url.split('/').splice(0, 3).join('/') | ||
return url | ||
} | ||
|
||
export function createServiceCredential(asset: DDOData, formData: FormData) { | ||
const filename = `service_did_op_${asset.id.split(':')[2]}` // to get only the id without did:op: | ||
const metadata = { | ||
'@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: `${formData.credentialHostingPath}/${filename}.json`, | ||
issuer: formData.didweb, | ||
issuanceDate: '', | ||
credentialSubject: { | ||
id: asset.id, | ||
type: 'gx:ServiceOffering', | ||
'gx:providedBy': { | ||
id: formData.pathToParticipantCredential | ||
}, | ||
'gx:maintainedBy': { | ||
id: formData.pathToParticipantCredential | ||
}, | ||
'gx:serviceOffering:serviceModel': 'subscription', | ||
'gx:serviceOffering:subscriptionDuration': | ||
asset.services[0].timeout || 'unlimited', | ||
'gx:policy': `${formData.credentialHostingPath}/yourpolicy.json`, | ||
'gx:termsAndConditions': { | ||
'gx:URL': '[basedomain]/yourtermsandconditions.txt', | ||
'gx:hash': '[hash]' | ||
}, | ||
'gx:dataAccountExport': { | ||
'gx:requestType': 'email', | ||
'gx:accessType': 'digital', | ||
'gx:formatType': 'mime/json' | ||
}, | ||
'gx:serviceOffering:dataProtectionRegime': ['GDPR2016'], | ||
'gx:serviceOffering:gdpr': [ | ||
{ | ||
'gx:serviceOffering:imprint': `${getDomain( | ||
formData.credentialHostingPath | ||
)}/imprint/` | ||
}, | ||
{ | ||
'gx:serviceOffering:privacyPolicy': `${getDomain( | ||
formData.credentialHostingPath | ||
)}/privacy/` | ||
} | ||
], | ||
'gx:dependsOn': formData.dependencyCredentialsList || [], | ||
'gx:aggregationOf': formData.serviceCredentialList || [] | ||
} | ||
} | ||
downloadJSON(JSON.stringify(metadata), filename) | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,18 @@ | ||
.credential_margin_bottom { | ||
margin-bottom: calc(var(--spacer) * var(--line-height)); | ||
} | ||
.credential_input { | ||
width: 70%; | ||
} | ||
|
||
.credential_input_div { | ||
display: flex; | ||
justify-content: space-between; | ||
align-items: flex-end; | ||
flex-wrap: wrap; | ||
width: 100%; | ||
} | ||
|
||
.button { | ||
max-height: 70px; | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,20 +1,120 @@ | ||
import { ReactElement } from 'react' | ||
import { ReactElement, useState } from 'react' | ||
import Button from '../atoms/Button' | ||
import { downloadJSON } from '@utils/downloadJSON' | ||
import Modal from '../atoms/Modal' | ||
import Input from '../FormInput' | ||
import { createServiceCredential, DDOData } from './createJSON' | ||
import { Field, Form, Formik } from 'formik' | ||
import { getFieldContent } from '@utils/form' | ||
import content from '../../../../content/DDOtoServiceCredential/serviceCredentialForm.json' | ||
import { initialValuesAsset, validationAsset } from './_validation' | ||
import InputWithList from './inputWithList' | ||
import styles from './index.module.css' | ||
|
||
interface values { | ||
didweb: string | ||
credentialHostingPath: string | ||
pathToParticipantCredential: string | ||
knownDependencyCredentials: string | ||
knownAggregatedServiceCredentials: string | ||
} | ||
|
||
export default function DDODownloadButton({ | ||
asset | ||
}: { | ||
asset: any | ||
asset: DDOData | ||
}): ReactElement { | ||
const [openModal, setOpenModal] = useState(false) | ||
const [serviceCredentialList, setServiceCredentialList] = useState< | ||
{ id: string }[] | ||
>([]) | ||
const [dependencyCredentialsList, setDependencyCredentialsList] = useState< | ||
{ id: string }[] | ||
>([]) | ||
const clearLists = () => { | ||
setOpenModal(false) | ||
setServiceCredentialList([]) | ||
setDependencyCredentialsList([]) | ||
} | ||
const handleSubmit = (values: values) => { | ||
const formData = { | ||
...values, | ||
serviceCredentialList, | ||
dependencyCredentialsList | ||
} | ||
createServiceCredential(asset, formData) | ||
clearLists() | ||
} | ||
|
||
return ( | ||
<Button | ||
onClick={() => | ||
downloadJSON(JSON.stringify(asset), `${asset.metadata.name}_metadata`) | ||
} | ||
size="small" | ||
> | ||
Download DDO | ||
</Button> | ||
<> | ||
<Button | ||
className={styles.button} | ||
onClick={() => setOpenModal(true)} | ||
size="small" | ||
> | ||
Prepare Service Credential | ||
</Button> | ||
|
||
<Modal | ||
title="Prepare Gaia-X Service Credential" | ||
isOpen={openModal} | ||
onToggleModal={() => { | ||
clearLists() | ||
}} | ||
> | ||
<p> | ||
This manual export functionality will assist you to create Gaia-X | ||
Service Credentials for this service which can be added to this | ||
service for verification against the | ||
<Button | ||
style="text" | ||
href={'https://docs.gaia-x.eu/framework/?tab=clearing-house'} | ||
> | ||
Gaia-X Digital Clearing Houses (GXDCH) | ||
</Button> | ||
. Credentials should be signed and hosted by the service provider. | ||
</p> | ||
<Formik | ||
initialValues={initialValuesAsset} | ||
validationSchema={validationAsset} | ||
onSubmit={handleSubmit} | ||
> | ||
<Form> | ||
<Field | ||
{...getFieldContent('didweb', content.metadata.fields)} | ||
component={Input} | ||
name="didweb" | ||
/> | ||
<Field | ||
{...getFieldContent( | ||
'credentialHostingPath', | ||
content.metadata.fields | ||
)} | ||
component={Input} | ||
name="credentialHostingPath" | ||
/> | ||
<Field | ||
{...getFieldContent( | ||
'pathToParticipantCredential', | ||
content.metadata.fields | ||
)} | ||
component={Input} | ||
name="pathToParticipantCredential" | ||
/> | ||
<InputWithList | ||
fieldname="knownDependencyCredentials" | ||
setList={setDependencyCredentialsList} | ||
list={dependencyCredentialsList} | ||
/> | ||
<InputWithList | ||
fieldname="knownAggregatedServiceCredentials" | ||
setList={setServiceCredentialList} | ||
list={serviceCredentialList} | ||
/> | ||
<Button type="submit">Download</Button> | ||
</Form> | ||
</Formik> | ||
</Modal> | ||
</> | ||
) | ||
} |
Oops, something went wrong.