Enable users to change signature flow when updating file if admin
has not enforced a specific flow mode.
Signed-off-by: Vitor Mattos <1079143+vitormattos@users.noreply.github.com>
Return null instead of default value to allow frontend
to detect when admin has not enforced a signature flow.
Signed-off-by: Vitor Mattos <1079143+vitormattos@users.noreply.github.com>
Update setSignatureFlowConfig to accept enabled parameter.
When disabled, the signature_flow config key is deleted,
allowing document creators to choose their preferred order.
Signed-off-by: Vitor Mattos <1079143+vitormattos@users.noreply.github.com>
- Changed CaIdentifierService to use system's instanceid from config.php
- Removed custom instance_id generation logic using ISecureRandom
- Updated unit tests to mock IConfig and verify correct instanceid usage
- This fixes race condition in certificate generation during integration tests
Signed-off-by: Vitor Mattos <1079143+vitormattos@users.noreply.github.com>
When Activity app doesn't know about LibreSign's notification settings
(common in test environments or fresh installations), we should allow
notifications by default instead of blocking them.
This fix checks if the Activity manager has the setting registered before
enforcing the admin setting. If the setting is not found, notifications
are allowed, respecting LibreSign's isDefaultEnabledMail() and
isDefaultEnabledNotification() which return true.
Fixes email and notification delivery in integration tests.
Signed-off-by: Vitor Mattos <1079143+vitormattos@users.noreply.github.com>
Include acceptsEmailNotifications field in search results for account
method signers. This field indicates whether a user accepts email
notifications based on both Activity admin settings and user
preferences. Returns false when user has no email, Activity app is
unavailable, or notifications are disabled at admin or user level.
Signed-off-by: Vitor Mattos <1079143+vitormattos@users.noreply.github.com>
Add description, displayName, notify, and acceptsEmailNotifications
fields to OpenAPI response type definitions for LibresignNewSigner
and LibresignIdentifyAccount.
Signed-off-by: Vitor Mattos <1079143+vitormattos@users.noreply.github.com>
Support custom signer descriptions in SMS, Signal, Telegram, WhatsApp,
and XMPP notifications. The description is prepended to the notification
message when provided, allowing personalized instructions through all
supported notification channels.
Signed-off-by: Vitor Mattos <1079143+vitormattos@users.noreply.github.com>
Add explicit check for Activity admin (global) setting before checking
user preference for in-app notifications. This ensures consistency
across all notification channels and prevents users from enabling
notifications when disabled globally by the admin.
Signed-off-by: Vitor Mattos <1079143+vitormattos@users.noreply.github.com>
Add explicit check for Activity admin (global) setting before checking
user preference in email notifications. This ensures that when an admin
disables email notifications globally, users cannot override it with
their personal settings. The admin setting acts as a gate that must be
enabled for user preferences to take effect.
Signed-off-by: Vitor Mattos <1079143+vitormattos@users.noreply.github.com>
Add optional description parameter to notifyUnsignedUser and
notifySignDataUpdated methods. When provided, the custom message is
prepended to the email body, allowing personalized instructions for
signers.
Signed-off-by: Vitor Mattos <1079143+vitormattos@users.noreply.github.com>
Include signer description in notification metadata when incrementing
notification counter. This allows tracking custom messages sent to
signers for each notification attempt.
Signed-off-by: Vitor Mattos <1079143+vitormattos@users.noreply.github.com>
Save user's selected tab (Account/Email) in the 'Add new signer' modal
to userconfig store. The preference is now persisted across modal
closures and page reloads, improving user experience by remembering
the last selected identification method.
Changes:
- Add activeTab state to RequestSignatureTab component
- Load saved tab preference from userconfig store on mount
- Save tab changes to backend with debounce (500ms)
- Add signer_identify_tab to AccountService config output
- Use snake_case naming convention for consistency with backend
Signed-off-by: Vitor Mattos <1079143+vitormattos@users.noreply.github.com>
The CA ID (libresign-ca-id:...) in OrganizationalUnit should only be
filtered out when the certificate is not generated (isSetupOk() returns
false). When the certificate is successfully generated, the CA ID must
be preserved in the API response.
This ensures:
- Generated certificates: CA ID is visible (expected behavior)
- Failed/not generated: CA ID is filtered to prevent stale data in form
Integration tests validated:
- features/account/signature.feature:2 (OpenSSL)
- features/account/signature.feature:23 (CFSSL)
- features/admin/certificate_openssl.feature:2
- features/admin/certificate_openssl.feature:35
Signed-off-by: Vitor Mattos <1079143+vitormattos@users.noreply.github.com>
Filter configPath from API response when certificate is not generated to prevent
form pre-population with outdated generation numbers that cause validation errors.
Filter CA ID (libresign-ca-id:*) from OrganizationalUnit field to prevent users
from submitting stale generation values that conflict with certificate validation.
Refactor toArray() method by extracting logic into dedicated methods:
- getConfigPathForApi(): Returns empty string for non-generated certificates
- removeCaIdFromOrganizationalUnit(): Filters CA IDs from OU arrays
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>
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>
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>
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>
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>
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>
When user provides a specific signing order, the next auto-assigned
order should be the provided value + 1.
Changed condition from > to >= and set currentOrder to userProvidedOrder + 1
instead of just userProvidedOrder.
This ensures proper order sequencing when mixing user-provided and
auto-assigned orders.
Signed-off-by: Vitor Mattos <1079143+vitormattos@users.noreply.github.com>
Add signatureFlow field to ValidateFile schema in OpenAPI specs and
ResponseDefinitions.
- Update openapi.json and openapi-full.json schemas
- Add signatureFlow to LibresignValidateFile psalm type
- Mark as required field with integer type
This fixes OpenAPI validation errors in API tests.
Signed-off-by: Vitor Mattos <1079143+vitormattos@users.noreply.github.com>
Move database value constants from File entity to SignatureFlow enum
where they belong as the single source of truth.
- Add SignatureFlow::NUMERIC_PARALLEL and NUMERIC_ORDERED_NUMERIC
- Remove circular dependency between File and SignatureFlow
- Update all references to use enum constants
- Use descriptive names instead of abbreviations
This follows single responsibility principle: the enum owns its
database representation.
Signed-off-by: Vitor Mattos <1079143+vitormattos@users.noreply.github.com>
Expose signature flow configuration in file list and detail endpoints.
FileService changes:
- Add signatureFlow to fileData object in formatFile()
SignRequestMapper changes:
- Include f.signature_flow in SELECT query
- Convert numeric value to enum string in formatListRow()
- Remove signature_flow from response (cleanup after conversion)
This enables frontend to display and use per-file signature flow
configuration.
Signed-off-by: Vitor Mattos <1079143+vitormattos@users.noreply.github.com>