mirror of
https://github.com/nextcloud/server.git
synced 2026-05-17 02:49:55 -04:00
Merge pull request #50693 from nextcloud/backport/50655/stable29
[stable29] enh: Fix display default expire date, add tests & tiny refactors
This commit is contained in:
commit
3fbbcdf011
13 changed files with 70 additions and 47 deletions
|
|
@ -307,7 +307,7 @@ class ShareAPIController extends OCSController {
|
|||
/** @var array{share_with_displayname: string, share_with_link: string, share_with?: string, token?: string} $roomShare */
|
||||
$roomShare = $this->getRoomShareHelper()->formatShare($share);
|
||||
$result = array_merge($result, $roomShare);
|
||||
} catch (QueryException $e) {
|
||||
} catch (ContainerExceptionInterface $e) {
|
||||
}
|
||||
} elseif ($share->getShareType() === IShare::TYPE_DECK) {
|
||||
$result['share_with'] = $share->getSharedWith();
|
||||
|
|
@ -317,7 +317,7 @@ class ShareAPIController extends OCSController {
|
|||
/** @var array{share_with: string, share_with_displayname: string, share_with_link: string} $deckShare */
|
||||
$deckShare = $this->getDeckShareHelper()->formatShare($share);
|
||||
$result = array_merge($result, $deckShare);
|
||||
} catch (QueryException $e) {
|
||||
} catch (ContainerExceptionInterface $e) {
|
||||
}
|
||||
} elseif ($share->getShareType() === IShare::TYPE_SCIENCEMESH) {
|
||||
$result['share_with'] = $share->getSharedWith();
|
||||
|
|
@ -327,7 +327,7 @@ class ShareAPIController extends OCSController {
|
|||
/** @var array{share_with: string, share_with_displayname: string, token: string} $scienceMeshShare */
|
||||
$scienceMeshShare = $this->getSciencemeshShareHelper()->formatShare($share);
|
||||
$result = array_merge($result, $scienceMeshShare);
|
||||
} catch (QueryException $e) {
|
||||
} catch (ContainerExceptionInterface $e) {
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -663,7 +663,9 @@ class ShareAPIController extends OCSController {
|
|||
$share = $this->setShareAttributes($share, $attributes);
|
||||
}
|
||||
|
||||
//Expire date
|
||||
// Expire date checks
|
||||
// Normally, null means no expiration date but we still set the default for backwards compatibility
|
||||
// If the client sends an empty string, we set noExpirationDate to true
|
||||
if ($expireDate !== null) {
|
||||
if ($expireDate !== '') {
|
||||
try {
|
||||
|
|
@ -756,7 +758,7 @@ class ShareAPIController extends OCSController {
|
|||
$share->setSharedWith($shareWith);
|
||||
$share->setPermissions($permissions);
|
||||
} elseif ($shareType === IShare::TYPE_CIRCLE) {
|
||||
if (!\OC::$server->getAppManager()->isEnabledForUser('circles') || !class_exists('\OCA\Circles\ShareByCircleProvider')) {
|
||||
if (!\OCP\Server::get(IAppManager::class)->isEnabledForUser('circles') || !class_exists('\OCA\Circles\ShareByCircleProvider')) {
|
||||
throw new OCSNotFoundException($this->l->t('You cannot share to a Team if the app is not enabled'));
|
||||
}
|
||||
|
||||
|
|
@ -771,19 +773,19 @@ class ShareAPIController extends OCSController {
|
|||
} elseif ($shareType === IShare::TYPE_ROOM) {
|
||||
try {
|
||||
$this->getRoomShareHelper()->createShare($share, $shareWith, $permissions, $expireDate ?? '');
|
||||
} catch (QueryException $e) {
|
||||
} catch (ContainerExceptionInterface $e) {
|
||||
throw new OCSForbiddenException($this->l->t('Sharing %s failed because the back end does not support room shares', [$node->getPath()]));
|
||||
}
|
||||
} elseif ($shareType === IShare::TYPE_DECK) {
|
||||
try {
|
||||
$this->getDeckShareHelper()->createShare($share, $shareWith, $permissions, $expireDate ?? '');
|
||||
} catch (QueryException $e) {
|
||||
} catch (ContainerExceptionInterface $e) {
|
||||
throw new OCSForbiddenException($this->l->t('Sharing %s failed because the back end does not support room shares', [$node->getPath()]));
|
||||
}
|
||||
} elseif ($shareType === IShare::TYPE_SCIENCEMESH) {
|
||||
try {
|
||||
$this->getSciencemeshShareHelper()->createShare($share, $shareWith, $permissions, $expireDate ?? '');
|
||||
} catch (QueryException $e) {
|
||||
} catch (ContainerExceptionInterface $e) {
|
||||
throw new OCSForbiddenException($this->l->t('Sharing %s failed because the back end does not support ScienceMesh shares', [$node->getPath()]));
|
||||
}
|
||||
} else {
|
||||
|
|
@ -1770,10 +1772,10 @@ class ShareAPIController extends OCSController {
|
|||
* Returns the helper of ShareAPIController for room shares.
|
||||
*
|
||||
* If the Talk application is not enabled or the helper is not available
|
||||
* a QueryException is thrown instead.
|
||||
* a ContainerExceptionInterface is thrown instead.
|
||||
*
|
||||
* @return \OCA\Talk\Share\Helper\ShareAPIController
|
||||
* @throws QueryException
|
||||
* @throws ContainerExceptionInterface
|
||||
*/
|
||||
private function getRoomShareHelper() {
|
||||
if (!$this->appManager->isEnabledForUser('spreed')) {
|
||||
|
|
@ -1787,10 +1789,10 @@ class ShareAPIController extends OCSController {
|
|||
* Returns the helper of ShareAPIHelper for deck shares.
|
||||
*
|
||||
* If the Deck application is not enabled or the helper is not available
|
||||
* a QueryException is thrown instead.
|
||||
* a ContainerExceptionInterface is thrown instead.
|
||||
*
|
||||
* @return \OCA\Deck\Sharing\ShareAPIHelper
|
||||
* @throws QueryException
|
||||
* @throws ContainerExceptionInterface
|
||||
*/
|
||||
private function getDeckShareHelper() {
|
||||
if (!$this->appManager->isEnabledForUser('deck')) {
|
||||
|
|
@ -1804,10 +1806,10 @@ class ShareAPIController extends OCSController {
|
|||
* Returns the helper of ShareAPIHelper for sciencemesh shares.
|
||||
*
|
||||
* If the sciencemesh application is not enabled or the helper is not available
|
||||
* a QueryException is thrown instead.
|
||||
* a ContainerExceptionInterface is thrown instead.
|
||||
*
|
||||
* @return \OCA\Deck\Sharing\ShareAPIHelper
|
||||
* @throws QueryException
|
||||
* @throws ContainerExceptionInterface
|
||||
*/
|
||||
private function getSciencemeshShareHelper() {
|
||||
if (!$this->appManager->isEnabledForUser('sciencemesh')) {
|
||||
|
|
@ -1940,7 +1942,7 @@ class ShareAPIController extends OCSController {
|
|||
return true;
|
||||
}
|
||||
|
||||
if ($share->getShareType() === IShare::TYPE_CIRCLE && \OC::$server->getAppManager()->isEnabledForUser('circles')
|
||||
if ($share->getShareType() === IShare::TYPE_CIRCLE && \OCP\Server::get(IAppManager::class)->isEnabledForUser('circles')
|
||||
&& class_exists('\OCA\Circles\Api\v1\Circles')) {
|
||||
$hasCircleId = (str_ends_with($share->getSharedWith(), ']'));
|
||||
$shareWithStart = ($hasCircleId ? strrpos($share->getSharedWith(), '[') + 1 : 0);
|
||||
|
|
@ -1956,7 +1958,7 @@ class ShareAPIController extends OCSController {
|
|||
return true;
|
||||
}
|
||||
return false;
|
||||
} catch (QueryException $e) {
|
||||
} catch (ContainerExceptionInterface $e) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -102,12 +102,13 @@
|
|||
:checked.sync="defaultExpirationDateEnabled"
|
||||
:disabled="pendingEnforcedExpirationDate || saving"
|
||||
class="share-link-expiration-date-checkbox"
|
||||
@change="onDefaultExpirationDateEnabledChange">
|
||||
@change="onExpirationDateToggleChange">
|
||||
{{ config.isDefaultExpireDateEnforced ? t('files_sharing', 'Enable link expiration (enforced)') : t('files_sharing', 'Enable link expiration') }}
|
||||
</NcActionCheckbox>
|
||||
|
||||
<!-- expiration date -->
|
||||
<NcActionInput v-if="(pendingDefaultExpirationDate || pendingEnforcedExpirationDate) && defaultExpirationDateEnabled"
|
||||
data-cy-files-sharing-expiration-date-input
|
||||
class="share-link-expire-date"
|
||||
:label="pendingEnforcedExpirationDate ? t('files_sharing', 'Enter expiration date (enforced)') : t('files_sharing', 'Enter expiration date')"
|
||||
:disabled="saving"
|
||||
|
|
@ -117,7 +118,7 @@
|
|||
type="date"
|
||||
:min="dateTomorrow"
|
||||
:max="maxExpirationDateEnforced"
|
||||
@input="onExpirationChange /* let's not submit when picked, the user might want to still edit or copy the password */">
|
||||
@change="expirationDateChanged($event)">
|
||||
<template #icon>
|
||||
<IconCalendarBlank :size="20" />
|
||||
</template>
|
||||
|
|
@ -592,6 +593,9 @@ export default {
|
|||
},
|
||||
mounted() {
|
||||
this.defaultExpirationDateEnabled = this.config.defaultExpirationDate instanceof Date
|
||||
if (this.share && this.isNewShare) {
|
||||
this.share.expireDate = this.defaultExpirationDateEnabled ? this.formatDateToString(this.config.defaultExpirationDate) : ''
|
||||
}
|
||||
},
|
||||
|
||||
methods: {
|
||||
|
|
@ -710,7 +714,7 @@ export default {
|
|||
path,
|
||||
shareType: ShareTypes.SHARE_TYPE_LINK,
|
||||
password: share.password,
|
||||
expireDate: share.expireDate,
|
||||
expireDate: share.expireDate ?? '',
|
||||
attributes: JSON.stringify(this.fileInfo.shareAttributes),
|
||||
// we do not allow setting the publicUpload
|
||||
// before the share creation.
|
||||
|
|
@ -866,9 +870,14 @@ export default {
|
|||
this.onPasswordSubmit()
|
||||
this.onNoteSubmit()
|
||||
},
|
||||
onDefaultExpirationDateEnabledChange(enabled) {
|
||||
onExpirationDateToggleChange(enabled) {
|
||||
this.share.expireDate = enabled ? this.formatDateToString(this.config.defaultExpirationDate) : ''
|
||||
},
|
||||
expirationDateChanged(event) {
|
||||
const date = event.target.value
|
||||
this.onExpirationChange(date)
|
||||
this.defaultExpirationDateEnabled = !!date
|
||||
},
|
||||
|
||||
/**
|
||||
* Cancel the share creation
|
||||
|
|
|
|||
|
|
@ -24,6 +24,7 @@
|
|||
</template>
|
||||
|
||||
<script>
|
||||
import { subscribe, unsubscribe } from '@nextcloud/event-bus'
|
||||
import DropdownIcon from 'vue-material-design-icons/TriangleSmallDown.vue'
|
||||
import SharesMixin from '../mixins/SharesMixin.js'
|
||||
import ShareDetails from '../mixins/ShareDetails.js'
|
||||
|
|
@ -141,7 +142,17 @@ export default {
|
|||
created() {
|
||||
this.selectedOption = this.preSelectedOption
|
||||
},
|
||||
|
||||
mounted() {
|
||||
subscribe('update:share', (share) => {
|
||||
if (share.id === this.share.id) {
|
||||
this.share.permissions = share.permissions
|
||||
this.selectedOption = this.preSelectedOption
|
||||
}
|
||||
})
|
||||
},
|
||||
unmounted() {
|
||||
unsubscribe('update:share')
|
||||
},
|
||||
methods: {
|
||||
selectOption(optionLabel) {
|
||||
this.selectedOption = optionLabel
|
||||
|
|
|
|||
|
|
@ -131,6 +131,9 @@ export default {
|
|||
monthFormat: 'MMM',
|
||||
}
|
||||
},
|
||||
isNewShare() {
|
||||
return !this.share.id
|
||||
},
|
||||
isFolder() {
|
||||
return this.fileInfo.type === 'dir'
|
||||
},
|
||||
|
|
@ -231,17 +234,8 @@ export default {
|
|||
* @param {Date} date
|
||||
*/
|
||||
onExpirationChange(date) {
|
||||
this.share.expireDate = this.formatDateToString(new Date(date))
|
||||
},
|
||||
|
||||
/**
|
||||
* Uncheck expire date
|
||||
* We need this method because @update:checked
|
||||
* is ran simultaneously as @uncheck, so
|
||||
* so we cannot ensure data is up-to-date
|
||||
*/
|
||||
onExpirationDisable() {
|
||||
this.share.expireDate = ''
|
||||
const formattedDate = date ? this.formatDateToString(new Date(date)) : ''
|
||||
this.share.expireDate = formattedDate
|
||||
},
|
||||
|
||||
/**
|
||||
|
|
|
|||
|
|
@ -521,9 +521,6 @@ export default {
|
|||
isGroupShare() {
|
||||
return this.share.type === this.SHARE_TYPES.SHARE_TYPE_GROUP
|
||||
},
|
||||
isNewShare() {
|
||||
return !this.share.id
|
||||
},
|
||||
allowsFileDrop() {
|
||||
if (this.isFolder && this.config.isPublicUploadEnabled) {
|
||||
if (this.share.type === this.SHARE_TYPES.SHARE_TYPE_LINK || this.share.type === this.SHARE_TYPES.SHARE_TYPE_EMAIL) {
|
||||
|
|
@ -909,6 +906,7 @@ export default {
|
|||
this.$emit('add:share', this.share)
|
||||
} else {
|
||||
this.$emit('update:share', this.share)
|
||||
emit('update:share', this.share)
|
||||
this.queueUpdate(...permissionsAndAttributes)
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -51,9 +51,9 @@ export function setupData(user: User, shareName: string): void {
|
|||
*/
|
||||
function checkPasswordState(enforced: boolean, alwaysAskForPassword: boolean) {
|
||||
if (enforced) {
|
||||
cy.contains('Password protection (enforced)').should('exist')
|
||||
cy.contains('Password protection (enforced)').should('exist')
|
||||
} else if (alwaysAskForPassword) {
|
||||
cy.contains('Password protection').should('exist')
|
||||
cy.contains('Password protection').should('exist')
|
||||
}
|
||||
cy.contains('Enter a password')
|
||||
.should('exist')
|
||||
|
|
@ -68,13 +68,22 @@ function checkPasswordState(enforced: boolean, alwaysAskForPassword: boolean) {
|
|||
*/
|
||||
function checkExpirationDateState(enforced: boolean, hasDefault: boolean) {
|
||||
if (enforced) {
|
||||
cy.contains('Enable link expiration (enforced)').should('exist')
|
||||
cy.contains('Enable link expiration (enforced)').should('exist')
|
||||
} else if (hasDefault) {
|
||||
cy.contains('Enable link expiration').should('exist')
|
||||
cy.contains('Enable link expiration').should('exist')
|
||||
}
|
||||
cy.contains('Enter expiration date')
|
||||
.should('exist')
|
||||
.and('not.be.disabled')
|
||||
cy.get('input[data-cy-files-sharing-expiration-date-input]').should('exist')
|
||||
cy.get('input[data-cy-files-sharing-expiration-date-input]')
|
||||
.invoke('val')
|
||||
.then((val) => {
|
||||
const expectedDate = new Date()
|
||||
expectedDate.setDate(expectedDate.getDate() + 2)
|
||||
expect(new Date(val).toDateString()).to.eq(expectedDate.toDateString())
|
||||
})
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
|
|
@ -90,7 +99,7 @@ export function createShare(context: ShareContext, shareName: string, options: S
|
|||
|
||||
cy.intercept('POST', '**/ocs/v2.php/apps/files_sharing/api/v1/shares').as('createShare')
|
||||
cy.findByRole('button', { name: 'Create a new share link' }).click()
|
||||
// Conduct optional checks based on the provided options
|
||||
// Conduct optional checks based on the provided options
|
||||
if (options) {
|
||||
cy.get('.sharing-entry__actions').should('be.visible') // Wait for the dialog to open
|
||||
checkPasswordState(options.enforcePassword ?? false, options.alwaysAskForPassword ?? false)
|
||||
|
|
|
|||
3
dist/113-113.js
vendored
3
dist/113-113.js
vendored
File diff suppressed because one or more lines are too long
1
dist/113-113.js.map
vendored
1
dist/113-113.js.map
vendored
File diff suppressed because one or more lines are too long
3
dist/221-221.js
vendored
Normal file
3
dist/221-221.js
vendored
Normal file
File diff suppressed because one or more lines are too long
1
dist/221-221.js.map
vendored
Normal file
1
dist/221-221.js.map
vendored
Normal file
File diff suppressed because one or more lines are too long
4
dist/files_sharing-files_sharing_tab.js
vendored
4
dist/files_sharing-files_sharing_tab.js
vendored
File diff suppressed because one or more lines are too long
2
dist/files_sharing-files_sharing_tab.js.map
vendored
2
dist/files_sharing-files_sharing_tab.js.map
vendored
File diff suppressed because one or more lines are too long
Loading…
Reference in a new issue