Skip to content

fix: check edit permission on parent note in relation routes - #311

Open
neSpecc wants to merge 6 commits into
fix/check-parent-note-permissionfrom
fix/check-relation-parent-permission
Open

neSpecc wants to merge 6 commits into
fix/check-parent-note-permissionfrom
fix/check-relation-parent-permission

Conversation

@neSpecc

@neSpecc neSpecc commented Oct 21, 2026 •

Copy link
Copy Markdown
Member

Stacked on #310: the base is fix/check-parent-note-permission, so the diff shows only the relation routes. After #310 is merged, retarget this PR to main (GitHub does it automatically if #310's branch is deleted on merge).

Problem

POST and PATCH /note/:notePublicId/relation use the authRequired and userCanEdit policies, but userCanEdit only checks the child note from the URL. The parent named in parentNoteId was never checked, and NoteService.createNoteRelation / updateNoteRelation take no user id. So a user could put their own note under anyone else's note.

This is the same gap #310 closes for POST /note with parentId.

Changes

  • Both relation routes now use the parentNoteResolver middleware and the userCanEditParentNote policy added in fix: check edit permission on parent note in POST /note #310. The resolver reads parentNoteId from the body. The policy requires MemberRole.Write on the parent (same rule as userCanEdit, a role inherited from an ancestor's team counts) and replies 403 You don't have permission to edit the parent note otherwise.
  • Behaviour change: an unknown parent now gets 406 Parent note not found from the resolver, instead of 400 Incorrect parent note Id (POST) / Incorrect parent note (PATCH) from the service. The two existing tests are updated.
  • Tests in note.test.ts: for both routes, a user who is not in the parent's team and a user with MemberRole.Read get 403, and a follow-up GET shows the relation did not change. These four fail against main.

Testing

yarn typecheck, yarn eslint src and yarn vitest run pass locally (173 tests, together with #310).

🤖 Generated with Claude Code

POST and PATCH /note/:notePublicId/relation only checked that the user
can edit the child note. The parent passed in parentNoteId was never
checked, so a user could put their own note under anyone's note.

Both handlers now require a Write role on the parent (same rule as the
userCanEdit policy) and reply 403 otherwise. An unknown parent is still
left to the note service, so its 400 responses are unchanged.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
@github-actions

github-actions Bot commented Oct 21, 2026 •

Copy link
Copy Markdown

Coverage Report

Status Category Percentage Covered / Total
🟢 Lines 85.91% (🎯 80%)
⬆️ +0.10 pp
9433 / 10979
🟢 Statements 85.91% (🎯 80%)
⬆️ +0.10 pp
9433 / 10979
🔴 Functions 79.83% (🎯 80%)
⬆️ +0.23 pp
289 / 362
🟢 Branches 84.97% (🎯 80%)
⬆️ +0.08 pp
492 / 579
File Coverage
File Stmts Branches Functions Lines Uncovered Lines
Changed Files
src/presentation/http/router/note.ts 98%
⬆️ +0.04 pp
79.41%
🟰 ±0 pp
100%
🟰 ±0 pp
98%
⬆️ +0.04 pp
162-163, 644-645, 661-667, 728-729, 785-786, 837-838
Generated in workflow #949 for commit 218502d by the Vitest Coverage Report Action

neSpecc and others added 2 commits October 21, 2026 03:53
Replace the router helper with parentNoteResolver and the
userCanEditParentNote policy from #310. An unknown parent note now gets
406 "Parent note not found" from the resolver, as in POST /note.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
@neSpecc
neSpecc changed the base branch from main to fix/check-parent-note-permission October 21, 2026 00:55
@neSpecc
neSpecc added this pull request to stack #312 October 21, 2026 01:18
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.

1 participant