fix(portal): collection share thumbnails, idempotent revoke, confirm UI#486
Merged
Conversation
…nt revoke, confirm before remove Asset thumbnails in shared collections returned 403 because canViewAsset only checked asset-level shares, not collection membership. Added GetUserAssetPermissionViaCollection which joins through collection sections and items to find collection-level share grants. Revoke is now idempotent (no error on already-revoked shares) to prevent 500 on repeat clicks. useRevokeShare invalidates collection-shares queries so the UI refreshes after revoking a collection share. The trash icon on shares now requires a confirmation click before revoking. Clicking the trash shows inline Remove/Cancel buttons instead of firing the mutation immediately. Confirmation state resets when the dialog closes.
cd269ed to
ed52114
Compare
Codecov Report❌ Patch coverage is
Additional details and impacted files@@ Coverage Diff @@
## main #486 +/- ##
=======================================
Coverage 86.20% 86.21%
=======================================
Files 237 237
Lines 33025 33046 +21
=======================================
+ Hits 28468 28489 +21
- Misses 3298 3299 +1
+ Partials 1259 1258 -1 ☔ View full report in Codecov by Sentry. 🚀 New features to boost your workflow:
|
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Summary
canViewAssetonly checked asset-level shares, not collection membership.Revokeerrored on already-revoked shares anduseRevokeSharedid not invalidate collection share queries.What changed
pkg/portal/store.goGetUserAssetPermissionViaCollectionjoinsportal_sharesthroughportal_collection_sectionsandportal_collection_itemsto find whether a user has access to an asset via a shared collection. Returns the highest permission found.Revokeis now idempotent:UPDATE ... SET revoked = TRUE WHERE id = $1without theAND revoked = FALSEguard, so revoking an already-revoked share succeeds silently.pkg/portal/handler.gocanViewAssetandcanEditAssetfall back toGetUserAssetPermissionViaCollectionwhen no direct asset share exists.ui/src/api/portal/hooks.tsuseRevokeShare.onSuccessnow also invalidates["collection-shares"]queries so the share list refreshes after revoking a collection share.ui/src/components/ShareDialog.tsxThe trash icon now shows inline "Remove" / "Cancel" buttons instead of firing the mutation on click.
Verified
GetUserAssetPermissionViaCollectionSQL against production DB with a real shared user's email and an asset inside the shared collection. Returnededitor.TestGetThumbnailViaCollectionShare/granted_via_collection_share: non-owner with no direct asset share but a collection-level share gets 200 and the thumbnail.TestGetThumbnailViaCollectionShare/denied_without_any_share: same user without any share gets 403.TestGetThumbnailNotOwnerNotShared: existing test unchanged, still 403.TestRevokeCollectionShareandTestPostgresShareStoreRevokeIdempotentpass.go test -race ./pkg/portal/...passes.npx tsc --noEmitclean.Test plan
TestGetThumbnailViaCollectionShare/granted_via_collection_share- 200TestGetThumbnailViaCollectionShare/denied_without_any_share- 403TestGetThumbnailNotOwnerNotShared- 403 (no regression)TestRevokeCollectionShare/owner_can_revoke- 200TestPostgresShareStoreRevokeIdempotent- no error on already-revokedgo test -race ./pkg/portal/...- all passnpx tsc --noEmit- clean