Desktop: Fixed sharing notebook when recipient is not allowed to share

pull/5771/head
Laurent Cozic 2021-11-21 14:35:01 +00:00
parent 8b68da4040
commit 1bb7bbb9e5
2 changed files with 54 additions and 7 deletions

View File

@ -1,6 +1,10 @@
import { CommandRuntime, CommandDeclaration, CommandContext } from '@joplin/lib/services/CommandService';
import { _ } from '@joplin/lib/locale';
import ShareService from '@joplin/lib/services/share/ShareService';
import Setting from '@joplin/lib/models/Setting';
import Logger from '@joplin/lib/Logger';
const logger = Logger.create('leaveSharedFolder');
export const declaration: CommandDeclaration = {
name: 'leaveSharedFolder',
@ -12,7 +16,24 @@ export const runtime = (): CommandRuntime => {
execute: async (_context: CommandContext, folderId: string = null) => {
const answer = confirm(_('This will remove the notebook from your collection and you will no longer have access to its content. Do you wish to continue?'));
if (!answer) return;
await ShareService.instance().leaveSharedFolder(folderId);
try {
// Since we are going to delete the notebook, do some extra safety checks. In particular:
// - Check that the notebook is indeed being shared.
// - Check that it does **not** belong to the current user.
const shares = await ShareService.instance().refreshShares();
const share = shares.find(s => s.folder_id === folderId);
if (!share) throw new Error(_('Could not verify the share status of this notebook - aborting. Please try again when you are connected to the internet.'));
const userId = Setting.value('sync.userId');
if (share.user.id === userId) throw new Error('Cannot leave own notebook');
await ShareService.instance().leaveSharedFolder(folderId);
} catch (error) {
logger.error(error);
alert(_('Error: %s', error.message));
}
},
enabledCondition: 'joplinServerConnected && folderIsShareRootAndNotOwnedByUser',
};

View File

@ -5,7 +5,7 @@ import { _ } from '@joplin/lib/locale';
import { useEffect, useState } from 'react';
import { FolderEntity } from '@joplin/lib/services/database/types';
import Folder from '@joplin/lib/models/Folder';
import ShareService from '@joplin/lib/services/share/ShareService';
import ShareService, { ApiShare } from '@joplin/lib/services/share/ShareService';
import styled from 'styled-components';
import StyledFormLabel from '../style/StyledFormLabel';
import StyledInput from '../style/StyledInput';
@ -167,11 +167,38 @@ function ShareFolderDialog(props: Props) {
async function shareRecipient_click() {
setShareState(ShareState.Creating);
setLatestError(null);
let errorSet = false;
const handleError = (error: any) => {
if (!errorSet) setLatestError(error);
errorSet = true;
logger.error(error);
};
const defer = (error: any) => {
if (error) handleError(error);
setShareState(ShareState.Idle);
};
let share: ApiShare = null;
try {
share = await ShareService.instance().shareFolder(props.folderId);
} catch (error) {
return defer(error);
}
try {
setLatestError(null);
const share = await ShareService.instance().shareFolder(props.folderId);
await ShareService.instance().addShareRecipient(share.id, share.master_key_id, recipientEmail);
} catch (error) {
// Handle the error but continue the process because we need to at
// least refresh the shares since one has been created above.
handleError(error);
}
try {
await Promise.all([
ShareService.instance().refreshShares(),
ShareService.instance().refreshShareUsers(share.id),
@ -180,10 +207,9 @@ function ShareFolderDialog(props: Props) {
await synchronize();
} catch (error) {
logger.error(error);
setLatestError(error);
handleError(error);
} finally {
setShareState(ShareState.Idle);
defer(null);
}
}