123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165 |
- <template>
- <div>
- <p class="settings-hint">
- {{ t('settings', 'Two-factor authentication can be enforced for all users and specific groups. If they do not have a two-factor provider configured, they will be unable to log into the system.') }}
- </p>
- <p v-if="loading">
- <span class="icon-loading-small two-factor-loading" />
- <span>{{ t('settings', 'Enforce two-factor authentication') }}</span>
- </p>
- <p v-else>
- <input id="two-factor-enforced"
- v-model="enforced"
- type="checkbox"
- class="checkbox">
- <label for="two-factor-enforced">{{ t('settings', 'Enforce two-factor authentication') }}</label>
- </p>
- <template v-if="enforced">
- <h3>{{ t('settings', 'Limit to groups') }}</h3>
- {{ t('settings', 'Enforcement of two-factor authentication can be set for certain groups only.') }}
- <p>
- {{ t('settings', 'Two-factor authentication is enforced for all members of the following groups.') }}
- </p>
- <p>
- <Multiselect v-model="enforcedGroups"
- :options="groups"
- :placeholder="t('settings', 'Enforced groups')"
- :disabled="loading"
- :multiple="true"
- :searchable="true"
- :loading="loadingGroups"
- :show-no-options="false"
- :close-on-select="false"
- @search-change="searchGroup" />
- </p>
- <p>
- {{ t('settings', 'Two-factor authentication is not enforced for members of the following groups.') }}
- </p>
- <p>
- <Multiselect v-model="excludedGroups"
- :options="groups"
- :placeholder="t('settings', 'Excluded groups')"
- :disabled="loading"
- :multiple="true"
- :searchable="true"
- :loading="loadingGroups"
- :show-no-options="false"
- :close-on-select="false"
- @search-change="searchGroup" />
- </p>
- <p>
- <em>
- <!-- this text is also found in the documentation. update it there as well if it ever changes -->
- {{ t('settings', 'When groups are selected/excluded, they use the following logic to determine if a user has 2FA enforced: If no groups are selected, 2FA is enabled for everyone except members of the excluded groups. If groups are selected, 2FA is enabled for all members of these. If a user is both in a selected and excluded group, the selected takes precedence and 2FA is enforced.') }}
- </em>
- </p>
- </template>
- <p>
- <button v-if="dirty"
- class="button primary"
- :disabled="loading"
- @click="saveChanges">
- {{ t('settings', 'Save changes') }}
- </button>
- </p>
- </div>
- </template>
- <script>
- import axios from '@nextcloud/axios'
- import { Multiselect } from 'nextcloud-vue'
- import _ from 'lodash'
- export default {
- name: 'AdminTwoFactor',
- components: {
- Multiselect,
- },
- data() {
- return {
- loading: false,
- dirty: false,
- groups: [],
- loadingGroups: false,
- }
- },
- computed: {
- enforced: {
- get: function() {
- return this.$store.state.enforced
- },
- set: function(val) {
- this.dirty = true
- this.$store.commit('setEnforced', val)
- },
- },
- enforcedGroups: {
- get: function() {
- return this.$store.state.enforcedGroups
- },
- set: function(val) {
- this.dirty = true
- this.$store.commit('setEnforcedGroups', val)
- },
- },
- excludedGroups: {
- get: function() {
- return this.$store.state.excludedGroups
- },
- set: function(val) {
- this.dirty = true
- this.$store.commit('setExcludedGroups', val)
- },
- },
- },
- mounted() {
- // Groups are loaded dynamically, but the assigned ones *should*
- // be valid groups, so let's add them as initial state
- this.groups = _.sortedUniq(_.uniq(this.enforcedGroups.concat(this.excludedGroups)))
- // Populate the groups with a first set so the dropdown is not empty
- // when opening the page the first time
- this.searchGroup('')
- },
- methods: {
- searchGroup: _.debounce(function(query) {
- this.loadingGroups = true
- axios.get(OC.linkToOCS(`cloud/groups?offset=0&search=${encodeURIComponent(query)}&limit=20`, 2))
- .then(res => res.data.ocs)
- .then(ocs => ocs.data.groups)
- .then(groups => { this.groups = _.sortedUniq(_.uniq(this.groups.concat(groups))) })
- .catch(err => console.error('could not search groups', err))
- .then(() => { this.loadingGroups = false })
- }, 500),
- saveChanges() {
- this.loading = true
- const data = {
- enforced: this.enforced,
- enforcedGroups: this.enforcedGroups,
- excludedGroups: this.excludedGroups,
- }
- axios.put(OC.generateUrl('/settings/api/admin/twofactorauth'), data)
- .then(resp => resp.data)
- .then(state => {
- this.state = state
- this.dirty = false
- })
- .catch(err => {
- console.error('could not save changes', err)
- })
- .then(() => { this.loading = false })
- },
- },
- }
- </script>
- <style>
- .two-factor-loading {
- display: inline-block;
- vertical-align: sub;
- margin-left: -2px;
- margin-right: 1px;
- }
- </style>
|