import React from 'react'; import { redirect } from 'next/navigation'; import { match } from 'ts-pattern'; import { UAParser } from 'ua-parser-js'; import { RECIPIENT_ROLES_DESCRIPTION, RECIPIENT_ROLE_SIGNING_REASONS, } from '@documenso/lib/constants/recipient-roles'; import { getEntireDocument } from '@documenso/lib/server-only/admin/get-entire-document'; import { decryptSecondaryData } from '@documenso/lib/server-only/crypto/decrypt'; import { getDocumentCertificateAuditLogs } from '@documenso/lib/server-only/document/get-document-certificate-audit-logs'; import { DOCUMENT_AUDIT_LOG_TYPE } from '@documenso/lib/types/document-audit-logs'; import { extractDocumentAuthMethods } from '@documenso/lib/utils/document-auth'; import { FieldType } from '@documenso/prisma/client'; import { Card, CardContent } from '@documenso/ui/primitives/card'; import { Table, TableBody, TableCell, TableHead, TableHeader, TableRow, } from '@documenso/ui/primitives/table'; import { Logo } from '~/components/branding/logo'; import { LocaleDate } from '~/components/formatter/locale-date'; type SigningCertificateProps = { searchParams: { d: string; }; }; const FRIENDLY_SIGNING_REASONS = { ['__OWNER__']: 'I am the owner of this document', ...RECIPIENT_ROLE_SIGNING_REASONS, }; export default async function SigningCertificate({ searchParams }: SigningCertificateProps) { const { d } = searchParams; if (typeof d !== 'string' || !d) { return redirect('/'); } const rawDocumentId = decryptSecondaryData(d); if (!rawDocumentId || isNaN(Number(rawDocumentId))) { return redirect('/'); } const documentId = Number(rawDocumentId); const document = await getEntireDocument({ id: documentId, }).catch(() => null); if (!document) { return redirect('/'); } const auditLogs = await getDocumentCertificateAuditLogs({ id: documentId, }); const isOwner = (email: string) => { return email.toLowerCase() === document.User.email.toLowerCase(); }; const getDevice = (userAgent?: string | null) => { if (!userAgent) { return 'Unknown'; } const parser = new UAParser(userAgent); parser.setUA(userAgent); const result = parser.getResult(); return `${result.os.name} - ${result.browser.name} ${result.browser.version}`; }; const getAuthenticationLevel = (recipientId: number) => { const recipient = document.Recipient.find((recipient) => recipient.id === recipientId); if (!recipient) { return 'Unknown'; } const extractedAuthMethods = extractDocumentAuthMethods({ documentAuth: document.authOptions, recipientAuth: recipient.authOptions, }); let authLevel = match(extractedAuthMethods.derivedRecipientActionAuth) .with('ACCOUNT', () => 'Account Re-Authentication') .with('TWO_FACTOR_AUTH', () => 'Two-Factor Re-Authentication') .with('PASSKEY', () => 'Passkey Re-Authentication') .with('EXPLICIT_NONE', () => 'Email') .with(null, () => null) .exhaustive(); if (!authLevel) { authLevel = match(extractedAuthMethods.derivedRecipientAccessAuth) .with('ACCOUNT', () => 'Account Authentication') .with(null, () => 'Email') .exhaustive(); } return authLevel; }; const getRecipientAuditLogs = (recipientId: number) => { return { [DOCUMENT_AUDIT_LOG_TYPE.EMAIL_SENT]: auditLogs[DOCUMENT_AUDIT_LOG_TYPE.EMAIL_SENT].filter( (log) => log.type === DOCUMENT_AUDIT_LOG_TYPE.EMAIL_SENT && log.data.recipientId === recipientId, ), [DOCUMENT_AUDIT_LOG_TYPE.DOCUMENT_OPENED]: auditLogs[ DOCUMENT_AUDIT_LOG_TYPE.DOCUMENT_OPENED ].filter( (log) => log.type === DOCUMENT_AUDIT_LOG_TYPE.DOCUMENT_OPENED && log.data.recipientId === recipientId, ), [DOCUMENT_AUDIT_LOG_TYPE.DOCUMENT_RECIPIENT_COMPLETED]: auditLogs[ DOCUMENT_AUDIT_LOG_TYPE.DOCUMENT_RECIPIENT_COMPLETED ].filter( (log) => log.type === DOCUMENT_AUDIT_LOG_TYPE.DOCUMENT_RECIPIENT_COMPLETED && log.data.recipientId === recipientId, ), }; }; const getRecipientSignatureField = (recipientId: number) => { return document.Recipient.find((recipient) => recipient.id === recipientId)?.Field.find( (field) => field.type === FieldType.SIGNATURE || field.type === FieldType.FREE_SIGNATURE, ); }; return (

Signing Certificate

Signer Events Signature Details {/* Security */} {document.Recipient.map((recipient, i) => { const logs = getRecipientAuditLogs(recipient.id); const signature = getRecipientSignatureField(recipient.id); return (
{recipient.name}
{recipient.email}

{RECIPIENT_ROLES_DESCRIPTION[recipient.role].roleName}

Authentication Level:{' '} {getAuthenticationLevel(recipient.id)}

{signature ? ( <>
Signature

Signature ID:{' '} {signature.secondaryId}

IP Address:{' '} {logs.DOCUMENT_RECIPIENT_COMPLETED[0]?.ipAddress ?? 'Unknown'}

Device:{' '} {getDevice(logs.DOCUMENT_RECIPIENT_COMPLETED[0]?.userAgent)}

) : (

N/A

)}

Sent:{' '} {logs.EMAIL_SENT[0] ? ( ) : ( 'Unknown' )}

Viewed:{' '} {logs.DOCUMENT_OPENED[0] ? ( ) : ( 'Unknown' )}

Signed:{' '} {logs.DOCUMENT_RECIPIENT_COMPLETED[0] ? ( ) : ( 'Unknown' )}

Reason:{' '} {isOwner(recipient.email) ? FRIENDLY_SIGNING_REASONS['__OWNER__'] : FRIENDLY_SIGNING_REASONS[recipient.role]}

); })}

Signing certificate provided by:

); }