Files
Hemachandar d3eb3db7ba feat: Public sharing of collections (#9529)
* shares.info, collections.info, documents.info

* shares.list, shares.create, shares.update

* shares.sitemap

* parity with existing document shared screen

* collection share popover

* parent share and table

* collection scene

* collection link in sidebar

* sidebar and breadcrumb collection link click

* collection link click in editor

* meta

* more meta + 404 page

* map internal link, remove showLastUpdated option

* fix shares.list pagination

* show last updated

* shareLoader tests

* lint

* sidebar context for collection link

* badge in shares table

* fix existing tests

* tsc

* update failing test snapshot

* env

* signed url for collection attachments

* include collection content in SSR for screen readers

* search

* drafts can be shared

* review

* tsc, remove old shared-doc scene

* tweaks

* DRY

* refactor loader

* Remove share/collection urls

* fix: Collection overview should not be editable when viewing shared link and logged in

* Tweak public breadcrumb

* fix: Deleted documents should never be exposed through share

* empty sharedTree array where includeChildDocuments is false

* revert includeChildDocs guard for logical correctness + SSR bug fix

* fix: check document is part of share

---------

Co-authored-by: Tom Moor <tom@getoutline.com>
2025-08-03 13:07:39 -04:00

50 lines
963 B
TypeScript

import { Share, Team, User } from "@server/models";
import { allow, can } from "./cancan";
import { and, isOwner, isTeamModel, isTeamMutable, or } from "./utils";
allow(User, "createShare", Team, (actor, team) =>
and(
//
isTeamModel(actor, team),
isTeamMutable(actor),
!actor.isGuest
)
);
allow(User, "listShares", Team, (actor, team) =>
and(
//
isTeamModel(actor, team),
!actor.isGuest
)
);
allow(User, "read", Share, (actor, share) =>
and(
//
isTeamModel(actor, share),
!actor.isGuest
)
);
allow(User, "update", Share, (actor, share) =>
and(
isTeamModel(actor, share),
!actor.isGuest,
!actor.isViewer,
or(
can(actor, "share", share?.collection),
can(actor, "share", share?.document)
)
)
);
allow(User, "revoke", Share, (actor, share) =>
and(
isTeamModel(actor, share),
!actor.isGuest,
!actor.isViewer,
or(actor.isAdmin, isOwner(actor, share))
)
);