Viewing File: /usr/local/cpanel/whostmgr/docroot/js2/edituser.js

//                                      Copyright 2024 WebPros International, LLC
//                                                           All rights reserved.
// copyright@cpanel.net                                         http://cpanel.net
// This code is subject to the cPanel license. Unauthorized copying is prohibited.

/* globals LANG: false, original_values: false, user_package: false, childNodeOptions: false */
/* eslint-disable camelcase */
/* eslint-disable strict */
var VALID = {};

var MAX_USERNAME_LENGTH = 16;
var isRtl = CPANEL.dom.isRtl();

var ensure_dmarc_deps = function() {
    var spfElement   = DOM.get("HASSPF_check");
    var dkimElement  = DOM.get("HASDKIM_check");
    var dmarcElement = DOM.get("HASDMARC_check");
    if ( spfElement && dkimElement && dmarcElement ) {
        if ( dmarcElement.checked ) {
            spfElement.checked = true;
            dkimElement.checked = true;
            spfElement.disabled = true;
            dkimElement.disabled = true;
        } else {
            spfElement.disabled = false;
            dkimElement.disabled = false;
        }
    }
    return;
};

function update_displayed_package_values() {
    var pkg_vals = user_package;
    if (pkg_vals) {
        for (var key in pkg_vals) {
            if (key in original_values) {
                if (String(pkg_vals[key]) === String(original_values[key])) {
                    DOM.setStyle("package_value_label_" + key, "display", "none");
                } else {
                    DOM.setStyle("package_value_label_" + key, "display", "");

                    var val = pkg_vals[key];
                    var formatted = val;
                    if (!isNaN(parseFloat(val)) && isFinite(val)) {
                        if (key == "BWLIMIT" || key == "QUOTA") {
                            formatted = LOCALE.numf(val / 1048576);
                        } else {
                            formatted = BOOLEAN_PACKAGE_VALUES[key] ? ON_OFF[ !!parseInt(val)] : LOCALE.numf(val);
                        }
                    }

                    // package extensions may not have this element
                    // in their subforms, and the element doesn't seem essential
                    // so only set the value if the form element actually exists

                    var packageValueElement = DOM.get("package_value_" + key);

                    if (packageValueElement) {
                        packageValueElement.innerHTML = formatted;
                    }
                }
            }
        }
    } else {
        CPANEL.Y.all(".package-value-label").forEach(function(el) {
            DOM.setStyle(el, "display", "none");
        });
    }
}

/**
 * remove the missing extensions warning on successful save if
 * "remove" checkbox is checked
 *
 * @method  check_for_missing_extensions
 */

function check_for_missing_extensions() {
    var missingExtensionsDiv = DOM.get("missingExtensionsGroup");
    var missing_extensions_checkbox = DOM.get("missingPackageExtensionsCheckbox");
    if (missingExtensionsDiv && missing_extensions_checkbox.checked == true) {
        DOM.addClass(missingExtensionsDiv, "hidden");
        missingExtensionsDiv.parentNode.removeChild(missingExtensionsDiv);
    }
}

