From c9f2fa9feb43d45047ecf91951744ee15cc57470 Mon Sep 17 00:00:00 2001 From: Vitor Mattos <1079143+vitormattos@users.noreply.github.com> Date: Fri, 12 Dec 2025 14:46:24 -0300 Subject: [PATCH] fix: add ordering validation for signature request actions In ordered numeric signing flow, the frontend now validates that all lower-order signers have signed before showing 'Request signature' or 'Send reminder' buttons for higher-order signers. Changes: - Extract duplicate ordering validation logic into shared method canSignerActInOrder - Apply ordering validation to both canRequestSignature and canSendReminder computed properties - Move canSignerActInOrder to methods section (takes parameter) This prevents users from requesting signatures or sending reminders to signers out of turn when sequential signing is enabled. Signed-off-by: Vitor Mattos <1079143+vitormattos@users.noreply.github.com> --- .../RightSidebar/RequestSignatureTab.vue | 44 ++++++++++++++----- 1 file changed, 33 insertions(+), 11 deletions(-) diff --git a/src/Components/RightSidebar/RequestSignatureTab.vue b/src/Components/RightSidebar/RequestSignatureTab.vue index 9655dd5e4..0fdc4e6d3 100644 --- a/src/Components/RightSidebar/RequestSignatureTab.vue +++ b/src/Components/RightSidebar/RequestSignatureTab.vue @@ -263,20 +263,28 @@ export default { }, canRequestSignature() { return (signer) => { - return this.filesStore.canRequestSign - && !signer.signed - && signer.signRequestId - && !signer.me - && signer.status === 0 + if (!this.filesStore.canRequestSign + || signer.signed + || !signer.signRequestId + || signer.me + || signer.status !== 0) { + return false + } + + return this.canSignerActInOrder(signer) } }, canSendReminder() { return (signer) => { - return this.filesStore.canRequestSign - && !signer.signed - && signer.signRequestId - && !signer.me - && signer.status === 1 + if (!this.filesStore.canRequestSign + || signer.signed + || !signer.signRequestId + || signer.me + || signer.status !== 1) { + return false + } + + return this.canSignerActInOrder(signer) } }, showSaveButton() { @@ -353,6 +361,21 @@ export default { getSvgIcon(name) { return iconMap[`svg${name.charAt(0).toUpperCase() + name.slice(1)}`] || iconMap.svgAccount }, + canSignerActInOrder(signer) { + if (!this.isOrderedNumeric) { + return true + } + + const file = this.filesStore.getFile() + const signerOrder = signer.signingOrder || 1 + + const hasPendingLowerOrder = file.signers.some(s => { + const otherOrder = s.signingOrder || 1 + return otherOrder < signerOrder && !s.signed + }) + + return !hasPendingLowerOrder + }, enabledMethods() { return this.methods.filter(method => method.enabled) }, @@ -473,7 +496,6 @@ export default { await this.filesStore.updateSignatureRequest({ visibleElements: [], signers, - status: 1, }) showSuccess(t('libresign', 'Signature requested')) } catch (error) {