1
0
mirror of https://github.com/laurent22/joplin.git synced 2024-11-27 08:21:03 +02:00

Server: Fixed issue when an item is associated with a share that no longer exists

This commit is contained in:
Laurent Cozic 2023-02-06 18:58:06 +00:00
parent 793e8f6c0f
commit ba5f0bc6e3
2 changed files with 38 additions and 3 deletions

View File

@ -299,12 +299,29 @@ export default class ShareModel extends BaseModel<Share> {
for (const change of changes) {
const item = items.find(i => i.id === change.item_id);
// When a folder is unshared, the share object is
// deleted, then all items that were shared get their
// 'share_id' property set to an empty string. This is
// all done client side.
//
// However it means that if a share object is deleted
// but the items are not synced, we'll find items that
// are associated with a share that no longer exists.
// This is fine, but we need to handle it properly
// below, otherwise the share update process will fail.
const itemShare = shares.find(s => s.id === item.jop_share_id);
if (change.type === ChangeType.Create) {
await handleCreated(change, item, shares.find(s => s.id === item.jop_share_id));
if (!itemShare) {
logger.warn(`Found an item (${item.id}) associated with a share that no longer exists (${item.jop_share_id}) - skipping it`);
} else {
await handleCreated(change, item, itemShare);
}
}
if (change.type === ChangeType.Update) {
await handleUpdated(change, item, shares.find(s => s.id === item.jop_share_id));
await handleUpdated(change, item, itemShare);
}
// We don't need to handle ChangeType.Delete because when an

View File

@ -1,5 +1,5 @@
import { ChangeType, Share, ShareType, ShareUser, ShareUserStatus } from '../../services/database/types';
import { beforeAllDb, afterAllTests, beforeEachDb, createUserAndSession, models, createNote, createFolder, updateItem, createItemTree, makeNoteSerializedBody, updateNote, expectHttpError, createResource } from '../../utils/testing/testUtils';
import { beforeAllDb, afterAllTests, beforeEachDb, createUserAndSession, models, createNote, createFolder, updateItem, createItemTree, makeNoteSerializedBody, updateNote, expectHttpError, createResource, expectNotThrow } from '../../utils/testing/testUtils';
import { postApi, patchApi, getApi, deleteApi } from '../../utils/testing/apiUtils';
import { PaginatedDeltaChanges } from '../../models/ChangeModel';
import { inviteUserToShare, shareFolderWithUser } from '../../utils/testing/shareApiUtils';
@ -367,6 +367,24 @@ describe('shares.folder', function() {
expect(newChildren.items[0].id).toBe(folderItem1.id);
});
test('should not throw an error if an item is associated with a share that no longer exists', async function() {
const { session: session1 } = await createUserAndSession(1);
const { session: session2 } = await createUserAndSession(2);
const { share } = await shareFolderWithUser(session1.id, session2.id, '000000000000000000000000000000F1', {
'000000000000000000000000000000F1': {},
});
await createNote(session1.id, {
id: '00000000000000000000000000000007',
share_id: share.id,
});
await models().share().delete(share.id);
await expectNotThrow(async () => await models().share().updateSharedItems3());
});
test('should unshare a deleted item', async function() {
const { user: user1, session: session1 } = await createUserAndSession(1);
const { user: user2, session: session2 } = await createUserAndSession(2);