function check_submit(clicked_el) {
    var form = document.getElementById("edituser_form");
    var form_data = CPANEL.dom.get_data_from_form("edituser_form", {
        include_unchecked_checkboxes: 0,
    });
    var hasshell = form.HASSHELL;

    for (var key in form_data) {
        var match = key.match(/^(.*)_chooser$/);
        if (match) {
            if (form_data[key] !== "custom") {
                form_data[match[1]] = form_data[key];
            }
            delete form_data[key];
        }
    }

    var package_altered = false;

    // the API wants bytes
    ["QUOTA", "BWLIMIT"].forEach(function(k) {
        if ((k in form_data) && (form_data[k] !== "unlimited")) {
            form_data[k] = parseInt(form_data[k]) * 1048576;
        }
    });

    // Check username, domain, and contact email "manually" since
    // these are spelled differently in different places.
    var something_changed = form_data.newuser !== original_values.USER || form_data.domain !== original_values.DOMAIN || form_data.contactemail !== original_values.CONTACTEMAILS;

    // use fuzzy equality checks here since Perl does not typecast reliably
    /* jshint -W116 */
    if ( form_data ) {
        var value;
        for ( [key, value] of Object.entries(form_data)) {
            if ( key in original_values ) {

                if ( key === "HASDMARC" && original_values[key] === undefined ) {
                    something_changed = true;
                    continue;
                }

                if ((key in original_values) && value !== original_values[key]) {

                    // HASSHELL is a checkbox, but has its value set to the path of the
                    // current shell. We just need to see if the checkbox is checked
                    // and if that is different from the original value, which would be either
                    // a "0" or a "1".
                    if (key === "HASSHELL" && hasshell.checked === Boolean(Number(original_values["HASSHELL"]))) {
                        continue;
                    }

                    something_changed = true;

                    // Convert strings "0" and "1" to numerical 0 or 1, so the === and !== checks
                    // mandated by ESLint pass
                    if ( typeof (value) === "number" && typeof (user_package[key]) === "string" ) {
                        if ( value === 1 ) {
                            value = "1";
                        } else if ( value === 0 ) {
                            value = "0";
                        }
                    }
                    if (user_package && (key !== "LOCALE") && (key in user_package) && (value !== user_package[key])) {
                        package_altered = true;
                    }

                }

                // only enhancements that are checked have a non-zero value
                if (key.startsWith("account_enhancements-")) {
                    if (parseInt(value, 10) === 0) {
                        delete form_data[key];
                    }
                }
            }
        }
    }
    /* jshint +W116 */

    // check to see if remove missing packages is checked

    var missing_extensions_checkbox = DOM.get("missingPackageExtensionsCheckbox");
    if (missing_extensions_checkbox && missing_extensions_checkbox.checked == true) {

        // force something_changed and package_altered to true if checked
        something_changed = true;

        // if PLAN is not undefined, force the reconciliation dialog
        if (original_values.PLAN && original_values.PLAN !== "undefined") {
            package_altered = true;
        }
    }

    // nothing changed, so do nothing
    if (!something_changed) {
        alert(LANG.must_change);
        return;
    }

    // make sure we have valid data
    if (!CPANEL.util.values(VALID).every(function(v) {
        return v.is_valid();
    })) {
        return;
    }

    form_data.user = original_values.USER;

    delete form_data._submit;

    var status_html = package_altered ? LANG.checking_for_matches : YAHOO.lang.substitute(LANG.saving, form_data);

    var progress_panel = new CPANEL.ajax.Progress_Panel(null, {
        show_status: true,
        status_html: status_html,
    });

    progress_panel.show_from_source(clicked_el);

    // no change of package values, so we just save and go on
    if (!package_altered) {
        save_without_dialog(form_data, progress_panel);
        return;
    }

    // Change the package values, so offer these options:
    // 1. Change this account to a package matching the new values.
    //   (requires an AJAX call before showing the dialog box)
    // 2. Add a package with the new values and set the account to use it.
    // 3. Change the package (and all its users) to have the new values.
    // 4. Take the account off the package, and save the values.
    // 5. Save the account's new values and leave the package setting in place.

    var callback = CPANEL.ajax.build_callback(
        function(o) {
            var packages = o.cpanel_data;
            var form_template;
            if (packages && packages.length > 0) {
                form_template = CPANEL.ajax.templates.submit_with_match_template;
            } else {
                form_template = CPANEL.ajax.templates.submit_no_match_template;
            }

            if (form_template) {
                var packages_html = packages.map(function(p) {
                    return "<option value='" + p.name.html_encode() + "'>" + p.name.elide(50).html_encode() + "</option>";
                });

                if (can_add_package) {
                    form_template += CPANEL.ajax.templates._submit_add_pkg_template;
                }

                form_template += CPANEL.ajax.templates._submit_include_template;

                var form_template_variables = {
                    package_options_html: packages_html,
                    PLAN: original_values.PLAN.elide(50).html_encode(),
                };

                var dialog_opts = {
                    header_html: LANG.plan_conflict_resolution,
                    form_template: form_template,
                    form_template_variables: form_template_variables,
                    clicked_element: clicked_el,
                    show_status: true,
                    success_status: LOCALE.maketext("Success!"),
                    success_function: function() {
                        delete form_data["PLAN"];
                        check_for_missing_extensions();
                        update_original_values(form_data);
                    },
                };

                save_with_dialog(form_data, progress_panel, dialog_opts);
            }
        }, {
            current: progress_panel,
        }, {
            keep_current_on_success: true,
            whm: true,
        }
    );

    if (user_package) {
        form_data.exclude = original_values.PLAN;
    }

    CPANEL.api({
        application: "whm",
        func: "matchpkgs",
        data: form_data,
        callback: callback,
    });
}

