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 <noreply@anthropic.com>
This commit is contained in:
2026-06-17 22:58:27 -04:00
parent bebd5bd7cb
commit b15ed4bff8
+13 -1
View File
@@ -29,6 +29,11 @@ function toSmtpSenderConfig(sender: any) {
}; };
} }
async function sha256Hex(bytes: Uint8Array): Promise<string> {
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) => { Deno.serve(async (req) => {
if (req.method === "OPTIONS") return new Response(null, { headers: corsHeaders }); 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")!); 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); const pdfRes = await fetch(env.document_url);
if (!pdfRes.ok) throw new Error("Could not fetch original document"); if (!pdfRes.ok) throw new Error("Could not fetch original document");
const pdfBytes = new Uint8Array(await pdfRes.arrayBuffer()); const pdfBytes = new Uint8Array(await pdfRes.arrayBuffer());
const docHash = await sha256Hex(pdfBytes);
let pdfDoc: PDFDocument; let pdfDoc: PDFDocument;
try { 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("Completed:", new Date(env.completed_at || Date.now()).toLocaleString("en-US", { timeZone: "America/New_York" }) + " EST");
drawRow("Status:", "COMPLETED"); 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 }); cert.drawText("SIGNERS", { x: 70, y, size: 12, font: helvBold });
y -= 20; y -= 20;