aboutsummaryrefslogtreecommitdiffstats
path: root/apps/settings/src/components/AdminSettingsSharingForm.vue
diff options
context:
space:
mode:
Diffstat (limited to 'apps/settings/src/components/AdminSettingsSharingForm.vue')
-rw-r--r--apps/settings/src/components/AdminSettingsSharingForm.vue184
1 files changed, 117 insertions, 67 deletions
diff --git a/apps/settings/src/components/AdminSettingsSharingForm.vue b/apps/settings/src/components/AdminSettingsSharingForm.vue
index de23adf67d2..b0e142d8480 100644
--- a/apps/settings/src/components/AdminSettingsSharingForm.vue
+++ b/apps/settings/src/components/AdminSettingsSharingForm.vue
@@ -1,23 +1,6 @@
<!--
- - @copyright 2023 Ferdinand Thiessen <opensource@fthiessen.de>
- -
- - @author Ferdinand Thiessen <opensource@fthiessen.de>
- -
- - @license AGPL-3.0-or-later
- -
- - This program is free software: you can redistribute it and/or modify
- - it under the terms of the GNU Affero General Public License as
- - published by the Free Software Foundation, either version 3 of the
- - License, or (at your option) any later version.
- -
- - This program is distributed in the hope that it will be useful,
- - but WITHOUT ANY WARRANTY; without even the implied warranty of
- - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- - GNU Affero General Public License for more details.
- -
- - You should have received a copy of the GNU Affero General Public License
- - along with this program. If not, see <http://www.gnu.org/licenses/>.
- -
+ - SPDX-FileCopyrightText: 2023 Nextcloud GmbH and Nextcloud contributors
+ - SPDX-License-Identifier: AGPL-3.0-or-later
-->
<template>
<form class="sharing">
@@ -37,6 +20,22 @@
<NcCheckboxRadioSwitch :checked.sync="settings.onlyShareWithGroupMembers">
{{ t('settings', 'Restrict users to only share with users in their groups') }}
</NcCheckboxRadioSwitch>
+ <div v-show="settings.onlyShareWithGroupMembers" id="settings-sharing-api-excluded-groups" class="sharing__labeled-entry sharing__input">
+ <label for="settings-sharing-only-group-members-excluded-groups">{{ t('settings', 'Ignore the following groups when checking group membership') }}</label>
+ <NcSettingsSelectGroup id="settings-sharing-only-group-members-excluded-groups"
+ v-model="settings.onlyShareWithGroupMembersExcludeGroupList"
+ :label="t('settings', 'Ignore the following groups when checking group membership')"
+ style="width: 100%" />
+ </div>
+ <NcCheckboxRadioSwitch :checked.sync="settings.allowViewWithoutDownload">
+ {{ t('settings', 'Allow users to preview files even if download is disabled') }}
+ </NcCheckboxRadioSwitch>
+ <NcNoteCard v-show="settings.allowViewWithoutDownload"
+ id="settings-sharing-api-view-without-download-hint"
+ class="sharing__note"
+ type="warning">
+ {{ t('settings', 'Users will still be able to screenshot or record the screen. This does not provide any definitive protection.') }}
+ </NcNoteCard>
</div>
<div v-show="settings.enabled" id="settings-sharing-api" class="sharing__section">
@@ -49,15 +48,19 @@
<NcCheckboxRadioSwitch :checked.sync="settings.allowPublicUpload">
{{ t('settings', 'Allow public uploads') }}
</NcCheckboxRadioSwitch>
+ <NcCheckboxRadioSwitch v-model="settings.allowFederationOnPublicShares">
+ {{ t('settings', 'Allow public shares to be added to other clouds by federation.') }}
+ {{ t('settings', 'This will add share permissions to all newly created link shares.') }}
+ </NcCheckboxRadioSwitch>
<NcCheckboxRadioSwitch :checked.sync="settings.enableLinkPasswordByDefault">
{{ t('settings', 'Always ask for a password') }}
</NcCheckboxRadioSwitch>
<NcCheckboxRadioSwitch :checked.sync="settings.enforceLinksPassword" :disabled="!settings.enableLinkPasswordByDefault">
{{ t('settings', 'Enforce password protection') }}
</NcCheckboxRadioSwitch>
- <label v-if="settings.passwordExcludedGroupsFeatureEnabled" class="sharing__labeled-entry sharing__input">
+ <label v-if="settings.enforceLinksPasswordExcludedGroupsEnabled" class="sharing__labeled-entry sharing__input">
<span>{{ t('settings', 'Exclude groups from password requirements') }}</span>
- <NcSettingsSelectGroup v-model="settings.passwordExcludedGroups"
+ <NcSettingsSelectGroup v-model="settings.enforceLinksPasswordExcludedGroups"
style="width: 100%"
:disabled="!settings.enforceLinksPassword || !settings.enableLinkPasswordByDefault" />
</label>
@@ -69,26 +72,62 @@
</label>
</fieldset>
- <NcCheckboxRadioSwitch type="switch" :checked.sync="settings.excludeGroups">
- {{ t('settings', 'Exclude groups from sharing') }}
+ <NcCheckboxRadioSwitch type="switch"
+ aria-describedby="settings-sharing-custom-token-disable-hint settings-sharing-custom-token-access-hint"
+ :checked.sync="settings.allowCustomTokens">
+ {{ t('settings', 'Allow users to set custom share link tokens') }}
</NcCheckboxRadioSwitch>
- <div v-show="settings.excludeGroups" class="sharing__sub-section">
- <div class="sharing__labeled-entry sharing__input">
- <label for="settings-sharing-excluded-groups">{{ t('settings', 'Groups excluded from sharing') }}</label>
+ <div class="sharing__sub-section">
+ <NcNoteCard id="settings-sharing-custom-token-disable-hint"
+ class="sharing__note"
+ type="info">
+ {{ t('settings', 'Shares with custom tokens will continue to be accessible after this setting has been disabled') }}
+ </NcNoteCard>
+ <NcNoteCard id="settings-sharing-custom-token-access-hint"
+ class="sharing__note"
+ type="warning">
+ {{ t('settings', 'Shares with guessable tokens may be accessed easily') }}
+ </NcNoteCard>
+ </div>
+
+ <label>{{ t('settings', 'Limit sharing based on groups') }}</label>
+ <div class="sharing__sub-section">
+ <NcCheckboxRadioSwitch :checked.sync="settings.excludeGroups"
+ name="excludeGroups"
+ value="no"
+ type="radio"
+ @update:checked="onUpdateExcludeGroups">
+ {{ t('settings', 'Allow sharing for everyone (default)') }}
+ </NcCheckboxRadioSwitch>
+ <NcCheckboxRadioSwitch :checked.sync="settings.excludeGroups"
+ name="excludeGroups"
+ value="yes"
+ type="radio"
+ @update:checked="onUpdateExcludeGroups">
+ {{ t('settings', 'Exclude some groups from sharing') }}
+ </NcCheckboxRadioSwitch>
+ <NcCheckboxRadioSwitch :checked.sync="settings.excludeGroups"
+ name="excludeGroups"
+ value="allow"
+ type="radio"
+ @update:checked="onUpdateExcludeGroups">
+ {{ t('settings', 'Limit sharing to some groups') }}
+ </NcCheckboxRadioSwitch>
+ <div v-show="settings.excludeGroups !== 'no'" class="sharing__labeled-entry sharing__input">
<NcSettingsSelectGroup id="settings-sharing-excluded-groups"
v-model="settings.excludeGroupsList"
aria-describedby="settings-sharing-excluded-groups-desc"
- :label="t('settings', 'Groups excluded from sharing')"
- :disabled="!settings.excludeGroups"
+ :label="settings.excludeGroups === 'allow' ? t('settings', 'Groups allowed to share') : t('settings', 'Groups excluded from sharing')"
+ :disabled="settings.excludeGroups === 'no'"
style="width: 100%" />
- <em id="settings-sharing-excluded-groups-desc">{{ t('settings', 'These groups will still be able to receive shares, but not to initiate them.') }}</em>
+ <em id="settings-sharing-excluded-groups-desc">{{ t('settings', 'Not allowed groups will still be able to receive shares, but not to initiate them.') }}</em>
</div>
</div>
<NcCheckboxRadioSwitch type="switch"
aria-controls="settings-sharing-api-expiration"
:checked.sync="settings.defaultInternalExpireDate">
- {{ t('settings', 'Set default expiration date for shares') }}
+ {{ t('settings', 'Set default expiration date for internal shares') }}
</NcCheckboxRadioSwitch>
<fieldset v-show="settings.defaultInternalExpireDate" id="settings-sharing-api-expiration" class="sharing__sub-section">
<NcCheckboxRadioSwitch :checked.sync="settings.enforceInternalExpireDate">
@@ -123,9 +162,9 @@
:disabled="!settings.allowLinks">
{{ t('settings', 'Set default expiration date for shares via link or mail') }}
</NcCheckboxRadioSwitch>
- <fieldset v-show="settings.allowLinks && settings.defaultExpireDate" id="settings-sharing-link-api-expiration" class="sharing__sub-section">
+ <fieldset v-show="settings.allowLinks && settings.defaultExpireDate" id="settings-sharing-api-api-expiration" class="sharing__sub-section">
<NcCheckboxRadioSwitch :checked.sync="settings.enforceExpireDate">
- {{ t('settings', 'Enforce expiration date for remote shares') }}
+ {{ t('settings', 'Enforce expiration date for link or mail shares') }}
</NcCheckboxRadioSwitch>
<NcTextField type="number"
class="sharing__input"
@@ -141,17 +180,17 @@
<NcCheckboxRadioSwitch type="switch"
aria-controls="settings-sharing-privacy-user-enumeration"
:checked.sync="settings.allowShareDialogUserEnumeration">
- {{ t('settings', 'Allow username autocompletion in share dialog and allow access to the system address book') }}
+ {{ t('settings', 'Allow account name autocompletion in share dialog and allow access to the system address book') }}
</NcCheckboxRadioSwitch>
<fieldset v-show="settings.allowShareDialogUserEnumeration" id="settings-sharing-privacy-user-enumeration" class="sharing__sub-section">
<em>
{{ t('settings', 'If autocompletion "same group" and "phone number integration" are enabled a match in either is enough to show the user.') }}
</em>
<NcCheckboxRadioSwitch :checked.sync="settings.restrictUserEnumerationToGroup">
- {{ t('settings', 'Allow username autocompletion to users within the same groups and limit system address books to users in the same groups') }}
+ {{ t('settings', 'Restrict account name autocompletion and system address book access to users within the same groups') }}
</NcCheckboxRadioSwitch>
<NcCheckboxRadioSwitch :checked.sync="settings.restrictUserEnumerationToPhone">
- {{ t('settings', 'Allow username autocompletion to users based on phone number integration') }}
+ {{ t('settings', 'Restrict account name autocompletion to users based on phone number integration') }}
</NcCheckboxRadioSwitch>
</fieldset>
@@ -159,17 +198,15 @@
{{ t('settings', 'Allow autocompletion when entering the full name or email address (ignoring missing phonebook match and being in the same group)') }}
</NcCheckboxRadioSwitch>
- <NcCheckboxRadioSwitch type="switch"
- aria-controls="settings-sharing-privary-related-disclaimer"
- :checked.sync="publicShareDisclaimerEnabled">
+ <NcCheckboxRadioSwitch type="switch" :checked.sync="publicShareDisclaimerEnabled">
{{ t('settings', 'Show disclaimer text on the public link upload page (only shown when the file list is hidden)') }}
</NcCheckboxRadioSwitch>
- <div v-if="typeof settings.publicShareDisclaimerText === 'string'"
- id="settings-sharing-privary-related-disclaimer"
+ <div v-if="publicShareDisclaimerEnabled"
aria-describedby="settings-sharing-privary-related-disclaimer-hint"
class="sharing__sub-section">
<NcTextArea class="sharing__input"
:label="t('settings', 'Disclaimer text')"
+ aria-describedby="settings-sharing-privary-related-disclaimer-hint"
:value="settings.publicShareDisclaimerText"
@update:value="onUpdateDisclaimer" />
<em id="settings-sharing-privary-related-disclaimer-hint" class="sharing__input">
@@ -186,19 +223,19 @@
</template>
<script lang="ts">
-import {
- NcCheckboxRadioSwitch,
- NcSettingsSelectGroup,
- NcTextArea,
- NcTextField,
-} from '@nextcloud/vue'
import { showError, showSuccess } from '@nextcloud/dialogs'
-import { translate as t } from '@nextcloud/l10n'
import { loadState } from '@nextcloud/initial-state'
+import { t } from '@nextcloud/l10n'
+import { snakeCase } from 'lodash'
import { defineComponent } from 'vue'
+import debounce from 'debounce'
+import NcCheckboxRadioSwitch from '@nextcloud/vue/components/NcCheckboxRadioSwitch'
+import NcNoteCard from '@nextcloud/vue/components/NcNoteCard'
+import NcSettingsSelectGroup from '@nextcloud/vue/components/NcSettingsSelectGroup'
+import NcTextArea from '@nextcloud/vue/components/NcTextArea'
+import NcTextField from '@nextcloud/vue/components/NcTextField'
import SelectSharingPermissions from './SelectSharingPermissions.vue'
-import { snakeCase, debounce } from 'lodash'
interface IShareSettings {
enabled: boolean
@@ -208,6 +245,7 @@ interface IShareSettings {
allowPublicUpload: boolean
allowResharing: boolean
allowShareDialogUserEnumeration: boolean
+ allowFederationOnPublicShares: boolean
restrictUserEnumerationToGroup: boolean
restrictUserEnumerationToPhone: boolean
restrictUserEnumerationFullMatch: boolean
@@ -215,15 +253,16 @@ interface IShareSettings {
restrictUserEnumerationFullMatchEmail: boolean
restrictUserEnumerationFullMatchIgnoreSecondDN: boolean
enforceLinksPassword: boolean
- passwordExcludedGroups: string[]
- passwordExcludedGroupsFeatureEnabled: boolean
+ enforceLinksPasswordExcludedGroups: string[]
+ enforceLinksPasswordExcludedGroupsEnabled: boolean
onlyShareWithGroupMembers: boolean
+ onlyShareWithGroupMembersExcludeGroupList: string[]
defaultExpireDate: boolean
expireAfterNDays: string
enforceExpireDate: boolean
- excludeGroups: boolean
+ excludeGroups: string
excludeGroupsList: string[]
- publicShareDisclaimerText?: string
+ publicShareDisclaimerText: string
enableLinkPasswordByDefault: boolean
defaultPermissions: number
defaultInternalExpireDate: boolean
@@ -232,6 +271,8 @@ interface IShareSettings {
defaultRemoteExpireDate: boolean
remoteExpireAfterNDays: string
enforceRemoteExpireDate: boolean
+ allowCustomTokens: boolean
+ allowViewWithoutDownload: boolean
}
export default defineComponent({
@@ -239,13 +280,16 @@ export default defineComponent({
components: {
NcCheckboxRadioSwitch,
NcSettingsSelectGroup,
+ NcNoteCard,
NcTextArea,
NcTextField,
SelectSharingPermissions,
},
data() {
+ const settingsData = loadState<IShareSettings>('settings', 'sharingSettings')
return {
- settingsData: loadState<IShareSettings>('settings', 'sharingSettings'),
+ settingsData,
+ publicShareDisclaimerEnabled: settingsData.publicShareDisclaimerText !== '',
}
},
computed: {
@@ -264,26 +308,24 @@ export default defineComponent({
},
})
},
- publicShareDisclaimerEnabled: {
- get() {
- return typeof this.settingsData.publicShareDisclaimerText === 'string'
- },
- set(value) {
- if (value) {
- this.settingsData.publicShareDisclaimerText = ''
- } else {
- this.onUpdateDisclaimer()
- }
- },
+ },
+
+ watch: {
+ publicShareDisclaimerEnabled() {
+ // When disabled we just remove the disclaimer content
+ if (this.publicShareDisclaimerEnabled === false) {
+ this.onUpdateDisclaimer('')
+ }
},
},
+
methods: {
t,
- onUpdateDisclaimer: debounce(function(value?: string) {
+ onUpdateDisclaimer: debounce(function(value: string) {
const options = {
success() {
- if (value) {
+ if (value !== '') {
showSuccess(t('settings', 'Changed disclaimer text'))
} else {
showSuccess(t('settings', 'Deleted disclaimer text'))
@@ -293,13 +335,17 @@ export default defineComponent({
showError(t('settings', 'Could not set disclaimer text'))
},
}
- if (!value) {
+ if (value === '') {
window.OCP.AppConfig.deleteKey('core', 'shareapi_public_link_disclaimertext', options)
} else {
window.OCP.AppConfig.setValue('core', 'shareapi_public_link_disclaimertext', value, options)
}
this.settingsData.publicShareDisclaimerText = value
}, 500) as (v?: string) => void,
+ onUpdateExcludeGroups: debounce(function(value: string) {
+ window.OCP.AppConfig.setValue('core', 'excludeGroups', value)
+ this.settings.excludeGroups = value
+ }, 500) as (v?: string) => void,
},
})
</script>
@@ -342,6 +388,10 @@ export default defineComponent({
width: 100%;
}
}
+
+ & &__note {
+ margin: 2px 0;
+ }
}
@media only screen and (max-width: 350px) {