Skip to content

Passport uploaded dockument does not reach SIGNED status #7860

Description

@tebbiworld

Describe the bug

ID document approval never completes: uploader's draft sign request blocks file from reaching SIGNED status

To reproduce

Affected version

LibreSign 13.2.6 (also present in current main, source ref de81c97).

Environment

  • Nextcloud with LibreSign, identification documents feature enabled ("Ablauf der Ausweisdokumente ermöglichen").
  • Users provided via LDAP; approval groups configured (e.g. ["admin","libresignadmin"]).

Summary

When the "identification documents" workflow is enabled, an uploaded ID document can never reach the APPROVED/SIGNED state, even after an authorized approver signs it. The file stays at "Partially signed" forever.

Root cause

Two interacting issues in the ID-doc workflow:

  1. IdDocsService::addIdDocs() creates a sign request for the uploader without setting a status. SignRequestEntity defaults to status 0 (DRAFT). The uploader therefore can never sign their own document (and by design should not need to).

  2. SignFileService::evaluateStatusFromSigners() counts every sign request of the file, including the uploader's DRAFT request. When an approver signs, the count is 1 signed of 2 total, so the file is set to PARTIAL_SIGNED and never to SIGNED, because the uploader DRAFT request is never signed.

Result: the file is stuck at PARTIAL_SIGNED, "Approved by" stays empty, and the uploader can consequently never obtain an approved ID document to sign other documents.

Steps to reproduce

  1. Enable identification documents, set an approval group.
  2. As a regular user (member of a signing-request group, not of the approval group), upload an ID document.
  3. As a member of the approval group, open the document via the approval flow and sign it.
  4. Observe: status remains "Partially signed", "Approved by" empty.

Expected

After an authorized approver signs the ID document, the document should reach SIGNED/APPROVED. The uploader should not be required to sign their own ID document (they are already authenticated via their login/signature password).

Proposed fix

In SignFileService::evaluateStatusFromSigners(), exclude DRAFT sign requests (status 0) from the completion count, so the file becomes SIGNED once all active signers have signed:

private function evaluateStatusFromSigners(): ?int {
    $signers = $this->getSigners();
    $signers = array_filter($signers, fn ($s) => $s->getStatus() !== 0); // ignore DRAFT (uploader) requests
    $total = count($signers);
    if ($total === 0) {
        return null;
    }
    $totalSigned = count(array_filter($signers, fn ($s) => $s->getSigned() !== null));
    if ($totalSigned === $total) {
        return FileStatus::SIGNED->value;
    }
    if ($totalSigned > 0) {
        return FileStatus::PARTIAL_SIGNED->value;
    }
    return null;
}

This was verified to make the workflow complete without any manual database intervention.

Additional related findings (separate, lower priority)

While investigating, the following were also observed in 13.2.6 and may deserve their own issues:

  • IdDocsMapper::list() uses an INNER JOIN on oc_users when filtering by userId. LDAP users do not exist in oc_users, so their uploaded ID documents are invisible on the account page ("Noch nicht gesendet"/"not sent yet") even though the record exists. Changing the join to a LEFT JOIN fixes it; the WHERE clause on id.user_id still filters correctly.
  • AccountSettingsProvider::canRequestSign appears to read the approval_group setting instead of groups_request_sign, so the frontend "request signature" button visibility can diverge from the backend permission check (which uses groups_request_sign).
  • Opening /f/sign/{uuid} for an ID document without the idDocApproval=true parameter renders an empty (white) content area; the ID-doc approval flow requires that parameter.

I'm happy to open the related findings as separate issues if preferred.

Expected behavior

No response

Screenshots

No response

Operational System

Nethserver 8 rocky linux running nextcloud with app libresign

Browser Type and Version

No response

Libresign Version

13.2.6

Nextcloud Server Version

No response

Logs from Nextcloud Server

No fatal entries in nextcloud.log or php-fpm output at the time of signing.
The failure is logical, not an exception: the file status is computed from all
sign requests including the uploader's DRAFT request, so the file never reaches
SIGNED. Verified directly in the database:

oc_libresign_file.status stays 2 (PARTIAL_SIGNED) after the approver signs.
oc_libresign_sign_request for the file: uploader request status=0 (DRAFT, unsigned),
approver request status=2 (SIGNED). Total counted 2, signed 1 -> PARTIAL_SIGNED.

Logs from Developers tools

No response

Additional context

No response

Metadata

Metadata

Assignees

No one assigned

    Labels

    bugSomething isn't working

    Type

    Fields

    No fields configured for Bug.

    Projects

    Status
    0. Needs triage

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions