cozy-sharing 28.9.2 → 28.11.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/CHANGELOG.md +12 -0
- package/dist/SharingProvider.js +66 -25
- package/dist/SharingProvider.spec.js +138 -42
- package/jest.config.js +3 -1
- package/package.json +9 -9
- package/src/SharingProvider.jsx +13 -1
- package/src/SharingProvider.spec.jsx +57 -0
package/CHANGELOG.md
CHANGED
|
@@ -3,6 +3,18 @@
|
|
|
3
3
|
All notable changes to this project will be documented in this file.
|
|
4
4
|
See [Conventional Commits](https://conventionalcommits.org) for commit guidelines.
|
|
5
5
|
|
|
6
|
+
# [28.11.0](https://github.com/cozy/cozy-libs/compare/cozy-sharing@28.10.0...cozy-sharing@28.11.0) (2026-03-17)
|
|
7
|
+
|
|
8
|
+
### Features
|
|
9
|
+
|
|
10
|
+
- Upgrade Jest to 28 ([b92c56c](https://github.com/cozy/cozy-libs/commit/b92c56ce2fdd65b3dd8e9c5170dc5eb86cc369a7))
|
|
11
|
+
|
|
12
|
+
# [28.10.0](https://github.com/cozy/cozy-libs/compare/cozy-sharing@28.9.2...cozy-sharing@28.10.0) (2026-03-17)
|
|
13
|
+
|
|
14
|
+
### Features
|
|
15
|
+
|
|
16
|
+
- Allow to revoke shared drive file sharing link ([7cff1da](https://github.com/cozy/cozy-libs/commit/7cff1da36a8b048a25efd302a5e3e0efb114e327))
|
|
17
|
+
|
|
6
18
|
## [28.9.2](https://github.com/cozy/cozy-libs/compare/cozy-sharing@28.9.1...cozy-sharing@28.9.2) (2026-03-16)
|
|
7
19
|
|
|
8
20
|
**Note:** Version bump only for package cozy-sharing
|
package/dist/SharingProvider.js
CHANGED
|
@@ -788,32 +788,73 @@ export var SharingProvider = /*#__PURE__*/function (_Component) {
|
|
|
788
788
|
};
|
|
789
789
|
}());
|
|
790
790
|
|
|
791
|
-
_defineProperty(_this2, "
|
|
792
|
-
var _ref18 = _asyncToGenerator( /*#__PURE__*/_regeneratorRuntime.mark(function _callee16(document) {
|
|
793
|
-
var
|
|
791
|
+
_defineProperty(_this2, "revokeSharedDriveSharingLink", /*#__PURE__*/function () {
|
|
792
|
+
var _ref18 = _asyncToGenerator( /*#__PURE__*/_regeneratorRuntime.mark(function _callee16(document, perms) {
|
|
793
|
+
var client, drivePermissionCollection;
|
|
794
794
|
return _regeneratorRuntime.wrap(function _callee16$(_context16) {
|
|
795
795
|
while (1) switch (_context16.prev = _context16.next) {
|
|
796
|
+
case 0:
|
|
797
|
+
client = _this2.props.client;
|
|
798
|
+
drivePermissionCollection = client.collection('io.cozy.permissions', {
|
|
799
|
+
driveId: document.driveId
|
|
800
|
+
});
|
|
801
|
+
_context16.next = 4;
|
|
802
|
+
return Promise.all(perms.map(function (p) {
|
|
803
|
+
return drivePermissionCollection.destroy(p);
|
|
804
|
+
}));
|
|
805
|
+
|
|
806
|
+
case 4:
|
|
807
|
+
case "end":
|
|
808
|
+
return _context16.stop();
|
|
809
|
+
}
|
|
810
|
+
}, _callee16);
|
|
811
|
+
}));
|
|
812
|
+
|
|
813
|
+
return function (_x30, _x31) {
|
|
814
|
+
return _ref18.apply(this, arguments);
|
|
815
|
+
};
|
|
816
|
+
}());
|
|
817
|
+
|
|
818
|
+
_defineProperty(_this2, "revokeSharingLink", /*#__PURE__*/function () {
|
|
819
|
+
var _ref19 = _asyncToGenerator( /*#__PURE__*/_regeneratorRuntime.mark(function _callee17(document) {
|
|
820
|
+
var perms;
|
|
821
|
+
return _regeneratorRuntime.wrap(function _callee17$(_context17) {
|
|
822
|
+
while (1) switch (_context17.prev = _context17.next) {
|
|
796
823
|
case 0:
|
|
797
824
|
// Because some duplicate links have been created in the past, we must ensure
|
|
798
825
|
// we revoke all of them
|
|
799
826
|
perms = _getDocumentPermissions(_this2.state, document.id);
|
|
800
|
-
|
|
827
|
+
|
|
828
|
+
if (!document.driveId) {
|
|
829
|
+
_context17.next = 6;
|
|
830
|
+
break;
|
|
831
|
+
}
|
|
832
|
+
|
|
833
|
+
_context17.next = 4;
|
|
834
|
+
return _this2.revokeSharedDriveSharingLink(document, perms);
|
|
835
|
+
|
|
836
|
+
case 4:
|
|
837
|
+
_context17.next = 8;
|
|
838
|
+
break;
|
|
839
|
+
|
|
840
|
+
case 6:
|
|
841
|
+
_context17.next = 8;
|
|
801
842
|
return Promise.all(perms.map(function (p) {
|
|
802
843
|
return _this2.permissionCol.destroy(p);
|
|
803
844
|
}));
|
|
804
845
|
|
|
805
|
-
case
|
|
846
|
+
case 8:
|
|
806
847
|
_this2.dispatch(revokeSharingLink(perms));
|
|
807
848
|
|
|
808
|
-
case
|
|
849
|
+
case 9:
|
|
809
850
|
case "end":
|
|
810
|
-
return
|
|
851
|
+
return _context17.stop();
|
|
811
852
|
}
|
|
812
|
-
},
|
|
853
|
+
}, _callee17);
|
|
813
854
|
}));
|
|
814
855
|
|
|
815
|
-
return function (
|
|
816
|
-
return
|
|
856
|
+
return function (_x32) {
|
|
857
|
+
return _ref19.apply(this, arguments);
|
|
817
858
|
};
|
|
818
859
|
}());
|
|
819
860
|
|
|
@@ -937,14 +978,14 @@ export var SharingProvider = /*#__PURE__*/function (_Component) {
|
|
|
937
978
|
}, {
|
|
938
979
|
key: "fetchAllSharings",
|
|
939
980
|
value: function () {
|
|
940
|
-
var _fetchAllSharings = _asyncToGenerator( /*#__PURE__*/_regeneratorRuntime.mark(function
|
|
981
|
+
var _fetchAllSharings = _asyncToGenerator( /*#__PURE__*/_regeneratorRuntime.mark(function _callee18() {
|
|
941
982
|
var _this$props, doctype, client, _yield$Promise$all, _yield$Promise$all2, sharings, permissions, apps, sharedDocIds, resp, folderPaths, filePaths;
|
|
942
983
|
|
|
943
|
-
return _regeneratorRuntime.wrap(function
|
|
944
|
-
while (1) switch (
|
|
984
|
+
return _regeneratorRuntime.wrap(function _callee18$(_context18) {
|
|
985
|
+
while (1) switch (_context18.prev = _context18.next) {
|
|
945
986
|
case 0:
|
|
946
987
|
if (!this.isPublic) {
|
|
947
|
-
|
|
988
|
+
_context18.next = 4;
|
|
948
989
|
break;
|
|
949
990
|
}
|
|
950
991
|
|
|
@@ -953,17 +994,17 @@ export var SharingProvider = /*#__PURE__*/function (_Component) {
|
|
|
953
994
|
this.setState({
|
|
954
995
|
allLoaded: true
|
|
955
996
|
});
|
|
956
|
-
return
|
|
997
|
+
return _context18.abrupt("return");
|
|
957
998
|
|
|
958
999
|
case 4:
|
|
959
1000
|
_this$props = this.props, doctype = _this$props.doctype, client = _this$props.client;
|
|
960
|
-
|
|
1001
|
+
_context18.next = 7;
|
|
961
1002
|
return Promise.all([this.sharingCol.findByDoctype(doctype, {
|
|
962
1003
|
withSharedDocs: false
|
|
963
1004
|
}), this.permissionCol.findLinksByDoctype(doctype), client.fetchQueryAndGetFromState(fetchApps())]);
|
|
964
1005
|
|
|
965
1006
|
case 7:
|
|
966
|
-
_yield$Promise$all =
|
|
1007
|
+
_yield$Promise$all = _context18.sent;
|
|
967
1008
|
_yield$Promise$all2 = _slicedToArray(_yield$Promise$all, 3);
|
|
968
1009
|
sharings = _yield$Promise$all2[0];
|
|
969
1010
|
permissions = _yield$Promise$all2[1];
|
|
@@ -977,35 +1018,35 @@ export var SharingProvider = /*#__PURE__*/function (_Component) {
|
|
|
977
1018
|
this.setState({
|
|
978
1019
|
hasLoadedAtLeastOnePage: true
|
|
979
1020
|
});
|
|
980
|
-
|
|
1021
|
+
_context18.next = 16;
|
|
981
1022
|
return fetchNextPermissions(permissions, this.dispatch, this.permissionCol);
|
|
982
1023
|
|
|
983
1024
|
case 16:
|
|
984
1025
|
if (!(doctype === 'io.cozy.files')) {
|
|
985
|
-
|
|
1026
|
+
_context18.next = 26;
|
|
986
1027
|
break;
|
|
987
1028
|
}
|
|
988
1029
|
|
|
989
1030
|
sharedDocIds = getSharedDocIdsBySharings(sharings);
|
|
990
|
-
|
|
1031
|
+
_context18.next = 20;
|
|
991
1032
|
return client.collection(doctype).all({
|
|
992
1033
|
keys: sharedDocIds
|
|
993
1034
|
});
|
|
994
1035
|
|
|
995
1036
|
case 20:
|
|
996
|
-
resp =
|
|
1037
|
+
resp = _context18.sent;
|
|
997
1038
|
folderPaths = resp.data.filter(function (f) {
|
|
998
1039
|
return f.type === 'directory' && !f.trashed;
|
|
999
1040
|
}).map(function (f) {
|
|
1000
1041
|
return f.path;
|
|
1001
1042
|
});
|
|
1002
|
-
|
|
1043
|
+
_context18.next = 24;
|
|
1003
1044
|
return fetchFilesPaths(client, doctype, resp.data.filter(function (f) {
|
|
1004
1045
|
return f.type !== 'directory' && !f.trashed;
|
|
1005
1046
|
}));
|
|
1006
1047
|
|
|
1007
1048
|
case 24:
|
|
1008
|
-
filePaths =
|
|
1049
|
+
filePaths = _context18.sent;
|
|
1009
1050
|
this.dispatch(receivePaths([].concat(_toConsumableArray(folderPaths), _toConsumableArray(filePaths))));
|
|
1010
1051
|
|
|
1011
1052
|
case 26:
|
|
@@ -1015,9 +1056,9 @@ export var SharingProvider = /*#__PURE__*/function (_Component) {
|
|
|
1015
1056
|
|
|
1016
1057
|
case 27:
|
|
1017
1058
|
case "end":
|
|
1018
|
-
return
|
|
1059
|
+
return _context18.stop();
|
|
1019
1060
|
}
|
|
1020
|
-
},
|
|
1061
|
+
}, _callee18, this);
|
|
1021
1062
|
}));
|
|
1022
1063
|
|
|
1023
1064
|
function fetchAllSharings() {
|
|
@@ -257,6 +257,102 @@ describe('shareByLink', function () {
|
|
|
257
257
|
}, _callee4);
|
|
258
258
|
})));
|
|
259
259
|
});
|
|
260
|
+
describe('revokeSharingLink', function () {
|
|
261
|
+
var PERM = {
|
|
262
|
+
type: 'io.cozy.permissions',
|
|
263
|
+
id: 'perm_1',
|
|
264
|
+
attributes: {
|
|
265
|
+
type: 'share',
|
|
266
|
+
permissions: {
|
|
267
|
+
rule0: {
|
|
268
|
+
type: 'io.cozy.files',
|
|
269
|
+
verbs: ['GET'],
|
|
270
|
+
values: ['file_id']
|
|
271
|
+
}
|
|
272
|
+
}
|
|
273
|
+
}
|
|
274
|
+
};
|
|
275
|
+
var provider;
|
|
276
|
+
var mockDestroy;
|
|
277
|
+
beforeEach(function () {
|
|
278
|
+
mockDestroy = jest.fn().mockResolvedValue({});
|
|
279
|
+
var mockClient = createMockClient({});
|
|
280
|
+
|
|
281
|
+
mockClient.getStackClient = function () {
|
|
282
|
+
return {
|
|
283
|
+
uri: 'http://cozy.local'
|
|
284
|
+
};
|
|
285
|
+
};
|
|
286
|
+
|
|
287
|
+
mockClient.collection = jest.fn().mockReturnValue({
|
|
288
|
+
destroy: mockDestroy
|
|
289
|
+
});
|
|
290
|
+
provider = new SharingProvider({
|
|
291
|
+
client: mockClient
|
|
292
|
+
});
|
|
293
|
+
provider.state = reducer(undefined, addSharingLink(PERM));
|
|
294
|
+
provider.dispatch = jest.fn(function (action) {
|
|
295
|
+
provider.state = reducer(provider.state, action);
|
|
296
|
+
});
|
|
297
|
+
});
|
|
298
|
+
it('uses permissionCol.destroy for a regular file', /*#__PURE__*/_asyncToGenerator( /*#__PURE__*/_regeneratorRuntime.mark(function _callee5() {
|
|
299
|
+
var regularFile;
|
|
300
|
+
return _regeneratorRuntime.wrap(function _callee5$(_context5) {
|
|
301
|
+
while (1) switch (_context5.prev = _context5.next) {
|
|
302
|
+
case 0:
|
|
303
|
+
regularFile = {
|
|
304
|
+
_id: 'file_id',
|
|
305
|
+
id: 'file_id'
|
|
306
|
+
};
|
|
307
|
+
provider.permissionCol = {
|
|
308
|
+
destroy: mockDestroy
|
|
309
|
+
};
|
|
310
|
+
_context5.next = 4;
|
|
311
|
+
return provider.revokeSharingLink(regularFile);
|
|
312
|
+
|
|
313
|
+
case 4:
|
|
314
|
+
expect(mockDestroy).toHaveBeenCalledTimes(1);
|
|
315
|
+
expect(mockDestroy).toHaveBeenCalledWith(PERM);
|
|
316
|
+
expect(provider.dispatch).toHaveBeenCalledTimes(1);
|
|
317
|
+
|
|
318
|
+
case 7:
|
|
319
|
+
case "end":
|
|
320
|
+
return _context5.stop();
|
|
321
|
+
}
|
|
322
|
+
}, _callee5);
|
|
323
|
+
})));
|
|
324
|
+
it('uses drivePermissionCollection.destroy for a shared drive file', /*#__PURE__*/_asyncToGenerator( /*#__PURE__*/_regeneratorRuntime.mark(function _callee6() {
|
|
325
|
+
var driveFile, mockDriveCollection;
|
|
326
|
+
return _regeneratorRuntime.wrap(function _callee6$(_context6) {
|
|
327
|
+
while (1) switch (_context6.prev = _context6.next) {
|
|
328
|
+
case 0:
|
|
329
|
+
driveFile = {
|
|
330
|
+
_id: 'file_id',
|
|
331
|
+
id: 'file_id',
|
|
332
|
+
driveId: 'drive_123'
|
|
333
|
+
};
|
|
334
|
+
mockDriveCollection = {
|
|
335
|
+
destroy: mockDestroy
|
|
336
|
+
};
|
|
337
|
+
provider.props.client.collection = jest.fn().mockReturnValue(mockDriveCollection);
|
|
338
|
+
_context6.next = 5;
|
|
339
|
+
return provider.revokeSharingLink(driveFile);
|
|
340
|
+
|
|
341
|
+
case 5:
|
|
342
|
+
expect(provider.props.client.collection).toHaveBeenCalledWith('io.cozy.permissions', {
|
|
343
|
+
driveId: 'drive_123'
|
|
344
|
+
});
|
|
345
|
+
expect(mockDestroy).toHaveBeenCalledTimes(1);
|
|
346
|
+
expect(mockDestroy).toHaveBeenCalledWith(PERM);
|
|
347
|
+
expect(provider.dispatch).toHaveBeenCalledTimes(1);
|
|
348
|
+
|
|
349
|
+
case 9:
|
|
350
|
+
case "end":
|
|
351
|
+
return _context6.stop();
|
|
352
|
+
}
|
|
353
|
+
}, _callee6);
|
|
354
|
+
})));
|
|
355
|
+
});
|
|
260
356
|
describe('updateDocumentPermissions', function () {
|
|
261
357
|
var PERM_DRIVE_FILE = {
|
|
262
358
|
type: 'io.cozy.permissions',
|
|
@@ -275,10 +371,10 @@ describe('updateDocumentPermissions', function () {
|
|
|
275
371
|
}
|
|
276
372
|
}
|
|
277
373
|
};
|
|
278
|
-
it('sends only one PATCH request for a shared drive file', /*#__PURE__*/_asyncToGenerator( /*#__PURE__*/_regeneratorRuntime.mark(function
|
|
374
|
+
it('sends only one PATCH request for a shared drive file', /*#__PURE__*/_asyncToGenerator( /*#__PURE__*/_regeneratorRuntime.mark(function _callee7() {
|
|
279
375
|
var driveFile, mockAdd, mockClient, provider;
|
|
280
|
-
return _regeneratorRuntime.wrap(function
|
|
281
|
-
while (1) switch (
|
|
376
|
+
return _regeneratorRuntime.wrap(function _callee7$(_context7) {
|
|
377
|
+
while (1) switch (_context7.prev = _context7.next) {
|
|
282
378
|
case 0:
|
|
283
379
|
driveFile = {
|
|
284
380
|
_id: 'file_in_drive',
|
|
@@ -298,7 +394,7 @@ describe('updateDocumentPermissions', function () {
|
|
|
298
394
|
|
|
299
395
|
provider.state = reducer(undefined, addSharingLink(PERM_DRIVE_FILE));
|
|
300
396
|
provider.dispatch = jest.fn();
|
|
301
|
-
|
|
397
|
+
_context7.next = 9;
|
|
302
398
|
return provider.updateDocumentPermissions(driveFile, {
|
|
303
399
|
verbs: ['GET'],
|
|
304
400
|
expiresAt: '',
|
|
@@ -310,9 +406,9 @@ describe('updateDocumentPermissions', function () {
|
|
|
310
406
|
|
|
311
407
|
case 10:
|
|
312
408
|
case "end":
|
|
313
|
-
return
|
|
409
|
+
return _context7.stop();
|
|
314
410
|
}
|
|
315
|
-
},
|
|
411
|
+
}, _callee7);
|
|
316
412
|
})));
|
|
317
413
|
});
|
|
318
414
|
describe('updateSharingMemberType', function () {
|
|
@@ -362,53 +458,53 @@ describe('updateSharingMemberType', function () {
|
|
|
362
458
|
};
|
|
363
459
|
jest.spyOn(instance, 'addRecipients').mockResolvedValue({});
|
|
364
460
|
});
|
|
365
|
-
it('should throw when sharing is not found', /*#__PURE__*/_asyncToGenerator( /*#__PURE__*/_regeneratorRuntime.mark(function
|
|
366
|
-
return _regeneratorRuntime.wrap(function
|
|
367
|
-
while (1) switch (
|
|
461
|
+
it('should throw when sharing is not found', /*#__PURE__*/_asyncToGenerator( /*#__PURE__*/_regeneratorRuntime.mark(function _callee8() {
|
|
462
|
+
return _regeneratorRuntime.wrap(function _callee8$(_context8) {
|
|
463
|
+
while (1) switch (_context8.prev = _context8.next) {
|
|
368
464
|
case 0:
|
|
369
|
-
|
|
465
|
+
_context8.next = 2;
|
|
370
466
|
return expect(instance.updateSharingMemberType('unknown-id', 1, 'one-way')).rejects.toThrow('Sharing not found');
|
|
371
467
|
|
|
372
468
|
case 2:
|
|
373
469
|
case "end":
|
|
374
|
-
return
|
|
470
|
+
return _context8.stop();
|
|
375
471
|
}
|
|
376
|
-
},
|
|
472
|
+
}, _callee8);
|
|
377
473
|
})));
|
|
378
|
-
it('should throw when member is not found', /*#__PURE__*/_asyncToGenerator( /*#__PURE__*/_regeneratorRuntime.mark(function
|
|
379
|
-
return _regeneratorRuntime.wrap(function
|
|
380
|
-
while (1) switch (
|
|
474
|
+
it('should throw when member is not found', /*#__PURE__*/_asyncToGenerator( /*#__PURE__*/_regeneratorRuntime.mark(function _callee9() {
|
|
475
|
+
return _regeneratorRuntime.wrap(function _callee9$(_context9) {
|
|
476
|
+
while (1) switch (_context9.prev = _context9.next) {
|
|
381
477
|
case 0:
|
|
382
|
-
|
|
478
|
+
_context9.next = 2;
|
|
383
479
|
return expect(instance.updateSharingMemberType('sharing-123', 99, 'one-way')).rejects.toThrow('Member not found');
|
|
384
480
|
|
|
385
481
|
case 2:
|
|
386
482
|
case "end":
|
|
387
|
-
return
|
|
483
|
+
return _context9.stop();
|
|
388
484
|
}
|
|
389
|
-
},
|
|
485
|
+
}, _callee9);
|
|
390
486
|
})));
|
|
391
|
-
it('should throw when contact is not found', /*#__PURE__*/_asyncToGenerator( /*#__PURE__*/_regeneratorRuntime.mark(function
|
|
392
|
-
return _regeneratorRuntime.wrap(function
|
|
393
|
-
while (1) switch (
|
|
487
|
+
it('should throw when contact is not found', /*#__PURE__*/_asyncToGenerator( /*#__PURE__*/_regeneratorRuntime.mark(function _callee10() {
|
|
488
|
+
return _regeneratorRuntime.wrap(function _callee10$(_context10) {
|
|
489
|
+
while (1) switch (_context10.prev = _context10.next) {
|
|
394
490
|
case 0:
|
|
395
491
|
mockContactsCollection.find.mockResolvedValue({
|
|
396
492
|
data: []
|
|
397
493
|
});
|
|
398
|
-
|
|
494
|
+
_context10.next = 3;
|
|
399
495
|
return expect(instance.updateSharingMemberType('sharing-123', 1, 'one-way')).rejects.toThrow('Contact not found');
|
|
400
496
|
|
|
401
497
|
case 3:
|
|
402
498
|
case "end":
|
|
403
|
-
return
|
|
499
|
+
return _context10.stop();
|
|
404
500
|
}
|
|
405
|
-
},
|
|
501
|
+
}, _callee10);
|
|
406
502
|
})));
|
|
407
|
-
it('should revoke and re-add with readOnly when switching to one-way', /*#__PURE__*/_asyncToGenerator( /*#__PURE__*/_regeneratorRuntime.mark(function
|
|
408
|
-
return _regeneratorRuntime.wrap(function
|
|
409
|
-
while (1) switch (
|
|
503
|
+
it('should revoke and re-add with readOnly when switching to one-way', /*#__PURE__*/_asyncToGenerator( /*#__PURE__*/_regeneratorRuntime.mark(function _callee11() {
|
|
504
|
+
return _regeneratorRuntime.wrap(function _callee11$(_context11) {
|
|
505
|
+
while (1) switch (_context11.prev = _context11.next) {
|
|
410
506
|
case 0:
|
|
411
|
-
|
|
507
|
+
_context11.next = 2;
|
|
412
508
|
return instance.updateSharingMemberType('sharing-123', 1, 'one-way');
|
|
413
509
|
|
|
414
510
|
case 2:
|
|
@@ -421,15 +517,15 @@ describe('updateSharingMemberType', function () {
|
|
|
421
517
|
|
|
422
518
|
case 4:
|
|
423
519
|
case "end":
|
|
424
|
-
return
|
|
520
|
+
return _context11.stop();
|
|
425
521
|
}
|
|
426
|
-
},
|
|
522
|
+
}, _callee11);
|
|
427
523
|
})));
|
|
428
|
-
it('should revoke and re-add as read-write when switching to two-way', /*#__PURE__*/_asyncToGenerator( /*#__PURE__*/_regeneratorRuntime.mark(function
|
|
429
|
-
return _regeneratorRuntime.wrap(function
|
|
430
|
-
while (1) switch (
|
|
524
|
+
it('should revoke and re-add as read-write when switching to two-way', /*#__PURE__*/_asyncToGenerator( /*#__PURE__*/_regeneratorRuntime.mark(function _callee12() {
|
|
525
|
+
return _regeneratorRuntime.wrap(function _callee12$(_context12) {
|
|
526
|
+
while (1) switch (_context12.prev = _context12.next) {
|
|
431
527
|
case 0:
|
|
432
|
-
|
|
528
|
+
_context12.next = 2;
|
|
433
529
|
return instance.updateSharingMemberType('sharing-123', 1, 'two-way');
|
|
434
530
|
|
|
435
531
|
case 2:
|
|
@@ -442,23 +538,23 @@ describe('updateSharingMemberType', function () {
|
|
|
442
538
|
|
|
443
539
|
case 4:
|
|
444
540
|
case "end":
|
|
445
|
-
return
|
|
541
|
+
return _context12.stop();
|
|
446
542
|
}
|
|
447
|
-
},
|
|
543
|
+
}, _callee12);
|
|
448
544
|
})));
|
|
449
|
-
it('should rethrow error if addRecipients fails after revocation', /*#__PURE__*/_asyncToGenerator( /*#__PURE__*/_regeneratorRuntime.mark(function
|
|
450
|
-
return _regeneratorRuntime.wrap(function
|
|
451
|
-
while (1) switch (
|
|
545
|
+
it('should rethrow error if addRecipients fails after revocation', /*#__PURE__*/_asyncToGenerator( /*#__PURE__*/_regeneratorRuntime.mark(function _callee13() {
|
|
546
|
+
return _regeneratorRuntime.wrap(function _callee13$(_context13) {
|
|
547
|
+
while (1) switch (_context13.prev = _context13.next) {
|
|
452
548
|
case 0:
|
|
453
549
|
instance.addRecipients.mockRejectedValue(new Error('Network error'));
|
|
454
|
-
|
|
550
|
+
_context13.next = 3;
|
|
455
551
|
return expect(instance.updateSharingMemberType('sharing-123', 1, 'one-way')).rejects.toThrow('Network error');
|
|
456
552
|
|
|
457
553
|
case 3:
|
|
458
554
|
case "end":
|
|
459
|
-
return
|
|
555
|
+
return _context13.stop();
|
|
460
556
|
}
|
|
461
|
-
},
|
|
557
|
+
}, _callee13);
|
|
462
558
|
})));
|
|
463
559
|
}); // TODO Convert with react-testing-library
|
|
464
560
|
// describe('hasWriteAccess', () => {
|
package/jest.config.js
CHANGED
|
@@ -12,7 +12,9 @@ module.exports = {
|
|
|
12
12
|
],
|
|
13
13
|
roots: ['<rootDir>/src'],
|
|
14
14
|
testEnvironment: 'jsdom',
|
|
15
|
-
|
|
15
|
+
testEnvironmentOptions: {
|
|
16
|
+
url: 'http://localhost/'
|
|
17
|
+
},
|
|
16
18
|
moduleFileExtensions: ['js', 'jsx', 'json', 'styl'],
|
|
17
19
|
moduleDirectories: ['src', 'node_modules'],
|
|
18
20
|
moduleNameMapper: {
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "cozy-sharing",
|
|
3
|
-
"version": "28.
|
|
3
|
+
"version": "28.11.0",
|
|
4
4
|
"description": "Provides sharing login for React applications.",
|
|
5
5
|
"main": "dist/index.js",
|
|
6
6
|
"author": "Cozy",
|
|
@@ -31,7 +31,7 @@
|
|
|
31
31
|
"@cozy/minilog": "^1.0.0",
|
|
32
32
|
"classnames": "^2.5.1",
|
|
33
33
|
"cozy-device-helper": "^4.0.3",
|
|
34
|
-
"cozy-doctypes": "^1.
|
|
34
|
+
"cozy-doctypes": "^1.99.0",
|
|
35
35
|
"date-fns": "2.30.0",
|
|
36
36
|
"lodash": "^4.17.21",
|
|
37
37
|
"react-autosuggest": "^10.1.0",
|
|
@@ -51,22 +51,22 @@
|
|
|
51
51
|
"@testing-library/jest-dom": "5.17.0",
|
|
52
52
|
"@testing-library/react": "12.1.5",
|
|
53
53
|
"@testing-library/react-hooks": "8.0.1",
|
|
54
|
-
"babel-jest": "
|
|
54
|
+
"babel-jest": "28.1.3",
|
|
55
55
|
"babel-plugin-css-modules-transform": "1.6.2",
|
|
56
56
|
"babel-plugin-inline-react-svg": "1.1.2",
|
|
57
57
|
"cozy-client": "^60.22.0",
|
|
58
58
|
"cozy-device-helper": "^3.7.1",
|
|
59
|
-
"cozy-intent": "^2.
|
|
59
|
+
"cozy-intent": "^2.31.0",
|
|
60
60
|
"cozy-minilog": "^3.10.1",
|
|
61
61
|
"cozy-ui": "^135.0.0",
|
|
62
|
-
"cozy-ui-plus": "^5.
|
|
63
|
-
"jest": "
|
|
64
|
-
"jest-environment-jsdom": "
|
|
62
|
+
"cozy-ui-plus": "^5.3.0",
|
|
63
|
+
"jest": "28.1.3",
|
|
64
|
+
"jest-environment-jsdom": "28.1.3",
|
|
65
65
|
"react": "16.12.0",
|
|
66
66
|
"react-dom": "16.13.0",
|
|
67
67
|
"react-router": "^5.0.1",
|
|
68
68
|
"storybook": "7.6.0",
|
|
69
|
-
"twake-i18n": "^0.
|
|
69
|
+
"twake-i18n": "^0.4.0"
|
|
70
70
|
},
|
|
71
71
|
"peerDependencies": {
|
|
72
72
|
"cozy-client": ">=60.22.0",
|
|
@@ -83,5 +83,5 @@
|
|
|
83
83
|
"sideEffects": [
|
|
84
84
|
"*.css"
|
|
85
85
|
],
|
|
86
|
-
"gitHead": "
|
|
86
|
+
"gitHead": "a2816d422234922d845a1b6c01fae4c45fe81fc8"
|
|
87
87
|
}
|
package/src/SharingProvider.jsx
CHANGED
|
@@ -496,11 +496,23 @@ export class SharingProvider extends Component {
|
|
|
496
496
|
return responses
|
|
497
497
|
}
|
|
498
498
|
|
|
499
|
+
revokeSharedDriveSharingLink = async (document, perms) => {
|
|
500
|
+
const { client } = this.props
|
|
501
|
+
const drivePermissionCollection = client.collection('io.cozy.permissions', {
|
|
502
|
+
driveId: document.driveId
|
|
503
|
+
})
|
|
504
|
+
await Promise.all(perms.map(p => drivePermissionCollection.destroy(p)))
|
|
505
|
+
}
|
|
506
|
+
|
|
499
507
|
revokeSharingLink = async document => {
|
|
500
508
|
// Because some duplicate links have been created in the past, we must ensure
|
|
501
509
|
// we revoke all of them
|
|
502
510
|
const perms = getDocumentPermissions(this.state, document.id)
|
|
503
|
-
|
|
511
|
+
if (document.driveId) {
|
|
512
|
+
await this.revokeSharedDriveSharingLink(document, perms)
|
|
513
|
+
} else {
|
|
514
|
+
await Promise.all(perms.map(p => this.permissionCol.destroy(p)))
|
|
515
|
+
}
|
|
504
516
|
this.dispatch(revokeSharingLink(perms))
|
|
505
517
|
}
|
|
506
518
|
|
|
@@ -192,6 +192,63 @@ describe('shareByLink', () => {
|
|
|
192
192
|
})
|
|
193
193
|
})
|
|
194
194
|
|
|
195
|
+
describe('revokeSharingLink', () => {
|
|
196
|
+
const PERM = {
|
|
197
|
+
type: 'io.cozy.permissions',
|
|
198
|
+
id: 'perm_1',
|
|
199
|
+
attributes: {
|
|
200
|
+
type: 'share',
|
|
201
|
+
permissions: {
|
|
202
|
+
rule0: { type: 'io.cozy.files', verbs: ['GET'], values: ['file_id'] }
|
|
203
|
+
}
|
|
204
|
+
}
|
|
205
|
+
}
|
|
206
|
+
|
|
207
|
+
let provider
|
|
208
|
+
let mockDestroy
|
|
209
|
+
|
|
210
|
+
beforeEach(() => {
|
|
211
|
+
mockDestroy = jest.fn().mockResolvedValue({})
|
|
212
|
+
const mockClient = createMockClient({})
|
|
213
|
+
mockClient.getStackClient = () => ({ uri: 'http://cozy.local' })
|
|
214
|
+
mockClient.collection = jest.fn().mockReturnValue({ destroy: mockDestroy })
|
|
215
|
+
provider = new SharingProvider({ client: mockClient })
|
|
216
|
+
provider.state = reducer(undefined, addSharingLink(PERM))
|
|
217
|
+
provider.dispatch = jest.fn(action => {
|
|
218
|
+
provider.state = reducer(provider.state, action)
|
|
219
|
+
})
|
|
220
|
+
})
|
|
221
|
+
|
|
222
|
+
it('uses permissionCol.destroy for a regular file', async () => {
|
|
223
|
+
const regularFile = { _id: 'file_id', id: 'file_id' }
|
|
224
|
+
provider.permissionCol = { destroy: mockDestroy }
|
|
225
|
+
|
|
226
|
+
await provider.revokeSharingLink(regularFile)
|
|
227
|
+
|
|
228
|
+
expect(mockDestroy).toHaveBeenCalledTimes(1)
|
|
229
|
+
expect(mockDestroy).toHaveBeenCalledWith(PERM)
|
|
230
|
+
expect(provider.dispatch).toHaveBeenCalledTimes(1)
|
|
231
|
+
})
|
|
232
|
+
|
|
233
|
+
it('uses drivePermissionCollection.destroy for a shared drive file', async () => {
|
|
234
|
+
const driveFile = { _id: 'file_id', id: 'file_id', driveId: 'drive_123' }
|
|
235
|
+
const mockDriveCollection = { destroy: mockDestroy }
|
|
236
|
+
provider.props.client.collection = jest
|
|
237
|
+
.fn()
|
|
238
|
+
.mockReturnValue(mockDriveCollection)
|
|
239
|
+
|
|
240
|
+
await provider.revokeSharingLink(driveFile)
|
|
241
|
+
|
|
242
|
+
expect(provider.props.client.collection).toHaveBeenCalledWith(
|
|
243
|
+
'io.cozy.permissions',
|
|
244
|
+
{ driveId: 'drive_123' }
|
|
245
|
+
)
|
|
246
|
+
expect(mockDestroy).toHaveBeenCalledTimes(1)
|
|
247
|
+
expect(mockDestroy).toHaveBeenCalledWith(PERM)
|
|
248
|
+
expect(provider.dispatch).toHaveBeenCalledTimes(1)
|
|
249
|
+
})
|
|
250
|
+
})
|
|
251
|
+
|
|
195
252
|
describe('updateDocumentPermissions', () => {
|
|
196
253
|
const PERM_DRIVE_FILE = {
|
|
197
254
|
type: 'io.cozy.permissions',
|