function getChangedChildNodeOptions(original_values, new_values) {
    return Object.keys(childNodeOptions).filter(function(key) {
        var parameter = childNodeOptions[key].parameter;
        if (original_values[parameter] !== new_values[parameter]) {
            return true;
        }
        return false;
    }).map(function(key) {
        return childNodeOptions[key].parameter;
    });
}

function update_original_values(new_values) {
    for (var original_key in original_values) {
        if (original_key.startsWith("account_enhancements-")) {
            new_values[original_key] = new_values[original_key] || 0;
        }
    }

    for (var key in original_values) {
        if (key in new_values) {
            original_values[key] = new_values[key];
        }
    }

    if ("newuser" in new_values) {
        const upgradeUrlEl = document.getElementById("selectupgrade_url");
        if (upgradeUrlEl) {
            upgradeUrlEl.innerHTML = upgradeUrlEl.innerHTML.replace( "=" + original_values.USER, "=" + new_values.newuser );
        }

        update_original_value_for("USER", new_values.newuser);
        ORGUSER = new_values.newuser;
        CPANEL.util.set_text_content("editing_user", new_values.newuser);
    }

    if ("domain" in new_values) {
        update_original_value_for("DOMAIN", new_values.domain);
        ORGDOMAIN = new_values.domain;
        CPANEL.util.set_text_content("editing_domain", new_values.domain);
    }

    if ("contactemail" in new_values) {
        update_original_value_for("CONTACTEMAILS", new_values.contactemail);
    }

    noticeCollection.updateAllOriginalValues();
    hide_domain_data_warning();

    var showResellerWarning = Number(original_values.reseller);
    DOM.setStyle("reseller_warning", "display", showResellerWarning ? "" : "none");
    DOM.setStyle("basic_info_notes", "display", showResellerWarning ? "" : "none");

    update_displayed_package_values();

}

function update_user_package(new_values) {
    for (var key in user_package) {
        if (key in new_values) {
            user_package[key] = new_values[key];
        }
    }

    update_displayed_package_values();
}

function save_without_dialog(form_data, progress_panel) {
    var callback = CPANEL.ajax.build_callback(
        function(o) {
            progress_panel.cfg.setProperty("effect", CPANEL.ajax.FADE_MODAL);
            progress_panel.hide();
            new CPANEL.ajax.Dynamic_Notice({
                content: LOCALE.maketext("Success!"),
                level: "success",
            });
            check_for_missing_extensions();
            update_original_values(form_data);

            var json_response = YAHOO.lang.JSON.parse(o.responseText);
            if (json_response && json_response.metadata && json_response.metadata.output) {
                if (json_response.metadata.output.messages && json_response.metadata.output.messages.length) {
                    new CPANEL.widgets.Dynamic_Page_Notice({
                        level: "info",
                        content: json_response.metadata.output.messages.map(function(s) {
                            return s.html_encode();
                        }).join("<br />"),
                        container: "edituser_messages",
                    });
                }
                if (json_response.metadata.output.warnings && json_response.metadata.output.warnings.length) {
                    new CPANEL.widgets.Dynamic_Page_Notice({
                        level: "warn",
                        content: json_response.metadata.output.warnings.map(function(s) {
                            return s.html_encode();
                        }).join("<br />"),
                        container: "edituser_warnings",
                    });
                }
            }
        }, {
            current: progress_panel,
        }, {
            keep_current_on_success: true,
            whm: true,
        }
    );

    form_data.rename_database_objects = _read__rename_database_objects(form_data);

    CPANEL.api({
        application: "whm",
        func: "modifyacct",
        data: form_data,
        callback: callback,
    });
}

