Skip to content

Commit f81e0e6

Browse files
committed
fix(Sign): submit each envelope file independently with its UUID
When signing an envelope document that has multiple child PDFs, the current submitSignature sends every visible element to a single sign_request_uuid (the first me=true signer's). The backend rejects it with HTTP 422 because elements belonging to file 2 are sent under file 1's sign_request context. Fix: before submitting, collect all me=true signers that have a sign_request_uuid. If the document is an envelope and more than one signer is found, iterate them and make one signStore.submitSignature call per signer, filtering elements by signRequestId so each call only carries the elements that belong to that specific file. The fallback (no matched envelope signers, or non-envelope documents) preserves the existing single-file code path unchanged. Both the Composition API let submitSignature and the backward-compat Options API shim in defineOptions.methods are updated. Closes: #7344 (phase 2) Signed-off-by: Vitor Mattos <1079143+vitormattos@users.noreply.github.com>
1 parent 8250aa2 commit f81e0e6

1 file changed

Lines changed: 179 additions & 70 deletions

File tree

src/views/SignPDF/_partials/Sign.vue

Lines changed: 179 additions & 70 deletions
Original file line numberDiff line numberDiff line change
@@ -251,48 +251,102 @@ defineOptions({
251251
this.signStore.clearSigningErrors()
252252
253253
try {
254-
const payload: SubmitSignaturePayload = {
254+
const basePayload: SubmitSignaturePayload = {
255255
method: methodConfig.method,
256256
}
257257
258258
if (methodConfig.token) {
259-
payload.token = methodConfig.token
259+
basePayload.token = methodConfig.token
260260
}
261261
262-
if (this.elements?.length > 0) {
263-
if (this.canCreateSignature) {
264-
payload.elements = this.elements.flatMap((row) => typeof row.elementId === 'number'
265-
? [{
266-
documentElementId: row.elementId,
267-
profileNodeId: row.type ? this.signatureElementsStore.signs[row.type]?.file.nodeId : undefined,
268-
}]
269-
: [])
270-
} else {
271-
payload.elements = this.elements.flatMap((row) => typeof row.elementId === 'number'
272-
? [{
273-
documentElementId: row.elementId,
274-
}]
275-
: [])
262+
const myEnvelopeSigners = this.signStore.document?.nodeType === 'envelope'
263+
? (this.signStore.document?.signers ?? [])
264+
.filter((s): s is NonNullable<typeof s> & { signRequestId: number; sign_request_uuid: string } =>
265+
s.me === true && typeof s.sign_request_uuid === 'string')
266+
: []
267+
268+
if (myEnvelopeSigners.length > 0) {
269+
let anySigningInProgress = false
270+
let lastResult: SignResult | null = null
271+
272+
for (const signer of myEnvelopeSigners) {
273+
const filePayload: SubmitSignaturePayload = { ...basePayload }
274+
const fileElements = (this.elements ?? []).filter((el) => el.signRequestId === signer.signRequestId)
275+
if (fileElements.length > 0) {
276+
if (this.canCreateSignature) {
277+
filePayload.elements = fileElements.flatMap((row) => typeof row.elementId === 'number'
278+
? [{
279+
documentElementId: row.elementId,
280+
profileNodeId: row.type ? this.signatureElementsStore.signs[row.type]?.file.nodeId : undefined,
281+
}]
282+
: [])
283+
} else {
284+
filePayload.elements = fileElements.flatMap((row) => typeof row.elementId === 'number'
285+
? [{
286+
documentElementId: row.elementId,
287+
}]
288+
: [])
289+
}
290+
}
291+
lastResult = await this.signStore.submitSignature(filePayload, signer.sign_request_uuid, {
292+
documentId: this.signStore.document.id,
293+
})
294+
if (lastResult.status === 'signingInProgress') {
295+
anySigningInProgress = true
296+
}
276297
}
277-
}
278298
279-
const result = await this.signStore.submitSignature(payload, this.signRequestUuid, {
280-
documentId: this.signStore.document.id,
281-
})
299+
if (anySigningInProgress) {
300+
this.actionHandler.closeModal(methodConfig.modalCode || methodConfig.method || 'token')
301+
this.$emit('signing-started', {
302+
signRequestUuid: myEnvelopeSigners[0].sign_request_uuid,
303+
async: true,
304+
})
305+
} else if (lastResult?.status === 'signed') {
306+
this.actionHandler.closeModal(methodConfig.modalCode || methodConfig.method || 'token')
307+
this.sidebarStore.hideSidebar()
308+
this.$emit('signed', {
309+
...lastResult.data,
310+
signRequestUuid: myEnvelopeSigners[0].sign_request_uuid,
311+
})
312+
}
313+
} else {
314+
const payload = { ...basePayload }
315+
if (this.elements?.length > 0) {
316+
if (this.canCreateSignature) {
317+
payload.elements = this.elements.flatMap((row) => typeof row.elementId === 'number'
318+
? [{
319+
documentElementId: row.elementId,
320+
profileNodeId: row.type ? this.signatureElementsStore.signs[row.type]?.file.nodeId : undefined,
321+
}]
322+
: [])
323+
} else {
324+
payload.elements = this.elements.flatMap((row) => typeof row.elementId === 'number'
325+
? [{
326+
documentElementId: row.elementId,
327+
}]
328+
: [])
329+
}
330+
}
282331
283-
if (result.status === 'signingInProgress') {
284-
this.actionHandler.closeModal(methodConfig.modalCode || methodConfig.method || 'token')
285-
this.$emit('signing-started', {
286-
signRequestUuid: this.signRequestUuid,
287-
async: true,
288-
})
289-
} else if (result.status === 'signed') {
290-
this.actionHandler.closeModal(methodConfig.modalCode || methodConfig.method || 'token')
291-
this.sidebarStore.hideSidebar()
292-
this.$emit('signed', {
293-
...result.data,
294-
signRequestUuid: this.signRequestUuid,
332+
const result = await this.signStore.submitSignature(payload, this.signRequestUuid, {
333+
documentId: this.signStore.document.id,
295334
})
335+
336+
if (result.status === 'signingInProgress') {
337+
this.actionHandler.closeModal(methodConfig.modalCode || methodConfig.method || 'token')
338+
this.$emit('signing-started', {
339+
signRequestUuid: this.signRequestUuid,
340+
async: true,
341+
})
342+
} else if (result.status === 'signed') {
343+
this.actionHandler.closeModal(methodConfig.modalCode || methodConfig.method || 'token')
344+
this.sidebarStore.hideSidebar()
345+
this.$emit('signed', {
346+
...result.data,
347+
signRequestUuid: this.signRequestUuid,
348+
})
349+
}
296350
}
297351
} catch (error: unknown) {
298352
const signError = typeof error === 'object' && error !== null ? error as SignSubmissionError : {}
@@ -611,53 +665,108 @@ let submitSignature = async (methodConfig: SignatureMethodConfig = {}) => {
611665
signStore.clearSigningErrors()
612666
613667
try {
614-
const payload: SubmitSignaturePayload = {
668+
const basePayload: SubmitSignaturePayload = {
615669
method: methodConfig.method,
616670
}
617671
618672
if (methodConfig.token) {
619-
payload.token = methodConfig.token
673+
basePayload.token = methodConfig.token
620674
}
621675
622-
if (elements.value.length > 0) {
623-
if (canCreateSignature.value) {
624-
payload.elements = elements.value.flatMap((row) => typeof row.elementId === 'number'
625-
? [{
626-
documentElementId: row.elementId,
627-
profileNodeId: row.type ? signatureElementsStore.signs[row.type]?.file.nodeId : undefined,
628-
}]
629-
: [])
630-
} else {
631-
payload.elements = elements.value.flatMap((row) => typeof row.elementId === 'number'
632-
? [{
633-
documentElementId: row.elementId,
634-
}]
635-
: [])
676+
const myEnvelopeSigners = signStore.document?.nodeType === 'envelope'
677+
? (signStore.document?.signers ?? [])
678+
.filter((s): s is NonNullable<typeof s> & { signRequestId: number; sign_request_uuid: string } =>
679+
s.me === true && typeof s.sign_request_uuid === 'string')
680+
: []
681+
682+
if (myEnvelopeSigners.length > 0) {
683+
let anySigningInProgress = false
684+
let lastResult: SignResult | null = null
685+
686+
for (const signer of myEnvelopeSigners) {
687+
const filePayload: SubmitSignaturePayload = { ...basePayload }
688+
const fileElements = elements.value.filter((el) => el.signRequestId === signer.signRequestId)
689+
if (fileElements.length > 0) {
690+
if (canCreateSignature.value) {
691+
filePayload.elements = fileElements.flatMap((row) => typeof row.elementId === 'number'
692+
? [{
693+
documentElementId: row.elementId,
694+
profileNodeId: row.type ? signatureElementsStore.signs[row.type]?.file.nodeId : undefined,
695+
}]
696+
: [])
697+
} else {
698+
filePayload.elements = fileElements.flatMap((row) => typeof row.elementId === 'number'
699+
? [{
700+
documentElementId: row.elementId,
701+
}]
702+
: [])
703+
}
704+
}
705+
lastResult = await signStore.submitSignature(filePayload, signer.sign_request_uuid, {
706+
documentId: signStore.document.id,
707+
})
708+
if (lastResult.status === 'signingInProgress') {
709+
anySigningInProgress = true
710+
}
636711
}
637-
}
638712
639-
const result = await signStore.submitSignature(
640-
payload,
641-
signRequestUuid.value,
642-
{
643-
documentId: signStore.document.id,
644-
},
645-
)
713+
ensureServices()
714+
if (anySigningInProgress) {
715+
actionHandler!.closeModal(methodConfig.modalCode || methodConfig.method || 'token')
716+
emit('signing-started', {
717+
signRequestUuid: myEnvelopeSigners[0].sign_request_uuid,
718+
async: true,
719+
})
720+
} else if (lastResult?.status === 'signed') {
721+
actionHandler!.closeModal(methodConfig.modalCode || methodConfig.method || 'token')
722+
sidebarStore.hideSidebar()
723+
emit('signed', {
724+
...lastResult.data,
725+
signRequestUuid: myEnvelopeSigners[0].sign_request_uuid,
726+
})
727+
}
728+
} else {
729+
const payload = { ...basePayload }
730+
if (elements.value.length > 0) {
731+
if (canCreateSignature.value) {
732+
payload.elements = elements.value.flatMap((row) => typeof row.elementId === 'number'
733+
? [{
734+
documentElementId: row.elementId,
735+
profileNodeId: row.type ? signatureElementsStore.signs[row.type]?.file.nodeId : undefined,
736+
}]
737+
: [])
738+
} else {
739+
payload.elements = elements.value.flatMap((row) => typeof row.elementId === 'number'
740+
? [{
741+
documentElementId: row.elementId,
742+
}]
743+
: [])
744+
}
745+
}
646746
647-
ensureServices()
648-
if (result.status === 'signingInProgress') {
649-
actionHandler!.closeModal(methodConfig.modalCode || methodConfig.method || 'token')
650-
emit('signing-started', {
651-
signRequestUuid: signRequestUuid.value,
652-
async: true,
653-
})
654-
} else if (result.status === 'signed') {
655-
actionHandler!.closeModal(methodConfig.modalCode || methodConfig.method || 'token')
656-
sidebarStore.hideSidebar()
657-
emit('signed', {
658-
...result.data,
659-
signRequestUuid: signRequestUuid.value,
660-
})
747+
const result = await signStore.submitSignature(
748+
payload,
749+
signRequestUuid.value,
750+
{
751+
documentId: signStore.document.id,
752+
},
753+
)
754+
755+
ensureServices()
756+
if (result.status === 'signingInProgress') {
757+
actionHandler!.closeModal(methodConfig.modalCode || methodConfig.method || 'token')
758+
emit('signing-started', {
759+
signRequestUuid: signRequestUuid.value,
760+
async: true,
761+
})
762+
} else if (result.status === 'signed') {
763+
actionHandler!.closeModal(methodConfig.modalCode || methodConfig.method || 'token')
764+
sidebarStore.hideSidebar()
765+
emit('signed', {
766+
...result.data,
767+
signRequestUuid: signRequestUuid.value,
768+
})
769+
}
661770
}
662771
} catch (error: unknown) {
663772
const signError = isSignSubmissionError(error) ? error : {}

0 commit comments

Comments
 (0)