Skip to content

feat: folder-scoped sharing - #154

Merged
vishwajeet-13 merged 3 commits into
developfrom
feat/folder-scoped-sharing
Sep 5, 2026
Merged

feat: folder-scoped sharing#154
vishwajeet-13 merged 3 commits into
developfrom
feat/folder-scoped-sharing

Conversation

@vishwajeet-13

Copy link
Copy Markdown
Collaborator

What

Share a single VMS Folder without exposing the rest of the project. Today VMS Project carries one share_token and get_shared_project_assets returns every asset in the project as a flat list — there was no way to share one folder.

How it works

  • Each VMS Folder gets its own share_token, independent of the project share and of other folders. Project + any number of folders can be shared at once; revoking one touches nothing else.
  • Public link is /vms/shared/folder/<folder-id>?token=…no project segment, so moving the folder between projects doesn't break it.
  • Scope: the folder's own assets only. Nested subfolders are not shown or reachable.
  • Lifecycle: moving the folder keeps the link; trashing it clears share_token (link dies); restoring does not re-enable it.

Changes

Backend (vms/api.py, VMS Folder)

  • share_token field (hidden, unique) + revoke_share_on_trash controller hook
  • enable_folder_sharing / disable_folder_sharing / get_shared_folder / get_shared_folder_assets
  • get_shared_asset_view_url / get_shared_asset_download_url gain an optional folder arg validated against the folder token — project path unchanged
  • folder-token validation also rejects an unshared/trashed folder for authenticated non-VMS users

Frontend

  • ShareFolderPanel.vue; "Share" entry in folder card / row / in-folder actions menus
  • /vms/shared/folder/:folderId route reuses SharedProjectPage in folder mode (title = folder name, flat grid, preview, Download all)
  • in-folder header now shows the folder's actions (was project actions)

Spec: plans/folder-scoped-sharing.md

Verification

  • ruff check + format, yarn typecheck / lint / build — clean
  • Manual security checks: scope isolation, bad/missing tokens rejected, unshared folder blocked (guest and authed non-VMS user), sibling/child asset blocked, trash revokes token
  • Regression: project-share endpoints, URLs, token idempotency, disable-revokes, guest page over HTTP — byte-identical behaviour

Follow-ups (not in this PR)

  • Automated tests deferred — recommend adding the folder-scope e2e case to sharing.spec.ts before merge
  • Pre-existing (untouched): the project-path get_shared_asset_*_url endpoints don't re-check "is it shared" — the folder path added here is hardened against this; worth a separate ticket

🤖 Generated with Claude Code

Share a single VMS Folder without exposing the rest of the project.
Each folder gets its own share_token, independent of the project share
and of other folders. The public link is /vms/shared/folder/<id> with no
project segment, so moving the folder never breaks it. Trashing the
folder clears the token; scope is the folder's own assets only (nested
subfolders excluded).

Backend (vms/api.py, VMS Folder):
- share_token field + revoke_share_on_trash controller hook
- enable/disable_folder_sharing, get_shared_folder,
  get_shared_folder_assets
- get_shared_asset_view_url / _download_url take an optional folder arg,
  validated against the folder token (project path unchanged); folder
  validation also rejects an unshared folder for authenticated non-VMS
  users

Frontend:
- ShareFolderPanel, Share entry in folder card / row / actions menus
- /vms/shared/folder/:folderId route reuses SharedProjectPage in folder
  mode
- in-folder header menu now shows the folder's actions

Tests deferred (see plans/folder-scoped-sharing.md).

Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01UDbtFtgkUmtPEU8PhbcoC5
@greptile-apps

greptile-apps Bot commented Sep 5, 2026

Copy link
Copy Markdown

Greptile Summary

Adds independently revocable, folder-scoped public sharing while preserving existing project sharing.

  • Adds per-folder share tokens and revokes them when folders are trashed.
  • Adds token-protected folder metadata, asset listing, preview, and download APIs restricted to direct folder assets.
  • Adds folder-sharing controls and a guest folder route that reuses the existing shared gallery.
  • Hardens shared asset URL endpoints against trashed and still-uploading assets.