function _read__rename_database_objects(form_data) {
    if ("rename_database_objects" in form_data) {
        return form_data.rename_database_objects ? 1 : 0;
    }

    return 1;
}

function save_with_dialog(form_data, progress_panel, dialog_opts) {
    var the_dialog = new CPANEL.ajax.Common_Action_Dialog("confirm_dialog", dialog_opts);

    the_dialog.beforeShowEvent.subscribe(function initdialog() {
        the_dialog.beforeShowEvent.unsubscribe(initdialog);

        // Set the overlay element to a smaller width so it does not need to cover the side navigation
        DOM.setStyle(the_dialog.element, "width", "80%");

        // center the element so that horizontal and vertical centering is handled (vertical centering value will not change after this)
        this.center();

        var asideSize = document.querySelector("#cp-main-menu-container").getBoundingClientRect();
        var newSize = asideSize.width + (asideSize.width * 0.1);

        // move the overlay element horizontally the width of the side navigation element + 10%
        if (isRtl) {
            this.moveTo(newSize * -1);
        } else {
            this.moveTo(newSize);
        }


        DOM.getElementBy(
            function(el) {
                return el.type.toLowerCase() === "radio";
            },
            "input",
            the_dialog.form
        ).checked = true;

        var grouped_input_set = new CPANEL.ajax.Grouped_Input_Set(the_dialog.form);
    });

    the_dialog.beforeSubmitEvent.subscribe(function() {

        var non_package_values = {};
        for (var key in form_data) {
            if (!(key in original_values)) {
                continue;
            }
            if (key === "PLAN") {
                continue;
            }

            if (form_data[key] !== original_values[key]) {
                non_package_values[key] = form_data[key];
            }
        }

        if (original_values.USER !== form_data.newuser) {
            non_package_values.newuser = form_data.newuser;
        }
        if (original_values.DOMAIN !== form_data.domain) {
            non_package_values.domain = form_data.domain;
        }
        if (original_values.CONTACTEMAILS !== form_data.contactemail) {
            non_package_values.contactemail = form_data.contactemail;
        }

        var dialog_data = CPANEL.dom.get_data_from_form(this.form);

        var api_calls = [];
        if (Object.keys(non_package_values).length) {
            non_package_values.user = original_values.USER;
            non_package_values.rename_database_objects = _read__rename_database_objects(form_data);

            api_calls.push({
                api_application: "whm",
                api_function: "modifyacct",
                data: non_package_values,
                status_template: LOCALE.maketext("Saving non-package values …"),
                success_function: function(o) {
                    update_original_values(non_package_values);
                    var json_response = YAHOO.lang.JSON.parse(o.responseText);
                    if (json_response && json_response.metadata && json_response.metadata.output) {
                        if (json_response.metadata.output.messages && json_response.metadata.output.messages.length) {
                            new CPANEL.widgets.Dynamic_Page_Notice({
                                level: "info",
                                content: json_response.metadata.output.messages.map(function(s) {
                                    return s.html_encode();
                                }).join("<br />"),
                                container: "edituser_messages",
                            });
                        }
                        if (json_response.metadata.output.warnings && json_response.metadata.output.warnings.length) {
                            new CPANEL.widgets.Dynamic_Page_Notice({
                                level: "warn",
                                content: json_response.metadata.output.warnings.map(function(s) {
                                    return s.html_encode();
                                }).join("<br />"),
                                container: "edituser_warnings",
                            });
                        }
                    }
                },
            });
        }

        if (dialog_data.plan_change_resolution === "modify_pkg") {
            form_data.pkgname = original_values.PLAN;
            api_calls.unshift({
                api_application: "whm",
                api_function: "editpkg",
                data: form_data,
                status_template: LANG.updating_package,
                success_function: function() {
                    update_user_package(form_data);
                },
            });
        } else if (can_add_package && dialog_data.plan_change_resolution === "add_pkg") {
            form_data.pkgname = dialog_data.ADDPLAN;

            // restore the values that were removed
            YAHOO.lang.augmentObject(form_data, original_values);

            // the actual package name might differ slightly from what we submit
            var created_package = {};

            api_calls.unshift({
                api_application: "whm",
                api_function: "addpkg",
                data: form_data,
                status_template: LANG.creating_package,
                success_function: function(result) {
                    created_package.name = result.cpanel_data.pkg;
                },
            }, {
                api_application: "whm",
                api_function: "changepackage",
                data: function() {
                    return {
                        user: original_values.USER,
                        pkg: created_package.name,
                    };
                },
                status_template: LANG.assigning_account_to_package,
                success_function: function() {
                    CPANEL.util.set_text_content("package_name", created_package.name);
                    update_original_value_for("PLAN", created_package.name);
                    update_user_package(form_data);
                },
            });
        } else if (dialog_data.plan_change_resolution === "change_pkg") {
            api_calls.unshift({
                api_application: "whm",
                api_function: "changepackage",
                data: {
                    user: original_values.USER,
                    pkg: dialog_data.CHANGEPLAN,
                },
                status_template: LANG.assigning_account_to_package,
                success_function: function() {
                    CPANEL.util.set_text_content("package_name", dialog_data.CHANGEPLAN);
                    update_original_value_for("PLAN", dialog_data.CHANGEPLAN);
                    update_user_package(form_data);
                },
            });
        } else {
            form_data.USER = original_values.USER;

            form_data.rename_database_objects = _read__rename_database_objects(form_data);

            api_calls = [{
                api_application: "whm",
                api_function: "modifyacct",
                data: form_data,
                status_template: LANG.saving,
            }];

            if (dialog_data.plan_change_resolution === "undefined") {
                form_data.PLAN = "undefined";
                api_calls[0].success_function = function() {
                    CPANEL.util.set_text_content("package_name", "undefined");
                    user_package = null;
                    update_original_value_for("PLAN", "undefined");

                    // Hide the "package value" notices.
                    var dummy = document.createElement("div");
                    dummy.innerHTML = "<style>.package-value-label {display:none}</style>";
                    document.body.appendChild(dummy.firstChild);
                };
            } else {
                api_calls[0].success_function = function() {
                    update_original_values(form_data);
                };
            }
        }

        the_dialog.cfg.setProperty("api_calls", api_calls);
    });

    progress_panel.fade_to(the_dialog);
}

