/* 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 "You mut confirm..." warning 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 the settings below to complete 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=settings_${snakeCaseName}]`, ).disabled = newValue; } } closeAdminModal() { // per forem/internalEngineering#336, need to short-circuit the // "Update Settings" 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; 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; 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 Settings to save this action!
`; } activateAuthProviderModal(event) { event.preventDefault(); const {providerName} = event.target.dataset; const {providerOfficialName} = event.target.dataset; 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; 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; 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(); }); } }