From 5de688f3e916e50a4cdce503586efc0b4799c1c9 Mon Sep 17 00:00:00 2001 From: Sam Hellawell Date: Tue, 20 Aug 2024 05:28:16 +0100 Subject: [PATCH 1/2] Temporary standalone openid demo page --- pages/openid.js | 356 ++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 356 insertions(+) create mode 100644 pages/openid.js diff --git a/pages/openid.js b/pages/openid.js new file mode 100644 index 0000000..7f097e6 --- /dev/null +++ b/pages/openid.js @@ -0,0 +1,356 @@ +import OrganizationCard from 'components/org/organizationCard'; +import organizations from 'data/organizations'; +import Image from 'next/image'; +import React, { useEffect, useState } from 'react'; +import Link from 'next/link'; +import { Separator } from 'components/ui/separator'; +import DemoFlow from 'components/demo-flow'; +import { Button } from 'components/ui/button'; +import { QRCodeGenerator } from 'components/qrcode/qr-generator'; +import { apiGet, postRequest } from 'utils/request'; +import { dockUrl } from 'utils/constants'; + +const credential = { + type: ['DockCredential'], + subject: { + nested: { + field: true, + }, + inheritedField: 'test', + }, + expirationDate: '2099-08-24T14:15:22Z', +}; + +const authProvider = { + url: 'https://creds.dock.io/claims', + scope: ['openid'], + clientId: + 'eyAic2NoZW1hIjogImh0dHBzOi8vZG9ja25ldHdvcmsuZ2l0aHViLmlvL3ZjLXNjaGVtYXMvYmFzaWMtY3JlZGVudGlhbC5qc29uIiwgImNsYWltcyI6IFsibmFtZSJdIH0=', + clientSecret: 'gpO2IVK+OALL8W+DcFlIfFhJtNA=', +}; + +const claimMap = { + name: 'name', +}; + +const sphereonProofRequest = { + name: 'SphereonID Proof Request', + nonce: '1234567890', + request: { + name: 'SphereonID JWT credential request', + purpose: 'Dock -> SphereonID interop', + id: 'example_jwt_vc', + input_descriptors: [ + { + id: 'id_credential', + constraints: { + fields: [ + { + path: ['$.type', '$.vc.type'], + filter: { + type: 'array', + contains: { + const: 'SphereonWalletIdentityCredential', + }, + }, + }, + ], + }, + }, + ], + }, +}; + +const dockProofRequest = { + name: 'Proof request', + nonce: '1234567890', + request: { + name: 'OID4VP test proof request', + purpose: 'To present a test credential on the Dock Sales Demo', + input_descriptors: [ + { + id: 'Dock Credential', + name: 'OID4VP test proof request', + purpose: 'To present a test credential on the Dock Sales Demo', + constraints: { + fields: [ + { + path: ['$.credentialSubject.name'], + }, + { + path: ['$.name'], + filter: { + type: 'string', + pattern: 'Dock Credential', + }, + }, + ], + }, + }, + ], + }, +}; + +const ebsiConformanceProofRequest = { + name: 'EBSI Request', + nonce: '12338123', + request: { + id: 'k5j458432r8f', + format: { jwt_vc: { alg: ['ES256'] }, jwt_vp: { alg: ['ES256'] } }, + input_descriptors: [ + { + id: 'jkodasjd204', + format: { jwt_vc: { alg: ['ES256'] } }, + constraints: { + fields: [ + { + path: ['$.vc.type'], + filter: { + type: 'array', + contains: { const: 'VerifiableAttestation' }, + }, + }, + ], + }, + }, + { + id: 'j3i84594388', + format: { jwt_vc: { alg: ['ES256'] } }, + constraints: { + fields: [ + { + path: ['$.vc.type'], + filter: { + type: 'array', + contains: { const: 'VerifiableAttestation' }, + }, + }, + ], + }, + }, + { + id: 'h10321032c', + format: { jwt_vc: { alg: ['ES256'] } }, + constraints: { + fields: [ + { + path: ['$.vc.type'], + filter: { + type: 'array', + contains: { const: 'VerifiableAttestation' }, + }, + }, + ], + }, + }, + ], + }, +}; + +function OID4VPProofRequest({ title, desc, proofRequestSetupObject }) { + const [proofRequest, setProofRequest] = useState(); + const [isVerified, setIsVerified] = useState(false); + + async function createProofRequest() { + const { data: proofRequest } = await postRequest(`${dockUrl}/proof-requests`, { + did: process.env.NEXT_PUBLIC_QUOTIENT_ISSUER_ID, + ...proofRequestSetupObject, + }); + + const { data: qrUrlData } = await postRequest( + `${dockUrl}/openid/vp/${proofRequest.id}/request-url`, + { + withRequestURI: true, + } + ); + console.log('qrUrlData', qrUrlData); + setProofRequest({ + ...proofRequest, + qrUrlData, + }); + + const int = setInterval(async () => { + try { + const { data: res } = await apiGet(`${dockUrl}/proof-requests/${proofRequest.id}`); + if (res.verified) { + setProofRequest(res); + setIsVerified(true); + clearInterval(int); + } + } catch (e) { + console.error(e); + } + }, 2000); + } + + useEffect(() => { + if (!proofRequest) { + createProofRequest(); + } + }); + + function getSubjectID() { + if (proofRequest.presentation.holder) { + return proofRequest.presentation.holder; + } + + const cred = proofRequest.credentials[0]; + if (cred) { + return cred.credentialSubject.id; + } + + return 'Unknown'; + } + + return ( +
+
+
+

{title}

+ {isVerified ? ( +
+ Verified! +
+
+ {proofRequest && proofRequest.presentation && ( + <> + Subject ID: {getSubjectID().substr(0, 32)}... +
+ + )} +
+ ) : ( +
+ {proofRequest ? ( + + ) : ( + <>Loading... + )} +
+ )} +
+
+
+

{desc}

+
+
+
+ ); +} + +export default function Home() { + const [ebsiURLS, setEBSIUrls] = useState(); + const [credentialOffer, setCredentialOffer] = useState(); + + async function createCredentialOffer() { + const { data: oidcIssuer } = await postRequest(`${dockUrl}/openid/issuers`, { + claimMap, + credentialOptions: { + credential: { + ...credential, + issuer: process.env.NEXT_PUBLIC_QUOTIENT_ISSUER_ID, + }, + }, + singleUse: true, + authProvider, + }); + + const { data: credentialOffer } = await postRequest(`${dockUrl}/openid/credential-offers`, { + id: oidcIssuer.id, + }); + + setCredentialOffer(credentialOffer); + } + + async function generateEBSIUrls() { + const { data: proofRequest } = await postRequest(`${dockUrl}/proof-requests`, { + did: process.env.NEXT_PUBLIC_QUOTIENT_ISSUER_ID, + ...ebsiConformanceProofRequest, + }); + + setEBSIUrls({ + verifier: `${dockUrl}/openid/vp/${proofRequest.id}`, + }); + } + + useEffect(() => { + if (!credentialOffer) { + createCredentialOffer(); + } + }, []); + + return ( + <> +
+
+
+ docklogo +
+
+

+ | Sales Demo +

+
+
+
+
+
+
+

OID4VCI

+
+ {credentialOffer ? ( + + ) : ( + <>Loading... + )} +
+
+
+
+

+ Scan this QR code to initiate an OID4VCI import flow, it will ask you to enter + your name which will be put in the credential. +

+
+
+
+ + + + +
+
+ +
+
+ +
+
+ {ebsiURLS && ( + <> + Verifier ( + + https://hub.ebsi.eu/wallet-conformance/verifier/flow + + ) Client ID: +
+ + {ebsiURLS.verifier} + + + )} +
+
+ + ); +} From b66bee58cf1ce899d8bd889141c3c579c1390d57 Mon Sep 17 00:00:00 2001 From: Sam <3194321+cykoder@users.noreply.github.com> Date: Tue, 20 Aug 2024 21:16:55 +0100 Subject: [PATCH 2/2] Update openid.js --- pages/openid.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pages/openid.js b/pages/openid.js index 7f097e6..a6a5315 100644 --- a/pages/openid.js +++ b/pages/openid.js @@ -163,7 +163,7 @@ function OID4VPProofRequest({ title, desc, proofRequestSetupObject }) { withRequestURI: true, } ); - console.log('qrUrlData', qrUrlData); + setProofRequest({ ...proofRequest, qrUrlData,