function update_original_value_for(k, v) {
    window.original_values[k] = v;
    return;
}

function limits_chooser(limittype, choosername) {
    var working_id = document.getElementById(choosername + "_text");
    if (/custom/i.test(limittype)) {
        working_id.style.color = "#000";
        working_id.disabled = false;
        working_id.focus();
    } else {
        working_id.style.color = "#ccc";
        working_id.disabled = true;
    }
    VALID[choosername].clear_messages();
    VALID[choosername].verify();
}

function limits_chooser_custommod(choosername) {
    document.getElementById(choosername + "_text").style.color = "#000";
    document.getElementById(choosername + "_chooser_custom").checked = true;
    VALID[choosername].clear_messages();
    VALID[choosername].verify();
}

function display_domain_data_warning() {
    YAHOO.util.Dom.replaceClass("domain_data_warning", "hidden", "note");
}

function hide_domain_data_warning() {
    YAHOO.util.Dom.replaceClass("domain_data_warning", "note", "hidden");
}

function dismiss_paper_lantern_warning(clicked_el) {  // eslint-disable-line no-unused-vars
    YAHOO.util.Dom.replaceClass("paper_lantern_warning", "note", "hidden");

    var request = new XMLHttpRequest();
    request.open("POST", CPANEL.security_token + "/json-api/personalization_set");
    request.setRequestHeader("Content-Type", "application/json");
    request.send(JSON.stringify({ "api.version": 1, "personalization": { "hide_paper_lantern_notice": 1 } }));
}

