Skip to content

Read-only board members can't see card descriptions: Text session fails with NoPermissionException #8742

Description

@MR-1997

How to use GitHub

  • Please use the 👍 reaction to show that you are affected by the same issue.
  • Please don't comment if you have no relevant information to add. It's just extra noise for everyone subscribed to this issue.
  • Subscribe to receive notifications on status change and new comments.

Describe the bug
Users who have read-only access to a board (shared without edit permission) can't see card descriptions in the web UI. The description area stays empty, so checklists in the description are invisible too. Opening a card makes the frontend create a Text session (PUT /apps/text/session/deck_card/{cardId}/create), and that request fails with "Permission denied".

The cause is lib/Provider/TextContextProvider.php:

public function prepareSession(): SessionInfo {
    $readonly = !$this->permissionService->checkPermission($this->cardMapper, $this->cardId, Acl::PERMISSION_EDIT, $this->userId);

PermissionService::checkPermission() doesn't return false when the permission is missing. It throws NoPermissionException. So $readonly is never true: for every read-only user the exception ends the request, instead of the session being opened read-only. isReadOnly() has the same pattern. main still has this code.

The data itself is readable: the same user gets the full description from GET /index.php/apps/deck/api/v1.0/boards/{boardId}/stacks/{stackId}/cards/{cardId}, and can read and post comments.

A possible fix is to treat the exception as read-only:

public function prepareSession(): SessionInfo {
    return new SessionInfo(
        readOnly: $this->isReadOnly(),
        lock: null,
        canAttachFiles: false,
    );
}

public function isReadOnly(): bool {
    try {
        return !$this->permissionService->checkPermission($this->cardMapper, $this->cardId, Acl::PERMISSION_EDIT, $this->userId);
    } catch (NoPermissionException) {
        return true;
    }
}

Users without read access still can't get at the content, because loadContent() goes through CardService::find(), which checks read permission.

I tried this change on the setup below. PUT /apps/text/session/deck_card/{cardId}/create then returns:

User Board access Before With the change
B read-only 500, NoPermissionException 200, readOnly: true, with the description
C can edit 200, readOnly: false unchanged
D no access 403 403, unchanged

To Reproduce
Reproduced on a fresh nextcloud:35-apache Docker container (SQLite) with Deck 1.19.2:

  1. As user A, create a board and a card with a description.
  2. Share the board with a group that user B is in. Leave "Can edit" unchecked.
  3. Log in as user B, open the board, and open the card.
  4. The description is empty. nextcloud.log shows OCA\Deck\NoPermissionException: Permission denied for PUT /apps/text/session/deck_card/{cardId}/create.

Expected behavior
User B sees the description and its checklists read-only. The read-only path looks like it was intended: prepareSession() passes readOnly to SessionInfo.

Screenshots
Not needed: the card opens, but the description area is empty.

Client details:

  • OS: any
  • Browser: any (the error is server-side)
  • Version: -
  • Device: desktop
Server details

Operating system: Debian GNU/Linux 13 (trixie), official nextcloud:35-apache Docker image

Web server: Apache 2.4.69

Database: SQLite

PHP version: 8.5.12

Nextcloud version: 35.0.2

Where did you install Nextcloud from: official Docker image (nextcloud:35-apache), Deck installed with occ app:install deck

Signing status:

No errors. Reproduced on unmodified Deck files; only the test of the fix above changed TextContextProvider.php.

List of activated apps:

Stock apps of the nextcloud:35-apache image, plus:
  - deck: 1.19.2
Text (shipped): 9.0.1

Nextcloud configuration:

{
    "system": {
        "htaccess.RewriteBase": "/",
        "memcache.local": "\\OC\\Memcache\\APCu",
        "apps_paths": [
            { "path": "/var/www/html/apps", "url": "/apps", "writable": false },
            { "path": "/var/www/html/custom_apps", "url": "/custom_apps", "writable": true }
        ],
        "upgrade.disable-web": true,
        "passwordsalt": "***REMOVED SENSITIVE VALUE***",
        "secret": "***REMOVED SENSITIVE VALUE***",
        "trusted_domains": [ "localhost" ],
        "datadirectory": "***REMOVED SENSITIVE VALUE***",
        "dbtype": "sqlite3",
        "version": "35.0.2.2",
        "overwrite.cli.url": "http://localhost",
        "instanceid": "***REMOVED SENSITIVE VALUE***",
        "dbname": "***REMOVED SENSITIVE VALUE***",
        "installed": true
    }
}

Are you using an external user-backend, if yes which one: no, local users

Logs

Nextcloud log (data/nextcloud.log)

PUT /apps/text/session/deck_card/7876/create | Permission denied

OCA\Deck\NoPermissionException: Permission denied
  custom_apps/deck/lib/Provider/TextContextProvider.php:64  OCA\Deck\Service\PermissionService->checkPermission()
  apps/text/lib/Service/ApiService.php:71                   OCA\Deck\Provider\TextContextProvider->prepareSession()
  apps/text/lib/Controller/SessionController.php:71         OCA\Text\Service\ApiService->create()
  lib/private/AppFramework/Http/Dispatcher.php:198          OCA\Text\Controller\SessionController->create()
  lib/private/AppFramework/Http/Dispatcher.php:86           OC\AppFramework\Http\Dispatcher->executeController()
  lib/private/AppFramework/App.php:138                      OC\AppFramework\Http\Dispatcher->dispatch()
  lib/private/Route/Router.php:324                          OC\AppFramework\App::main()

Browser log

PUT /apps/text/session/deck_card/{cardId}/create -> 500 (read-only user)

Activity

  1. added theissue type on Nov 13, 2026
  2. blizzz commented on Nov 13, 2026

    @blizzz
    Member

    Fix in #8739

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

Metadata

Metadata

Assignees

No one assigned

    Type

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions