mirror of
https://github.com/documenso/documenso.git
synced 2026-07-27 02:15:05 +10:00
chore: merge main, resolve biome formatting conflicts
Merge origin/main into feat/external-2fa-codes. Resolve formatting conflicts caused by biome rollout; preserve both feature streams: PR's external 2FA token + signing-session 2FA proof additions plus main's RateLimit/RecipientExpired/signingReminders/date-auto-insert. In complete-document-with-token.ts, drop the duplicate early field-fetching block introduced when main moved that logic later with date auto-insert support; keep the EXTERNAL_TWO_FACTOR_AUTH check using derivedRecipientActionAuth.
This commit is contained in:
@@ -1,6 +1,3 @@
|
||||
import { PDF } from '@libpdf/core';
|
||||
import { EnvelopeType } from '@prisma/client';
|
||||
|
||||
import { DOCUMENT_AUDIT_LOG_TYPE } from '@documenso/lib/types/document-audit-logs';
|
||||
import type { TFieldAndMeta } from '@documenso/lib/types/field-meta';
|
||||
import type { ApiRequestMetadata } from '@documenso/lib/universal/extract-request-metadata';
|
||||
@@ -8,6 +5,8 @@ import { getFileServerSide } from '@documenso/lib/universal/upload/get-file.serv
|
||||
import { putPdfFileServerSide } from '@documenso/lib/universal/upload/put-file.server';
|
||||
import { createDocumentAuditLogData } from '@documenso/lib/utils/document-audit-logs';
|
||||
import { prisma } from '@documenso/prisma';
|
||||
import { PDF } from '@libpdf/core';
|
||||
import { EnvelopeType } from '@prisma/client';
|
||||
|
||||
import { AppError, AppErrorCode } from '../../errors/app-error';
|
||||
import type { EnvelopeIdOptions } from '../../utils/envelope';
|
||||
@@ -157,8 +156,7 @@ export const createEnvelopeFields = async ({
|
||||
// Check whether the recipient associated with the field can have new fields created.
|
||||
if (!canRecipientFieldsBeModified(recipient, envelope.fields)) {
|
||||
throw new AppError(AppErrorCode.INVALID_REQUEST, {
|
||||
message:
|
||||
'Recipient type cannot have fields, or they have already interacted with the document.',
|
||||
message: 'Recipient type cannot have fields, or they have already interacted with the document.',
|
||||
});
|
||||
}
|
||||
|
||||
@@ -265,9 +263,7 @@ export const createEnvelopeFields = async ({
|
||||
if (envelope.type === EnvelopeType.DOCUMENT) {
|
||||
await tx.documentAuditLog.createMany({
|
||||
data: newlyCreatedFields.map((createdField) => {
|
||||
const recipient = validatedFields.find(
|
||||
(field) => field.recipientId === createdField.recipientId,
|
||||
);
|
||||
const recipient = validatedFields.find((field) => field.recipientId === createdField.recipientId);
|
||||
|
||||
return createDocumentAuditLogData({
|
||||
type: DOCUMENT_AUDIT_LOG_TYPE.FIELD_CREATED,
|
||||
@@ -308,7 +304,7 @@ export const createEnvelopeFields = async ({
|
||||
continue;
|
||||
}
|
||||
|
||||
const newDocumentData = await putPdfFileServerSide({
|
||||
const { documentData: newDocumentData } = await putPdfFileServerSide({
|
||||
name: 'document.pdf',
|
||||
type: 'application/pdf',
|
||||
arrayBuffer: async () => Promise.resolve(Buffer.from(modifiedPdfBytes)),
|
||||
|
||||
@@ -1,9 +1,8 @@
|
||||
import { EnvelopeType } from '@prisma/client';
|
||||
|
||||
import { DOCUMENT_AUDIT_LOG_TYPE } from '@documenso/lib/types/document-audit-logs';
|
||||
import type { ApiRequestMetadata } from '@documenso/lib/universal/extract-request-metadata';
|
||||
import { createDocumentAuditLogData } from '@documenso/lib/utils/document-audit-logs';
|
||||
import { prisma } from '@documenso/prisma';
|
||||
import { EnvelopeType } from '@prisma/client';
|
||||
|
||||
import { AppError, AppErrorCode } from '../../errors/app-error';
|
||||
import { canRecipientFieldsBeModified } from '../../utils/recipients';
|
||||
@@ -16,12 +15,7 @@ export interface DeleteDocumentFieldOptions {
|
||||
requestMetadata: ApiRequestMetadata;
|
||||
}
|
||||
|
||||
export const deleteDocumentField = async ({
|
||||
userId,
|
||||
teamId,
|
||||
fieldId,
|
||||
requestMetadata,
|
||||
}: DeleteDocumentFieldOptions) => {
|
||||
export const deleteDocumentField = async ({ userId, teamId, fieldId, requestMetadata }: DeleteDocumentFieldOptions) => {
|
||||
// Unauthenticated check, we do the real check later.
|
||||
const field = await prisma.field.findFirst({
|
||||
where: {
|
||||
|
||||
@@ -1,6 +1,5 @@
|
||||
import { EnvelopeType } from '@prisma/client';
|
||||
|
||||
import { prisma } from '@documenso/prisma';
|
||||
import { EnvelopeType } from '@prisma/client';
|
||||
|
||||
import { AppError, AppErrorCode } from '../../errors/app-error';
|
||||
import { buildTeamWhereQuery } from '../../utils/teams';
|
||||
@@ -12,11 +11,7 @@ export interface DeleteTemplateFieldOptions {
|
||||
fieldId: number;
|
||||
}
|
||||
|
||||
export const deleteTemplateField = async ({
|
||||
userId,
|
||||
teamId,
|
||||
fieldId,
|
||||
}: DeleteTemplateFieldOptions): Promise<void> => {
|
||||
export const deleteTemplateField = async ({ userId, teamId, fieldId }: DeleteTemplateFieldOptions): Promise<void> => {
|
||||
const field = await prisma.field.findFirst({
|
||||
where: {
|
||||
id: fieldId,
|
||||
|
||||
@@ -1,14 +1,11 @@
|
||||
import { SigningStatus } from '@prisma/client';
|
||||
|
||||
import { prisma } from '@documenso/prisma';
|
||||
import { SigningStatus } from '@prisma/client';
|
||||
|
||||
export type GetCompletedFieldsForDocumentOptions = {
|
||||
documentId: number;
|
||||
};
|
||||
|
||||
export const getCompletedFieldsForDocument = async ({
|
||||
documentId,
|
||||
}: GetCompletedFieldsForDocumentOptions) => {
|
||||
export const getCompletedFieldsForDocument = async ({ documentId }: GetCompletedFieldsForDocumentOptions) => {
|
||||
return await prisma.field.findMany({
|
||||
where: {
|
||||
documentId,
|
||||
|
||||
@@ -1,6 +1,5 @@
|
||||
import { EnvelopeType, SigningStatus } from '@prisma/client';
|
||||
|
||||
import { prisma } from '@documenso/prisma';
|
||||
import { EnvelopeType, SigningStatus } from '@prisma/client';
|
||||
|
||||
export type GetCompletedFieldsForTokenOptions = {
|
||||
token: string;
|
||||
|
||||
@@ -1,6 +1,5 @@
|
||||
import type { EnvelopeType } from '@prisma/client';
|
||||
|
||||
import { prisma } from '@documenso/prisma';
|
||||
import type { EnvelopeType } from '@prisma/client';
|
||||
|
||||
import { AppError, AppErrorCode } from '../../errors/app-error';
|
||||
import { mapFieldToLegacyField } from '../../utils/fields';
|
||||
@@ -14,12 +13,7 @@ export type GetFieldByIdOptions = {
|
||||
envelopeType?: EnvelopeType;
|
||||
};
|
||||
|
||||
export const getFieldById = async ({
|
||||
userId,
|
||||
teamId,
|
||||
fieldId,
|
||||
envelopeType,
|
||||
}: GetFieldByIdOptions) => {
|
||||
export const getFieldById = async ({ userId, teamId, fieldId, envelopeType }: GetFieldByIdOptions) => {
|
||||
const field = await prisma.field.findFirst({
|
||||
where: {
|
||||
id: fieldId,
|
||||
|
||||
@@ -1,6 +1,5 @@
|
||||
import { EnvelopeType, FieldType, RecipientRole, SigningStatus } from '@prisma/client';
|
||||
|
||||
import { prisma } from '@documenso/prisma';
|
||||
import { EnvelopeType, FieldType, RecipientRole, SigningStatus } from '@prisma/client';
|
||||
|
||||
export type GetFieldsForTokenOptions = {
|
||||
token: string;
|
||||
@@ -35,6 +34,7 @@ export const getFieldsForToken = async ({ token }: GetFieldsForTokenOptions) =>
|
||||
signingOrder: {
|
||||
gte: recipient.signingOrder ?? 0,
|
||||
},
|
||||
envelopeId: recipient.envelopeId,
|
||||
},
|
||||
envelope: {
|
||||
id: recipient.envelopeId,
|
||||
|
||||
@@ -1,9 +1,9 @@
|
||||
import { DocumentStatus, RecipientRole, SigningStatus } from '@prisma/client';
|
||||
|
||||
import { DOCUMENT_AUDIT_LOG_TYPE } from '@documenso/lib/types/document-audit-logs';
|
||||
import type { RequestMetadata } from '@documenso/lib/universal/extract-request-metadata';
|
||||
import { createDocumentAuditLogData } from '@documenso/lib/utils/document-audit-logs';
|
||||
import { assertRecipientNotExpired } from '@documenso/lib/utils/recipients';
|
||||
import { prisma } from '@documenso/prisma';
|
||||
import { DocumentStatus, RecipientRole, SigningStatus } from '@prisma/client';
|
||||
|
||||
export type RemovedSignedFieldWithTokenOptions = {
|
||||
token: string;
|
||||
@@ -37,6 +37,7 @@ export const removeSignedFieldWithToken = async ({
|
||||
signingStatus: {
|
||||
not: SigningStatus.SIGNED,
|
||||
},
|
||||
envelopeId: recipient.envelopeId,
|
||||
}),
|
||||
},
|
||||
},
|
||||
@@ -56,10 +57,9 @@ export const removeSignedFieldWithToken = async ({
|
||||
throw new Error(`Document ${envelope.id} must be pending`);
|
||||
}
|
||||
|
||||
if (
|
||||
recipient?.signingStatus === SigningStatus.SIGNED ||
|
||||
field.recipient.signingStatus === SigningStatus.SIGNED
|
||||
) {
|
||||
assertRecipientNotExpired(recipient);
|
||||
|
||||
if (recipient?.signingStatus === SigningStatus.SIGNED || field.recipient.signingStatus === SigningStatus.SIGNED) {
|
||||
throw new Error(`Recipient ${recipient.id} has already signed`);
|
||||
}
|
||||
|
||||
|
||||
@@ -1,6 +1,3 @@
|
||||
import { EnvelopeType, type Field, FieldType } from '@prisma/client';
|
||||
import { isDeepEqual } from 'remeda';
|
||||
|
||||
import { validateCheckboxField } from '@documenso/lib/advanced-fields-validation/validate-checkbox';
|
||||
import { validateDropdownField } from '@documenso/lib/advanced-fields-validation/validate-dropdown';
|
||||
import { validateNumberField } from '@documenso/lib/advanced-fields-validation/validate-number';
|
||||
@@ -8,6 +5,7 @@ import { validateRadioField } from '@documenso/lib/advanced-fields-validation/va
|
||||
import { validateTextField } from '@documenso/lib/advanced-fields-validation/validate-text';
|
||||
import { DOCUMENT_AUDIT_LOG_TYPE } from '@documenso/lib/types/document-audit-logs';
|
||||
import {
|
||||
FIELD_META_DEFAULT_VALUES,
|
||||
type TFieldMetaSchema as FieldMeta,
|
||||
ZCheckboxFieldMeta,
|
||||
ZDropdownFieldMeta,
|
||||
@@ -17,11 +15,10 @@ import {
|
||||
ZTextFieldMeta,
|
||||
} from '@documenso/lib/types/field-meta';
|
||||
import type { ApiRequestMetadata } from '@documenso/lib/universal/extract-request-metadata';
|
||||
import {
|
||||
createDocumentAuditLogData,
|
||||
diffFieldChanges,
|
||||
} from '@documenso/lib/utils/document-audit-logs';
|
||||
import { createDocumentAuditLogData, diffFieldChanges } from '@documenso/lib/utils/document-audit-logs';
|
||||
import { prisma } from '@documenso/prisma';
|
||||
import { EnvelopeType, type Field, FieldType } from '@prisma/client';
|
||||
import { isDeepEqual } from 'remeda';
|
||||
|
||||
import { AppError, AppErrorCode } from '../../errors/app-error';
|
||||
import type { EnvelopeIdOptions } from '../../utils/envelope';
|
||||
@@ -92,9 +89,7 @@ export const setFieldsForDocument = async ({
|
||||
const recipient = envelope.recipients.find((recipient) => recipient.id === field.recipientId);
|
||||
|
||||
// Check whether the field is being attached to an allowed envelope item.
|
||||
const foundEnvelopeItem = envelope.envelopeItems.find(
|
||||
(envelopeItem) => envelopeItem.id === field.envelopeItemId,
|
||||
);
|
||||
const foundEnvelopeItem = envelope.envelopeItems.find((envelopeItem) => envelopeItem.id === field.envelopeItemId);
|
||||
|
||||
if (!foundEnvelopeItem) {
|
||||
throw new AppError(AppErrorCode.INVALID_REQUEST, {
|
||||
@@ -110,22 +105,16 @@ export const setFieldsForDocument = async ({
|
||||
}
|
||||
|
||||
// Check whether the existing field can be modified.
|
||||
if (
|
||||
existing &&
|
||||
hasFieldBeenChanged(existing, field) &&
|
||||
!canRecipientFieldsBeModified(recipient, existingFields)
|
||||
) {
|
||||
if (existing && hasFieldBeenChanged(existing, field) && !canRecipientFieldsBeModified(recipient, existingFields)) {
|
||||
throw new AppError(AppErrorCode.INVALID_REQUEST, {
|
||||
message:
|
||||
'Cannot modify a field where the recipient has already interacted with the document',
|
||||
message: 'Cannot modify a field where the recipient has already interacted with the document',
|
||||
});
|
||||
}
|
||||
|
||||
// Prevent creating new fields when recipient has interacted with the document.
|
||||
if (!existing && !canRecipientFieldsBeModified(recipient, existingFields)) {
|
||||
throw new AppError(AppErrorCode.INVALID_REQUEST, {
|
||||
message:
|
||||
'Cannot modify a field where the recipient has already interacted with the document',
|
||||
message: 'Cannot modify a field where the recipient has already interacted with the document',
|
||||
});
|
||||
}
|
||||
|
||||
@@ -143,7 +132,7 @@ export const setFieldsForDocument = async ({
|
||||
|
||||
const parsedFieldMeta = field.fieldMeta
|
||||
? ZFieldMetaSchema.parse(field.fieldMeta)
|
||||
: undefined;
|
||||
: FIELD_META_DEFAULT_VALUES[field.type];
|
||||
|
||||
if (field.type === FieldType.TEXT && field.fieldMeta) {
|
||||
const textFieldParsedMeta = ZTextFieldMeta.parse(field.fieldMeta);
|
||||
@@ -157,11 +146,7 @@ export const setFieldsForDocument = async ({
|
||||
if (field.type === FieldType.NUMBER && field.fieldMeta) {
|
||||
const numberFieldParsedMeta = ZNumberFieldMeta.parse(field.fieldMeta);
|
||||
|
||||
const errors = validateNumberField(
|
||||
String(numberFieldParsedMeta.value || ''),
|
||||
numberFieldParsedMeta,
|
||||
false,
|
||||
);
|
||||
const errors = validateNumberField(String(numberFieldParsedMeta.value || ''), numberFieldParsedMeta, false);
|
||||
|
||||
if (errors.length > 0) {
|
||||
throw new Error(errors.join(', '));
|
||||
@@ -180,18 +165,14 @@ export const setFieldsForDocument = async ({
|
||||
throw new Error(errors.join(', '));
|
||||
}
|
||||
} else {
|
||||
throw new Error(
|
||||
'To proceed further, please set at least one value for the Checkbox field',
|
||||
);
|
||||
throw new Error('To proceed further, please set at least one value for the Checkbox field');
|
||||
}
|
||||
}
|
||||
|
||||
if (field.type === FieldType.RADIO) {
|
||||
if (field.fieldMeta) {
|
||||
const radioFieldParsedMeta = ZRadioFieldMeta.parse(field.fieldMeta);
|
||||
const checkedRadioFieldValue = radioFieldParsedMeta.values?.find(
|
||||
(option) => option.checked,
|
||||
)?.value;
|
||||
const checkedRadioFieldValue = radioFieldParsedMeta.values?.find((option) => option.checked)?.value;
|
||||
|
||||
const errors = validateRadioField(checkedRadioFieldValue, radioFieldParsedMeta);
|
||||
|
||||
@@ -199,9 +180,7 @@ export const setFieldsForDocument = async ({
|
||||
throw new Error(errors.join('. '));
|
||||
}
|
||||
} else {
|
||||
throw new Error(
|
||||
'To proceed further, please set at least one value for the Radio field',
|
||||
);
|
||||
throw new Error('To proceed further, please set at least one value for the Radio field');
|
||||
}
|
||||
}
|
||||
|
||||
@@ -214,9 +193,7 @@ export const setFieldsForDocument = async ({
|
||||
throw new Error(errors.join('. '));
|
||||
}
|
||||
} else {
|
||||
throw new Error(
|
||||
'To proceed further, please set at least one value for the Dropdown field',
|
||||
);
|
||||
throw new Error('To proceed further, please set at least one value for the Dropdown field');
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -1,11 +1,10 @@
|
||||
import { EnvelopeType, FieldType } from '@prisma/client';
|
||||
|
||||
import { validateCheckboxField } from '@documenso/lib/advanced-fields-validation/validate-checkbox';
|
||||
import { validateDropdownField } from '@documenso/lib/advanced-fields-validation/validate-dropdown';
|
||||
import { validateNumberField } from '@documenso/lib/advanced-fields-validation/validate-number';
|
||||
import { validateRadioField } from '@documenso/lib/advanced-fields-validation/validate-radio';
|
||||
import { validateTextField } from '@documenso/lib/advanced-fields-validation/validate-text';
|
||||
import {
|
||||
FIELD_META_DEFAULT_VALUES,
|
||||
type TFieldMetaSchema as FieldMeta,
|
||||
ZCheckboxFieldMeta,
|
||||
ZDropdownFieldMeta,
|
||||
@@ -15,6 +14,7 @@ import {
|
||||
ZTextFieldMeta,
|
||||
} from '@documenso/lib/types/field-meta';
|
||||
import { prisma } from '@documenso/prisma';
|
||||
import { EnvelopeType, FieldType } from '@prisma/client';
|
||||
|
||||
import { AppError, AppErrorCode } from '../../errors/app-error';
|
||||
import type { EnvelopeIdOptions } from '../../utils/envelope';
|
||||
@@ -40,12 +40,7 @@ export type SetFieldsForTemplateOptions = {
|
||||
}[];
|
||||
};
|
||||
|
||||
export const setFieldsForTemplate = async ({
|
||||
userId,
|
||||
teamId,
|
||||
id,
|
||||
fields,
|
||||
}: SetFieldsForTemplateOptions) => {
|
||||
export const setFieldsForTemplate = async ({ userId, teamId, id, fields }: SetFieldsForTemplateOptions) => {
|
||||
const { envelopeWhereInput } = await getEnvelopeWhereInput({
|
||||
id,
|
||||
type: EnvelopeType.TEMPLATE,
|
||||
@@ -88,9 +83,7 @@ export const setFieldsForTemplate = async ({
|
||||
const recipient = envelope.recipients.find((recipient) => recipient.id === field.recipientId);
|
||||
|
||||
// Check whether the field is being attached to an allowed envelope item.
|
||||
const foundEnvelopeItem = envelope.envelopeItems.find(
|
||||
(envelopeItem) => envelopeItem.id === field.envelopeItemId,
|
||||
);
|
||||
const foundEnvelopeItem = envelope.envelopeItems.find((envelopeItem) => envelopeItem.id === field.envelopeItemId);
|
||||
|
||||
if (!foundEnvelopeItem) {
|
||||
throw new AppError(AppErrorCode.INVALID_REQUEST, {
|
||||
@@ -116,7 +109,9 @@ export const setFieldsForTemplate = async ({
|
||||
// Disabling as wrapping promises here causes type issues
|
||||
// eslint-disable-next-line @typescript-eslint/promise-function-async
|
||||
linkedFields.map(async (field) => {
|
||||
const parsedFieldMeta = field.fieldMeta ? ZFieldMetaSchema.parse(field.fieldMeta) : undefined;
|
||||
const parsedFieldMeta = field.fieldMeta
|
||||
? ZFieldMetaSchema.parse(field.fieldMeta)
|
||||
: FIELD_META_DEFAULT_VALUES[field.type];
|
||||
|
||||
if (field.type === FieldType.TEXT && field.fieldMeta) {
|
||||
const textFieldParsedMeta = ZTextFieldMeta.parse(field.fieldMeta);
|
||||
@@ -128,10 +123,7 @@ export const setFieldsForTemplate = async ({
|
||||
|
||||
if (field.type === FieldType.NUMBER && field.fieldMeta) {
|
||||
const numberFieldParsedMeta = ZNumberFieldMeta.parse(field.fieldMeta);
|
||||
const errors = validateNumberField(
|
||||
String(numberFieldParsedMeta.value || ''),
|
||||
numberFieldParsedMeta,
|
||||
);
|
||||
const errors = validateNumberField(String(numberFieldParsedMeta.value || ''), numberFieldParsedMeta);
|
||||
if (errors.length > 0) {
|
||||
throw new Error(errors.join(', '));
|
||||
}
|
||||
@@ -156,9 +148,7 @@ export const setFieldsForTemplate = async ({
|
||||
throw new Error('Radio field is missing required metadata');
|
||||
}
|
||||
const radioFieldParsedMeta = ZRadioFieldMeta.parse(field.fieldMeta);
|
||||
const checkedRadioFieldValue = radioFieldParsedMeta.values?.find(
|
||||
(option) => option.checked,
|
||||
)?.value;
|
||||
const checkedRadioFieldValue = radioFieldParsedMeta.values?.find((option) => option.checked)?.value;
|
||||
const errors = validateRadioField(checkedRadioFieldValue, radioFieldParsedMeta);
|
||||
if (errors.length > 0) {
|
||||
throw new Error(errors.join('. '));
|
||||
|
||||
@@ -1,8 +1,3 @@
|
||||
import { DocumentStatus, FieldType, RecipientRole, SigningStatus } from '@prisma/client';
|
||||
import { DateTime } from 'luxon';
|
||||
import { isDeepEqual } from 'remeda';
|
||||
import { match } from 'ts-pattern';
|
||||
|
||||
import { validateCheckboxField } from '@documenso/lib/advanced-fields-validation/validate-checkbox';
|
||||
import { validateDropdownField } from '@documenso/lib/advanced-fields-validation/validate-dropdown';
|
||||
import { validateNumberField } from '@documenso/lib/advanced-fields-validation/validate-number';
|
||||
@@ -10,6 +5,10 @@ import { validateRadioField } from '@documenso/lib/advanced-fields-validation/va
|
||||
import { validateTextField } from '@documenso/lib/advanced-fields-validation/validate-text';
|
||||
import { fromCheckboxValue } from '@documenso/lib/universal/field-checkbox';
|
||||
import { prisma } from '@documenso/prisma';
|
||||
import { DocumentStatus, FieldType, RecipientRole, SigningStatus } from '@prisma/client';
|
||||
import { DateTime } from 'luxon';
|
||||
import { isDeepEqual } from 'remeda';
|
||||
import { match } from 'ts-pattern';
|
||||
|
||||
import { AUTO_SIGNABLE_FIELD_TYPES } from '../../constants/autosign';
|
||||
import { DEFAULT_DOCUMENT_DATE_FORMAT } from '../../constants/date-formats';
|
||||
@@ -25,6 +24,7 @@ import {
|
||||
} from '../../types/field-meta';
|
||||
import type { RequestMetadata } from '../../universal/extract-request-metadata';
|
||||
import { createDocumentAuditLogData } from '../../utils/document-audit-logs';
|
||||
import { assertRecipientNotExpired } from '../../utils/recipients';
|
||||
import { validateFieldAuth } from '../document/validate-field-auth';
|
||||
|
||||
export type SignFieldWithTokenOptions = {
|
||||
@@ -77,6 +77,7 @@ export const signFieldWithToken = async ({
|
||||
signingOrder: {
|
||||
gte: recipient.signingOrder ?? 0,
|
||||
},
|
||||
envelopeId: recipient.envelopeId,
|
||||
}),
|
||||
},
|
||||
},
|
||||
@@ -108,10 +109,9 @@ export const signFieldWithToken = async ({
|
||||
throw new Error(`Document ${envelope.id} must be pending for signing`);
|
||||
}
|
||||
|
||||
if (
|
||||
recipient.signingStatus === SigningStatus.SIGNED ||
|
||||
field.recipient.signingStatus === SigningStatus.SIGNED
|
||||
) {
|
||||
assertRecipientNotExpired(recipient);
|
||||
|
||||
if (recipient.signingStatus === SigningStatus.SIGNED || field.recipient.signingStatus === SigningStatus.SIGNED) {
|
||||
throw new Error(`Recipient ${recipient.id} has already signed`);
|
||||
}
|
||||
|
||||
@@ -188,8 +188,7 @@ export const signFieldWithToken = async ({
|
||||
},
|
||||
});
|
||||
|
||||
const isSignatureField =
|
||||
field.type === FieldType.SIGNATURE || field.type === FieldType.FREE_SIGNATURE;
|
||||
const isSignatureField = field.type === FieldType.SIGNATURE || field.type === FieldType.FREE_SIGNATURE;
|
||||
|
||||
let customText = !isSignatureField ? value : undefined;
|
||||
|
||||
@@ -292,27 +291,14 @@ export const signFieldWithToken = async ({
|
||||
type,
|
||||
data: signatureImageAsBase64 || typedSignature || '',
|
||||
}))
|
||||
.with(
|
||||
FieldType.DATE,
|
||||
FieldType.EMAIL,
|
||||
FieldType.NAME,
|
||||
FieldType.TEXT,
|
||||
FieldType.INITIALS,
|
||||
(type) => ({
|
||||
type,
|
||||
data: updatedField.customText,
|
||||
}),
|
||||
)
|
||||
.with(
|
||||
FieldType.NUMBER,
|
||||
FieldType.RADIO,
|
||||
FieldType.CHECKBOX,
|
||||
FieldType.DROPDOWN,
|
||||
(type) => ({
|
||||
type,
|
||||
data: updatedField.customText,
|
||||
}),
|
||||
)
|
||||
.with(FieldType.DATE, FieldType.EMAIL, FieldType.NAME, FieldType.TEXT, FieldType.INITIALS, (type) => ({
|
||||
type,
|
||||
data: updatedField.customText,
|
||||
}))
|
||||
.with(FieldType.NUMBER, FieldType.RADIO, FieldType.CHECKBOX, FieldType.DROPDOWN, (type) => ({
|
||||
type,
|
||||
data: updatedField.customText,
|
||||
}))
|
||||
.exhaustive(),
|
||||
fieldSecurity: derivedRecipientActionAuth
|
||||
? {
|
||||
|
||||
@@ -1,16 +1,12 @@
|
||||
import { EnvelopeType, type FieldType } from '@prisma/client';
|
||||
|
||||
import { DOCUMENT_AUDIT_LOG_TYPE } from '@documenso/lib/types/document-audit-logs';
|
||||
import type { TFieldMetaSchema } from '@documenso/lib/types/field-meta';
|
||||
import type { ApiRequestMetadata } from '@documenso/lib/universal/extract-request-metadata';
|
||||
import {
|
||||
createDocumentAuditLogData,
|
||||
diffFieldChanges,
|
||||
} from '@documenso/lib/utils/document-audit-logs';
|
||||
import { createDocumentAuditLogData, diffFieldChanges } from '@documenso/lib/utils/document-audit-logs';
|
||||
import { prisma } from '@documenso/prisma';
|
||||
import { EnvelopeType, type FieldType } from '@prisma/client';
|
||||
|
||||
import { AppError, AppErrorCode } from '../../errors/app-error';
|
||||
import { type EnvelopeIdOptions } from '../../utils/envelope';
|
||||
import type { EnvelopeIdOptions } from '../../utils/envelope';
|
||||
import { mapFieldToLegacyField } from '../../utils/fields';
|
||||
import { canRecipientFieldsBeModified } from '../../utils/recipients';
|
||||
import { getEnvelopeWhereInput } from '../envelope/get-envelope-by-id';
|
||||
@@ -79,9 +75,7 @@ export const updateEnvelopeFields = async ({
|
||||
});
|
||||
}
|
||||
|
||||
const recipient = envelope.recipients.find(
|
||||
(recipient) => recipient.id === originalField.recipientId,
|
||||
);
|
||||
const recipient = envelope.recipients.find((recipient) => recipient.id === originalField.recipientId);
|
||||
|
||||
// Each field MUST have a recipient associated with it.
|
||||
if (!recipient) {
|
||||
@@ -93,8 +87,7 @@ export const updateEnvelopeFields = async ({
|
||||
// Check whether the recipient associated with the field can be modified.
|
||||
if (!canRecipientFieldsBeModified(recipient, envelope.fields)) {
|
||||
throw new AppError(AppErrorCode.INVALID_REQUEST, {
|
||||
message:
|
||||
'Cannot modify a field where the recipient has already interacted with the document',
|
||||
message: 'Cannot modify a field where the recipient has already interacted with the document',
|
||||
});
|
||||
}
|
||||
|
||||
@@ -102,20 +95,13 @@ export const updateEnvelopeFields = async ({
|
||||
const fieldMetaType = field.fieldMeta?.type || originalField.fieldMeta?.type;
|
||||
|
||||
// Not going to mess with V1 envelopes.
|
||||
if (
|
||||
envelope.internalVersion === 2 &&
|
||||
fieldMetaType &&
|
||||
fieldMetaType.toLowerCase() !== fieldType.toLowerCase()
|
||||
) {
|
||||
if (envelope.internalVersion === 2 && fieldMetaType && fieldMetaType.toLowerCase() !== fieldType.toLowerCase()) {
|
||||
throw new AppError(AppErrorCode.INVALID_REQUEST, {
|
||||
message: 'Field meta type does not match the field type',
|
||||
});
|
||||
}
|
||||
|
||||
if (
|
||||
field.envelopeItemId &&
|
||||
!envelope.envelopeItems.some((item) => item.id === field.envelopeItemId)
|
||||
) {
|
||||
if (field.envelopeItemId && !envelope.envelopeItems.some((item) => item.id === field.envelopeItemId)) {
|
||||
throw new AppError(AppErrorCode.INVALID_REQUEST, {
|
||||
message: 'Envelope item not found',
|
||||
});
|
||||
|
||||
Reference in New Issue
Block a user