cozy-sharing 34.0.2 → 34.1.1
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/components/FederatedFolder/FederatedFolderModal.js +67 -17
- package/dist/components/FederatedFolder/FederatedFolderModal.spec.js +1 -0
- package/dist/components/Recipient/GroupRecipientPermissions.js +8 -4
- package/dist/components/Recipient/RecipientList.js +1 -0
- package/package.json +2 -2
- package/src/components/FederatedFolder/FederatedFolderModal.jsx +36 -1
- package/src/components/FederatedFolder/FederatedFolderModal.spec.jsx +1 -0
- package/src/components/Recipient/GroupRecipientPermissions.jsx +9 -3
- package/src/components/Recipient/RecipientList.jsx +1 -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
|
+
## [34.1.1](https://github.com/cozy/cozy-libs/compare/cozy-sharing@34.1.0...cozy-sharing@34.1.1) (2026-06-25)
|
|
7
|
+
|
|
8
|
+
### Bug Fixes
|
|
9
|
+
|
|
10
|
+
- **federated:** Show correct recipients for files inside shared folder ([b656e73](https://github.com/cozy/cozy-libs/commit/b656e73240a30303c8063494ee052a197736d07c))
|
|
11
|
+
|
|
12
|
+
# [34.1.0](https://github.com/cozy/cozy-libs/compare/cozy-sharing@34.0.2...cozy-sharing@34.1.0) (2026-06-25)
|
|
13
|
+
|
|
14
|
+
### Features
|
|
15
|
+
|
|
16
|
+
- Show text and not menu if forced readonly for groups ([24d6df8](https://github.com/cozy/cozy-libs/commit/24d6df8c6d7ad0da2f63719d264001dbf67624cc))
|
|
17
|
+
|
|
6
18
|
## [34.0.2](https://github.com/cozy/cozy-libs/compare/cozy-sharing@34.0.1...cozy-sharing@34.0.2) (2026-06-24)
|
|
7
19
|
|
|
8
20
|
**Note:** Version bump only for package cozy-sharing
|
|
@@ -15,6 +15,7 @@ import { getOrCreateFromArray } from '../../helpers/contacts';
|
|
|
15
15
|
import withLocales from '../../hoc/withLocales';
|
|
16
16
|
import { usePendingRecipients } from '../../hooks/usePendingRecipients';
|
|
17
17
|
import { useSharingContext } from '../../hooks/useSharingContext';
|
|
18
|
+
import { getRecipientsFromSharing } from '../../state';
|
|
18
19
|
var styles = {
|
|
19
20
|
"share-modal-content": "share__share-modal-content___1iqEq",
|
|
20
21
|
"coz-form": "share__coz-form___1ICST",
|
|
@@ -40,7 +41,7 @@ import WhoHasAccess from '../WhoHasAccess';
|
|
|
40
41
|
var log = minilog('FederatedFolderModal');
|
|
41
42
|
|
|
42
43
|
var FederatedFolderModalContent = function FederatedFolderModalContent(_ref) {
|
|
43
|
-
var _sharedDriveSharing$a;
|
|
44
|
+
var _sharedDriveSharing$a, _sharedDriveSharing$a2;
|
|
44
45
|
|
|
45
46
|
var onClose = _ref.onClose,
|
|
46
47
|
existingDocument = _ref.document,
|
|
@@ -59,6 +60,7 @@ var FederatedFolderModalContent = function FederatedFolderModalContent(_ref) {
|
|
|
59
60
|
getDocumentPermissions = _useSharingContext.getDocumentPermissions,
|
|
60
61
|
fetchSharedDriveSharingLinks = _useSharingContext.fetchSharedDriveSharingLinks,
|
|
61
62
|
getRecipients = _useSharingContext.getRecipients,
|
|
63
|
+
getSharedParentPath = _useSharingContext.getSharedParentPath,
|
|
62
64
|
hasSharedChild = _useSharingContext.hasSharedChild,
|
|
63
65
|
hasSharedParent = _useSharingContext.hasSharedParent,
|
|
64
66
|
revoke = _useSharingContext.revoke;
|
|
@@ -220,8 +222,56 @@ var FederatedFolderModalContent = function FederatedFolderModalContent(_ref) {
|
|
|
220
222
|
};
|
|
221
223
|
}();
|
|
222
224
|
|
|
223
|
-
var documentId = (existingDocument === null || existingDocument === void 0 ? void 0 : existingDocument._id) || (existingDocument === null || existingDocument === void 0 ? void 0 : existingDocument.id);
|
|
224
|
-
|
|
225
|
+
var documentId = (existingDocument === null || existingDocument === void 0 ? void 0 : existingDocument._id) || (existingDocument === null || existingDocument === void 0 ? void 0 : existingDocument.id); // Owner case: when document is inside a shared folder (via path) but has no driveId,
|
|
226
|
+
// find the parent shared folder to use its _id for recipient/permission lookups.
|
|
227
|
+
|
|
228
|
+
var sharedParentPath = !sharedDriveSharing && hasSharedParentByPath && documentPath ? getSharedParentPath(documentPath) : null;
|
|
229
|
+
|
|
230
|
+
var _useState11 = useState(null),
|
|
231
|
+
_useState12 = _slicedToArray(_useState11, 2),
|
|
232
|
+
sharedParentFolder = _useState12[0],
|
|
233
|
+
setSharedParentFolder = _useState12[1];
|
|
234
|
+
|
|
235
|
+
useEffect(function () {
|
|
236
|
+
if (!sharedParentPath) return;
|
|
237
|
+
|
|
238
|
+
var fetchParentFolder = /*#__PURE__*/function () {
|
|
239
|
+
var _ref3 = _asyncToGenerator( /*#__PURE__*/_regeneratorRuntime.mark(function _callee2() {
|
|
240
|
+
var res;
|
|
241
|
+
return _regeneratorRuntime.wrap(function _callee2$(_context2) {
|
|
242
|
+
while (1) switch (_context2.prev = _context2.next) {
|
|
243
|
+
case 0:
|
|
244
|
+
_context2.prev = 0;
|
|
245
|
+
_context2.next = 3;
|
|
246
|
+
return client.collection('io.cozy.files').statByPath(sharedParentPath);
|
|
247
|
+
|
|
248
|
+
case 3:
|
|
249
|
+
res = _context2.sent;
|
|
250
|
+
if (res.data) setSharedParentFolder(res.data);
|
|
251
|
+
_context2.next = 10;
|
|
252
|
+
break;
|
|
253
|
+
|
|
254
|
+
case 7:
|
|
255
|
+
_context2.prev = 7;
|
|
256
|
+
_context2.t0 = _context2["catch"](0);
|
|
257
|
+
log.error('Failed to fetch shared parent folder', _context2.t0);
|
|
258
|
+
|
|
259
|
+
case 10:
|
|
260
|
+
case "end":
|
|
261
|
+
return _context2.stop();
|
|
262
|
+
}
|
|
263
|
+
}, _callee2, null, [[0, 7]]);
|
|
264
|
+
}));
|
|
265
|
+
|
|
266
|
+
return function fetchParentFolder() {
|
|
267
|
+
return _ref3.apply(this, arguments);
|
|
268
|
+
};
|
|
269
|
+
}();
|
|
270
|
+
|
|
271
|
+
fetchParentFolder();
|
|
272
|
+
}, [sharedParentPath, client]);
|
|
273
|
+
var sharingReferenceId = !sharedDriveSharing && sharedParentFolder !== null && sharedParentFolder !== void 0 && sharedParentFolder._id ? sharedParentFolder._id : documentId;
|
|
274
|
+
var existingRecipients = sharedDriveSharing !== null && sharedDriveSharing !== void 0 && (_sharedDriveSharing$a2 = sharedDriveSharing.attributes) !== null && _sharedDriveSharing$a2 !== void 0 && _sharedDriveSharing$a2.members && documentId ? getRecipientsFromSharing(sharedDriveSharing, documentId) : sharingReferenceId ? getRecipients(sharingReferenceId) : [];
|
|
225
275
|
var documentPermissions = documentId ? getDocumentPermissions(documentId) : [];
|
|
226
276
|
var displayedLink = existingDocument !== null && existingDocument !== void 0 && existingDocument.driveId ? getFederatedShareLink(existingDocument) : getSharingLink(existingDocument === null || existingDocument === void 0 ? void 0 : existingDocument._id);
|
|
227
277
|
useEffect(function () {
|
|
@@ -233,39 +283,39 @@ var FederatedFolderModalContent = function FederatedFolderModalContent(_ref) {
|
|
|
233
283
|
if (fetchedSharingLinksDocumentId === documentId) return;
|
|
234
284
|
|
|
235
285
|
var fetchSharingLinks = /*#__PURE__*/function () {
|
|
236
|
-
var
|
|
237
|
-
return _regeneratorRuntime.wrap(function
|
|
238
|
-
while (1) switch (
|
|
286
|
+
var _ref4 = _asyncToGenerator( /*#__PURE__*/_regeneratorRuntime.mark(function _callee3() {
|
|
287
|
+
return _regeneratorRuntime.wrap(function _callee3$(_context3) {
|
|
288
|
+
while (1) switch (_context3.prev = _context3.next) {
|
|
239
289
|
case 0:
|
|
240
290
|
setIsFetchingSharingLinks(true);
|
|
241
|
-
|
|
242
|
-
|
|
291
|
+
_context3.prev = 1;
|
|
292
|
+
_context3.next = 4;
|
|
243
293
|
return fetchSharedDriveSharingLinks(existingDocument);
|
|
244
294
|
|
|
245
295
|
case 4:
|
|
246
|
-
|
|
296
|
+
_context3.next = 9;
|
|
247
297
|
break;
|
|
248
298
|
|
|
249
299
|
case 6:
|
|
250
|
-
|
|
251
|
-
|
|
252
|
-
log.error('Failed to fetch shared drive sharing links',
|
|
300
|
+
_context3.prev = 6;
|
|
301
|
+
_context3.t0 = _context3["catch"](1);
|
|
302
|
+
log.error('Failed to fetch shared drive sharing links', _context3.t0);
|
|
253
303
|
|
|
254
304
|
case 9:
|
|
255
|
-
|
|
305
|
+
_context3.prev = 9;
|
|
256
306
|
setFetchedSharingLinksDocumentId(documentId);
|
|
257
307
|
setIsFetchingSharingLinks(false);
|
|
258
|
-
return
|
|
308
|
+
return _context3.finish(9);
|
|
259
309
|
|
|
260
310
|
case 13:
|
|
261
311
|
case "end":
|
|
262
|
-
return
|
|
312
|
+
return _context3.stop();
|
|
263
313
|
}
|
|
264
|
-
},
|
|
314
|
+
}, _callee3, null, [[1, 6, 9, 13]]);
|
|
265
315
|
}));
|
|
266
316
|
|
|
267
317
|
return function fetchSharingLinks() {
|
|
268
|
-
return
|
|
318
|
+
return _ref4.apply(this, arguments);
|
|
269
319
|
};
|
|
270
320
|
}();
|
|
271
321
|
|
|
@@ -40,6 +40,7 @@ jest.mock('../../hooks/useSharingContext', function () {
|
|
|
40
40
|
fetchSharedDriveSharingLinks: mockFetchSharedDriveSharingLinks,
|
|
41
41
|
getOwner: jest.fn(),
|
|
42
42
|
getRecipients: mockGetRecipients,
|
|
43
|
+
getSharedParentPath: jest.fn().mockReturnValue(null),
|
|
43
44
|
getSharingById: mockGetSharingById,
|
|
44
45
|
hasSharedChild: mockHasSharedChild,
|
|
45
46
|
hasSharedParent: mockHasSharedParent
|
|
@@ -11,6 +11,7 @@ import IconButton from 'cozy-ui/transpiled/react/IconButton';
|
|
|
11
11
|
import ListItemIcon from 'cozy-ui/transpiled/react/ListItemIcon';
|
|
12
12
|
import ListItemText from 'cozy-ui/transpiled/react/ListItemText';
|
|
13
13
|
import Spinner from 'cozy-ui/transpiled/react/Spinner';
|
|
14
|
+
import Typography from 'cozy-ui/transpiled/react/Typography';
|
|
14
15
|
import { useI18n } from 'twake-i18n';
|
|
15
16
|
import { permission } from './actions/permission';
|
|
16
17
|
import { useSharingContext } from '../../hooks/useSharingContext';
|
|
@@ -19,10 +20,11 @@ import { GroupAvatar } from '../Avatar/GroupAvatar';
|
|
|
19
20
|
var GroupRecipientPermissions = function GroupRecipientPermissions(_ref) {
|
|
20
21
|
var name = _ref.name,
|
|
21
22
|
isOwner = _ref.isOwner,
|
|
23
|
+
isReadOnly = _ref.isReadOnly,
|
|
22
24
|
sharingId = _ref.sharingId,
|
|
23
25
|
groupIndex = _ref.groupIndex,
|
|
24
26
|
_ref$read_only = _ref.read_only,
|
|
25
|
-
|
|
27
|
+
read_only = _ref$read_only === void 0 ? false : _ref$read_only,
|
|
26
28
|
className = _ref.className,
|
|
27
29
|
isUserInsideMembers = _ref.isUserInsideMembers,
|
|
28
30
|
document = _ref.document;
|
|
@@ -46,7 +48,7 @@ var GroupRecipientPermissions = function GroupRecipientPermissions(_ref) {
|
|
|
46
48
|
revoking = _useState4[0],
|
|
47
49
|
setRevoking = _useState4[1];
|
|
48
50
|
|
|
49
|
-
var shouldShowMenu = !revoking && (isOwner || isUserInsideMembers);
|
|
51
|
+
var shouldShowMenu = !isReadOnly && !revoking && (isOwner || isUserInsideMembers);
|
|
50
52
|
|
|
51
53
|
var toggleMenu = function toggleMenu() {
|
|
52
54
|
return setMenuDisplayed(!isMenuDisplayed);
|
|
@@ -94,14 +96,16 @@ var GroupRecipientPermissions = function GroupRecipientPermissions(_ref) {
|
|
|
94
96
|
};
|
|
95
97
|
}();
|
|
96
98
|
|
|
97
|
-
var type =
|
|
99
|
+
var type = read_only ? 'one-way' : 'two-way';
|
|
98
100
|
var actions = makeActions([permission], {
|
|
99
101
|
t: t,
|
|
100
102
|
type: type
|
|
101
103
|
});
|
|
102
104
|
return /*#__PURE__*/React.createElement("div", {
|
|
103
105
|
className: className
|
|
104
|
-
}, revoking && /*#__PURE__*/React.createElement(Spinner, null), shouldShowMenu && /*#__PURE__*/React.createElement(
|
|
106
|
+
}, revoking && /*#__PURE__*/React.createElement(Spinner, null), !shouldShowMenu && /*#__PURE__*/React.createElement(Typography, {
|
|
107
|
+
variant: "body2"
|
|
108
|
+
}, t("Share.type.".concat(type))), shouldShowMenu && /*#__PURE__*/React.createElement(React.Fragment, null, /*#__PURE__*/React.createElement(DropdownButton, {
|
|
105
109
|
ref: buttonRef,
|
|
106
110
|
"aria-controls": "simple-menu",
|
|
107
111
|
"aria-haspopup": "true",
|
|
@@ -27,6 +27,7 @@ var RecipientList = function RecipientList(_ref) {
|
|
|
27
27
|
if (isGroupRecipient) {
|
|
28
28
|
return /*#__PURE__*/React.createElement(GroupRecipient, _extends({}, recipient, {
|
|
29
29
|
isOwner: isOwner,
|
|
30
|
+
isReadOnly: isReadOnly,
|
|
30
31
|
key: recipient.index,
|
|
31
32
|
document: document,
|
|
32
33
|
documentType: documentType,
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "cozy-sharing",
|
|
3
|
-
"version": "34.
|
|
3
|
+
"version": "34.1.1",
|
|
4
4
|
"description": "Provides sharing login for React applications.",
|
|
5
5
|
"main": "dist/index.js",
|
|
6
6
|
"author": "Cozy",
|
|
@@ -85,5 +85,5 @@
|
|
|
85
85
|
"sideEffects": [
|
|
86
86
|
"*.css"
|
|
87
87
|
],
|
|
88
|
-
"gitHead": "
|
|
88
|
+
"gitHead": "f5d5d581fa16bf65f8411057274fae219f7ee709"
|
|
89
89
|
}
|
|
@@ -16,6 +16,7 @@ import { getOrCreateFromArray } from '../../helpers/contacts'
|
|
|
16
16
|
import withLocales from '../../hoc/withLocales'
|
|
17
17
|
import { usePendingRecipients } from '../../hooks/usePendingRecipients'
|
|
18
18
|
import { useSharingContext } from '../../hooks/useSharingContext'
|
|
19
|
+
import { getRecipientsFromSharing } from '../../state'
|
|
19
20
|
import styles from '../../styles/share.styl'
|
|
20
21
|
import AntivirusAlert from '../AntivirusAlert'
|
|
21
22
|
import { default as DumbShareByEmail } from '../ShareByEmail'
|
|
@@ -40,6 +41,7 @@ const FederatedFolderModalContent = ({
|
|
|
40
41
|
getDocumentPermissions,
|
|
41
42
|
fetchSharedDriveSharingLinks,
|
|
42
43
|
getRecipients,
|
|
44
|
+
getSharedParentPath,
|
|
43
45
|
hasSharedChild,
|
|
44
46
|
hasSharedParent,
|
|
45
47
|
revoke
|
|
@@ -178,7 +180,40 @@ const FederatedFolderModalContent = ({
|
|
|
178
180
|
}
|
|
179
181
|
|
|
180
182
|
const documentId = existingDocument?._id || existingDocument?.id
|
|
181
|
-
|
|
183
|
+
// Owner case: when document is inside a shared folder (via path) but has no driveId,
|
|
184
|
+
// find the parent shared folder to use its _id for recipient/permission lookups.
|
|
185
|
+
const sharedParentPath =
|
|
186
|
+
!sharedDriveSharing && hasSharedParentByPath && documentPath
|
|
187
|
+
? getSharedParentPath(documentPath)
|
|
188
|
+
: null
|
|
189
|
+
const [sharedParentFolder, setSharedParentFolder] = useState(null)
|
|
190
|
+
|
|
191
|
+
useEffect(() => {
|
|
192
|
+
if (!sharedParentPath) return
|
|
193
|
+
const fetchParentFolder = async () => {
|
|
194
|
+
try {
|
|
195
|
+
const res = await client
|
|
196
|
+
.collection('io.cozy.files')
|
|
197
|
+
.statByPath(sharedParentPath)
|
|
198
|
+
if (res.data) setSharedParentFolder(res.data)
|
|
199
|
+
} catch (err) {
|
|
200
|
+
log.error('Failed to fetch shared parent folder', err)
|
|
201
|
+
}
|
|
202
|
+
}
|
|
203
|
+
fetchParentFolder()
|
|
204
|
+
}, [sharedParentPath, client])
|
|
205
|
+
|
|
206
|
+
const sharingReferenceId =
|
|
207
|
+
!sharedDriveSharing && sharedParentFolder?._id
|
|
208
|
+
? sharedParentFolder._id
|
|
209
|
+
: documentId
|
|
210
|
+
|
|
211
|
+
const existingRecipients =
|
|
212
|
+
sharedDriveSharing?.attributes?.members && documentId
|
|
213
|
+
? getRecipientsFromSharing(sharedDriveSharing, documentId)
|
|
214
|
+
: sharingReferenceId
|
|
215
|
+
? getRecipients(sharingReferenceId)
|
|
216
|
+
: []
|
|
182
217
|
const documentPermissions = documentId
|
|
183
218
|
? getDocumentPermissions(documentId)
|
|
184
219
|
: []
|
|
@@ -33,6 +33,7 @@ jest.mock('../../hooks/useSharingContext', () => ({
|
|
|
33
33
|
fetchSharedDriveSharingLinks: mockFetchSharedDriveSharingLinks,
|
|
34
34
|
getOwner: jest.fn(),
|
|
35
35
|
getRecipients: mockGetRecipients,
|
|
36
|
+
getSharedParentPath: jest.fn().mockReturnValue(null),
|
|
36
37
|
getSharingById: mockGetSharingById,
|
|
37
38
|
hasSharedChild: mockHasSharedChild,
|
|
38
39
|
hasSharedParent: mockHasSharedParent
|
|
@@ -9,6 +9,7 @@ import IconButton from 'cozy-ui/transpiled/react/IconButton'
|
|
|
9
9
|
import ListItemIcon from 'cozy-ui/transpiled/react/ListItemIcon'
|
|
10
10
|
import ListItemText from 'cozy-ui/transpiled/react/ListItemText'
|
|
11
11
|
import Spinner from 'cozy-ui/transpiled/react/Spinner'
|
|
12
|
+
import Typography from 'cozy-ui/transpiled/react/Typography'
|
|
12
13
|
import { useI18n } from 'twake-i18n'
|
|
13
14
|
|
|
14
15
|
import { permission } from './actions/permission'
|
|
@@ -18,9 +19,10 @@ import { GroupAvatar } from '../Avatar/GroupAvatar'
|
|
|
18
19
|
const GroupRecipientPermissions = ({
|
|
19
20
|
name,
|
|
20
21
|
isOwner,
|
|
22
|
+
isReadOnly,
|
|
21
23
|
sharingId,
|
|
22
24
|
groupIndex,
|
|
23
|
-
read_only
|
|
25
|
+
read_only = false,
|
|
24
26
|
className,
|
|
25
27
|
isUserInsideMembers,
|
|
26
28
|
document
|
|
@@ -32,7 +34,8 @@ const GroupRecipientPermissions = ({
|
|
|
32
34
|
const [isMenuDisplayed, setMenuDisplayed] = useState(false)
|
|
33
35
|
const [revoking, setRevoking] = useState(false)
|
|
34
36
|
|
|
35
|
-
const shouldShowMenu =
|
|
37
|
+
const shouldShowMenu =
|
|
38
|
+
!isReadOnly && !revoking && (isOwner || isUserInsideMembers)
|
|
36
39
|
|
|
37
40
|
const toggleMenu = () => setMenuDisplayed(!isMenuDisplayed)
|
|
38
41
|
const hideMenu = () => setMenuDisplayed(false)
|
|
@@ -47,7 +50,7 @@ const GroupRecipientPermissions = ({
|
|
|
47
50
|
setRevoking(false)
|
|
48
51
|
}
|
|
49
52
|
|
|
50
|
-
const type =
|
|
53
|
+
const type = read_only ? 'one-way' : 'two-way'
|
|
51
54
|
|
|
52
55
|
const actions = makeActions([permission], {
|
|
53
56
|
t,
|
|
@@ -57,6 +60,9 @@ const GroupRecipientPermissions = ({
|
|
|
57
60
|
return (
|
|
58
61
|
<div className={className}>
|
|
59
62
|
{revoking && <Spinner />}
|
|
63
|
+
{!shouldShowMenu && (
|
|
64
|
+
<Typography variant="body2">{t(`Share.type.${type}`)}</Typography>
|
|
65
|
+
)}
|
|
60
66
|
{shouldShowMenu && (
|
|
61
67
|
<>
|
|
62
68
|
<DropdownButton
|