diff --git a/apps/remix/app/components/dialogs/envelope-distribute-dialog.tsx b/apps/remix/app/components/dialogs/envelope-distribute-dialog.tsx index 98ffd07e3..a92e17d62 100644 --- a/apps/remix/app/components/dialogs/envelope-distribute-dialog.tsx +++ b/apps/remix/app/components/dialogs/envelope-distribute-dialog.tsx @@ -19,6 +19,7 @@ import * as z from 'zod'; import { useCurrentEnvelopeEditor } from '@documenso/lib/client-only/providers/envelope-editor-provider'; import { useCurrentOrganisation } from '@documenso/lib/client-only/providers/organisation'; +import { extractDocumentAuthMethods } from '@documenso/lib/utils/document-auth'; import { trpc, trpc as trpcReact } from '@documenso/trpc/react'; import { DocumentSendEmailMessageHelper } from '@documenso/ui/components/document/document-send-email-message-helper'; import { cn } from '@documenso/ui/lib/utils'; @@ -129,18 +130,41 @@ export const EnvelopeDistributeDialog = ({ const distributionMethod = watch('meta.distributionMethod'); + const recipientsWithIndex = useMemo( + () => + envelope.recipients.map((recipient, index) => ({ + ...recipient, + index, + })), + [envelope.recipients], + ); + const recipientsMissingSignatureFields = useMemo( () => - envelope.recipients.filter( + recipientsWithIndex.filter( (recipient) => recipient.role === RecipientRole.SIGNER && !envelope.fields.some( (field) => field.type === FieldType.SIGNATURE && field.recipientId === recipient.id, ), ), - [envelope.recipients, envelope.fields], + [recipientsWithIndex, envelope.fields], ); + /** + * List of recipients who must have an email due to having auth enabled. + */ + const recipientsMissingRequiredEmail = useMemo(() => { + return recipientsWithIndex.filter((recipient) => { + const auth = extractDocumentAuthMethods({ + documentAuth: envelope.authOptions, + recipientAuth: recipient.authOptions, + }); + + return auth.recipientAccessAuthRequired || auth.recipientActionAuthRequired; + }); + }, [recipientsWithIndex, envelope.authOptions]); + const invalidEnvelopeCode = useMemo(() => { if (recipientsMissingSignatureFields.length > 0) { return 'MISSING_SIGNATURES'; @@ -150,8 +174,12 @@ export const EnvelopeDistributeDialog = ({ return 'MISSING_RECIPIENTS'; } + if (recipientsMissingRequiredEmail.length > 0) { + return 'MISSING_REQUIRED_EMAIL'; + } + return null; - }, [envelope.recipients, envelope.fields, recipientsMissingSignatureFields]); + }, [envelope.recipients, recipientsMissingRequiredEmail, recipientsMissingSignatureFields]); const onFormSubmit = async ({ meta }: TEnvelopeDistributeFormSchema) => { try { @@ -444,7 +472,22 @@ export const EnvelopeDistributeDialog = ({ + + )) + .with('MISSING_REQUIRED_EMAIL', () => ( + + The following recipients require an email address: + + diff --git a/apps/remix/app/components/dialogs/template-use-dialog.tsx b/apps/remix/app/components/dialogs/template-use-dialog.tsx index 129132dd4..c53d7bac9 100644 --- a/apps/remix/app/components/dialogs/template-use-dialog.tsx +++ b/apps/remix/app/components/dialogs/template-use-dialog.tsx @@ -21,6 +21,7 @@ import { SKIP_QUERY_BATCH_META, } from '@documenso/lib/constants/trpc'; import { AppError } from '@documenso/lib/errors/app-error'; +import { ZRecipientEmailSchema } from '@documenso/lib/types/recipient'; import { putPdfFile } from '@documenso/lib/universal/upload/put-file'; import { trpc } from '@documenso/trpc/react'; import { cn } from '@documenso/ui/lib/utils'; @@ -65,7 +66,7 @@ const ZAddRecipientsForNewDocumentSchema = z.object({ recipients: z.array( z.object({ id: z.number(), - email: z.string().email(), + email: ZRecipientEmailSchema, name: z.string(), signingOrder: z.number().optional(), }), @@ -349,7 +350,7 @@ export function TemplateUseDialog({ {documentDistributionMethod === DocumentDistributionMethod.EMAIL && (