cozy-sharing 26.5.1 → 26.5.2

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 CHANGED
@@ -3,6 +3,12 @@
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
+ ## [26.5.2](https://github.com/cozy/cozy-libs/compare/cozy-sharing@26.5.1...cozy-sharing@26.5.2) (2025-10-07)
7
+
8
+ ### Bug Fixes
9
+
10
+ - Check correct sharing rule in shared drive :bug: ([6dc7dad](https://github.com/cozy/cozy-libs/commit/6dc7dadf1192912563c656050606c18379a7bdcc))
11
+
6
12
  ## [26.5.1](https://github.com/cozy/cozy-libs/compare/cozy-sharing@26.5.0...cozy-sharing@26.5.1) (2025-10-06)
7
13
 
8
14
  ### Bug Fixes
@@ -2,7 +2,8 @@ import React from 'react';
2
2
  import SharingContext from './context';
3
3
  export var SharedDocument = function SharedDocument(_ref) {
4
4
  var docId = _ref.docId,
5
- children = _ref.children;
5
+ children = _ref.children,
6
+ driveId = _ref.driveId;
6
7
  return /*#__PURE__*/React.createElement(SharingContext.Consumer, null, function () {
7
8
  var _ref2 = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : {},
8
9
  hasWriteAccess = _ref2.hasWriteAccess,
@@ -14,7 +15,7 @@ export var SharedDocument = function SharedDocument(_ref) {
14
15
  revokeSelf = _ref2.revokeSelf;
15
16
 
16
17
  return children({
17
- hasWriteAccess: hasWriteAccess(docId),
18
+ hasWriteAccess: hasWriteAccess(docId, driveId),
18
19
  isShared: byDocId !== undefined && byDocId[docId],
19
20
  isSharedByMe: byDocId !== undefined && byDocId[docId] && isOwner(docId),
20
21
  isSharedWithMe: byDocId !== undefined && byDocId[docId] && !isOwner(docId),
@@ -39,7 +39,7 @@ import { fetchFilesPaths } from './helpers/files';
39
39
  import { getSharingObject, createSharingInStore, updateSharingInStore } from './helpers/sharings';
40
40
  import { SynchronousJobQueue } from './helpers/synchronousJobQueue';
41
41
  import { fetchApps } from './queries/queries';
42
- import reducer, { receiveSharings, addSharing, updateSharing, addSharingLink, updateSharingLink, revokeSharingLink, revokeRecipient, revokeGroup as revokeGroupFromState, revokeSelf, receivePaths, isOwner as _isOwner, isSharedDrive as _isSharedDrive, canReshare as _canReshare, getOwner as _getOwner, getRecipients as _getRecipients, getSharingById, getExternalSharingIds, getSharingForSelf as _getSharingForSelf, getSharingType as _getSharingType, getSharingLink as _getSharingLink, getSharedDocIdsBySharings, getDocumentSharing, getDocumentPermissions as _getDocumentPermissions, hasSharedParent as _hasSharedParent, hasSharedChild as _hasSharedChild, getSharedParentPath as _getSharedParentPath } from './state';
42
+ import reducer, { receiveSharings, addSharing, updateSharing, addSharingLink, updateSharingLink, revokeSharingLink, revokeRecipient, revokeGroup as revokeGroupFromState, revokeSelf, receivePaths, isOwner as _isOwner, isSharedDrive as _isSharedDrive, canReshare as _canReshare, getOwner as _getOwner, getRecipients as _getRecipients, getSharingById, getExternalSharingIds, getSharingForSelf as _getSharingForSelf, getSharingType as _getSharingType, getSharingLink as _getSharingLink, getSharedDocIdsBySharings, getDocumentSharing, getDocumentPermissions as _getDocumentPermissions, hasSharedParent as _hasSharedParent, hasSharedChild as _hasSharedChild, getSharedParentPath as _getSharedParentPath, getSharedDriveSharingType, SHARING_TYPE } from './state';
43
43
  var log = minilog('SharingProvider');
44
44
  var SHARING_DOCTYPE = 'io.cozy.sharings';
45
45
  var PERMISSION_DOCTYPE = 'io.cozy.permissions';
@@ -563,9 +563,21 @@ export var SharingProvider = /*#__PURE__*/function (_Component) {
563
563
  }());
564
564
 
565
565
  _defineProperty(_this2, "hasWriteAccess", function (docId) {
566
+ var driveId = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : undefined;
567
+
566
568
  var instanceUri = _this2.props.client.getStackClient().uri;
569
+ /** Split another case for checking sharing type for shared drive
570
+ * In case of shared drive, we just check if shared drive has write access or not.
571
+ * All the files / folders inside must follow the sharing rule of shared drive.
572
+ * `driveId` only exist in files / folders from recipient, so we don't need to check it belong to owner or not.
573
+ */
574
+
575
+
576
+ if (driveId) {
577
+ return getSharedDriveSharingType(_this2.state, driveId, instanceUri) === SHARING_TYPE.TWO_WAY;
578
+ }
567
579
 
568
- return !_this2.state.byDocId || !_this2.state.byDocId[docId] || _isOwner(_this2.state, docId) || _getSharingType(_this2.state, docId, instanceUri) === 'two-way';
580
+ return !_this2.state.byDocId || !_this2.state.byDocId[docId] || _isOwner(_this2.state, docId) || _getSharingType(_this2.state, docId, instanceUri) === SHARING_TYPE.TWO_WAY;
569
581
  });
570
582
 
571
583
  var _instanceUri = props.client.getStackClient().uri;
package/dist/state.js CHANGED
@@ -21,7 +21,11 @@ var REVOKE_SELF = 'REVOKE_SELF';
21
21
  var ADD_SHARING_LINK = 'ADD_SHARING_LINK';
22
22
  var UPDATE_SHARING_LINK = 'UPDATE_SHARING_LINK';
23
23
  var REVOKE_SHARING_LINK = 'REVOKE_SHARING_LINK';
24
- var RECEIVE_PATHS = 'RECEIVE_PATHS'; // actions
24
+ var RECEIVE_PATHS = 'RECEIVE_PATHS';
25
+ export var SHARING_TYPE = {
26
+ TWO_WAY: 'two-way',
27
+ ONE_WAY: 'one-way'
28
+ }; // actions
25
29
 
26
30
  export var receiveSharings = function receiveSharings(_ref) {
27
31
  var instanceUri = _ref.instanceUri,
@@ -697,7 +701,7 @@ var getDirectorySharingType = function getDirectorySharingType(rule) {
697
701
  // If a document has no rule, it is a shortcut preview of a sharing.
698
702
  // Since the sharing hasn't been accepted, it can't be synced so we return the "one-way" type.
699
703
  // TODO : the sharing type shouldn't be based on rule but on ready_only prop of the member
700
- return rule && rule.update === 'sync' && rule.remove === 'sync' ? 'two-way' : 'one-way';
704
+ return rule && rule.update === 'sync' && rule.remove === 'sync' ? SHARING_TYPE.TWO_WAY : SHARING_TYPE.ONE_WAY;
701
705
  };
702
706
  /**
703
707
  * Returns the sharing type of a file
@@ -710,7 +714,7 @@ var getFileSharingType = function getFileSharingType(rule) {
710
714
  // If a document has no rule, it is a shortcut preview of a sharing.
711
715
  // Since the sharing hasn't been accepted, it can't be synced so we return the "one-way" type.
712
716
  // TODO : the sharing type shouldn't be based on rule but on ready_only prop of the member
713
- return rule && rule.update === 'sync' && rule.remove === 'revoke' ? 'two-way' : 'one-way';
717
+ return rule && rule.update === 'sync' && rule.remove === 'revoke' ? SHARING_TYPE.TWO_WAY : SHARING_TYPE.ONE_WAY;
714
718
  };
715
719
  /**
716
720
  * Returns the sharing type of a document
@@ -725,13 +729,13 @@ export var getDocumentSharingType = function getDocumentSharingType(sharing, doc
725
729
  var rule = getSharingRule(sharing, docId);
726
730
  var directorySharingType = getDirectorySharingType(rule);
727
731
  var fileSharingType = getFileSharingType(rule);
728
- return directorySharingType === 'two-way' || fileSharingType === 'two-way' ? 'two-way' : 'one-way';
732
+ return directorySharingType === SHARING_TYPE.TWO_WAY || fileSharingType === SHARING_TYPE.TWO_WAY ? SHARING_TYPE.TWO_WAY : SHARING_TYPE.ONE_WAY;
729
733
  };
730
734
  export var isReadOnlySharing = function isReadOnlySharing(sharing, docId) {
731
735
  var rule = getSharingRule(sharing, docId);
732
736
  var directorySharingType = getDirectorySharingType(rule);
733
737
  var fileSharingType = getFileSharingType(rule);
734
- return directorySharingType === 'two-way' || fileSharingType === 'two-way' ? false : true;
738
+ return directorySharingType === SHARING_TYPE.TWO_WAY || fileSharingType === SHARING_TYPE.TWO_WAY ? false : true;
735
739
  };
736
740
 
737
741
  var buildSharingLink = function buildSharingLink(state, documentType, sharecode) {
@@ -792,4 +796,41 @@ export var getSharedDocIdsBySharings = function getSharedDocIdsBySharings(sharin
792
796
  }
793
797
  });
794
798
  return docs;
799
+ };
800
+ /**
801
+ * Resolves shared drive sharing type.
802
+ *
803
+ * @param {object} sharing
804
+ * @returns {'two-way'|'one-way'|null}
805
+ */
806
+
807
+ var resolveDriveSharingTypeFromRule = function resolveDriveSharingTypeFromRule(sharing) {
808
+ var _sharing$attributes;
809
+
810
+ if (!(sharing !== null && sharing !== void 0 && (_sharing$attributes = sharing.attributes) !== null && _sharing$attributes !== void 0 && (_sharing$attributes = _sharing$attributes.rules) !== null && _sharing$attributes !== void 0 && _sharing$attributes.length)) return null;
811
+ var rule = sharing.attributes.rules[0];
812
+ var dirType = getDirectorySharingType(rule);
813
+ var fileType = getFileSharingType(rule);
814
+ return dirType === SHARING_TYPE.TWO_WAY || fileType === SHARING_TYPE.TWO_WAY ? SHARING_TYPE.TWO_WAY : SHARING_TYPE.ONE_WAY;
815
+ };
816
+ /**
817
+ * Computes the effective sharing type for a drive.
818
+ *
819
+ * @param {string} state - the state
820
+ * @param {string} driveId - the shared drive ID
821
+ * @param {string} instanceUri - the URI of the instance
822
+ * @returns {string|null} - the sharing type
823
+ */
824
+
825
+
826
+ export var getSharedDriveSharingType = function getSharedDriveSharingType(state, driveId, instanceUri) {
827
+ var _sharing$attributes$m;
828
+
829
+ var sharing = getSharingById(state, driveId);
830
+ if (!sharing) return null;
831
+ var baseType = resolveDriveSharingTypeFromRule(sharing);
832
+ if (sharing.attributes.owner) return baseType;
833
+ var me = (_sharing$attributes$m = sharing.attributes.members) === null || _sharing$attributes$m === void 0 ? void 0 : _sharing$attributes$m.find(matchingInstanceName(instanceUri));
834
+ if (!me) return baseType;
835
+ return me.read_only ? SHARING_TYPE.ONE_WAY : baseType;
795
836
  };
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "cozy-sharing",
3
- "version": "26.5.1",
3
+ "version": "26.5.2",
4
4
  "description": "Provides sharing login for React applications.",
5
5
  "main": "dist/index.js",
6
6
  "author": "Cozy",
@@ -79,5 +79,5 @@
79
79
  "sideEffects": [
80
80
  "*.css"
81
81
  ],
82
- "gitHead": "d9725e74f7a7245a8f8abd3d2cf595202ff6bf56"
82
+ "gitHead": "4ff71a0d8c2f1483f60b2a5febad0a92b49e8aa2"
83
83
  }
@@ -2,7 +2,7 @@ import React from 'react'
2
2
 
3
3
  import SharingContext from './context'
4
4
 
5
- export const SharedDocument = ({ docId, children }) => (
5
+ export const SharedDocument = ({ docId, children, driveId }) => (
6
6
  <SharingContext.Consumer>
7
7
  {({
8
8
  hasWriteAccess,
@@ -14,7 +14,7 @@ export const SharedDocument = ({ docId, children }) => (
14
14
  revokeSelf
15
15
  } = {}) =>
16
16
  children({
17
- hasWriteAccess: hasWriteAccess(docId),
17
+ hasWriteAccess: hasWriteAccess(docId, driveId),
18
18
  isShared: byDocId !== undefined && byDocId[docId],
19
19
  isSharedByMe: byDocId !== undefined && byDocId[docId] && isOwner(docId),
20
20
  isSharedWithMe:
@@ -39,7 +39,9 @@ import reducer, {
39
39
  getDocumentPermissions,
40
40
  hasSharedParent,
41
41
  hasSharedChild,
42
- getSharedParentPath
42
+ getSharedParentPath,
43
+ getSharedDriveSharingType,
44
+ SHARING_TYPE
43
45
  } from './state'
44
46
 
45
47
  const log = minilog('SharingProvider')
@@ -374,14 +376,26 @@ export class SharingProvider extends Component {
374
376
  this.dispatch(revokeSharingLink(perms))
375
377
  }
376
378
 
377
- hasWriteAccess = docId => {
379
+ hasWriteAccess = (docId, driveId = undefined) => {
378
380
  const instanceUri = this.props.client.getStackClient().uri
379
381
 
382
+ /** Split another case for checking sharing type for shared drive
383
+ * In case of shared drive, we just check if shared drive has write access or not.
384
+ * All the files / folders inside must follow the sharing rule of shared drive.
385
+ * `driveId` only exist in files / folders from recipient, so we don't need to check it belong to owner or not.
386
+ */
387
+ if (driveId) {
388
+ return (
389
+ getSharedDriveSharingType(this.state, driveId, instanceUri) ===
390
+ SHARING_TYPE.TWO_WAY
391
+ )
392
+ }
393
+
380
394
  return (
381
395
  !this.state.byDocId ||
382
396
  !this.state.byDocId[docId] ||
383
397
  isOwner(this.state, docId) ||
384
- getSharingType(this.state, docId, instanceUri) === 'two-way'
398
+ getSharingType(this.state, docId, instanceUri) === SHARING_TYPE.TWO_WAY
385
399
  )
386
400
  }
387
401
 
package/src/state.js CHANGED
@@ -12,6 +12,10 @@ const ADD_SHARING_LINK = 'ADD_SHARING_LINK'
12
12
  const UPDATE_SHARING_LINK = 'UPDATE_SHARING_LINK'
13
13
  const REVOKE_SHARING_LINK = 'REVOKE_SHARING_LINK'
14
14
  const RECEIVE_PATHS = 'RECEIVE_PATHS'
15
+ export const SHARING_TYPE = {
16
+ TWO_WAY: 'two-way',
17
+ ONE_WAY: 'one-way'
18
+ }
15
19
 
16
20
  // actions
17
21
  export const receiveSharings = ({
@@ -575,8 +579,8 @@ const getDirectorySharingType = rule => {
575
579
  // Since the sharing hasn't been accepted, it can't be synced so we return the "one-way" type.
576
580
  // TODO : the sharing type shouldn't be based on rule but on ready_only prop of the member
577
581
  return rule && rule.update === 'sync' && rule.remove === 'sync'
578
- ? 'two-way'
579
- : 'one-way'
582
+ ? SHARING_TYPE.TWO_WAY
583
+ : SHARING_TYPE.ONE_WAY
580
584
  }
581
585
 
582
586
  /**
@@ -589,8 +593,8 @@ const getFileSharingType = rule => {
589
593
  // Since the sharing hasn't been accepted, it can't be synced so we return the "one-way" type.
590
594
  // TODO : the sharing type shouldn't be based on rule but on ready_only prop of the member
591
595
  return rule && rule.update === 'sync' && rule.remove === 'revoke'
592
- ? 'two-way'
593
- : 'one-way'
596
+ ? SHARING_TYPE.TWO_WAY
597
+ : SHARING_TYPE.ONE_WAY
594
598
  }
595
599
 
596
600
  /**
@@ -605,9 +609,10 @@ export const getDocumentSharingType = (sharing, docId) => {
605
609
  const directorySharingType = getDirectorySharingType(rule)
606
610
  const fileSharingType = getFileSharingType(rule)
607
611
 
608
- return directorySharingType === 'two-way' || fileSharingType === 'two-way'
609
- ? 'two-way'
610
- : 'one-way'
612
+ return directorySharingType === SHARING_TYPE.TWO_WAY ||
613
+ fileSharingType === SHARING_TYPE.TWO_WAY
614
+ ? SHARING_TYPE.TWO_WAY
615
+ : SHARING_TYPE.ONE_WAY
611
616
  }
612
617
 
613
618
  export const isReadOnlySharing = (sharing, docId) => {
@@ -615,7 +620,8 @@ export const isReadOnlySharing = (sharing, docId) => {
615
620
  const directorySharingType = getDirectorySharingType(rule)
616
621
  const fileSharingType = getFileSharingType(rule)
617
622
 
618
- return directorySharingType === 'two-way' || fileSharingType === 'two-way'
623
+ return directorySharingType === SHARING_TYPE.TWO_WAY ||
624
+ fileSharingType === SHARING_TYPE.TWO_WAY
619
625
  ? false
620
626
  : true
621
627
  }
@@ -670,3 +676,42 @@ export const getSharedDocIdsBySharings = sharings => {
670
676
  })
671
677
  return docs
672
678
  }
679
+
680
+ /**
681
+ * Resolves shared drive sharing type.
682
+ *
683
+ * @param {object} sharing
684
+ * @returns {'two-way'|'one-way'|null}
685
+ */
686
+ const resolveDriveSharingTypeFromRule = sharing => {
687
+ if (!sharing?.attributes?.rules?.length) return null
688
+
689
+ const rule = sharing.attributes.rules[0]
690
+ const dirType = getDirectorySharingType(rule)
691
+ const fileType = getFileSharingType(rule)
692
+
693
+ return dirType === SHARING_TYPE.TWO_WAY || fileType === SHARING_TYPE.TWO_WAY
694
+ ? SHARING_TYPE.TWO_WAY
695
+ : SHARING_TYPE.ONE_WAY
696
+ }
697
+
698
+ /**
699
+ * Computes the effective sharing type for a drive.
700
+ *
701
+ * @param {string} state - the state
702
+ * @param {string} driveId - the shared drive ID
703
+ * @param {string} instanceUri - the URI of the instance
704
+ * @returns {string|null} - the sharing type
705
+ */
706
+ export const getSharedDriveSharingType = (state, driveId, instanceUri) => {
707
+ const sharing = getSharingById(state, driveId)
708
+ if (!sharing) return null
709
+
710
+ const baseType = resolveDriveSharingTypeFromRule(sharing)
711
+ if (sharing.attributes.owner) return baseType
712
+
713
+ const me = sharing.attributes.members?.find(matchingInstanceName(instanceUri))
714
+ if (!me) return baseType
715
+
716
+ return me.read_only ? SHARING_TYPE.ONE_WAY : baseType
717
+ }