WARNING: THIS SITE IS A MIRROR OF GITHUB.COM / IT CANNOT LOGIN OR REGISTER ACCOUNTS / THE CONTENTS ARE PROVIDED AS-IS / THIS SITE ASSUMES NO RESPONSIBILITY FOR ANY DISPLAYED CONTENT OR LINKS / IF YOU FOUND SOMETHING MAY NOT GOOD FOR EVERYONE, CONTACT ADMIN AT ilovescratch@foxmail.com
Skip to content

Conversation

@vitormattos
Copy link
Member

No description provided.

@vitormattos vitormattos added this to the Next Major (33) milestone Dec 19, 2025
@vitormattos vitormattos self-assigned this Dec 19, 2025
@github-project-automation github-project-automation bot moved this to 0. Needs triage in Roadmap Dec 19, 2025
@vitormattos vitormattos force-pushed the feature/envelope-support branch from 6d91725 to 7f6910b Compare December 19, 2025 23:40
Signed-off-by: Vitor Mattos <[email protected]>
- Create new FileUploadHelper with validateUploadedFile() and readUploadedFile()
- Centralizes upload validation (error check, is_uploaded_file, filename validation, size check)
- Automatic cleanup (@Unlink) before throwing exceptions
- Comprehensive unit tests with 7 test cases covering all edge cases
- Mock is_uploaded_file() via namespace for testing
- Follows Nextcloud core patterns (AvatarControllerTest)

Signed-off-by: Vitor Mattos <[email protected]>
- Add validateEnvelopeConstraints() method for business rule validation
- Validate envelope_enabled and envelope_max_files before processing files
- Fix uploadHelper property conflict with TFile trait
- Improves separation of concerns: FileService owns validation logic

Signed-off-by: Vitor Mattos <[email protected]>
- Import OCP\Files\Node for proper type resolution
- Fix Psalm docblock type annotations
- Use fully qualified namespace in return types

Signed-off-by: Vitor Mattos <[email protected]>
- Remove duplicate fileName extraction logic in saveFiles
- Let prepareFileForSaving handle all name extraction
- Fix Psalm type annotations with fully qualified namespaces
- Add inline @var annotation for  parameter type

Signed-off-by: Vitor Mattos <[email protected]>
- Add FileUploadHelper mock to AccountServiceTest
- Add FileUploadHelper instance to FileServiceTest
- Add FileUploadHelper mock to IdDocsServiceTest
- Replace FileService with FileUploadHelper in RequestSignatureServiceTest
- All services now correctly inject FileUploadHelper dependency

Signed-off-by: Vitor Mattos <[email protected]>
- Generate folderName once in saveEnvelope() using envelope UUID
- Pass same folderName to all files via settings
- Pattern: envelope-{uuid} ensures uniqueness across envelopes
- All files in an envelope now go to the same folder

Signed-off-by: Vitor Mattos <[email protected]>
- Changed property type from FileUploadHelper&MockObject to FileUploadHelper
- Use \OCP\Server::get(FileUploadHelper::class) to get real instance
- Fixes 'File is too big' test that requires actual validation logic
- All 105 FileServiceTest tests now passing

Signed-off-by: Vitor Mattos <[email protected]>
- Suppress file_get_contents warning in FileUploadHelper::readUploadedFile()
- Fix risky test in FileUploadHelperTest::testValidateUploadedFileWithForbiddenName
- Add explicit escape parameter to str_getcsv in FooterHandlerTest (PHP 8.4 compat)
- Tests now properly skip when OS-specific conditions aren't met

Signed-off-by: Vitor Mattos <[email protected]>
Expose file validation without node creation, allowing controllers
to validate uploaded files before deciding the file creation strategy.

Signed-off-by: Vitor Mattos <[email protected]>
Changed processUploadedFiles to only validate and return file data
instead of creating nodes immediately. This ensures nodes are created
with the correct envelope folder path in saveEnvelope.

- processUploadedFiles now returns uploadedFile data structure
- Node creation moved to RequestSignatureService.saveEnvelope
- Fixed return type annotation to include uploadedFile field

Signed-off-by: Vitor Mattos <[email protected]>
Envelope creation now ensures atomicity:
- Generate envelope UUID and folderName before creating nodes
- Create nodes with correct settings containing folderName
- Rollback all changes (nodes, files, envelope) on any error

Added dedicated rollback methods:
- rollbackEnvelopeCreation: orchestrates complete rollback
- rollbackCreatedNodes: removes filesystem nodes
- rollbackCreatedFiles: removes file entities from database
- rollbackEnvelope: removes envelope entity from database

