Skip to content

feat(identity): reject identification documents with reason and replacement - #9434

Draft
vitormattos wants to merge 7 commits into
mainfrom
feat/id-document-rejection-9370-20261110
Draft

vitormattos wants to merge 7 commits into
mainfrom
feat/id-document-rejection-9370-20261110

Conversation

@vitormattos

@vitormattos vitormattos commented Nov 10, 2026 •

Copy link
Copy Markdown
Member

Summary

Implements #9370 on top of the merged approval UX from #9360.

Reviewers can now reject an identification document with a required reason, rather than treating Delete as a rejection. The recorded decision retains the reviewer and date for auditing, allows the signer to upload a replacement, and does not cancel the original signing request.

Changes

  • Add a reviewer-only rejection endpoint with server-side authorization, input validation, pending-status checks, and atomic one-time audit persistence.
  • Store rejection time, reason, and reviewer on identification-document records; distinguish rejected history from active documents so replacement can proceed.
  • Present Reject alongside Review and approve, provide a reason dialog, expose a rejected status/filter, and show the reason to the affected signer.
  • Notify signers using the existing notification delivery/outbox machinery: email for reachable addresses and Nextcloud notifications for account users.
  • Prevent rejected documents from being mistaken for pending/approved documents or approved after rejection; add targeted PHP and frontend tests.

Real UI screenshots — before vs after

These are captures from a real LibreSign UI running in an isolated Nextcloud 36 instance at 1440 × 900. The demonstration uses a synthetic signer and file (Example Signer, synthetic-id.pdf). To exercise each UI state reproducibly without sharing any personal documents, the screenshots use an instrumented Playwright API-response fixture, including a simulated rejection response. They demonstrate the actual rendered frontend, not an independently completed backend end-to-end signing test.

Surface Before (current main) After (this PR)
Approval queue for the same synthetic submission Before: approval queue without Reject After: approval queue with Reject action

Sequential reviewer walkthrough

Step Real UI capture What the reviewer is checking
1. Rejection action is available next to approval Reject available beside Review and approve Approval and rejection are separate choices; Delete is unchanged
2. Open the rejection dialog Dialog requesting the rejection reason A reason is required and the signer will be asked to upload a replacement
3. Enter a reason Reviewer enters expired identification document explanation The concrete explanation is visible before confirmation
4. Review the rejected record Rejected document shown with its reason, without approval or delete actions Rejected documents remain identifiable rather than disappearing from the queue

Verification performed

  • Vue/TypeScript check: npm run ts:check
  • Frontend build: npm run dev (after installing viewer dependencies)
  • ESLint on affected frontend/test files
  • Focused Vitest queue tests: 11 passing
  • Focused PHP unit tests: 6 passing, 12 assertions with Nextcloud-backed test bootstrap
  • PHP syntax checks for changed backend classes
  • Browser-rendered before/after and sequential screens with synthetic fixture
  • Run full CI and resolve any failures on this branch
  • Validate a real rejection → delivery → replacement → signature workflow against the backend; the screenshot fixture does not substitute for this
  • Generate narrowly scoped OpenAPI JSON and TypeScript contracts for the rejection endpoint and document status; CI confirmation remains required

Review guidance: Please focus on the authorization boundary for rejection; reviewer concurrency and persistence; ability to replace a rejected upload without unblocking signature prematurely; recipient privacy; notification retry/idempotency; and consistency between account/guest signers. The PR is intentionally a draft until integration verification and CI are complete.

Scope: No merge or production deployment is requested.

Signed-off-by: Vitor Mattos <1079143+vitormattos@users.noreply.github.com>
Signed-off-by: Vitor Mattos <1079143+vitormattos@users.noreply.github.com>
Signed-off-by: Vitor Mattos <1079143+vitormattos@users.noreply.github.com>
Signed-off-by: Vitor Mattos <1079143+vitormattos@users.noreply.github.com>
Signed-off-by: Vitor Mattos <1079143+vitormattos@users.noreply.github.com>
Signed-off-by: Vitor Mattos <1079143+vitormattos@users.noreply.github.com>
…ntract

Signed-off-by: Vitor Mattos <1079143+vitormattos@users.noreply.github.com>
@github-actions

Copy link
Copy Markdown
Contributor

Code Metrics Report

Note: Metrics describe the revision analyzed by the successful PHPUnit run. Newer commits with pending, canceled or failed checks may not yet be represented in this report.

main (b02d0b8) #9434 (d02a7cc) +/-
Coverage 76.1% 75.9% -0.3%
Test Execution Time 1s 3m12s +3m11s
Details
  |                     | main (b02d0b8) | #9434 (d02a7cc) |  +/-   |
  |---------------------|----------------|-----------------|--------|
- | Coverage            |          76.1% |           75.9% |  -0.3% |
  |   Files             |            500 |             502 |     +2 |
  |   Lines             |          28578 |           28735 |   +157 |
+ |   Covered           |          21776 |           21827 |    +51 |
- | Test Execution Time |             1s |           3m12s | +3m11s |

Code coverage of files in pull request scope (59.5% → 56.1%, patch 32.5%)

Files Coverage +/- Patch Coverage Status
lib/Controller/IdDocsController.php 31.6% -1.7% 20.0% modified
lib/Db/IdDocs.php 100.0% 0.0% 100.0% modified
lib/Db/IdDocsMapper.php 62.9% -2.1% 40.5% modified
lib/Notification/Notifier.php 0.0% 0.0% 0.0% modified
lib/ResponseDefinitions.php 0.0% 0.0% - modified
lib/Service/IdDocRejectionService.php 39.3% +39.3% 39.3% added
lib/Service/IdDocsPolicyService.php 80.0% -0.9% 50.0% modified
lib/Service/IdDocsService.php 75.6% -3.3% 40.0% modified
lib/Service/MailService.php 70.2% -5.9% 0.0% modified
lib/Service/Notification/IdDocRejectionPayload.php 0.0% 0.0% 0.0% added
lib/Service/Notification/MailChannel.php 64.2% -25.2% 11.1% modified
lib/Service/Notification/NotificationEnvelopeCodec.php 88.9% -2.6% 55.5% modified
lib/Service/Validation/IdentityDocumentValidator.php 67.5% -3.9% 0.0% modified

Reported by octocov

This branch has not been deployed

No deployments
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant