code.gitea.io/gitea@v1.22.3/web_src/js/features/admin/common.js (about) 1 import $ from 'jquery'; 2 import {checkAppUrl} from '../common-global.js'; 3 import {hideElem, showElem, toggleElem} from '../../utils/dom.js'; 4 import {POST} from '../../modules/fetch.js'; 5 6 const {appSubUrl} = window.config; 7 8 function onSecurityProtocolChange() { 9 if (Number(document.getElementById('security_protocol')?.value) > 0) { 10 showElem('.has-tls'); 11 } else { 12 hideElem('.has-tls'); 13 } 14 } 15 16 export function initAdminCommon() { 17 if (!document.querySelector('.page-content.admin')) return; 18 19 // check whether appUrl(ROOT_URL) is correct, if not, show an error message 20 checkAppUrl(); 21 22 // New user 23 if ($('.admin.new.user').length > 0 || $('.admin.edit.user').length > 0) { 24 document.getElementById('login_type')?.addEventListener('change', function () { 25 if (this.value?.substring(0, 1) === '0') { 26 document.getElementById('user_name')?.removeAttribute('disabled'); 27 document.getElementById('login_name')?.removeAttribute('required'); 28 hideElem('.non-local'); 29 showElem('.local'); 30 document.getElementById('user_name')?.focus(); 31 32 if (this.getAttribute('data-password') === 'required') { 33 document.getElementById('password')?.setAttribute('required', 'required'); 34 } 35 } else { 36 if (document.querySelector('.admin.edit.user')) { 37 document.getElementById('user_name')?.setAttribute('disabled', 'disabled'); 38 } 39 document.getElementById('login_name')?.setAttribute('required', 'required'); 40 showElem('.non-local'); 41 hideElem('.local'); 42 document.getElementById('login_name')?.focus(); 43 44 document.getElementById('password')?.removeAttribute('required'); 45 } 46 }); 47 } 48 49 function onUsePagedSearchChange() { 50 const searchPageSizeElements = document.querySelectorAll('.search-page-size'); 51 if (document.getElementById('use_paged_search').checked) { 52 showElem('.search-page-size'); 53 for (const el of searchPageSizeElements) { 54 el.querySelector('input')?.setAttribute('required', 'required'); 55 } 56 } else { 57 hideElem('.search-page-size'); 58 for (const el of searchPageSizeElements) { 59 el.querySelector('input')?.removeAttribute('required'); 60 } 61 } 62 } 63 64 function onOAuth2Change(applyDefaultValues) { 65 hideElem('.open_id_connect_auto_discovery_url, .oauth2_use_custom_url'); 66 for (const input of document.querySelectorAll('.open_id_connect_auto_discovery_url input[required]')) { 67 input.removeAttribute('required'); 68 } 69 70 const provider = document.getElementById('oauth2_provider').value; 71 switch (provider) { 72 case 'openidConnect': 73 document.querySelector('.open_id_connect_auto_discovery_url input').setAttribute('required', 'required'); 74 showElem('.open_id_connect_auto_discovery_url'); 75 break; 76 default: { 77 const elProviderCustomUrlSettings = document.querySelector(`#${provider}_customURLSettings`); 78 if (!elProviderCustomUrlSettings) break; // some providers do not have custom URL settings 79 const couldChangeCustomURLs = elProviderCustomUrlSettings.getAttribute('data-available') === 'true'; 80 const mustProvideCustomURLs = elProviderCustomUrlSettings.getAttribute('data-required') === 'true'; 81 if (couldChangeCustomURLs) { 82 showElem('.oauth2_use_custom_url'); // show the checkbox 83 } 84 if (mustProvideCustomURLs) { 85 document.querySelector('#oauth2_use_custom_url').checked = true; // make the checkbox checked 86 } 87 break; 88 } 89 } 90 onOAuth2UseCustomURLChange(applyDefaultValues); 91 } 92 93 function onOAuth2UseCustomURLChange(applyDefaultValues) { 94 const provider = document.getElementById('oauth2_provider').value; 95 hideElem('.oauth2_use_custom_url_field'); 96 for (const input of document.querySelectorAll('.oauth2_use_custom_url_field input[required]')) { 97 input.removeAttribute('required'); 98 } 99 100 const elProviderCustomUrlSettings = document.querySelector(`#${provider}_customURLSettings`); 101 if (elProviderCustomUrlSettings && document.getElementById('oauth2_use_custom_url').checked) { 102 for (const custom of ['token_url', 'auth_url', 'profile_url', 'email_url', 'tenant']) { 103 if (applyDefaultValues) { 104 document.getElementById(`oauth2_${custom}`).value = document.getElementById(`${provider}_${custom}`).value; 105 } 106 const customInput = document.getElementById(`${provider}_${custom}`); 107 if (customInput && customInput.getAttribute('data-available') === 'true') { 108 for (const input of document.querySelectorAll(`.oauth2_${custom} input`)) { 109 input.setAttribute('required', 'required'); 110 } 111 showElem(`.oauth2_${custom}`); 112 } 113 } 114 } 115 } 116 117 function onEnableLdapGroupsChange() { 118 toggleElem(document.getElementById('ldap-group-options'), $('.js-ldap-group-toggle')[0].checked); 119 } 120 121 // New authentication 122 if (document.querySelector('.admin.new.authentication')) { 123 document.getElementById('auth_type')?.addEventListener('change', function () { 124 hideElem('.ldap, .dldap, .smtp, .pam, .oauth2, .has-tls, .search-page-size, .sspi'); 125 126 for (const input of document.querySelectorAll('.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]')) { 127 input.removeAttribute('required'); 128 } 129 130 document.querySelector('.binddnrequired')?.classList.remove('required'); 131 132 const authType = this.value; 133 switch (authType) { 134 case '2': // LDAP 135 showElem('.ldap'); 136 for (const input of document.querySelectorAll('.binddnrequired input, .ldap div.required:not(.dldap) input')) { 137 input.setAttribute('required', 'required'); 138 } 139 document.querySelector('.binddnrequired')?.classList.add('required'); 140 break; 141 case '3': // SMTP 142 showElem('.smtp'); 143 showElem('.has-tls'); 144 for (const input of document.querySelectorAll('.smtp div.required input, .has-tls')) { 145 input.setAttribute('required', 'required'); 146 } 147 break; 148 case '4': // PAM 149 showElem('.pam'); 150 for (const input of document.querySelectorAll('.pam input')) { 151 input.setAttribute('required', 'required'); 152 } 153 break; 154 case '5': // LDAP 155 showElem('.dldap'); 156 for (const input of document.querySelectorAll('.dldap div.required:not(.ldap) input')) { 157 input.setAttribute('required', 'required'); 158 } 159 break; 160 case '6': // OAuth2 161 showElem('.oauth2'); 162 for (const input of document.querySelectorAll('.oauth2 div.required:not(.oauth2_use_custom_url,.oauth2_use_custom_url_field,.open_id_connect_auto_discovery_url) input')) { 163 input.setAttribute('required', 'required'); 164 } 165 onOAuth2Change(true); 166 break; 167 case '7': // SSPI 168 showElem('.sspi'); 169 for (const input of document.querySelectorAll('.sspi div.required input')) { 170 input.setAttribute('required', 'required'); 171 } 172 break; 173 } 174 if (authType === '2' || authType === '5') { 175 onSecurityProtocolChange(); 176 onEnableLdapGroupsChange(); 177 } 178 if (authType === '2') { 179 onUsePagedSearchChange(); 180 } 181 }); 182 $('#auth_type').trigger('change'); 183 document.getElementById('security_protocol')?.addEventListener('change', onSecurityProtocolChange); 184 document.getElementById('use_paged_search')?.addEventListener('change', onUsePagedSearchChange); 185 document.getElementById('oauth2_provider')?.addEventListener('change', () => onOAuth2Change(true)); 186 document.getElementById('oauth2_use_custom_url')?.addEventListener('change', () => onOAuth2UseCustomURLChange(true)); 187 $('.js-ldap-group-toggle').on('change', onEnableLdapGroupsChange); 188 } 189 // Edit authentication 190 if (document.querySelector('.admin.edit.authentication')) { 191 const authType = document.getElementById('auth_type')?.value; 192 if (authType === '2' || authType === '5') { 193 document.getElementById('security_protocol')?.addEventListener('change', onSecurityProtocolChange); 194 $('.js-ldap-group-toggle').on('change', onEnableLdapGroupsChange); 195 onEnableLdapGroupsChange(); 196 if (authType === '2') { 197 document.getElementById('use_paged_search')?.addEventListener('change', onUsePagedSearchChange); 198 } 199 } else if (authType === '6') { 200 document.getElementById('oauth2_provider')?.addEventListener('change', () => onOAuth2Change(true)); 201 document.getElementById('oauth2_use_custom_url')?.addEventListener('change', () => onOAuth2UseCustomURLChange(false)); 202 onOAuth2Change(false); 203 } 204 } 205 206 if (document.querySelector('.admin.authentication')) { 207 $('#auth_name').on('input', function () { 208 // appSubUrl is either empty or is a path that starts with `/` and doesn't have a trailing slash. 209 document.getElementById('oauth2-callback-url').textContent = `${window.location.origin}${appSubUrl}/user/oauth2/${encodeURIComponent(this.value)}/callback`; 210 }).trigger('input'); 211 } 212 213 // Notice 214 if (document.querySelector('.admin.notice')) { 215 const detailModal = document.getElementById('detail-modal'); 216 217 // Attach view detail modals 218 $('.view-detail').on('click', function () { 219 const description = this.closest('tr').querySelector('.notice-description').textContent; 220 detailModal.querySelector('.content pre').textContent = description; 221 $(detailModal).modal('show'); 222 return false; 223 }); 224 225 // Select actions 226 const checkboxes = document.querySelectorAll('.select.table .ui.checkbox input'); 227 228 $('.select.action').on('click', function () { 229 switch ($(this).data('action')) { 230 case 'select-all': 231 for (const checkbox of checkboxes) { 232 checkbox.checked = true; 233 } 234 break; 235 case 'deselect-all': 236 for (const checkbox of checkboxes) { 237 checkbox.checked = false; 238 } 239 break; 240 case 'inverse': 241 for (const checkbox of checkboxes) { 242 checkbox.checked = !checkbox.checked; 243 } 244 break; 245 } 246 }); 247 document.getElementById('delete-selection')?.addEventListener('click', async function (e) { 248 e.preventDefault(); 249 this.classList.add('is-loading', 'disabled'); 250 const data = new FormData(); 251 for (const checkbox of checkboxes) { 252 if (checkbox.checked) { 253 data.append('ids[]', checkbox.closest('.ui.checkbox').getAttribute('data-id')); 254 } 255 } 256 await POST(this.getAttribute('data-link'), {data}); 257 window.location.href = this.getAttribute('data-redirect'); 258 }); 259 } 260 }