Confidence Score: 5/5

The PR appears safe to merge, although automated coverage of the new sharing boundary remains a worthwhile non-blocking follow-up.

The two prior authorization defects are fully fixed: every caller must now provide the folder token, and media URL endpoints reject trashed or still-uploading assets consistently with shared listings. The remaining previous feedback concerns deferred automated coverage and does not identify a current functional failure.

Important Files Changed

Filename Overview
vms/api.py Adds folder-scoped sharing APIs and aligns folder-token, asset-scope, and lifecycle validation across listing and media URL endpoints.
vms/video_management_solution/doctype/vms_folder/vms_folder.py Revokes an active folder share token whenever the folder enters the trash lifecycle.
vms/video_management_solution/doctype/vms_folder/vms_folder.json Adds a hidden, read-only, unique share token to the folder data model.
frontend/src/pages/SharedProjectPage.vue Generalizes the guest sharing page to support either project or direct-folder scope.
frontend/src/components/folders/ShareFolderPanel.vue Adds the folder public-link toggle, link display, and clipboard interaction.
frontend/src/router.ts Registers the guest folder-sharing route outside the authenticated shell.
plans/folder-scoped-sharing.md Documents the folder-sharing boundary and explicitly defers automated regression coverage.

Reviews (3): Last reviewed commit: "fix: harden shared-folder access checks ..." | Re-trigger Greptile

Comment thread vms/api.py Outdated
Comment thread vms/api.py Outdated
Comment on lines +82 to +87
## Testing

Deferred — full e2e/unit suite is a follow-up. One security assertion was
verified during implementation: folder A (file a1) with subfolder B (b1) and
sibling C (c1); sharing A, a guest gets a1 only, b1/c1 are rejected; trashing A
clears the token and kills the link.

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

P2 Sharing boundary lacks tests

The new token-protected sharing boundary, including sibling and child isolation and trash revocation, has no automated regression coverage; this plan explicitly defers testing. Add an end-to-end case covering invalid or missing tokens, non-VMS authenticated sessions, out-of-scope assets, and folder and asset trash so future authorization changes cannot silently broaden public access.

Knowledge Base Used: Project workspaces and sharing

Prompt To Fix With AI
This is a comment left during a code review.
Path: plans/folder-scoped-sharing.md
Line: 82-87

Comment:
**Sharing boundary lacks tests**

The new token-protected sharing boundary, including sibling and child isolation and trash revocation, has no automated regression coverage; this plan explicitly defers testing. Add an end-to-end case covering invalid or missing tokens, non-VMS authenticated sessions, out-of-scope assets, and folder and asset trash so future authorization changes cannot silently broaden public access.

**Knowledge Base Used:** [Project workspaces and sharing](https://app.greptile.com/bwh-tech/-/custom-context/knowledge-base/bwhtech/vms/-/docs/project-workspaces-and-sharing.md)

---

For each issue above, determine whether it is valid and should be fixed. If so, fix it directly.

Note: If this suggestion doesn't match your team's coding style, reply to this and let me know. I'll remember it for next time!

Fix in Claude Code Fix in Codex

vishwajeet-13 and others added 2 commits September 6, 2026 00:08
- nosemgrep markers on the guest-whitelisted folder-share endpoints
- type hints on get_shared_folder_assets page params

Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01UDbtFtgkUmtPEU8PhbcoC5
- _validate_folder_token requires a valid token for every caller; the
  authenticated-session branch that skipped the token comparison is gone,
  so a logged-in non-VMS account can no longer read a shared folder by id
- get_shared_asset_view_url / _download_url reject a trashed or
  still-uploading asset instead of only checking scope, for both the
  folder and project paths

Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01UDbtFtgkUmtPEU8PhbcoC5
@vishwajeet-13
vishwajeet-13 merged commit bfc42b4 into develop Sep 5, 2026
4 of 5 checks passed
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