var add_new_validation = function() {  // eslint-disable-line strict
    // eslint-disable-next-line new-cap
    VALID["domain"] = new CPANEL.validate.validator(LOCALE.maketext("Domain"));
    VALID["domain"].add("domain", "fqdn", LANG.must_be_fqdn);
    VALID["domain"].add("domain", function() {
        var domain = YAHOO.util.Dom.get("domain").value;
        if ( domain !== ORGDOMAIN && DOMAINS_WITH_DATA.indexOf(domain) !== -1 ) {
            display_domain_data_warning();
        } else {
            hide_domain_data_warning();
        }
        return true; // always return true, because we will still allow the attempt even though it could be risky
    }, LOCALE.maketext("It is dangerous to change the account’s primary domain to one that already has data associated with it."));
    VALID["domain"].attach();

    YAHOO.util.Event.on("HASSPF_check", "change", ensure_dmarc_deps);
    YAHOO.util.Event.on("HASDKIM_check", "change", ensure_dmarc_deps);
    YAHOO.util.Event.on("HASDMARC_check", "change", ensure_dmarc_deps);
    ensure_dmarc_deps();

    if (document.getElementById("newuser")) {
        var username_length = function() {
            var username = YAHOO.util.Dom.get("newuser").value;
            if (username === ORGNAME) {
                return true;
            }

            return CPANEL.validate.max_length(username, MAX_USERNAME_LENGTH);
        };
        var username_stupidstuff = function() {
            var username = YAHOO.util.Dom.get("newuser").value;
            return CPANEL.validate.alpha(username.charAt(0));
        };
        var valid_username = function() {
            var value = document.getElementById("newuser").value;
            return (new RegExp(window.username_regexp)).test(value);
        };
        // eslint-disable-next-line new-cap
        VALID["newuser"] = new CPANEL.validate.validator(LOCALE.maketext("Username"));
        VALID["newuser"].add("newuser", "no_chars(%input%,' ')", LOCALE.maketext("A username cannot have spaces."));
        VALID["newuser"].add("newuser", username_length, LOCALE.maketext("A username cannot be longer than [quant,_1,character,characters].", MAX_USERNAME_LENGTH));
        VALID["newuser"].add("newuser", username_stupidstuff, LOCALE.maketext("A username cannot start with a number."));
        VALID["newuser"].add("newuser", valid_username, LOCALE.maketext("A username must only contain lowercase alphanumeric characters."));
        VALID["newuser"].add("newuser", function() {

            // We allow understores if DB prefixing is disabled.
            if ( !HAS_DB_PREFIX ) {
                return 1;
            }

            // If the value has not changed there is no need to validate it
            // as we want to allow everything that already exists in.
            if ( document.getElementById("newuser").value === document.getElementById("newuser").defaultValue ) {
                return 1;
            }
            // eslint-disable-next-line no-useless-escape
            return !/\_/.test(document.getElementById("newuser").value);
        }, LOCALE.maketext("Usernames may not contain underscores."));
        VALID["newuser"].attach();
    }

    if (DOM.get("contactemail")) {
        var valid_emails = function() {
            var contactemail = DOM.get("contactemail").value.trim();

            if (!contactemail) {
                return true;
            }

            contactemail = contactemail.split(/[\s;,]+/);
            if (contactemail.length > 2) {
                return false;
            }

            return contactemail.every(CPANEL.validate.email);
        };
        // eslint-disable-next-line new-cap
        VALID["contactemail"] = new CPANEL.validate.validator(LOCALE.maketext("Contact Email"));
        VALID["contactemail"].add("contactemail", valid_emails, LOCALE.maketext("You must provide one or two valid contact emails."));
        VALID["contactemail"].attach();
    }

    CPANEL.validate.validate_limits = function(val, el) {
        var el2 = document.getElementById(el + "_chooser_custom").checked;
        return (el2 && CPANEL.validate.positive_integer(val));
    };

    els = YAHOO.util.Dom.getElementsByClassName("validation_selector");

    for (var i = els.length - 1; i >= 0; i--) {
        var cur_el = els[i];

        var maxvar = cur_el.id.split("_text")[0];
        VALID[maxvar] = new CPANEL.validate.validator(VARHEADERS[maxvar]);
        VALID[maxvar].add(cur_el.id, 'validate_limits($INPUT$,"' + maxvar + '")', LANG.must_be_number.replace("{label}", VARHEADERS[maxvar]));
        VALID[maxvar].attach();

        var cell = DOM.getAncestorByTagName(cur_el, "div");
        var inputs = cell.getElementsByTagName("input");

        if (inputs[0].type.toLowerCase() === "radio") {
            var gset = new CPANEL.ajax.Grouped_Input_Set(cur_el.form, inputs[0], inputs[inputs.length - 1]);

            // In some scenarios the layout seems to change after the
            // Grouped_Input_Set object is created. When that happens
            // the gset object goes out of alignment with its underlying
            // <input> element. Ideally we’d install some sort of hook to
            // align after such layout changes, but there seems no obvious
            // way to do that. The below is inelegant, but it’s also simple,
            // and it does fix the problem for all practical purposes.
            //
            setInterval( gset.align.bind(gset), 0.01 );

            (function() {
                var my_el = cur_el,
                    validator = VALID[maxvar],
                    err_el = DOM.get(maxvar + "_text_error");
                gset.onrefresh = function(grp) {
                    if (grp.inputs[0] === my_el) {
                        err_el.style.display = "";
                        validator.verify();
                    } else {
                        err_el.style.display = "none";
                        validator.hide_all_panels();
                    }
                };
            }());
        }

    }

    if (DOM.get("max_team_users_field")) {
        var valid_max_team_users = function() {
            var max_team_users_field = DOM.get("max_team_users_field").value.trim();

            if (!max_team_users_field) {
                return false;
            }

            max_team_users_field = max_team_users_field.split(/[\s;,]+/);
            if (max_team_users_field.length > 2) {
                return false;
            }

            if ( max_team_users_field < 0 || max_team_users_field > window.PAGE.SERVER_MAX_TEAM_USERS ) {
                return false;
            }

            return true;
        };
        // eslint-disable-next-line new-cap
        VALID["max_team_users_field"] = new CPANEL.validate.validator(
            LOCALE.maketext("Max Team Users with Roles")
        );
        VALID["max_team_users_field"].add(
            "max_team_users_field",
            valid_max_team_users,
            LOCALE.maketext(
                "The input must be a number between “[_1]” and “[_2]”.",
                0,
                window.PAGE.SERVER_MAX_TEAM_USERS
            )
        );
        VALID["max_team_users_field"].attach();
    }

    CPANEL.validate.attach_to_form("submitit", VALID);
};

