cozy-sharing 38.1.9 → 38.1.11
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 +10 -0
- package/dist/SharingProvider.js +6 -6
- package/dist/SharingProvider.spec.js +108 -80
- package/package.json +4 -4
- package/src/SharingProvider.jsx +8 -11
- package/src/SharingProvider.spec.jsx +104 -85
package/CHANGELOG.md
CHANGED
|
@@ -3,6 +3,16 @@
|
|
|
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
|
+
## [38.1.11](https://github.com/cozy/cozy-libs/compare/cozy-sharing@38.1.10...cozy-sharing@38.1.11) (2026-10-05)
|
|
7
|
+
|
|
8
|
+
**Note:** Version bump only for package cozy-sharing
|
|
9
|
+
|
|
10
|
+
## [38.1.10](https://github.com/cozy/cozy-libs/compare/cozy-sharing@38.1.9...cozy-sharing@38.1.10) (2026-10-05)
|
|
11
|
+
|
|
12
|
+
### Bug Fixes
|
|
13
|
+
|
|
14
|
+
- **cozy-sharing:** Respect nested permissions in hasWriteAccess ([b04a8aa](https://github.com/cozy/cozy-libs/commit/b04a8aa6bda15e5ef5dfa357c3c75a5fdc040e1a))
|
|
15
|
+
|
|
6
16
|
## [38.1.9](https://github.com/cozy/cozy-libs/compare/cozy-sharing@38.1.8...cozy-sharing@38.1.9) (2026-10-04)
|
|
7
17
|
|
|
8
18
|
**Note:** Version bump only for package cozy-sharing
|
package/dist/SharingProvider.js
CHANGED
|
@@ -1225,21 +1225,21 @@ export var SharingProvider = /*#__PURE__*/function (_Component) {
|
|
|
1225
1225
|
}());
|
|
1226
1226
|
|
|
1227
1227
|
_defineProperty(_this2, "hasWriteAccess", function (docId) {
|
|
1228
|
+
var _this2$state$byDocId;
|
|
1229
|
+
|
|
1228
1230
|
var driveId = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : undefined;
|
|
1229
1231
|
|
|
1230
1232
|
var instanceUri = _this2.props.client.getStackClient().uri;
|
|
1231
|
-
/** Split another case for checking sharing type for shared drive
|
|
1232
|
-
* In case of shared drive, we just check if shared drive has write access or not.
|
|
1233
|
-
* All the files / folders inside must follow the sharing rule of shared drive.
|
|
1234
|
-
* `driveId` only exist in files / folders from recipient, so we don't need to check it belong to owner or not.
|
|
1235
|
-
*/
|
|
1236
1233
|
|
|
1234
|
+
if ((_this2$state$byDocId = _this2.state.byDocId) !== null && _this2$state$byDocId !== void 0 && _this2$state$byDocId[docId]) {
|
|
1235
|
+
return _isOwner(_this2.state, docId) || _getSharingType(_this2.state, docId, instanceUri) === SHARING_TYPE.TWO_WAY;
|
|
1236
|
+
}
|
|
1237
1237
|
|
|
1238
1238
|
if (driveId) {
|
|
1239
1239
|
return getSharedDriveSharingType(_this2.state, driveId, instanceUri) === SHARING_TYPE.TWO_WAY;
|
|
1240
1240
|
}
|
|
1241
1241
|
|
|
1242
|
-
return
|
|
1242
|
+
return true;
|
|
1243
1243
|
});
|
|
1244
1244
|
|
|
1245
1245
|
var _instanceUri = props.client.getStackClient().uri;
|
|
@@ -1714,83 +1714,111 @@ describe('updateSharingMemberType', function () {
|
|
|
1714
1714
|
}
|
|
1715
1715
|
}, _callee39);
|
|
1716
1716
|
})));
|
|
1717
|
-
});
|
|
1718
|
-
|
|
1719
|
-
|
|
1720
|
-
|
|
1721
|
-
|
|
1722
|
-
|
|
1723
|
-
|
|
1724
|
-
|
|
1725
|
-
|
|
1726
|
-
|
|
1727
|
-
|
|
1728
|
-
|
|
1729
|
-
|
|
1730
|
-
|
|
1731
|
-
|
|
1732
|
-
|
|
1733
|
-
|
|
1734
|
-
|
|
1735
|
-
|
|
1736
|
-
|
|
1737
|
-
|
|
1738
|
-
|
|
1739
|
-
|
|
1740
|
-
|
|
1741
|
-
|
|
1742
|
-
|
|
1743
|
-
|
|
1744
|
-
|
|
1745
|
-
|
|
1746
|
-
|
|
1747
|
-
|
|
1748
|
-
|
|
1749
|
-
|
|
1750
|
-
|
|
1751
|
-
|
|
1752
|
-
|
|
1753
|
-
|
|
1754
|
-
|
|
1755
|
-
|
|
1756
|
-
|
|
1757
|
-
|
|
1758
|
-
|
|
1759
|
-
|
|
1760
|
-
|
|
1761
|
-
|
|
1762
|
-
|
|
1763
|
-
|
|
1764
|
-
|
|
1765
|
-
|
|
1766
|
-
|
|
1767
|
-
|
|
1768
|
-
|
|
1769
|
-
|
|
1770
|
-
|
|
1771
|
-
|
|
1772
|
-
|
|
1773
|
-
|
|
1774
|
-
|
|
1775
|
-
|
|
1776
|
-
|
|
1777
|
-
|
|
1778
|
-
|
|
1779
|
-
|
|
1780
|
-
|
|
1781
|
-
|
|
1782
|
-
|
|
1783
|
-
|
|
1784
|
-
|
|
1785
|
-
|
|
1786
|
-
|
|
1787
|
-
|
|
1788
|
-
|
|
1789
|
-
|
|
1790
|
-
|
|
1791
|
-
|
|
1792
|
-
|
|
1793
|
-
|
|
1794
|
-
|
|
1795
|
-
|
|
1796
|
-
|
|
1717
|
+
});
|
|
1718
|
+
describe('hasWriteAccess', function () {
|
|
1719
|
+
var createClient = function createClient() {
|
|
1720
|
+
var client = createMockClient({});
|
|
1721
|
+
client.getStackClient().uri = 'http://cozy.tools:8080';
|
|
1722
|
+
return client;
|
|
1723
|
+
};
|
|
1724
|
+
|
|
1725
|
+
var parentSharing = {
|
|
1726
|
+
id: 'parent-drive',
|
|
1727
|
+
type: 'io.cozy.sharings',
|
|
1728
|
+
attributes: {
|
|
1729
|
+
owner: false,
|
|
1730
|
+
drive: true,
|
|
1731
|
+
members: [{
|
|
1732
|
+
read_only: true,
|
|
1733
|
+
instance: 'http://cozy.tools:8080'
|
|
1734
|
+
}],
|
|
1735
|
+
rules: [{
|
|
1736
|
+
values: ['parent-folder']
|
|
1737
|
+
}]
|
|
1738
|
+
}
|
|
1739
|
+
};
|
|
1740
|
+
var nestedSharing = {
|
|
1741
|
+
id: 'nested-drive',
|
|
1742
|
+
type: 'io.cozy.sharings',
|
|
1743
|
+
attributes: {
|
|
1744
|
+
owner: false,
|
|
1745
|
+
drive: true,
|
|
1746
|
+
members: [{
|
|
1747
|
+
read_only: false,
|
|
1748
|
+
instance: 'http://cozy.tools:8080'
|
|
1749
|
+
}],
|
|
1750
|
+
rules: [{
|
|
1751
|
+
values: ['nested-folder']
|
|
1752
|
+
}]
|
|
1753
|
+
}
|
|
1754
|
+
};
|
|
1755
|
+
var ownerSharing = {
|
|
1756
|
+
id: 'owner-drive',
|
|
1757
|
+
type: 'io.cozy.sharings',
|
|
1758
|
+
attributes: {
|
|
1759
|
+
owner: true,
|
|
1760
|
+
drive: true,
|
|
1761
|
+
members: [{
|
|
1762
|
+
read_only: false,
|
|
1763
|
+
instance: 'http://cozy.tools:8080'
|
|
1764
|
+
}],
|
|
1765
|
+
rules: [{
|
|
1766
|
+
values: ['owner-folder']
|
|
1767
|
+
}]
|
|
1768
|
+
}
|
|
1769
|
+
};
|
|
1770
|
+
it('returns true when document is not shared and no driveId is provided', function () {
|
|
1771
|
+
var provider = setupProvider(createClient());
|
|
1772
|
+
expect(provider.hasWriteAccess('unshared-doc')).toBe(true);
|
|
1773
|
+
});
|
|
1774
|
+
it('returns true when user is owner of the shared document', function () {
|
|
1775
|
+
var provider = setupProvider(createClient());
|
|
1776
|
+
provider.dispatch(receiveSharings({
|
|
1777
|
+
sharings: [ownerSharing],
|
|
1778
|
+
permissions: []
|
|
1779
|
+
}));
|
|
1780
|
+
expect(provider.hasWriteAccess('owner-folder')).toBe(true);
|
|
1781
|
+
expect(provider.hasWriteAccess('owner-folder', 'owner-drive')).toBe(true);
|
|
1782
|
+
});
|
|
1783
|
+
it('returns false for viewer of a shared document', function () {
|
|
1784
|
+
var provider = setupProvider(createClient());
|
|
1785
|
+
provider.dispatch(receiveSharings({
|
|
1786
|
+
sharings: [parentSharing],
|
|
1787
|
+
permissions: []
|
|
1788
|
+
}));
|
|
1789
|
+
expect(provider.hasWriteAccess('parent-folder')).toBe(false);
|
|
1790
|
+
});
|
|
1791
|
+
it('returns true for editor of a shared document', function () {
|
|
1792
|
+
var provider = setupProvider(createClient());
|
|
1793
|
+
provider.dispatch(receiveSharings({
|
|
1794
|
+
sharings: [nestedSharing],
|
|
1795
|
+
permissions: []
|
|
1796
|
+
}));
|
|
1797
|
+
expect(provider.hasWriteAccess('nested-folder')).toBe(true);
|
|
1798
|
+
});
|
|
1799
|
+
it('returns drive write access when document has no explicit sharing', function () {
|
|
1800
|
+
var provider = setupProvider(createClient());
|
|
1801
|
+
provider.dispatch(receiveSharings({
|
|
1802
|
+
sharings: [parentSharing, nestedSharing],
|
|
1803
|
+
permissions: []
|
|
1804
|
+
}));
|
|
1805
|
+
expect(provider.hasWriteAccess('child-file', 'parent-drive')).toBe(false);
|
|
1806
|
+
expect(provider.hasWriteAccess('child-file', 'nested-drive')).toBe(true);
|
|
1807
|
+
});
|
|
1808
|
+
it('takes nested document permissions into account when driveId is provided (issue linagora/twake-drive#4220)', function () {
|
|
1809
|
+
var provider = setupProvider(createClient());
|
|
1810
|
+
provider.dispatch(receiveSharings({
|
|
1811
|
+
sharings: [parentSharing, nestedSharing],
|
|
1812
|
+
permissions: []
|
|
1813
|
+
}));
|
|
1814
|
+
expect(provider.hasWriteAccess('nested-folder', 'parent-drive')).toBe(true);
|
|
1815
|
+
});
|
|
1816
|
+
it('takes nested restricted permissions into account when driveId is editor', function () {
|
|
1817
|
+
var provider = setupProvider(createClient());
|
|
1818
|
+
provider.dispatch(receiveSharings({
|
|
1819
|
+
sharings: [parentSharing, nestedSharing],
|
|
1820
|
+
permissions: []
|
|
1821
|
+
}));
|
|
1822
|
+
expect(provider.hasWriteAccess('parent-folder', 'nested-drive')).toBe(false);
|
|
1823
|
+
});
|
|
1824
|
+
});
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "cozy-sharing",
|
|
3
|
-
"version": "38.1.
|
|
3
|
+
"version": "38.1.11",
|
|
4
4
|
"description": "Provides sharing login for React applications.",
|
|
5
5
|
"main": "dist/index.js",
|
|
6
6
|
"author": "Cozy",
|
|
@@ -58,14 +58,14 @@
|
|
|
58
58
|
"cozy-intent": "^2.31.1",
|
|
59
59
|
"cozy-minilog": "^3.10.1",
|
|
60
60
|
"cozy-ui": "^140.5.0",
|
|
61
|
-
"cozy-ui-plus": "^13.0.
|
|
61
|
+
"cozy-ui-plus": "^13.0.15",
|
|
62
62
|
"jest": "30.3.0",
|
|
63
63
|
"jest-environment-jsdom": "30.3.0",
|
|
64
64
|
"react": "16.12.0",
|
|
65
65
|
"react-dom": "16.13.0",
|
|
66
66
|
"react-router": "^5.0.1",
|
|
67
67
|
"storybook": "7.6.0",
|
|
68
|
-
"twake-i18n": "^0.6.
|
|
68
|
+
"twake-i18n": "^0.6.1"
|
|
69
69
|
},
|
|
70
70
|
"peerDependencies": {
|
|
71
71
|
"@linagora/twake-icons": ">=2.9.0",
|
|
@@ -84,5 +84,5 @@
|
|
|
84
84
|
"sideEffects": [
|
|
85
85
|
"*.css"
|
|
86
86
|
],
|
|
87
|
-
"gitHead": "
|
|
87
|
+
"gitHead": "bb3e6c8272d39337be9ceb7abc633049be71638b"
|
|
88
88
|
}
|
package/src/SharingProvider.jsx
CHANGED
|
@@ -718,11 +718,13 @@ export class SharingProvider extends Component {
|
|
|
718
718
|
hasWriteAccess = (docId, driveId = undefined) => {
|
|
719
719
|
const instanceUri = this.props.client.getStackClient().uri
|
|
720
720
|
|
|
721
|
-
|
|
722
|
-
|
|
723
|
-
|
|
724
|
-
|
|
725
|
-
|
|
721
|
+
if (this.state.byDocId?.[docId]) {
|
|
722
|
+
return (
|
|
723
|
+
isOwner(this.state, docId) ||
|
|
724
|
+
getSharingType(this.state, docId, instanceUri) === SHARING_TYPE.TWO_WAY
|
|
725
|
+
)
|
|
726
|
+
}
|
|
727
|
+
|
|
726
728
|
if (driveId) {
|
|
727
729
|
return (
|
|
728
730
|
getSharedDriveSharingType(this.state, driveId, instanceUri) ===
|
|
@@ -730,12 +732,7 @@ export class SharingProvider extends Component {
|
|
|
730
732
|
)
|
|
731
733
|
}
|
|
732
734
|
|
|
733
|
-
return
|
|
734
|
-
!this.state.byDocId ||
|
|
735
|
-
!this.state.byDocId[docId] ||
|
|
736
|
-
isOwner(this.state, docId) ||
|
|
737
|
-
getSharingType(this.state, docId, instanceUri) === SHARING_TYPE.TWO_WAY
|
|
738
|
-
)
|
|
735
|
+
return true
|
|
739
736
|
}
|
|
740
737
|
|
|
741
738
|
render() {
|
|
@@ -1330,88 +1330,107 @@ describe('updateSharingMemberType', () => {
|
|
|
1330
1330
|
})
|
|
1331
1331
|
})
|
|
1332
1332
|
|
|
1333
|
-
|
|
1334
|
-
|
|
1335
|
-
|
|
1336
|
-
|
|
1337
|
-
|
|
1338
|
-
|
|
1339
|
-
|
|
1340
|
-
|
|
1341
|
-
|
|
1342
|
-
|
|
1343
|
-
|
|
1344
|
-
|
|
1345
|
-
|
|
1346
|
-
|
|
1347
|
-
|
|
1348
|
-
|
|
1349
|
-
|
|
1350
|
-
|
|
1351
|
-
|
|
1352
|
-
|
|
1353
|
-
|
|
1354
|
-
|
|
1355
|
-
|
|
1356
|
-
|
|
1357
|
-
|
|
1358
|
-
|
|
1359
|
-
|
|
1360
|
-
|
|
1361
|
-
|
|
1362
|
-
|
|
1363
|
-
|
|
1364
|
-
|
|
1365
|
-
|
|
1366
|
-
|
|
1367
|
-
|
|
1368
|
-
|
|
1369
|
-
|
|
1370
|
-
|
|
1371
|
-
|
|
1372
|
-
|
|
1373
|
-
|
|
1374
|
-
|
|
1375
|
-
|
|
1376
|
-
|
|
1377
|
-
|
|
1378
|
-
|
|
1379
|
-
|
|
1380
|
-
|
|
1381
|
-
|
|
1382
|
-
|
|
1383
|
-
|
|
1384
|
-
|
|
1385
|
-
|
|
1386
|
-
|
|
1387
|
-
|
|
1388
|
-
|
|
1389
|
-
|
|
1390
|
-
|
|
1391
|
-
|
|
1392
|
-
|
|
1393
|
-
|
|
1394
|
-
|
|
1395
|
-
|
|
1396
|
-
|
|
1397
|
-
|
|
1398
|
-
|
|
1399
|
-
|
|
1400
|
-
|
|
1401
|
-
|
|
1402
|
-
|
|
1403
|
-
|
|
1404
|
-
|
|
1405
|
-
|
|
1406
|
-
|
|
1407
|
-
|
|
1408
|
-
|
|
1409
|
-
|
|
1410
|
-
|
|
1411
|
-
|
|
1412
|
-
|
|
1413
|
-
|
|
1414
|
-
|
|
1415
|
-
|
|
1416
|
-
|
|
1417
|
-
|
|
1333
|
+
describe('hasWriteAccess', () => {
|
|
1334
|
+
const createClient = () => {
|
|
1335
|
+
const client = createMockClient({})
|
|
1336
|
+
client.getStackClient().uri = 'http://cozy.tools:8080'
|
|
1337
|
+
return client
|
|
1338
|
+
}
|
|
1339
|
+
|
|
1340
|
+
const parentSharing = {
|
|
1341
|
+
id: 'parent-drive',
|
|
1342
|
+
type: 'io.cozy.sharings',
|
|
1343
|
+
attributes: {
|
|
1344
|
+
owner: false,
|
|
1345
|
+
drive: true,
|
|
1346
|
+
members: [{ read_only: true, instance: 'http://cozy.tools:8080' }],
|
|
1347
|
+
rules: [{ values: ['parent-folder'] }]
|
|
1348
|
+
}
|
|
1349
|
+
}
|
|
1350
|
+
|
|
1351
|
+
const nestedSharing = {
|
|
1352
|
+
id: 'nested-drive',
|
|
1353
|
+
type: 'io.cozy.sharings',
|
|
1354
|
+
attributes: {
|
|
1355
|
+
owner: false,
|
|
1356
|
+
drive: true,
|
|
1357
|
+
members: [{ read_only: false, instance: 'http://cozy.tools:8080' }],
|
|
1358
|
+
rules: [{ values: ['nested-folder'] }]
|
|
1359
|
+
}
|
|
1360
|
+
}
|
|
1361
|
+
|
|
1362
|
+
const ownerSharing = {
|
|
1363
|
+
id: 'owner-drive',
|
|
1364
|
+
type: 'io.cozy.sharings',
|
|
1365
|
+
attributes: {
|
|
1366
|
+
owner: true,
|
|
1367
|
+
drive: true,
|
|
1368
|
+
members: [{ read_only: false, instance: 'http://cozy.tools:8080' }],
|
|
1369
|
+
rules: [{ values: ['owner-folder'] }]
|
|
1370
|
+
}
|
|
1371
|
+
}
|
|
1372
|
+
|
|
1373
|
+
it('returns true when document is not shared and no driveId is provided', () => {
|
|
1374
|
+
const provider = setupProvider(createClient())
|
|
1375
|
+
expect(provider.hasWriteAccess('unshared-doc')).toBe(true)
|
|
1376
|
+
})
|
|
1377
|
+
|
|
1378
|
+
it('returns true when user is owner of the shared document', () => {
|
|
1379
|
+
const provider = setupProvider(createClient())
|
|
1380
|
+
provider.dispatch(
|
|
1381
|
+
receiveSharings({ sharings: [ownerSharing], permissions: [] })
|
|
1382
|
+
)
|
|
1383
|
+
expect(provider.hasWriteAccess('owner-folder')).toBe(true)
|
|
1384
|
+
expect(provider.hasWriteAccess('owner-folder', 'owner-drive')).toBe(true)
|
|
1385
|
+
})
|
|
1386
|
+
|
|
1387
|
+
it('returns false for viewer of a shared document', () => {
|
|
1388
|
+
const provider = setupProvider(createClient())
|
|
1389
|
+
provider.dispatch(
|
|
1390
|
+
receiveSharings({ sharings: [parentSharing], permissions: [] })
|
|
1391
|
+
)
|
|
1392
|
+
expect(provider.hasWriteAccess('parent-folder')).toBe(false)
|
|
1393
|
+
})
|
|
1394
|
+
|
|
1395
|
+
it('returns true for editor of a shared document', () => {
|
|
1396
|
+
const provider = setupProvider(createClient())
|
|
1397
|
+
provider.dispatch(
|
|
1398
|
+
receiveSharings({ sharings: [nestedSharing], permissions: [] })
|
|
1399
|
+
)
|
|
1400
|
+
expect(provider.hasWriteAccess('nested-folder')).toBe(true)
|
|
1401
|
+
})
|
|
1402
|
+
|
|
1403
|
+
it('returns drive write access when document has no explicit sharing', () => {
|
|
1404
|
+
const provider = setupProvider(createClient())
|
|
1405
|
+
provider.dispatch(
|
|
1406
|
+
receiveSharings({
|
|
1407
|
+
sharings: [parentSharing, nestedSharing],
|
|
1408
|
+
permissions: []
|
|
1409
|
+
})
|
|
1410
|
+
)
|
|
1411
|
+
expect(provider.hasWriteAccess('child-file', 'parent-drive')).toBe(false)
|
|
1412
|
+
expect(provider.hasWriteAccess('child-file', 'nested-drive')).toBe(true)
|
|
1413
|
+
})
|
|
1414
|
+
|
|
1415
|
+
it('takes nested document permissions into account when driveId is provided (issue linagora/twake-drive#4220)', () => {
|
|
1416
|
+
const provider = setupProvider(createClient())
|
|
1417
|
+
provider.dispatch(
|
|
1418
|
+
receiveSharings({
|
|
1419
|
+
sharings: [parentSharing, nestedSharing],
|
|
1420
|
+
permissions: []
|
|
1421
|
+
})
|
|
1422
|
+
)
|
|
1423
|
+
expect(provider.hasWriteAccess('nested-folder', 'parent-drive')).toBe(true)
|
|
1424
|
+
})
|
|
1425
|
+
|
|
1426
|
+
it('takes nested restricted permissions into account when driveId is editor', () => {
|
|
1427
|
+
const provider = setupProvider(createClient())
|
|
1428
|
+
provider.dispatch(
|
|
1429
|
+
receiveSharings({
|
|
1430
|
+
sharings: [parentSharing, nestedSharing],
|
|
1431
|
+
permissions: []
|
|
1432
|
+
})
|
|
1433
|
+
)
|
|
1434
|
+
expect(provider.hasWriteAccess('parent-folder', 'nested-drive')).toBe(false)
|
|
1435
|
+
})
|
|
1436
|
+
})
|