cozy-sharing 30.1.1 → 30.2.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/DumbFederatedFolderModal.js +9 -3
- package/dist/components/FederatedFolder/FederatedFolderModal.js +9 -3
- package/dist/components/ShareByLink.js +115 -54
- package/dist/components/ShareDialogCozyToCozy.js +18 -3
- package/dist/components/ShareDialogOnlyByLink.js +6 -2
- package/dist/components/ShareModal/ShareModal.js +6 -5
- package/dist/components/ShareModal.js +13 -3
- package/dist/components/ShareModal.spec.js +4 -4
- package/dist/components/ShareRestrictionModal/ShareRestrictionModal.js +51 -64
- package/dist/components/ShareRestrictionModal/helpers.js +61 -12
- package/dist/components/SharedDrive/DumbSharedDriveModal.js +9 -3
- package/dist/components/SharedDrive/SharedDriveEditModal.js +14 -3
- package/dist/components/SharedFolder/DumbBatchSharedFolderModal.js +12 -4
- package/package.json +2 -2
- package/src/components/FederatedFolder/DumbFederatedFolderModal.jsx +8 -2
- package/src/components/FederatedFolder/FederatedFolderModal.jsx +11 -2
- package/src/components/ShareByLink.jsx +66 -25
- package/src/components/ShareDialogCozyToCozy.jsx +17 -2
- package/src/components/ShareDialogOnlyByLink.jsx +5 -1
- package/src/components/ShareModal/ShareModal.jsx +4 -2
- package/src/components/ShareModal.jsx +10 -0
- package/src/components/ShareModal.spec.js +7 -3
- package/src/components/ShareRestrictionModal/ShareRestrictionModal.jsx +42 -38
- package/src/components/ShareRestrictionModal/helpers.js +23 -4
- package/src/components/SharedDrive/DumbSharedDriveModal.jsx +8 -2
- package/src/components/SharedDrive/SharedDriveEditModal.jsx +20 -2
- package/src/components/SharedFolder/DumbBatchSharedFolderModal.jsx +10 -2
|
@@ -36,7 +36,7 @@ export const ShareModal = withLocales(props => {
|
|
|
36
36
|
|
|
37
37
|
const isFederatedMode = flag('drive.federated-shared-folder.enabled')
|
|
38
38
|
if (isFederatedMode && allLoaded) {
|
|
39
|
-
return <FederatedFolderModal document={document}
|
|
39
|
+
return <FederatedFolderModal document={document} {...rest} />
|
|
40
40
|
}
|
|
41
41
|
|
|
42
42
|
const isEditable =
|
|
@@ -61,6 +61,8 @@ export const ShareModal = withLocales(props => {
|
|
|
61
61
|
})
|
|
62
62
|
|
|
63
63
|
ShareModal.propTypes = {
|
|
64
|
+
autoOpenShareRestriction: PropTypes.bool,
|
|
64
65
|
document: PropTypes.object.isRequired,
|
|
65
|
-
onRevokeSuccess: PropTypes.func
|
|
66
|
+
onRevokeSuccess: PropTypes.func,
|
|
67
|
+
showGenerateLinkButton: PropTypes.bool
|
|
66
68
|
}
|
|
@@ -8,6 +8,7 @@ import ShareDialogOnlyByLink from './ShareDialogOnlyByLink'
|
|
|
8
8
|
import { SharedDriveEditModal } from './SharedDrive/SharedDriveEditModal'
|
|
9
9
|
|
|
10
10
|
export const ShareModal = ({
|
|
11
|
+
autoOpenShareRestriction,
|
|
11
12
|
createContact,
|
|
12
13
|
document,
|
|
13
14
|
documentType = 'Document',
|
|
@@ -24,6 +25,7 @@ export const ShareModal = ({
|
|
|
24
25
|
recipients,
|
|
25
26
|
sharing,
|
|
26
27
|
sharingDesc,
|
|
28
|
+
showGenerateLinkButton,
|
|
27
29
|
twoStepsConfirmationMethods
|
|
28
30
|
}) => {
|
|
29
31
|
if (isSharedDrive && !flag('drive.federated-shared-folder.enabled')) {
|
|
@@ -35,6 +37,8 @@ export const ShareModal = ({
|
|
|
35
37
|
onShare={onShare}
|
|
36
38
|
onRevoke={onRevoke}
|
|
37
39
|
onClose={onClose}
|
|
40
|
+
autoOpenShareRestriction={autoOpenShareRestriction}
|
|
41
|
+
showGenerateLinkButton={showGenerateLinkButton}
|
|
38
42
|
/>
|
|
39
43
|
)
|
|
40
44
|
}
|
|
@@ -58,6 +62,8 @@ export const ShareModal = ({
|
|
|
58
62
|
link={link}
|
|
59
63
|
onClose={onClose}
|
|
60
64
|
permissions={permissions}
|
|
65
|
+
showGenerateLinkButton={showGenerateLinkButton}
|
|
66
|
+
autoOpenShareRestriction={autoOpenShareRestriction}
|
|
61
67
|
/>
|
|
62
68
|
) : (
|
|
63
69
|
<ShareDialogCozyToCozy
|
|
@@ -79,6 +85,8 @@ export const ShareModal = ({
|
|
|
79
85
|
showShareByLink={showShareByLink}
|
|
80
86
|
showShareOnlyByLink={showShareOnlyByLink}
|
|
81
87
|
showWhoHasAccess={showWhoHasAccess}
|
|
88
|
+
showGenerateLinkButton={showGenerateLinkButton}
|
|
89
|
+
autoOpenShareRestriction={autoOpenShareRestriction}
|
|
82
90
|
twoStepsConfirmationMethods={twoStepsConfirmationMethods}
|
|
83
91
|
/>
|
|
84
92
|
)
|
|
@@ -87,6 +95,7 @@ export const ShareModal = ({
|
|
|
87
95
|
export default ShareModal
|
|
88
96
|
|
|
89
97
|
ShareModal.propTypes = {
|
|
98
|
+
autoOpenShareRestriction: PropTypes.bool,
|
|
90
99
|
createContact: PropTypes.func.isRequired,
|
|
91
100
|
document: PropTypes.object.isRequired,
|
|
92
101
|
documentType: PropTypes.string,
|
|
@@ -100,6 +109,7 @@ ShareModal.propTypes = {
|
|
|
100
109
|
permissions: PropTypes.array.isRequired,
|
|
101
110
|
recipients: PropTypes.array.isRequired,
|
|
102
111
|
sharingDesc: PropTypes.string,
|
|
112
|
+
showGenerateLinkButton: PropTypes.bool,
|
|
103
113
|
twoStepsConfirmationMethods: PropTypes.shape({
|
|
104
114
|
getRecipientsToBeConfirmed: PropTypes.func,
|
|
105
115
|
confirmRecipient: PropTypes.func,
|
|
@@ -6,8 +6,12 @@ import flag from 'cozy-flags'
|
|
|
6
6
|
import { ShareModal } from './ShareModal'
|
|
7
7
|
import AppLike from '../../test/AppLike'
|
|
8
8
|
|
|
9
|
-
jest.mock('./ShareDialogCozyToCozy', () => () =>
|
|
10
|
-
|
|
9
|
+
jest.mock('./ShareDialogCozyToCozy', () => () => (
|
|
10
|
+
<div>ShareDialogCozyToCozy</div>
|
|
11
|
+
))
|
|
12
|
+
jest.mock('./ShareDialogOnlyByLink', () => () => (
|
|
13
|
+
<div>ShareDialogOnlyByLink</div>
|
|
14
|
+
))
|
|
11
15
|
|
|
12
16
|
jest.mock('cozy-flags')
|
|
13
17
|
|
|
@@ -43,7 +47,7 @@ describe('ShareModal component', () => {
|
|
|
43
47
|
})
|
|
44
48
|
|
|
45
49
|
it('should render ShareDialogOnlyByLink if flag cozy.hide-sharing-cozy-to-cozy is true', () => {
|
|
46
|
-
flag.mockImplementation(
|
|
50
|
+
flag.mockImplementation(name => name === 'cozy.hide-sharing-cozy-to-cozy')
|
|
47
51
|
|
|
48
52
|
const root = setup({ documentType: 'Document' })
|
|
49
53
|
|
|
@@ -77,51 +77,55 @@ export const ShareRestrictionModal = ({ file, onClose }) => {
|
|
|
77
77
|
|
|
78
78
|
const handleClick = async () => {
|
|
79
79
|
setLoading(true)
|
|
80
|
-
//
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
|
|
84
|
-
|
|
85
|
-
|
|
86
|
-
|
|
87
|
-
|
|
88
|
-
|
|
89
|
-
|
|
90
|
-
|
|
91
|
-
|
|
92
|
-
|
|
93
|
-
|
|
94
|
-
|
|
95
|
-
|
|
96
|
-
|
|
97
|
-
|
|
98
|
-
|
|
99
|
-
|
|
100
|
-
|
|
101
|
-
|
|
102
|
-
|
|
103
|
-
|
|
104
|
-
|
|
105
|
-
|
|
106
|
-
|
|
107
|
-
|
|
108
|
-
|
|
109
|
-
password,
|
|
110
|
-
editingRights,
|
|
111
|
-
documentType,
|
|
112
|
-
updateDocumentPermissions,
|
|
113
|
-
showAlert
|
|
114
|
-
})
|
|
115
|
-
const url = generateWebLink({
|
|
80
|
+
// The clipboard write must be initiated synchronously within the click
|
|
81
|
+
// handler for Safari to honor the user gesture; we pass a pending blob
|
|
82
|
+
// whose content resolves after the permission round-trip.
|
|
83
|
+
const permsPromise = hasSharingLink
|
|
84
|
+
? updatePermissions({
|
|
85
|
+
file,
|
|
86
|
+
t,
|
|
87
|
+
dateToggle,
|
|
88
|
+
selectedDate,
|
|
89
|
+
passwordToggle,
|
|
90
|
+
password,
|
|
91
|
+
editingRights,
|
|
92
|
+
documentType,
|
|
93
|
+
updateDocumentPermissions,
|
|
94
|
+
showAlert
|
|
95
|
+
}).then(([{ data: perms }]) => perms)
|
|
96
|
+
: createPermissions({
|
|
97
|
+
file,
|
|
98
|
+
t,
|
|
99
|
+
ttl: makeTTL(dateToggle && selectedDate),
|
|
100
|
+
password,
|
|
101
|
+
editingRights,
|
|
102
|
+
documentType,
|
|
103
|
+
shareByLink,
|
|
104
|
+
showAlert
|
|
105
|
+
}).then(({ data: perms }) => perms)
|
|
106
|
+
|
|
107
|
+
const urlPromise = permsPromise.then(perms =>
|
|
108
|
+
generateWebLink({
|
|
116
109
|
cozyUrl: client.getStackClient().uri,
|
|
117
110
|
searchParams: [['sharecode', perms.attributes.shortcodes.code]],
|
|
118
111
|
pathname: '/public',
|
|
119
112
|
slug: getAppSlugFromDocumentType({ documentType }),
|
|
120
113
|
subDomainType: client.capabilities.flat_subdomains ? 'flat' : 'nested'
|
|
121
114
|
})
|
|
122
|
-
|
|
123
|
-
|
|
115
|
+
)
|
|
116
|
+
|
|
117
|
+
await copyToClipboard(urlPromise, { t, showAlert })
|
|
118
|
+
try {
|
|
119
|
+
// Observe the permission result so we can keep the modal open (and
|
|
120
|
+
// preserve the user's date / password / editing-rights inputs) if
|
|
121
|
+
// the permission round-trip failed. copyToClipboard swallows its
|
|
122
|
+
// own errors so the await above always resolves.
|
|
123
|
+
await permsPromise
|
|
124
|
+
} catch {
|
|
125
|
+
setLoading(false)
|
|
126
|
+
return
|
|
124
127
|
}
|
|
128
|
+
onClose()
|
|
125
129
|
}
|
|
126
130
|
|
|
127
131
|
const handleRevokeLink = async () => {
|
|
@@ -96,17 +96,36 @@ export const generateShareLinkFromFile = ({
|
|
|
96
96
|
}
|
|
97
97
|
|
|
98
98
|
/**
|
|
99
|
-
* Copy a
|
|
99
|
+
* Copy a value to the clipboard.
|
|
100
100
|
*
|
|
101
|
-
*
|
|
101
|
+
* Accepts a resolved string or a `Promise<string>`. The promise form is
|
|
102
|
+
* required when the value depends on a prior async step (e.g. creating a
|
|
103
|
+
* sharing link) from within a click handler: Safari drops the user-gesture
|
|
104
|
+
* context across any `await`, so `navigator.clipboard.writeText` called after
|
|
105
|
+
* an awaited call throws `NotAllowedError`. Passing a pending blob to
|
|
106
|
+
* `ClipboardItem` lets the clipboard API be invoked synchronously while the
|
|
107
|
+
* content is resolved later.
|
|
108
|
+
*
|
|
109
|
+
* @param {string | Promise<string>} value - Value to copy
|
|
102
110
|
* @param {object} [options]
|
|
103
|
-
* @param {
|
|
111
|
+
* @param {Function} options.t - Translation function
|
|
104
112
|
* @param {Function} options.showAlert - Function to display an alert
|
|
105
113
|
*/
|
|
106
114
|
export const copyToClipboard = async (value, { t, showAlert } = {}) => {
|
|
107
115
|
if (!value) return false
|
|
108
116
|
try {
|
|
109
|
-
|
|
117
|
+
if (typeof value === 'string') {
|
|
118
|
+
await navigator.clipboard.writeText(value)
|
|
119
|
+
} else if (typeof ClipboardItem !== 'undefined') {
|
|
120
|
+
const blobPromise = Promise.resolve(value).then(
|
|
121
|
+
text => new Blob([text], { type: 'text/plain' })
|
|
122
|
+
)
|
|
123
|
+
await navigator.clipboard.write([
|
|
124
|
+
new ClipboardItem({ 'text/plain': blobPromise })
|
|
125
|
+
])
|
|
126
|
+
} else {
|
|
127
|
+
await navigator.clipboard.writeText(await value)
|
|
128
|
+
}
|
|
110
129
|
showAlert({
|
|
111
130
|
message: t('copyReminderContent.success'),
|
|
112
131
|
severity: 'success',
|
|
@@ -23,7 +23,9 @@ export const DumbSharedDriveModal = withLocales(
|
|
|
23
23
|
onShare,
|
|
24
24
|
onRename,
|
|
25
25
|
showNameField = true,
|
|
26
|
-
sharingLink
|
|
26
|
+
sharingLink,
|
|
27
|
+
autoOpenShareRestriction,
|
|
28
|
+
showGenerateLinkButton
|
|
27
29
|
}) => {
|
|
28
30
|
const { t } = useI18n()
|
|
29
31
|
return (
|
|
@@ -51,6 +53,8 @@ export const DumbSharedDriveModal = withLocales(
|
|
|
51
53
|
createLabel={t('SharedDrive.sharedDriveModal.create')}
|
|
52
54
|
shareLabel={t('FederatedFolder.share')}
|
|
53
55
|
saveLabel={t('SharedDrive.sharedDriveModal.save')}
|
|
56
|
+
autoOpenShareRestriction={autoOpenShareRestriction}
|
|
57
|
+
showGenerateLinkButton={showGenerateLinkButton}
|
|
54
58
|
/>
|
|
55
59
|
)
|
|
56
60
|
}
|
|
@@ -72,7 +76,9 @@ DumbSharedDriveModal.propTypes = {
|
|
|
72
76
|
onShare: PropTypes.func.isRequired,
|
|
73
77
|
onRename: PropTypes.func,
|
|
74
78
|
showNameField: PropTypes.bool,
|
|
75
|
-
sharingLink: PropTypes.string
|
|
79
|
+
sharingLink: PropTypes.string,
|
|
80
|
+
autoOpenShareRestriction: PropTypes.bool,
|
|
81
|
+
showGenerateLinkButton: PropTypes.bool
|
|
76
82
|
}
|
|
77
83
|
|
|
78
84
|
export default DumbSharedDriveModal
|
|
@@ -11,7 +11,16 @@ import { useSharingContext } from '../../hooks/useSharingContext'
|
|
|
11
11
|
import { Contact } from '../../models'
|
|
12
12
|
|
|
13
13
|
export const SharedDriveEditModal = withLocales(
|
|
14
|
-
({
|
|
14
|
+
({
|
|
15
|
+
document,
|
|
16
|
+
sharing,
|
|
17
|
+
recipients,
|
|
18
|
+
onShare,
|
|
19
|
+
onRevoke,
|
|
20
|
+
onClose,
|
|
21
|
+
autoOpenShareRestriction,
|
|
22
|
+
showGenerateLinkButton
|
|
23
|
+
}) => {
|
|
15
24
|
const client = useClient()
|
|
16
25
|
const { t } = useI18n()
|
|
17
26
|
const { showAlert } = useAlert()
|
|
@@ -51,11 +60,20 @@ export const SharedDriveEditModal = withLocales(
|
|
|
51
60
|
sharedDriveName={name}
|
|
52
61
|
handleSharedDriveNameChange={handleNameChange}
|
|
53
62
|
onRename={onRename}
|
|
63
|
+
autoOpenShareRestriction={autoOpenShareRestriction}
|
|
64
|
+
showGenerateLinkButton={showGenerateLinkButton}
|
|
54
65
|
/>
|
|
55
66
|
)
|
|
56
67
|
}
|
|
57
68
|
)
|
|
58
69
|
|
|
59
70
|
SharedDriveEditModal.propTypes = {
|
|
60
|
-
|
|
71
|
+
document: PropTypes.object,
|
|
72
|
+
sharing: PropTypes.object,
|
|
73
|
+
recipients: PropTypes.array,
|
|
74
|
+
onShare: PropTypes.func.isRequired,
|
|
75
|
+
onRevoke: PropTypes.func.isRequired,
|
|
76
|
+
onClose: PropTypes.func.isRequired,
|
|
77
|
+
autoOpenShareRestriction: PropTypes.bool,
|
|
78
|
+
showGenerateLinkButton: PropTypes.bool
|
|
61
79
|
}
|
|
@@ -38,7 +38,9 @@ export const DumbBatchSharedFolderModal = withLocales(
|
|
|
38
38
|
shareLabel,
|
|
39
39
|
saveLabel,
|
|
40
40
|
sharingDesc,
|
|
41
|
-
showShareByEmail = true
|
|
41
|
+
showShareByEmail = true,
|
|
42
|
+
autoOpenShareRestriction,
|
|
43
|
+
showGenerateLinkButton
|
|
42
44
|
}) => {
|
|
43
45
|
const hasRecipients = Boolean(recipients?.length)
|
|
44
46
|
|
|
@@ -59,6 +61,8 @@ export const DumbBatchSharedFolderModal = withLocales(
|
|
|
59
61
|
link={sharingLink}
|
|
60
62
|
document={document}
|
|
61
63
|
documentType="Files"
|
|
64
|
+
showGenerateLinkButton={showGenerateLinkButton}
|
|
65
|
+
autoOpenShareRestriction={autoOpenShareRestriction}
|
|
62
66
|
/>
|
|
63
67
|
)
|
|
64
68
|
}
|
|
@@ -70,6 +74,8 @@ export const DumbBatchSharedFolderModal = withLocales(
|
|
|
70
74
|
link={sharingLink}
|
|
71
75
|
document={document}
|
|
72
76
|
documentType="Files"
|
|
77
|
+
showGenerateLinkButton={showGenerateLinkButton}
|
|
78
|
+
autoOpenShareRestriction={autoOpenShareRestriction}
|
|
73
79
|
/>
|
|
74
80
|
<Button
|
|
75
81
|
variant="primary"
|
|
@@ -182,7 +188,9 @@ DumbBatchSharedFolderModal.propTypes = {
|
|
|
182
188
|
shareLabel: PropTypes.string,
|
|
183
189
|
saveLabel: PropTypes.string,
|
|
184
190
|
sharingDesc: PropTypes.string,
|
|
185
|
-
showShareByEmail: PropTypes.bool
|
|
191
|
+
showShareByEmail: PropTypes.bool,
|
|
192
|
+
autoOpenShareRestriction: PropTypes.bool,
|
|
193
|
+
showGenerateLinkButton: PropTypes.bool
|
|
186
194
|
}
|
|
187
195
|
|
|
188
196
|
DumbBatchSharedFolderModal.defaultProps = {
|