var addLastStyleToPropertyGroups = function() {
    var packageExtensions = DOM.getElementsByClassName("propertyGroup", "div", "packageExtensions");

    var isLastPropertyEditor = function(el) {
        return DOM.hasClass(el, "propertyEditor");
    };

    var propertyGroupCount = packageExtensions.length;
    for (var j = 0; j < propertyGroupCount; j++) {
        var lastInGroup = DOM.getLastChildBy(packageExtensions[j], isLastPropertyEditor);
        if (lastInGroup) {
            DOM.addClass(lastInGroup, "last");
        }
    }
};

/**
 * Show and hide the change notices
 */
var Notice = (function() {

    function Notice(notice_id, input_id) {
        this.noticeElem = document.getElementById(notice_id);
        this.inputElem  = document.getElementById(input_id);
        this.originalInputVal = this.inputElem.value;
        this.clicked = false;
        this.focused = false;
    }

    Notice.prototype.show = function() {
        YAHOO.util.Dom.replaceClass(this.noticeElem, "hidden", "note");
    };

    Notice.prototype.hide = function() {
        YAHOO.util.Dom.replaceClass(this.noticeElem, "note", "hidden");
    };

    Notice.prototype.render = function() {
        var changed = this.inputElem.value !== this.originalInputVal;

        if (changed || this.clicked || this.focused) {
            this.show();
        } else {
            this.hide();
        }
    };

    Notice.prototype.clearFlags = function() {
        this.clicked = this.focused = false;
    };

    return Notice;
})();

