From ca7339e078954ba066b5f8b047fcd509a4aaf60b Mon Sep 17 00:00:00 2001 From: Vitor Mattos <1079143+vitormattos@users.noreply.github.com> Date: Thu, 11 Dec 2025 17:04:55 -0300 Subject: [PATCH 1/2] fix: prevent signers from seeing files with DRAFT sign_request status Filter out sign_requests with status DRAFT (0) in the file list endpoint when the user is not the file owner. This ensures that signers do not see documents where their sign_request is in DRAFT status, unless they are the requester (owner) of the document. The filter is applied in the getFilesAssociatedFilesWithMeQueryBuilder method by adding conditions to exclude: - Files with status DRAFT (0) - Sign requests with status DRAFT (0) Only when the user is not the file owner (not matching f.user_id). This change affects only the /api/v1/file/list endpoint and does not impact other file access methods or signature flows. Ref: Security improvement to prevent premature document visibility Signed-off-by: Vitor Mattos <1079143+vitormattos@users.noreply.github.com> --- lib/Db/SignRequestMapper.php | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/lib/Db/SignRequestMapper.php b/lib/Db/SignRequestMapper.php index 8cd9d7eb3..0c8ad3ffd 100644 --- a/lib/Db/SignRequestMapper.php +++ b/lib/Db/SignRequestMapper.php @@ -528,7 +528,9 @@ class SignRequestMapper extends QBMapper { $qb->expr()->eq('f.user_id', $qb->createNamedParameter($userId)), $qb->expr()->andX( $qb->expr()->eq('im.identifier_key', $qb->createNamedParameter(IdentifyMethodService::IDENTIFY_ACCOUNT)), - $qb->expr()->eq('im.identifier_value', $qb->createNamedParameter($userId)) + $qb->expr()->eq('im.identifier_value', $qb->createNamedParameter($userId)), + $qb->expr()->neq('f.status', $qb->createNamedParameter(File::STATUS_DRAFT)), + $qb->expr()->neq('sr.status', $qb->createNamedParameter(SignRequestStatus::DRAFT->value)), ) ]; $qb->where($qb->expr()->orX(...$or))->andWhere($qb->expr()->isNull('id.id')); From adc396d52ee5193d813fed3a7beeae012b1dfb3f Mon Sep 17 00:00:00 2001 From: Vitor Mattos <1079143+vitormattos@users.noreply.github.com> Date: Thu, 11 Dec 2025 17:58:07 -0300 Subject: [PATCH 2/2] test: update sequential signing test to validate DRAFT filter Split the sequential signing test into two separate scenarios to better validate the DRAFT status filtering behavior: 1. First scenario: Tests that signer1 can see and sign the document (simpler flow without multiple user switches) 2. Second scenario: Tests that signer2 does NOT see the document when their sign_request is in DRAFT status This avoids multiple user context switches in the same scenario which was causing authentication issues in the Behat tests, and better isolates the behavior we want to validate. Signed-off-by: Vitor Mattos <1079143+vitormattos@users.noreply.github.com> --- .../features/sign/sequential_signing.feature | 27 +++++++++++-------- 1 file changed, 16 insertions(+), 11 deletions(-) diff --git a/tests/integration/features/sign/sequential_signing.feature b/tests/integration/features/sign/sequential_signing.feature index 2e2b80d4d..5bad17b86 100644 --- a/tests/integration/features/sign/sequential_signing.feature +++ b/tests/integration/features/sign/sequential_signing.feature @@ -43,21 +43,26 @@ Feature: sequential-signing | users | [{"identify":{"account":"signer1"},"signingOrder":1},{"identify":{"account":"signer2"},"signingOrder":2}] | | name | Sequential Document | Then the response should have a status code 200 - And as user "signer2" - And sending "get" to ocs "/apps/libresign/api/v1/file/list" - And the response should have a status code 200 - And fetch field "(SIGN_UUID_2)ocs.data.data.0.signers.1.sign_uuid" from previous JSON response - When sending "post" to ocs "/apps/libresign/api/v1/sign/uuid/" - | method | clickToSign | - Then the response should have a status code 422 - And as user "signer1" - And sending "get" to ocs "/apps/libresign/api/v1/file/list" - And the response should have a status code 200 + # Signer2 should NOT see the file yet (their sign_request is in DRAFT status) + Given as user "signer2" + When sending "get" to ocs "/apps/libresign/api/v1/file/list" + Then the response should have a status code 200 + And the response should be a JSON array with the following mandatory values + | key | value | + | (jq).ocs.data.data\|length | 0 | + # Signer1 can see and sign the document + Given as user "signer1" + When sending "get" to ocs "/apps/libresign/api/v1/file/list" + Then the response should have a status code 200 And fetch field "(SIGN_UUID_1)ocs.data.data.0.signers.0.sign_uuid" from previous JSON response When sending "post" to ocs "/apps/libresign/api/v1/sign/uuid/" | method | clickToSign | Then the response should have a status code 200 - And as user "signer2" + # After signer1 signs, signer2 should now see the file and be able to sign + Given as user "signer2" + When sending "get" to ocs "/apps/libresign/api/v1/file/list" + Then the response should have a status code 200 + And fetch field "(SIGN_UUID_2)ocs.data.data.0.signers.1.sign_uuid" from previous JSON response When sending "post" to ocs "/apps/libresign/api/v1/sign/uuid/" | method | clickToSign | Then the response should have a status code 200