/** * SPDX-FileCopyrightText: 2017-2024 Nextcloud GmbH and Nextcloud contributors * SPDX-FileCopyrightText: 2015-2016 ownCloud, Inc. * SPDX-License-Identifier: AGPL-3.0-or-later */ OCA = OCA || {}; (function() { /** * @classdesc An abstract tab view * @abstract */ var WizardTabGeneric = OCA.LDAP.Wizard.WizardObject.subClass({ isActive: false, /** * @property {string} - class that identifies a multiselect-plugin * control. */ multiSelectPluginClass: 'multiSelectPlugin', /** * @property {string} - class that identifies a multiselect-plugin * control. */ bjQuiButtonClass: 'ui-button', /** * @property {boolean} - indicates whether a filter mode toggle operation * is still in progress */ isToggling: false, /** @inheritdoc */ init: function(tabIndex, tabID) { this.tabIndex = tabIndex; this.tabID = tabID; this.spinner = $('.ldapSpinner').first().clone().removeClass('hidden'); _.bindAll(this, '_toggleRawFilterMode', '_toggleRawFilterModeConfirmation'); }, /** * sets the configuration items that are managed by that view. * * The parameter contains key-value pairs the key being the * configuration keys and the value being its setter method. * * @param {object} managedItems */ setManagedItems: function(managedItems) { this.managedItems = managedItems; this._enableAutoSave(); this._enableSaveButton(); }, /** * Sets the config model. The concrete view likely wants to subscribe * to events as well. * * @param {OCA.LDAP.Wizard.ConfigModel} configModel */ setModel: function(configModel) { this.configModel = configModel; this.parsedFilterMode = this.configModel.FILTER_MODE_ASSISTED; this.configModel.on('detectionStarted', this.onDetectionStarted, this); this.configModel.on('detectionCompleted', this.onDetectionCompleted, this); this.configModel.on('serverError', this.onServerError, this); this.configModel.on('setCompleted', this.onItemSaved, this); this.configModel.on('configUpdated', this.onConfigLoaded, this); }, /** * the method can be used to display a different error/information * message than provided by the Nextcloud server response. The concrete * Tab View may optionally implement it. Returning an empty string will * avoid any notification. * * @param {string} message * @param {string} key * @returns {string} */ overrideErrorMessage: function(message, key) { if(message === 'LDAP authentication method rejected' && !this.configModel.configuration.ldap_dn) { message = t('user_ldap', 'Anonymous bind is not allowed. Please provide a User DN and Password.'); } else if (message === 'LDAP Operations error' && !this.configModel.configuration.ldap_dn && !this.configModel.configuration.ldap_agent_password) { message = t('user_ldap', 'LDAP Operations error. Anonymous bind might not be allowed.'); } return message; }, /** * this is called by the main view, if the tab is being switched to. */ onActivate: function() { if(!_.isUndefined(this.filterModeKey) && this.configModel.configuration.ldap_experienced_admin === '1') { this.setFilterMode(this.configModel.FILTER_MODE_RAW); } }, /** * updates the tab when the model loaded a configuration and notified * this view. * * @param {WizardTabGeneric} view - this instance * @param {Object} configuration */ onConfigLoaded: function(view, configuration) { for(var key in view.managedItems){ if(!_.isUndefined(configuration[key])) { var value = configuration[key]; var methodName = view.managedItems[key].setMethod; if(!_.isUndefined(view[methodName])) { view[methodName](value); } } } }, /** * reacts on a set action on the model and updates the tab with the * valid value. * * @param {WizardTabGeneric} view * @param {Object} result */ onItemSaved: function(view, result) { if(!_.isUndefined(view.managedItems[result.key])) { var methodName = view.managedItems[result.key].setMethod; view[methodName](result.value); if(!result.isSuccess) { OC.Notification.showTemporary(t('user_ldap', 'Saving failed. Please make sure the database is in Operation. Reload before continuing.')); console.warn(result.errorMessage); } } }, /** * displays server error messages. * * @param {any} view - * @param {any} payload - */ onServerError: function(view, payload) { if ( !_.isUndefined(view.managedItems[payload.relatedKey])) { var message = view.overrideErrorMessage(payload.message, payload.relatedKey); if(message) { OC.Notification.showTemporary(message); } } }, /** * disables affected, managed fields if a detector is running against them * * @param {WizardTabGeneric} view * @param {string} key */ onDetectionStarted: function(view, key) { if(!_.isUndefined(view.managedItems[key])) { view.disableElement(view.managedItems[key].$element); if(!_.isUndefined(view.managedItems[key].$relatedElements)){ view.disableElement(view.managedItems[key].$relatedElements); } view.attachSpinner(view.managedItems[key].$element.attr('id')); } }, /** * enables affected, managed fields after a detector was run against them * * @param {WizardTabGeneric} view * @param {string} key */ onDetectionCompleted: function(view, key) { if(!_.isUndefined(view.managedItems[key])) { view.enableElement(view.managedItems[key].$element); if(!_.isUndefined(view.managedItems[key].$relatedElements)){ view.enableElement(view.managedItems[key].$relatedElements); } view.removeSpinner(view.managedItems[key].$element.attr('id')); } }, /** * sets the value to an HTML element. Checkboxes, text areas and (text) * input fields are supported. * * @param {jQuery} $element - the target element * @param {string|number|Array} value */ setElementValue: function($element, value) { // deal with check box if ($element.is('input[type=checkbox]')) { this._setCheckBox($element, value); return; } // special cases: deal with text area and multiselect if ($element.is('textarea') && $.isArray(value)) { value = value.join("\n"); } else if($element.hasClass(this.multiSelectPluginClass)) { if(!_.isArray(value)) { value = value.split("\n"); } } if ($element.is('span')) { $element.text(value); } else { $element.val(value); } }, /** * replaces options on a multiselect element * * @param {jQuery} $element - the multiselect element * @param {Array} options */ equipMultiSelect: function($element, options) { if($element.find('option').length === 0) { $element.empty(); for (var i in options) { var name = options[i]; $element.append($('