From afd2f2c0f8fa1f6cf385b26e8d029ac9308cb573 Mon Sep 17 00:00:00 2001 From: Timo Glastra Date: Sun, 24 Nov 2024 22:14:49 +0100 Subject: [PATCH] feat: add certificates Signed-off-by: Timo Glastra --- agent/src/endpoints.ts | 27 +++++++++++ app/components/X509Tab.tsx | 91 ++++++++++++++++++++++++++++++++++++++ app/components/main.tsx | 11 +++-- app/lib/api.ts | 14 ++++++ 4 files changed, 140 insertions(+), 3 deletions(-) create mode 100644 app/components/X509Tab.tsx diff --git a/agent/src/endpoints.ts b/agent/src/endpoints.ts index f8d69a0..dbb6b4e 100644 --- a/agent/src/endpoints.ts +++ b/agent/src/endpoints.ts @@ -6,6 +6,8 @@ import { RecordNotFoundError, W3cJsonLdVerifiablePresentation, W3cJwtVerifiablePresentation, + X509Certificate, + X509ModuleConfig, getJwkFromKey, } from '@credo-ts/core' import { OpenId4VcVerificationSessionState } from '@credo-ts/openid4vc' @@ -30,6 +32,10 @@ const zCreateOfferRequest = z.object({ issuerId: z.string(), }) +const zAddX509CertificateRequest = z.object({ + certificate: z.string(), +}) + export const apiRouter = express.Router() apiRouter.use(express.json()) @@ -80,6 +86,27 @@ apiRouter.get('/x509', async (_, response: Response) => { }) }) +apiRouter.post('/x509', async (request: Request, response: Response) => { + const addX509CertificateRequest = zAddX509CertificateRequest.parse(request.body) + + const trustedCertificates = agent.dependencyManager.resolve(X509ModuleConfig).trustedCertificates + try { + const instance = X509Certificate.fromEncodedCertificate(addX509CertificateRequest.certificate) + const base64 = instance.toString('base64') + + if (!trustedCertificates?.includes(base64)) { + await agent.x509.addTrustedCertificate(base64) + } + + return response.send(instance.toString('text')) + } catch (error) { + return response.status(500).json({ + errorMessage: 'error adding x509 certificate', + error, + }) + } +}) + apiRouter.get('/issuer', async (_, response: Response) => { return response.json({ credentialsSupported: issuers.flatMap((i) => diff --git a/app/components/X509Tab.tsx b/app/components/X509Tab.tsx new file mode 100644 index 0000000..4fb3e16 --- /dev/null +++ b/app/components/X509Tab.tsx @@ -0,0 +1,91 @@ +import { Button } from '@/components/ui/button' +import { Card } from '@/components/ui/card' +import { Label } from '@/components/ui/label' +import { CheckboxIcon, ExclamationTriangleIcon, InfoCircledIcon } from '@radix-ui/react-icons' +import { type FormEvent, useState } from 'react' +import { addX509Certificate } from '../lib/api' +import { Alert, AlertDescription, AlertTitle } from './ui/alert' +import { HighLight } from './highLight' + +export function X509Tab() { + const [x509Certificate, setX509Certificate] = useState() + const [response, setResponse] = useState<{ success: true; body: string } | { success: false; error: any }>() + + async function onSubmitX509Certificate(e: FormEvent) { + e.preventDefault() + + setResponse(undefined) + if (!x509Certificate) return + try { + const response = await addX509Certificate(x509Certificate) + console.log(response.ok) + if (response.ok) { + setResponse({ success: true, body: await response.text() }) + } else { + setResponse({ success: false, error: await response.json().catch(() => 'Unkonwn parsing error') }) + } + // biome-ignore lint/suspicious/noExplicitAny: + } catch (error: any) { + setResponse({ + success: false, + error: error.message, + }) + } + } + + return ( + + + + Info + + This playground was built in the context for the{' '} + + EUDI Wallet Prototype Funke + + . It is only compatible with the current deployed version of{' '} + + Animo's EUDI Wallet Prototype + + . + + +
+
+ +