This prevents partial envelope creation and ensures data consistency.

Signed-off-by: Vitor Mattos <[email protected]>
- Validate envelope_enabled config before creating envelopes
- Throw descriptive exception when feature is disabled
- Keep original error message for maximum files exceeded

Signed-off-by: Vitor Mattos <[email protected]>
Update expected message to match actual error message:
'Maximum number of files per envelope (2) exceeded'

Signed-off-by: Vitor Mattos <[email protected]>
Detect and delegate uploadedFile processing to getNodeFromUploadedFile
method instead of trying to extract base64 from non-existent file data.
This fixes TypeError when uploading single files via file upload.

Signed-off-by: Vitor Mattos <[email protected]>
Added handling for uploadedFile case in prepareFileForSaving method.
When a single file is uploaded via file upload, it now correctly
validates and creates the node using the uploadedFile data.

Also fixed list endpoint to skip envelopes when loading user settings,
preventing 'File not found' errors for envelope nodes.

Signed-off-by: Vitor Mattos <[email protected]>
Add envelope_enabled to initial state in PageController and
TemplateLoader, allowing frontend components to respect the
administrative configuration for envelope support.

This enables proper control of multiple file uploads based on
whether the envelope feature is enabled or disabled.

Signed-off-by: Vitor Mattos <[email protected]>
Load envelope_enabled from initial state and use it to control
whether multiple file selection is allowed in the upload dialog.

When envelope feature is disabled, only single file uploads are
permitted. When enabled, users can select multiple files to create
an envelope.

Signed-off-by: Vitor Mattos <[email protected]>
- Changed getThumbnail to use fileMapper->getByFileId instead of fileService->getMyLibresignFile
- getMyLibresignFile depends on signRequestMapper which requires sign requests to exist
- DRAFT files without signers were returning 404 on thumbnail endpoint
- Now uses direct file lookup with ownership verification

Signed-off-by: Vitor Mattos <[email protected]>
- Added FolderIcon component to FileEntryPreview
- Envelopes now show folder icon instead of file icon or thumbnail
- Added isEnvelope computed property to check source.isEnvelope
- Backend already sends isEnvelope flag in SignRequestMapper::formatListRow

Signed-off-by: Vitor Mattos <[email protected]>
- Add validateEnvelopeConstraints(int $fileCount) method
  - Validates envelope_enabled configuration
  - Validates file count against maximum allowed
  - Throws LibresignException with descriptive messages

- Add getMaxFilesPerEnvelope() helper method
  - Reads envelope_max_files from app config
  - Returns default value of 50 if not configured
  - Single source of truth for max files limit

- Refactor addFileToEnvelope() to use getMaxFilesPerEnvelope()
  - Removes hardcoded '50' value
  - Uses centralized configuration method

This establishes EnvelopeService as the single source of truth for
all envelope-related validation and configuration.

Signed-off-by: Vitor Mattos <[email protected]>
- Use EnvelopeService.validateEnvelopeConstraints() in saveEnvelope()
  - Replaces inline validation logic
  - Centralizes all envelope validation

- Add processFileData() helper method
  - Handles both uploadedFile and URL file types
  - Uses TFile trait's getNodeFromData()
  - Centralizes file node creation logic

- Refactor saveEnvelope() file processing loop
  - Process file to create node first
  - Preserve original fileData by adding node reference
  - Pass complete fileData to createFileForEnvelope()
  - Ensures rollback can clean up all created nodes

This improves code organization and ensures atomic envelope
creation with proper rollback on errors.

Signed-off-by: Vitor Mattos <[email protected]>
Remove validateEnvelopeConstraints() call from processUploadedFilesWithRollback()
- Method is not used in envelope creation flow
- Envelope validation happens in RequestSignatureService.saveEnvelope()
- Avoids duplicate validation logic

This follows single responsibility principle: envelope validation
belongs in EnvelopeService and is called from envelope-specific
methods, not from general file processing utilities.

Signed-off-by: Vitor Mattos <[email protected]>
Use nodeType field directly instead of creating a derived isEnvelope boolean.
The nodeType field already provides this information with value 'envelope'.

This simplifies the response structure and avoids data redundancy.

Signed-off-by: Vitor Mattos <[email protected]>
Create standalone dialog component for editing names with:
- Character counter (0-255 chars)
- Min/max length validation (3-255 chars)
- Success/error message display
- Disabled save button for invalid input
- Generic and reusable for various use cases

The component encapsulates all validation logic, styling,
and event handling, allowing reuse across RequestPicker
and other parts of the application.

