mirror of
https://github.com/penpot/penpot.git
synced 2026-11-10 20:10:37 +00:00
* 🐛 Apply the share-link page scope to the comment queries and writes A share link can be restricted to a subset of the pages of a file, and the comment queries enforced that scope. But the RPC that resolves the profiles of the commenters authorized the request with check-comment-permissions! and dropped the returned perms, so its query filtered only by file id. The holder of a page scoped link got the id, email, fullname and photo of every profile that commented on any page of the file, including the pages the owner left out of the link. The query now takes the pages of the share link and only selects the authors of the threads on them. The profile of the caller is still added, so the viewer keeps its own avatar. The scope was missing as well on the comment writes that take a page id or a thread id: create-comment-thread accepted a page outside the link, create-comment accepted a thread of an unshared page, and update-comment-thread, update-comment-thread-position and update-comment-thread-frame accepted a thread of an unshared page. They now raise not-found, the same way the comment queries already did. Replying to a thread of an unshared page also sent the emails to the thread participants. The page scope rule now lives in one place: share-link-pages returns the pages granted by a share link and check-page-scope raises not-found when a page is outside of it, so get-comment-threads reuses the helper instead of checking the pages inline. The docstring of get-profiles-for-file-comments said that it returns the participants of all the comment threads of the file, which is not true anymore for a share link. The docs are public, so the text and the changes list are updated. The tests of the share link page scope are hardened: the setup asserts that the comment threads are created, the membership case has a second commenter so it can no longer pass for the wrong reason, and the link without pages, the allowed paths of the thread updates and the who-comment=team denial are covered. Relates to GHSA-89cq-3wv7-987r AI-assisted-by: minimax-m3.1-flash * 🐛 Enforce the share-link page scope on the remaining comment writes Check the page scope of the share link before mutating in the four comment writes that still skipped it: update-comment-thread-status, update-comment, delete-comment-thread and delete-comment. The check runs before the ownership checks, so an out-of-scope write fails with not-found and the response does not reveal that the comment or thread exists. Load the file in create-comment only after the permissions and page scope checks, matching create-comment-thread, so a rejected reply does not load the file data. Cover the denial and the in-scope paths of the four commands, and the fail-closed case of a link without pages on the comment reads. Move the outsider thread creation after the profiles assertion so the caller-union assertion fails when the union is removed. Document the page scope invariant in the backend permissions memory. AI-assisted-by: deepseek-v4.1-flash