From b15ed4bff85bfd6b1402c45a2a5fc68fa72db012 Mon Sep 17 00:00:00 2001 From: renee-png Date: Wed, 17 Jun 2026 22:58:27 -0400 Subject: [PATCH] Avria Sign: add SHA-256 document hash to certificate of completion The Certificate of Validation claimed "cryptographic proof ... and integrity" but showed no hash. Add a real SHA-256 of the original document to the certificate page so the integrity claim is backed by a verifiable digest. (Deploy via MCP alongside the base-flow fix.) Co-Authored-By: Claude Opus 4.8 --- supabase/functions/avria-sign-stamp/index.ts | 14 +++++++++++++- 1 file changed, 13 insertions(+), 1 deletion(-) diff --git a/supabase/functions/avria-sign-stamp/index.ts b/supabase/functions/avria-sign-stamp/index.ts index 236e87a..7621525 100644 --- a/supabase/functions/avria-sign-stamp/index.ts +++ b/supabase/functions/avria-sign-stamp/index.ts @@ -29,6 +29,11 @@ function toSmtpSenderConfig(sender: any) { }; } +async function sha256Hex(bytes: Uint8Array): Promise { + const digest = await crypto.subtle.digest("SHA-256", bytes); + return Array.from(new Uint8Array(digest)).map((b) => b.toString(16).padStart(2, "0")).join(""); +} + Deno.serve(async (req) => { if (req.method === "OPTIONS") return new Response(null, { headers: corsHeaders }); const admin = createClient(Deno.env.get("SUPABASE_URL")!, Deno.env.get("SUPABASE_SERVICE_ROLE_KEY")!); @@ -50,6 +55,7 @@ Deno.serve(async (req) => { const pdfRes = await fetch(env.document_url); if (!pdfRes.ok) throw new Error("Could not fetch original document"); const pdfBytes = new Uint8Array(await pdfRes.arrayBuffer()); + const docHash = await sha256Hex(pdfBytes); let pdfDoc: PDFDocument; try { @@ -167,7 +173,13 @@ Deno.serve(async (req) => { drawRow("Completed:", new Date(env.completed_at || Date.now()).toLocaleString("en-US", { timeZone: "America/New_York" }) + " EST"); drawRow("Status:", "COMPLETED"); - y -= 10; + // Real cryptographic integrity proof: SHA-256 of the original document. + cert.drawText("Document SHA-256 (original):", { x: 70, y, size: 11, font: helvBold }); + y -= 14; + cert.drawText(docHash, { x: 70, y, size: 8, font: helv, color: rgb(0.3, 0.3, 0.3) }); + cert.drawLine({ start: { x: 70, y: y - 5 }, end: { x: width - 70, y: y - 5 }, thickness: 0.3, color: rgb(0.7, 0.7, 0.7) }); + y -= 26; + cert.drawText("SIGNERS", { x: 70, y, size: 12, font: helvBold }); y -= 20;