Merge branch 'main' into show-time

This commit is contained in:
Rushat Gabhane
2024-05-03 12:29:23 +05:30
committed by GitHub
7 changed files with 66 additions and 37 deletions

View File

@ -5,7 +5,7 @@ import { Button } from '@documenso/ui/primitives/button';
export default function SignatureDisclosure() { export default function SignatureDisclosure() {
return ( return (
<div> <div>
<article className="prose"> <article className="prose dark:prose-invert">
<h1>Electronic Signature Disclosure</h1> <h1>Electronic Signature Disclosure</h1>
<h2>Welcome</h2> <h2>Welcome</h2>

View File

@ -2,6 +2,8 @@ import type { NextApiRequest, NextApiResponse } from 'next';
import NextAuth from 'next-auth'; import NextAuth from 'next-auth';
import { getStripeCustomerByUser } from '@documenso/ee/server-only/stripe/get-customer';
import { IS_BILLING_ENABLED } from '@documenso/lib/constants/app';
import { NEXT_AUTH_OPTIONS } from '@documenso/lib/next-auth/auth-options'; import { NEXT_AUTH_OPTIONS } from '@documenso/lib/next-auth/auth-options';
import { extractNextApiRequestMetadata } from '@documenso/lib/universal/extract-request-metadata'; import { extractNextApiRequestMetadata } from '@documenso/lib/universal/extract-request-metadata';
import { prisma } from '@documenso/prisma'; import { prisma } from '@documenso/prisma';
@ -18,15 +20,29 @@ export default async function auth(req: NextApiRequest, res: NextApiResponse) {
error: '/signin', error: '/signin',
}, },
events: { events: {
signIn: async ({ user }) => { signIn: async ({ user: { id: userId } }) => {
const [user] = await Promise.all([
await prisma.user.findFirstOrThrow({
where: {
id: userId,
},
}),
await prisma.userSecurityAuditLog.create({ await prisma.userSecurityAuditLog.create({
data: { data: {
userId: user.id, userId,
ipAddress, ipAddress,
userAgent, userAgent,
type: UserSecurityAuditLogType.SIGN_IN, type: UserSecurityAuditLogType.SIGN_IN,
}, },
}),
]);
// Create the Stripe customer and attach it to the user if it doesn't exist.
if (user.customerId === null && IS_BILLING_ENABLED()) {
await getStripeCustomerByUser(user).catch((err) => {
console.error(err);
}); });
}
}, },
signOut: async ({ token }) => { signOut: async ({ token }) => {
const userId = typeof token.id === 'string' ? parseInt(token.id) : token.id; const userId = typeof token.id === 'string' ? parseInt(token.id) : token.id;

View File

@ -137,7 +137,7 @@ export const completeDocumentWithToken = async ({
await sendPendingEmail({ documentId, recipientId: recipient.id }); await sendPendingEmail({ documentId, recipientId: recipient.id });
} }
const documents = await prisma.document.updateMany({ const haveAllRecipientsSigned = await prisma.document.findFirst({
where: { where: {
id: document.id, id: document.id,
Recipient: { Recipient: {
@ -146,13 +146,9 @@ export const completeDocumentWithToken = async ({
}, },
}, },
}, },
data: {
status: DocumentStatus.COMPLETED,
completedAt: new Date(),
},
}); });
if (documents.count > 0) { if (haveAllRecipientsSigned) {
await sealDocument({ documentId: document.id, requestMetadata }); await sealDocument({ documentId: document.id, requestMetadata });
} }

View File

@ -75,17 +75,19 @@ export const deleteDocument = async ({
} }
// Continue to hide the document from the user if they are a recipient. // Continue to hide the document from the user if they are a recipient.
// Dirty way of doing this but it's faster than refetching the document.
if (userRecipient?.documentDeletedAt === null) { if (userRecipient?.documentDeletedAt === null) {
await prisma.recipient.update({ await prisma.recipient
.update({
where: { where: {
documentId_email: { id: userRecipient.id,
documentId: document.id,
email: user.email,
},
}, },
data: { data: {
documentDeletedAt: new Date().toISOString(), documentDeletedAt: new Date().toISOString(),
}, },
})
.catch(() => {
// Do nothing.
}); });
} }

View File

@ -40,6 +40,11 @@ export const sealDocument = async ({
const document = await prisma.document.findFirstOrThrow({ const document = await prisma.document.findFirstOrThrow({
where: { where: {
id: documentId, id: documentId,
Recipient: {
every: {
signingStatus: SigningStatus.SIGNED,
},
},
}, },
include: { include: {
documentData: true, documentData: true,
@ -53,10 +58,6 @@ export const sealDocument = async ({
throw new Error(`Document ${document.id} has no document data`); throw new Error(`Document ${document.id} has no document data`);
} }
if (document.status !== DocumentStatus.COMPLETED) {
throw new Error(`Document ${document.id} has not been completed`);
}
const recipients = await prisma.recipient.findMany({ const recipients = await prisma.recipient.findMany({
where: { where: {
documentId: document.id, documentId: document.id,
@ -92,9 +93,9 @@ export const sealDocument = async ({
// !: Need to write the fields onto the document as a hard copy // !: Need to write the fields onto the document as a hard copy
const pdfData = await getFile(documentData); const pdfData = await getFile(documentData);
const certificate = await getCertificatePdf({ documentId }).then(async (doc) => const certificate = await getCertificatePdf({ documentId })
PDFDocument.load(doc), .then(async (doc) => PDFDocument.load(doc))
); .catch(() => null);
const doc = await PDFDocument.load(pdfData); const doc = await PDFDocument.load(pdfData);
@ -103,11 +104,13 @@ export const sealDocument = async ({
doc.getForm().flatten(); doc.getForm().flatten();
flattenAnnotations(doc); flattenAnnotations(doc);
if (certificate) {
const certificatePages = await doc.copyPages(certificate, certificate.getPageIndices()); const certificatePages = await doc.copyPages(certificate, certificate.getPageIndices());
certificatePages.forEach((page) => { certificatePages.forEach((page) => {
doc.addPage(page); doc.addPage(page);
}); });
}
for (const field of fields) { for (const field of fields) {
await insertFieldInPDF(doc, field); await insertFieldInPDF(doc, field);
@ -138,6 +141,16 @@ export const sealDocument = async ({
} }
await prisma.$transaction(async (tx) => { await prisma.$transaction(async (tx) => {
await tx.document.update({
where: {
id: document.id,
},
data: {
status: DocumentStatus.COMPLETED,
completedAt: new Date(),
},
});
await tx.documentData.update({ await tx.documentData.update({
where: { where: {
id: documentData.id, id: documentData.id,

View File

@ -35,6 +35,7 @@ export const getCertificatePdf = async ({ documentId }: GetCertificatePdfOptions
await page.goto(`${NEXT_PUBLIC_WEBAPP_URL()}/__htmltopdf/certificate?d=${encryptedId}`, { await page.goto(`${NEXT_PUBLIC_WEBAPP_URL()}/__htmltopdf/certificate?d=${encryptedId}`, {
waitUntil: 'networkidle', waitUntil: 'networkidle',
timeout: 10_000,
}); });
const result = await page.pdf({ const result = await page.pdf({

View File

@ -282,6 +282,7 @@ export const AddTemplatePlaceholderRecipientsFormPartial = ({
<Button <Button
type="button" type="button"
className="dark:bg-muted dark:hover:bg-muted/80 bg-black/5 hover:bg-black/10" className="dark:bg-muted dark:hover:bg-muted/80 bg-black/5 hover:bg-black/10"
variant="secondary"
disabled={ disabled={
isSubmitting || getValues('signers').some((signer) => signer.email === user?.email) isSubmitting || getValues('signers').some((signer) => signer.email === user?.email)
} }