var noticesList = [
    new Notice("domain_change_notice", "domain"),
];

if (document.getElementById("newuser")) {
    noticesList.push(
        new Notice("username_change_warning", "newuser")
    );
}

var noticeCollection = {
    notices: noticesList,
    updateAllOriginalValues: function() {
        this.notices.forEach(function(notice) {
            notice.clicked = false;
            notice.focused = false;
            notice.originalInputVal = notice.inputElem.value;
        });
        this.renderAll();
    },
    renderAll: function() {
        this.notices.forEach(function(notice) {
            notice.render();
        });
    },
    clearFlagsAll: function() {
        this.notices.forEach(function(notice) {
            notice.clearFlags();
        });
    },
    findByNotice: function(noticeElem) {
        var found;
        this.notices.some(function(notice) {
            if (notice.noticeElem === noticeElem) {
                found = notice;
                return true;
            }
        });
        return found;
    },
    findByInput: function(inputElem) {
        var found;
        this.notices.some(function(notice) {
            if (notice.inputElem === inputElem) {
                found = notice;
                return true;
            }
        });
        return found;
    },
    addEventListeners: function() {
        var self = this;

        // Loop through the notice objects to attach the individual event listeners.
        this.notices.forEach(function(notice) {

            /**
             * When focusing an element with a notice, we should show that notice and remove any
             * state from other notices.
             *
             * @method processInputFocus
             */
            YAHOO.util.Event.addListener(notice.inputElem, "focus", function processInputFocus() {
                self.clearFlagsAll();
                notice.focused = true;
                self.renderAll();
            });

            /**
             * When blurring an element with a notice, we should adjust the focused state from the
             * associated notice and render all notices again (in case any have the clicked state).
             *
             * @method processInputFocus
             */
            YAHOO.util.Event.addListener(notice.inputElem, "blur", function processInputBlur() {
                notice.focused = false;
                self.renderAll();
            });
        });

        /**
         * We want to respond to clicks registered anywhere in the document. Once fired, we need
         * to determine if it originated from within a notice or not. If not, then we only want
         * to show notices for fields that have changed or are focused.
         *
         * We listen on mousedown instead of click, because that event fires before blur.
         *
         * @method processClick
         * @param  {Event} e   The click Event object.
         */
        YAHOO.util.Event.addListener(document.body, "mousedown", function processClick(e) {
            var clickedNotice = YAHOO.util.Dom.getAncestorByClassName(e.target, "note");
            var clickedInput = self.findByInput(e.target);
            var notice;

            if (clickedNotice) {

                // No need to render after setting clicked to true, because:
                // - We don't want the view to change just because they clicked on the notice.
                // - The blur handler will call the render method anyhow.
                notice = self.findByNotice(clickedNotice);
                if (notice) {
                    notice.clicked = true;
                }
            } else if (!clickedInput) { // Don't trigger if they clicked the same focused input.
                self.clearFlagsAll();
                self.renderAll();
            }
        });

        /**
         * When a focus event originates from somewhere other than one of our notices or inputs,
         * we only want to show notices belonging to changed inputs.
         *
         * We need to use the useCapture parameter to be able to grab bubbled focus events, so we
         * can't use the YAHOO method for adding the listener.
         *
         * @method processBubbledFocus
         * @param  {Event} e   The focus Event object.
         */
        document.body.addEventListener("focus", function processBubbledFocus(e) {
            var insideNotice = YAHOO.util.Dom.getAncestorByClassName(e.target, "note");
            if ( !self.findByInput(e.target) && !insideNotice ) {
                self.clearFlagsAll();
                self.renderAll();
            }
        }, true);
    },
};

var BOOLEAN_PACKAGE_VALUES = {
    HASCGI: 1,
    HASSHELL: 1,
};


noticeCollection.addEventListeners();

YAHOO.util.Event.onDOMReady(add_new_validation);
YAHOO.util.Event.onDOMReady(update_displayed_package_values);
YAHOO.util.Event.onDOMReady(addLastStyleToPropertyGroups);
Back to Directory File Manager