- Page publique /verify/[id] affichant Odentas Seal, TSA, certificat - API /api/signatures/create-verification pour créer preuves - Générateur PDF de preuve avec QR code (jsPDF) - Hook useSignatureProof() pour intégration facile - Table Supabase signature_verifications avec RLS public - Page de test /test-signature-verification - Documentation complète du système Les signataires peuvent scanner le QR code ou visiter l'URL pour vérifier l'authenticité et l'intégrité de leur document signé.
121 lines
3.4 KiB
TypeScript
121 lines
3.4 KiB
TypeScript
/**
|
|
* Hook pour générer une preuve de signature avec QR code
|
|
*
|
|
* Utilisation après signature d'un document:
|
|
*
|
|
* const { createSignatureProof, isCreating } = useSignatureProof();
|
|
*
|
|
* const proof = await createSignatureProof({
|
|
* document_name: "Contrat CDDU - Jean Dupont",
|
|
* pdf_url: "https://s3.eu-west-3.amazonaws.com/...",
|
|
* signer_name: "Jean Dupont",
|
|
* signer_email: "jean.dupont@example.com",
|
|
* signature_hash: "dafe9a5e258d144190bcf82327ed9dcc...",
|
|
* contract_id: "uuid",
|
|
* organization_id: "uuid"
|
|
* });
|
|
*
|
|
* // proof contient:
|
|
* // - verification_url: URL de vérification publique
|
|
* // - qr_code_data_url: Data URL du QR code
|
|
* // - proof_pdf_blob: Blob du PDF de preuve
|
|
*/
|
|
|
|
import { useState } from "react";
|
|
import { generateSignatureProofPDF } from "@/lib/signature-proof-pdf";
|
|
|
|
interface CreateSignatureProofParams {
|
|
document_name: string;
|
|
pdf_url: string;
|
|
signer_name: string;
|
|
signer_email: string;
|
|
signature_hash: string;
|
|
signature_hex?: string;
|
|
certificate_info?: {
|
|
issuer: string;
|
|
subject: string;
|
|
valid_from: string;
|
|
valid_until: string;
|
|
serial_number: string;
|
|
};
|
|
timestamp?: {
|
|
tsa_url: string;
|
|
timestamp: string;
|
|
hash: string;
|
|
};
|
|
contract_id?: string;
|
|
organization_id: string;
|
|
}
|
|
|
|
interface SignatureProofResult {
|
|
verification_id: string;
|
|
verification_url: string;
|
|
qr_code_data_url: string;
|
|
proof_pdf_blob: Blob;
|
|
}
|
|
|
|
export function useSignatureProof() {
|
|
const [isCreating, setIsCreating] = useState(false);
|
|
const [error, setError] = useState<string | null>(null);
|
|
|
|
const createSignatureProof = async (
|
|
params: CreateSignatureProofParams
|
|
): Promise<SignatureProofResult | null> => {
|
|
setIsCreating(true);
|
|
setError(null);
|
|
|
|
try {
|
|
// Appeler l'API pour créer l'entrée de vérification et générer le QR code
|
|
const response = await fetch("/api/signatures/create-verification", {
|
|
method: "POST",
|
|
headers: {
|
|
"Content-Type": "application/json",
|
|
},
|
|
body: JSON.stringify(params),
|
|
});
|
|
|
|
if (!response.ok) {
|
|
throw new Error("Erreur lors de la création de la preuve");
|
|
}
|
|
|
|
const data = await response.json();
|
|
|
|
// Générer le PDF de preuve avec le QR code
|
|
const proofPdfBlob = await generateSignatureProofPDF({
|
|
document_name: params.document_name,
|
|
signer_name: params.signer_name,
|
|
signer_email: params.signer_email,
|
|
signed_at: new Date().toISOString(),
|
|
signature_hash: params.signature_hash,
|
|
verification_url: data.verification_url,
|
|
qr_code_data_url: data.qr_code_data_url,
|
|
certificate_info: params.certificate_info || {
|
|
issuer: "Odentas Media SAS",
|
|
subject: `CN=${params.signer_name}`,
|
|
valid_from: new Date().toISOString(),
|
|
valid_until: new Date(Date.now() + 365 * 24 * 60 * 60 * 1000).toISOString(),
|
|
serial_number: Math.random().toString(16).substring(2, 18),
|
|
},
|
|
});
|
|
|
|
return {
|
|
verification_id: data.verification_id,
|
|
verification_url: data.verification_url,
|
|
qr_code_data_url: data.qr_code_data_url,
|
|
proof_pdf_blob: proofPdfBlob,
|
|
};
|
|
} catch (err) {
|
|
console.error("Erreur création preuve:", err);
|
|
setError(err instanceof Error ? err.message : "Erreur inconnue");
|
|
return null;
|
|
} finally {
|
|
setIsCreating(false);
|
|
}
|
|
};
|
|
|
|
return {
|
|
createSignatureProof,
|
|
isCreating,
|
|
error,
|
|
};
|
|
}
|