Signed-off-by: Vitor Mattos <[email protected]>
Replace inline NcDialog form with reusable EditNameDialog component:
- Removes duplicate code (~17 lines)
- Adds consistent validation (3-255 chars)
- Improves UX with character counter and validation feedback
- Simplifies confirmEnvelopeName to receive name as parameter

Maintains all existing functionality while improving code
maintainability and user experience.

Signed-off-by: Vitor Mattos <[email protected]>
Implement inline envelope name editing in EnvelopeFilesList with:
- Direct NcTextField in header (no modal needed)
- 1-second debounce for auto-save
- Real-time validation (3-255 chars)
- Inline feedback (success/error states)
- Loading indicator during save
- Helper text for validation messages

User experience improvements:
- Edit name directly without clicking edit button
- Automatic save after typing stops
- Immediate visual feedback on success/error
- No need to manually trigger save action

Replaces modal-based editing for more fluid UX.

Signed-off-by: Vitor Mattos <[email protected]>
Signed-off-by: Vitor Mattos <[email protected]>
- Add async rename(uuid, newName) method
- Makes PATCH request to /apps/libresign/api/v1/request-signature
- Updates file name in store on success
- Returns boolean indicating success/failure

Signed-off-by: Vitor Mattos <[email protected]>
- Add conditional rendering of rename form with NcTextField
- Implement startRenaming() to activate form with auto-focus and text selection
- Implement stopRenaming() to close form and reset state
- Implement onRename() to validate and emit rename event
- Add renaming event to notify parent components about editing state
- Add styling for inline rename form with border and padding

Signed-off-by: Vitor Mattos <[email protected]>
- Import pencil-outline icon (mdi-pencil-outline)
- Register 'rename' action in mounted hook
- Add rename action handler in onActionClick to emit 'start-rename' event
- Implement doRename(newName) method that calls filesStore.rename()
- Add 'rename' and 'start-rename' to component emits

Signed-off-by: Vitor Mattos <[email protected]>
- Add renamingSaving state to show spinner only during API request
- Listen to 'rename' event from FileEntryName and trigger doRename()
- Listen to 'renaming' event from FileEntryName to track editing state
- Listen to 'start-rename' event from FileEntryActions to activate form
- Close rename form after successful save with stopRenaming()
- Show success notification with renamed filename information
- Update checkbox loading state to include renamingSaving indicator

Signed-off-by: Vitor Mattos <[email protected]>
…ition NcActions using CSS vars on .app-content (non-scoped transform)\n- Constrain popper with boundaries/container to .app-content > .files-list\n- Clear --mouse-pos-x/y on NcActions @closed only when no menu open\n- Close previous menu and reopen on nextTick to avoid stale content\n\nfix(actions): hide "Open file" for envelopes; DRY file lookup\n\n- Do not show "Open file" when source.nodeType is envelope\n- Add computed file and refactor visibleIf to reuse it\n\nMatches Nextcloud Files behavior and prevents flicker/jump.

Signed-off-by: Vitor Mattos <[email protected]>
@vitormattos vitormattos requested a review from Copilot December 29, 2025 04:54
Copy link

Copilot AI left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

This PR introduces comprehensive support for envelopes in LibreSign, enabling users to group multiple PDF files into a single signing workflow. The implementation spans backend services, API controllers, database models, frontend components, and test coverage.

Key changes:

  • Added envelope creation, validation, and management functionality with draft status restrictions
  • Introduced new database entities and services to handle envelope-specific operations
  • Implemented frontend components for envelope validation and file management
  • Enhanced API endpoints to support envelope operations and multi-file uploads
  • Added comprehensive unit and integration test coverage for envelope features

Reviewed changes

Copilot reviewed 125 out of 132 changed files in this pull request and generated no comments.

