From f82bf9748046404af7d8142a31809cd86705eb83 Mon Sep 17 00:00:00 2001 From: Lucas Smith Date: Mon, 9 Mar 2026 13:30:27 +1100 Subject: [PATCH] fix: only use embed hash name/email as fallback when recipient values are blank (#2586) For document signing embeds, the hash-provided name and email should only be used when the recipient doesn't already have values set. For template signing, the hash values are always allowed. Also makes the email input editable in V1 embeds when the recipient has no email, matching V2 behavior. Ref: documenso/embeds#53 --- .../embed/embed-document-signing-page-v1.tsx | 14 ++++++++++--- .../embed/embed-document-signing-page-v2.tsx | 21 ++++++++++++------- 2 files changed, 24 insertions(+), 11 deletions(-) diff --git a/apps/remix/app/components/embed/embed-document-signing-page-v1.tsx b/apps/remix/app/components/embed/embed-document-signing-page-v1.tsx index cc5911110..149fd30dd 100644 --- a/apps/remix/app/components/embed/embed-document-signing-page-v1.tsx +++ b/apps/remix/app/components/embed/embed-document-signing-page-v1.tsx @@ -74,7 +74,7 @@ export const EmbedSignDocumentV1ClientPage = ({ const { _ } = useLingui(); const { toast } = useToast(); - const { fullName, email, signature, setFullName, setSignature } = + const { fullName, email, signature, setFullName, setEmail, setSignature } = useRequiredDocumentSigningContext(); const [hasFinishedInit, setHasFinishedInit] = useState(false); @@ -89,6 +89,7 @@ export const EmbedSignDocumentV1ClientPage = ({ const [isExpanded, setIsExpanded] = useState(false); const [isNameLocked, setIsNameLocked] = useState(false); + const [isEmailLocked, setIsEmailLocked] = useState(!!email); const [showPendingFieldTooltip, setShowPendingFieldTooltip] = useState(false); const [_showOtherRecipientsCompletedFields, setShowOtherRecipientsCompletedFields] = useState(false); @@ -205,13 +206,19 @@ export const EmbedSignDocumentV1ClientPage = ({ try { const data = ZSignDocumentEmbedDataSchema.parse(JSON.parse(decodeURIComponent(atob(hash)))); - if (!isCompleted && data.name) { + if (!isCompleted && data.name && !fullName) { setFullName(data.name); } // Since a recipient can be provided a name we can lock it without requiring // a to be provided by the parent application, unlike direct templates. setIsNameLocked(!!data.lockName); + + if (!isCompleted && data.email && !email) { + setEmail(data.email); + setIsEmailLocked(!!data.lockEmail); + } + setAllowDocumentRejection(!!data.allowDocumentRejection); setShowOtherRecipientsCompletedFields(!!data.showOtherRecipientsCompletedFields); @@ -449,7 +456,8 @@ export const EmbedSignDocumentV1ClientPage = ({ id="email" className="mt-2 bg-background" value={email} - disabled + onChange={(e) => setEmail(e.target.value)} + disabled={isEmailLocked} /> diff --git a/apps/remix/app/components/embed/embed-document-signing-page-v2.tsx b/apps/remix/app/components/embed/embed-document-signing-page-v2.tsx index 0d6bdabe9..df7def6a5 100644 --- a/apps/remix/app/components/embed/embed-document-signing-page-v2.tsx +++ b/apps/remix/app/components/embed/embed-document-signing-page-v2.tsx @@ -26,7 +26,7 @@ export const EmbedSignDocumentV2ClientPage = ({ }: EmbedSignDocumentV2ClientPageProps) => { const { _ } = useLingui(); - const { envelope, recipient, envelopeData, setFullName, setEmail, fullName } = + const { envelope, recipient, envelopeData, setFullName, setEmail, fullName, email } = useRequiredEnvelopeSigningContext(); const { isCompleted, isRejected, recipientSignature } = envelopeData; @@ -36,7 +36,9 @@ export const EmbedSignDocumentV2ClientPage = ({ const [hasFinishedInit, setHasFinishedInit] = useState(false); const [allowDocumentRejection, setAllowDocumentRejection] = useState(false); const [isNameLocked, setIsNameLocked] = useState(false); - const [isEmailLocked, setIsEmailLocked] = useState(envelope.type === EnvelopeType.DOCUMENT); + const [isEmailLocked, setIsEmailLocked] = useState( + envelope.type === EnvelopeType.DOCUMENT && !!email, + ); const onDocumentCompleted = (data: { token: string; @@ -128,19 +130,22 @@ export const EmbedSignDocumentV2ClientPage = ({ const data = ZSignDocumentEmbedDataSchema.parse(JSON.parse(decodeURIComponent(atob(hash)))); if (!isCompleted && data.name) { - setFullName(data.name); + // For documents, only use the hash name if the recipient doesn't already have one. + // For templates, always allow the hash name to be used. + if (envelope.type === EnvelopeType.TEMPLATE || !fullName) { + setFullName(data.name); + } } // Since a recipient can be provided a name we can lock it without requiring // a to be provided by the parent application, unlike direct templates. setIsNameLocked(!!data.lockName); - if (envelope.type === EnvelopeType.TEMPLATE) { - if (!isCompleted && data.email) { + if (!isCompleted && data.email) { + // For documents, only use the hash email if the recipient doesn't already have one. + // For templates, always allow the hash email to be used. + if (envelope.type === EnvelopeType.TEMPLATE || !email) { setEmail(data.email); - } - - if (data.email) { setIsEmailLocked(!!data.lockEmail); } }