mirror of
https://github.com/documenso/documenso.git
synced 2025-11-15 01:01:49 +10:00
feat: add envelope editor
This commit is contained in:
@ -1,3 +1,4 @@
|
||||
import { EnvelopeType } from '@prisma/client';
|
||||
import { TRPCError } from '@trpc/server';
|
||||
import { DateTime } from 'luxon';
|
||||
|
||||
@ -23,8 +24,9 @@ export const accessAuthRequest2FAEmailRoute = procedure
|
||||
const user = ctx.user;
|
||||
|
||||
// Get document and recipient by token
|
||||
const document = await prisma.document.findFirst({
|
||||
const envelope = await prisma.envelope.findFirst({
|
||||
where: {
|
||||
type: EnvelopeType.DOCUMENT,
|
||||
recipients: {
|
||||
some: {
|
||||
token,
|
||||
@ -40,17 +42,17 @@ export const accessAuthRequest2FAEmailRoute = procedure
|
||||
},
|
||||
});
|
||||
|
||||
if (!document) {
|
||||
if (!envelope) {
|
||||
throw new TRPCError({
|
||||
code: 'NOT_FOUND',
|
||||
message: 'Document not found',
|
||||
});
|
||||
}
|
||||
|
||||
const [recipient] = document.recipients;
|
||||
const [recipient] = envelope.recipients;
|
||||
|
||||
const { derivedRecipientAccessAuth } = extractDocumentAuthMethods({
|
||||
documentAuth: document.authOptions,
|
||||
documentAuth: envelope.authOptions,
|
||||
recipientAuth: recipient.authOptions,
|
||||
});
|
||||
|
||||
@ -72,7 +74,7 @@ export const accessAuthRequest2FAEmailRoute = procedure
|
||||
|
||||
await send2FATokenEmail({
|
||||
token,
|
||||
documentId: document.id,
|
||||
envelopeId: envelope.id,
|
||||
});
|
||||
|
||||
return {
|
||||
|
||||
@ -61,6 +61,7 @@ export const createDocumentTemporaryRoute = authenticatedProcedure
|
||||
userId: ctx.user.id,
|
||||
teamId,
|
||||
normalizePdf: false, // Not normalizing because of presigned URL.
|
||||
internalVersion: 1,
|
||||
data: {
|
||||
type: EnvelopeType.DOCUMENT,
|
||||
title,
|
||||
@ -100,7 +101,11 @@ export const createDocumentTemporaryRoute = authenticatedProcedure
|
||||
return {
|
||||
document: {
|
||||
...createdEnvelope,
|
||||
documentData: firstDocumentData,
|
||||
envelopeId: createdEnvelope.id,
|
||||
documentData: {
|
||||
...firstDocumentData,
|
||||
envelopeItemId: envelopeItems[0].id,
|
||||
},
|
||||
id: legacyDocumentId,
|
||||
fields: createdEnvelope.fields.map((field) => ({
|
||||
...field,
|
||||
|
||||
@ -1,4 +1,3 @@
|
||||
import { DocumentSigningOrder } from '@prisma/client';
|
||||
import { z } from 'zod';
|
||||
|
||||
import { ZDocumentSchema } from '@documenso/lib/types/document';
|
||||
@ -6,8 +5,8 @@ import {
|
||||
ZDocumentAccessAuthTypesSchema,
|
||||
ZDocumentActionAuthTypesSchema,
|
||||
} from '@documenso/lib/types/document-auth';
|
||||
import { ZDocumentEmailSettingsSchema } from '@documenso/lib/types/document-email';
|
||||
import { ZDocumentFormValuesSchema } from '@documenso/lib/types/document-form-values';
|
||||
import { ZDocumentMetaCreateSchema } from '@documenso/lib/types/document-meta';
|
||||
import {
|
||||
ZFieldHeightSchema,
|
||||
ZFieldPageNumberSchema,
|
||||
@ -21,16 +20,6 @@ import { ZCreateRecipientSchema } from '../recipient-router/schema';
|
||||
import type { TrpcRouteMeta } from '../trpc';
|
||||
import {
|
||||
ZDocumentExternalIdSchema,
|
||||
ZDocumentMetaDateFormatSchema,
|
||||
ZDocumentMetaDistributionMethodSchema,
|
||||
ZDocumentMetaDrawSignatureEnabledSchema,
|
||||
ZDocumentMetaLanguageSchema,
|
||||
ZDocumentMetaMessageSchema,
|
||||
ZDocumentMetaRedirectUrlSchema,
|
||||
ZDocumentMetaSubjectSchema,
|
||||
ZDocumentMetaTimezoneSchema,
|
||||
ZDocumentMetaTypedSignatureEnabledSchema,
|
||||
ZDocumentMetaUploadSignatureEnabledSchema,
|
||||
ZDocumentTitleSchema,
|
||||
ZDocumentVisibilitySchema,
|
||||
} from './schema';
|
||||
@ -80,22 +69,7 @@ export const ZCreateDocumentTemporaryRequestSchema = z.object({
|
||||
)
|
||||
|
||||
.optional(),
|
||||
meta: z
|
||||
.object({
|
||||
subject: ZDocumentMetaSubjectSchema.optional(),
|
||||
message: ZDocumentMetaMessageSchema.optional(),
|
||||
timezone: ZDocumentMetaTimezoneSchema.optional(),
|
||||
dateFormat: ZDocumentMetaDateFormatSchema.optional(),
|
||||
distributionMethod: ZDocumentMetaDistributionMethodSchema.optional(),
|
||||
signingOrder: z.nativeEnum(DocumentSigningOrder).optional(),
|
||||
redirectUrl: ZDocumentMetaRedirectUrlSchema.optional(),
|
||||
language: ZDocumentMetaLanguageSchema.optional(),
|
||||
typedSignatureEnabled: ZDocumentMetaTypedSignatureEnabledSchema.optional(),
|
||||
drawSignatureEnabled: ZDocumentMetaDrawSignatureEnabledSchema.optional(),
|
||||
uploadSignatureEnabled: ZDocumentMetaUploadSignatureEnabledSchema.optional(),
|
||||
emailSettings: ZDocumentEmailSettingsSchema.optional(),
|
||||
})
|
||||
.optional(),
|
||||
meta: ZDocumentMetaCreateSchema.optional(),
|
||||
});
|
||||
|
||||
export const ZCreateDocumentTemporaryResponseSchema = z.object({
|
||||
|
||||
@ -36,6 +36,7 @@ export const createDocumentRoute = authenticatedProcedure
|
||||
const document = await createEnvelope({
|
||||
userId: user.id,
|
||||
teamId,
|
||||
internalVersion: 1,
|
||||
data: {
|
||||
type: EnvelopeType.DOCUMENT,
|
||||
title,
|
||||
|
||||
@ -1,6 +1,8 @@
|
||||
import { z } from 'zod';
|
||||
|
||||
import { ZDocumentMetaTimezoneSchema, ZDocumentTitleSchema } from './schema';
|
||||
import { ZDocumentMetaTimezoneSchema } from '@documenso/lib/types/document-meta';
|
||||
|
||||
import { ZDocumentTitleSchema } from './schema';
|
||||
|
||||
// Currently not in use until we allow passthrough documents on create.
|
||||
// export const createDocumentMeta: TrpcRouteMeta = {
|
||||
|
||||
@ -25,7 +25,10 @@ export const deleteDocumentRoute = authenticatedProcedure
|
||||
const userId = ctx.user.id;
|
||||
|
||||
await deleteDocument({
|
||||
id: documentId,
|
||||
id: {
|
||||
type: 'documentId',
|
||||
id: documentId,
|
||||
},
|
||||
userId,
|
||||
teamId,
|
||||
requestMetadata: ctx.metadata,
|
||||
|
||||
@ -2,8 +2,6 @@ import { z } from 'zod';
|
||||
|
||||
import { ZDocumentLiteSchema } from '@documenso/lib/types/document';
|
||||
import { ZDocumentEmailSettingsSchema } from '@documenso/lib/types/document-email';
|
||||
|
||||
import type { TrpcRouteMeta } from '../trpc';
|
||||
import {
|
||||
ZDocumentMetaDateFormatSchema,
|
||||
ZDocumentMetaDistributionMethodSchema,
|
||||
@ -12,7 +10,9 @@ import {
|
||||
ZDocumentMetaRedirectUrlSchema,
|
||||
ZDocumentMetaSubjectSchema,
|
||||
ZDocumentMetaTimezoneSchema,
|
||||
} from './schema';
|
||||
} from '@documenso/lib/types/document-meta';
|
||||
|
||||
import type { TrpcRouteMeta } from '../trpc';
|
||||
|
||||
export const distributeDocumentMeta: TrpcRouteMeta = {
|
||||
openapi: {
|
||||
|
||||
@ -1,4 +1,4 @@
|
||||
import { duplicateDocument } from '@documenso/lib/server-only/document/duplicate-document-by-id';
|
||||
import { duplicateEnvelope } from '@documenso/lib/server-only/envelope/duplicate-envelope';
|
||||
|
||||
import { authenticatedProcedure } from '../trpc';
|
||||
import {
|
||||
@ -21,7 +21,7 @@ export const duplicateDocumentRoute = authenticatedProcedure
|
||||
},
|
||||
});
|
||||
|
||||
return await duplicateDocument({
|
||||
const duplicatedEnvelope = await duplicateEnvelope({
|
||||
id: {
|
||||
type: 'documentId',
|
||||
id: documentId,
|
||||
@ -29,4 +29,9 @@ export const duplicateDocumentRoute = authenticatedProcedure
|
||||
userId: user.id,
|
||||
teamId,
|
||||
});
|
||||
|
||||
return {
|
||||
id: duplicatedEnvelope.id,
|
||||
documentId: duplicatedEnvelope.legacyId.id,
|
||||
};
|
||||
});
|
||||
|
||||
@ -16,7 +16,8 @@ export const ZDuplicateDocumentRequestSchema = z.object({
|
||||
});
|
||||
|
||||
export const ZDuplicateDocumentResponseSchema = z.object({
|
||||
documentId: z.number(),
|
||||
id: z.string().describe('The envelope ID'),
|
||||
documentId: z.number().describe('The legacy document ID'),
|
||||
});
|
||||
|
||||
export type TDuplicateDocumentRequest = z.infer<typeof ZDuplicateDocumentRequestSchema>;
|
||||
|
||||
@ -34,7 +34,6 @@ export const getDocumentByTokenRoute = authenticatedProcedure
|
||||
},
|
||||
});
|
||||
|
||||
// Todo: Envelopes
|
||||
const firstDocumentData = envelope?.envelopeItems[0].documentData;
|
||||
|
||||
if (!envelope || !firstDocumentData) {
|
||||
|
||||
@ -26,7 +26,10 @@ export const redistributeDocumentRoute = authenticatedProcedure
|
||||
await resendDocument({
|
||||
userId: ctx.user.id,
|
||||
teamId,
|
||||
documentId,
|
||||
id: {
|
||||
type: 'documentId',
|
||||
id: documentId,
|
||||
},
|
||||
recipients,
|
||||
requestMetadata: ctx.metadata,
|
||||
});
|
||||
|
||||
@ -1,10 +1,6 @@
|
||||
import { DocumentDistributionMethod, DocumentVisibility } from '@prisma/client';
|
||||
import { DocumentVisibility } from '@prisma/client';
|
||||
import { z } from 'zod';
|
||||
|
||||
import { VALID_DATE_FORMAT_VALUES } from '@documenso/lib/constants/date-formats';
|
||||
import { SUPPORTED_LANGUAGE_CODES } from '@documenso/lib/constants/i18n';
|
||||
import { isValidRedirectUrl } from '@documenso/lib/utils/is-valid-redirect-url';
|
||||
|
||||
/**
|
||||
* Required for empty responses since we currently can't 201 requests for our openapi setup.
|
||||
*
|
||||
@ -34,58 +30,3 @@ export const ZDocumentExternalIdSchema = z
|
||||
export const ZDocumentVisibilitySchema = z
|
||||
.nativeEnum(DocumentVisibility)
|
||||
.describe('The visibility of the document.');
|
||||
|
||||
export const ZDocumentMetaTimezoneSchema = z
|
||||
.string()
|
||||
.describe(
|
||||
'The timezone to use for date fields and signing the document. Example Etc/UTC, Australia/Melbourne',
|
||||
);
|
||||
// Cooked.
|
||||
// .refine((value) => TIME_ZONES.includes(value), {
|
||||
// message: 'Invalid timezone. Please provide a valid timezone',
|
||||
// });
|
||||
|
||||
export type TDocumentMetaTimezone = z.infer<typeof ZDocumentMetaTimezoneSchema>;
|
||||
|
||||
export const ZDocumentMetaDateFormatSchema = z
|
||||
.enum(VALID_DATE_FORMAT_VALUES)
|
||||
.describe('The date format to use for date fields and signing the document.');
|
||||
|
||||
export type TDocumentMetaDateFormat = z.infer<typeof ZDocumentMetaDateFormatSchema>;
|
||||
|
||||
export const ZDocumentMetaRedirectUrlSchema = z
|
||||
.string()
|
||||
.describe('The URL to which the recipient should be redirected after signing the document.')
|
||||
.refine((value) => value === undefined || value === '' || isValidRedirectUrl(value), {
|
||||
message: 'Please enter a valid URL, make sure you include http:// or https:// part of the url.',
|
||||
});
|
||||
|
||||
export const ZDocumentMetaLanguageSchema = z
|
||||
.enum(SUPPORTED_LANGUAGE_CODES)
|
||||
.describe('The language to use for email communications with recipients.');
|
||||
|
||||
export const ZDocumentMetaSubjectSchema = z
|
||||
.string()
|
||||
.max(254)
|
||||
.describe('The subject of the email that will be sent to the recipients.');
|
||||
|
||||
export const ZDocumentMetaMessageSchema = z
|
||||
.string()
|
||||
.max(5000)
|
||||
.describe('The message of the email that will be sent to the recipients.');
|
||||
|
||||
export const ZDocumentMetaDistributionMethodSchema = z
|
||||
.nativeEnum(DocumentDistributionMethod)
|
||||
.describe('The distribution method to use when sending the document to the recipients.');
|
||||
|
||||
export const ZDocumentMetaTypedSignatureEnabledSchema = z
|
||||
.boolean()
|
||||
.describe('Whether to allow recipients to sign using a typed signature.');
|
||||
|
||||
export const ZDocumentMetaDrawSignatureEnabledSchema = z
|
||||
.boolean()
|
||||
.describe('Whether to allow recipients to sign using a draw signature.');
|
||||
|
||||
export const ZDocumentMetaUploadSignatureEnabledSchema = z
|
||||
.boolean()
|
||||
.describe('Whether to allow recipients to sign using an uploaded signature.');
|
||||
|
||||
@ -1,5 +1,4 @@
|
||||
import { updateDocumentMeta } from '@documenso/lib/server-only/document-meta/upsert-document-meta';
|
||||
import { updateDocument } from '@documenso/lib/server-only/document/update-document';
|
||||
import { updateEnvelope } from '@documenso/lib/server-only/envelope/update-envelope';
|
||||
import { mapSecondaryIdToDocumentId } from '@documenso/lib/utils/envelope';
|
||||
|
||||
import { authenticatedProcedure } from '../trpc';
|
||||
@ -28,44 +27,22 @@ export const updateDocumentRoute = authenticatedProcedure
|
||||
|
||||
const userId = ctx.user.id;
|
||||
|
||||
if (Object.values(meta).length > 0) {
|
||||
await updateDocumentMeta({
|
||||
userId: ctx.user.id,
|
||||
teamId,
|
||||
id: {
|
||||
type: 'documentId',
|
||||
id: documentId,
|
||||
},
|
||||
subject: meta.subject,
|
||||
message: meta.message,
|
||||
timezone: meta.timezone,
|
||||
dateFormat: meta.dateFormat,
|
||||
language: meta.language,
|
||||
typedSignatureEnabled: meta.typedSignatureEnabled,
|
||||
uploadSignatureEnabled: meta.uploadSignatureEnabled,
|
||||
drawSignatureEnabled: meta.drawSignatureEnabled,
|
||||
redirectUrl: meta.redirectUrl,
|
||||
distributionMethod: meta.distributionMethod,
|
||||
signingOrder: meta.signingOrder,
|
||||
allowDictateNextSigner: meta.allowDictateNextSigner,
|
||||
emailId: meta.emailId,
|
||||
emailReplyTo: meta.emailReplyTo,
|
||||
emailSettings: meta.emailSettings,
|
||||
requestMetadata: ctx.metadata,
|
||||
});
|
||||
}
|
||||
|
||||
const envelope = await updateDocument({
|
||||
const envelope = await updateEnvelope({
|
||||
userId,
|
||||
teamId,
|
||||
documentId,
|
||||
id: {
|
||||
type: 'documentId',
|
||||
id: documentId,
|
||||
},
|
||||
data,
|
||||
meta,
|
||||
requestMetadata: ctx.metadata,
|
||||
});
|
||||
|
||||
const mappedDocument = {
|
||||
...envelope,
|
||||
id: mapSecondaryIdToDocumentId(envelope.secondaryId),
|
||||
envelopeId: envelope.id,
|
||||
};
|
||||
|
||||
return mappedDocument;
|
||||
|
||||
@ -1,4 +1,3 @@
|
||||
import { DocumentSigningOrder } from '@prisma/client';
|
||||
// import type { OpenApiMeta } from 'trpc-to-openapi';
|
||||
import { z } from 'zod';
|
||||
|
||||
@ -7,21 +6,11 @@ import {
|
||||
ZDocumentAccessAuthTypesSchema,
|
||||
ZDocumentActionAuthTypesSchema,
|
||||
} from '@documenso/lib/types/document-auth';
|
||||
import { ZDocumentEmailSettingsSchema } from '@documenso/lib/types/document-email';
|
||||
import { ZDocumentMetaUpdateSchema } from '@documenso/lib/types/document-meta';
|
||||
|
||||
import type { TrpcRouteMeta } from '../trpc';
|
||||
import {
|
||||
ZDocumentExternalIdSchema,
|
||||
ZDocumentMetaDateFormatSchema,
|
||||
ZDocumentMetaDistributionMethodSchema,
|
||||
ZDocumentMetaDrawSignatureEnabledSchema,
|
||||
ZDocumentMetaLanguageSchema,
|
||||
ZDocumentMetaMessageSchema,
|
||||
ZDocumentMetaRedirectUrlSchema,
|
||||
ZDocumentMetaSubjectSchema,
|
||||
ZDocumentMetaTimezoneSchema,
|
||||
ZDocumentMetaTypedSignatureEnabledSchema,
|
||||
ZDocumentMetaUploadSignatureEnabledSchema,
|
||||
ZDocumentTitleSchema,
|
||||
ZDocumentVisibilitySchema,
|
||||
} from './schema';
|
||||
@ -48,25 +37,7 @@ export const ZUpdateDocumentRequestSchema = z.object({
|
||||
folderId: z.string().nullish(),
|
||||
})
|
||||
.optional(),
|
||||
meta: z
|
||||
.object({
|
||||
subject: ZDocumentMetaSubjectSchema.optional(),
|
||||
message: ZDocumentMetaMessageSchema.optional(),
|
||||
timezone: ZDocumentMetaTimezoneSchema.optional(),
|
||||
dateFormat: ZDocumentMetaDateFormatSchema.optional(),
|
||||
distributionMethod: ZDocumentMetaDistributionMethodSchema.optional(),
|
||||
signingOrder: z.nativeEnum(DocumentSigningOrder).optional(),
|
||||
allowDictateNextSigner: z.boolean().optional(),
|
||||
redirectUrl: ZDocumentMetaRedirectUrlSchema.optional(),
|
||||
language: ZDocumentMetaLanguageSchema.optional(),
|
||||
typedSignatureEnabled: ZDocumentMetaTypedSignatureEnabledSchema.optional(),
|
||||
uploadSignatureEnabled: ZDocumentMetaUploadSignatureEnabledSchema.optional(),
|
||||
drawSignatureEnabled: ZDocumentMetaDrawSignatureEnabledSchema.optional(),
|
||||
emailId: z.string().nullish(),
|
||||
emailReplyTo: z.string().email().nullish(),
|
||||
emailSettings: ZDocumentEmailSettingsSchema.optional(),
|
||||
})
|
||||
.optional(),
|
||||
meta: ZDocumentMetaUpdateSchema.optional(),
|
||||
});
|
||||
|
||||
export const ZUpdateDocumentResponseSchema = ZDocumentLiteSchema;
|
||||
|
||||
Reference in New Issue
Block a user