diff --git a/apps/web/src/components/(dashboard)/settings/layout/desktop-nav.tsx b/apps/web/src/components/(dashboard)/settings/layout/desktop-nav.tsx
index 214c5af99..848ff17cc 100644
--- a/apps/web/src/components/(dashboard)/settings/layout/desktop-nav.tsx
+++ b/apps/web/src/components/(dashboard)/settings/layout/desktop-nav.tsx
@@ -57,7 +57,7 @@ export const DesktopNav = ({ className, ...props }: DesktopNavProps) => {
)}
>
- API Token
+ API Tokens
diff --git a/apps/web/src/components/(dashboard)/settings/layout/mobile-nav.tsx b/apps/web/src/components/(dashboard)/settings/layout/mobile-nav.tsx
index ce61ba97d..7482c2f10 100644
--- a/apps/web/src/components/(dashboard)/settings/layout/mobile-nav.tsx
+++ b/apps/web/src/components/(dashboard)/settings/layout/mobile-nav.tsx
@@ -60,7 +60,7 @@ export const MobileNav = ({ className, ...props }: MobileNavProps) => {
)}
>
- API Token
+ API Tokens
diff --git a/apps/web/src/pages/api/v1/[...ts-rest].tsx b/apps/web/src/pages/api/v1/[...ts-rest].tsx
index b8e36340b..96e1584a1 100644
--- a/apps/web/src/pages/api/v1/[...ts-rest].tsx
+++ b/apps/web/src/pages/api/v1/[...ts-rest].tsx
@@ -1,12 +1,14 @@
import type { NextApiRequest, NextApiResponse } from 'next';
-import { createDocumentData } from '@documenso/lib/server-only/document-data/create-document-data';
-import { createDocument } from '@documenso/lib/server-only/document/create-document';
+import { upsertDocumentMeta } from '@documenso/lib/server-only/document-meta/upsert-document-meta';
import { deleteDocument } from '@documenso/lib/server-only/document/delete-document';
+import { findDocuments } from '@documenso/lib/server-only/document/find-documents';
import { getDocumentById } from '@documenso/lib/server-only/document/get-document-by-id';
-import { getDocuments } from '@documenso/lib/server-only/public-api/get-documents';
+import { sendDocument } from '@documenso/lib/server-only/document/send-document';
+import { setFieldsForDocument } from '@documenso/lib/server-only/field/set-fields-for-document';
import { checkUserFromToken } from '@documenso/lib/server-only/public-api/get-user-by-token';
-import { putFile } from '@documenso/lib/universal/upload/put-file';
+import { setRecipientsForDocument } from '@documenso/lib/server-only/recipient/set-recipients-for-document';
+import { getPresignPostUrl } from '@documenso/lib/universal/upload/server-actions';
import { contract } from '@documenso/trpc/api-contract/contract';
import { createNextRoute, createNextRouter } from '@documenso/trpc/server/public-api/ts-rest';
@@ -35,7 +37,7 @@ const router = createNextRoute(contract, {
};
}
- const { documents, totalPages } = await getDocuments({ page, perPage, userId: user.id });
+ const { data: documents, totalPages } = await findDocuments({ page, perPage, userId: user.id });
return {
status: 200,
@@ -114,7 +116,30 @@ const router = createNextRoute(contract, {
}
},
createDocument: async (args) => {
+ const { body } = args;
+
+ try {
+ const { url, key } = await getPresignPostUrl(body.fileName, body.contentType);
+
+ return {
+ status: 200,
+ body: {
+ url,
+ key,
+ },
+ };
+ } catch (e) {
+ return {
+ status: 404,
+ body: {
+ message: 'An error has occured while uploading the file',
+ },
+ };
+ }
+ },
+ sendDocumentForSigning: async (args) => {
const { authorization } = args.headers;
+ const { id } = args.params;
const { body } = args;
const user = await validateUserToken(authorization);
@@ -128,39 +153,72 @@ const router = createNextRoute(contract, {
};
}
+ const document = await getDocumentById({ id: Number(id), userId: user.id });
+
+ if (!document) {
+ return {
+ status: 404,
+ body: {
+ message: 'Document not found',
+ },
+ };
+ }
+
+ if (document.status === 'PENDING') {
+ return {
+ status: 400,
+ body: {
+ message: 'Document is already waiting for signing',
+ },
+ };
+ }
+
try {
- const regexPattern = /filename="(.+?)"/;
- const match = body.toString().match(regexPattern);
- const documentTitle = match?.[1] ?? 'Untitled document';
-
- const file = new Blob([body], {
- type: 'application/pdf',
+ await setRecipientsForDocument({
+ userId: user.id,
+ documentId: Number(id),
+ recipients: [
+ {
+ email: body.signerEmail,
+ name: body.signerName ?? '',
+ },
+ ],
});
- const { type, data } = await putFile(file);
-
- const { id: documentDataId } = await createDocumentData({
- type,
- data,
+ await setFieldsForDocument({
+ documentId: Number(id),
+ userId: user.id,
+ fields: body.fields.map((field) => ({
+ signerEmail: body.signerEmail,
+ type: field.fieldType,
+ pageNumber: field.pageNumber,
+ pageX: field.pageX,
+ pageY: field.pageY,
+ pageWidth: field.pageWidth,
+ pageHeight: field.pageHeight,
+ })),
});
- const { id } = await createDocument({
- title: documentTitle,
- documentDataId,
+ if (body.emailBody || body.emailSubject) {
+ await upsertDocumentMeta({
+ documentId: Number(id),
+ subject: body.emailSubject ?? '',
+ message: body.emailBody ?? '',
+ });
+ }
+
+ await sendDocument({
+ documentId: Number(id),
userId: user.id,
});
return {
status: 200,
body: {
- uploadedFile: {
- id,
- message: 'Document uploaded successfuly',
- },
+ message: 'Document sent for signing successfully',
},
};
} catch (e) {
- console.error(e);
return {
status: 500,
body: {
diff --git a/packages/lib/server-only/public-api/delete-api-token-by-id.ts b/packages/lib/server-only/public-api/delete-api-token-by-id.ts
index af176063f..398288006 100644
--- a/packages/lib/server-only/public-api/delete-api-token-by-id.ts
+++ b/packages/lib/server-only/public-api/delete-api-token-by-id.ts
@@ -6,7 +6,7 @@ export type DeleteTokenByIdOptions = {
};
export const deleteTokenById = async ({ id, userId }: DeleteTokenByIdOptions) => {
- return prisma.apiToken.delete({
+ return await prisma.apiToken.delete({
where: {
id,
userId,
diff --git a/packages/lib/server-only/public-api/get-documents.ts b/packages/lib/server-only/public-api/get-documents.ts
deleted file mode 100644
index deea612e8..000000000
--- a/packages/lib/server-only/public-api/get-documents.ts
+++ /dev/null
@@ -1,25 +0,0 @@
-import { prisma } from '@documenso/prisma';
-
-type GetDocumentsProps = {
- page: number;
- perPage: number;
- userId: number;
-};
-
-export const getDocuments = async ({ page = 1, perPage = 10, userId }: GetDocumentsProps) => {
- const [documents, count] = await Promise.all([
- await prisma.document.findMany({
- where: {
- userId,
- },
- take: perPage,
- skip: Math.max(page - 1, 0) * perPage,
- }),
- await prisma.document.count(),
- ]);
-
- return {
- documents,
- totalPages: Math.ceil(count / perPage),
- };
-};
diff --git a/packages/trpc/api-contract/schema.ts b/packages/trpc/api-contract/schema.ts
index 504fa55b2..d62d50d52 100644
--- a/packages/trpc/api-contract/schema.ts
+++ b/packages/trpc/api-contract/schema.ts
@@ -38,10 +38,8 @@ export const SendDocumentForSigningMutationSchema = z.object({
});
export const UploadDocumentSuccessfulSchema = z.object({
- uploadedFile: z.object({
- url: z.string(),
- key: z.string(),
- }),
+ url: z.string(),
+ key: z.string(),
});
export const CreateDocumentMutationSchema = z.object({
diff --git a/packages/trpc/server/api-token-router/router.ts b/packages/trpc/server/api-token-router/router.ts
index 266c045d0..bae094456 100644
--- a/packages/trpc/server/api-token-router/router.ts
+++ b/packages/trpc/server/api-token-router/router.ts
@@ -23,6 +23,7 @@ export const apiTokenRouter = router({
});
}
}),
+
getTokenById: authenticatedProcedure
.input(ZGetApiTokenByIdQuerySchema)
.query(async ({ input, ctx }) => {
@@ -40,6 +41,7 @@ export const apiTokenRouter = router({
});
}
}),
+
createToken: authenticatedProcedure
.input(ZCreateTokenMutationSchema)
.mutation(async ({ input, ctx }) => {
@@ -56,6 +58,7 @@ export const apiTokenRouter = router({
});
}
}),
+
deleteTokenById: authenticatedProcedure
.input(ZDeleteTokenByIdMutationSchema)
.mutation(async ({ input, ctx }) => {