diff options
Diffstat (limited to 'apps/settings/src/components/AdminSettingsSharingForm.vue')
-rw-r--r-- | apps/settings/src/components/AdminSettingsSharingForm.vue | 176 |
1 files changed, 114 insertions, 62 deletions
diff --git a/apps/settings/src/components/AdminSettingsSharingForm.vue b/apps/settings/src/components/AdminSettingsSharingForm.vue index 2165303349f..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"> @@ -125,7 +164,7 @@ </NcCheckboxRadioSwitch> <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> @@ -162,7 +201,7 @@ <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'" + <div v-if="publicShareDisclaimerEnabled" aria-describedby="settings-sharing-privary-related-disclaimer-hint" class="sharing__sub-section"> <NcTextArea class="sharing__input" @@ -184,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 @@ -206,6 +245,7 @@ interface IShareSettings { allowPublicUpload: boolean allowResharing: boolean allowShareDialogUserEnumeration: boolean + allowFederationOnPublicShares: boolean restrictUserEnumerationToGroup: boolean restrictUserEnumerationToPhone: boolean restrictUserEnumerationFullMatch: boolean @@ -213,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 @@ -230,6 +271,8 @@ interface IShareSettings { defaultRemoteExpireDate: boolean remoteExpireAfterNDays: string enforceRemoteExpireDate: boolean + allowCustomTokens: boolean + allowViewWithoutDownload: boolean } export default defineComponent({ @@ -237,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: { @@ -262,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')) @@ -291,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> @@ -340,6 +388,10 @@ export default defineComponent({ width: 100%; } } + + & &__note { + margin: 2px 0; + } } @media only screen and (max-width: 350px) { |