2022-01-29 00:00:11 +03:00
import $ from 'jquery' ;
2024-07-07 18:32:30 +03:00
import { checkAppUrl } from '../common-page.ts' ;
import { hideElem , showElem , toggleElem } from '../../utils/dom.ts' ;
import { POST } from '../../modules/fetch.ts' ;
2022-01-29 00:00:11 +03:00
2024-02-25 15:36:11 +03:00
const { appSubUrl } = window . config ;
2021-10-16 20:28:04 +03:00
2024-11-11 14:13:57 +03:00
function onSecurityProtocolChange ( ) : void {
if ( Number ( document . querySelector < HTMLInputElement > ( '#security_protocol' ) ? . value ) > 0 ) {
2024-03-27 13:45:05 +03:00
showElem ( '.has-tls' ) ;
} else {
hideElem ( '.has-tls' ) ;
}
}
2024-11-11 14:13:57 +03:00
export function initAdminCommon ( ) : void {
2024-03-27 13:45:05 +03:00
if ( ! document . querySelector ( '.page-content.admin' ) ) return ;
2021-10-16 20:28:04 +03:00
2023-02-09 19:14:45 +03:00
// check whether appUrl(ROOT_URL) is correct, if not, show an error message
checkAppUrl ( ) ;
2021-10-16 20:28:04 +03:00
// New user
if ( $ ( '.admin.new.user' ) . length > 0 || $ ( '.admin.edit.user' ) . length > 0 ) {
2024-11-11 14:13:57 +03:00
document . querySelector < HTMLInputElement > ( '#login_type' ) ? . addEventListener ( 'change' , function ( ) {
if ( this . value ? . startsWith ( '0' ) ) {
document . querySelector < HTMLInputElement > ( '#user_name' ) ? . removeAttribute ( 'disabled' ) ;
document . querySelector < HTMLInputElement > ( '#login_name' ) ? . removeAttribute ( 'required' ) ;
2024-03-26 22:38:37 +03:00
hideElem ( '.non-local' ) ;
showElem ( '.local' ) ;
2024-11-11 14:13:57 +03:00
document . querySelector < HTMLInputElement > ( '#user_name' ) ? . focus ( ) ;
2021-10-16 20:28:04 +03:00
2024-03-27 13:45:05 +03:00
if ( this . getAttribute ( 'data-password' ) === 'required' ) {
2024-06-10 23:49:33 +03:00
document . querySelector ( '#password' ) ? . setAttribute ( 'required' , 'required' ) ;
2021-10-16 20:28:04 +03:00
}
} else {
2024-11-11 14:13:57 +03:00
if ( document . querySelector < HTMLDivElement > ( '.admin.edit.user' ) ) {
document . querySelector < HTMLInputElement > ( '#user_name' ) ? . setAttribute ( 'disabled' , 'disabled' ) ;
2021-10-16 20:28:04 +03:00
}
2024-11-11 14:13:57 +03:00
document . querySelector < HTMLInputElement > ( '#login_name' ) ? . setAttribute ( 'required' , 'required' ) ;
2024-03-26 22:38:37 +03:00
showElem ( '.non-local' ) ;
hideElem ( '.local' ) ;
2024-11-11 14:13:57 +03:00
document . querySelector < HTMLInputElement > ( '#login_name' ) ? . focus ( ) ;
2021-10-16 20:28:04 +03:00
2024-11-11 14:13:57 +03:00
document . querySelector < HTMLInputElement > ( '#password' ) ? . removeAttribute ( 'required' ) ;
2021-10-16 20:28:04 +03:00
}
} ) ;
}
function onUsePagedSearchChange() {
2024-11-11 14:13:57 +03:00
const searchPageSizeElements = document . querySelectorAll < HTMLDivElement > ( '.search-page-size' ) ;
if ( document . querySelector < HTMLInputElement > ( '#use_paged_search' ) . checked ) {
2023-02-22 18:26:02 +03:00
showElem ( '.search-page-size' ) ;
2024-03-27 13:45:05 +03:00
for ( const el of searchPageSizeElements ) {
el . querySelector ( 'input' ) ? . setAttribute ( 'required' , 'required' ) ;
}
2021-10-16 20:28:04 +03:00
} else {
2023-02-22 18:26:02 +03:00
hideElem ( '.search-page-size' ) ;
2024-03-27 13:45:05 +03:00
for ( const el of searchPageSizeElements ) {
el . querySelector ( 'input' ) ? . removeAttribute ( 'required' ) ;
}
2021-10-16 20:28:04 +03:00
}
}
2024-11-11 14:13:57 +03:00
function onOAuth2Change ( applyDefaultValues : boolean ) {
2024-03-26 22:38:37 +03:00
hideElem ( '.open_id_connect_auto_discovery_url, .oauth2_use_custom_url' ) ;
2024-11-11 14:13:57 +03:00
for ( const input of document . querySelectorAll < HTMLInputElement > ( '.open_id_connect_auto_discovery_url input[required]' ) ) {
2024-03-27 13:45:05 +03:00
input . removeAttribute ( 'required' ) ;
}
2021-10-16 20:28:04 +03:00
2024-11-11 14:13:57 +03:00
const provider = document . querySelector < HTMLInputElement > ( '#oauth2_provider' ) . value ;
2021-10-16 20:28:04 +03:00
switch ( provider ) {
case 'openidConnect' :
2024-11-11 14:13:57 +03:00
document . querySelector < HTMLInputElement > ( '.open_id_connect_auto_discovery_url input' ) . setAttribute ( 'required' , 'required' ) ;
2024-03-26 22:38:37 +03:00
showElem ( '.open_id_connect_auto_discovery_url' ) ;
2021-10-16 20:28:04 +03:00
break ;
2024-06-04 18:06:21 +03:00
default : {
2024-11-11 14:13:57 +03:00
const elProviderCustomUrlSettings = document . querySelector < HTMLInputElement > ( ` # ${ provider } _customURLSettings ` ) ;
2024-06-04 18:06:21 +03:00
if ( ! elProviderCustomUrlSettings ) break ; // some providers do not have custom URL settings
const couldChangeCustomURLs = elProviderCustomUrlSettings . getAttribute ( 'data-available' ) === 'true' ;
const mustProvideCustomURLs = elProviderCustomUrlSettings . getAttribute ( 'data-required' ) === 'true' ;
if ( couldChangeCustomURLs ) {
showElem ( '.oauth2_use_custom_url' ) ; // show the checkbox
2021-10-16 20:28:04 +03:00
}
2024-06-04 18:06:21 +03:00
if ( mustProvideCustomURLs ) {
2024-11-11 14:13:57 +03:00
document . querySelector < HTMLInputElement > ( '#oauth2_use_custom_url' ) . checked = true ; // make the checkbox checked
2021-10-16 20:28:04 +03:00
}
2024-06-04 18:06:21 +03:00
break ;
}
2021-10-16 20:28:04 +03:00
}
onOAuth2UseCustomURLChange ( applyDefaultValues ) ;
}
function onOAuth2UseCustomURLChange ( applyDefaultValues ) {
2024-11-11 14:13:57 +03:00
const provider = document . querySelector < HTMLInputElement > ( '#oauth2_provider' ) . value ;
2024-03-26 22:38:37 +03:00
hideElem ( '.oauth2_use_custom_url_field' ) ;
2024-11-11 14:13:57 +03:00
for ( const input of document . querySelectorAll < HTMLInputElement > ( '.oauth2_use_custom_url_field input[required]' ) ) {
2024-03-27 13:45:05 +03:00
input . removeAttribute ( 'required' ) ;
}
2021-10-16 20:28:04 +03:00
2024-06-04 18:06:21 +03:00
const elProviderCustomUrlSettings = document . querySelector ( ` # ${ provider } _customURLSettings ` ) ;
2024-11-11 14:13:57 +03:00
if ( elProviderCustomUrlSettings && document . querySelector < HTMLInputElement > ( '#oauth2_use_custom_url' ) . checked ) {
2021-10-16 20:28:04 +03:00
for ( const custom of [ 'token_url' , 'auth_url' , 'profile_url' , 'email_url' , 'tenant' ] ) {
if ( applyDefaultValues ) {
2024-11-11 14:13:57 +03:00
document . querySelector < HTMLInputElement > ( ` #oauth2_ ${ custom } ` ) . value = document . querySelector < HTMLInputElement > ( ` # ${ provider } _ ${ custom } ` ) . value ;
2021-10-16 20:28:04 +03:00
}
2024-06-10 23:49:33 +03:00
const customInput = document . querySelector ( ` # ${ provider } _ ${ custom } ` ) ;
2024-06-04 18:06:21 +03:00
if ( customInput && customInput . getAttribute ( 'data-available' ) === 'true' ) {
2024-03-27 13:45:05 +03:00
for ( const input of document . querySelectorAll ( ` .oauth2_ ${ custom } input ` ) ) {
input . setAttribute ( 'required' , 'required' ) ;
}
showElem ( ` .oauth2_ ${ custom } ` ) ;
2021-10-16 20:28:04 +03:00
}
}
}
}
2022-02-11 17:24:58 +03:00
function onEnableLdapGroupsChange() {
2024-11-11 14:13:57 +03:00
const checked = document . querySelector < HTMLInputElement > ( '.js-ldap-group-toggle' ) ? . checked ;
toggleElem ( document . querySelector ( '#ldap-group-options' ) , checked ) ;
2021-10-16 20:28:04 +03:00
}
// New authentication
2024-11-11 14:13:57 +03:00
if ( document . querySelector < HTMLDivElement > ( '.admin.new.authentication' ) ) {
document . querySelector < HTMLInputElement > ( '#auth_type' ) ? . addEventListener ( 'change' , function ( ) {
2024-03-26 22:38:37 +03:00
hideElem ( '.ldap, .dldap, .smtp, .pam, .oauth2, .has-tls, .search-page-size, .sspi' ) ;
2021-10-16 20:28:04 +03:00
2024-11-11 14:13:57 +03:00
for ( const input of document . querySelectorAll < HTMLInputElement > ( '.ldap input[required], .binddnrequired input[required], .dldap input[required], .smtp input[required], .pam input[required], .oauth2 input[required], .has-tls input[required], .sspi input[required]' ) ) {
2024-03-27 13:45:05 +03:00
input . removeAttribute ( 'required' ) ;
}
2024-11-11 14:13:57 +03:00
document . querySelector < HTMLDivElement > ( '.binddnrequired' ) ? . classList . remove ( 'required' ) ;
2021-10-16 20:28:04 +03:00
2024-03-27 13:45:05 +03:00
const authType = this . value ;
2021-10-16 20:28:04 +03:00
switch ( authType ) {
case '2' : // LDAP
2024-03-26 22:38:37 +03:00
showElem ( '.ldap' ) ;
2024-11-11 14:13:57 +03:00
for ( const input of document . querySelectorAll < HTMLInputElement > ( '.binddnrequired input, .ldap div.required:not(.dldap) input' ) ) {
2024-03-27 13:45:05 +03:00
input . setAttribute ( 'required' , 'required' ) ;
}
2024-03-27 19:14:18 +03:00
document . querySelector ( '.binddnrequired' ) ? . classList . add ( 'required' ) ;
2021-10-16 20:28:04 +03:00
break ;
case '3' : // SMTP
2024-03-26 22:38:37 +03:00
showElem ( '.smtp' ) ;
showElem ( '.has-tls' ) ;
2024-11-11 14:13:57 +03:00
for ( const input of document . querySelectorAll < HTMLInputElement > ( '.smtp div.required input, .has-tls' ) ) {
2024-03-27 13:45:05 +03:00
input . setAttribute ( 'required' , 'required' ) ;
}
2021-10-16 20:28:04 +03:00
break ;
case '4' : // PAM
2024-03-26 22:38:37 +03:00
showElem ( '.pam' ) ;
2024-11-11 14:13:57 +03:00
for ( const input of document . querySelectorAll < HTMLInputElement > ( '.pam input' ) ) {
2024-03-27 13:45:05 +03:00
input . setAttribute ( 'required' , 'required' ) ;
}
2021-10-16 20:28:04 +03:00
break ;
case '5' : // LDAP
2024-03-26 22:38:37 +03:00
showElem ( '.dldap' ) ;
2024-11-11 14:13:57 +03:00
for ( const input of document . querySelectorAll < HTMLInputElement > ( '.dldap div.required:not(.ldap) input' ) ) {
2024-03-27 13:45:05 +03:00
input . setAttribute ( 'required' , 'required' ) ;
}
2021-10-16 20:28:04 +03:00
break ;
case '6' : // OAuth2
2024-03-26 22:38:37 +03:00
showElem ( '.oauth2' ) ;
2024-11-11 14:13:57 +03:00
for ( const input of document . querySelectorAll < HTMLInputElement > ( '.oauth2 div.required:not(.oauth2_use_custom_url,.oauth2_use_custom_url_field,.open_id_connect_auto_discovery_url) input' ) ) {
2024-03-27 13:45:05 +03:00
input . setAttribute ( 'required' , 'required' ) ;
}
2021-10-16 20:28:04 +03:00
onOAuth2Change ( true ) ;
break ;
case '7' : // SSPI
2024-03-26 22:38:37 +03:00
showElem ( '.sspi' ) ;
2024-11-11 14:13:57 +03:00
for ( const input of document . querySelectorAll < HTMLInputElement > ( '.sspi div.required input' ) ) {
2024-03-27 13:45:05 +03:00
input . setAttribute ( 'required' , 'required' ) ;
}
2021-10-16 20:28:04 +03:00
break ;
}
if ( authType === '2' || authType === '5' ) {
onSecurityProtocolChange ( ) ;
2022-02-11 17:24:58 +03:00
onEnableLdapGroupsChange ( ) ;
2021-10-16 20:28:04 +03:00
}
if ( authType === '2' ) {
onUsePagedSearchChange ( ) ;
}
} ) ;
$ ( '#auth_type' ) . trigger ( 'change' ) ;
2024-11-11 14:13:57 +03:00
document . querySelector < HTMLInputElement > ( '#security_protocol' ) ? . addEventListener ( 'change' , onSecurityProtocolChange ) ;
document . querySelector < HTMLInputElement > ( '#use_paged_search' ) ? . addEventListener ( 'change' , onUsePagedSearchChange ) ;
document . querySelector < HTMLInputElement > ( '#oauth2_provider' ) ? . addEventListener ( 'change' , ( ) = > onOAuth2Change ( true ) ) ;
document . querySelector < HTMLInputElement > ( '#oauth2_use_custom_url' ) ? . addEventListener ( 'change' , ( ) = > onOAuth2UseCustomURLChange ( true ) ) ;
2022-02-11 17:24:58 +03:00
$ ( '.js-ldap-group-toggle' ) . on ( 'change' , onEnableLdapGroupsChange ) ;
2021-10-16 20:28:04 +03:00
}
// Edit authentication
2024-11-11 14:13:57 +03:00
if ( document . querySelector < HTMLDivElement > ( '.admin.edit.authentication' ) ) {
const authType = document . querySelector < HTMLInputElement > ( '#auth_type' ) ? . value ;
2021-10-16 20:28:04 +03:00
if ( authType === '2' || authType === '5' ) {
2024-11-11 14:13:57 +03:00
document . querySelector < HTMLInputElement > ( '#security_protocol' ) ? . addEventListener ( 'change' , onSecurityProtocolChange ) ;
2022-02-11 17:24:58 +03:00
$ ( '.js-ldap-group-toggle' ) . on ( 'change' , onEnableLdapGroupsChange ) ;
onEnableLdapGroupsChange ( ) ;
2021-10-16 20:28:04 +03:00
if ( authType === '2' ) {
2024-11-11 14:13:57 +03:00
document . querySelector < HTMLInputElement > ( '#use_paged_search' ) ? . addEventListener ( 'change' , onUsePagedSearchChange ) ;
2021-10-16 20:28:04 +03:00
}
} else if ( authType === '6' ) {
2024-11-11 14:13:57 +03:00
document . querySelector < HTMLInputElement > ( '#oauth2_provider' ) ? . addEventListener ( 'change' , ( ) = > onOAuth2Change ( true ) ) ;
document . querySelector < HTMLInputElement > ( '#oauth2_use_custom_url' ) ? . addEventListener ( 'change' , ( ) = > onOAuth2UseCustomURLChange ( false ) ) ;
2021-10-16 20:28:04 +03:00
onOAuth2Change ( false ) ;
}
}
2024-11-11 14:13:57 +03:00
if ( document . querySelector < HTMLDivElement > ( '.admin.authentication' ) ) {
2023-06-15 04:12:50 +03:00
$ ( '#auth_name' ) . on ( 'input' , function ( ) {
2023-11-29 04:37:12 +03:00
// appSubUrl is either empty or is a path that starts with `/` and doesn't have a trailing slash.
2024-11-11 14:13:57 +03:00
document . querySelector ( '#oauth2-callback-url' ) . textContent = ` ${ window . location . origin } ${ appSubUrl } /user/oauth2/ ${ encodeURIComponent ( ( this as HTMLInputElement ) . value ) } /callback ` ;
2023-06-15 04:12:50 +03:00
} ) . trigger ( 'input' ) ;
}
2021-10-16 20:28:04 +03:00
// Notice
2024-11-11 14:13:57 +03:00
if ( document . querySelector < HTMLDivElement > ( '.admin.notice' ) ) {
const detailModal = document . querySelector < HTMLDivElement > ( '#detail-modal' ) ;
2021-10-16 20:28:04 +03:00
// Attach view detail modals
$ ( '.view-detail' ) . on ( 'click' , function ( ) {
2024-04-13 10:46:02 +03:00
const description = this . closest ( 'tr' ) . querySelector ( '.notice-description' ) . textContent ;
detailModal . querySelector ( '.content pre' ) . textContent = description ;
$ ( detailModal ) . modal ( 'show' ) ;
2021-10-16 20:28:04 +03:00
return false ;
} ) ;
// Select actions
2024-11-11 14:13:57 +03:00
const checkboxes = document . querySelectorAll < HTMLInputElement > ( '.select.table .ui.checkbox input' ) ;
2024-03-29 07:56:01 +03:00
2021-10-16 20:28:04 +03:00
$ ( '.select.action' ) . on ( 'click' , function ( ) {
switch ( $ ( this ) . data ( 'action' ) ) {
case 'select-all' :
2024-03-29 07:56:01 +03:00
for ( const checkbox of checkboxes ) {
checkbox . checked = true ;
}
2021-10-16 20:28:04 +03:00
break ;
case 'deselect-all' :
2024-03-29 07:56:01 +03:00
for ( const checkbox of checkboxes ) {
checkbox . checked = false ;
}
2021-10-16 20:28:04 +03:00
break ;
case 'inverse' :
2024-03-29 07:56:01 +03:00
for ( const checkbox of checkboxes ) {
checkbox . checked = ! checkbox . checked ;
}
2021-10-16 20:28:04 +03:00
break ;
}
} ) ;
2024-11-11 14:13:57 +03:00
document . querySelector < HTMLButtonElement > ( '#delete-selection' ) ? . addEventListener ( 'click' , async function ( e ) {
2023-03-14 06:34:09 +03:00
e . preventDefault ( ) ;
2024-03-27 19:14:18 +03:00
this . classList . add ( 'is-loading' , 'disabled' ) ;
2024-02-25 15:36:11 +03:00
const data = new FormData ( ) ;
2024-03-29 07:56:01 +03:00
for ( const checkbox of checkboxes ) {
if ( checkbox . checked ) {
data . append ( 'ids[]' , checkbox . closest ( '.ui.checkbox' ) . getAttribute ( 'data-id' ) ) ;
2021-10-16 20:28:04 +03:00
}
2024-03-29 07:56:01 +03:00
}
2024-03-27 19:14:18 +03:00
await POST ( this . getAttribute ( 'data-link' ) , { data } ) ;
window . location . href = this . getAttribute ( 'data-redirect' ) ;
2021-10-16 20:28:04 +03:00
} ) ;
}
}