You've already forked joplin
mirror of
https://github.com/laurent22/joplin.git
synced 2025-12-08 23:07:32 +02:00
Compare commits
5 Commits
server-v3.
...
sharing_bu
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
f53bb2d167 | ||
|
|
113b259b81 | ||
|
|
c7e31d1ac9 | ||
|
|
c51b13ca73 | ||
|
|
f5febb18b4 |
@@ -182,6 +182,12 @@ do
|
|||||||
fi
|
fi
|
||||||
done
|
done
|
||||||
|
|
||||||
|
echo '----------------------------------------------------'
|
||||||
|
echo 'Running commands:'
|
||||||
|
echo '';
|
||||||
|
cat "$CMD_FILE"
|
||||||
|
echo '----------------------------------------------------'
|
||||||
|
|
||||||
cd "$ROOT_DIR/packages/app-cli"
|
cd "$ROOT_DIR/packages/app-cli"
|
||||||
yarn start --profile "$PROFILE_DIR" batch "$CMD_FILE"
|
yarn start --profile "$PROFILE_DIR" batch "$CMD_FILE"
|
||||||
|
|
||||||
|
|||||||
@@ -448,6 +448,7 @@ export default class Synchronizer {
|
|||||||
// Before synchronising make sure all share_id properties are set
|
// Before synchronising make sure all share_id properties are set
|
||||||
// correctly so as to share/unshare the right items.
|
// correctly so as to share/unshare the right items.
|
||||||
try {
|
try {
|
||||||
|
if (this.shareService_) await this.shareService_.maintenance();
|
||||||
await Folder.updateAllShareIds(this.resourceService(), this.shareService_ ? this.shareService_.shares : []);
|
await Folder.updateAllShareIds(this.resourceService(), this.shareService_ ? this.shareService_.shares : []);
|
||||||
if (this.shareService_) await this.shareService_.checkShareConsistency();
|
if (this.shareService_) await this.shareService_.checkShareConsistency();
|
||||||
} catch (error) {
|
} catch (error) {
|
||||||
|
|||||||
@@ -10,6 +10,25 @@ import { StateShare } from '../services/share/reducer';
|
|||||||
|
|
||||||
const testImagePath = `${supportDir}/photo.jpg`;
|
const testImagePath = `${supportDir}/photo.jpg`;
|
||||||
|
|
||||||
|
const makeStateShares = (folderIds: string[] | string, shareIds: string|string[] = 'abcd1234'): StateShare[] => {
|
||||||
|
folderIds = (typeof folderIds === 'string') ? [folderIds] : folderIds;
|
||||||
|
shareIds = (typeof shareIds === 'string') ? [shareIds] : shareIds;
|
||||||
|
|
||||||
|
const output: StateShare[] = [];
|
||||||
|
|
||||||
|
for (let i = 0; i < folderIds.length; i++) {
|
||||||
|
output.push({
|
||||||
|
folder_id: folderIds[i],
|
||||||
|
master_key_id: '',
|
||||||
|
id: shareIds[i],
|
||||||
|
note_id: '',
|
||||||
|
type: 3,
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
return output;
|
||||||
|
};
|
||||||
|
|
||||||
describe('models/Folder.sharing', () => {
|
describe('models/Folder.sharing', () => {
|
||||||
|
|
||||||
beforeEach(async () => {
|
beforeEach(async () => {
|
||||||
@@ -41,7 +60,7 @@ describe('models/Folder.sharing', () => {
|
|||||||
]);
|
]);
|
||||||
|
|
||||||
await Folder.save({ id: folder.id, share_id: 'abcd1234' });
|
await Folder.save({ id: folder.id, share_id: 'abcd1234' });
|
||||||
await Folder.updateAllShareIds(resourceService(), []);
|
await Folder.updateAllShareIds(resourceService(), makeStateShares(folder.id));
|
||||||
|
|
||||||
const allItems = await allNotesFolders();
|
const allItems = await allNotesFolders();
|
||||||
for (const item of allItems) {
|
for (const item of allItems) {
|
||||||
@@ -87,7 +106,7 @@ describe('models/Folder.sharing', () => {
|
|||||||
|
|
||||||
await Folder.save({ id: folder1.id, share_id: 'abcd1234' });
|
await Folder.save({ id: folder1.id, share_id: 'abcd1234' });
|
||||||
|
|
||||||
await Folder.updateAllShareIds(resourceService(), []);
|
await Folder.updateAllShareIds(resourceService(), makeStateShares(folder1.id));
|
||||||
|
|
||||||
folder1 = await Folder.loadByTitle('folder 1');
|
folder1 = await Folder.loadByTitle('folder 1');
|
||||||
const folder2 = await Folder.loadByTitle('folder 2');
|
const folder2 = await Folder.loadByTitle('folder 2');
|
||||||
@@ -121,7 +140,7 @@ describe('models/Folder.sharing', () => {
|
|||||||
|
|
||||||
await Folder.save({ id: folder1.id, share_id: 'abcd1234' });
|
await Folder.save({ id: folder1.id, share_id: 'abcd1234' });
|
||||||
|
|
||||||
await Folder.updateAllShareIds(resourceService(), []);
|
await Folder.updateAllShareIds(resourceService(), makeStateShares(folder1.id));
|
||||||
|
|
||||||
folder1 = await Folder.loadByTitle('folder 1');
|
folder1 = await Folder.loadByTitle('folder 1');
|
||||||
let folder2 = await Folder.loadByTitle('folder 2');
|
let folder2 = await Folder.loadByTitle('folder 2');
|
||||||
@@ -133,7 +152,7 @@ describe('models/Folder.sharing', () => {
|
|||||||
// Move the folder outside the shared folder
|
// Move the folder outside the shared folder
|
||||||
|
|
||||||
await Folder.save({ id: folder2.id, parent_id: folder3.id });
|
await Folder.save({ id: folder2.id, parent_id: folder3.id });
|
||||||
await Folder.updateAllShareIds(resourceService(), []);
|
await Folder.updateAllShareIds(resourceService(), makeStateShares(folder1.id));
|
||||||
folder2 = await Folder.loadByTitle('folder 2');
|
folder2 = await Folder.loadByTitle('folder 2');
|
||||||
expect(folder2.share_id).toBe('');
|
expect(folder2.share_id).toBe('');
|
||||||
|
|
||||||
@@ -141,7 +160,7 @@ describe('models/Folder.sharing', () => {
|
|||||||
|
|
||||||
{
|
{
|
||||||
await Folder.save({ id: folder2.id, parent_id: folder1.id });
|
await Folder.save({ id: folder2.id, parent_id: folder1.id });
|
||||||
await Folder.updateAllShareIds(resourceService(), []);
|
await Folder.updateAllShareIds(resourceService(), makeStateShares(folder1.id));
|
||||||
folder2 = await Folder.loadByTitle('folder 2');
|
folder2 = await Folder.loadByTitle('folder 2');
|
||||||
expect(folder2.share_id).toBe('abcd1234');
|
expect(folder2.share_id).toBe('abcd1234');
|
||||||
}
|
}
|
||||||
@@ -162,15 +181,7 @@ describe('models/Folder.sharing', () => {
|
|||||||
|
|
||||||
await Folder.save({ id: folder1.id, share_id: 'abcd1234' });
|
await Folder.save({ id: folder1.id, share_id: 'abcd1234' });
|
||||||
|
|
||||||
const stateShares: StateShare[] = [
|
const stateShares: StateShare[] = makeStateShares(folder1.id);
|
||||||
{
|
|
||||||
folder_id: folder1.id,
|
|
||||||
id: 'abcd1234',
|
|
||||||
master_key_id: '',
|
|
||||||
note_id: '',
|
|
||||||
type: 3,
|
|
||||||
},
|
|
||||||
];
|
|
||||||
|
|
||||||
await Folder.updateAllShareIds(resourceService(), stateShares);
|
await Folder.updateAllShareIds(resourceService(), stateShares);
|
||||||
|
|
||||||
@@ -221,7 +232,7 @@ describe('models/Folder.sharing', () => {
|
|||||||
|
|
||||||
await Folder.save({ id: folder1.id, share_id: 'abcd1234' });
|
await Folder.save({ id: folder1.id, share_id: 'abcd1234' });
|
||||||
|
|
||||||
await Folder.updateAllShareIds(resourceService(), []);
|
await Folder.updateAllShareIds(resourceService(), makeStateShares(folder1.id));
|
||||||
|
|
||||||
const note1: NoteEntity = await Note.loadByTitle('note 1');
|
const note1: NoteEntity = await Note.loadByTitle('note 1');
|
||||||
const note2: NoteEntity = await Note.loadByTitle('note 2');
|
const note2: NoteEntity = await Note.loadByTitle('note 2');
|
||||||
@@ -251,7 +262,7 @@ describe('models/Folder.sharing', () => {
|
|||||||
]);
|
]);
|
||||||
|
|
||||||
await Folder.save({ id: folder1.id, share_id: 'abcd1234' });
|
await Folder.save({ id: folder1.id, share_id: 'abcd1234' });
|
||||||
await Folder.updateAllShareIds(resourceService(), []);
|
await Folder.updateAllShareIds(resourceService(), makeStateShares(folder1.id));
|
||||||
const note1: NoteEntity = await Note.loadByTitle('note 1');
|
const note1: NoteEntity = await Note.loadByTitle('note 1');
|
||||||
const folder2: FolderEntity = await Folder.loadByTitle('folder 2');
|
const folder2: FolderEntity = await Folder.loadByTitle('folder 2');
|
||||||
expect(note1.share_id).toBe('abcd1234');
|
expect(note1.share_id).toBe('abcd1234');
|
||||||
@@ -259,7 +270,7 @@ describe('models/Folder.sharing', () => {
|
|||||||
// Move the note outside of the shared folder
|
// Move the note outside of the shared folder
|
||||||
|
|
||||||
await Note.save({ id: note1.id, parent_id: folder2.id });
|
await Note.save({ id: note1.id, parent_id: folder2.id });
|
||||||
await Folder.updateAllShareIds(resourceService(), []);
|
await Folder.updateAllShareIds(resourceService(), makeStateShares(folder1.id));
|
||||||
|
|
||||||
{
|
{
|
||||||
const note1: NoteEntity = await Note.loadByTitle('note 1');
|
const note1: NoteEntity = await Note.loadByTitle('note 1');
|
||||||
@@ -269,7 +280,7 @@ describe('models/Folder.sharing', () => {
|
|||||||
// Move the note back inside the shared folder
|
// Move the note back inside the shared folder
|
||||||
|
|
||||||
await Note.save({ id: note1.id, parent_id: folder1.id });
|
await Note.save({ id: note1.id, parent_id: folder1.id });
|
||||||
await Folder.updateAllShareIds(resourceService(), []);
|
await Folder.updateAllShareIds(resourceService(), makeStateShares(folder1.id));
|
||||||
|
|
||||||
{
|
{
|
||||||
const note1: NoteEntity = await Note.loadByTitle('note 1');
|
const note1: NoteEntity = await Note.loadByTitle('note 1');
|
||||||
@@ -297,7 +308,7 @@ describe('models/Folder.sharing', () => {
|
|||||||
]);
|
]);
|
||||||
|
|
||||||
await Folder.save({ id: folder1.id, share_id: 'abcd1234' });
|
await Folder.save({ id: folder1.id, share_id: 'abcd1234' });
|
||||||
await Folder.updateAllShareIds(resourceService(), []);
|
await Folder.updateAllShareIds(resourceService(), makeStateShares(folder1.id));
|
||||||
|
|
||||||
let note1: NoteEntity = await Note.loadByTitle('note 1');
|
let note1: NoteEntity = await Note.loadByTitle('note 1');
|
||||||
let note2: NoteEntity = await Note.loadByTitle('note 2');
|
let note2: NoteEntity = await Note.loadByTitle('note 2');
|
||||||
@@ -307,7 +318,7 @@ describe('models/Folder.sharing', () => {
|
|||||||
expect(note2.share_id).toBe('abcd1234');
|
expect(note2.share_id).toBe('abcd1234');
|
||||||
|
|
||||||
await Note.save({ id: note1.id, parent_id: folder2.id });
|
await Note.save({ id: note1.id, parent_id: folder2.id });
|
||||||
await Folder.updateAllShareIds(resourceService(), []);
|
await Folder.updateAllShareIds(resourceService(), makeStateShares(folder1.id));
|
||||||
|
|
||||||
note1 = await Note.loadByTitle('note 1');
|
note1 = await Note.loadByTitle('note 1');
|
||||||
note2 = await Note.loadByTitle('note 2');
|
note2 = await Note.loadByTitle('note 2');
|
||||||
@@ -315,6 +326,60 @@ describe('models/Folder.sharing', () => {
|
|||||||
expect(note2.share_id).toBe('abcd1234');
|
expect(note2.share_id).toBe('abcd1234');
|
||||||
}));
|
}));
|
||||||
|
|
||||||
|
it('should clear the share ID if that share no longer exists', (async () => {
|
||||||
|
const folder1 = await createFolderTree('', [
|
||||||
|
{
|
||||||
|
title: 'folder 1',
|
||||||
|
children: [
|
||||||
|
{
|
||||||
|
title: 'note 1',
|
||||||
|
},
|
||||||
|
{
|
||||||
|
title: 'note 2',
|
||||||
|
},
|
||||||
|
{
|
||||||
|
title: 'subfolder',
|
||||||
|
children: [],
|
||||||
|
},
|
||||||
|
],
|
||||||
|
},
|
||||||
|
{
|
||||||
|
title: 'folder 2',
|
||||||
|
children: [],
|
||||||
|
},
|
||||||
|
]);
|
||||||
|
|
||||||
|
let note1: NoteEntity = await Note.loadByTitle('note 1');
|
||||||
|
await shim.attachFileToNote(note1, testImagePath);
|
||||||
|
await resourceService().indexNoteResources();
|
||||||
|
|
||||||
|
await Folder.save({ id: folder1.id, share_id: 'abcd1234' });
|
||||||
|
|
||||||
|
await Folder.updateAllShareIds(resourceService(), makeStateShares(folder1.id));
|
||||||
|
|
||||||
|
note1 = await Note.loadByTitle('note 1');
|
||||||
|
let note2: NoteEntity = await Note.loadByTitle('note 2');
|
||||||
|
let resource: ResourceEntity = (await Resource.all())[0];
|
||||||
|
let subFolder: FolderEntity = await Folder.loadByTitle('subfolder');
|
||||||
|
|
||||||
|
expect(note1.share_id).toBe('abcd1234');
|
||||||
|
expect(note2.share_id).toBe('abcd1234');
|
||||||
|
expect(resource.share_id).toBe('abcd1234');
|
||||||
|
expect(subFolder.share_id).toBe('abcd1234');
|
||||||
|
|
||||||
|
await Folder.updateAllShareIds(resourceService(), []);
|
||||||
|
|
||||||
|
note1 = await Note.loadByTitle('note 1');
|
||||||
|
note2 = await Note.loadByTitle('note 2');
|
||||||
|
resource = (await Resource.all())[0];
|
||||||
|
subFolder = await Folder.loadByTitle('subfolder');
|
||||||
|
|
||||||
|
expect(note1.share_id).toBe('');
|
||||||
|
expect(note2.share_id).toBe('');
|
||||||
|
expect(resource.share_id).toBe('');
|
||||||
|
expect(subFolder.share_id).toBe('');
|
||||||
|
}));
|
||||||
|
|
||||||
it('should apply the note share ID to its resources', async () => {
|
it('should apply the note share ID to its resources', async () => {
|
||||||
const resourceService = new ResourceService();
|
const resourceService = new ResourceService();
|
||||||
|
|
||||||
@@ -337,7 +402,7 @@ describe('models/Folder.sharing', () => {
|
|||||||
]);
|
]);
|
||||||
|
|
||||||
await Folder.save({ id: folder.id, share_id: 'abcd1234' });
|
await Folder.save({ id: folder.id, share_id: 'abcd1234' });
|
||||||
await Folder.updateAllShareIds(resourceService, []);
|
await Folder.updateAllShareIds(resourceService, makeStateShares(folder.id));
|
||||||
|
|
||||||
const folder2: FolderEntity = await Folder.loadByTitle('folder 2');
|
const folder2: FolderEntity = await Folder.loadByTitle('folder 2');
|
||||||
const note1: NoteEntity = await Note.loadByTitle('note 1');
|
const note1: NoteEntity = await Note.loadByTitle('note 1');
|
||||||
@@ -355,7 +420,7 @@ describe('models/Folder.sharing', () => {
|
|||||||
|
|
||||||
const previousBlobUpdatedTime = (await Resource.load(resourceId)).blob_updated_time;
|
const previousBlobUpdatedTime = (await Resource.load(resourceId)).blob_updated_time;
|
||||||
await msleep(1);
|
await msleep(1);
|
||||||
await Folder.updateAllShareIds(resourceService, []);
|
await Folder.updateAllShareIds(resourceService, makeStateShares(folder.id));
|
||||||
|
|
||||||
{
|
{
|
||||||
const resource: ResourceEntity = await Resource.load(resourceId);
|
const resource: ResourceEntity = await Resource.load(resourceId);
|
||||||
@@ -366,7 +431,7 @@ describe('models/Folder.sharing', () => {
|
|||||||
await Note.save({ id: note1.id, parent_id: folder2.id });
|
await Note.save({ id: note1.id, parent_id: folder2.id });
|
||||||
await resourceService.indexNoteResources();
|
await resourceService.indexNoteResources();
|
||||||
|
|
||||||
await Folder.updateAllShareIds(resourceService, []);
|
await Folder.updateAllShareIds(resourceService, makeStateShares(folder.id));
|
||||||
|
|
||||||
{
|
{
|
||||||
const resource: ResourceEntity = await Resource.load(resourceId);
|
const resource: ResourceEntity = await Resource.load(resourceId);
|
||||||
@@ -434,7 +499,7 @@ describe('models/Folder.sharing', () => {
|
|||||||
// We need to index the resources to populate the note_resources table
|
// We need to index the resources to populate the note_resources table
|
||||||
|
|
||||||
await resourceService.indexNoteResources();
|
await resourceService.indexNoteResources();
|
||||||
await Folder.updateAllShareIds(resourceService, []);
|
await Folder.updateAllShareIds(resourceService, makeStateShares(folder1.id, 'share1'));
|
||||||
|
|
||||||
// BEFORE:
|
// BEFORE:
|
||||||
//
|
//
|
||||||
@@ -506,7 +571,7 @@ describe('models/Folder.sharing', () => {
|
|||||||
|
|
||||||
await resourceService.indexNoteResources();
|
await resourceService.indexNoteResources();
|
||||||
|
|
||||||
await Folder.updateAllShareIds(resourceService, []);
|
await Folder.updateAllShareIds(resourceService, makeStateShares([folder1.id, folder2.id], ['1', '2']));
|
||||||
|
|
||||||
await Folder.updateNoLongerSharedItems(['1']);
|
await Folder.updateNoLongerSharedItems(['1']);
|
||||||
|
|
||||||
|
|||||||
@@ -484,7 +484,8 @@ export default class Folder extends BaseItem {
|
|||||||
public static async updateFolderShareIds(activeShares: StateShare[]): Promise<void> {
|
public static async updateFolderShareIds(activeShares: StateShare[]): Promise<void> {
|
||||||
// Get all the sub-folders of the shared folders, and set the share_id
|
// Get all the sub-folders of the shared folders, and set the share_id
|
||||||
// property.
|
// property.
|
||||||
const rootFolders = await this.rootSharedFolders(activeShares);
|
const activeShareIds = activeShares.map(s => s.id);
|
||||||
|
const rootFolders = (await this.rootSharedFolders(activeShares)).filter(f => activeShareIds.includes(f.share_id));
|
||||||
|
|
||||||
let sharedFolderIds: string[] = [];
|
let sharedFolderIds: string[] = [];
|
||||||
|
|
||||||
@@ -538,19 +539,26 @@ export default class Folder extends BaseItem {
|
|||||||
logger.debug('updateFolderShareIds:', report);
|
logger.debug('updateFolderShareIds:', report);
|
||||||
}
|
}
|
||||||
|
|
||||||
public static async updateNoteShareIds() {
|
public static async updateNoteShareIds(activeShares: StateShare[]) {
|
||||||
// Find all the notes where the share_id is not the same as the
|
// Find all the notes where the share_id is not the same as the
|
||||||
// parent share_id because we only need to update those.
|
// parent share_id because we only need to update those.
|
||||||
const rows = await this.db().selectAll(`
|
const rows1 = await this.db().selectAll(`
|
||||||
SELECT notes.id, folders.share_id, notes.parent_id
|
SELECT notes.id, folders.share_id, notes.parent_id
|
||||||
FROM notes
|
FROM notes
|
||||||
LEFT JOIN folders ON notes.parent_id = folders.id
|
LEFT JOIN folders ON notes.parent_id = folders.id
|
||||||
WHERE notes.share_id != folders.share_id
|
WHERE notes.share_id != folders.share_id
|
||||||
`);
|
`);
|
||||||
|
|
||||||
logger.debug('updateNoteShareIds: notes to update:', rows.length);
|
const rows2 = await this.db().selectAll(`
|
||||||
|
SELECT notes.id, notes.parent_id
|
||||||
|
FROM notes
|
||||||
|
WHERE notes.share_id != '' AND notes.share_id NOT IN (${BaseModel.escapeIdsForSql(activeShares.map(s => s.id))})
|
||||||
|
`);
|
||||||
|
|
||||||
for (const row of rows) {
|
logger.debug('updateNoteShareIds: notes to update (1)', rows1);
|
||||||
|
logger.debug('updateNoteShareIds: notes to update (2)', rows2);
|
||||||
|
|
||||||
|
for (const row of rows1.concat(rows2)) {
|
||||||
await Note.save({
|
await Note.save({
|
||||||
id: row.id,
|
id: row.id,
|
||||||
share_id: row.share_id || '',
|
share_id: row.share_id || '',
|
||||||
@@ -710,7 +718,7 @@ export default class Folder extends BaseItem {
|
|||||||
|
|
||||||
public static async updateAllShareIds(resourceService: ResourceService, activeShares: StateShare[]) {
|
public static async updateAllShareIds(resourceService: ResourceService, activeShares: StateShare[]) {
|
||||||
await this.updateFolderShareIds(activeShares);
|
await this.updateFolderShareIds(activeShares);
|
||||||
await this.updateNoteShareIds();
|
await this.updateNoteShareIds(activeShares);
|
||||||
await this.updateResourceShareIds(resourceService);
|
await this.updateResourceShareIds(resourceService);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -18,6 +18,17 @@ import Setting from '../../models/Setting';
|
|||||||
import { ModelType } from '../../BaseModel';
|
import { ModelType } from '../../BaseModel';
|
||||||
import { remoteNotesFoldersResources } from '../../testing/test-utils-synchronizer';
|
import { remoteNotesFoldersResources } from '../../testing/test-utils-synchronizer';
|
||||||
import mockShareService from '../../testing/share/mockShareService';
|
import mockShareService from '../../testing/share/mockShareService';
|
||||||
|
import { StateShare } from './reducer';
|
||||||
|
|
||||||
|
const makeStateShares = (folderId: string, shareId = 'abcd1234'): StateShare[] => {
|
||||||
|
return [{
|
||||||
|
folder_id: folderId,
|
||||||
|
master_key_id: '',
|
||||||
|
id: shareId,
|
||||||
|
note_id: '',
|
||||||
|
type: 3,
|
||||||
|
}];
|
||||||
|
};
|
||||||
|
|
||||||
interface TestShareFolderServiceOptions {
|
interface TestShareFolderServiceOptions {
|
||||||
master_key_id?: string;
|
master_key_id?: string;
|
||||||
@@ -157,7 +168,7 @@ describe('ShareService', () => {
|
|||||||
|
|
||||||
async function testShareFolder(service: ShareService) {
|
async function testShareFolder(service: ShareService) {
|
||||||
const { folder, note, resource } = await prepareNoteFolderResource();
|
const { folder, note, resource } = await prepareNoteFolderResource();
|
||||||
const share = await service.shareFolder(folder.id);
|
const share = await service.shareFolder(folder.id, makeStateShares(folder.id, 'share_1'));
|
||||||
expect(share.id).toBe('share_1');
|
expect(share.id).toBe('share_1');
|
||||||
expect((await Folder.load(folder.id)).share_id).toBe('share_1');
|
expect((await Folder.load(folder.id)).share_id).toBe('share_1');
|
||||||
expect((await Note.load(note.id)).share_id).toBe('share_1');
|
expect((await Note.load(note.id)).share_id).toBe('share_1');
|
||||||
@@ -185,9 +196,9 @@ describe('ShareService', () => {
|
|||||||
BaseItem.shareService_ = shareService;
|
BaseItem.shareService_ = shareService;
|
||||||
Resource.shareService_ = shareService;
|
Resource.shareService_ = shareService;
|
||||||
|
|
||||||
await shareService.shareFolder(folder.id);
|
const share = await shareService.shareFolder(folder.id, makeStateShares(folder.id, 'share_1'));
|
||||||
|
|
||||||
await Folder.updateAllShareIds(resourceService(), []);
|
await Folder.updateAllShareIds(resourceService(), makeStateShares(folder.id, share.id));
|
||||||
|
|
||||||
// The share service should automatically create a new encryption key
|
// The share service should automatically create a new encryption key
|
||||||
// specifically for that shared folder
|
// specifically for that shared folder
|
||||||
@@ -318,7 +329,7 @@ describe('ShareService', () => {
|
|||||||
const cleanup = simulateReadOnlyShareEnv('123456789');
|
const cleanup = simulateReadOnlyShareEnv('123456789');
|
||||||
|
|
||||||
const shareService = testShareFolderService();
|
const shareService = testShareFolderService();
|
||||||
await shareService.leaveSharedFolder(folder1.id, 'somethingrandom');
|
await shareService.leaveSharedFolder(folder1.id, 'somethingrandom', BaseItem.syncShareCache.shares);
|
||||||
|
|
||||||
expect(await Folder.count()).toBe(0);
|
expect(await Folder.count()).toBe(0);
|
||||||
expect(await Note.count()).toBe(0);
|
expect(await Note.count()).toBe(0);
|
||||||
|
|||||||
@@ -98,7 +98,9 @@ export default class ShareService {
|
|||||||
return this.api_;
|
return this.api_;
|
||||||
}
|
}
|
||||||
|
|
||||||
public async shareFolder(folderId: string): Promise<ApiShare> {
|
public async shareFolder(folderId: string, stateShares: StateShare[]|null = null): Promise<ApiShare> {
|
||||||
|
if (stateShares === null) stateShares = this.shares;
|
||||||
|
|
||||||
const folder = await Folder.load(folderId);
|
const folder = await Folder.load(folderId);
|
||||||
if (!folder) throw new Error(`No such folder: ${folderId}`);
|
if (!folder) throw new Error(`No such folder: ${folderId}`);
|
||||||
|
|
||||||
@@ -137,7 +139,7 @@ export default class ShareService {
|
|||||||
// Note: race condition if the share is created but the app crashes
|
// Note: race condition if the share is created but the app crashes
|
||||||
// before setting share_id on the folder. See unshareFolder() for info.
|
// before setting share_id on the folder. See unshareFolder() for info.
|
||||||
await Folder.save({ id: folder.id, share_id: share.id });
|
await Folder.save({ id: folder.id, share_id: share.id });
|
||||||
await Folder.updateAllShareIds(ResourceService.instance(), this.shares);
|
await Folder.updateAllShareIds(ResourceService.instance(), stateShares);
|
||||||
|
|
||||||
return share;
|
return share;
|
||||||
}
|
}
|
||||||
@@ -206,17 +208,19 @@ export default class ShareService {
|
|||||||
// If `folderShareUserId` is provided, the function will check that the user
|
// If `folderShareUserId` is provided, the function will check that the user
|
||||||
// does not own the share. It would be an error to leave such a folder
|
// does not own the share. It would be an error to leave such a folder
|
||||||
// (instead "unshareFolder" should be called).
|
// (instead "unshareFolder" should be called).
|
||||||
public async leaveSharedFolder(folderId: string, folderShareUserId: string = null): Promise<void> {
|
public async leaveSharedFolder(folderId: string, folderShareUserId: string = null, stateShares: StateShare[]|null = null): Promise<void> {
|
||||||
if (folderShareUserId !== null) {
|
if (folderShareUserId !== null) {
|
||||||
const userId = Setting.value('sync.userId');
|
const userId = Setting.value('sync.userId');
|
||||||
if (folderShareUserId === userId) throw new Error('Cannot leave own notebook');
|
if (folderShareUserId === userId) throw new Error('Cannot leave own notebook');
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (stateShares === null) stateShares = this.shares;
|
||||||
|
|
||||||
const folder = await Folder.load(folderId);
|
const folder = await Folder.load(folderId);
|
||||||
|
|
||||||
// We call this to make sure all items are correctly linked before we
|
// We call this to make sure all items are correctly linked before we
|
||||||
// call deleteAllByShareId()
|
// call deleteAllByShareId()
|
||||||
await Folder.updateAllShareIds(ResourceService.instance(), this.shares);
|
await Folder.updateAllShareIds(ResourceService.instance(), stateShares);
|
||||||
|
|
||||||
const source = 'ShareService.leaveSharedFolder';
|
const source = 'ShareService.leaveSharedFolder';
|
||||||
await Folder.delete(folderId, { deleteChildren: false, disableReadOnlyCheck: true, sourceDescription: source });
|
await Folder.delete(folderId, { deleteChildren: false, disableReadOnlyCheck: true, sourceDescription: source });
|
||||||
|
|||||||
Reference in New Issue
Block a user