mirror of
https://github.com/documenso/documenso.git
synced 2025-11-14 08:42:12 +10:00
fix: add regression test
This commit is contained in:
@ -13,7 +13,7 @@ export const createAttachmentRoute = authenticatedProcedure
|
||||
path: '/envelope/attachment/create',
|
||||
summary: 'Create attachment',
|
||||
description: 'Create a new attachment for an envelope',
|
||||
tags: ['Envelope'],
|
||||
tags: ['Envelope Attachment'],
|
||||
},
|
||||
})
|
||||
.input(ZCreateAttachmentRequestSchema)
|
||||
|
||||
@ -13,7 +13,7 @@ export const deleteAttachmentRoute = authenticatedProcedure
|
||||
path: '/envelope/attachment/delete',
|
||||
summary: 'Delete attachment',
|
||||
description: 'Delete an attachment from an envelope',
|
||||
tags: ['Envelope'],
|
||||
tags: ['Envelope Attachment'],
|
||||
},
|
||||
})
|
||||
.input(ZDeleteAttachmentRequestSchema)
|
||||
|
||||
@ -2,20 +2,20 @@ import { AppError, AppErrorCode } from '@documenso/lib/errors/app-error';
|
||||
import { findAttachmentsByEnvelopeId } from '@documenso/lib/server-only/envelope-attachment/find-attachments-by-envelope-id';
|
||||
import { findAttachmentsByToken } from '@documenso/lib/server-only/envelope-attachment/find-attachments-by-token';
|
||||
|
||||
import { procedure } from '../../trpc';
|
||||
import { maybeAuthenticatedProcedure } from '../../trpc';
|
||||
import {
|
||||
ZFindAttachmentsRequestSchema,
|
||||
ZFindAttachmentsResponseSchema,
|
||||
} from './find-attachments.types';
|
||||
|
||||
export const findAttachmentsRoute = procedure
|
||||
export const findAttachmentsRoute = maybeAuthenticatedProcedure
|
||||
.meta({
|
||||
openapi: {
|
||||
method: 'GET',
|
||||
path: '/envelope/attachment',
|
||||
summary: 'Find attachments',
|
||||
description: 'Find all attachments for an envelope',
|
||||
tags: ['Envelope'],
|
||||
tags: ['Envelope Attachment'],
|
||||
},
|
||||
})
|
||||
.input(ZFindAttachmentsRequestSchema)
|
||||
|
||||
@ -13,7 +13,7 @@ export const updateAttachmentRoute = authenticatedProcedure
|
||||
path: '/envelope/attachment/update',
|
||||
summary: 'Update attachment',
|
||||
description: 'Update an existing attachment',
|
||||
tags: ['Envelope'],
|
||||
tags: ['Envelope Attachment'],
|
||||
},
|
||||
})
|
||||
.input(ZUpdateAttachmentRequestSchema)
|
||||
|
||||
@ -14,15 +14,15 @@ import {
|
||||
|
||||
export const createEnvelopeItemsRoute = authenticatedProcedure
|
||||
// Todo: Envelopes - Pending direct uploads
|
||||
// .meta({
|
||||
// openapi: {
|
||||
// method: 'POST',
|
||||
// path: '/envelope/item/create-many',
|
||||
// summary: 'Create envelope items',
|
||||
// description: 'Create multiple envelope items for an envelope',
|
||||
// tags: ['Envelope Item'],
|
||||
// },
|
||||
// })
|
||||
.meta({
|
||||
openapi: {
|
||||
method: 'POST',
|
||||
path: '/envelope/item/create-many',
|
||||
summary: 'Create envelope items',
|
||||
description: 'Create multiple envelope items for an envelope',
|
||||
tags: ['Envelope Item'],
|
||||
},
|
||||
})
|
||||
.input(ZCreateEnvelopeItemsRequestSchema)
|
||||
.output(ZCreateEnvelopeItemsResponseSchema)
|
||||
.mutation(async ({ input, ctx }) => {
|
||||
|
||||
@ -2,8 +2,8 @@ import { z } from 'zod';
|
||||
|
||||
import {
|
||||
ZClampedFieldHeightSchema,
|
||||
ZClampedFieldPageXSchema,
|
||||
ZClampedFieldPageYSchema,
|
||||
ZClampedFieldPositionXSchema,
|
||||
ZClampedFieldPositionYSchema,
|
||||
ZClampedFieldWidthSchema,
|
||||
ZFieldPageNumberSchema,
|
||||
ZFieldSchema,
|
||||
@ -19,9 +19,9 @@ const ZCreateFieldSchema = ZFieldAndMetaSchema.and(
|
||||
.describe(
|
||||
'The ID of the envelope item to put the field on. If not provided, field will be placed on the first item.',
|
||||
),
|
||||
pageNumber: ZFieldPageNumberSchema,
|
||||
pageX: ZClampedFieldPageXSchema,
|
||||
pageY: ZClampedFieldPageYSchema,
|
||||
page: ZFieldPageNumberSchema,
|
||||
positionX: ZClampedFieldPositionXSchema,
|
||||
positionY: ZClampedFieldPositionYSchema,
|
||||
width: ZClampedFieldWidthSchema,
|
||||
height: ZClampedFieldHeightSchema,
|
||||
}),
|
||||
|
||||
@ -2,8 +2,8 @@ import { z } from 'zod';
|
||||
|
||||
import {
|
||||
ZClampedFieldHeightSchema,
|
||||
ZClampedFieldPageXSchema,
|
||||
ZClampedFieldPageYSchema,
|
||||
ZClampedFieldPositionXSchema,
|
||||
ZClampedFieldPositionYSchema,
|
||||
ZClampedFieldWidthSchema,
|
||||
ZFieldPageNumberSchema,
|
||||
ZFieldSchema,
|
||||
@ -19,9 +19,9 @@ const ZUpdateFieldSchema = ZFieldAndMetaSchema.and(
|
||||
.describe(
|
||||
'The ID of the envelope item to put the field on. If not provided, field will be placed on the first item.',
|
||||
),
|
||||
pageNumber: ZFieldPageNumberSchema.optional(),
|
||||
pageX: ZClampedFieldPageXSchema.optional(),
|
||||
pageY: ZClampedFieldPageYSchema.optional(),
|
||||
page: ZFieldPageNumberSchema.optional(),
|
||||
positionX: ZClampedFieldPositionXSchema.optional(),
|
||||
positionY: ZClampedFieldPositionYSchema.optional(),
|
||||
width: ZClampedFieldWidthSchema.optional(),
|
||||
height: ZClampedFieldHeightSchema.optional(),
|
||||
}),
|
||||
|
||||
@ -27,14 +27,18 @@ import { signEnvelopeFieldRoute } from './sign-envelope-field';
|
||||
import { updateEnvelopeRoute } from './update-envelope';
|
||||
import { updateEnvelopeItemsRoute } from './update-envelope-items';
|
||||
|
||||
/**
|
||||
* Note: The order of the routes is important for public API routes.
|
||||
*
|
||||
* Example: GET /envelope/attachment must appear before GET /envelope/:id
|
||||
*/
|
||||
export const envelopeRouter = router({
|
||||
get: getEnvelopeRoute,
|
||||
create: createEnvelopeRoute,
|
||||
update: updateEnvelopeRoute,
|
||||
delete: deleteEnvelopeRoute,
|
||||
duplicate: duplicateEnvelopeRoute,
|
||||
distribute: distributeEnvelopeRoute,
|
||||
redistribute: redistributeEnvelopeRoute,
|
||||
attachment: {
|
||||
find: findAttachmentsRoute,
|
||||
create: createAttachmentRoute,
|
||||
update: updateAttachmentRoute,
|
||||
delete: deleteAttachmentRoute,
|
||||
},
|
||||
item: {
|
||||
getMany: getEnvelopeItemsRoute,
|
||||
getManyByToken: getEnvelopeItemsByTokenRoute,
|
||||
@ -57,10 +61,11 @@ export const envelopeRouter = router({
|
||||
set: setEnvelopeFieldsRoute,
|
||||
sign: signEnvelopeFieldRoute,
|
||||
},
|
||||
attachment: {
|
||||
find: findAttachmentsRoute,
|
||||
create: createAttachmentRoute,
|
||||
update: updateAttachmentRoute,
|
||||
delete: deleteAttachmentRoute,
|
||||
},
|
||||
get: getEnvelopeRoute,
|
||||
create: createEnvelopeRoute,
|
||||
update: updateEnvelopeRoute,
|
||||
delete: deleteEnvelopeRoute,
|
||||
duplicate: duplicateEnvelopeRoute,
|
||||
distribute: distributeEnvelopeRoute,
|
||||
redistribute: redistributeEnvelopeRoute,
|
||||
});
|
||||
|
||||
@ -3,8 +3,8 @@ import { z } from 'zod';
|
||||
|
||||
import {
|
||||
ZClampedFieldHeightSchema,
|
||||
ZClampedFieldPageXSchema,
|
||||
ZClampedFieldPageYSchema,
|
||||
ZClampedFieldPositionXSchema,
|
||||
ZClampedFieldPositionYSchema,
|
||||
ZClampedFieldWidthSchema,
|
||||
} from '@documenso/lib/types/field';
|
||||
import { ZFieldMetaSchema } from '@documenso/lib/types/field-meta';
|
||||
@ -26,8 +26,8 @@ export const ZSetEnvelopeFieldsRequestSchema = z.object({
|
||||
.number()
|
||||
.min(1)
|
||||
.describe('The page number of the field on the envelope. Starts from 1.'),
|
||||
positionX: ZClampedFieldPageXSchema,
|
||||
positionY: ZClampedFieldPageYSchema,
|
||||
positionX: ZClampedFieldPositionXSchema,
|
||||
positionY: ZClampedFieldPositionYSchema,
|
||||
width: ZClampedFieldWidthSchema,
|
||||
height: ZClampedFieldHeightSchema,
|
||||
fieldMeta: ZFieldMetaSchema,
|
||||
|
||||
@ -108,7 +108,14 @@ export const fieldRouter = router({
|
||||
type: 'documentId',
|
||||
id: documentId,
|
||||
},
|
||||
fields: [field],
|
||||
fields: [
|
||||
{
|
||||
...field,
|
||||
page: field.pageNumber,
|
||||
positionX: field.pageX,
|
||||
positionY: field.pageY,
|
||||
},
|
||||
],
|
||||
requestMetadata: ctx.metadata,
|
||||
});
|
||||
|
||||
@ -147,7 +154,12 @@ export const fieldRouter = router({
|
||||
type: 'documentId',
|
||||
id: documentId,
|
||||
},
|
||||
fields,
|
||||
fields: fields.map((field) => ({
|
||||
...field,
|
||||
page: field.pageNumber,
|
||||
positionX: field.pageX,
|
||||
positionY: field.pageY,
|
||||
})),
|
||||
requestMetadata: ctx.metadata,
|
||||
});
|
||||
}),
|
||||
@ -335,7 +347,14 @@ export const fieldRouter = router({
|
||||
type: 'templateId',
|
||||
id: templateId,
|
||||
},
|
||||
fields: [field],
|
||||
fields: [
|
||||
{
|
||||
...field,
|
||||
page: field.pageNumber,
|
||||
positionX: field.pageX,
|
||||
positionY: field.pageY,
|
||||
},
|
||||
],
|
||||
requestMetadata: ctx.metadata,
|
||||
});
|
||||
|
||||
@ -408,7 +427,12 @@ export const fieldRouter = router({
|
||||
type: 'templateId',
|
||||
id: templateId,
|
||||
},
|
||||
fields,
|
||||
fields: fields.map((field) => ({
|
||||
...field,
|
||||
page: field.pageNumber,
|
||||
positionX: field.pageX,
|
||||
positionY: field.pageY,
|
||||
})),
|
||||
requestMetadata: ctx.metadata,
|
||||
});
|
||||
}),
|
||||
|
||||
@ -164,14 +164,62 @@ export const maybeAuthenticatedMiddleware = t.middleware(async ({ ctx, next, pat
|
||||
nonBatchedRequestId: alphaid(),
|
||||
});
|
||||
|
||||
ctx.logger.info({
|
||||
const infoToLog: TrpcApiLog = {
|
||||
path,
|
||||
auth: ctx.metadata.auth,
|
||||
source: ctx.metadata.source,
|
||||
userId: ctx.user?.id,
|
||||
apiTokenId: null,
|
||||
trpcMiddleware: 'maybeAuthenticated',
|
||||
unverifiedTeamId: ctx.teamId,
|
||||
};
|
||||
|
||||
const authorizationHeader = ctx.req.headers.get('authorization');
|
||||
|
||||
// Taken from `authenticatedMiddleware` in `@documenso/api/v1/middleware/authenticated.ts`.
|
||||
if (authorizationHeader) {
|
||||
// Support for both "Authorization: Bearer api_xxx" and "Authorization: api_xxx"
|
||||
const [token] = (authorizationHeader || '').split('Bearer ').filter((s) => s.length > 0);
|
||||
|
||||
if (!token) {
|
||||
throw new Error('Token was not provided for authenticated middleware');
|
||||
}
|
||||
|
||||
const apiToken = await getApiTokenByToken({ token });
|
||||
|
||||
ctx.logger.info({
|
||||
...infoToLog,
|
||||
userId: apiToken.user.id,
|
||||
apiTokenId: apiToken.id,
|
||||
} satisfies TrpcApiLog);
|
||||
|
||||
return await next({
|
||||
ctx: {
|
||||
...ctx,
|
||||
user: apiToken.user,
|
||||
teamId: apiToken.teamId,
|
||||
session: null,
|
||||
metadata: {
|
||||
...ctx.metadata,
|
||||
auditUser: apiToken.team
|
||||
? {
|
||||
id: null,
|
||||
email: null,
|
||||
name: apiToken.team.name,
|
||||
}
|
||||
: {
|
||||
id: apiToken.user.id,
|
||||
email: apiToken.user.email,
|
||||
name: apiToken.user.name,
|
||||
},
|
||||
auth: 'api',
|
||||
} satisfies ApiRequestMetadata,
|
||||
},
|
||||
});
|
||||
}
|
||||
|
||||
trpcSessionLogger.info({
|
||||
...infoToLog,
|
||||
userId: ctx.user?.id,
|
||||
apiTokenId: null,
|
||||
} satisfies TrpcApiLog);
|
||||
|
||||
return await next({
|
||||
|
||||
Reference in New Issue
Block a user