feat: Always show share button (#2469)

This is to enable the share page also for internal team members.

closes #2444
This commit is contained in:
Wesley
2021-08-23 08:20:29 +02:00
committed by GitHub
parent d8ad2fc1a2
commit a50471959b
4 changed files with 48 additions and 10 deletions

View File

@ -79,7 +79,6 @@ function DocumentHeader({
const isNew = document.isNewDocument; const isNew = document.isNewDocument;
const isTemplate = document.isTemplate; const isTemplate = document.isTemplate;
const can = policies.abilities(document.id); const can = policies.abilities(document.id);
const canShareDocument = auth.team && auth.team.sharing && can.share;
const canToggleEmbeds = auth.team && auth.team.documentEmbeds; const canToggleEmbeds = auth.team && auth.team.documentEmbeds;
const canEdit = can.update && !isEditing; const canEdit = can.update && !isEditing;
@ -171,7 +170,7 @@ function DocumentHeader({
<TemplatesMenu document={document} /> <TemplatesMenu document={document} />
</Action> </Action>
)} )}
{!isEditing && canShareDocument && (!isMobile || !isTemplate) && ( {!isEditing && (!isMobile || !isTemplate) && (
<Action> <Action>
<ShareButton document={document} /> <ShareButton document={document} />
</Action> </Action>

View File

@ -27,12 +27,17 @@ type Props = {|
function SharePopover({ document, share, sharedParent, onSubmit }: Props) { function SharePopover({ document, share, sharedParent, onSubmit }: Props) {
const { t } = useTranslation(); const { t } = useTranslation();
const { policies, shares } = useStores(); const { policies, shares, auth } = useStores();
const { showToast } = useToasts(); const { showToast } = useToasts();
const [isCopied, setIsCopied] = React.useState(false); const [isCopied, setIsCopied] = React.useState(false);
const timeout = React.useRef<?TimeoutID>(); const timeout = React.useRef<?TimeoutID>();
const can = policies.abilities(share ? share.id : ""); const can = policies.abilities(share ? share.id : "");
const canPublish = can.update && !document.isTemplate; const documentAbilities = policies.abilities(document.id);
const canPublish =
can.update &&
!document.isTemplate &&
auth.team?.sharing &&
documentAbilities.share;
const isPubliclyShared = (share && share.published) || sharedParent; const isPubliclyShared = (share && share.published) || sharedParent;
React.useEffect(() => { React.useEffect(() => {
@ -102,7 +107,7 @@ function SharePopover({ document, share, sharedParent, onSubmit }: Props) {
</Notice> </Notice>
)} )}
{canPublish && ( {canPublish ? (
<SwitchWrapper> <SwitchWrapper>
<Switch <Switch
id="published" id="published"
@ -132,8 +137,11 @@ function SharePopover({ document, share, sharedParent, onSubmit }: Props) {
</SwitchText> </SwitchText>
</SwitchLabel> </SwitchLabel>
</SwitchWrapper> </SwitchWrapper>
) : (
<HelpText>{t("Only team members with permission can view")}</HelpText>
)} )}
{share && share.published && (
{canPublish && share?.published && (
<SwitchWrapper> <SwitchWrapper>
<Switch <Switch
id="includeChildDocuments" id="includeChildDocuments"

View File

@ -36,7 +36,7 @@ import { sequelize } from "../sequelize";
import pagination from "./middlewares/pagination"; import pagination from "./middlewares/pagination";
const Op = Sequelize.Op; const Op = Sequelize.Op;
const { authorize, cannot } = policy; const { authorize, cannot, can } = policy;
const router = new Router(); const router = new Router();
router.post("documents.list", auth(), pagination(), async (ctx) => { router.post("documents.list", auth(), pagination(), async (ctx) => {
@ -534,10 +534,20 @@ async function loadDocument({
document = share.document; document = share.document;
} }
// "published" === on the public internet. So if the share isn't published // If the user has access to read the document, we can just update
// then we must have permission to read the document // the last access date and return the document without additional checks.
const canReadDocument = can(user, "read", document);
if (canReadDocument) {
await share.update({ lastAccessedAt: new Date() });
return { document, share, collection };
}
// "published" === on the public internet.
// We already know that there's either no logged in user or the user doesn't
// have permission to read the document, so we can throw an error.
if (!share.published) { if (!share.published) {
authorize(user, "read", document); throw new AuthorizationError();
} }
// It is possible to disable sharing at the collection so we must check // It is possible to disable sharing at the collection so we must check

View File

@ -235,6 +235,27 @@ describe("#documents.info", () => {
expect(res.status).toEqual(403); expect(res.status).toEqual(403);
}); });
it("should return document from shareId if public sharing is disabled but the user has permission to read", async () => {
const { document, collection, team, user } = await seed();
const share = await buildShare({
documentId: document.id,
teamId: document.teamId,
userId: user.id,
});
team.sharing = false;
await team.save();
collection.sharing = false;
await collection.save();
const res = await server.post("/api/documents.info", {
body: { token: user.getJwtToken(), shareId: share.id },
});
expect(res.status).toEqual(200);
});
it("should not return document from revoked shareId", async () => { it("should not return document from revoked shareId", async () => {
const { document, user } = await seed(); const { document, user } = await seed();
const share = await buildShare({ const share = await buildShare({