mirror of
https://github.com/nextcloud/server.git
synced 2026-04-22 06:37:56 -04:00
chore(files_sharing): refactor sharing config
Signed-off-by: skjnldsv <skjnldsv@protonmail.com>
This commit is contained in:
parent
06462804f7
commit
208ff8013d
14 changed files with 464 additions and 379 deletions
|
|
@ -24,21 +24,23 @@
|
|||
class="file-request-dialog__form"
|
||||
aria-labelledby="file-request-dialog-description"
|
||||
data-cy-file-request-dialog-form
|
||||
@submit.prevent.stop="onSubmit">
|
||||
<FileRequestIntro v-if="currentStep === STEP.FIRST"
|
||||
@submit.prevent.stop="">
|
||||
<FileRequestIntro v-show="currentStep === STEP.FIRST"
|
||||
:context="context"
|
||||
:destination.sync="destination"
|
||||
:disabled="loading"
|
||||
:label.sync="label"
|
||||
:note.sync="note" />
|
||||
|
||||
<FileRequestDatePassword v-else-if="currentStep === STEP.SECOND"
|
||||
<FileRequestDatePassword v-show="currentStep === STEP.SECOND"
|
||||
:deadline.sync="deadline"
|
||||
:disabled="loading"
|
||||
:password.sync="password" />
|
||||
|
||||
<FileRequestFinish v-else-if="share"
|
||||
<FileRequestFinish v-if="share"
|
||||
v-show="currentStep === STEP.LAST"
|
||||
:emails="emails"
|
||||
:isShareByMailEnabled="isShareByMailEnabled"
|
||||
:share="share"
|
||||
@add-email="email => emails.push(email)"
|
||||
@remove-email="onRemoveEmail" />
|
||||
|
|
@ -79,17 +81,19 @@
|
|||
<NcLoadingIcon v-if="loading" />
|
||||
<IconNext v-else :size="20" />
|
||||
</template>
|
||||
{{ continueButtonLabel }}
|
||||
{{ t('files_sharing', 'Continue') }}
|
||||
</NcButton>
|
||||
|
||||
<!-- Finish -->
|
||||
<NcButton v-else
|
||||
:aria-label="t('files_sharing', 'Close the creation dialog')"
|
||||
:aria-label="finishButtonLabel"
|
||||
:disabled="loading"
|
||||
data-cy-file-request-dialog-controls="finish"
|
||||
type="primary"
|
||||
@click="$emit('close')">
|
||||
@click="onFinish">
|
||||
<template #icon>
|
||||
<IconCheck :size="20" />
|
||||
<NcLoadingIcon v-if="loading" />
|
||||
<IconCheck v-else :size="20" />
|
||||
</template>
|
||||
{{ finishButtonLabel }}
|
||||
</NcButton>
|
||||
|
|
@ -99,14 +103,15 @@
|
|||
|
||||
<script lang="ts">
|
||||
import type { AxiosError } from 'axios'
|
||||
import type { Folder, Node } from '@nextcloud/files'
|
||||
import { Permission, type Folder, type Node } from '@nextcloud/files'
|
||||
import type { OCSResponse } from '@nextcloud/typings/ocs'
|
||||
import type { PropType } from 'vue'
|
||||
|
||||
import { defineComponent } from 'vue'
|
||||
import { emit } from '@nextcloud/event-bus'
|
||||
import { generateOcsUrl } from '@nextcloud/router'
|
||||
import { showError } from '@nextcloud/dialogs'
|
||||
import { getCapabilities } from '@nextcloud/capabilities'
|
||||
import { showError, showSuccess } from '@nextcloud/dialogs'
|
||||
import { translate, translatePlural } from '@nextcloud/l10n'
|
||||
import { Type } from '@nextcloud/sharing'
|
||||
import axios from '@nextcloud/axios'
|
||||
|
|
@ -159,9 +164,12 @@ export default defineComponent({
|
|||
|
||||
setup() {
|
||||
return {
|
||||
STEP,
|
||||
|
||||
n: translatePlural,
|
||||
t: translate,
|
||||
STEP,
|
||||
|
||||
isShareByMailEnabled: getCapabilities()?.files_sharing?.sharebymail?.enabled === true
|
||||
}
|
||||
},
|
||||
|
||||
|
|
@ -183,13 +191,6 @@ export default defineComponent({
|
|||
},
|
||||
|
||||
computed: {
|
||||
continueButtonLabel() {
|
||||
if (this.currentStep === STEP.LAST) {
|
||||
return this.t('files_sharing', 'Close')
|
||||
}
|
||||
return this.t('files_sharing', 'Continue')
|
||||
},
|
||||
|
||||
finishButtonLabel() {
|
||||
if (this.emails.length === 0) {
|
||||
return this.t('files_sharing', 'Close')
|
||||
|
|
@ -231,8 +232,17 @@ export default defineComponent({
|
|||
this.$emit('close')
|
||||
},
|
||||
|
||||
onSubmit() {
|
||||
this.$emit('submit')
|
||||
async onFinish() {
|
||||
if (this.emails.length === 0 || this.isShareByMailEnabled === false) {
|
||||
showSuccess(this.t('files_sharing', 'File request created'))
|
||||
this.$emit('close')
|
||||
return
|
||||
}
|
||||
|
||||
await this.setShareEmails()
|
||||
await this.sendEmails()
|
||||
showSuccess(this.t('files_sharing', 'File request created and emails sent'))
|
||||
this.$emit('close')
|
||||
},
|
||||
|
||||
async createShare() {
|
||||
|
|
@ -244,7 +254,7 @@ export default defineComponent({
|
|||
try {
|
||||
const request = await axios.post(shareUrl, {
|
||||
shareType: Type.SHARE_TYPE_EMAIL,
|
||||
publicUpload: 'true',
|
||||
permissions: Permission.CREATE,
|
||||
|
||||
label: this.label,
|
||||
path: this.destination,
|
||||
|
|
@ -253,13 +263,13 @@ export default defineComponent({
|
|||
password: this.password || undefined,
|
||||
expireDate,
|
||||
|
||||
// Empty string to fallback to the attributes
|
||||
sharedWith: '',
|
||||
attributes: JSON.stringify({
|
||||
value: this.emails,
|
||||
key: 'emails',
|
||||
scope: 'sharedWith',
|
||||
})
|
||||
// Empty string
|
||||
shareWith: '',
|
||||
attributes: JSON.stringify([{
|
||||
value: true,
|
||||
key: 'enabled',
|
||||
scope: 'fileRequest',
|
||||
}])
|
||||
})
|
||||
|
||||
// If not an ocs request
|
||||
|
|
@ -288,6 +298,74 @@ export default defineComponent({
|
|||
this.loading = false
|
||||
}
|
||||
},
|
||||
|
||||
async setShareEmails() {
|
||||
this.loading = true
|
||||
|
||||
// This should never happen™
|
||||
if (!this.share || !this.share?.id) {
|
||||
throw new Error('Share ID is missing')
|
||||
}
|
||||
|
||||
const shareUrl = generateOcsUrl('apps/files_sharing/api/v1/shares/' + this.share.id)
|
||||
try {
|
||||
// Convert link share to email share
|
||||
const request = await axios.put(shareUrl, {
|
||||
attributes: JSON.stringify([{
|
||||
value: this.emails,
|
||||
key: 'emails',
|
||||
scope: 'shareWith',
|
||||
}])
|
||||
})
|
||||
|
||||
// If not an ocs request
|
||||
if (!request?.data?.ocs) {
|
||||
throw request
|
||||
}
|
||||
} catch (error) {
|
||||
this.onEmailSendError(error)
|
||||
throw error
|
||||
} finally {
|
||||
this.loading = false
|
||||
}
|
||||
},
|
||||
|
||||
async sendEmails () {
|
||||
this.loading = true
|
||||
|
||||
// This should never happen™
|
||||
if (!this.share || !this.share?.id) {
|
||||
throw new Error('Share ID is missing')
|
||||
}
|
||||
|
||||
const shareUrl = generateOcsUrl('apps/files_sharing/api/v1/shares/' + this.share.id + '/send-email')
|
||||
try {
|
||||
// Convert link share to email share
|
||||
const request = await axios.post(shareUrl, {
|
||||
password: this.password || undefined,
|
||||
})
|
||||
|
||||
// If not an ocs request
|
||||
if (!request?.data?.ocs) {
|
||||
throw request
|
||||
}
|
||||
} catch (error) {
|
||||
this.onEmailSendError(error)
|
||||
throw error
|
||||
} finally {
|
||||
this.loading = false
|
||||
}
|
||||
},
|
||||
|
||||
onEmailSendError(error: AxiosError<OCSResponse>|any) {
|
||||
const errorMessage = error.response?.data?.ocs?.meta?.message
|
||||
showError(
|
||||
errorMessage
|
||||
? this.t('files_sharing', 'Error sending emails: {errorMessage}', { errorMessage })
|
||||
: this.t('files_sharing', 'Error sending emails'),
|
||||
)
|
||||
logger.error('Error while sending emails', { error, errorMessage })
|
||||
},
|
||||
},
|
||||
})
|
||||
</script>
|
||||
|
|
|
|||
|
|
@ -68,7 +68,7 @@
|
|||
<NcButton :aria-label="t('files_sharing', 'Generate a new password')"
|
||||
:title="t('files_sharing', 'Generate a new password')"
|
||||
type="tertiary-no-background"
|
||||
@click="generatePassword(); showPassword()">
|
||||
@click="onGeneratePassword">
|
||||
<template #icon>
|
||||
<IconPasswordGen :size="20" />
|
||||
</template>
|
||||
|
|
@ -90,8 +90,11 @@ import NcPasswordField from '@nextcloud/vue/dist/Components/NcPasswordField.js'
|
|||
|
||||
import IconPasswordGen from 'vue-material-design-icons/AutoFix.vue'
|
||||
|
||||
import Config from '../../services/ConfigService'
|
||||
import GeneratePassword from '../../utils/GeneratePassword'
|
||||
|
||||
const sharingConfig = new Config()
|
||||
|
||||
export default defineComponent({
|
||||
name: 'FileRequestDatePassword',
|
||||
|
||||
|
|
@ -132,16 +135,16 @@ export default defineComponent({
|
|||
t: translate,
|
||||
|
||||
// Default expiration date if defaultExpireDateEnabled is true
|
||||
defaultExpireDate: window.OC.appConfig.core.defaultExpireDate as number,
|
||||
defaultExpireDate: sharingConfig.defaultExpireDate,
|
||||
// Default expiration date is enabled for public links (can be disabled)
|
||||
defaultExpireDateEnabled: window.OC.appConfig.core.defaultExpireDateEnabled === true,
|
||||
defaultExpireDateEnabled: sharingConfig.isDefaultExpireDateEnabled,
|
||||
// Default expiration date is enforced for public links (can't be disabled)
|
||||
defaultExpireDateEnforced: window.OC.appConfig.core.defaultExpireDateEnforced === true,
|
||||
defaultExpireDateEnforced: sharingConfig.isDefaultExpireDateEnforced,
|
||||
|
||||
// Default password protection is enabled for public links (can be disabled)
|
||||
enableLinkPasswordByDefault: window.OC.appConfig.core.enableLinkPasswordByDefault === true,
|
||||
enableLinkPasswordByDefault: sharingConfig.enableLinkPasswordByDefault,
|
||||
// Password protection is enforced for public links (can't be disabled)
|
||||
enforcePasswordForPublicLink: window.OC.appConfig.core.enforcePasswordForPublicLink === true,
|
||||
enforcePasswordForPublicLink: sharingConfig.enforcePasswordForPublicLink,
|
||||
}
|
||||
},
|
||||
|
||||
|
|
@ -176,13 +179,13 @@ export default defineComponent({
|
|||
|
||||
mounted() {
|
||||
// If defined, we set the default expiration date
|
||||
if (this.defaultExpireDate > 0) {
|
||||
this.$emit('update:deadline', new Date(new Date().setDate(new Date().getDate() + this.defaultExpireDate)))
|
||||
if (this.defaultExpireDate) {
|
||||
this.$emit('update:deadline', sharingConfig.defaultExpirationDate)
|
||||
}
|
||||
|
||||
// If enforced, we cannot set a date before the default expiration days (see admin settings)
|
||||
if (this.defaultExpireDateEnforced) {
|
||||
this.maxDate = new Date(new Date().setDate(new Date().getDate() + this.defaultExpireDate))
|
||||
this.maxDate = sharingConfig.defaultExpirationDate
|
||||
}
|
||||
|
||||
// If enabled by default, we generate a valid password
|
||||
|
|
@ -204,8 +207,14 @@ export default defineComponent({
|
|||
this.$emit('update:password', null)
|
||||
},
|
||||
|
||||
generatePassword() {
|
||||
GeneratePassword().then(password => {
|
||||
|
||||
async onGeneratePassword() {
|
||||
await this.generatePassword()
|
||||
this.showPassword()
|
||||
},
|
||||
|
||||
async generatePassword() {
|
||||
await GeneratePassword().then(password => {
|
||||
this.$emit('update:password', password)
|
||||
})
|
||||
},
|
||||
|
|
|
|||
|
|
@ -7,7 +7,7 @@
|
|||
<div>
|
||||
<!-- Request note -->
|
||||
<NcNoteCard type="success">
|
||||
{{ t('files_sharing', 'You can now share the link below to allow others to upload files to your directory.') }}
|
||||
{{ t('files_sharing', 'Once created, you can share the link below to allow people to upload files to your directory.') }}
|
||||
</NcNoteCard>
|
||||
|
||||
<!-- Copy share link -->
|
||||
|
|
@ -71,7 +71,6 @@ import NcChip from '@nextcloud/vue/dist/Components/NcChip.js'
|
|||
|
||||
import IconCheck from 'vue-material-design-icons/Check.vue'
|
||||
import IconClipboard from 'vue-material-design-icons/Clipboard.vue'
|
||||
import { getCapabilities } from '@nextcloud/capabilities'
|
||||
|
||||
export default defineComponent({
|
||||
name: 'FileRequestFinish',
|
||||
|
|
@ -95,6 +94,10 @@ export default defineComponent({
|
|||
type: Array as PropType<string[]>,
|
||||
required: true,
|
||||
},
|
||||
isShareByMailEnabled: {
|
||||
type: Boolean,
|
||||
required: true,
|
||||
},
|
||||
},
|
||||
|
||||
emits: ['add-email', 'remove-email'],
|
||||
|
|
@ -103,7 +106,6 @@ export default defineComponent({
|
|||
return {
|
||||
n: translatePlural,
|
||||
t: translate,
|
||||
isShareByMailEnabled: getCapabilities()?.files_sharing?.sharebymail?.enabled === true,
|
||||
}
|
||||
},
|
||||
|
||||
|
|
|
|||
|
|
@ -327,6 +327,11 @@ export default {
|
|||
}
|
||||
if (this.share.label && this.share.label.trim() !== '') {
|
||||
if (this.isEmailShareType) {
|
||||
if (this.isFileRequest) {
|
||||
return t('files_sharing', 'File request ({label})', {
|
||||
label: this.share.label.trim(),
|
||||
})
|
||||
}
|
||||
return t('files_sharing', 'Mail share ({label})', {
|
||||
label: this.share.label.trim(),
|
||||
})
|
||||
|
|
@ -336,6 +341,11 @@ export default {
|
|||
})
|
||||
}
|
||||
if (this.isEmailShareType) {
|
||||
if (!this.share.shareWith || this.share.shareWith.trim() === '') {
|
||||
return this.isFileRequest
|
||||
? t('files_sharing', 'File request')
|
||||
: t('files_sharing', 'Mail share')
|
||||
}
|
||||
return this.share.shareWith
|
||||
}
|
||||
}
|
||||
|
|
@ -554,9 +564,13 @@ export default {
|
|||
},
|
||||
|
||||
canChangeHideDownload() {
|
||||
const hasDisabledDownload = (shareAttribute) => shareAttribute.key === 'download' && shareAttribute.scope === 'permissions' && shareAttribute.value === false
|
||||
const hasDisabledDownload = (shareAttribute) => shareAttribute.scope === 'permissions' && shareAttribute.key === 'download'&& shareAttribute.value === false
|
||||
return this.fileInfo.shareAttributes.some(hasDisabledDownload)
|
||||
},
|
||||
|
||||
isFileRequest() {
|
||||
return this.share.isFileRequest
|
||||
},
|
||||
},
|
||||
|
||||
methods: {
|
||||
|
|
|
|||
|
|
@ -80,7 +80,7 @@ export default {
|
|||
return t('files_sharing', 'Can edit')
|
||||
},
|
||||
fileDropText() {
|
||||
return t('files_sharing', 'File requests')
|
||||
return t('files_sharing', 'File request')
|
||||
},
|
||||
customPermissionsText() {
|
||||
return t('files_sharing', 'Custom permissions')
|
||||
|
|
|
|||
|
|
@ -34,7 +34,7 @@ import axios from '@nextcloud/axios'
|
|||
import debounce from 'debounce'
|
||||
import NcSelect from '@nextcloud/vue/dist/Components/NcSelect.js'
|
||||
|
||||
import Config from '../services/ConfigService.js'
|
||||
import Config from '../services/ConfigService.ts'
|
||||
import GeneratePassword from '../utils/GeneratePassword.ts'
|
||||
import Share from '../models/Share.js'
|
||||
import ShareRequests from '../mixins/ShareRequests.js'
|
||||
|
|
|
|||
|
|
@ -4,7 +4,7 @@
|
|||
*/
|
||||
|
||||
import Share from '../models/Share.js'
|
||||
import Config from '../services/ConfigService.js'
|
||||
import Config from '../services/ConfigService.ts'
|
||||
|
||||
export default {
|
||||
methods: {
|
||||
|
|
|
|||
|
|
@ -14,7 +14,7 @@ import debounce from 'debounce'
|
|||
import Share from '../models/Share.js'
|
||||
import SharesRequests from './ShareRequests.js'
|
||||
import ShareTypes from './ShareTypes.js'
|
||||
import Config from '../services/ConfigService.js'
|
||||
import Config from '../services/ConfigService.ts'
|
||||
import logger from '../services/logger.ts'
|
||||
|
||||
import {
|
||||
|
|
|
|||
|
|
@ -532,16 +532,27 @@ export default class Share {
|
|||
* @memberof Share
|
||||
*/
|
||||
get hasDownloadPermission() {
|
||||
for (const i in this._share.attributes) {
|
||||
const attr = this._share.attributes[i]
|
||||
if (attr.scope === 'permissions' && attr.key === 'download') {
|
||||
return attr.value
|
||||
}
|
||||
const hasDisabledDownload = (attribute) => {
|
||||
return attribute.scope === 'permissions' && attribute.key === 'download' && attribute.value === false
|
||||
}
|
||||
|
||||
return true
|
||||
return this.attributes.some(hasDisabledDownload)
|
||||
}
|
||||
|
||||
/**
|
||||
* Is this mail share a file request ?
|
||||
*
|
||||
* @return {boolean}
|
||||
* @readonly
|
||||
* @memberof Share
|
||||
*/
|
||||
get isFileRequest() {
|
||||
const isFileRequest = (attribute) => {
|
||||
return attribute.scope === 'fileRequest' && attribute.key === 'enabled' && attribute.value === true
|
||||
}
|
||||
return this.attributes.some(isFileRequest)
|
||||
}
|
||||
|
||||
|
||||
set hasDownloadPermission(enabled) {
|
||||
this.setAttribute('permissions', 'download', !!enabled)
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1,322 +0,0 @@
|
|||
/**
|
||||
* SPDX-FileCopyrightText: 2019 Nextcloud GmbH and Nextcloud contributors
|
||||
* SPDX-License-Identifier: AGPL-3.0-or-later
|
||||
*/
|
||||
import { getCapabilities } from '@nextcloud/capabilities'
|
||||
|
||||
export default class Config {
|
||||
|
||||
constructor() {
|
||||
this._capabilities = getCapabilities()
|
||||
}
|
||||
|
||||
/**
|
||||
* Get default share permissions, if any
|
||||
*
|
||||
* @return {boolean}
|
||||
* @readonly
|
||||
* @memberof Config
|
||||
*/
|
||||
get defaultPermissions() {
|
||||
return this._capabilities.files_sharing?.default_permissions
|
||||
}
|
||||
|
||||
/**
|
||||
* Is public upload allowed on link shares ?
|
||||
*
|
||||
* @return {boolean}
|
||||
* @readonly
|
||||
* @memberof Config
|
||||
*/
|
||||
get isPublicUploadEnabled() {
|
||||
return this._capabilities.files_sharing?.public.upload
|
||||
}
|
||||
|
||||
/**
|
||||
* Are link share allowed ?
|
||||
*
|
||||
* @return {boolean}
|
||||
* @readonly
|
||||
* @memberof Config
|
||||
*/
|
||||
get isShareWithLinkAllowed() {
|
||||
return document.getElementById('allowShareWithLink')
|
||||
&& document.getElementById('allowShareWithLink').value === 'yes'
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the federated sharing documentation link
|
||||
*
|
||||
* @return {string}
|
||||
* @readonly
|
||||
* @memberof Config
|
||||
*/
|
||||
get federatedShareDocLink() {
|
||||
return OC.appConfig.core.federatedCloudShareDoc
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the default link share expiration date
|
||||
*
|
||||
* @return {Date|null}
|
||||
* @readonly
|
||||
* @memberof Config
|
||||
*/
|
||||
get defaultExpirationDate() {
|
||||
if (this.isDefaultExpireDateEnabled) {
|
||||
return new Date(new Date().setDate(new Date().getDate() + this.defaultExpireDate))
|
||||
}
|
||||
return null
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the default internal expiration date
|
||||
*
|
||||
* @return {Date|null}
|
||||
* @readonly
|
||||
* @memberof Config
|
||||
*/
|
||||
get defaultInternalExpirationDate() {
|
||||
if (this.isDefaultInternalExpireDateEnabled) {
|
||||
return new Date(new Date().setDate(new Date().getDate() + this.defaultInternalExpireDate))
|
||||
}
|
||||
return null
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the default remote expiration date
|
||||
*
|
||||
* @return {Date|null}
|
||||
* @readonly
|
||||
* @memberof Config
|
||||
*/
|
||||
get defaultRemoteExpirationDateString() {
|
||||
if (this.isDefaultRemoteExpireDateEnabled) {
|
||||
return new Date(new Date().setDate(new Date().getDate() + this.defaultRemoteExpireDate))
|
||||
}
|
||||
return null
|
||||
}
|
||||
|
||||
/**
|
||||
* Are link shares password-enforced ?
|
||||
*
|
||||
* @return {boolean}
|
||||
* @readonly
|
||||
* @memberof Config
|
||||
*/
|
||||
get enforcePasswordForPublicLink() {
|
||||
return OC.appConfig.core.enforcePasswordForPublicLink === true
|
||||
}
|
||||
|
||||
/**
|
||||
* Is password asked by default on link shares ?
|
||||
*
|
||||
* @return {boolean}
|
||||
* @readonly
|
||||
* @memberof Config
|
||||
*/
|
||||
get enableLinkPasswordByDefault() {
|
||||
return OC.appConfig.core.enableLinkPasswordByDefault === true
|
||||
}
|
||||
|
||||
/**
|
||||
* Is link shares expiration enforced ?
|
||||
*
|
||||
* @return {boolean}
|
||||
* @readonly
|
||||
* @memberof Config
|
||||
*/
|
||||
get isDefaultExpireDateEnforced() {
|
||||
return OC.appConfig.core.defaultExpireDateEnforced === true
|
||||
}
|
||||
|
||||
/**
|
||||
* Is there a default expiration date for new link shares ?
|
||||
*
|
||||
* @return {boolean}
|
||||
* @readonly
|
||||
* @memberof Config
|
||||
*/
|
||||
get isDefaultExpireDateEnabled() {
|
||||
return OC.appConfig.core.defaultExpireDateEnabled === true
|
||||
}
|
||||
|
||||
/**
|
||||
* Is internal shares expiration enforced ?
|
||||
*
|
||||
* @return {boolean}
|
||||
* @readonly
|
||||
* @memberof Config
|
||||
*/
|
||||
get isDefaultInternalExpireDateEnforced() {
|
||||
return OC.appConfig.core.defaultInternalExpireDateEnforced === true
|
||||
}
|
||||
|
||||
/**
|
||||
* Is remote shares expiration enforced ?
|
||||
*
|
||||
* @return {boolean}
|
||||
* @readonly
|
||||
* @memberof Config
|
||||
*/
|
||||
get isDefaultRemoteExpireDateEnforced() {
|
||||
return OC.appConfig.core.defaultRemoteExpireDateEnforced === true
|
||||
}
|
||||
|
||||
/**
|
||||
* Is there a default expiration date for new internal shares ?
|
||||
*
|
||||
* @return {boolean}
|
||||
* @readonly
|
||||
* @memberof Config
|
||||
*/
|
||||
get isDefaultInternalExpireDateEnabled() {
|
||||
return OC.appConfig.core.defaultInternalExpireDateEnabled === true
|
||||
}
|
||||
|
||||
/**
|
||||
* Is there a default expiration date for new remote shares ?
|
||||
*
|
||||
* @return {boolean}
|
||||
* @readonly
|
||||
* @memberof Config
|
||||
*/
|
||||
get isDefaultRemoteExpireDateEnabled() {
|
||||
return OC.appConfig.core.defaultRemoteExpireDateEnabled === true
|
||||
}
|
||||
|
||||
/**
|
||||
* Are users on this server allowed to send shares to other servers ?
|
||||
*
|
||||
* @return {boolean}
|
||||
* @readonly
|
||||
* @memberof Config
|
||||
*/
|
||||
get isRemoteShareAllowed() {
|
||||
return OC.appConfig.core.remoteShareAllowed === true
|
||||
}
|
||||
|
||||
/**
|
||||
* Is sharing my mail (link share) enabled ?
|
||||
*
|
||||
* @return {boolean}
|
||||
* @readonly
|
||||
* @memberof Config
|
||||
*/
|
||||
get isMailShareAllowed() {
|
||||
// eslint-disable-next-line camelcase
|
||||
return this._capabilities?.files_sharing?.sharebymail !== undefined
|
||||
// eslint-disable-next-line camelcase
|
||||
&& this._capabilities?.files_sharing?.public?.enabled === true
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the default days to link shares expiration
|
||||
*
|
||||
* @return {number}
|
||||
* @readonly
|
||||
* @memberof Config
|
||||
*/
|
||||
get defaultExpireDate() {
|
||||
return OC.appConfig.core.defaultExpireDate
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the default days to internal shares expiration
|
||||
*
|
||||
* @return {number}
|
||||
* @readonly
|
||||
* @memberof Config
|
||||
*/
|
||||
get defaultInternalExpireDate() {
|
||||
return OC.appConfig.core.defaultInternalExpireDate
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the default days to remote shares expiration
|
||||
*
|
||||
* @return {number}
|
||||
* @readonly
|
||||
* @memberof Config
|
||||
*/
|
||||
get defaultRemoteExpireDate() {
|
||||
return OC.appConfig.core.defaultRemoteExpireDate
|
||||
}
|
||||
|
||||
/**
|
||||
* Is resharing allowed ?
|
||||
*
|
||||
* @return {boolean}
|
||||
* @readonly
|
||||
* @memberof Config
|
||||
*/
|
||||
get isResharingAllowed() {
|
||||
return OC.appConfig.core.resharingAllowed === true
|
||||
}
|
||||
|
||||
/**
|
||||
* Is password enforced for mail shares ?
|
||||
*
|
||||
* @return {boolean}
|
||||
* @readonly
|
||||
* @memberof Config
|
||||
*/
|
||||
get isPasswordForMailSharesRequired() {
|
||||
return (this._capabilities.files_sharing.sharebymail === undefined) ? false : this._capabilities.files_sharing.sharebymail.password.enforced
|
||||
}
|
||||
|
||||
/**
|
||||
* @return {boolean}
|
||||
* @readonly
|
||||
* @memberof Config
|
||||
*/
|
||||
get shouldAlwaysShowUnique() {
|
||||
return (this._capabilities.files_sharing?.sharee?.always_show_unique === true)
|
||||
}
|
||||
|
||||
/**
|
||||
* Is sharing with groups allowed ?
|
||||
*
|
||||
* @return {boolean}
|
||||
* @readonly
|
||||
* @memberof Config
|
||||
*/
|
||||
get allowGroupSharing() {
|
||||
return OC.appConfig.core.allowGroupSharing === true
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the maximum results of a share search
|
||||
*
|
||||
* @return {number}
|
||||
* @readonly
|
||||
* @memberof Config
|
||||
*/
|
||||
get maxAutocompleteResults() {
|
||||
return parseInt(OC.config['sharing.maxAutocompleteResults'], 10) || 25
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the minimal string length
|
||||
* to initiate a share search
|
||||
*
|
||||
* @return {number}
|
||||
* @readonly
|
||||
* @memberof Config
|
||||
*/
|
||||
get minSearchStringLength() {
|
||||
return parseInt(OC.config['sharing.minSearchStringLength'], 10) || 0
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the password policy config
|
||||
*
|
||||
* @return {object}
|
||||
* @readonly
|
||||
* @memberof Config
|
||||
*/
|
||||
get passwordPolicy() {
|
||||
return this._capabilities.password_policy ? this._capabilities.password_policy : {}
|
||||
}
|
||||
|
||||
}
|
||||
293
apps/files_sharing/src/services/ConfigService.ts
Normal file
293
apps/files_sharing/src/services/ConfigService.ts
Normal file
|
|
@ -0,0 +1,293 @@
|
|||
/**
|
||||
* SPDX-FileCopyrightText: 2019 Nextcloud GmbH and Nextcloud contributors
|
||||
* SPDX-License-Identifier: AGPL-3.0-or-later
|
||||
*/
|
||||
import { getCapabilities } from '@nextcloud/capabilities'
|
||||
|
||||
export default class Config {
|
||||
_capabilities: Capabilities
|
||||
|
||||
constructor() {
|
||||
this._capabilities = getCapabilities() as Capabilities
|
||||
}
|
||||
|
||||
/**
|
||||
* Get default share permissions, if any
|
||||
*/
|
||||
get defaultPermissions(): number {
|
||||
return this._capabilities.files_sharing?.default_permissions
|
||||
}
|
||||
|
||||
/**
|
||||
* Is public upload allowed on link shares ?
|
||||
* This covers File request and Full upload/edit option.
|
||||
*/
|
||||
get isPublicUploadEnabled(): boolean {
|
||||
return this._capabilities.files_sharing?.public?.upload === true
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the federated sharing documentation link
|
||||
*/
|
||||
get federatedShareDocLink() {
|
||||
return window.OC.appConfig.core.federatedCloudShareDoc
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the default link share expiration date
|
||||
*/
|
||||
get defaultExpirationDate(): Date|null {
|
||||
if (this.isDefaultExpireDateEnabled && this.defaultExpireDate !== null) {
|
||||
return new Date(new Date().setDate(new Date().getDate() + this.defaultExpireDate))
|
||||
}
|
||||
return null
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the default internal expiration date
|
||||
*/
|
||||
get defaultInternalExpirationDate(): Date|null {
|
||||
if (this.isDefaultInternalExpireDateEnabled && this.defaultInternalExpireDate !== null) {
|
||||
return new Date(new Date().setDate(new Date().getDate() + this.defaultInternalExpireDate))
|
||||
}
|
||||
return null
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the default remote expiration date
|
||||
*/
|
||||
get defaultRemoteExpirationDateString(): Date|null {
|
||||
if (this.isDefaultRemoteExpireDateEnabled && this.defaultRemoteExpireDate !== null) {
|
||||
return new Date(new Date().setDate(new Date().getDate() + this.defaultRemoteExpireDate))
|
||||
}
|
||||
return null
|
||||
}
|
||||
|
||||
/**
|
||||
* Are link shares password-enforced ?
|
||||
*/
|
||||
get enforcePasswordForPublicLink(): boolean {
|
||||
return window.OC.appConfig.core.enforcePasswordForPublicLink === true
|
||||
}
|
||||
|
||||
/**
|
||||
* Is password asked by default on link shares ?
|
||||
*/
|
||||
get enableLinkPasswordByDefault(): boolean {
|
||||
return window.OC.appConfig.core.enableLinkPasswordByDefault === true
|
||||
}
|
||||
|
||||
/**
|
||||
* Is link shares expiration enforced ?
|
||||
*/
|
||||
get isDefaultExpireDateEnforced(): boolean {
|
||||
return window.OC.appConfig.core.defaultExpireDateEnforced === true
|
||||
}
|
||||
|
||||
/**
|
||||
* Is there a default expiration date for new link shares ?
|
||||
*/
|
||||
get isDefaultExpireDateEnabled(): boolean {
|
||||
return window.OC.appConfig.core.defaultExpireDateEnabled === true
|
||||
}
|
||||
|
||||
/**
|
||||
* Is internal shares expiration enforced ?
|
||||
*/
|
||||
get isDefaultInternalExpireDateEnforced(): boolean {
|
||||
return window.OC.appConfig.core.defaultInternalExpireDateEnforced === true
|
||||
}
|
||||
|
||||
/**
|
||||
* Is there a default expiration date for new internal shares ?
|
||||
*/
|
||||
get isDefaultInternalExpireDateEnabled(): boolean {
|
||||
return window.OC.appConfig.core.defaultInternalExpireDateEnabled === true
|
||||
}
|
||||
|
||||
/**
|
||||
* Is remote shares expiration enforced ?
|
||||
*/
|
||||
get isDefaultRemoteExpireDateEnforced(): boolean {
|
||||
return window.OC.appConfig.core.defaultRemoteExpireDateEnforced === true
|
||||
}
|
||||
|
||||
/**
|
||||
* Is there a default expiration date for new remote shares ?
|
||||
*/
|
||||
get isDefaultRemoteExpireDateEnabled(): boolean {
|
||||
return window.OC.appConfig.core.defaultRemoteExpireDateEnabled === true
|
||||
}
|
||||
|
||||
/**
|
||||
* Are users on this server allowed to send shares to other servers ?
|
||||
*/
|
||||
get isRemoteShareAllowed(): boolean {
|
||||
return window.OC.appConfig.core.remoteShareAllowed === true
|
||||
}
|
||||
|
||||
/**
|
||||
* Is sharing my mail (link share) enabled ?
|
||||
*/
|
||||
get isMailShareAllowed(): boolean {
|
||||
// eslint-disable-next-line camelcase
|
||||
return this._capabilities?.files_sharing?.sharebymail?.enabled === true
|
||||
// eslint-disable-next-line camelcase
|
||||
&& this._capabilities?.files_sharing?.public?.enabled === true
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the default days to link shares expiration
|
||||
*/
|
||||
get defaultExpireDate(): number|null {
|
||||
return window.OC.appConfig.core.defaultExpireDate
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the default days to internal shares expiration
|
||||
*/
|
||||
get defaultInternalExpireDate(): number|null {
|
||||
return window.OC.appConfig.core.defaultInternalExpireDate
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the default days to remote shares expiration
|
||||
*/
|
||||
get defaultRemoteExpireDate(): number|null {
|
||||
return window.OC.appConfig.core.defaultRemoteExpireDate
|
||||
}
|
||||
|
||||
/**
|
||||
* Is resharing allowed ?
|
||||
*/
|
||||
get isResharingAllowed(): boolean {
|
||||
return window.OC.appConfig.core.resharingAllowed === true
|
||||
}
|
||||
|
||||
/**
|
||||
* Is password enforced for mail shares ?
|
||||
*/
|
||||
get isPasswordForMailSharesRequired(): boolean {
|
||||
return this._capabilities.files_sharing?.sharebymail?.password?.enforced === true
|
||||
}
|
||||
|
||||
/**
|
||||
* Always show the email or userid unique sharee label if enabled by the admin
|
||||
*/
|
||||
get shouldAlwaysShowUnique(): boolean {
|
||||
return this._capabilities.files_sharing?.sharee?.always_show_unique === true
|
||||
}
|
||||
|
||||
/**
|
||||
* Is sharing with groups allowed ?
|
||||
*/
|
||||
get allowGroupSharing(): boolean {
|
||||
return window.OC.appConfig.core.allowGroupSharing === true
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the maximum results of a share search
|
||||
*/
|
||||
get maxAutocompleteResults(): number {
|
||||
return parseInt(window.OC.config['sharing.maxAutocompleteResults'], 10) || 25
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the minimal string length
|
||||
* to initiate a share search
|
||||
*/
|
||||
get minSearchStringLength(): number {
|
||||
return parseInt(window.OC.config['sharing.minSearchStringLength'], 10) || 0
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the password policy configuration
|
||||
*/
|
||||
get passwordPolicy(): PasswordPolicyCapabilities {
|
||||
return this._capabilities?.password_policy || {}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
type PasswordPolicyCapabilities = {
|
||||
enforceNonCommonPassword: boolean
|
||||
enforceNumericCharacters: boolean
|
||||
enforceSpecialCharacters: boolean
|
||||
enforceUpperLowerCase: boolean
|
||||
minLength: number
|
||||
}
|
||||
|
||||
type FileSharingCapabilities = {
|
||||
api_enabled: boolean,
|
||||
public: {
|
||||
enabled: boolean,
|
||||
password: {
|
||||
enforced: boolean,
|
||||
askForOptionalPassword: boolean
|
||||
},
|
||||
expire_date: {
|
||||
enabled: boolean,
|
||||
days: number,
|
||||
enforced: boolean
|
||||
},
|
||||
multiple_links: boolean,
|
||||
expire_date_internal: {
|
||||
enabled: boolean
|
||||
},
|
||||
expire_date_remote: {
|
||||
enabled: boolean
|
||||
},
|
||||
send_mail: boolean,
|
||||
upload: boolean,
|
||||
upload_files_drop: boolean
|
||||
},
|
||||
resharing: boolean,
|
||||
user: {
|
||||
send_mail: boolean,
|
||||
expire_date: {
|
||||
enabled: boolean
|
||||
}
|
||||
},
|
||||
group_sharing: boolean,
|
||||
group: {
|
||||
enabled: boolean,
|
||||
expire_date: {
|
||||
enabled: true
|
||||
}
|
||||
},
|
||||
default_permissions: number,
|
||||
federation: {
|
||||
outgoing: boolean,
|
||||
incoming: boolean,
|
||||
expire_date: {
|
||||
enabled: boolean
|
||||
},
|
||||
expire_date_supported: {
|
||||
enabled: boolean
|
||||
}
|
||||
},
|
||||
sharee: {
|
||||
query_lookup_default: boolean,
|
||||
always_show_unique: boolean
|
||||
},
|
||||
sharebymail: {
|
||||
enabled: boolean,
|
||||
send_password_by_mail: boolean,
|
||||
upload_files_drop: {
|
||||
enabled: boolean
|
||||
},
|
||||
password: {
|
||||
enabled: boolean,
|
||||
enforced: boolean
|
||||
},
|
||||
expire_date: {
|
||||
enabled: boolean,
|
||||
enforced: boolean
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
type Capabilities = {
|
||||
files_sharing: FileSharingCapabilities
|
||||
password_policy: PasswordPolicyCapabilities
|
||||
}
|
||||
|
|
@ -4,7 +4,7 @@
|
|||
*/
|
||||
|
||||
import axios from '@nextcloud/axios'
|
||||
import Config from '../services/ConfigService.js'
|
||||
import Config from '../services/ConfigService.ts'
|
||||
import { showError, showSuccess } from '@nextcloud/dialogs'
|
||||
import { translate as t } from '@nextcloud/l10n'
|
||||
|
||||
|
|
|
|||
|
|
@ -62,7 +62,7 @@
|
|||
type="radio"
|
||||
button-variant-grouped="vertical"
|
||||
@update:checked="toggleCustomPermissions">
|
||||
{{ t('files_sharing', 'File requests') }}
|
||||
{{ t('files_sharing', 'File request') }}
|
||||
<small class="subline">{{ t('files_sharing', 'Upload only') }}</small>
|
||||
<template #icon>
|
||||
<UploadIcon :size="20" />
|
||||
|
|
|
|||
|
|
@ -88,7 +88,7 @@ import NcAvatar from '@nextcloud/vue/dist/Components/NcAvatar.js'
|
|||
import axios from '@nextcloud/axios'
|
||||
import { loadState } from '@nextcloud/initial-state'
|
||||
|
||||
import Config from '../services/ConfigService.js'
|
||||
import Config from '../services/ConfigService.ts'
|
||||
import { shareWithTitle } from '../utils/SharedWithMe.js'
|
||||
import Share from '../models/Share.js'
|
||||
import ShareTypes from '../mixins/ShareTypes.js'
|
||||
|
|
|
|||
Loading…
Reference in a new issue