2018-10-08 08:03:22 -04:00
< template >
2023-07-22 20:03:13 -04:00
< NcSettingsSection : name = "t('settings', 'Two-Factor Authentication')"
2022-05-19 13:09:12 -04:00
: description = "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.')"
: doc - url = "twoFactorAdminDoc" >
2018-10-08 08:03:22 -04:00
< p v-if = "loading" >
2019-09-25 12:19:42 -04:00
< span class = "icon-loading-small two-factor-loading" / >
2018-10-08 08:03:22 -04:00
< span > { { t ( 'settings' , 'Enforce two-factor authentication' ) } } < / span >
< / p >
2022-08-22 08:29:58 -04:00
< NcCheckboxRadioSwitch v -else
2022-05-19 13:09:12 -04:00
id = "two-factor-enforced"
: checked . sync = "enforced"
type = "switch" >
{ { t ( 'settings' , 'Enforce two-factor authentication' ) } }
2022-08-22 08:29:58 -04:00
< / NcCheckboxRadioSwitch >
2019-03-15 07:28:56 -04:00
< 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.' ) } }
2022-05-19 13:09:12 -04:00
< p class = "top-margin" >
2020-02-22 12:29:40 -05:00
{ { t ( 'settings' , 'Two-factor authentication is enforced for all members of the following groups.' ) } }
2019-03-15 07:28:56 -04:00
< / p >
< p >
2023-05-16 06:11:03 -04:00
< label for = "enforcedGroups" >
< span > { { t ( 'settings' , 'Enforced groups' ) } } < / span >
< / label >
2023-07-25 08:47:27 -04:00
< NcSelect v-model = "enforcedGroups"
input - id = "enforcedGroups"
2019-09-25 12:19:42 -04:00
: options = "groups"
: disabled = "loading"
: multiple = "true"
: loading = "loadingGroups"
: close - on - select = "false"
2023-05-16 06:11:03 -04:00
@ search = "searchGroup" / >
2019-03-15 07:28:56 -04:00
< / p >
2022-05-19 13:09:12 -04:00
< p class = "top-margin" >
2020-02-22 12:29:40 -05:00
{ { t ( 'settings' , 'Two-factor authentication is not enforced for members of the following groups.' ) } }
2019-03-15 07:28:56 -04:00
< / p >
< p >
2023-05-16 06:11:03 -04:00
< label for = "excludedGroups" >
< span > { { t ( 'settings' , 'Excluded groups' ) } } < / span >
< / label >
2023-07-25 08:47:27 -04:00
< NcSelect v-model = "excludedGroups"
input - id = "excludedGroups"
2019-09-25 12:19:42 -04:00
: options = "groups"
: disabled = "loading"
: multiple = "true"
: loading = "loadingGroups"
: close - on - select = "false"
2023-05-16 06:11:03 -04:00
@ search = "searchGroup" / >
2019-03-15 07:28:56 -04:00
< / p >
2022-05-19 13:09:12 -04:00
< p class = "top-margin" >
2019-03-15 07:28:56 -04:00
< 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 >
2022-05-19 13:09:12 -04:00
< p class = "top-margin" >
2022-08-22 08:29:58 -04:00
< NcButton v-if = "dirty"
2022-02-24 08:11:02 -05:00
type = "primary"
2019-09-25 12:19:42 -04:00
: disabled = "loading"
@ click = "saveChanges" >
2018-10-11 06:20:18 -04:00
{ { t ( 'settings' , 'Save changes' ) } }
2022-08-22 08:29:58 -04:00
< / NcButton >
2018-10-11 06:20:18 -04:00
< / p >
2022-08-22 08:29:58 -04:00
< / NcSettingsSection >
2018-10-08 08:03:22 -04:00
< / template >
< script >
2019-10-04 06:17:09 -04:00
import axios from '@nextcloud/axios'
2023-05-16 06:11:03 -04:00
import NcSelect from '@nextcloud/vue/dist/Components/NcSelect.js'
2023-03-23 02:38:34 -04:00
import NcButton from '@nextcloud/vue/dist/Components/NcButton.js'
import NcCheckboxRadioSwitch from '@nextcloud/vue/dist/Components/NcCheckboxRadioSwitch.js'
import NcSettingsSection from '@nextcloud/vue/dist/Components/NcSettingsSection.js'
2022-05-19 13:09:12 -04:00
import { loadState } from '@nextcloud/initial-state'
2022-02-24 08:11:02 -05:00
2023-05-17 12:56:50 -04:00
import sortedUniq from 'lodash/sortedUniq.js'
import uniq from 'lodash/uniq.js'
import debounce from 'lodash/debounce.js'
2020-05-08 04:01:54 -04:00
import { generateUrl , generateOcsUrl } from '@nextcloud/router'
2018-10-08 08:03:22 -04:00
2019-09-25 12:19:42 -04:00
export default {
name : 'AdminTwoFactor' ,
components : {
2023-05-16 06:11:03 -04:00
NcSelect ,
2022-08-22 08:29:58 -04:00
NcButton ,
NcCheckboxRadioSwitch ,
NcSettingsSection ,
2019-09-25 12:19:42 -04:00
} ,
data ( ) {
return {
loading : false ,
dirty : false ,
groups : [ ] ,
2019-11-13 07:05:10 -05:00
loadingGroups : false ,
2022-05-19 13:09:12 -04:00
twoFactorAdminDoc : loadState ( 'settings' , 'two-factor-admin-doc' ) ,
2019-09-25 12:19:42 -04:00
}
} ,
computed : {
enforced : {
2020-07-31 03:40:53 -04:00
get ( ) {
2019-09-25 12:19:42 -04:00
return this . $store . state . enforced
} ,
2020-07-31 03:40:53 -04:00
set ( val ) {
2019-09-25 12:19:42 -04:00
this . dirty = true
this . $store . commit ( 'setEnforced' , val )
2019-11-13 07:05:10 -05:00
} ,
2018-10-08 08:03:22 -04:00
} ,
2019-09-25 12:19:42 -04:00
enforcedGroups : {
2020-07-31 03:40:53 -04:00
get ( ) {
2019-09-25 12:19:42 -04:00
return this . $store . state . enforcedGroups
2019-03-15 07:28:56 -04:00
} ,
2020-07-31 03:40:53 -04:00
set ( val ) {
2019-09-25 12:19:42 -04:00
this . dirty = true
this . $store . commit ( 'setEnforcedGroups' , val )
2019-11-13 07:05:10 -05:00
} ,
2019-01-10 10:04:13 -05:00
} ,
2019-09-25 12:19:42 -04:00
excludedGroups : {
2020-07-31 03:40:53 -04:00
get ( ) {
2019-09-25 12:19:42 -04:00
return this . $store . state . excludedGroups
} ,
2020-07-31 03:40:53 -04:00
set ( val ) {
2019-09-25 12:19:42 -04:00
this . dirty = true
this . $store . commit ( 'setExcludedGroups' , val )
2019-11-13 07:05:10 -05:00
} ,
} ,
2019-09-25 12:19:42 -04:00
} ,
mounted ( ) {
// Groups are loaded dynamically, but the assigned ones *should*
// be valid groups, so let's add them as initial state
2023-05-16 18:50:25 -04:00
this . groups = sortedUniq ( uniq ( this . enforcedGroups . concat ( this . excludedGroups ) ) )
2019-02-27 07:57:18 -05:00
2019-09-25 12:19:42 -04:00
// Populate the groups with a first set so the dropdown is not empty
// when opening the page the first time
this . searchGroup ( '' )
} ,
methods : {
2023-05-16 18:50:25 -04:00
searchGroup : debounce ( function ( query ) {
2019-09-25 12:19:42 -04:00
this . loadingGroups = true
2021-07-15 08:46:14 -04:00
axios . get ( generateOcsUrl ( 'cloud/groups?offset=0&search={query}&limit=20' , { query } ) )
2019-09-25 12:19:42 -04:00
. then ( res => res . data . ocs )
. then ( ocs => ocs . data . groups )
2023-05-16 18:50:25 -04:00
. then ( groups => { this . groups = sortedUniq ( uniq ( this . groups . concat ( groups ) ) ) } )
2019-09-25 12:19:42 -04:00
. catch ( err => console . error ( 'could not search groups' , err ) )
. then ( ( ) => { this . loadingGroups = false } )
} , 500 ) ,
2018-10-11 06:20:18 -04:00
2019-09-25 12:19:42 -04:00
saveChanges ( ) {
this . loading = true
2018-10-11 06:20:18 -04:00
2019-09-25 12:19:42 -04:00
const data = {
enforced : this . enforced ,
enforcedGroups : this . enforcedGroups ,
2019-11-13 07:05:10 -05:00
excludedGroups : this . excludedGroups ,
2018-10-08 08:03:22 -04:00
}
2020-05-08 04:01:54 -04:00
axios . put ( generateUrl ( '/settings/api/admin/twofactorauth' ) , data )
2019-09-25 12:19:42 -04:00
. 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 } )
2019-11-13 07:05:10 -05:00
} ,
} ,
2019-09-25 12:19:42 -04:00
}
2018-10-08 08:03:22 -04:00
< / script >
2022-05-19 13:09:12 -04:00
< style scoped >
2018-10-08 08:03:22 -04:00
. two - factor - loading {
display : inline - block ;
vertical - align : sub ;
margin - left : - 2 px ;
margin - right : 1 px ;
}
2022-05-19 13:09:12 -04:00
. top - margin {
margin - top : 0.5 rem ;
}
2018-11-04 18:19:18 -05:00
< / style >