/* global jQuery */ import { Controller } from 'stimulus'; import { adminModal } from '../adminModal'; const recaptchaFields = document.getElementById('recaptchaContainer'); const emailRegistrationCheckbox = document.getElementById( 'email-registration-checkbox', ); const emailAuthSettingsSection = document.getElementById( 'email-auth-settings-section', ); const emailAuthModalTitle = 'Disable Email address registration'; // TODO: Remove the sentence "You must update site config to save this action!" // once we build more robust flow for Admin/Config const emailAuthModalBody = `
If you disable Email address as a registration option, people cannot create an account with their email address.
However, people who have already created an account using their email address can continue to login.
You must confirm and update site config to save below this action.
`; export default class ConfigController extends Controller { static targets = [ 'authenticationProviders', 'authSectionForm', 'collectiveNoun', 'configModalAnchor', 'emailAuthSettingsBtn', 'enabledIndicator', 'inviteOnlyMode', 'requireCaptchaForEmailPasswordRegistration', ]; // GENERAL FUNCTIONS START // This is a bit of hack because we have to deal with Bootstrap used inline, jQuery and Stimulus :-/ // NOTE: it'd be best to rewrite this as a reusable "toggle" element in Stimulus without using jQuery + Bootstrap toggleAccordionButtonLabel(event) { const $target = jQuery(event.target); const $container = $target.parent(); const text = $target.text(); if ($container) { const show = $container.attr('aria-expanded') === 'true'; if (show) { $target.text(text.replace(/Hide/i, 'Show')); } else { $target.text(text.replace(/Show/i, 'Hide')); } } } disableTargetField(event) { const targetElementName = event.target.dataset.disableTarget; const targetElement = this[`${targetElementName}Target`]; const newValue = event.target.checked; targetElement.disabled = newValue; // Disable the button generated by ERB for select tags if (targetElement.nodeName === 'SELECT') { const snakeCaseName = targetElementName.replace( /[A-Z]/g, (letter) => `_${letter.toLowerCase()}`, ); document.querySelector( `button[data-id=site_config_${snakeCaseName}]`, ).disabled = newValue; } } closeAdminModal() { // per forem/internalEngineering#336, need to short-circuit the // "Update Site Configuration" button submit action; chose not to // define Target on actual "Update" button (since it's a partial). // The Target is defined on the Authentication form, and that section's // "Update" button is queried. const submitBtn = this.authSectionFormTarget.querySelector( 'input[type="submit"]', ); this.configModalAnchorTarget.innerHTML = ''; document.body.style.height = 'inherit'; document.body.style.overflowY = 'inherit'; if (submitBtn.hasAttribute('disabled')) { submitBtn.removeAttribute('disabled'); } } positionModalOnPage() { if (document.getElementsByClassName('crayons-modal')[0]) { document.body.style.height = '100vh'; document.body.style.overflowY = 'hidden'; } } // GENERAL FUNCTIONS END // EMAIL AUTH FUNCTIONS START toggleGoogleRecaptchaFields() { if (this.requireCaptchaForEmailPasswordRegistrationTarget.checked) { recaptchaFields.classList.remove('hidden'); } else { recaptchaFields.classList.add('hidden'); } } enableOrEditEmailAuthSettings(event) { event.preventDefault(); if (this.emailAuthSettingsBtnTarget.dataset.buttonText === 'enable') { emailRegistrationCheckbox.checked = true; this.emailAuthSettingsBtnTarget.setAttribute('data-button-text', 'edit'); this.enabledIndicatorTarget.classList.add('visible'); } this.emailAuthSettingsBtnTarget.classList.add('hidden'); emailAuthSettingsSection.classList.remove('hidden'); } hideEmailAuthSettings(event) { event.preventDefault(); this.emailAuthSettingsBtnTarget.classList.remove('hidden'); emailAuthSettingsSection.classList.add('hidden'); } activateEmailAuthModal(event) { event.preventDefault(); this.configModalAnchorTarget.innerHTML = adminModal({ title: emailAuthModalTitle, body: emailAuthModalBody, leftBtnText: 'Confirm disable', leftBtnAction: 'disableEmailAuthFromModal', rightBtnText: 'Cancel', rightBtnAction: 'closeAdminModal', leftBtnClasses: 'crayons-btn--danger', rightBtnClasses: 'crayons-btn--secondary', }); this.positionModalOnPage(); } disableEmailAuthFromModal(event) { event.preventDefault(); this.disableEmailAuth(event); this.closeAdminModal(); } disableEmailAuth(event) { event.preventDefault(); emailRegistrationCheckbox.checked = false; this.emailAuthSettingsBtnTarget.innerHTML = 'Enable'; this.emailAuthSettingsBtnTarget.setAttribute('data-button-text', 'enable'); this.enabledIndicatorTarget.classList.remove('visible'); this.hideEmailAuthSettings(event); } // EMAIL AUTH FUNCTIONS END // AUTH PROVIDERS FUNCTIONS START enableOrEditAuthProvider(event) { event.preventDefault(); const providerName = event.target.dataset.providerName; const enabledIndicator = document.getElementById( `${providerName}-enabled-indicator`, ); document .getElementById(`${providerName}-auth-settings`) .classList.remove('hidden'); event.target.classList.add('hidden'); if (event.target.dataset.buttonText === 'enable') { enabledIndicator.classList.add('visible'); event.target.setAttribute('data-enable-auth', 'true'); this.listAuthToBeEnabled(); } } disableAuthProvider(event) { event.preventDefault(); const providerName = event.target.dataset.providerName; const enabledIndicator = document.getElementById( `${providerName}-enabled-indicator`, ); const authEnableButton = document.getElementById( `${providerName}-auth-btn`, ); authEnableButton.setAttribute('data-enable-auth', 'false'); enabledIndicator.classList.remove('visible'); this.listAuthToBeEnabled(); this.hideAuthProviderSettings(event); } authProviderModalTitle(provider) { return `Disable ${provider} login`; } authProviderModalBody(provider) { return `If you disable ${provider} as a login option, people cannot authenticate with ${provider}.
You must update Site Config to save this action!
`; } activateAuthProviderModal(event) { event.preventDefault(); const providerName = event.target.dataset.providerName; const providerOfficialName = event.target.dataset.providerOfficialName; this.configModalAnchorTarget.innerHTML = adminModal({ title: this.authProviderModalTitle(providerOfficialName), body: this.authProviderModalBody(providerOfficialName), leftBtnText: 'Confirm disable', leftBtnAction: 'disableAuthProviderFromModal', rightBtnText: 'Cancel', rightBtnAction: 'closeAdminModal', leftBtnClasses: 'crayons-btn--danger', rightBtnClasses: 'crayons-btn--secondary', leftCustomDataAttr: `data-provider-name=${providerName}`, }); this.positionModalOnPage(); } disableAuthProviderFromModal(event) { event.preventDefault(); const providerName = event.target.dataset.providerName; const authEnableButton = document.getElementById( `${providerName}-auth-btn`, ); const enabledIndicator = document.getElementById( `${providerName}-enabled-indicator`, ); authEnableButton.setAttribute('data-enable-auth', 'false'); this.listAuthToBeEnabled(event); this.checkForAndGuardSoleAuthProvider(); enabledIndicator.classList.remove('visible'); this.hideAuthProviderSettings(event); this.closeAdminModal(); } checkForAndGuardSoleAuthProvider() { if ( document.querySelectorAll('[data-enable-auth="true"]').length === 1 && document .getElementById('email-auth-enable-edit-btn') .getAttribute('data-button-text') === 'enable' ) { const targetAuthDisableBtn = document.querySelector( '[data-enable-auth="true"]', ); targetAuthDisableBtn.parentElement.classList.add('crayons-tooltip'); targetAuthDisableBtn.parentElement.setAttribute( 'data-tooltip', 'To edit this, you must first enable Email address as a registration option', ); targetAuthDisableBtn.setAttribute('disabled', true); } } hideAuthProviderSettings(event) { event.preventDefault(); const providerName = event.target.dataset.providerName; document .getElementById(`${providerName}-auth-settings`) .classList.add('hidden'); document .getElementById(`${providerName}-auth-btn`) .classList.remove('hidden'); } listAuthToBeEnabled() { const enabledProviderArray = []; document .querySelectorAll('[data-enable-auth="true"]') .forEach((provider) => { enabledProviderArray.push(provider.dataset.providerName); }); document.getElementById( 'auth_providers_to_enable', ).value = enabledProviderArray; } adjustAuthenticationOptions() { if (this.inviteOnlyModeTarget.checked) { document.getElementById('auth_providers_to_enable').value = ''; emailRegistrationCheckbox.checked = false; } else { emailRegistrationCheckbox.checked = true; } } // AUTH PROVIDERS FUNCTIONS END enabledProvidersWithMissingKeys() { const providersWithMissingKeys = []; document .querySelectorAll('[data-enable-auth="true"]') .forEach((provider) => { const { providerName } = provider.dataset; if ( !document.getElementById( `settings_authentication_${providerName}_key`, ).value || !document.getElementById( `settings_authentication_${providerName}_secret`, ).value ) { providersWithMissingKeys.push(providerName); } }); return providersWithMissingKeys; } generateProvidersList(providers) { const list = providers.reduce((html, provider) => { return `${html}You haven't filled out all of the required fields to enable the following authentication providers:
You may continue editing these authentication providers, or you may cancel.
`; } submitForm() { this.authSectionFormTarget.submit(); } activateMissingKeysModal(providers) { this.configModalAnchorTarget.innerHTML = adminModal({ title: 'Setup not complete', body: this.missingAuthKeysModalBody(providers), leftBtnText: 'Continue editing', leftBtnAction: 'closeAdminModal', rightBtnText: 'Cancel', rightBtnAction: 'cancelAuthProviderEnable', rightBtnClasses: 'crayons-btn--secondary', }); } configUpdatePrecheck(event) { if (this.enabledProvidersWithMissingKeys().length > 0) { event.preventDefault(); this.activateMissingKeysModal(this.enabledProvidersWithMissingKeys()); } else { event.target.submit(); } } cancelAuthProviderEnable() { const providers = this.enabledProvidersWithMissingKeys(); providers.forEach((provider) => { const enabledIndicator = document.getElementById( `${provider}-enabled-indicator`, ); const authEnableButton = document.getElementById(`${provider}-auth-btn`); authEnableButton.setAttribute('data-enable-auth', 'false'); enabledIndicator.classList.remove('visible'); this.listAuthToBeEnabled(); document .getElementById(`${provider}-auth-settings`) .classList.add('hidden'); document .getElementById(`${provider}-auth-btn`) .classList.remove('hidden'); this.closeAdminModal(); }); } }