diff --git a/infrastructure/control-panel/src/app.css b/infrastructure/control-panel/src/app.css index 403bc8e2..783713ab 100644 --- a/infrastructure/control-panel/src/app.css +++ b/infrastructure/control-panel/src/app.css @@ -69,3 +69,259 @@ --color-green: #0fb340; } } + +@layer utilities { + /* Primary colors */ + .bg-primary { + background-color: var(--color-primary); + } + .bg-primary-100 { + background-color: var(--color-primary-100); + } + .bg-primary-200 { + background-color: var(--color-primary-200); + } + .bg-primary-300 { + background-color: var(--color-primary-300); + } + .bg-primary-400 { + background-color: var(--color-primary-400); + } + .bg-primary-500 { + background-color: var(--color-primary-500); + } + + .text-primary { + color: var(--color-primary); + } + .text-primary-100 { + color: var(--color-primary-100); + } + .text-primary-200 { + color: var(--color-primary-200); + } + .text-primary-300 { + color: var(--color-primary-300); + } + .text-primary-400 { + color: var(--color-primary-400); + } + .text-primary-500 { + color: var(--color-primary-500); + } + + .border-primary { + border-color: var(--color-primary); + } + .border-primary-100 { + border-color: var(--color-primary-100); + } + .border-primary-200 { + border-color: var(--color-primary-200); + } + .border-primary-300 { + border-color: var(--color-primary-300); + } + .border-primary-400 { + border-color: var(--color-primary-400); + } + .border-primary-500 { + border-color: var(--color-primary-500); + } + + /* Secondary colors */ + .bg-secondary { + background-color: var(--color-secondary); + } + .bg-secondary-100 { + background-color: var(--color-secondary-100); + } + .bg-secondary-200 { + background-color: var(--color-secondary-200); + } + .bg-secondary-300 { + background-color: var(--color-secondary-300); + } + .bg-secondary-400 { + background-color: var(--color-secondary-400); + } + .bg-secondary-500 { + background-color: var(--color-secondary-500); + } + + .text-secondary { + color: var(--color-secondary); + } + .text-secondary-100 { + color: var(--color-secondary-100); + } + .text-secondary-200 { + color: var(--color-secondary-200); + } + .text-secondary-300 { + color: var(--color-secondary-300); + } + .text-secondary-400 { + color: var(--color-secondary-400); + } + .text-secondary-500 { + color: var(--color-secondary-500); + } + + /* Danger colors */ + .bg-danger { + background-color: var(--color-danger); + } + .bg-danger-100 { + background-color: var(--color-danger-100); + } + .bg-danger-200 { + background-color: var(--color-danger-200); + } + .bg-danger-300 { + background-color: var(--color-danger-300); + } + .bg-danger-400 { + background-color: var(--color-danger-400); + } + .bg-danger-500 { + background-color: var(--color-danger-500); + } + + .text-danger { + color: var(--color-danger); + } + .text-danger-100 { + color: var(--color-danger-100); + } + .text-danger-200 { + color: var(--color-danger-200); + } + .text-danger-300 { + color: var(--color-danger-300); + } + .text-danger-400 { + color: var(--color-danger-400); + } + .text-danger-500 { + color: var(--color-danger-500); + } + + /* Black colors */ + .bg-black-100 { + background-color: var(--color-black-100); + } + .bg-black-300 { + background-color: var(--color-black-300); + } + .bg-black-500 { + background-color: var(--color-black-500); + } + .bg-black-700 { + background-color: var(--color-black-700); + } + .bg-black-900 { + background-color: var(--color-black-900); + } + + .text-black-100 { + color: var(--color-black-100); + } + .text-black-300 { + color: var(--color-black-300); + } + .text-black-500 { + color: var(--color-black-500); + } + .text-black-700 { + color: var(--color-black-700); + } + .text-black-900 { + color: var(--color-black-900); + } + + .border-black-100 { + border-color: var(--color-black-100); + } + + /* Green color */ + .text-green { + color: var(--color-green); + } + + /* Basic colors */ + .bg-white { + background-color: var(--color-white); + } + .bg-gray { + background-color: var(--color-gray); + } + .bg-gray-50 { + background-color: #f9fafb; + } + .bg-gray-100 { + background-color: #f3f4f6; + } + .bg-gray-200 { + background-color: #e5e7eb; + } + .bg-gray-300 { + background-color: #d1d5db; + } + .bg-gray-400 { + background-color: #9ca3af; + } + .bg-gray-500 { + background-color: #6b7280; + } + .bg-gray-600 { + background-color: #4b5563; + } + .bg-gray-700 { + background-color: #374151; + } + .bg-gray-800 { + background-color: #1f2937; + } + .bg-gray-900 { + background-color: #111827; + } + + .text-gray-50 { + color: #f9fafb; + } + .text-gray-100 { + color: #f3f4f6; + } + .text-gray-200 { + color: #e5e7eb; + } + .text-gray-300 { + color: #d1d5db; + } + .text-gray-400 { + color: #9ca3af; + } + .text-gray-500 { + color: #6b7280; + } + .text-gray-600 { + color: #4b5563; + } + .text-gray-700 { + color: #374151; + } + .text-gray-800 { + color: #1f2937; + } + .text-gray-900 { + color: #111827; + } + + .border-gray-300 { + border-color: #d1d5db; + } + .border-gray-700 { + border-color: #374151; + } +} diff --git a/infrastructure/control-panel/src/lib/fragments/Nodes/VaultNode.svelte b/infrastructure/control-panel/src/lib/fragments/Nodes/VaultNode.svelte index f4d51933..2257fc53 100644 --- a/infrastructure/control-panel/src/lib/fragments/Nodes/VaultNode.svelte +++ b/infrastructure/control-panel/src/lib/fragments/Nodes/VaultNode.svelte @@ -3,10 +3,11 @@ import { HugeiconsIcon } from '@hugeicons/svelte'; import { Cancel01FreeIcons, Database01FreeIcons } from '@hugeicons/core-free-icons'; - export let data: { label: string; subLabel: string }; + export let data: { label: string; subLabel: string; type?: string }; + export let selected = false; -
+
@@ -17,8 +18,17 @@
{data.subLabel}
- - + + + {#if data.type === 'platform'} + + + + {:else} + + + + {/if} diff --git a/infrastructure/control-panel/src/lib/ui/Checkbox/Checkbox.svelte b/infrastructure/control-panel/src/lib/ui/Checkbox/Checkbox.svelte index eea2ed30..5c8c705d 100644 --- a/infrastructure/control-panel/src/lib/ui/Checkbox/Checkbox.svelte +++ b/infrastructure/control-panel/src/lib/ui/Checkbox/Checkbox.svelte @@ -43,7 +43,10 @@ tabindex="0" role="checkbox" aria-checked={checked} - onclick={() => inputElement?.click()} + onclick={(e) => { + e.stopPropagation(); + inputElement?.click(); + }} > {#if checked} diff --git a/infrastructure/control-panel/src/lib/ui/Table/Table.svelte b/infrastructure/control-panel/src/lib/ui/Table/Table.svelte index d77dc858..87957e6a 100644 --- a/infrastructure/control-panel/src/lib/ui/Table/Table.svelte +++ b/infrastructure/control-panel/src/lib/ui/Table/Table.svelte @@ -67,6 +67,7 @@ onSort?: (column: string) => void; sortBy?: string; sortOrder?: 'asc' | 'desc'; + onSelectionChange?: (index: number, checked: boolean) => void; } let { @@ -88,6 +89,7 @@ onSort, sortBy, sortOrder, + onSelectionChange, ...restProps }: ITableProps = $props(); @@ -108,6 +110,11 @@ if (checkAll !== all) { checkAll = all; } + + // Call the onSelectionChange callback if provided + if (onSelectionChange) { + onSelectionChange(i, checked); + } } let tableContainer: HTMLDivElement | null = null; @@ -210,7 +217,7 @@ > {#if withSelection} - + toggleCheckAll(e as boolean)} /> {/if} @@ -239,15 +246,24 @@ {#each tableData as data, i} { - selectedRow = i; - handleSelectedRow && handleSelectedRow(i); + onclick={(e) => { + // Don't trigger row selection if clicking on checkbox area + const target = e.target as HTMLElement; + const isCheckboxClick = + target.closest('th') || + target.closest('[role="checkbox"]') || + target.closest('input[type="checkbox"]'); + + if (!isCheckboxClick) { + selectedRow = i; + handleSelectedRow && handleSelectedRow(i); + } }} - class="hover:bg-gray w-full bg-white select-none + class="hover:bg-gray w-full select-none bg-white {selectedRow === i && 'bg-gray!'}" > {#if withSelection} - + toggleCheckItem(i, e as boolean)} @@ -309,7 +325,7 @@ {#snippet BodyCell(data: Record, field: string, i: number)} (null); let mappedData = $state([]); + // Track selected items + let selectedEVaults = $state([]); + let selectedPlatforms = $state([]); + + // Platform data + const platforms = [ + { + name: 'Blabsy', + url: 'blabsy.staging.metastate.foundation', + status: 'Active', + uptime: '24h' + }, + { + name: 'Pictique', + url: 'pictique.staging.metastate.foundation', + status: 'Active', + uptime: '24h' + }, + { + name: 'Group Charter', + url: 'charter.staging.metastate.foundation', + status: 'Active', + uptime: '24h' + }, + { + name: 'Cerberus', + url: 'cerberus.staging.metastate.foundation', + status: 'Active', + uptime: '24h' + } + ]; + + const mappedPlatformsData = platforms.map((platform) => ({ + Name: { + type: 'text', + value: platform.name + }, + Status: { + type: 'text', + value: platform.status + }, + Uptime: { + type: 'text', + value: platform.uptime + }, + URL: { + type: 'link', + value: platform.url, + link: `https://${platform.url}`, + external: true + } + })); + const handlePreviousPage = async () => { alert('Previous btn clicked. Make a call to your server to fetch data.'); }; @@ -30,6 +83,36 @@ { name: '3', href: '#' } ]; + // Handle eVault selection changes + function handleEVaultSelectionChange(index: number, checked: boolean) { + if (checked) { + selectedEVaults = [...selectedEVaults, index]; + } else { + selectedEVaults = selectedEVaults.filter((i) => i !== index); + } + } + + // Handle platform selection changes + function handlePlatformSelectionChange(index: number, checked: boolean) { + if (checked) { + selectedPlatforms = [...selectedPlatforms, index]; + } else { + selectedPlatforms = selectedPlatforms.filter((i) => i !== index); + } + } + + // Navigate to monitoring with selected items + function goToMonitoring() { + const selectedEVaultData = selectedEVaults.map((i) => evaults[i]); + const selectedPlatformData = selectedPlatforms.map((i) => platforms[i]); + + // Store selected data in sessionStorage to pass to monitoring page + sessionStorage.setItem('selectedEVaults', JSON.stringify(selectedEVaultData)); + sessionStorage.setItem('selectedPlatforms', JSON.stringify(selectedPlatformData)); + + goto('/monitoring'); + } + const fetchEVaults = async () => { try { isLoading = true; @@ -129,6 +212,7 @@ {handlePreviousPage} {handleNextPage} handleSelectedRow={handleEVaultRowClick} + onSelectionChange={handleEVaultSelectionChange} /> {/if} @@ -138,14 +222,26 @@ title="Platforms" placeholder="Search Platforms" bind:searchValue={platformsSearchQuery} - rightTitle="No platform selected. Select an platform to monitor logs" + rightTitle="No platform selected. Select a platform to monitor logs" /> + + +
+ +
diff --git a/infrastructure/control-panel/src/routes/api/events/+server.ts b/infrastructure/control-panel/src/routes/api/events/+server.ts new file mode 100644 index 00000000..4e54395b --- /dev/null +++ b/infrastructure/control-panel/src/routes/api/events/+server.ts @@ -0,0 +1,118 @@ +import { json } from '@sveltejs/kit'; +import type { RequestHandler } from './$types'; + +export const GET: RequestHandler = async () => { + const stream = new ReadableStream({ + start(controller) { + let isConnected = true; + const timeouts: NodeJS.Timeout[] = []; + + // Send initial connection message + if (isConnected) { + controller.enqueue(`data: ${JSON.stringify({ type: 'connected', timestamp: new Date().toISOString() })}\n\n`); + } + + // Helper function to safely enqueue data + const safeEnqueue = (data: any) => { + if (isConnected) { + try { + controller.enqueue(`data: ${JSON.stringify(data)}\n\n`); + } catch (error) { + console.log('Client disconnected, stopping stream'); + isConnected = false; + } + } + }; + + // Simulate the data flow sequence + const timeout1 = setTimeout(() => { + // Step 1: Platform 1 creates a message + safeEnqueue({ + type: 'platform_message_created', + platformIndex: 1, + platformName: 'Pictique', + message: 'Creating new message in blob storage', + timestamp: new Date().toISOString() + }); + }, 3000); + timeouts.push(timeout1); + + const timeout2 = setTimeout(() => { + // Step 2: Request sent to eVault 0 + safeEnqueue({ + type: 'request_sent_to_evault', + platformIndex: 1, + evaultIndex: 0, + message: 'Request sent to eVault', + timestamp: new Date().toISOString() + }); + }, 8000); + timeouts.push(timeout2); + + const timeout3 = setTimeout(() => { + // Step 3: eVault 0 creates metaenvelope + const uuid = crypto.randomUUID(); + safeEnqueue({ + type: 'evault_metaenvelope_created', + evaultIndex: 0, + uuid: uuid, + message: `Created metaenvelope with ID: ${uuid}`, + timestamp: new Date().toISOString() + }); + }, 13000); + timeouts.push(timeout3); + + const timeout4 = setTimeout(() => { + // Step 4: Notify all platforms through awareness protocol + safeEnqueue({ + type: 'notify_platforms_awareness', + evaultIndex: 0, + message: 'Notifying platforms through awareness protocol', + timestamp: new Date().toISOString() + }); + }, 18000); + timeouts.push(timeout4); + + // Keep connection alive with periodic heartbeats + const heartbeat = setInterval(() => { + if (isConnected) { + try { + controller.enqueue(`data: ${JSON.stringify({ type: 'heartbeat', timestamp: new Date().toISOString() })}\n\n`); + } catch (error) { + console.log('Client disconnected during heartbeat, stopping stream'); + isConnected = false; + clearInterval(heartbeat); + } + } + }, 30000); + + // Cleanup function + const cleanup = () => { + isConnected = false; + timeouts.forEach(timeout => clearTimeout(timeout)); + clearInterval(heartbeat); + }; + + // Handle client disconnect + const handleDisconnect = () => { + console.log('Client disconnected, cleaning up...'); + cleanup(); + }; + + // Return cleanup function + return () => { + cleanup(); + }; + } + }); + + return new Response(stream, { + headers: { + 'Content-Type': 'text/event-stream', + 'Cache-Control': 'no-cache', + 'Connection': 'keep-alive', + 'Access-Control-Allow-Origin': '*', + 'Access-Control-Allow-Headers': 'Cache-Control' + } + }); +}; \ No newline at end of file diff --git a/infrastructure/control-panel/src/routes/monitoring/+page.svelte b/infrastructure/control-panel/src/routes/monitoring/+page.svelte index c308041e..1589659f 100644 --- a/infrastructure/control-panel/src/routes/monitoring/+page.svelte +++ b/infrastructure/control-panel/src/routes/monitoring/+page.svelte @@ -1,171 +1,341 @@
-

Live Monitoring

+
+

Live Monitoring

+

+ Monitoring {selectedEVaults.length} eVault{selectedEVaults.length !== 1 + ? 's' + : ''} and {selectedPlatforms.length} platform{selectedPlatforms.length !== 1 + ? 's' + : ''} +

+ {#if currentFlowStep > 0} +
+
+ + {currentFlowStep === 1 + ? 'Platform creating message' + : currentFlowStep === 2 + ? 'Request sent to eVault' + : currentFlowStep === 3 + ? 'eVault created metaenvelope' + : currentFlowStep === 4 + ? 'Notifying platforms' + : 'Complete'} + +
+ {/if} +
- { - isModalOpen = !isModalOpen; - }}>+ Add Vault goto('/')} + class="font-geist flex items-center gap-2 rounded-full border border-[#e5e5e5] bg-white px-4 py-2 text-base font-medium text-gray-700 shadow-md transition-colors hover:bg-gray-50" > + ← Back to Control Panel +
{#if SvelteFlowComponent} -
- -
+ {#if selectedEVaults.length === 0 && selectedPlatforms.length === 0} +
+
+

No Items Selected

+

+ Go back to the main page and select eVaults and platforms to monitor. +

+
+
+ {:else} +
+ + + + + + + + + + + + + + + + +
+ {/if} {:else}
Loading flow chart...
{/if}
- -
- -

Search vaults

- - -
    - {#each availableVaults as vault (vault.id)} -
  • - - - -
  • - {/each} -
- Add Voults +
= 4 ? startSequence : undefined} + class:cursor-pointer={!sequenceStarted || currentFlowStep >= 4} + class:cursor-default={sequenceStarted && currentFlowStep < 4} > - +
+

Data Flow

+ {#if sequenceStarted} +
+ Current Step: {currentFlowStep === 0 + ? 'Waiting...' + : currentFlowStep === 1 + ? 'Platform creating message' + : currentFlowStep === 2 + ? 'Request sent to eVault' + : currentFlowStep === 3 + ? 'eVault created metaenvelope' + : currentFlowStep === 4 + ? 'Notifying platforms' + : 'Complete'} +
+ {/if} +
+ +
+ {#each flowMessages as message, i} +
+ {message} +
+ {/each} +
+
+ diff --git a/infrastructure/eid-wallet/src-tauri/capabilities/mobile.json b/infrastructure/eid-wallet/src-tauri/capabilities/mobile.json index fa6ee646..7410b853 100644 --- a/infrastructure/eid-wallet/src-tauri/capabilities/mobile.json +++ b/infrastructure/eid-wallet/src-tauri/capabilities/mobile.json @@ -9,7 +9,8 @@ "store:default", "biometric:default", "barcode-scanner:default", - "deep-link:default" + "deep-link:default", + "crypto-hw:default" ], "platforms": ["iOS", "android"] } diff --git a/infrastructure/eid-wallet/src-tauri/src/lib.rs b/infrastructure/eid-wallet/src-tauri/src/lib.rs index 586f8506..18334828 100644 --- a/infrastructure/eid-wallet/src-tauri/src/lib.rs +++ b/infrastructure/eid-wallet/src-tauri/src/lib.rs @@ -43,6 +43,7 @@ pub fn run() { { _app.handle().plugin(tauri_plugin_biometric::init())?; _app.handle().plugin(tauri_plugin_barcode_scanner::init())?; + _app.handle().plugin(tauri_plugin_crypto_hw::init())?; } Ok(()) }) diff --git a/infrastructure/evault-core/src/evault.ts b/infrastructure/evault-core/src/evault.ts index d30864df..dec41d74 100644 --- a/infrastructure/evault-core/src/evault.ts +++ b/infrastructure/evault-core/src/evault.ts @@ -22,12 +22,16 @@ class EVault { graphqlServer: GraphQLServer; logService: LogService; driver: Driver; + publicKey: string | null; + w3id: string | null; private constructor(driver: Driver) { this.driver = driver; + this.publicKey = process.env.EVAULT_PUBLIC_KEY || null; + this.w3id = process.env.W3ID || null; const dbService = new DbService(driver); this.logService = new LogService(driver); - this.graphqlServer = new GraphQLServer(dbService); + this.graphqlServer = new GraphQLServer(dbService, this.publicKey, this.w3id); this.server = fastify({ logger: true, }); @@ -48,18 +52,27 @@ class EVault { ); } + if (!process.env.W3ID) { + console.warn( + "W3ID environment variable not set. The eVault will not have an associated W3ID identifier.", + ); + } + + if (!process.env.EVAULT_PUBLIC_KEY) { + console.warn( + "EVAULT_PUBLIC_KEY environment variable not set. The eVault will not have an associated public key for cryptographic operations.", + ); + } + const driver = await connectWithRetry(uri, user, password); return new EVault(driver); } async initialize() { - await registerHttpRoutes(this.server); + await registerHttpRoutes(this.server, this); - const w3id = await W3ID.get({ - id: process.env.W3ID as string, - driver: this.driver, - password: process.env.ENCRYPTION_PASSWORD, - }); + // No longer automatically create W3ID - just use the provided W3ID and public key + // The private key is now managed on the user's phone const yoga = this.graphqlServer.init(); diff --git a/infrastructure/evault-core/src/http/server.ts b/infrastructure/evault-core/src/http/server.ts index ea1d01d8..4bbda27f 100644 --- a/infrastructure/evault-core/src/http/server.ts +++ b/infrastructure/evault-core/src/http/server.ts @@ -1,11 +1,7 @@ import fastify, { FastifyInstance } from "fastify"; import swagger from "@fastify/swagger"; import swaggerUi from "@fastify/swagger-ui"; -import { W3ID } from "../w3id/w3id"; -import { LogEvent } from "w3id"; -import axios from "axios"; import { WatcherRequest, TypedRequest, TypedReply } from "./types"; -import { verifierCallback } from "../utils/signer"; interface WatcherSignatureRequest { w3id: string; @@ -18,7 +14,8 @@ interface WatcherSignatureRequest { } export async function registerHttpRoutes( - server: FastifyInstance + server: FastifyInstance, + evault: any // EVault instance to access publicKey ): Promise { // Register Swagger await server.register(swagger, { @@ -42,61 +39,46 @@ export async function registerHttpRoutes( routePrefix: "/docs", }); - // Whois endpoint + // Whois endpoint - returns both W3ID identifier and public key server.get( "/whois", { schema: { tags: ["identity"], - description: "Get W3ID response with logs", + description: "Get eVault W3ID identifier and public key", response: { 200: { type: "object", properties: { w3id: { type: "string" }, - logs: { - type: "array", - items: { - type: "object", - properties: { - id: { type: "string" }, - versionId: { type: "string" }, - versionTime: { type: "string", format: "date-time" }, - updateKeys: { type: "array", items: { type: "string" } }, - nextKeyHashes: { type: "array", items: { type: "string" } }, - method: { type: "string" }, - proofs: { - type: "array", - items: { - type: "object", - properties: { - signature: { type: "string" }, - alg: { type: "string" }, - kid: { type: "string" }, - }, - }, - }, - }, - }, - }, + publicKey: { type: "string" }, + message: { type: "string" }, }, }, }, }, }, async (request: TypedRequest<{}>, reply: TypedReply) => { - const w3id = await W3ID.get(); - const logs = (await w3id.logs?.repository.findMany({})) as LogEvent[]; const result = { - w3id: w3id.id, - logs: logs, + w3id: evault.w3id, + publicKey: evault.publicKey, + message: evault.w3id && evault.publicKey + ? "eVault identified by W3ID and public key" + : evault.w3id + ? "eVault identified by W3ID only (no public key)" + : evault.publicKey + ? "eVault identified by public key only (no W3ID)" + : "eVault has no associated identifier or public key", }; - console.log(result); + console.log("Whois request:", result); return result; } ); - // Watchers signature endpoint + // Watchers signature endpoint - DISABLED: Requires W3ID functionality + // This endpoint is disabled because the eVault no longer creates/manages W3IDs + // The private key is now stored on the user's phone + /* server.post<{ Body: WatcherSignatureRequest }>( "/watchers/sign", { @@ -178,12 +160,17 @@ export async function registerHttpRoutes( error instanceof Error ? error.message : "Failed to store signature", + requestId: "", }; } } ); + */ - // Watchers request endpoint + // Watchers request endpoint - DISABLED: Requires W3ID functionality + // This endpoint is disabled because the eVault no longer creates/manages W3IDs + // The private key is now stored on the user's phone + /* server.post<{ Body: WatcherRequest }>( "/watchers/request", { @@ -262,4 +249,5 @@ export async function registerHttpRoutes( } } ); + */ } diff --git a/infrastructure/evault-core/src/protocol/graphql-server.ts b/infrastructure/evault-core/src/protocol/graphql-server.ts index 44ae7d88..410467a5 100644 --- a/infrastructure/evault-core/src/protocol/graphql-server.ts +++ b/infrastructure/evault-core/src/protocol/graphql-server.ts @@ -17,9 +17,14 @@ export class GraphQLServer { resolvers: {}, }); server?: Server; - constructor(db: DbService) { + private evaultPublicKey: string | null; + private evaultW3ID: string | null; + + constructor(db: DbService, evaultPublicKey?: string | null, evaultW3ID?: string | null) { this.db = db; this.accessGuard = new VaultAccessGuard(db); + this.evaultPublicKey = evaultPublicKey || process.env.EVAULT_PUBLIC_KEY || null; + this.evaultW3ID = evaultW3ID || process.env.W3ID || null; } public getSchema(): GraphQLSchema { @@ -165,7 +170,8 @@ export class GraphQLServer { context.tokenPayload?.platform || null; const webhookPayload = { id: result.metaEnvelope.id, - w3id: `@${process.env.W3ID}`, + w3id: this.evaultW3ID, + evaultPublicKey: this.evaultPublicKey, data: input.payload, schemaId: input.ontology, }; @@ -222,7 +228,8 @@ export class GraphQLServer { context.tokenPayload?.platform || null; const webhookPayload = { id: id, - w3id: `@${process.env.W3ID}`, + w3id: this.evaultW3ID, + evaultPublicKey: this.evaultPublicKey, data: input.payload, schemaId: input.ontology, }; diff --git a/infrastructure/evault-provisioner/src/index.ts b/infrastructure/evault-provisioner/src/index.ts index e5ede877..5673a9db 100644 --- a/infrastructure/evault-provisioner/src/index.ts +++ b/infrastructure/evault-provisioner/src/index.ts @@ -53,6 +53,7 @@ interface ProvisionRequest { registryEntropy: string; namespace: string; verificationId: string; + publicKey: string; } interface ProvisionResponse { @@ -81,13 +82,13 @@ app.post( console.log("provisioner log 1"); if (!process.env.PUBLIC_REGISTRY_URL) throw new Error("PUBLIC_REGISTRY_URL is not set"); - const { registryEntropy, namespace, verificationId } = req.body; - if (!registryEntropy || !namespace || !verificationId) { + const { registryEntropy, namespace, verificationId, publicKey } = req.body; + if (!registryEntropy || !namespace || !verificationId || !publicKey) { return res.status(400).json({ success: false, error: "registryEntropy and namespace are required", message: - "Missing required fields: registryEntropy, namespace, verifficationId", + "Missing required fields: registryEntropy, namespace, verifficationId, publicKey", }); } @@ -129,7 +130,8 @@ app.post( const evaultId = await new W3IDBuilder().withGlobal(true).build(); const uri = await provisionEVault( w3id, - process.env.PUBLIC_REGISTRY_URL + process.env.PUBLIC_REGISTRY_URL, + publicKey ); await axios.post( new URL( diff --git a/infrastructure/evault-provisioner/src/templates/evault.nomad.ts b/infrastructure/evault-provisioner/src/templates/evault.nomad.ts index bc2aa115..8fe41048 100644 --- a/infrastructure/evault-provisioner/src/templates/evault.nomad.ts +++ b/infrastructure/evault-provisioner/src/templates/evault.nomad.ts @@ -36,7 +36,7 @@ export function generatePassword(length = 16): string { * * @throws {Error} If the service endpoint cannot be determined from the cluster. */ -export async function provisionEVault(w3id: string, registryUrl: string) { +export async function provisionEVault(w3id: string, registryUrl: string, publicKey: string) { console.log("starting to provision"); const idParts = w3id.split("@"); w3id = idParts[idParts.length - 1]; @@ -128,6 +128,10 @@ export async function provisionEVault(w3id: string, registryUrl: string) { name: "REGISTRY_URL", value: registryUrl, }, + { + name: "EVAULT_PUBLIC_KEY", + value: publicKey + }, { name: "NEO4J_PASSWORD", value: neo4jPassword,