@@ -348,6 +348,130 @@ public function testSignerIdentifiedAsCurrentUserHasUrlField(): void {
348348 $ this ->assertStringContainsString ('uuid-signer ' , $ result ['url ' ]);
349349 }
350350
351+ #[DataProvider('provideSignerUuidExposureScenarios ' )]
352+ public function testSignRequestUuidIsScopedToCurrentSigner (
353+ string $ currentUserId ,
354+ bool $ expectSignerScopedUuid ,
355+ ): void {
356+ $ file = self ::createFileEntity (1 , 'file ' , 'doc.pdf ' );
357+
358+ $ signer = $ this ->createSigner (100 , 1 );
359+ $ signer ->setUuid ('sign-request-uuid ' );
360+
361+ $ identifyMethod = $ this ->createIdentifyMethod (
362+ IdentifyMethodService::IDENTIFY_ACCOUNT ,
363+ 'signer-user '
364+ );
365+
366+ $ this ->user ->method ('getUID ' )->willReturn ($ currentUserId );
367+
368+ $ this ->signRequestMapper ->method ('getByMultipleFileId ' )->willReturn ([$ signer ]);
369+ $ this ->signRequestMapper ->method ('getIdentifyMethodsFromSigners ' )->willReturn ([100 => [$ identifyMethod ]]);
370+ $ this ->signRequestMapper ->method ('getVisibleElementsFromSigners ' )->willReturn ([]);
371+ $ this ->signRequestMapper ->method ('getTextOfSignerStatus ' )->willReturn ('pending ' );
372+
373+ if ($ expectSignerScopedUuid ) {
374+ $ this ->mockSignatureMethodsResolution ();
375+ $ this ->urlGenerator ->method ('linkToRoute ' )->willReturn ('https://example.com/sign?uuid=sign-request-uuid ' );
376+ }
377+
378+ $ service = $ this ->getService ();
379+ $ result = $ service ->formatSingleFile ($ this ->user , $ file );
380+
381+ $ this ->assertArrayNotHasKey ('signUuid ' , $ result );
382+ $ this ->assertCount (1 , $ result ['signers ' ]);
383+ $ this ->assertArrayNotHasKey ('sign_uuid ' , $ result ['signers ' ][0 ]);
384+
385+ if ($ expectSignerScopedUuid ) {
386+ $ this ->assertSame ('sign-request-uuid ' , $ result ['signers ' ][0 ]['sign_request_uuid ' ]);
387+ $ this ->assertArrayHasKey ('url ' , $ result );
388+ $ this ->assertStringContainsString ('sign-request-uuid ' , $ result ['url ' ]);
389+ return ;
390+ }
391+
392+ $ this ->assertArrayNotHasKey ('sign_request_uuid ' , $ result ['signers ' ][0 ]);
393+ }
394+
395+ public static function provideSignerUuidExposureScenarios (): array {
396+ return [
397+ 'current signer gets signer-scoped sign request uuid ' => ['signer-user ' , true ],
398+ 'other viewer does not get signer-scoped sign request uuid ' => ['other-user ' , false ],
399+ ];
400+ }
401+
402+ public function testDetailedFileDoesNotExposeSignRequestUuidAtRoot (): void {
403+ $ file = self ::createFileEntity (1 , 'file ' , 'doc.pdf ' );
404+
405+ $ signer = $ this ->createSigner (100 , 1 );
406+ $ signer ->setUuid ('sign-request-uuid ' );
407+
408+ $ identifyMethod = $ this ->createIdentifyMethod (
409+ IdentifyMethodService::IDENTIFY_ACCOUNT ,
410+ 'signer-user '
411+ );
412+
413+ $ this ->user ->method ('getUID ' )->willReturn ('signer-user ' );
414+
415+ $ this ->signRequestMapper ->method ('getByFileId ' )->willReturn ([$ signer ]);
416+ $ this ->signRequestMapper ->method ('getIdentifyMethodsFromSigners ' )->willReturn ([100 => [$ identifyMethod ]]);
417+ $ this ->signRequestMapper ->method ('getVisibleElementsFromSigners ' )->willReturn ([]);
418+ $ this ->signRequestMapper ->method ('getTextOfSignerStatus ' )->willReturn ('pending ' );
419+
420+ $ this ->mockSignatureMethodsResolution ();
421+ $ this ->urlGenerator ->method ('linkToRoute ' )->willReturn ('https://example.com/sign?uuid=sign-request-uuid ' );
422+
423+ $ service = $ this ->getService ();
424+ $ result = $ service ->formatFileWithChildren ($ file , [], $ this ->user );
425+
426+ $ this ->assertArrayNotHasKey ('signUuid ' , $ result );
427+ $ this ->assertSame ('sign-request-uuid ' , $ result ['signers ' ][0 ]['sign_request_uuid ' ]);
428+ $ this ->assertArrayNotHasKey ('sign_uuid ' , $ result ['signers ' ][0 ]);
429+ $ this ->assertArrayHasKey ('url ' , $ result );
430+ $ this ->assertStringContainsString ('sign-request-uuid ' , $ result ['url ' ]);
431+ }
432+
433+ public function testSummaryListDoesNotExposeSignRequestUuidAtRoot (): void {
434+ $ file = self ::createFileEntity (1 , 'file ' , 'doc.pdf ' );
435+
436+ $ signer = $ this ->createSigner (100 , 1 );
437+ $ signer ->setUuid ('sign-request-uuid ' );
438+
439+ $ identifyMethod = $ this ->createIdentifyMethod (
440+ IdentifyMethodService::IDENTIFY_ACCOUNT ,
441+ 'signer-user '
442+ );
443+
444+ $ this ->user ->method ('getUID ' )->willReturn ('signer-user ' );
445+ $ this ->appConfig ->method ('getValueInt ' )->willReturn (100 );
446+ $ this ->signRequestMapper ->method ('getFilesAssociatedFilesWithMe ' )->willReturn ([
447+ 'data ' => [$ file ],
448+ 'pagination ' => new class {
449+ public function setRouteName (string $ routeName ): void {
450+ }
451+
452+ public function getPagination (int $ page , int $ length , array $ filter ): array {
453+ return [
454+ 'total ' => 1 ,
455+ 'current ' => null ,
456+ 'next ' => null ,
457+ 'prev ' => null ,
458+ 'last ' => null ,
459+ 'first ' => null ,
460+ ];
461+ }
462+ },
463+ ]);
464+ $ this ->signRequestMapper ->method ('getByMultipleFileId ' )->willReturn ([$ signer ]);
465+ $ this ->signRequestMapper ->method ('getIdentifyMethodsFromSigners ' )->willReturn ([100 => [$ identifyMethod ]]);
466+ $ this ->fileMapper ->method ('getTextOfStatus ' )->willReturn ('Status text ' );
467+
468+ $ service = $ this ->getService ();
469+ $ result = $ service ->listAssociatedFilesOfSignFlow ($ this ->user , 1 , 100 , [], [], false );
470+
471+ $ this ->assertCount (1 , $ result ['data ' ]);
472+ $ this ->assertArrayNotHasKey ('signUuid ' , $ result ['data ' ][0 ]);
473+ }
474+
351475 public function testRequestedByIncludesUserDisplayName (): void {
352476 $ file = self ::createFileEntity (1 , 'file ' , 'doc.pdf ' );
353477 $ file ->setUserId ('creator-user ' );
@@ -601,4 +725,12 @@ private function createIdentifyMethod(string $key, string $value): \OCA\Libresig
601725 $ method ->setMandatory (true );
602726 return $ method ;
603727 }
728+
729+ private function mockSignatureMethodsResolution (): void {
730+ $ this ->identifyMethodService ->method ('setCurrentIdentifyMethod ' )->willReturnSelf ();
731+ $ this ->identifyMethodService ->method ('setIsRequest ' )->willReturnSelf ();
732+ $ mockIdentifyMethod = $ this ->createMock (\OCA \Libresign \Service \IdentifyMethod \IIdentifyMethod::class);
733+ $ mockIdentifyMethod ->method ('getSignatureMethods ' )->willReturn ([]);
734+ $ this ->identifyMethodService ->method ('getInstanceOfIdentifyMethod ' )->willReturn ($ mockIdentifyMethod );
735+ }
604736}
0 commit comments