Skip to content

Commit

Permalink
Merge pull request #10080 from owncloud/expiration-rules
Browse files Browse the repository at this point in the history
refactor: move link expiration rules to a helper method
  • Loading branch information
JammingBen authored Nov 30, 2023
2 parents d7bf410 + fd86ff1 commit 905e499
Show file tree
Hide file tree
Showing 12 changed files with 115 additions and 58 deletions.
47 changes: 10 additions & 37 deletions packages/web-app-files/src/components/SideBar/Shares/FileLinks.vue
Original file line number Diff line number Diff line change
Expand Up @@ -14,14 +14,14 @@
<name-and-copy v-if="quicklink" :link="quicklink" />
<create-quick-link
v-else-if="canCreateLinks"
:expiration-date="expirationDate"
:expiration-rules="expirationRules"
@create-public-link="checkLinkToCreate"
/>
<details-and-edit
v-if="quicklink"
:available-role-options="getAvailableRoleOptions(quicklink)"
:can-rename="false"
:expiration-date="expirationDate"
:expiration-rules="expirationRules"
:is-folder-share="resource.isFolder"
:is-modifiable="canEditLink(quicklink)"
:is-password-enforced="isPasswordEnforcedFor(quicklink)"
Expand Down Expand Up @@ -54,7 +54,7 @@
<details-and-edit
:available-role-options="getAvailableRoleOptions(link)"
:can-rename="true"
:expiration-date="expirationDate"
:expiration-rules="expirationRules"
:is-folder-share="resource.isFolder"
:is-modifiable="canEditLink(link)"
:is-password-enforced="isPasswordEnforcedFor(link)"
Expand Down Expand Up @@ -89,7 +89,7 @@
<name-and-copy :link="link" />
<details-and-edit
:available-role-options="getAvailableRoleOptions(link)"
:expiration-date="expirationDate"
:expiration-rules="expirationRules"
:is-folder-share="true"
:is-modifiable="false"
:link="link"
Expand Down Expand Up @@ -124,7 +124,8 @@ import {
useCapabilityFilesSharingPublicPasswordEnforcedFor,
useAbility,
usePasswordPolicyService,
getDefaultLinkPermissions
getDefaultLinkPermissions,
useExpirationRules
} from '@ownclouders/web-pkg'
import { shareViaLinkHelp, shareViaIndirectLinkHelp } from '../../../helpers/contextualHelpers'
import {
Expand Down Expand Up @@ -162,6 +163,7 @@ export default defineComponent({
const store = useStore()
const ability = useAbility()
const { can } = ability
const { expirationRules } = useExpirationRules()
const passwordPolicyService = usePasswordPolicyService()
const hasResharing = useCapabilityFilesSharingResharing()
Expand Down Expand Up @@ -241,7 +243,8 @@ export default defineComponent({
configurationManager,
passwordPolicyService,
canCreateLinks,
canEditLink
canEditLink,
expirationRules
}
},
computed: {
Expand All @@ -264,36 +267,6 @@ export default defineComponent({
return this.outgoingLinks.find((link) => link.quicklink === true && !link.indirect)
},
expirationDate() {
const expireDate = this.capabilities.files_sharing.public.expire_date
let defaultExpireDate = null
let maxExpireDateFromCaps = null
if (expireDate.days) {
const days = parseInt(expireDate.days)
defaultExpireDate = DateTime.now()
.setLocale(getLocaleFromLanguage(this.$language.current))
.plus({ days })
.toJSDate()
}
if (expireDate.enforced) {
const days = parseInt(expireDate.days)
maxExpireDateFromCaps = DateTime.now()
.setLocale(getLocaleFromLanguage(this.$language.current))
.plus({ days })
.toJSDate()
}
return {
enforced: expireDate.enforced,
default: defaultExpireDate,
min: DateTime.now().setLocale(getLocaleFromLanguage(this.$language.current)).toJSDate(),
max: maxExpireDateFromCaps
}
},
helpersEnabled() {
return this.configuration?.options?.contextHelpers
},
Expand Down Expand Up @@ -415,7 +388,7 @@ export default defineComponent({
ability: this.ability,
store: this.$store
}).toString(),
expiration: this.expirationDate.default,
expiration: this.expirationRules.default,
password: false
}
})
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -26,16 +26,20 @@
</template>

<script lang="ts">
import { defineComponent } from 'vue'
import { useAbility, getDefaultLinkPermissions, useStore } from '@ownclouders/web-pkg'
import { defineComponent, PropType } from 'vue'
import {
useAbility,
getDefaultLinkPermissions,
useStore,
ExpirationRules
} from '@ownclouders/web-pkg'
import { useGettext } from 'vue3-gettext'
export default defineComponent({
name: 'CreateQuickLink',
props: {
expirationDate: {
type: Object,
default: () => {},
expirationRules: {
type: Object as PropType<ExpirationRules>,
required: true
}
},
Expand All @@ -50,7 +54,7 @@ export default defineComponent({
link: {
name: $gettext('Link'),
permissions: getDefaultLinkPermissions({ ability, store }).toString(),
expiration: props.expirationDate.enforced ? props.expirationDate.default : null,
expiration: props.expirationRules.enforced ? props.expirationRules.default : null,
quicklink: true,
password: false
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -85,10 +85,10 @@
v-if="option.showDatepicker"
v-model="newExpiration"
class="link-expiry-picker oc-flex oc-width-1-1"
:min-date="expirationDate.min"
:max-date="expirationDate.max"
:min-date="expirationRules.min"
:max-date="expirationRules.max"
:locale="$language.current"
:is-required="expirationDate.enforce"
:is-required="expirationRules.enforced"
>
<template #default="{ togglePopover }">
<oc-button
Expand Down Expand Up @@ -168,7 +168,7 @@ import { formatDateFromDateTime, formatRelativeDateFromDateTime } from '@ownclou
import { Resource, SpaceResource } from '@ownclouders/web-client/src/helpers'
import { createFileRouteOptions } from '@ownclouders/web-pkg'
import { OcDrop } from 'design-system/src/components'
import { usePasswordPolicyService } from '@ownclouders/web-pkg'
import { usePasswordPolicyService, ExpirationRules } from '@ownclouders/web-pkg'
import { useGettext } from 'vue3-gettext'
export default defineComponent({
Expand All @@ -183,9 +183,8 @@ export default defineComponent({
type: Boolean,
default: false
},
expirationDate: {
type: Object,
default: () => ({}),
expirationRules: {
type: Object as PropType<ExpirationRules>,
required: true
},
isFolderShare: {
Expand Down Expand Up @@ -290,7 +289,7 @@ export default defineComponent({
id: 'remove-expiration',
title: this.$gettext('Remove expiration date'),
icon: 'close',
isRemovable: !this.expirationDate.enforced,
isRemovable: !this.expirationRules.enforced,
method: () =>
this.updateLink({
link: {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -77,7 +77,7 @@ function getShallowMountedWrapper(link, expireDateEnforced = false, isModifiable
props: {
availableRoleOptions,
canRename: true,
expirationDate: {
expirationRules: {
enforced: expireDateEnforced,
default: null,
min: 'Wed Apr 01 2020 00:00:00 GMT+0000 (Coordinated Universal Time)',
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -24,7 +24,7 @@ exports[`DetailsAndEdit component if user can edit renders dropdown and edit but
</oc-button-stub>
</li>
<li class="oc-rounded oc-menu-item-hover">
<date-picker-stub class="oc-datepicker link-expiry-picker oc-flex oc-width-1-1 link-expiry-picker oc-flex oc-width-1-1" inputdebounce="1000" is24hr="false" isrange="false" locale="en" min-date="Wed Apr 01 2020 00:00:00 GMT+0000 (Coordinated Universal Time)" mode="date" modelconfig="[object Object]" popover="[object Object]" updateoninput="true">
<date-picker-stub class="oc-datepicker link-expiry-picker oc-flex oc-width-1-1 link-expiry-picker oc-flex oc-width-1-1" inputdebounce="1000" is24hr="false" isrange="false" isrequired="false" locale="en" min-date="Wed Apr 01 2020 00:00:00 GMT+0000 (Coordinated Universal Time)" mode="date" modelconfig="[object Object]" popover="[object Object]" updateoninput="true">
<!-- @slot Default slot to use as the popover anchor for datepicker -->
<!-- args is undefined during initial render, hence we check it here -->
<!--v-if-->
Expand Down
10 changes: 7 additions & 3 deletions packages/web-client/src/ocs/capabilities.ts
Original file line number Diff line number Diff line change
Expand Up @@ -26,6 +26,12 @@ export interface PasswordEnforcedForCapability {
read_write_delete?: boolean
}

export interface PublicExpirationCapability {
days?: string
enabled?: boolean
enforced?: boolean
}

export interface LastModifiedFilterCapability {
keywords?: string[]
enabled?: boolean
Expand Down Expand Up @@ -101,9 +107,7 @@ export interface Capabilities {
alias?: boolean
can_edit: boolean
enabled: boolean
expire_date: {
enabled: boolean
}
expire_date: PublicExpirationCapability
multiple: boolean
password: {
enforced: boolean
Expand Down
1 change: 1 addition & 0 deletions packages/web-pkg/src/composables/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,7 @@ export * from './fileListHeaderPosition'
export * from './filesList'
export * from './folderLink'
export * from './keyboardActions'
export * from './links'
export * from './loadingService'
export * from './localStorage'
export * from './pagination'
Expand Down
1 change: 1 addition & 0 deletions packages/web-pkg/src/composables/links/index.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
export * from './useExpirationRules'
13 changes: 13 additions & 0 deletions packages/web-pkg/src/composables/links/useExpirationRules.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
import { computed } from 'vue'
import { getExpirationRules } from '../../helpers'
import { useStore } from '../store'
import { useGettext } from 'vue3-gettext'

export const useExpirationRules = () => {
const store = useStore()
const { current: currentLanguage } = useGettext()

const expirationRules = computed(() => getExpirationRules({ store, currentLanguage }))

return { expirationRules }
}
41 changes: 41 additions & 0 deletions packages/web-pkg/src/helpers/share/link.ts
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,8 @@ import { Resource } from '@ownclouders/web-client'
import { Language } from 'vue3-gettext'
import { unref } from 'vue'
import { showQuickLinkPasswordModal } from '../../quickActions'
import { getLocaleFromLanguage } from '../locale'
import { PublicExpirationCapability } from '@ownclouders/web-client/src/ocs/capabilities'

export interface CreateQuicklink {
clientService: ClientService
Expand Down Expand Up @@ -181,3 +183,42 @@ export const getDefaultLinkPermissions = ({

return defaultPermissions
}

export type ExpirationRules = { enforced: boolean; default: DateTime; min: DateTime; max: DateTime }

export const getExpirationRules = ({
store,
currentLanguage
}: {
store: Store<any>
currentLanguage: string
}): ExpirationRules => {
const expireDate: PublicExpirationCapability =
store.getters.capabilities.files_sharing.public.expire_date

let defaultExpireDate: DateTime = null
let maxExpireDateFromCaps: DateTime = null

if (expireDate.days) {
const days = parseInt(expireDate.days)
defaultExpireDate = DateTime.now()
.setLocale(getLocaleFromLanguage(currentLanguage))
.plus({ days })
.toJSDate()
}

if (expireDate.enforced) {
const days = parseInt(expireDate.days)
maxExpireDateFromCaps = DateTime.now()
.setLocale(getLocaleFromLanguage(currentLanguage))
.plus({ days })
.toJSDate()
}

return {
enforced: expireDate.enforced,
default: defaultExpireDate,
min: DateTime.now().setLocale(getLocaleFromLanguage(currentLanguage)).toJSDate(),
max: maxExpireDateFromCaps
}
}
23 changes: 22 additions & 1 deletion packages/web-pkg/tests/unit/helpers/share/link.spec.ts
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,8 @@ import {
copyQuicklink,
createQuicklink,
CreateQuicklink,
getDefaultLinkPermissions
getDefaultLinkPermissions,
getExpirationRules
} from '../../../../src/helpers/share'
import { DateTime } from 'luxon'
import { Store } from 'vuex'
Expand All @@ -13,6 +14,7 @@ import { mock, mockDeep } from 'jest-mock-extended'
import { Language } from 'vue3-gettext'
import { Resource } from '@ownclouders/web-client'
import { SharePermissionBit } from '@ownclouders/web-client/src/helpers'
import { PublicExpirationCapability } from '@ownclouders/web-client/src/ocs/capabilities'

jest.mock('@vueuse/core', () => ({
useClipboard: jest.fn().mockReturnValue({ copy: jest.fn() })
Expand Down Expand Up @@ -186,3 +188,22 @@ describe('getDefaultLinkPermissions', () => {
}
)
})

describe('getExpirationRules', () => {
it('correctly computes rules based on the "expire_date"-capability', () => {
jest.useFakeTimers().setSystemTime(new Date('2000-01-01'))

const capabilities = mock<PublicExpirationCapability>({ enforced: true, days: '10' })
const rules = getExpirationRules({
currentLanguage: 'de',
store: {
getters: { capabilities: { files_sharing: { public: { expire_date: capabilities } } } }
} as Store<any>
})

expect(rules.enforced).toEqual(capabilities.enforced)
expect(rules.default).toEqual(new Date('2000-01-11'))
expect(rules.min).toEqual(new Date('2000-01-01'))
expect(rules.max).toEqual(new Date('2000-01-11'))
})
})
2 changes: 1 addition & 1 deletion packages/web-runtime/src/App.vue
Original file line number Diff line number Diff line change
Expand Up @@ -46,9 +46,9 @@
<template v-if="modal.customContent || modal.customComponent" #content>
<div v-if="modal.customContent" v-html="modal.customContent" />
<component
ref="modalComponent"
:is="modal.customComponent"
v-else
ref="modalComponent"
:modal="modal"
v-bind="modal.customComponentAttrs"
/>
Expand Down

0 comments on commit 905e499

Please sign in to comment.