cozy-sharing 19.0.0 → 21.0.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.
Files changed (38) hide show
  1. package/CHANGELOG.md +68 -0
  2. package/dist/SharingProvider.js +16 -9
  3. package/dist/actions/{openSharingLink.js → addToCozySharingLink.js} +12 -16
  4. package/dist/actions/createCozySharingLink.js +51 -0
  5. package/dist/actions/syncToCozySharingLink.js +51 -0
  6. package/dist/components/Recipient/LinkRecipient.js +20 -4
  7. package/dist/components/ShareRestrictionModal/BoxPassword.js +21 -4
  8. package/dist/components/ShareRestrictionModal/ShareRestrictionContentModal.js +33 -9
  9. package/dist/components/ShareRestrictionModal/ShareRestrictionModal.js +74 -78
  10. package/dist/components/ShareRestrictionModal/helpers.js +82 -47
  11. package/dist/components/ShareRestrictionModal/helpers.spec.js +142 -20
  12. package/dist/components/SharingBanner/components/PublicBanner.js +3 -3
  13. package/dist/components/SharingBanner/components/PublicBanner.spec.js +1 -1
  14. package/dist/components/SharingBanner/components/SharingBanner.js +3 -3
  15. package/dist/components/SharingBanner/hooks/useSharingInfos.js +37 -25
  16. package/dist/components/SharingBanner/hooks/useSharingInfos.spec.js +9 -9
  17. package/dist/helpers/permissions.js +15 -0
  18. package/dist/index.js +3 -1
  19. package/locales/en.json +2 -0
  20. package/locales/fr.json +2 -0
  21. package/package.json +4 -4
  22. package/src/SharingProvider.jsx +10 -5
  23. package/src/actions/addToCozySharingLink.js +51 -0
  24. package/src/actions/createCozySharingLink.js +47 -0
  25. package/src/actions/{openSharingLink.js → syncToCozySharingLink.js} +10 -12
  26. package/src/components/Recipient/LinkRecipient.jsx +28 -4
  27. package/src/components/ShareRestrictionModal/BoxPassword.jsx +14 -0
  28. package/src/components/ShareRestrictionModal/ShareRestrictionContentModal.jsx +31 -9
  29. package/src/components/ShareRestrictionModal/ShareRestrictionModal.jsx +55 -46
  30. package/src/components/ShareRestrictionModal/helpers.js +65 -31
  31. package/src/components/ShareRestrictionModal/helpers.spec.js +92 -11
  32. package/src/components/SharingBanner/components/PublicBanner.jsx +3 -3
  33. package/src/components/SharingBanner/components/PublicBanner.spec.jsx +1 -1
  34. package/src/components/SharingBanner/components/SharingBanner.jsx +3 -3
  35. package/src/components/SharingBanner/hooks/useSharingInfos.jsx +12 -3
  36. package/src/components/SharingBanner/hooks/useSharingInfos.spec.js +7 -7
  37. package/src/helpers/permissions.js +12 -0
  38. package/src/index.jsx +3 -1
@@ -1,4 +1,4 @@
1
- import { addDays } from 'date-fns'
1
+ import { addDays, isValid } from 'date-fns'
2
2
  import PropTypes from 'prop-types'
3
3
  import React from 'react'
4
4
 
@@ -9,6 +9,8 @@ import { useI18n } from 'cozy-ui/transpiled/react/providers/I18n'
9
9
  import { BoxDate } from './BoxDate'
10
10
  import { BoxEditingRights } from './BoxEditingRights'
11
11
  import { BoxPassword } from './BoxPassword'
12
+ import { checkIsPermissionHasPassword } from '../../helpers/permissions'
13
+ import { useSharingContext } from '../../hooks/useSharingContext'
12
14
 
13
15
  const PASSWORD_MIN_LENGTH = 4
14
16
 