Show a summary per file
File Description
tests/php/Unit/Service/FileElementServiceTest.php Tests for formatting visible elements with coordinate transformations
tests/php/Unit/Service/File/UploadProcessorTest.php Tests for file upload validation and rollback mechanisms
tests/php/Unit/Service/File/SignersLoaderTest.php Tests for loading signer data from certificate information
tests/php/Unit/Service/File/SettingsLoaderTest.php Tests for user settings and identification document status logic
tests/php/Unit/Service/File/PdfValidatorTest.php Tests for PDF validation using DocMDP handler
tests/php/Unit/Service/File/MimeServiceTest.php Tests for MIME type detection and extension mapping
tests/php/Unit/Service/File/MetadataLoaderTest.php Tests for loading file metadata with node ID precedence
tests/php/Unit/Service/File/MessagesLoaderTest.php Tests for loading user-facing messages based on settings
tests/php/Unit/Service/File/FileResponseOptionsTest.php Tests for file response option configuration
tests/php/Unit/Service/File/FileListServiceTest.php Tests for file list formatting with envelope support
tests/php/Unit/Service/File/FileContentProviderTest.php Tests for retrieving file content from various sources
tests/php/Unit/Service/File/EnvelopeProgressServiceTest.php Tests for computing envelope signing progress
tests/php/Unit/Service/File/EnvelopeAssemblerTest.php Tests for building envelope child data structures
tests/php/Unit/Service/File/CertificateChainServiceTest.php Tests for certificate chain retrieval and validation
tests/php/Unit/Service/File/AccountSettingsProviderTest.php Tests for user account settings retrieval
tests/php/Unit/Service/EnvelopeServiceTest.php Tests for envelope creation, validation, and file management
tests/php/Unit/Service/AccountServiceTest.php Added FileUploadHelper dependency
tests/php/Unit/Helper/ValidateHelperTest.php Updated method calls from getByFileId to getById
tests/php/Unit/Helper/FileUploadHelperTest.php Tests for file upload validation with custom is_uploaded_file
tests/php/Unit/Handler/FooterHandlerTest.php Fixed CSV parsing with escape character parameter
tests/php/Unit/Enum/NodeTypeTest.php Tests for NodeType enum envelope detection
tests/php/Unit/Db/FileTest.php Tests for envelope and parent relationship methods
tests/php/Unit/CapabilitiesTest.php Added EnvelopeService dependency
tests/php/Api/Controller/SignFileControllerTest.php Updated file ID references from nodeId to id
tests/php/Api/Controller/NotifyControllerTest.php Updated file ID reference in request body
tests/php/Api/Controller/FileElementControllerTest.php Added fileId parameter to requests
tests/php/Api/Controller/FileControllerTest.php Added comment about settings behavior
tests/integration/features/sign/cancel.feature Updated field references from NODE_ID to FILE_ID
tests/integration/features/page/sign_identify_account.feature Updated initial state from libresign-pdf to libresign-pdfs array
tests/integration/features/notification/custom_message_notification.feature Updated FILE_ID field reference
tests/integration/features/file/list.feature Updated field references from NODE_ID to FILE_ID
tests/integration/features/file/envelope.feature Comprehensive integration tests for envelope feature
src/views/Validation.vue Major refactoring to support envelope validation with child components
src/views/SignPDF/_partials/Sign.vue Added missing return statement
src/views/SignPDF/SignPDF.vue Enhanced to handle envelope PDFs and multi-file display
src/views/Settings/Settings.vue Added Envelope settings component
src/views/Settings/Envelope.vue New component for envelope feature configuration
src/views/Request.vue Updated selectedNodeId to selectedId
src/views/IncompleteCertification.vue Added null safety for getCurrentUser
src/views/FilesList/VirtualList.vue Updated key from nodeId to id
src/views/FilesList/FilesListTableHeaderActions.vue Updated variable names from nodeId to fileId
src/views/FilesList/FileEntry/* Multiple updates for rename functionality and envelope display
src/types/openapi/* Updated OpenAPI specifications with envelope types
src/store/signMethods.js Simplified settings structure and password validation
src/store/sign.js Updated to use id instead of nodeId throughout
src/store/files.js Major updates for envelope support and file management
src/components/validation/* New validation components for file and envelope display

…pe settings section with a switch to enable/disable envelopes (writes to app config key 'envelope_enabled').\n- Reads initial value from provisioning API and updates capabilities via backend check.\n- Matches existing settings patterns (NcCheckboxRadioSwitch, OCP.AppConfig).

Signed-off-by: Vitor Mattos <[email protected]>
Signed-off-by: Vitor Mattos <[email protected]>
Signed-off-by: Vitor Mattos <[email protected]>
@vitormattos vitormattos force-pushed the feature/envelope-support branch from 2e34ad8 to 8b2865a Compare December 29, 2025 04:59
@vitormattos
Copy link
Member Author

/backport to stable32

@vitormattos
Copy link
Member Author

/backport to stable31

@vitormattos vitormattos merged commit a541b1f into main Dec 29, 2025
57 of 66 checks passed
@vitormattos vitormattos deleted the feature/envelope-support branch December 29, 2025 13:41
@github-project-automation github-project-automation bot moved this from 0. Needs triage to 4. to release in Roadmap Dec 29, 2025
@vitormattos vitormattos restored the feature/envelope-support branch December 29, 2025 21:46
@vitormattos vitormattos deleted the feature/envelope-support branch December 30, 2025 00:06
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

Status: 4. to release

Development

Successfully merging this pull request may close these issues.

2 participants