KamoCRM

A document share now actually reaches its recipient, and edit is gated

FixDocsService
Shipped
September 23, 2026 at 2:56 AM UTC
Author
Kamo
Commit
80e1d6f

**************** matched an ImgShare by ImgShare.member — the SHARER, who created the row so they can list what THEY shared (getSharesByImage) — instead of ImgShare.swMember, the "shared with" recipient. A share never actually granted its intended recipient anything: the sharer already had access by virtue of being the sharer (redundant with the org+clearance check every read already runs), and the recipient's read here always came back empty. That is also why img_shares has zero rows in production (confirmed via ysqlsh) — sharing has never worked, so there is no data to migrate. canUserAccess/canUserWrite now match an active, unexpired share against the recipient: by ImgShare.swMember directly, or — for a TeamMember, the only Member subtype the department/job-title share targets can resolve against — by **************** matching the member's own Department/JobTitle. createShare (ImagingController) already builds all three share shapes (shareType **************** this is what makes the two group shapes it already lets a sharer create actually grant anything either. createShare itself had two gaps once the match above stopped being silently inert: - Granting isAllowEdit=true took only VIEW_DOCUMENTS, with no check that the sharer had any particular relationship to the document — any org member could grant ANYONE edit access to ANY document they could merely view. Now requires EDIT_DOCUMENTS on the sharer, AND that the sharer is the document's own creator/owner or holds MANAGE_DOCS_SETTINGS. A plain view share (the default, isAllowEdit omitted or false) is unaffected and still needs only VIEW_DOCUMENTS. - No self-share block: a member could name themselves as swMember. Refused outright now (400) rather than left as a harmless-looking no-op — canUserAccess already treats the creator as having full access, so a self-share was never meaningful, and leaving it possible is one more shape for a decoy row. New tests: DocumentServiceShareAccessTest (9 cases: recipient access, sharer-gets-nothing, an outsider, edit-vs-view, expiry, revocation, department, job title, plain-Member-is-unaffected) and 6 cases added to ImagingShareCreateTest (the edit-grant gate's four combinations, self-share). Mutation-checked: reverting hasActiveShareFor/targets to the old findByImgAndMember(img, member) query turns 2 of the new DocumentServiceShareAccessTest cases red; reverting ImagingController.java's createShare changes to origin/main turns 3 of the 6 new ImagingShareCreateTest cases red. Full suite: 758 tests green (was 743; +15 new).

All changes

Like what you see shipping?

All of it arrives in your workspace on its own. Start on the free plan and read this page again in a month.

Start Free ForeverView Pricing