Skip to content

Show unlock action for the file owner - #17838

Open
falkloewert wants to merge 2 commits into
nextcloud:masterfrom
falkloewert:fix/unlock-file-owner
Open

falkloewert wants to merge 2 commits into
nextcloud:masterfrom
falkloewert:fix/unlock-file-owner

Conversation

@falkloewert

Copy link
Copy Markdown

Fixes #17837

Summary

The "Unlock file" entry was only shown when the current user owns the lock (lockOwnerId == userId). The server also allows the file owner to unlock TYPE_USER locks — OCA\FilesLock\Service\LockService::canUnlock():

if ($request->getType() === ILock::TYPE_USER && $isFileOwner) {
    return;
}

Without this, a stale lock created by another client (e.g. the Text app, lock owner text) cannot be released from the app at all; with the default lock_timeout = -1 it never expires.

Change: FileLockingHelper.canUserUnlockFile() now also accepts file.ownerId == userId.

Known limitation: for group folders and external storage the server deliberately skips the file-owner check (MountProvider allowlist in canUnlock), so the client cannot mirror the rule exactly there; the action can then fail with the existing error snackbar.

🖼️ Screenshots

Not applicable — the only visible difference is an additional entry in the file overflow menu.

🏁 Checklist

  • ⛑️ Tests (unit and/or integration) are included or not needed — one added case; existing cases still pass (FileLockingHelperTest, 5 tests)
  • 🔙 Backport requests are created or not needed: not needed
  • 📅 Milestone is set
  • 🌸 PR title is meaningful (if it should be in the changelog: is it meaningful to users?): "Unlock a file locked by another client"

🤖 AI (if applicable)

  • The content of this PR was partly or fully generated using AI — assistant-generated patch, reviewed and tested by me.

Falk Loewert added 2 commits October 18, 2026 21:53
The server allows the owner of a file to unlock TYPE_USER locks
(LockService::canUnlock), so a stale lock created by another client -
e.g. the Text app, whose locks have the owner "text" - can be released
by the user. The client only offered the action when the lock owner
matched the current user, leaving users without a way to clear such
locks until the lock timeout expires (which defaults to unlimited).

Signed-off-by: Falk Loewert <falk@co-sinus.de>
App locks created by the Text or OnlyOffice apps are of type TYPE_APP.
For those the server does not expose a lock owner and reports the lock
type as COLLABORATIVE, so the previous check (lock owner equals the
current user, MANUAL lock type) never matched and the unlock action
stayed hidden even for the owner of the file. LockService::canUnlock
accepts a TYPE_USER unlock request from the file owner for TYPE_USER and
TYPE_APP locks, so mirror that on the client and only keep TOKEN locks
restricted.

Additionally the lock info row was appended to the action list before
displayActions() ran. That method returns early when the list is not
empty, which left the bottom sheet without any action at all for locked
files. Render the actions first and append the lock info afterwards.

Signed-off-by: Falk Loewert <falk@co-sinus.de>
@falkloewert

Copy link
Copy Markdown
Author

Updated the patch after testing on a real device (Android 16, Pixel 9 Pro, files_lock 34.0.1, server 34).

Two things the first revision got wrong or missed:

  1. App locks are not MANUAL. Text and OnlyOffice lock with TYPE_APP (1), which the client maps to COLLABORATIVE, and for those locks the server returns no lock-owner at all. The old check (lockOwnerId == userId && lockType == MANUAL) could therefore never match. LockService::canUnlock accepts a TYPE_USER unlock request from the file owner for both TYPE_USER and TYPE_APP locks, so the client now mirrors that and only keeps TOKEN locks restricted.

  2. The action list was invisible for locked files. FileActionsBottomSheet.handleState() called displayLockInfo() before displayActions(), and displayActions() returns early when fileActionsList is not empty. With a lock present the sheet rendered only the "Locked by …" row and no actions at all — the unlock entry could not have been reached even with the permission check fixed. Reordered.

Verified end-to-end on device: open the actions sheet for a docx locked by OnlyOffice, tap "Unlock file", lock disappears from oc_files_lock.

🤖 Generated with Claude Code

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.

[Bug] Lock owned by another client (e.g. Text app) cannot be unlocked from the app

1 participant