From c10c95ca006c49cbc9a8b8dab00fce0f4315f9d8 Mon Sep 17 00:00:00 2001 From: David Nguyen Date: Mon, 3 Nov 2025 20:17:52 +1100 Subject: [PATCH] fix: add tests --- .../e2e/api/v2/envelopes-api.spec.ts | 390 +++++++++++++++--- .../v2/test-unauthorized-api-access.spec.ts | 82 ++++ .../server-only/envelope/create-envelope.ts | 5 +- .../server/document-router/create-document.ts | 6 +- .../document-router/create-document.types.ts | 3 +- .../server/envelope-router/create-envelope.ts | 20 +- .../envelope-router/create-envelope.types.ts | 16 +- .../trpc/server/recipient-router/schema.ts | 8 +- .../trpc/server/template-router/router.ts | 3 +- .../trpc/server/template-router/schema.ts | 2 +- 10 files changed, 456 insertions(+), 79 deletions(-) diff --git a/packages/app-tests/e2e/api/v2/envelopes-api.spec.ts b/packages/app-tests/e2e/api/v2/envelopes-api.spec.ts index 4de9f402d..db71dd30b 100644 --- a/packages/app-tests/e2e/api/v2/envelopes-api.spec.ts +++ b/packages/app-tests/e2e/api/v2/envelopes-api.spec.ts @@ -2,20 +2,27 @@ import { expect, test } from '@playwright/test'; import type { Team, User } from '@prisma/client'; import fs from 'node:fs'; import path from 'node:path'; +import { pick } from 'remeda'; import { NEXT_PUBLIC_WEBAPP_URL } from '@documenso/lib/constants/app'; -import { incrementDocumentId } from '@documenso/lib/server-only/envelope/increment-id'; import { createApiToken } from '@documenso/lib/server-only/public-api/create-api-token'; -import { prefixedId } from '@documenso/lib/universal/id'; import { prisma } from '@documenso/prisma'; import { - DocumentSource, + DocumentDistributionMethod, + DocumentSigningOrder, + DocumentStatus, DocumentVisibility, EnvelopeType, + FieldType, + FolderType, RecipientRole, } from '@documenso/prisma/client'; import { seedUser } from '@documenso/prisma/seed/users'; import type { TCreateEnvelopeItemsRequest } from '@documenso/trpc/server/envelope-router/create-envelope-items.types'; +import type { + TCreateEnvelopePayload, + TCreateEnvelopeResponse, +} from '@documenso/trpc/server/envelope-router/create-envelope.types'; import type { TCreateEnvelopeRecipientsRequest } from '@documenso/trpc/server/envelope-router/envelope-recipients/create-envelope-recipients.types'; import type { TGetEnvelopeResponse } from '@documenso/trpc/server/envelope-router/get-envelope.types'; import type { TUpdateEnvelopeRequest } from '@documenso/trpc/server/envelope-router/update-envelope.types'; @@ -51,64 +58,354 @@ test.describe('API V2 Envelopes', () => { })); }); + test.describe('Envelope create endpoint', () => { + test('should fail on invalid form', async ({ request }) => { + const payload = { + type: 'Invalid Type', + title: 'Test Envelope', + }; + + const formData = new FormData(); + formData.append('payload', JSON.stringify(payload)); + + const res = await request.post(`${WEBAPP_BASE_URL}/api/v2-beta/envelope/create`, { + headers: { Authorization: `Bearer ${tokenB}` }, + multipart: formData, + }); + + expect(res.ok()).toBeFalsy(); + expect(res.status()).toBe(400); + }); + + test('should create envelope with single file', async ({ request }) => { + const payload = { + type: EnvelopeType.TEMPLATE, + title: 'Test Envelope', + } satisfies TCreateEnvelopePayload; + + const formData = new FormData(); + + formData.append('payload', JSON.stringify(payload)); + + const files = [ + { + name: 'field-font-alignment.pdf', + data: fs.readFileSync( + path.join(__dirname, '../../../../../assets/field-font-alignment.pdf'), + ), + }, + ]; + + for (const file of files) { + formData.append('files', new File([file.data], file.name, { type: 'application/pdf' })); + } + + const res = await request.post(`${WEBAPP_BASE_URL}/api/v2-beta/envelope/create`, { + headers: { Authorization: `Bearer ${tokenB}` }, + multipart: formData, + }); + + expect(res.ok()).toBeTruthy(); + expect(res.status()).toBe(200); + + const response = (await res.json()) as TCreateEnvelopeResponse; + + const envelope = await prisma.envelope.findUnique({ + where: { + id: response.id, + }, + include: { + envelopeItems: true, + }, + }); + + expect(envelope).toBeDefined(); + expect(envelope?.title).toBe('Test Envelope'); + expect(envelope?.type).toBe(EnvelopeType.TEMPLATE); + expect(envelope?.status).toBe(DocumentStatus.DRAFT); + expect(envelope?.envelopeItems.length).toBe(1); + expect(envelope?.envelopeItems[0].title).toBe('field-font-alignment'); + expect(envelope?.envelopeItems[0].documentDataId).toBeDefined(); + }); + + test('should create envelope with multiple file', async ({ request }) => { + const folder = await prisma.folder.create({ + data: { + name: 'Test Folder', + teamId: teamA.id, + userId: userA.id, + type: FolderType.DOCUMENT, + }, + }); + + const payload = { + title: 'Envelope Title', + type: EnvelopeType.DOCUMENT, + externalId: 'externalId', + visibility: DocumentVisibility.MANAGER_AND_ABOVE, + globalAccessAuth: ['ACCOUNT'], + formValues: { + hello: 'world', + }, + folderId: folder.id, + recipients: [ + { + email: userA.email, + name: 'Name', + role: RecipientRole.SIGNER, + accessAuth: ['TWO_FACTOR_AUTH'], + signingOrder: 1, + fields: [ + { + type: FieldType.SIGNATURE, + identifier: 'field-font-alignment.pdf', + page: 1, + positionX: 0, + positionY: 0, + width: 0, + height: 0, + }, + { + type: FieldType.SIGNATURE, + identifier: 0, + page: 1, + positionX: 0, + positionY: 0, + width: 0, + height: 0, + }, + ], + }, + ], + meta: { + subject: 'Subject', + message: 'Message', + timezone: 'Europe/Berlin', + dateFormat: 'dd.MM.yyyy', + distributionMethod: DocumentDistributionMethod.NONE, + signingOrder: DocumentSigningOrder.SEQUENTIAL, + allowDictateNextSigner: true, + redirectUrl: 'https://documenso.com', + language: 'de', + typedSignatureEnabled: true, + uploadSignatureEnabled: false, + drawSignatureEnabled: false, + emailReplyTo: userA.email, + emailSettings: { + recipientSigningRequest: false, + recipientRemoved: false, + recipientSigned: false, + documentPending: false, + documentCompleted: false, + documentDeleted: false, + ownerDocumentCompleted: true, + }, + }, + attachments: [ + { + label: 'Test Attachment', + data: 'https://documenso.com', + type: 'link', + }, + ], + } satisfies TCreateEnvelopePayload; + + const formData = new FormData(); + + formData.append('payload', JSON.stringify(payload)); + + const files = [ + { + name: 'field-meta.pdf', + data: fs.readFileSync(path.join(__dirname, '../../../../../assets/field-meta.pdf')), + }, + { + name: 'field-font-alignment.pdf', + data: fs.readFileSync( + path.join(__dirname, '../../../../../assets/field-font-alignment.pdf'), + ), + }, + ]; + + for (const file of files) { + formData.append('files', new File([file.data], file.name, { type: 'application/pdf' })); + } + + // Should error since folder is not owned by the user. + const invalidRes = await request.post(`${WEBAPP_BASE_URL}/api/v2-beta/envelope/create`, { + headers: { Authorization: `Bearer ${tokenB}` }, + multipart: formData, + }); + + expect(invalidRes.ok()).toBeFalsy(); + + const res = await request.post(`${WEBAPP_BASE_URL}/api/v2-beta/envelope/create`, { + headers: { Authorization: `Bearer ${tokenA}` }, + multipart: formData, + }); + + expect(res.ok()).toBeTruthy(); + expect(res.status()).toBe(200); + + const response = (await res.json()) as TCreateEnvelopeResponse; + + const envelope = await prisma.envelope.findUniqueOrThrow({ + where: { + id: response.id, + }, + include: { + documentMeta: true, + envelopeItems: true, + recipients: true, + fields: true, + envelopeAttachments: true, + }, + }); + + console.log(userB.email); + + expect(envelope.envelopeItems.length).toBe(2); + expect(envelope.envelopeItems[0].title).toBe('field-meta.pdf'); + expect(envelope.envelopeItems[1].title).toBe('field-font-alignment.pdf'); + + expect(envelope.title).toBe(payload.title); + expect(envelope.type).toBe(payload.type); + expect(envelope.externalId).toBe(payload.externalId); + expect(envelope.visibility).toBe(payload.visibility); + expect(envelope.authOptions).toEqual({ + globalAccessAuth: payload.globalAccessAuth, + globalActionAuth: [], + }); + expect(envelope.formValues).toEqual(payload.formValues); + expect(envelope.folderId).toBe(payload.folderId); + + expect(envelope.documentMeta.subject).toBe(payload.meta.subject); + expect(envelope.documentMeta.message).toBe(payload.meta.message); + expect(envelope.documentMeta.timezone).toBe(payload.meta.timezone); + expect(envelope.documentMeta.dateFormat).toBe(payload.meta.dateFormat); + expect(envelope.documentMeta.distributionMethod).toBe(payload.meta.distributionMethod); + expect(envelope.documentMeta.signingOrder).toBe(payload.meta.signingOrder); + expect(envelope.documentMeta.allowDictateNextSigner).toBe( + payload.meta.allowDictateNextSigner, + ); + expect(envelope.documentMeta.redirectUrl).toBe(payload.meta.redirectUrl); + expect(envelope.documentMeta.language).toBe(payload.meta.language); + expect(envelope.documentMeta.typedSignatureEnabled).toBe(payload.meta.typedSignatureEnabled); + expect(envelope.documentMeta.uploadSignatureEnabled).toBe( + payload.meta.uploadSignatureEnabled, + ); + expect(envelope.documentMeta.drawSignatureEnabled).toBe(payload.meta.drawSignatureEnabled); + expect(envelope.documentMeta.emailReplyTo).toBe(payload.meta.emailReplyTo); + expect(envelope.documentMeta.emailSettings).toEqual(payload.meta.emailSettings); + + expect([ + { + label: envelope.envelopeAttachments[0].label, + data: envelope.envelopeAttachments[0].data, + type: envelope.envelopeAttachments[0].type, + }, + ]).toEqual(payload.attachments); + + const field = envelope.fields[0]; + const recipient = envelope.recipients[0]; + + expect({ + email: recipient.email, + name: recipient.name, + role: recipient.role, + signingOrder: recipient.signingOrder, + accessAuth: recipient.authOptions?.accessAuth, + }).toEqual( + pick(payload.recipients[0], ['email', 'name', 'role', 'signingOrder', 'accessAuth']), + ); + + expect({ + type: field.type, + page: field.page, + positionX: field.positionX.toNumber(), + positionY: field.positionY.toNumber(), + width: field.width.toNumber(), + height: field.height.toNumber(), + }).toEqual( + pick(payload.recipients[0].fields[0], [ + 'type', + 'page', + 'positionX', + 'positionY', + 'width', + 'height', + ]), + ); + + // Expect string based ID to work. + expect(field.envelopeItemId).toBe( + envelope.envelopeItems.find((item) => item.title === 'field-font-alignment.pdf')?.id, + ); + + // Expect index based ID to work. + expect(envelope.fields[1].envelopeItemId).toBe( + envelope.envelopeItems.find((item) => item.title === 'field-meta.pdf')?.id, + ); + }); + }); + /** * Creates envelopes with the two field test PDFs. */ test('Envelope full test', async ({ request }) => { // Step 1: Create initial envelope with Prisma (with first envelope item) - const alignmentPdf = fs - .readFileSync(path.join(__dirname, '../../../../../assets/field-font-alignment.pdf')) - .toString('base64'); + const alignmentPdf = fs.readFileSync( + path.join(__dirname, '../../../../../assets/field-font-alignment.pdf'), + ); - const fieldMetaPdf = fs - .readFileSync(path.join(__dirname, '../../../../../assets/field-meta.pdf')) - .toString('base64'); + const fieldMetaPdf = fs.readFileSync( + path.join(__dirname, '../../../../../assets/field-meta.pdf'), + ); - const alignmentDocumentData = await prisma.documentData.create({ - data: { - type: 'BYTES_64', - data: alignmentPdf, - initialData: alignmentPdf, - }, - }); + const formData = new FormData(); - const documentId = await incrementDocumentId(); - const documentMeta = await prisma.documentMeta.create({ - data: {}, - }); - - const createdEnvelope = await prisma.envelope.create({ - data: { - id: prefixedId('envelope'), - secondaryId: documentId.formattedDocumentId, - internalVersion: 2, + formData.append( + 'payload', + JSON.stringify({ type: EnvelopeType.DOCUMENT, - documentMetaId: documentMeta.id, - source: DocumentSource.DOCUMENT, - title: `Envelope Full Field Test`, - status: 'DRAFT', - userId: userA.id, - teamId: teamA.id, - envelopeItems: { - create: { - id: prefixedId('envelope_item'), - title: `Alignment Test`, - documentDataId: alignmentDocumentData.id, - order: 1, - }, - }, - }, - include: { - envelopeItems: true, - }, + title: 'Envelope Full Field Test', + } satisfies TCreateEnvelopePayload), + ); + + // Only add one file for now. + formData.append( + 'files', + new File([alignmentPdf], 'field-font-alignment.pdf', { type: 'application/pdf' }), + ); + + const res = await request.post(`${WEBAPP_BASE_URL}/api/v2-beta/envelope/create`, { + headers: { Authorization: `Bearer ${tokenA}` }, + multipart: formData, }); + const response: TCreateEnvelopeResponse = await res.json(); + + const createdEnvelope: TGetEnvelopeResponse = await request + .get(`${baseUrl}/envelope/${response.id}`, { + headers: { Authorization: `Bearer ${tokenA}` }, + }) + .then(async (res) => await res.json()); + + // Might as well testing access control here as well. + const unauthRequest = await request.get(`${baseUrl}/envelope/${response.id}`, { + headers: { Authorization: `Bearer ${tokenB}` }, + }); + + expect(unauthRequest.ok()).toBeFalsy(); + expect(unauthRequest.status()).toBe(404); + // Step 2: Create second envelope item via API + // Todo: Envelopes - Use API Route const fieldMetaDocumentData = await prisma.documentData.create({ data: { type: 'BYTES_64', - data: fieldMetaPdf, - initialData: fieldMetaPdf, + data: fieldMetaPdf.toString('base64'), + initialData: fieldMetaPdf.toString('base64'), }, }); @@ -133,7 +430,6 @@ test.describe('API V2 Envelopes', () => { // Step 3: Update envelope via API const updateEnvelopeRequest: TUpdateEnvelopeRequest = { envelopeId: createdEnvelope.id, - envelopeType: EnvelopeType.DOCUMENT, data: { title: 'Envelope Full Field Test', visibility: DocumentVisibility.MANAGER_AND_ABOVE, diff --git a/packages/app-tests/e2e/api/v2/test-unauthorized-api-access.spec.ts b/packages/app-tests/e2e/api/v2/test-unauthorized-api-access.spec.ts index 86c95d1bc..f648ed1de 100644 --- a/packages/app-tests/e2e/api/v2/test-unauthorized-api-access.spec.ts +++ b/packages/app-tests/e2e/api/v2/test-unauthorized-api-access.spec.ts @@ -1,5 +1,7 @@ import { expect, test } from '@playwright/test'; import type { Team, User } from '@prisma/client'; +import fs from 'node:fs'; +import path from 'node:path'; import { NEXT_PUBLIC_WEBAPP_URL } from '@documenso/lib/constants/app'; import { createApiToken } from '@documenso/lib/server-only/public-api/create-api-token'; @@ -2858,6 +2860,86 @@ test.describe('Document API V2', () => { }); }); + test.describe('Document create endpoint', () => { + test('should allow authorized access to document create endpoint', async ({ request }) => { + const payload = { + title: 'Test Document', + }; + + const formData = new FormData(); + formData.append('payload', JSON.stringify(payload)); + + const pdfPath = path.join(__dirname, '../../../../../assets/example.pdf'); + const pdfData = fs.existsSync(pdfPath) ? fs.readFileSync(pdfPath) : Buffer.from('%PDF-1.4\n'); + + formData.append('file', new File([pdfData], 'test.pdf', { type: 'application/pdf' })); + + const res = await request.post(`${WEBAPP_BASE_URL}/api/v2-beta/document/create`, { + headers: { Authorization: `Bearer ${tokenA}` }, + multipart: formData, + }); + + expect(res.ok()).toBeTruthy(); + expect(res.status()).toBe(200); + + const data = await res.json(); + expect(data.envelopeId).toBeDefined(); + expect(data.id).toBeDefined(); + + const envelope = await prisma.envelope.findFirstOrThrow({ + where: { + id: data.envelopeId, + }, + include: { + envelopeItems: true, + }, + }); + + expect(envelope?.title).toBe(payload.title); + expect(envelope.envelopeItems.length).toBe(1); + }); + }); + + test.describe('Template create endpoint', () => { + test('should allow authorized access to template create endpoint', async ({ request }) => { + const payload = { + title: 'Test Template', + }; + + const formData = new FormData(); + formData.append('payload', JSON.stringify(payload)); + + const pdfPath = path.join(__dirname, '../../../../../assets/example.pdf'); + const pdfData = fs.existsSync(pdfPath) ? fs.readFileSync(pdfPath) : Buffer.from('%PDF-1.4\n'); + + formData.append('file', new File([pdfData], 'test.pdf', { type: 'application/pdf' })); + + const res = await request.post(`${WEBAPP_BASE_URL}/api/v2-beta/template/create`, { + headers: { Authorization: `Bearer ${tokenA}` }, + multipart: formData, + }); + + expect(res.ok()).toBeTruthy(); + expect(res.status()).toBe(200); + + const data = await res.json(); + expect(data.envelopeId).toBeDefined(); + expect(data.id).toBeDefined(); + + const envelope = await prisma.envelope.findFirstOrThrow({ + where: { + id: data.envelopeId, + }, + include: { + envelopeItems: true, + }, + }); + + expect(envelope.title).toBe(payload.title); + expect(envelope.envelopeItems.length).toBe(1); + }); + }); + test.describe('Envelope API V2', () => { let userA: User, teamA: Team, userB: User, teamB: Team, tokenA: string, tokenB: string; diff --git a/packages/lib/server-only/envelope/create-envelope.ts b/packages/lib/server-only/envelope/create-envelope.ts index 6e24ee35f..210346b4d 100644 --- a/packages/lib/server-only/envelope/create-envelope.ts +++ b/packages/lib/server-only/envelope/create-envelope.ts @@ -70,7 +70,6 @@ export type CreateEnvelopeOptions = { envelopeItems: { title?: string; documentDataId: string; order?: number }[]; formValues?: TDocumentFormValues; - timezone?: string; userTimezone?: string; templateType?: TemplateType; @@ -107,7 +106,6 @@ export const createEnvelope = async ({ title, externalId, formValues, - timezone, userTimezone, folderId, templateType, @@ -166,6 +164,7 @@ export const createEnvelope = async ({ let envelopeItems: { title?: string; documentDataId: string; order?: number }[] = data.envelopeItems; + // Todo: Envelopes - Remove if (normalizePdf) { envelopeItems = await Promise.all( data.envelopeItems.map(async (item) => { @@ -243,7 +242,7 @@ export const createEnvelope = async ({ // userTimezone is last because it's always passed in regardless of the organisation/team settings // for uploads from the frontend - const timezoneToUse = timezone || settings.documentTimezone || userTimezone; + const timezoneToUse = meta?.timezone || settings.documentTimezone || userTimezone; const documentMeta = await prisma.documentMeta.create({ data: extractDerivedDocumentMeta(settings, { diff --git a/packages/trpc/server/document-router/create-document.ts b/packages/trpc/server/document-router/create-document.ts index 10d771c11..a5f915ffb 100644 --- a/packages/trpc/server/document-router/create-document.ts +++ b/packages/trpc/server/document-router/create-document.ts @@ -10,10 +10,12 @@ import { authenticatedProcedure } from '../trpc'; import { ZCreateDocumentRequestSchema, ZCreateDocumentResponseSchema, + createDocumentMeta, } from './create-document.types'; export const createDocumentRoute = authenticatedProcedure - .input(ZCreateDocumentRequestSchema) // Note: Before releasing this to public, update the response schema to be correct. + .meta(createDocumentMeta) + .input(ZCreateDocumentRequestSchema) .output(ZCreateDocumentResponseSchema) .mutation(async ({ input, ctx }) => { const { user, teamId } = ctx; @@ -62,6 +64,6 @@ export const createDocumentRoute = authenticatedProcedure return { envelopeId: document.id, - legacyDocumentId: mapSecondaryIdToDocumentId(document.secondaryId), + id: mapSecondaryIdToDocumentId(document.secondaryId), }; }); diff --git a/packages/trpc/server/document-router/create-document.types.ts b/packages/trpc/server/document-router/create-document.types.ts index 51587498c..07ccc8302 100644 --- a/packages/trpc/server/document-router/create-document.types.ts +++ b/packages/trpc/server/document-router/create-document.types.ts @@ -8,7 +8,6 @@ import { zodFormData } from '../../utils/zod-form-data'; import type { TrpcRouteMeta } from '../trpc'; import { ZDocumentTitleSchema } from './schema'; -// Currently not in use until we allow passthrough documents on create. export const createDocumentMeta: TrpcRouteMeta = { openapi: { method: 'POST', @@ -42,7 +41,7 @@ export const ZCreateDocumentRequestSchema = zodFormData({ export const ZCreateDocumentResponseSchema = z.object({ envelopeId: z.string(), - legacyDocumentId: z.number(), + id: z.number(), }); export type TCreateDocumentPayloadSchema = z.infer; diff --git a/packages/trpc/server/envelope-router/create-envelope.ts b/packages/trpc/server/envelope-router/create-envelope.ts index 0c49b8c4d..a4b0dd9c9 100644 --- a/packages/trpc/server/envelope-router/create-envelope.ts +++ b/packages/trpc/server/envelope-router/create-envelope.ts @@ -10,15 +10,14 @@ import { } from './create-envelope.types'; export const createEnvelopeRoute = authenticatedProcedure - // Todo: Envelopes - Pending direct uploads - // .meta({ - // openapi: { - // method: 'POST', - // path: '/envelope/create', - // summary: 'Create envelope', - // tags: ['Envelope'], - // }, - // }) + .meta({ + openapi: { + method: 'POST', + path: '/envelope/create', + summary: 'Create envelope', + tags: ['Envelope'], + }, + }) .input(ZCreateEnvelopeRequestSchema) .output(ZCreateEnvelopeResponseSchema) .mutation(async ({ input, ctx }) => { @@ -33,6 +32,7 @@ export const createEnvelopeRoute = authenticatedProcedure visibility, globalAccessAuth, globalActionAuth, + formValues, recipients, folderId, meta, @@ -121,6 +121,7 @@ export const createEnvelopeRoute = authenticatedProcedure type, title, externalId, + formValues, visibility, globalAccessAuth, globalActionAuth, @@ -130,7 +131,6 @@ export const createEnvelopeRoute = authenticatedProcedure }, attachments, meta, - normalizePdf: true, requestMetadata: ctx.metadata, }); diff --git a/packages/trpc/server/envelope-router/create-envelope.types.ts b/packages/trpc/server/envelope-router/create-envelope.types.ts index 18207391f..7467d9920 100644 --- a/packages/trpc/server/envelope-router/create-envelope.types.ts +++ b/packages/trpc/server/envelope-router/create-envelope.types.ts @@ -10,11 +10,11 @@ import { ZDocumentFormValuesSchema } from '@documenso/lib/types/document-form-va import { ZDocumentMetaCreateSchema } from '@documenso/lib/types/document-meta'; import { ZEnvelopeAttachmentTypeSchema } from '@documenso/lib/types/envelope-attachment'; import { - ZFieldHeightSchema, + ZClampedFieldHeightSchema, + ZClampedFieldPositionXSchema, + ZClampedFieldPositionYSchema, + ZClampedFieldWidthSchema, ZFieldPageNumberSchema, - ZFieldPageXSchema, - ZFieldPageYSchema, - ZFieldWidthSchema, } from '@documenso/lib/types/field'; import { ZFieldAndMetaSchema } from '@documenso/lib/types/field-meta'; @@ -65,10 +65,10 @@ export const ZCreateEnvelopePayloadSchema = z.object({ ) .optional(), page: ZFieldPageNumberSchema, - positionX: ZFieldPageXSchema, - positionY: ZFieldPageYSchema, - width: ZFieldWidthSchema, - height: ZFieldHeightSchema, + positionX: ZClampedFieldPositionXSchema, + positionY: ZClampedFieldPositionYSchema, + width: ZClampedFieldWidthSchema, + height: ZClampedFieldHeightSchema, }), ) .array() diff --git a/packages/trpc/server/recipient-router/schema.ts b/packages/trpc/server/recipient-router/schema.ts index dafebd196..58a2a1289 100644 --- a/packages/trpc/server/recipient-router/schema.ts +++ b/packages/trpc/server/recipient-router/schema.ts @@ -28,8 +28,8 @@ export const ZCreateRecipientSchema = z.object({ name: z.string().max(255), role: z.nativeEnum(RecipientRole), signingOrder: z.number().optional(), - accessAuth: z.array(ZRecipientAccessAuthTypesSchema).optional().default([]), - actionAuth: z.array(ZRecipientActionAuthTypesSchema).optional().default([]), + accessAuth: z.array(ZRecipientAccessAuthTypesSchema).default([]).optional(), + actionAuth: z.array(ZRecipientActionAuthTypesSchema).default([]).optional(), }); export const ZUpdateRecipientSchema = z.object({ @@ -38,8 +38,8 @@ export const ZUpdateRecipientSchema = z.object({ name: z.string().max(255).optional(), role: z.nativeEnum(RecipientRole).optional(), signingOrder: z.number().optional(), - accessAuth: z.array(ZRecipientAccessAuthTypesSchema).optional().default([]), - actionAuth: z.array(ZRecipientActionAuthTypesSchema).optional().default([]), + accessAuth: z.array(ZRecipientAccessAuthTypesSchema).default([]).optional(), + actionAuth: z.array(ZRecipientActionAuthTypesSchema).default([]).optional(), }); export const ZCreateDocumentRecipientRequestSchema = z.object({ diff --git a/packages/trpc/server/template-router/router.ts b/packages/trpc/server/template-router/router.ts index 81d050e14..4c1e62d15 100644 --- a/packages/trpc/server/template-router/router.ts +++ b/packages/trpc/server/template-router/router.ts @@ -161,7 +161,6 @@ export const templateRouter = router({ */ createTemplate: authenticatedProcedure .meta({ - // Note before releasing this to public, update the response schema to be correct. openapi: { method: 'POST', path: '/template/create', @@ -207,7 +206,7 @@ export const templateRouter = router({ return { envelopeId: envelope.id, - legacyTemplateId: mapSecondaryIdToTemplateId(envelope.secondaryId), + id: mapSecondaryIdToTemplateId(envelope.secondaryId), }; }), diff --git a/packages/trpc/server/template-router/schema.ts b/packages/trpc/server/template-router/schema.ts index 4f0214ea0..60b56ff3d 100644 --- a/packages/trpc/server/template-router/schema.ts +++ b/packages/trpc/server/template-router/schema.ts @@ -231,7 +231,7 @@ export const ZCreateTemplateV2ResponseSchema = z.object({ export const ZCreateTemplateResponseSchema = z.object({ envelopeId: z.string(), - legacyTemplateId: z.number(), + id: z.number(), }); export const ZUpdateTemplateRequestSchema = z.object({