mirror of
https://github.com/documenso/documenso.git
synced 2025-11-10 04:22:32 +10:00
Compare commits
2 Commits
4a0425b120
...
bbf1dd3c6b
| Author | SHA1 | Date | |
|---|---|---|---|
| bbf1dd3c6b | |||
| c10c95ca00 |
@ -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.pdf');
|
||||
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,
|
||||
|
||||
@ -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;
|
||||
|
||||
|
||||
@ -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, {
|
||||
|
||||
@ -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),
|
||||
};
|
||||
});
|
||||
|
||||
@ -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<typeof ZCreateDocumentPayloadSchema>;
|
||||
|
||||
@ -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,
|
||||
});
|
||||
|
||||
|
||||
@ -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()
|
||||
|
||||
@ -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({
|
||||
|
||||
@ -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),
|
||||
};
|
||||
}),
|
||||
|
||||
|
||||
@ -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({
|
||||
|
||||
Reference in New Issue
Block a user