Skip to content

Commit bb251ed

Browse files
committed
feat: default expiration dates
- folders expiration date defined in capability store - if the expiration is set for more than the maximum defined, is updated - removes the option to unset expiration dates for RW folders
1 parent 879d1f2 commit bb251ed

File tree

5 files changed

+94
-15
lines changed

5 files changed

+94
-15
lines changed

packages/web-app-files/src/components/SideBar/Shares/FileLinks.vue

Lines changed: 28 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -92,7 +92,8 @@ import {
9292
useResourcesStore,
9393
useLinkTypes,
9494
useCanShare,
95-
UpdateLinkOptions
95+
UpdateLinkOptions,
96+
useCapabilityStore
9697
} from '@ownclouders/web-pkg'
9798
import { shareViaLinkHelp, shareViaIndirectLinkHelp } from '../../../helpers/contextualHelpers'
9899
import { isSpaceResource, LinkShare } from '@ownclouders/web-client'
@@ -102,11 +103,14 @@ import { isLocationSharesActive, useSharesStore } from '@ownclouders/web-pkg'
102103
import { useGettext } from 'vue3-gettext'
103104
import { storeToRefs } from 'pinia'
104105
import { SharingLinkType } from '@ownclouders/web-client/graph/generated'
106+
import { DateTime, Duration } from 'luxon'
105107
106108
export default defineComponent({
107109
name: 'FileLinks',
108110
components: { ListItem },
109111
setup() {
112+
const { sharingPublicExpireDateDefaultRWFolders, sharingPublicExpireDateMaxRWFolders } =
113+
useCapabilityStore()
110114
const { showMessage, showErrorMessage } = useMessages()
111115
const { $gettext } = useGettext()
112116
const ability = useAbility()
@@ -192,6 +196,29 @@ export default defineComponent({
192196
options: UpdateLinkOptions['options']
193197
}) => {
194198
try {
199+
if (unref(resource).isFolder && options.type === 'edit' && !linkShare.expirationDateTime) {
200+
Object.assign(options, {
201+
...options,
202+
expirationDateTime: DateTime.now()
203+
.plus(sharingPublicExpireDateDefaultRWFolders)
204+
.endOf('day')
205+
.toISO()
206+
})
207+
}
208+
if (unref(resource).isFolder && linkShare.expirationDateTime) {
209+
if (
210+
DateTime.fromISO(linkShare.expirationDateTime).diff(DateTime.now(), 'days').as('days') >
211+
Duration.fromObject(sharingPublicExpireDateMaxRWFolders).as('days')
212+
) {
213+
Object.assign(options, {
214+
...options,
215+
expirationDateTime: DateTime.now()
216+
.plus(sharingPublicExpireDateDefaultRWFolders)
217+
.endOf('day')
218+
.toISO()
219+
})
220+
}
221+
}
195222
await updateLink({
196223
clientService,
197224
space: unref(space),

packages/web-app-files/src/components/SideBar/Shares/Links/EditDropdown.vue

Lines changed: 22 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -46,6 +46,7 @@
4646
import { DateTime } from 'luxon'
4747
import {
4848
createLocationSpaces,
49+
useCapabilityStore,
4950
useGetMatchingSpace,
5051
useModals,
5152
useResourcesStore
@@ -97,6 +98,7 @@ export default defineComponent({
9798
const { $gettext } = useGettext()
9899
const { getMatchingSpace } = useGetMatchingSpace()
99100
const resourcesStore = useResourcesStore()
101+
const { sharingPublicExpireDateMaxRWFolders } = useCapabilityStore()
100102
const editPublicLinkDropdown = useTemplateRef<typeof OcDrop>('editPublicLinkDropdown')
101103
102104
const resource = inject<Ref<Resource>>('resource')
@@ -110,7 +112,11 @@ export default defineComponent({
110112
customComponent: DatePickerModal,
111113
customComponentAttrs: () => ({
112114
currentDate: currentDate.isValid ? currentDate : null,
113-
minDate: DateTime.now()
115+
minDate: DateTime.now(),
116+
maxDate:
117+
resource.value.isFolder && props.linkShare.type === SharingLinkType.Edit
118+
? DateTime.now().plus(sharingPublicExpireDateMaxRWFolders).endOf('day')
119+
: null
114120
}),
115121
onConfirm: (expirationDateTime: DateTime) => {
116122
emit('updateLink', {
@@ -214,18 +220,21 @@ export default defineComponent({
214220
method: showDatePickerModal
215221
})
216222
217-
result.push({
218-
id: 'remove-expiration',
219-
title: $gettext('Remove expiration date'),
220-
icon: 'calendar-close',
221-
method: () => {
222-
emit('updateLink', {
223-
linkShare: { ...props.linkShare },
224-
options: { expirationDateTime: null }
225-
})
226-
unref(editPublicLinkDropdown).hide()
227-
}
228-
})
223+
// only if is not a edit folder link
224+
if (!(props.linkShare.type === SharingLinkType.Edit && resource.value.isFolder)) {
225+
result.push({
226+
id: 'remove-expiration',
227+
title: $gettext('Remove expiration date'),
228+
icon: 'calendar-close',
229+
method: () => {
230+
emit('updateLink', {
231+
linkShare: { ...props.linkShare },
232+
options: { expirationDateTime: null }
233+
})
234+
unref(editPublicLinkDropdown).hide()
235+
}
236+
})
237+
}
229238
} else if (!unref(isInternalLink)) {
230239
result.push({
231240
id: 'add-expiration',

packages/web-client/src/ocs/capabilities.ts

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -145,6 +145,19 @@ export interface Capabilities {
145145
send_mail?: boolean
146146
supports_upload_only?: boolean
147147
upload?: boolean
148+
expire_date?: {
149+
enabled?: boolean
150+
default_rw_folders?: {
151+
years?: number
152+
months?: number
153+
days?: number
154+
}
155+
max_rw_folders?: {
156+
years?: number
157+
months?: number
158+
days?: number
159+
}
160+
}
148161
}
149162
search_min_length?: number
150163
user?: {

packages/web-pkg/src/components/CreateLinkModal.vue

Lines changed: 17 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -48,6 +48,11 @@
4848
v-if="isAdvancedMode"
4949
class="oc-mt-s"
5050
:min-date="DateTime.now()"
51+
:max-date="
52+
isFolder && selectedType === 'edit'
53+
? DateTime.now().plus(sharingPublicExpireDateMaxRWFolders).endOf('day')
54+
: null
55+
"
5156
:label="$gettext('Expiry date')"
5257
@date-changed="onExpiryDateChanged"
5358
/>
@@ -125,7 +130,8 @@ import {
125130
useLinkTypes,
126131
Modal,
127132
useSharesStore,
128-
useClientService
133+
useClientService,
134+
useCapabilityStore
129135
} from '../composables'
130136
import { LinkShare, SpaceResource } from '@ownclouders/web-client'
131137
import { Resource } from '@ownclouders/web-client'
@@ -169,6 +175,7 @@ export default defineComponent({
169175
const { addLink } = useSharesStore()
170176
const isAdvancedMode = ref(false)
171177
const isInvalidExpiryDate = ref(false)
178+
const { sharingPublicExpireDateMaxRWFolders } = useCapabilityStore()
172179
173180
const isFolder = computed(() => props.resources.every(({ isFolder }) => isFolder))
174181
@@ -297,6 +304,14 @@ export default defineComponent({
297304
298305
const updateSelectedLinkType = (type: SharingLinkType) => {
299306
selectedType.value = type
307+
onExpiryDateChanged({
308+
date: unref(selectedExpiry),
309+
error:
310+
unref(selectedExpiry)?.toISO() >
311+
DateTime.now().plus(sharingPublicExpireDateMaxRWFolders).endOf('day').toISO() &&
312+
isFolder &&
313+
unref(selectedType) === 'edit'
314+
})
300315
}
301316
302317
onMounted(() => {
@@ -333,6 +348,7 @@ export default defineComponent({
333348
onExpiryDateChanged,
334349
confirmButtonDisabled,
335350
DateTime,
351+
sharingPublicExpireDateMaxRWFolders,
336352
337353
// unit tests
338354
onConfirm

packages/web-pkg/src/composables/piniaStores/capabilities.ts

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -35,6 +35,11 @@ const defaultValues = {
3535
enabled: true,
3636
password: {
3737
enforced_for: { read_only: false, upload_only: false, read_write: false }
38+
},
39+
expire_date: {
40+
enabled: true,
41+
default_rw_folders: null,
42+
max_rw_folders: null
3843
}
3944
}
4045
},
@@ -118,6 +123,13 @@ export const useCapabilityStore = defineStore('capabilities', () => {
118123
const sharingPublicPasswordEnforcedFor = computed(
119124
() => unref(capabilities).files_sharing.public?.password.enforced_for
120125
)
126+
const sharingPublicExpireDateDefaultRWFolders = computed(
127+
() => unref(capabilities).files_sharing.public?.expire_date.default_rw_folders
128+
)
129+
const sharingPublicExpireDateMaxRWFolders = computed(
130+
() => unref(capabilities).files_sharing.public?.expire_date.max_rw_folders
131+
)
132+
121133
const sharingSearchMinLength = computed(() => unref(capabilities).files_sharing.search_min_length)
122134
const sharingUserProfilePicture = computed(
123135
() => unref(capabilities).files_sharing.user?.profile_picture
@@ -175,6 +187,8 @@ export const useCapabilityStore = defineStore('capabilities', () => {
175187
sharingPublicAlias,
176188
sharingPublicDefaultPermissions,
177189
sharingPublicPasswordEnforcedFor,
190+
sharingPublicExpireDateDefaultRWFolders,
191+
sharingPublicExpireDateMaxRWFolders,
178192
sharingSearchMinLength,
179193
sharingUserProfilePicture,
180194
tusMaxChunkSize,

0 commit comments

Comments
 (0)