You've already forked joplin
mirror of
https://github.com/laurent22/joplin.git
synced 2025-08-10 22:11:50 +02:00
Server: Fix notebooks remain shared after being permanently deleted by the share owner (#12583)
This commit is contained in:
@@ -916,11 +916,11 @@ export default class ItemModel extends BaseModel<Item> {
|
|||||||
const userShare = await this.models().shareUser().byShareAndUserId(share.id, userId);
|
const userShare = await this.models().shareUser().byShareAndUserId(share.id, userId);
|
||||||
|
|
||||||
if (userShare) {
|
if (userShare) {
|
||||||
// Leave the share
|
// Leave the share, but keep the notebook for the owner
|
||||||
await this.models().shareUser().delete(userShare.id);
|
await this.models().shareUser().delete(userShare.id);
|
||||||
} else if (share.owner_id === userId) {
|
} else if (share.owner_id === userId) {
|
||||||
// Delete the share
|
// Delete the share for everyone
|
||||||
await this.models().share().delete(share.id);
|
await this.delete(item.id);
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
await this.delete(item.id);
|
await this.delete(item.id);
|
||||||
|
@@ -502,6 +502,55 @@ describe('shares.folder', () => {
|
|||||||
// Test deleting the share, but not the root folder
|
// Test deleting the share, but not the root folder
|
||||||
});
|
});
|
||||||
|
|
||||||
|
test.each([
|
||||||
|
{
|
||||||
|
label: 'not delete a shared root folder when deleted by the recipient',
|
||||||
|
deleteFromOwner: false,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
label: 'delete a shared root folder when deleted by the owner',
|
||||||
|
deleteFromOwner: true,
|
||||||
|
},
|
||||||
|
])('should $label', async ({ deleteFromOwner }) => {
|
||||||
|
const { user: owner, session: session1 } = await createUserAndSession(1);
|
||||||
|
const { user: recipient, session: session2 } = await createUserAndSession(2);
|
||||||
|
|
||||||
|
await shareFolderWithUser(session1.id, session2.id, '0000000TEST0FOLDER01000000000000', {
|
||||||
|
'0000000TEST0FOLDER01000000000000': { },
|
||||||
|
});
|
||||||
|
|
||||||
|
const folderItem = await models().item().loadByJopId(owner.id, '0000000TEST0FOLDER01000000000000');
|
||||||
|
|
||||||
|
const itemIdsForUser = async (userId: string) => {
|
||||||
|
return (await models().item().children(userId)).items.map(item => item.id);
|
||||||
|
};
|
||||||
|
|
||||||
|
if (deleteFromOwner) {
|
||||||
|
await models().item().deleteForUser(owner.id, folderItem);
|
||||||
|
|
||||||
|
// Deleting from the owner should delete the folder for both clients
|
||||||
|
expect(await itemIdsForUser(owner.id)).toHaveLength(0);
|
||||||
|
expect(await itemIdsForUser(recipient.id)).toHaveLength(0);
|
||||||
|
|
||||||
|
// Share should be removed
|
||||||
|
expect(await models().share().all()).toHaveLength(0);
|
||||||
|
} else {
|
||||||
|
// Delete from the recipient account
|
||||||
|
await models().item().deleteForUser(recipient.id, folderItem);
|
||||||
|
|
||||||
|
// Deleting from the recipient should delete the folder for just the recipient
|
||||||
|
expect(await itemIdsForUser(owner.id)).toContain(folderItem.id);
|
||||||
|
expect(await itemIdsForUser(recipient.id)).toHaveLength(0);
|
||||||
|
|
||||||
|
// The share should still exist since the owner hasn't cancelled the
|
||||||
|
// share.
|
||||||
|
expect(await models().share().all()).toHaveLength(1);
|
||||||
|
}
|
||||||
|
|
||||||
|
// The notebook should no longer be shared with anyone.
|
||||||
|
expect(await models().shareUser().all()).toHaveLength(0);
|
||||||
|
});
|
||||||
|
|
||||||
test('should unshare when the share object is deleted', async () => {
|
test('should unshare when the share object is deleted', async () => {
|
||||||
const { user: user1, session: session1 } = await createUserAndSession(1);
|
const { user: user1, session: session1 } = await createUserAndSession(1);
|
||||||
const { user: user2, session: session2 } = await createUserAndSession(2);
|
const { user: user2, session: session2 } = await createUserAndSession(2);
|
||||||
|
Reference in New Issue
Block a user