fix: add symmetric encryption to document passwords
This commit is contained in:
@@ -3,10 +3,12 @@ import { redirect } from 'next/navigation';
|
|||||||
|
|
||||||
import { ChevronLeft, Users2 } from 'lucide-react';
|
import { ChevronLeft, Users2 } from 'lucide-react';
|
||||||
|
|
||||||
|
import { DOCUMENSO_ENCRYPTION_KEY } from '@documenso/lib/constants/crypto';
|
||||||
import { getRequiredServerComponentSession } from '@documenso/lib/next-auth/get-server-component-session';
|
import { getRequiredServerComponentSession } from '@documenso/lib/next-auth/get-server-component-session';
|
||||||
import { getDocumentById } from '@documenso/lib/server-only/document/get-document-by-id';
|
import { getDocumentById } from '@documenso/lib/server-only/document/get-document-by-id';
|
||||||
import { getFieldsForDocument } from '@documenso/lib/server-only/field/get-fields-for-document';
|
import { getFieldsForDocument } from '@documenso/lib/server-only/field/get-fields-for-document';
|
||||||
import { getRecipientsForDocument } from '@documenso/lib/server-only/recipient/get-recipients-for-document';
|
import { getRecipientsForDocument } from '@documenso/lib/server-only/recipient/get-recipients-for-document';
|
||||||
|
import { symmetricDecrypt } from '@documenso/lib/universal/crypto';
|
||||||
import { DocumentStatus as InternalDocumentStatus } from '@documenso/prisma/client';
|
import { DocumentStatus as InternalDocumentStatus } from '@documenso/prisma/client';
|
||||||
import { LazyPDFViewer } from '@documenso/ui/primitives/lazy-pdf-viewer';
|
import { LazyPDFViewer } from '@documenso/ui/primitives/lazy-pdf-viewer';
|
||||||
|
|
||||||
@@ -42,6 +44,23 @@ export default async function DocumentPage({ params }: DocumentPageProps) {
|
|||||||
|
|
||||||
const { documentData, documentMeta } = document;
|
const { documentData, documentMeta } = document;
|
||||||
|
|
||||||
|
if (documentMeta?.password) {
|
||||||
|
const key = DOCUMENSO_ENCRYPTION_KEY;
|
||||||
|
|
||||||
|
if (!key) {
|
||||||
|
throw new Error('Missing DOCUMENSO_ENCRYPTION_KEY');
|
||||||
|
}
|
||||||
|
|
||||||
|
const securePassword = Buffer.from(
|
||||||
|
symmetricDecrypt({
|
||||||
|
key,
|
||||||
|
data: documentMeta.password,
|
||||||
|
}),
|
||||||
|
).toString('utf-8');
|
||||||
|
|
||||||
|
documentMeta.password = securePassword;
|
||||||
|
}
|
||||||
|
|
||||||
const [recipients, fields] = await Promise.all([
|
const [recipients, fields] = await Promise.all([
|
||||||
getRecipientsForDocument({
|
getRecipientsForDocument({
|
||||||
documentId,
|
documentId,
|
||||||
|
|||||||
@@ -2,6 +2,7 @@ import { notFound, redirect } from 'next/navigation';
|
|||||||
|
|
||||||
import { match } from 'ts-pattern';
|
import { match } from 'ts-pattern';
|
||||||
|
|
||||||
|
import { DOCUMENSO_ENCRYPTION_KEY } from '@documenso/lib/constants/crypto';
|
||||||
import { DEFAULT_DOCUMENT_DATE_FORMAT } from '@documenso/lib/constants/date-formats';
|
import { DEFAULT_DOCUMENT_DATE_FORMAT } from '@documenso/lib/constants/date-formats';
|
||||||
import { PDF_VIEWER_PAGE_SELECTOR } from '@documenso/lib/constants/pdf-viewer';
|
import { PDF_VIEWER_PAGE_SELECTOR } from '@documenso/lib/constants/pdf-viewer';
|
||||||
import { DEFAULT_DOCUMENT_TIME_ZONE } from '@documenso/lib/constants/time-zones';
|
import { DEFAULT_DOCUMENT_TIME_ZONE } from '@documenso/lib/constants/time-zones';
|
||||||
@@ -12,6 +13,7 @@ import { viewedDocument } from '@documenso/lib/server-only/document/viewed-docum
|
|||||||
import { getFieldsForToken } from '@documenso/lib/server-only/field/get-fields-for-token';
|
import { getFieldsForToken } from '@documenso/lib/server-only/field/get-fields-for-token';
|
||||||
import { getRecipientByToken } from '@documenso/lib/server-only/recipient/get-recipient-by-token';
|
import { getRecipientByToken } from '@documenso/lib/server-only/recipient/get-recipient-by-token';
|
||||||
import { getRecipientSignatures } from '@documenso/lib/server-only/recipient/get-recipient-signatures';
|
import { getRecipientSignatures } from '@documenso/lib/server-only/recipient/get-recipient-signatures';
|
||||||
|
import { symmetricDecrypt } from '@documenso/lib/universal/crypto';
|
||||||
import { DocumentStatus, FieldType, SigningStatus } from '@documenso/prisma/client';
|
import { DocumentStatus, FieldType, SigningStatus } from '@documenso/prisma/client';
|
||||||
import { Card, CardContent } from '@documenso/ui/primitives/card';
|
import { Card, CardContent } from '@documenso/ui/primitives/card';
|
||||||
import { ElementVisible } from '@documenso/ui/primitives/element-visible';
|
import { ElementVisible } from '@documenso/ui/primitives/element-visible';
|
||||||
@@ -66,6 +68,23 @@ export default async function SigningPage({ params: { token } }: SigningPageProp
|
|||||||
redirect(`/sign/${token}/complete`);
|
redirect(`/sign/${token}/complete`);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (documentMeta?.password) {
|
||||||
|
const key = DOCUMENSO_ENCRYPTION_KEY;
|
||||||
|
|
||||||
|
if (!key) {
|
||||||
|
throw new Error('Missing DOCUMENSO_ENCRYPTION_KEY');
|
||||||
|
}
|
||||||
|
|
||||||
|
const securePassword = Buffer.from(
|
||||||
|
symmetricDecrypt({
|
||||||
|
key,
|
||||||
|
data: documentMeta.password,
|
||||||
|
}),
|
||||||
|
).toString('utf-8');
|
||||||
|
|
||||||
|
documentMeta.password = securePassword;
|
||||||
|
}
|
||||||
|
|
||||||
const [recipientSignature] = await getRecipientSignatures({ recipientId: recipient.id });
|
const [recipientSignature] = await getRecipientSignatures({ recipientId: recipient.id });
|
||||||
|
|
||||||
if (document.deletedAt) {
|
if (document.deletedAt) {
|
||||||
|
|||||||
@@ -1,6 +1,7 @@
|
|||||||
import { TRPCError } from '@trpc/server';
|
import { TRPCError } from '@trpc/server';
|
||||||
|
|
||||||
import { getServerLimits } from '@documenso/ee/server-only/limits/server';
|
import { getServerLimits } from '@documenso/ee/server-only/limits/server';
|
||||||
|
import { DOCUMENSO_ENCRYPTION_KEY } from '@documenso/lib/constants/crypto';
|
||||||
import { upsertDocumentMeta } from '@documenso/lib/server-only/document-meta/upsert-document-meta';
|
import { upsertDocumentMeta } from '@documenso/lib/server-only/document-meta/upsert-document-meta';
|
||||||
import { createDocument } from '@documenso/lib/server-only/document/create-document';
|
import { createDocument } from '@documenso/lib/server-only/document/create-document';
|
||||||
import { deleteDocument } from '@documenso/lib/server-only/document/delete-document';
|
import { deleteDocument } from '@documenso/lib/server-only/document/delete-document';
|
||||||
@@ -13,6 +14,7 @@ import { sendDocument } from '@documenso/lib/server-only/document/send-document'
|
|||||||
import { updateTitle } from '@documenso/lib/server-only/document/update-title';
|
import { updateTitle } from '@documenso/lib/server-only/document/update-title';
|
||||||
import { setFieldsForDocument } from '@documenso/lib/server-only/field/set-fields-for-document';
|
import { setFieldsForDocument } from '@documenso/lib/server-only/field/set-fields-for-document';
|
||||||
import { setRecipientsForDocument } from '@documenso/lib/server-only/recipient/set-recipients-for-document';
|
import { setRecipientsForDocument } from '@documenso/lib/server-only/recipient/set-recipients-for-document';
|
||||||
|
import { symmetricEncrypt } from '@documenso/lib/universal/crypto';
|
||||||
|
|
||||||
import { authenticatedProcedure, procedure, router } from '../trpc';
|
import { authenticatedProcedure, procedure, router } from '../trpc';
|
||||||
import {
|
import {
|
||||||
@@ -182,9 +184,20 @@ export const documentRouter = router({
|
|||||||
try {
|
try {
|
||||||
const { documentId, password } = input;
|
const { documentId, password } = input;
|
||||||
|
|
||||||
|
const key = DOCUMENSO_ENCRYPTION_KEY;
|
||||||
|
|
||||||
|
if (!key) {
|
||||||
|
throw new Error('Missing encryption key');
|
||||||
|
}
|
||||||
|
|
||||||
|
const securePassword = symmetricEncrypt({
|
||||||
|
data: password,
|
||||||
|
key,
|
||||||
|
});
|
||||||
|
|
||||||
await upsertDocumentMeta({
|
await upsertDocumentMeta({
|
||||||
documentId,
|
documentId,
|
||||||
password,
|
password: securePassword,
|
||||||
userId: ctx.user.id,
|
userId: ctx.user.id,
|
||||||
});
|
});
|
||||||
} catch (err) {
|
} catch (err) {
|
||||||
|
|||||||
Reference in New Issue
Block a user