@@ -32,24 +34,43 @@ export const ShareRestrictionContentModal = ({
32
34
  setEditingRights
33
35
  }) => {
34
36
  const { t } = useI18n()
37
+ const { getDocumentPermissions } = useSharingContext()
38
+ const permissions = getDocumentPermissions(file._id)
39
+ const hasPassword = checkIsPermissionHasPassword(permissions)
35
40
 
36
- const handlePasswordToggle = val => {
37
- setPasswordToggle(val)
38
- }
39
41
  const handlePassword = value => {
40
42
  setPassword(value)
41
43
  setIsValidPassword(
42
- value.trim().length === 0 || value.trim().length >= PASSWORD_MIN_LENGTH
44
+ (hasPassword && value.trim().length === 0) ||
45
+ value.trim().length >= PASSWORD_MIN_LENGTH
43
46
  )
44
47
  }
45
48
 
49
+ const handlePasswordToggle = val => {
50
+ setPasswordToggle(val)
51
+ setPassword('')
52
+ if (val && !password) {
53
+ setIsValidPassword(hasPassword)
54
+ } else {
55
+ setIsValidPassword(true)
56
+ }
57
+ }
58
+
59
+ const handleDate = date => {
60
+ setSelectedDate(date)
61
+ setIsValidDate(isValid(date))
62
+ }
63
+
46
64
  const handleDateToggle = val => {
65
+ setDateToggle(val)
47
66
  if (!val) {
67
+ setSelectedDate(null)
68
+ setIsValidDate(true)
69
+ } else {
70
+ const defaultValue = val ? addDays(new Date(), 30) : null
71
+ setSelectedDate(defaultValue)
48
72
  setIsValidDate(true)
49
73
  }
50
- const defaultValue = val ? addDays(new Date(), 30) : null
51
- setSelectedDate(defaultValue, true)
52
- setDateToggle(val)
53
74
  }
54
75
 
55
76
  return (
@@ -64,12 +85,13 @@ export const ShareRestrictionContentModal = ({
64
85
  setEditingRights={setEditingRights}
65
86
  />
66
87
  <BoxDate
67
- onChange={setSelectedDate}
88
+ onChange={handleDate}
68
89
  date={selectedDate}
69
90
  onToggle={handleDateToggle}
70
91
  toggle={dateToggle}
71
92
  />
72
93
  <BoxPassword
94
+ file={file}
73
95
  onChange={handlePassword}
74
96
  password={password}
75
97
  onToggle={handlePasswordToggle}
@@ -2,9 +2,7 @@ import { addDays } from 'date-fns'
2
2
  import PropTypes from 'prop-types'
3
3
  import React, { useState } from 'react'
4
4
 
5
- import { useClient } from 'cozy-client'
6
- import { getSharingLink as makeSharingLink } from 'cozy-client/dist/models/sharing'
7
- import { isMobile } from 'cozy-device-helper'
5
+ import { generateWebLink, useClient } from 'cozy-client'
8
6
  import Button from 'cozy-ui/transpiled/react/Buttons'
9
7
  import { ConfirmDialog } from 'cozy-ui/transpiled/react/CozyDialogs'
10
8
  import Icon from 'cozy-ui/transpiled/react/Icon'
@@ -14,14 +12,17 @@ import { useI18n } from 'cozy-ui/transpiled/react/providers/I18n'
14
12
  import { ShareRestrictionContentModal } from './ShareRestrictionContentModal'
15
13
  import {
16
14
  copyToClipboard,
17
- forwardFile,
18
15
  updatePermissions,
19
16
  makeTTL,
20
- READ_ONLY_PERMS,
21
- WRITE_PERMS,
22
- revokePermissions
17
+ revokePermissions,
18
+ createPermissions
23
19
  } from './helpers'
24
- import { checkIsReadOnlyPermissions } from '../../helpers/permissions'
20
+ import {
21
+ checkIsPermissionHasExpiresDate,
22
+ checkIsPermissionHasPassword,
23
+ checkIsReadOnlyPermissions,
24
+ getPermissionExpiresDate
25
+ } from '../../helpers/permissions'
25
26
  import { useSharingContext } from '../../hooks/useSharingContext'
26
27
 
27
28
  const PASSWORD_MIN_LENGTH = 4
@@ -31,11 +32,8 @@ export const ShareRestrictionModal = ({ file, onClose }) => {
31
32
  const { t } = useI18n()
32
33
  const { showAlert } = useAlert()
33
34
  const [password, setPassword] = useState('')
34
- const [selectedDate, setSelectedDate] = useState(addDays(new Date(), 30))
35
35
  const [isValidDate, setIsValidDate] = useState(true)
36
36
  const [isValidPassword, setIsValidPassword] = useState(true)
37
- const [dateToggle, setDateToggle] = useState(true)
38
- const [passwordToggle, setPasswordToggle] = useState(false)
39
37
  const [loading, setLoading] = useState(false)
40
38
 
41
39
  const {
@@ -50,64 +48,75 @@ export const ShareRestrictionModal = ({ file, onClose }) => {
50
48
  const hasSharingLink = getSharingLink(file._id) !== null
51
49
  const permissions = getDocumentPermissions(file._id)
52
50
  const isReadOnlyPermissions = checkIsReadOnlyPermissions(permissions)
53
-
51
+ const hasPassword = checkIsPermissionHasPassword(permissions)
52
+ const hasExpiresDate = checkIsPermissionHasExpiresDate(permissions)
53
+ const expiresDate = getPermissionExpiresDate(permissions)
54
+ const defaultDate = expiresDate
55
+ ? new Date(expiresDate)
56
+ : addDays(new Date(), 30)
57
+
58
+ const [selectedDate, setSelectedDate] = useState(defaultDate)
59
+ const [dateToggle, setDateToggle] = useState(
60
+ permissions.length > 0 ? hasExpiresDate : true
61
+ )
62
+ const [passwordToggle, setPasswordToggle] = useState(hasPassword)
54
63
  const [editingRights, setEditingRights] = useState(
55
64
  isReadOnlyPermissions || permissions.length === 0 ? 'readOnly' : 'write'
56
65
  )
57
66
 
58
- const isDesktopOrMobileWithoutShareAPI =
59
- (isMobile() && !navigator.share) || !isMobile()
60
-
61
67
  const helperTextPassword = !isValidPassword
62
68
  ? t('ShareRestrictionModal.invalidPasswordMessage', {
63
69
  smart_count: PASSWORD_MIN_LENGTH - password.length
64
70
  })
65
71
  : null
66
72
 
67
- const handleDateChange = (date, isValid) => {
68
- setSelectedDate(date)
69
- setIsValidDate(isValid)
70
- }
71
-
72
73
  const handleClick = async () => {
73
74
  setLoading(true)
74
75
  // If the file is not shared, we create a new sharing link
75
76
  if (!hasSharingLink) {
76
- const verbs = editingRights === 'readOnly' ? READ_ONLY_PERMS : WRITE_PERMS
77
- await shareByLink(file, { verbs })
78
- const url = getSharingLink(file._id)
79
- await copyToClipboard(url, { t, showAlert })
80
- onClose()
81
- return
82
- }
83
-
84
- await updatePermissions({
85
- file,
86
- t,
87
- editingRights,
88
- documentType,
89
- updateDocumentPermissions,
90
- showAlert
91
- })
92
-
93
- const ttl = makeTTL(dateToggle && selectedDate)
94
- if (isDesktopOrMobileWithoutShareAPI) {
95
- const url = await makeSharingLink(client, [file._id], {
77
+ const ttl = makeTTL(dateToggle && selectedDate)
78
+ const { data: perms } = await createPermissions({
79
+ file,
80
+ t,
96
81
  ttl,
97
- password
82
+ password,
83
+ editingRights,
84
+ documentType,
85
+ shareByLink,
86
+ showAlert
87
+ })
88
+ const url = generateWebLink({
89
+ cozyUrl: client.getStackClient().uri,
90
+ searchParams: [['sharecode', perms.attributes.shortcodes.code]],
91
+ pathname: '/public',
92
+ slug: 'drive',
93
+ subDomainType: client.capabilities.flat_subdomains ? 'flat' : 'nested'
98
94
  })
99
95
  await copyToClipboard(url, { t, showAlert })
96
+ onClose()
100
97
  } else {
101
- await forwardFile({
102
- client,
98
+ const [{ data: perms }] = await updatePermissions({
103
99
  file,
104
100
  t,
105
- ttl,
101
+ dateToggle,
102
+ selectedDate,
103
+ passwordToggle,
106
104
  password,
105
+ editingRights,
106
+ documentType,
107
+ updateDocumentPermissions,
107
108
  showAlert
108
109
  })
110
+ const url = generateWebLink({
111
+ cozyUrl: client.getStackClient().uri,
112
+ searchParams: [['sharecode', perms.attributes.shortcodes.code]],
113
+ pathname: '/public',
114
+ slug: 'drive',
115
+ subDomainType: client.capabilities.flat_subdomains ? 'flat' : 'nested'
116
+ })
117
+ await copyToClipboard(url, { t, showAlert })
118
+ onClose()
109
119
  }
110
- onClose()
111
120
  }
112
121
 
113
122
  const handleRevokeLink = async () => {
@@ -132,7 +141,7 @@ export const ShareRestrictionModal = ({ file, onClose }) => {
132
141
  // Date
133
142
  dateToggle={dateToggle}
134
143
  setDateToggle={setDateToggle}
135
- setSelectedDate={handleDateChange}
144
+ setSelectedDate={setSelectedDate}
136
145
  selectedDate={selectedDate}
137
146
  setIsValidDate={setIsValidDate}
138
147
  // Password
@@ -109,11 +109,53 @@ export const forwardFile = async ({
109
109
  }
110
110
  }
111
111
 
112
+ /**
113
+ * createPermissions - Create the permissions of a file
114
+ * @param {object} options
115
+ * @param {import('cozy-client/types/types').IOCozyFile} options.file File to update permissions
116
+ * @param {Function} options.t i18n function
117
+ * @param {Date|string} options.ttl - Time to live of the sharing link
118
+ * @param {string} options.password - Password
119
+ * @param {'readOnly'|'write'} options.editingRights - Editing rights
120
+ * @param {string} options.documentType - Type of the document
121
+ * @param {Function} options.shareByLink - Function to create permissions
122
+ * @param {Function} options.showAlert - Function to display an alert
123
+ */
124
+ export const createPermissions = async ({
125
+ file,
126
+ t,
127
+ ttl,
128
+ password,
129
+ editingRights,
130
+ documentType,
131
+ shareByLink,
132
+ showAlert
133
+ }) => {
134
+ try {
135
+ const verbs = editingRights === 'readOnly' ? READ_ONLY_PERMS : WRITE_PERMS
136
+ return shareByLink(file, { verbs, ttl, password })
137
+ } catch (err) {
138
+ showAlert({
139
+ message: t(`${documentType}.share.shareByLink.permserror`),
140
+ severity: 'error',
141
+ variant: 'filled'
142
+ })
143
+ log.error(
144
+ "Error in 'readOnlyPermissionLink' function when trying to change permission",
145
+ err
146
+ )
147
+ }
148
+ }
149
+
112
150
  /**
113
151
  * updatePermissions - Updates the permissions of a file
114
152
  * @param {object} options
115
153
  * @param {import('cozy-client/types/types').IOCozyFile} options.file File to update permissions
116
154
  * @param {Function} options.t i18n function
155
+ * @param {boolean} options.dateToggle - Expiration date toggle
156
+ * @param {Date|null} options.selectedDate - Expiration date
157
+ * @param {boolean} options.passwordToggle - Password toggle
158
+ * @param {string} options.password - Password
117
159
  * @param {string} options.documentType - Type of the document
118
160
  * @param {'readOnly'|'write'} options.editingRights - Editing rights
119
161
  * @param {Function} options.updateDocumentPermissions - Function to update permissions
@@ -122,42 +164,34 @@ export const forwardFile = async ({
122
164
  export const updatePermissions = async ({
123
165
  file,
124
166
  t,
167
+ dateToggle,
168
+ selectedDate,
169
+ passwordToggle,
170
+ password,
125
171
  editingRights,
126
172
  documentType,
127
173
  updateDocumentPermissions,
128
174
  showAlert
129
175
  }) => {
130
- switch (editingRights) {
131
- case 'readOnly':
132
- try {
133
- return updateDocumentPermissions(file, READ_ONLY_PERMS)
134
- } catch (err) {
135
- showAlert({
136
- message: t(`${documentType}.share.shareByLink.permserror`),
137
- severity: 'error',
138
- variant: 'filled'
139
- })
140
- log.error(
141
- "Error in 'readOnlyPermissionLink' function when trying to change permission",
142
- err
143
- )
144
- }
145
- break
146
- case 'write':
147
- try {
148
- return updateDocumentPermissions(file, WRITE_PERMS)
149
- } catch (err) {
150
- showAlert({
151
- message: t(`${documentType}.share.shareByLink.permserror`),
152
- severity: 'error',
153
- variant: 'filled'
154
- })
155
- log.error(
156
- "Error in 'editPermissionLink' function when trying to change permission",
157
- err
158
- )
159
- }
160
- break
176
+ try {
177
+ const expiresAt = dateToggle ? selectedDate?.toISOString() || undefined : ''
178
+ const ensurePassword = passwordToggle ? password || undefined : ''
179
+ const verbs = editingRights === 'readOnly' ? READ_ONLY_PERMS : WRITE_PERMS
180
+ return updateDocumentPermissions(file, {
181
+ verbs,
182
+ expiresAt,
183
+ password: ensurePassword
184
+ })
185
+ } catch (err) {
186
+ showAlert({
187
+ message: t(`${documentType}.share.shareByLink.permserror`),
188
+ severity: 'error',
189
+ variant: 'filled'
190
+ })
191
+ log.error(
192
+ "Error in 'updateDocumentPermissions' function when trying to change permission",
193
+ err
194
+ )
161
195
  }
162
196
  }
163
197
 
@@ -21,40 +21,121 @@ describe('ShareRestrictionModal/helpers', () => {
21
21
  it('should call updateDocumentPermissions with "readOnly" permission', async () => {
22
22
  const updateDocumentPermissions = jest.fn()
23
23
  const file = { _id: '123' }
24
- const editingRights = 'readOnly'
25
24
 
26
25
  await updatePermissions({
27
26
  file,
28
27
  t: jest.fn(),
29
- editingRights,
28
+ dateToggle: false,
29
+ selectedDate: null,
30
+ passwordToggle: false,
31
+ password: '',
32
+ editingRights: 'readOnly',
30
33
  documentType,
31
34
  updateDocumentPermissions,
32
35
  showAlert: jest.fn()
33
36
  })
34
37
 
35
- expect(updateDocumentPermissions).toHaveBeenCalledWith(file, ['GET'])
38
+ expect(updateDocumentPermissions).toHaveBeenCalledWith(file, {
39
+ expiresAt: '',
40
+ password: '',
41
+ verbs: ['GET']
42
+ })
36
43
  })
37
44
 
38
45
  it('should call updateDocumentPermissions with "write" permissions', async () => {
39
46
  const updateDocumentPermissions = jest.fn()
40
47
  const file = { _id: '123' }
41
- const editingRights = 'write'
42
48
 
43
49
  await updatePermissions({
44
50
  file,
45
51
  t: jest.fn(),
46
- editingRights,
52
+ dateToggle: false,
53
+ selectedDate: null,
54
+ passwordToggle: false,
55
+ password: '',
56
+ editingRights: 'write',
57
+ documentType,
58
+ updateDocumentPermissions,
59
+ showAlert: jest.fn()
60
+ })
61
+
62
+ expect(updateDocumentPermissions).toHaveBeenCalledWith(file, {
63
+ expiresAt: '',
64
+ password: '',
65
+ verbs: ['GET', 'POST', 'PUT', 'PATCH']
66
+ })
67
+ })
68
+
69
+ it('should call updateDocumentPermissions with empty date & password if their switches are false', async () => {
70
+ const updateDocumentPermissions = jest.fn()
71
+ const file = { _id: '123' }
72
+
73
+ await updatePermissions({
74
+ file,
75
+ t: jest.fn(),
76
+ dateToggle: false,
77
+ selectedDate: null,
78
+ passwordToggle: false,
79
+ password: '',
80
+ editingRights: 'readOnly',
81
+ documentType,
82
+ updateDocumentPermissions,
83
+ showAlert: jest.fn()
84
+ })
85
+
86
+ expect(updateDocumentPermissions).toHaveBeenCalledWith(file, {
87
+ expiresAt: '',
88
+ password: '',
89
+ verbs: ['GET']
90
+ })
91
+ })
92
+
93
+ it('should call updateDocumentPermissions with "undefined" date & password if their switches are true but the permission doesn\'t yet have these values', async () => {
94
+ const updateDocumentPermissions = jest.fn()
95
+ const file = { _id: '123' }
96
+
97
+ await updatePermissions({
98
+ file,
99
+ t: jest.fn(),
100
+ dateToggle: true,
101
+ selectedDate: null,
102
+ passwordToggle: true,
103
+ password: '',
104
+ editingRights: 'readOnly',
105
+ documentType,
106
+ updateDocumentPermissions,
107
+ showAlert: jest.fn()
108
+ })
109
+
110
+ expect(updateDocumentPermissions).toHaveBeenCalledWith(file, {
111
+ expiresAt: undefined,
112
+ password: undefined,
113
+ verbs: ['GET']
114
+ })
115
+ })
116
+
117
+ it('should call updateDocumentPermissions with expected date & password if their switches are true', async () => {
118
+ const updateDocumentPermissions = jest.fn()
119
+ const file = { _id: '123' }
120
+
121
+ await updatePermissions({
122
+ file,
123
+ t: jest.fn(),
124
+ dateToggle: true,
125
+ selectedDate: new Date('2100-01-01T00:00:00.000Z'),
126
+ passwordToggle: true,
127
+ password: '1234',
128
+ editingRights: 'readOnly',
47
129
  documentType,
48
130
  updateDocumentPermissions,
49
131
  showAlert: jest.fn()
50
132
  })
51
133
 
52
- expect(updateDocumentPermissions).toHaveBeenCalledWith(file, [
53
- 'GET',
54
- 'POST',
55
- 'PUT',
56
- 'PATCH'
57
- ])
134
+ expect(updateDocumentPermissions).toHaveBeenCalledWith(file, {
135
+ expiresAt: '2100-01-01T00:00:00.000Z',
136
+ password: '1234',
137
+ verbs: ['GET']
138
+ })
58
139
  })
59
140
  })
60
141
 
@@ -49,12 +49,12 @@ const openExternalLink = url => (window.location = url)
49
49
  const SharingBannerCozyToCozy = ({
50
50
  sharing,
51
51
  isSharingShortcutCreated,
52
- discoveryLink,
52
+ addSharingLink,
53
53
  onClose
54
54
  }) => {
55
55
  const { t } = useI18n()
56
56
 
57
- const action = () => openExternalLink(discoveryLink)
57
+ const action = () => openExternalLink(addSharingLink)
58
58
  const buttonOne = isSharingShortcutCreated
59
59
  ? {
60
60
  label: t('Share.banner.sync_to_mine', { smart_count: 2 }),
@@ -139,7 +139,7 @@ const SharingBannerByLink = ({ onClose }) => {
139
139
  SharingBannerCozyToCozy.propTypes = {
140
140
  sharing: PropTypes.object.isRequired,
141
141
  isSharingShortcutCreated: PropTypes.bool.isRequired,
142
- discoveryLink: PropTypes.string.isRequired,
142
+ addToCozySharingLink: PropTypes.string.isRequired,
143
143
  onClose: PropTypes.func.isRequired
144
144
  }
145
145
  export { SharingBannerCozyToCozy, SharingBannerByLink }
@@ -34,7 +34,7 @@ describe('PublicBanner', () => {
34
34
  <SharingBannerCozyToCozy
35
35
  sharing={sharing}
36
36
  isSharingShortcutCreated={true}
37
- discoveryLink="discoveryLink"
37
+ addSharingLink="discoveryLink"
38
38
  onClose={() => {}}
39
39
  />
40
40
  )
@@ -7,19 +7,19 @@ export const SharingBanner = ({ sharingInfos }) => {
7
7
  const [isOpened, setIsOpened] = useState(true)
8
8
  const onClose = useCallback(() => setIsOpened(false), [setIsOpened])
9
9
 
10
- const { loading, discoveryLink, sharing, isSharingShortcutCreated } =
10
+ const { loading, addSharingLink, sharing, isSharingShortcutCreated } =
11
11
  sharingInfos
12
12
 
13
13
  if (loading) return null
14
14
  return (
15
15
  isOpened &&
16
- (!discoveryLink ? (
16
+ (!addSharingLink ? (
17
17
  <SharingBannerByLink onClose={onClose} />
18
18
  ) : (
19
19
  <SharingBannerCozyToCozy
20
20
  isSharingShortcutCreated={isSharingShortcutCreated}
21
21
  sharing={sharing}
22
- discoveryLink={discoveryLink}
22
+ addSharingLink={addSharingLink}
23
23
  onClose={onClose}
24
24
  />
25
25
  ))
@@ -12,10 +12,13 @@ const getSharingId = permission => {
12
12
  return sharingId
13
13
  }
14
14
 
15
+ const CREATE_COZY_LINK = 'https://manager.cozycloud.cc/cozy/create'
16
+
15
17
  export const useSharingInfos = (previewPath = '/preview') => {
16
18
  const client = useClient()
17
19
 
18
- const [discoveryLink, setDiscoveryLink] = useState()
20
+ const [addSharingLink, setAddSharingLink] = useState()
21
+ const [syncSharingLink, setSyncSharingLink] = useState()
19
22
  const [isSharingShortcutCreated, setIsSharingSharingcutCreated] =
20
23
  useState(false)
21
24
  const [sharing, setSharing] = useState()
@@ -35,6 +38,9 @@ export const useSharingInfos = (previewPath = '/preview') => {
35
38
  const { sharecode } = getQueryParameter()
36
39
 
37
40
  const link = client
41
+ .collection('io.cozy.sharings')
42
+ .getDiscoveryLink(sharingId, sharecode, { shortcut: true })
43
+ const linkSync = client
38
44
  .collection('io.cozy.sharings')
39
45
  .getDiscoveryLink(sharingId, sharecode)
40
46
  const sharingsByIdQuery = buildSharingsByIdQuery(sharingId)
@@ -42,7 +48,8 @@ export const useSharingInfos = (previewPath = '/preview') => {
42
48
  sharingsByIdQuery.definition
43
49
  )
44
50
 
45
- setDiscoveryLink(link)
51
+ setAddSharingLink(link)
52
+ setSyncSharingLink(linkSync)
46
53
  setIsSharingSharingcutCreated(isSharingShortcutCreated)
47
54
  setSharing(sharing)
48
55
  } catch (e) {
@@ -62,7 +69,9 @@ export const useSharingInfos = (previewPath = '/preview') => {
62
69
  return {
63
70
  sharing,
64
71
  loading,
65
- discoveryLink,
72
+ addSharingLink,
73
+ syncSharingLink,
74
+ createCozyLink: CREATE_COZY_LINK,
66
75
  isSharingShortcutCreated
67
76
  }
68
77
  }
@@ -81,8 +81,8 @@ describe('useSharingInfos', () => {
81
81
  })
82
82
 
83
83
  it('returns the right infos when using useSharingInfo', async () => {
84
- const discoveryLink = '/link'
85
- getDiscoveryLinkMock.mockReturnValue(discoveryLink)
84
+ const addSharingLink = '/addSharingLink'
85
+ getDiscoveryLinkMock.mockReturnValue(addSharingLink)
86
86
  fetchOwnPermissionsMock.mockResolvedValue(mockedPermissionsWithInstance)
87
87
  queryMock.mockResolvedValue(mockSharing)
88
88
  const { result, waitForNextUpdate } = setup()
@@ -93,12 +93,12 @@ describe('useSharingInfos', () => {
93
93
  expect(result.current.loading).toEqual(false)
94
94
  expect(result.current.isSharingShortcutCreated).toEqual(true)
95
95
  expect(result.current.sharing).toEqual(mockSharing.data)
96
- expect(result.current.discoveryLink).toEqual(discoveryLink)
96
+ expect(result.current.addSharingLink).toEqual(addSharingLink)
97
97
  })
98
98
 
99
- it('returns the right infos when using useSharingInfo without discoveryLink', async () => {
100
- const discoveryLink = false
101
- getDiscoveryLinkMock.mockReturnValue(discoveryLink)
99
+ it('returns the right infos when using useSharingInfo without addSharingLink', async () => {
100
+ const addSharingLink = undefined
101
+ getDiscoveryLinkMock.mockReturnValue(addSharingLink)
102
102
  fetchOwnPermissionsMock.mockResolvedValue(mockedPermissionsWithoutInstance)
103
103
  queryMock.mockResolvedValue(mockSharing)
104
104
  const { result, waitForNextUpdate } = setup()
@@ -109,7 +109,7 @@ describe('useSharingInfos', () => {
109
109
  expect(result.current.loading).toEqual(false)
110
110
  expect(result.current.isSharingShortcutCreated).toEqual(false)
111
111
  expect(result.current.sharing).toEqual(mockSharing.data)
112
- expect(result.current.discoveryLink).toEqual(discoveryLink)
112
+ expect(result.current.addSharingLink).toEqual(addSharingLink)
113
113
  })
114
114
 
115
115
  it('returns loading false if there is nothing to do aka sharing by link', () => {
@@ -14,3 +14,15 @@ export const checkIsReadOnlyPermissions = permissions => {
14
14
  ).length > 0
15
15
  )
16
16
  }
17
+
18
+ export const checkIsPermissionHasExpiresDate = permissions => {
19
+ return Boolean(permissions?.[0]?.attributes?.expires_at)
20
+ }
21
+
22
+ export const getPermissionExpiresDate = permissions => {
23
+ return permissions?.[0]?.attributes?.expires_at
24
+ }
25
+
26
+ export const checkIsPermissionHasPassword = permissions => {
27
+ return Boolean(permissions?.[0]?.attributes?.password)
28
+ }
package/src/index.jsx CHANGED
@@ -33,5 +33,7 @@ export {
33
33
  NativeFileSharingProvider,
34
34
  useNativeFileSharing
35
35
  } from './providers/NativeFileSharingProvider'
36
- export { openSharingLink } from './actions/openSharingLink'
36
+ export { createCozySharingLink } from './actions/createCozySharingLink'
37
+ export { addToCozySharingLink } from './actions/addToCozySharingLink'
38
+ export { syncToCozySharingLink } from './actions/syncToCozySharingLink'
37
39
  export { shareNative } from './actions/shareNative'