- Add isDocMdpNoChangesAllowed() method to files store
- Update canAddSigner() to check DocMDP level 1 with existing signers
- Only blocks after first signer is added (not before)
- Encapsulates logic in reusable method
Signed-off-by: Vitor Mattos <1079143+vitormattos@users.noreply.github.com>
- Add docmdp_level to SELECT and GROUP BY in SignRequestMapper
- Format docmdpLevel as integer in API response
- Add docmdpLevel to FileService::loadLibreSignData()
- Ensures frontend receives per-file DocMDP configuration
Signed-off-by: Vitor Mattos <1079143+vitormattos@users.noreply.github.com>
- Update validateDocMdpAllowsSignatures() to check file's docmdpLevel first
- Falls back to PDF extraction for legacy files (level 0)
- Throws consistent error message for DocMDP level 1
- Prevents adding signatures to certified documents with no changes allowed
Signed-off-by: Vitor Mattos <1079143+vitormattos@users.noreply.github.com>
- Add DocMdpConfigService dependency to RequestSignatureService
- Create setDocMdpLevelFromGlobalConfig() method
- Save admin DocMDP configuration to file entity on creation
- Allows per-file DocMDP configuration instead of only global
Signed-off-by: Vitor Mattos <1079143+vitormattos@users.noreply.github.com>
Removed IAppConfig mock from test setup to match updated
service constructor signature.
Signed-off-by: Vitor Mattos <1079143+vitormattos@users.noreply.github.com>
IAppConfig was injected but never used in any method.
Removed dependency to clean up constructor.
Signed-off-by: Vitor Mattos <1079143+vitormattos@users.noreply.github.com>
Updated tests to inject FileStatusService and SignRequestStatusService
mocks. Added specific tests validating parallel and ordered flow
behavior with correct parameter ordering for determineInitialStatus.
Signed-off-by: Vitor Mattos <1079143+vitormattos@users.noreply.github.com>
Created test suite with 53 tests validating business rules for sign
request status determination. Covers notification scenarios, status
updates, and initial status calculation based on file status, signer
status, signing order, and flow type. Uses PHP 8 DataProvider
attributes for parameterized testing.
Signed-off-by: Vitor Mattos <1079143+vitormattos@users.noreply.github.com>
Created test suite with 23 tests covering all file status upgrade
scenarios and notification validation. Uses PHP 8 DataProvider
attributes for parameterized testing.
Signed-off-by: Vitor Mattos <1079143+vitormattos@users.noreply.github.com>
Injected FileStatusService and SignRequestStatusService to delegate
all status-related operations. Removed status determination methods
and notification validation logic, delegating to specialized services.
Updated method calls to use appropriate service methods.
Signed-off-by: Vitor Mattos <1079143+vitormattos@users.noreply.github.com>
Created dedicated service to manage sign request status determination
and validation. Implements shouldNotifySignRequest, canNotifySignRequest,
updateStatusIfAllowed, determineInitialStatus, and private helper methods
for status calculation based on file status, signer status, signing order,
and flow type (parallel/sequential).
Signed-off-by: Vitor Mattos <1079143+vitormattos@users.noreply.github.com>
Created dedicated service to handle file status management.
Includes updateFileStatusIfUpgrade to upgrade file status and
canNotifySigners to validate if file status allows notifications.
Signed-off-by: Vitor Mattos <1079143+vitormattos@users.noreply.github.com>
The RequestSignatureService constructor was updated to require 18 parameters
including IEventDispatcher, but the test was only passing 17 parameters.
This commit adds the missing mock dependency to fix all failing tests.
Signed-off-by: Vitor Mattos <1079143+vitormattos@users.noreply.github.com>
Extracts the SignRequestCanceledEvent dispatching logic from
unassociateToUser into a dedicated dispatchCancellationEventIfNeeded
method for better code organization and single responsibility.
Signed-off-by: Vitor Mattos <1079143+vitormattos@users.noreply.github.com>
Changes default values for email and push notifications to false
in LibresignActivitySettings, ensuring all LibreSign activity types
follow the same pattern and respect user opt-in preference.
Signed-off-by: Vitor Mattos <1079143+vitormattos@users.noreply.github.com>
Adds the SignRequestCanceled setting and provider to the
activity section of info.xml, making it available in the
Nextcloud activity system.
Signed-off-by: Vitor Mattos <1079143+vitormattos@users.noreply.github.com>
Registers all three listeners (Notification, Mail, and Activity)
for the SignRequestCanceledEvent in the application bootstrap.
Signed-off-by: Vitor Mattos <1079143+vitormattos@users.noreply.github.com>
Registers the cancellation event in the activity stream,
allowing users to see signature request cancellations
in their activity history.
Signed-off-by: Vitor Mattos <1079143+vitormattos@users.noreply.github.com>
Implements email notification for canceled signature requests.
Sends email to users informing them that their signature
request has been canceled.
Signed-off-by: Vitor Mattos <1079143+vitormattos@users.noreply.github.com>
Implements the notification message formatting in Notifier
to display cancellation notifications with proper subject
and message text.
Signed-off-by: Vitor Mattos <1079143+vitormattos@users.noreply.github.com>
Implements the notification handler for canceled signature requests.
Sends in-app notifications to users when their signature request
is canceled, respecting user activity settings preferences.
Signed-off-by: Vitor Mattos <1079143+vitormattos@users.noreply.github.com>
Creates the Activity components for the cancellation notification:
- SignRequestCanceled settings class
- SignRequestCanceled provider for activity stream
Signed-off-by: Vitor Mattos <1079143+vitormattos@users.noreply.github.com>
When a signature request with status ABLE_TO_SIGN is deleted,
dispatch the SignRequestCanceledEvent for each identify method.
This allows notification and email listeners to inform users
about the cancellation.
Signed-off-by: Vitor Mattos <1079143+vitormattos@users.noreply.github.com>
This event is dispatched when a signature request is canceled,
allowing listeners to send notifications to the affected user.
Signed-off-by: Vitor Mattos <1079143+vitormattos@users.noreply.github.com>
Added confirmation dialogs before sending signature requests to improve
user awareness and prevent accidental submissions.
Changes:
- Added confirmation dialog for global 'Request signatures' button
- Added confirmation dialog for individual signer 'Request signature' action
- Created confirmRequest() and confirmRequestSigner() methods
- Added state management: showConfirmRequest, showConfirmRequestSigner, selectedSigner
- Modified request() to show confirmation instead of directly executing
- Modified requestSignatureForSigner() to show confirmation and store selected signer
The confirmation dialogs use NcDialog with @closing event for proper
closing behavior when user clicks X, ESC, or Cancel button.
Signed-off-by: Vitor Mattos <1079143+vitormattos@users.noreply.github.com>
The button in the signature positions modal now always shows 'Save'
instead of conditionally showing 'Send' or 'Save' based on draft status.
Changes:
- Button always calls save() method without changing status
- Removed confirmation dialog (showConfirm) from VisibleElements
- Removed request() method that was changing status to ABLE_TO_SIGN
- Removed unused Send icon component import
- Simplified button logic by removing isDraft condition
This improves UX by making the modal's purpose clear: it's for
positioning signatures, not for requesting them.
Signed-off-by: Vitor Mattos <1079143+vitormattos@users.noreply.github.com>
The 'Request signatures' button now appears conditionally based on signing flow:
- Parallel flow: Shows when any signer has DRAFT status (status === 0)
- Sequential flow: Shows only when current signing order has draft signers
- Finds the lowest pending order among unsigned signers
- Checks if that order contains any draft signers
This prevents requesting signatures from signers who aren't in their turn yet
in sequential signing, while maintaining flexibility in parallel signing.
Refactored logic into smaller, focused methods:
- hasAnyDraftSigner: Checks for any draft signer (parallel mode)
- hasSequentialDraftSigners: Orchestrates sequential mode verification
- getCurrentSigningOrder: Gets current order that should sign
- hasOrderDraftSigners: Checks if specific order has draft signers
Signed-off-by: Vitor Mattos <1079143+vitormattos@users.noreply.github.com>
Added two unit tests to validate status determination logic:
1. testParallelFlowIgnoresSignerDraftStatusWhenFileIsAbleToSign:
Validates that in parallel flow, all signers are set to ABLE_TO_SIGN
when file status is ABLE_TO_SIGN, ignoring individual DRAFT status
sent by frontend.
2. testOrderedFlowRespectsSigningOrderWhenFileIsAbleToSign:
Validates that in ordered flow, only the first signer (order 1)
gets ABLE_TO_SIGN status, while subsequent signers remain DRAFT
until their turn.
Also updated getService() method to accept optional
SequentialSigningService parameter for testing different flows.
Signed-off-by: Vitor Mattos <1079143+vitormattos@users.noreply.github.com>
When file status is ABLE_TO_SIGN (1) in parallel flow, all signers
should be set to ABLE_TO_SIGN regardless of individual signer status
sent by frontend. This fixes the issue where signers remained in DRAFT
status (0) even after clicking 'Request signatures'.
The logic now:
1. Check file status DRAFT first - keep all signers as DRAFT
2. Check file status ABLE_TO_SIGN - apply flow-based logic:
- Parallel: All signers get ABLE_TO_SIGN
- Ordered: Only first signer gets ABLE_TO_SIGN
3. Fallback to individual signer status for other cases
Resolves issue where sign_request records stayed at status 0 while
libresign_file was updated to status 1.
Signed-off-by: Vitor Mattos <1079143+vitormattos@users.noreply.github.com>