Viewing File: /usr/local/cpanel/whostmgr/docroot/templates/autossl/index.cmb.js

/*
# autossl/directives/starRating.js                                            Copyright(c) 2020 cPanel, L.L.C.
#                                                                                      All rights reserved.
# copyright@cpanel.net                                                                    http://cpanel.net
# This code is subject to the cPanel license.                            Unauthorized copying is prohibited
*/

/* global define: false */

define(
    'app/directives/starRating',[
        "angular",
        "cjt/core"
    ],
    function(angular, CJT) {

        "use strict";

        var module = angular.module("whostmgr.autossl.starRating", []);

        var TEMPLATE_PATH = "directives/starRating.phtml";

        module.directive("starRating", function() {

            return {
                templateUrl: TEMPLATE_PATH,
                restrict: "EA",
                replace: true,
                transclude: true,
                scope: {
                    max: "=",
                    rating: "="
                },
                controller: ["$scope", function($scope) {

                    function _buildStars() {
                        $scope.stars = [];
                        while ($scope.stars.length < $scope.max) {
                            $scope.stars.push($scope.rating > $scope.stars.length ? 1 : 0);
                        }
                    }

                    $scope.$watch("max", _buildStars);
                    $scope.$watch("rating", _buildStars);

                    _buildStars();
                }]
            };
        });
    }
);

/*
# Copyright 2022 cPanel, L.L.C. - All rights reserved.
# copyright@cpanel.net
# https://cpanel.net
# This code is subject to the cPanel license. Unauthorized copying is prohibited
*/

/* global define, PAGE */
/* jshint -W100 */
/* jshint -W089 */

define(
    'app/services/manageService',[
        "lodash",
        "angular",
        "cjt/util/parse",
        "cjt/util/query",
        "cjt/io/api",
        "cjt/io/whm-v1-request",
        "cjt/io/whm-v1", // IMPORTANT: Load the driver so it’s ready
    ],
    function(_, angular, CJT_PARSE, QUERY, API, APIREQUEST) {
        "use strict";

        var app = angular.module("App");

        var NO_MODULE = "";

        // Calculated by:
        // +1 for each supported DCV method (x2 if provider supports ancestor DCV)
        // +1 for lowest AVERAGE_DELIVERY_TIME
        // +1 for highest RATE_LIMIT_CERTIFICATES_PER_REGISTERED_DOMAIN_PER_WEEK
        // +1 for highest MAX_DOMAINS_PER_CERTIFICATE
        // +1 for highest HTTP_DCV_MAX_REDIRECTS
        // +1 for SUPPORTS_WILDCARD
        var MAX_USABILITY_SCORE = 8;

        var _tableColumns = [];

        function TableColumn(label, desc, starRating) {
            this.label = label;
            this.desc = desc;
            this.isScorePart = starRating ? true : false;
            this.starRating = starRating || 0;
            this.getLabel = function() {
                return this.label;
            };
            this.getDescription = function() {
                if (!this.desc) {
                    return "";
                }
                var combinedDesc = "";
                combinedDesc += this.desc;
                if (this.starRating) {
                    combinedDesc += "<br />";
                    combinedDesc += "<em>";
                    combinedDesc += this._starDescription();
                    combinedDesc += "</em>";
                }
                return combinedDesc;
            };
            this._starDescription = function() {
                return LOCALE.maketext("A maximum of [quant,_1,star,stars] is possible.", this.starRating);
            };
        }

        function DCVMethodsColumn(label, desc, starRating) {
            TableColumn.call(this, label, desc, starRating);
            this._starDescription = function() {
                var desc = "";
                desc += LOCALE.maketext("A maximum of 2 stars per method if the provider supports Ancestor DCV.");
                desc += " ";
                desc += LOCALE.maketext("Otherwise, a maximum of 1 star per method.");
                return desc;
            };
        }
        function SummaryColumn(label, desc, starRating) {
            TableColumn.call(this, label, desc, starRating);
            this.isScorePart = false;
        }

        _tableColumns[_tableColumns.length] = new TableColumn( LOCALE.maketext("Provider") );
        _tableColumns[_tableColumns.length] = new SummaryColumn( LOCALE.maketext("Usability Score"), LOCALE.maketext("The capabilities of a provider determine the provider’s rank."), MAX_USABILITY_SCORE);
        _tableColumns[_tableColumns.length] = new DCVMethodsColumn( LOCALE.maketext("DCV Methods"), LOCALE.maketext("The Domain Control Validation methods that the provider offers."), 4 );
        _tableColumns[_tableColumns.length] = new TableColumn( LOCALE.maketext("Ancestor DCV Support"), LOCALE.maketext("Whether the successful Domain Control Validation of a parent domain implies the success of a subdomain. For example, if “example.com” succeeds, “store.example.com” would succeed.") );
        _tableColumns[_tableColumns.length] = new TableColumn( LOCALE.maketext("Domains per Certificate"), LOCALE.maketext("The number of unique domains each certificate can contain."), 1 );
        _tableColumns[_tableColumns.length] = new TableColumn( LOCALE.maketext("Delivery Method"), LOCALE.maketext("The method that the provider uses to issue the certificate.") );
        _tableColumns[_tableColumns.length] = new TableColumn( LOCALE.maketext("Average Delivery Time"), LOCALE.maketext("The amount of time that the provider requires to issue a certificate."), 1 );
        _tableColumns[_tableColumns.length] = new TableColumn( LOCALE.maketext("Validity Period"), LOCALE.maketext("The amount of time before the certificate expires.") );
        _tableColumns[_tableColumns.length] = new TableColumn( LOCALE.maketext("Maximum Number of Redirects"), LOCALE.maketext("The maximum number of redirections a domain can use and still pass an HTTP-based Domain Control Validation."), 1 );

        _tableColumns[_tableColumns.length] = new TableColumn( LOCALE.maketext("Wildcard Support"), LOCALE.maketext("The provider supports wildcard domains."), 1 );

        function manageServiceFactory($q, $interval, PAGE) {

            function apiCallPromise(apiCall) {
                var deferred = $q.defer();
                API.promise(apiCall.getRunArguments())
                    .done(function(response) {
                        response = response.parsedResponse;

                        deferred[response.status ? "resolve" : "reject"](response);
                    });

                return deferred.promise;
            }

            // XXX TODO: Refactor this to be reusable.
            function _call_apiv1(call_info) {

                var apiCall = new APIREQUEST.Class();

                apiCall.initialize(NO_MODULE, call_info.func);

                if (call_info.data) {
                    for (var k in call_info.data) {
                        apiCall.addArgument(k, call_info.data[k]);
                    }
                }

                return apiCallPromise(apiCall);
            }

            // XXX TODO: Refactor this to be reusable.
            function _batch_apiv1(calls_infos) {
                var apiCall = new APIREQUEST.Class();
                apiCall.initialize(NO_MODULE, "batch");

                calls_infos.forEach(function(call, i) {
                    apiCall.addArgument(
                        ("command-" + i),
                        call.func + "?" + QUERY.make_query_string(call.data)
                    );
                });

                return apiCallPromise(apiCall);
            }

            // NB: There’s no particular reason to use epoch seconds here;
            // that’s just what this started off as, and changing it now
            // isn’t really worthwhile.
            function _convert_iso_to_epoch(things, key) {
                for (var r = 0; r < things.length; r++) {
                    if (!things[r][key]) {
                        continue;
                    }

                    things[r][key + "_epoch"] = Date.parse(things[r][key]) / 1000;
                }
            }

            var _bestSpecsList = ["AVERAGE_DELIVERY_TIME", "MAX_DOMAINS_PER_CERTIFICATE", "HTTP_DCV_MAX_REDIRECTS"];
            var _bestScores = {};

            function _updateUsabilityScore(provider) {
                var usabilityScore = 0;

                // For each DCV method ...
                usabilityScore += provider.specs.DCV_METHODS.length;

                // ... and counts double if ancestor dcv is supported
                if (provider.specs.SUPPORTS_ANCESTOR_DCV.toString() === "1") {
                    provider.specSpecifics["SUPPORTS_ANCESTOR_DCV"] = 1;
                    usabilityScore *= 2;
                }
                if (provider.specs.SUPPORTS_WILDCARD && provider.specs.SUPPORTS_WILDCARD.toString() === "1") {
                    provider.specSpecifics["SUPPORTS_WILDCARD"] = 1;
                    usabilityScore += 1;
                }
                _bestSpecsList.forEach(function(spec) {
                    if (provider.specs[spec] === _bestScores[spec]) {
                        provider.specSpecifics[spec] = 1;
                        usabilityScore++;
                    }
                });


                return usabilityScore;

            }

            var nullDefaults = {
                AVERAGE_DELIVERY_TIME: 1000000,
                RATE_LIMIT_CERTIFICATES_PER_REGISTERED_DOMAIN_PER_WEEK: -1,
                MAX_DOMAINS_PER_CERTIFICATE: -1,
            };

            // Find the best score based on
            function _findBestSpecScore(providers, spec) {

                if (_bestScores[spec]) {
                    return _bestScores[spec];
                }

                var findLowest = false;

                // These are best when they are highest
                // everything else is best when it's lowest
                if (["AVERAGE_DELIVERY_TIME"].indexOf(spec) !== -1) {
                    findLowest = true;
                }

                providers.forEach(function(provider) {
                    var value = _.isNil(provider.specs[spec]) && nullDefaults[spec] ? nullDefaults[spec] : provider.specs[spec];
                    if ( _.isUndefined(_bestScores[spec]) ) {
                        _bestScores[spec] = value;
                    } else if (spec === "RATE_LIMIT_CERTIFICATES_PER_REGISTERED_DOMAIN_PER_WEEK") {
                        if (_bestScores[spec] === 0) {

                            // Zero is the best score for this cause it's unlimited
                            return;
                        } else if (value.toString() === "0") {
                            _bestScores[spec] = 0;
                        } else {
                            if (value > _bestScores[spec]) {
                                _bestScores[spec] = value;
                            }
                        }
                    } else if ( findLowest && value < _bestScores[spec]) {
                        _bestScores[spec] = value;
                    } else if ( !findLowest && value > _bestScores[spec] ) {
                        _bestScores[spec] = value;
                    }
                });

                return _bestScores[spec];

            }

            // i.e., the system’s provider module setting
            var savedProviderModuleName;
            var currentProviderAccountID = PAGE.currentAccountID;

            PAGE.provider_info.forEach(function(p) {
                if (CJT_PARSE.parsePerlBoolean(p.enabled)) {
                    savedProviderModuleName = p.module_name;
                }
            });

            var metadataVars = [
                "clobber_externally_signed",
                "notify_autossl_expiry",
                "notify_autossl_expiry_coverage",
                "notify_autossl_renewal_coverage",
                "notify_autossl_renewal_coverage_reduced",
                "notify_autossl_renewal_uncovered_domains",
                "notify_autossl_renewal",
            ];

            metadataVars.forEach( function(v) {
                PAGE.metadata[v] = CJT_PARSE.parseInteger( PAGE.metadata[v] );
                if ( v !== "clobber_externally_signed" ) {
                    PAGE.metadata[v + "_user"] = CJT_PARSE.parseInteger( PAGE.metadata[v + "_user"] );
                }
            } );

            PAGE.constants.MIN_VALIDITY_DAYS_LEFT_BEFORE_CONSIDERED_ALMOST_EXPIRED = CJT_PARSE.parseInteger(
                PAGE.constants.MIN_VALIDITY_DAYS_LEFT_BEFORE_CONSIDERED_ALMOST_EXPIRED
            );

            var logsCatalog = _.sortBy(PAGE.logs_catalog, "start_time").reverse();

            // We save references to the $scope variables here upon view load.
            // That way, when/if the view is reloaded, we can grab any values
            // that we want to restore and put them into the controller.
            //
            // Note that the values on a saved scope will change after its
            // reference here is created.
            var SAVED_SCOPE = {};

            var providers = PAGE.provider_info;

            // Update the best scores because too many nest loops makes me uncomfortable
            _bestSpecsList.forEach(function(spec) {
                _findBestSpecScore(providers, spec);
            });

            providers.forEach(function(p) {

                p.specSpecifics = {};

                // so this checks the radio button correctly
                if (!p.x_terms_of_service_accepted) {
                    p.x_terms_of_service_accepted = "";
                }

                p.saved_x_terms_of_service_accepted = p.x_terms_of_service_accepted;

                p.usabilityScore = _updateUsabilityScore(p);
                p.maxUsabilityScore = MAX_USABILITY_SCORE;
            });

            providers.sort(function(a, b) {
                return b.usabilityScore - a.usabilityScore;
            });

            var nextAutosslCheckTime;
            var afterNextCheckRefresh;

            function refreshNextAutosslCheckTime() {
                return _call_apiv1({
                    func: "get_autossl_check_schedule",
                }).then(
                    function(resp) {
                        nextAutosslCheckTime = new Date(resp.data.next_time);
                        if (afterNextCheckRefresh) {
                            afterNextCheckRefresh(nextAutosslCheckTime);
                            afterNextCheckRefresh = null;
                        }

                        return nextAutosslCheckTime;
                    }
                );
            }

            // This is an interval, not a timeout, because it’s conceivable
            // that someone might tinker with their cron so that it only
            // runs once monthly. JS can’t handle timeouts greater than a
            // signed 32-bit integer, which gives us about 24 days.
            var nextTimeInterval;

            function nextTimeChecker() {
                var time = nextAutosslCheckTime;
                if (!time || time <= (new Date())) {
                    refreshNextAutosslCheckTime().then(function() {
                        if (!nextTimeInterval) {
                            nextTimeInterval = $interval(
                                nextTimeChecker,
                                60000 // 1 minute
                            );
                        }
                    });
                }
            }

            if (savedProviderModuleName) {
                nextTimeChecker();
            }

            function callProviderSetter(funcName, payload) {
                return _batch_apiv1([{
                    func: funcName,
                    data: payload,
                }, {
                    func: "get_autossl_check_schedule",
                }, {
                    func: "get_autossl_providers",
                }]).then(function(resp) {
                    var nextTimeIso = resp.data[1].parsedResponse.next_time;
                    nextAutosslCheckTime = new Date(nextTimeIso);

                    savedProviderModuleName = payload.provider;

                    var updatedProviders = resp.data[2].parsedResponse.data;

                    updatedProviders.forEach(function(provider) {
                        if (provider.enabled.toString() === "1") {
                            currentProviderAccountID = provider.x_account_id;
                        }
                    });

                    // This will set the interval to check whether
                    // it’s time to poll again.
                    nextTimeChecker();
                });
            }

            function _groom_logs_catalog(entries) {
                _convert_iso_to_epoch(entries, "start_time");
                for (var t = 0; t < entries.length; t++) {
                    entries[t].in_progress = CJT_PARSE.parsePerlBoolean(entries[t].in_progress);
                }
            }

            return {
                groom_logs_catalog: _groom_logs_catalog,

                get_next_autossl_check_time: function() {
                    return nextAutosslCheckTime;
                },

                refresh_next_autossl_check_time: refreshNextAutosslCheckTime,

                after_next_check_refresh: function(todoFn) {
                    if (typeof todoFn !== "function") {
                        throw "Needs a function!";
                    }

                    afterNextCheckRefresh = todoFn;
                },

                getTableColumns: function() {
                    return _tableColumns;
                },

                get_providers: function() {
                    return providers;
                },

                get_provider_display_name: function(p_mod_name) {
                    for (var p = 0; p < providers.length; p++) {
                        if (providers[p].module_name === p_mod_name) {
                            return providers[p].display_name;
                        }
                    }

                    return p_mod_name;
                },

                get_saved_provider_module_name: function() {
                    return savedProviderModuleName;
                },

                getSavedProviderAccountID: function getSavedProviderAccountID() {
                    return currentProviderAccountID;
                },

                // Called at the end of controller initialization.
                // The “key” identifies the view. If SAVED_SCOPE contains
                // a saved scope by that name, then we copy each of “props”
                // into the new scope. Once that’s done, “new_scope”
                // becomes the new SAVED_SCOPE[key], whose values will
                // be imported when/if the view is reloaded later.
                restore_and_save_scope: function(key, new_scope, props) {
                    if (SAVED_SCOPE[key]) {
                        props.forEach(function(p) {
                            new_scope[p] = SAVED_SCOPE[key][p];
                        });
                    }
                    SAVED_SCOPE[key] = new_scope;
                },

                get_logs_catalog: function() {
                    return logsCatalog;
                },

                refresh_logs_catalog: function() {
                    return _call_apiv1({
                        func: "get_autossl_logs_catalog",

                        // TODO: use abstraction layer
                        data: {
                            "api.sort.enable": 1,
                            "api.sort.a.field": "start_time",
                            "api.sort.a.reverse": 1,
                        },
                    }).then(
                        function(resp) {
                            resp = resp.data;
                            _groom_logs_catalog(resp, "start_time");
                            logsCatalog = resp;
                            return resp;
                        }
                    );
                },

                get_log: function(payload) {
                    return _call_apiv1({
                        func: "get_autossl_log",
                        data: payload,
                    }).then(
                        function(resp) {
                            resp = resp.data;
                            _convert_iso_to_epoch(resp, "timestamp");
                            return resp;
                        }
                    );
                },

                get_autossl_pending_queue: function() {
                    return _call_apiv1({
                        func: "get_autossl_pending_queue",
                    }).then(function(result) {
                        return result.data;
                    });
                },

                start_autossl_for_all_users: function() {
                    return _call_apiv1({
                        func: "start_autossl_check_for_all_users",
                    });
                },

                reset_provider_data: function(payload) {
                    return callProviderSetter(
                        "reset_autossl_provider",
                        payload
                    );
                },

                save_provider_data: function(payload) {
                    var promise;
                    if (payload.provider) {
                        promise = callProviderSetter(
                            "set_autossl_provider",
                            payload
                        );
                    } else {
                        promise = _call_apiv1({
                            func: "disable_autossl",
                        }).then(function() {
                            savedProviderModuleName = null;
                            $interval.cancel(nextTimeInterval);
                            nextAutosslCheckTime = null;
                        });
                    }

                    return promise;
                },

                metadata: PAGE.metadata,

                save_metadata: function() {
                    return _call_apiv1({
                        func: "set_autossl_metadata",
                        data: {
                            metadata_json: JSON.stringify(PAGE.metadata),
                        },
                    });
                },
            };
        }

        manageServiceFactory.$inject = ["$q", "$interval", "PAGE"];
        return app.factory("manageService", manageServiceFactory);
    }
);

/*
# templates/autossl/views/select_provider_controller.js
#                                                 Copyright(c) 2020 cPanel, L.L.C.
#                                                           All rights reserved.
# copyright@cpanel.net                                         http://cpanel.net
# This code is subject to the cPanel license. Unauthorized copying is prohibited
*/

/* global define: false */
/* jshint -W100 */

define(
    'app/views/select_provider_controller',[
        "lodash",
        "angular",
        "cjt/util/locale",
        "cjt/util/parse",
        "uiBootstrap",
        "cjt/directives/formWaiting",
    ],
    function(_, angular, LOCALE, CJT_PARSE) {
        "use strict";

        // Retrieve the current application
        // Or mock it for testing.
        var app;
        try {
            app = angular.module("App");
        } catch (e) {
            app = angular.module("App", []);
        }

        // Setup the controller
        var controller = app.controller(
            "select_provider_controller", [
                "$scope",
                "manageService",
                "growl",
                function($scope, manageService, growl) {
                    function _growlError(result) {
                        result.data && result.data.forEach(function(batchResponse) {
                            var parsedResponse = batchResponse.parsedResponse;
                            parsedResponse.messages.forEach(function(message) {
                                growl[message.level](_.escape(message.content));
                            });
                        });
                    }

                    function _convertMS(ms) {
                        var d, h, m, s, y;
                        s = Math.floor(ms / 1000);
                        m = Math.floor(s / 60);
                        s = s % 60;
                        h = Math.floor(m / 60);
                        m = m % 60;
                        d = Math.floor(h / 24);
                        h = h % 24;
                        y = Math.floor(d / 365);
                        d = d % 365;

                        return { y: y, d: d, h: h, m: m, s: s };
                    }

                    function _generateTimeString(timeObject) {
                        var timeString = [];
                        if (timeObject.y) {
                            timeString[timeString.length] = LOCALE.maketext("[quant,_1,year,years]", timeObject.y);
                        }
                        if (timeObject.d) {
                            timeString[timeString.length] = LOCALE.maketext("[quant,_1,day,days]", timeObject.d);
                        }
                        if (timeObject.h) {
                            timeString[timeString.length] = LOCALE.maketext("[quant,_1,hour,hours]", timeObject.h);
                        }
                        if (timeObject.m) {
                            timeString[timeString.length] = LOCALE.maketext("[quant,_1,minute,minutes]", timeObject.m);
                        }
                        if (timeObject.s) {
                            timeString[timeString.length] = LOCALE.maketext("[quant,_1,second,seconds]", timeObject.s);
                        }
                        return timeString.join("/");
                    }

                    function _getTimeString(value, unsetValue) {
                        if (!value) {
                            return unsetValue;
                        }

                        var fullTimeObject = _convertMS(value * 1000);

                        return _generateTimeString(fullTimeObject);
                    }

                    function _getFormattedSpec(specValue, specKey) {
                        specValue = _.isNil(specValue) ? "" : specValue;
                        var formattedSpec = specValue.toString();
                        switch (specKey) {
                            case "list_and_quoted":
                                formattedSpec = LOCALE.list_and_quoted(specValue);
                                break;
                            case "numf":
                                formattedSpec = LOCALE.numf(specValue);
                                break;
                            case "time_string":
                                formattedSpec = _getTimeString(specValue, LOCALE.maketext("[output,em,Unspecified]"));
                                break;
                            case "rate_limit":
                                formattedSpec = specValue.toString() === "0" ? LOCALE.maketext("unlimited") : specValue;
                        }
                        return formattedSpec.toString() === "" ? LOCALE.maketext("[output,em,Unspecified]") : formattedSpec.toString();
                    }

                    function _gather_save_data() { // eslint-disable-line camelcase
                        var providerModule = $scope.current_provider_module_name;

                        var providerObj = $scope.get_current_provider();

                        var tosAccepted = providerObj ? providerObj.x_terms_of_service_accepted : "";

                        var toSave = {
                            provider: providerModule
                        };
                        if (providerObj && providerObj.x_terms_of_service) {
                            toSave.x_terms_of_service_accepted = tosAccepted;
                        }

                        return toSave;
                    }

                    angular.extend($scope, {
                        providers: manageService.get_providers(),
                        showScoreDetails: false,
                        provider_by_module_name: {},
                        provider_submit_type: {},
                        current_provider_module_name: "",
                        getFormattedSpec: _getFormattedSpec,

                        toggleShowScoreDetails: function() {
                            $scope.showScoreDetails = !$scope.showScoreDetails;
                        },

                        get_current_provider: function() {
                            if ($scope.current_provider_module_name) {
                                return $scope.provider_by_module_name[$scope.current_provider_module_name];
                            }

                            return null;
                        },

                        getTableColumns: manageService.getTableColumns.bind(manageService),
                        getDetailsExplaination: function() {
                            var tableColumns = manageService.getTableColumns();
                            tableColumns = tableColumns.filter(function(column) {
                                return column.isScorePart;
                            }).map(function(column) {
                                return column.getLabel();
                            });
                            return LOCALE.maketext("This interface uses the following parameters to calculate the usability score: [list_and,_1].", tableColumns);
                        },

                        get_saved_provider_module_name: manageService.get_saved_provider_module_name,

                        do_submit: function() {
                            var toSave = _gather_save_data();

                            var providerObj = $scope.get_current_provider();

                            var toReset = ($scope.provider_submit_type[$scope.current_provider_module_name] === "reset");

                            var method;
                            if (toReset) {
                                method = "reset_provider_data";
                            } else {
                                method = "save_provider_data";
                            }

                            return manageService[method](toSave).then(
                                function() {
                                    var newProviderObj = $scope.provider_by_module_name[toSave.provider];

                                    if (toReset) {
                                        growl.success(LOCALE.maketext("You have created a new registration for this system with “[_1]” and configured [asis,AutoSSL] to use that provider.", _.escape(newProviderObj.display_name)));
                                    } else if (newProviderObj) {
                                        growl.success(LOCALE.maketext("You have configured [asis,AutoSSL] to use the “[_1]” provider.", _.escape(newProviderObj.display_name)));
                                    } else {
                                        growl.success(LOCALE.maketext("You have disabled [asis,AutoSSL]. Any users with [asis,SSL] certificates from [asis,AutoSSL] will continue to use them, but the system will not automatically renew these certificates."));
                                    }

                                    if (providerObj) {
                                        providerObj.saved_x_terms_of_service_accepted = providerObj.x_terms_of_service_accepted;
                                    }

                                    $scope.provider_submit_type[$scope.current_provider_module_name] = "";
                                },
                                _growlError
                            ).finally(function() {
                                $scope.$emit("provider-module-updated");
                            });
                        },
                    });

                    $scope.providers.forEach(function(p) {
                        if (CJT_PARSE.parsePerlBoolean(p.enabled)) {
                            $scope.current_provider_module_name = p.module_name;
                        }

                        $scope.provider_by_module_name[p.module_name] = p;
                    });

                    manageService.restore_and_save_scope(
                        "select_provider",
                        $scope, [
                            "current_provider_module_name",
                        ]
                    );
                }
            ]
        );

        return controller;
    }
);

/*
# templates/autossl/views/view_logs_controller.js Copyright(c) 2020 cPanel, L.L.C.
#                                                           All rights reserved.
# copyright@cpanel.net                                         http://cpanel.net
# This code is subject to the cPanel license. Unauthorized copying is prohibited
*/

/* global define, PAGE */
/* jshint -W100, -W089 */
/* eslint-disable camelcase */

define(
    'app/views/view_logs_controller',[
        "lodash",
        "angular",
        "cjt/util/locale",
        "cjt/core",
        "cjt/util/parse",
        "uiBootstrap",
        "cjt/directives/formWaiting",
    ],
    function(_, angular, LOCALE, CJT, CJT_PARSE) {
        "use strict";

        // Retrieve the current application
        var app = angular.module("App");

        // Setup the controller
        var controller = app.controller(
            "view_logs_controller", [
                "$scope",
                "$timeout",
                "manageService",
                "growl",
                "PAGE",
                function($scope, $timeout, manageService, growl, PAGE) {
                    function growlError(result) {
                        return growl.error( _.escape(result.error) );
                    }

                    manageService.groom_logs_catalog(PAGE.logs_catalog);

                    var providerDisplayName = {};
                    PAGE.provider_info.forEach( function(p) {
                        providerDisplayName[p.module_name] = p.display_name;
                    } );

                    // do this while CJT2’s CLDR is broken.
                    var cjt1_LOCALE = window.LOCALE;

                    var log_level_fontawesome = {

                        // warn: "fa-exclamation-triangle",
                        warn: "exclamation-triangle",
                        error: "minus-square",
                        out: "info-circle",
                        success: "check",
                    };

                    var log_level_localized = {
                        success: LOCALE.maketext("SUCCESS"),
                        warn: LOCALE.maketext("WARN"),
                        error: LOCALE.maketext("ERROR"),
                    };

                    var unparsable_template = LOCALE.maketext("Unparsable log data ([_1]):", "__ERR__");

                    angular.extend( $scope, {
                        log_level_localized: log_level_localized,

                        log_level_fontawesome: log_level_fontawesome,

                        logs_catalog: manageService.get_logs_catalog(),
                        chosen_log: manageService.get_logs_catalog()[0],

                        datetime: cjt1_LOCALE.local_datetime.bind(cjt1_LOCALE),

                        get_provider_display_name: manageService.get_provider_display_name,

                        fetch_logs_catalog: function() {
                            return manageService.refresh_logs_catalog().then(
                                function(catalog) {
                                    $scope.logs_catalog = catalog;
                                    var old_chosen_log = $scope.chosen_log;
                                    $scope.chosen_log = null;

                                    if (old_chosen_log) {
                                        for (var c = 0; c < catalog.length; c++) {
                                            if (old_chosen_log.provider !== catalog[c].provider) {
                                                continue;
                                            }
                                            if (old_chosen_log.start_time !== catalog[c].start_time) {
                                                continue;
                                            }

                                            $scope.chosen_log = catalog[c];
                                            break;
                                        }
                                    }

                                    if (!$scope.chosen_log) {
                                        $scope.chosen_log = catalog[0];
                                    }

                                    return;
                                },
                                growlError
                            );
                        },

                        // This optimization is ugly, but AngularJS was too slow
                        // when rendering thousands of DOM nodes.
                        _log_data_to_html: function(logs) {
                            var rows = [];

                            var log_level_html = {};
                            for (var key in log_level_localized) {
                                log_level_html[key] = _.escape(log_level_localized[key]);
                            }

                            var indentTimestamp;

                            for (var l = 0; l < logs.length; l++) {
                                var entry = logs[l];
                                var div_class = "logentry-" + entry.type;
                                if (("" + entry.indent) !== "0") {
                                    div_class += " indent" + entry.indent;
                                }
                                var r_html = "<div class='" + div_class + "'>";
                                if (log_level_fontawesome[entry.type]) {
                                    r_html += " <span class='fas fa-" + log_level_fontawesome[entry.type] + "'></span>";
                                }

                                var curIndentTimestamp = [entry.indent, entry.timestamp_epoch].join();

                                if ((curIndentTimestamp !== indentTimestamp) && entry.timestamp_epoch) {
                                    indentTimestamp = curIndentTimestamp;
                                    r_html += " <span>" + LOCALE.local_datetime(entry.timestamp_epoch, "time_format_medium") + "</span>";
                                }


                                if (log_level_localized[entry.type]) {
                                    r_html += " <span>" + log_level_html[entry.type] + "</span>";
                                }

                                if ("contents" in entry) {
                                    r_html += " " + _.escape(entry.contents);
                                } else {
                                    r_html += " <span class='log-unparsed'>??? " + unparsable_template.replace(/__ERR__/, _.escape(entry.parse_error)) + " " + _.escape(entry.raw) + "</span>";
                                }

                                r_html += "</div>";

                                rows.push(r_html);
                            }

                            return rows.join("");
                        },

                        log_submit: function() {
                            var loadData = Object.create($scope.chosen_log);

                            $scope.log_load_in_progress = true;

                            return manageService.get_log(loadData).then(
                                function(resp) {
                                    $scope.current_loaded_log = resp;
                                    $timeout(
                                        function() {
                                            document.getElementById("current_loaded_log_html").innerHTML = $scope._log_data_to_html(resp);
                                        }
                                    );

                                    loadData.start_time_epoch = $scope.chosen_log.start_time_epoch;
                                    $scope.last_load_data = loadData;
                                },
                                growlError
                            ).then( function() {
                                $scope.log_load_in_progress = false;
                            } );
                        },
                    } );

                    manageService.restore_and_save_scope(
                        "view_logs",
                        $scope,
                        [
                            "chosen_log",
                            "last_load_data",
                            "current_loaded_log",
                        ]
                    );
                }
            ]
        );

        return controller;
    }
);

/* global define, PAGE */

define(
    'app/services/AutoSSLConfigureService',[
        "angular",
        "lodash",
        "cjt/io/api",
        "cjt/io/whm-v1-request",
        "cjt/io/whm-v1", // IMPORTANT: Load the driver so it’s ready
    ],
    function(angular, _, API, APIREQUEST) {

        var app = angular.module("App");

        function AutoSSLConfigureServiceFactory($q, PAGE) {
            var AutoSSLConfigureService = {};

            var users = [];
            var usermap = {};
            var NO_MODULE = null;

            function _call_api(module, call, params, filters) {

                var deferred = $q.defer();
                var apiCall = new APIREQUEST.Class();
                apiCall.initialize(module, call);

                angular.forEach(params, function(param, key) {
                    apiCall.addArgument(key, param);
                });

                if (filters) {
                    angular.forEach(filters, function(filter) {
                        apiCall.addFilter(filter.key, filter.operator, filter.value);
                    });
                }

                API.promise(apiCall.getRunArguments())
                    .done(function(response) {
                        response = response.parsedResponse;
                        if (response.status) {
                            deferred.resolve(response);
                        } else {
                            deferred.reject(response.error);
                        }
                    });
                return deferred.promise;

            }

            function _build_batch_command(call, params) {
                var command_str = call;

                if (params) {
                    var command_params = [];
                    angular.forEach(params, function(value, key) {
                        command_params.push(key + "=" + encodeURIComponent(value));
                    });

                    command_str += "?" + command_params.join("&");
                }

                return command_str;
            }

            AutoSSLConfigureService._set_auto_ssl_for_users = function(items, enable) {

                /* enable the feature means disable the override */
                var features = JSON.stringify({
                    autossl: enable ? "1" : "0"
                });

                // This gets added to in the foreach loop. Format is necessary for batching.
                var params = {
                    command: []
                };

                angular.forEach(items, function(item) {
                    item.updating = true;
                    params.command.push(_build_batch_command("add_override_features_for_user", {
                        user: item.user,
                        features: features
                    }));
                });

                return _call_api(NO_MODULE, "batch", params).then(function() {
                    angular.forEach(items, function(item) {
                        item.auto_ssl_enabled = enable ? "enabled" : "disabled";
                    });
                }).finally(function() {
                    angular.forEach(items, function(item) {
                        item.updating = false;
                    });
                });
            };

            AutoSSLConfigureService.enable_auto_ssl_for_users = function(items) {
                return AutoSSLConfigureService._set_auto_ssl_for_users(items, true);
            };

            AutoSSLConfigureService.disable_auto_ssl_for_users = function(items) {
                return AutoSSLConfigureService._set_auto_ssl_for_users(items, false);
            };

            AutoSSLConfigureService.reset_auto_ssl_for_users = function(items) {

                /* enable the feature means disable the override */
                var features = JSON.stringify(["autossl"]);

                // This gets added to in the foreach loop. Format is necessary for batching.
                var params = {
                    command: []
                };

                angular.forEach(items, function(item) {

                    item.updating = true;
                    params.command.push(_build_batch_command("remove_override_features_for_user", {
                        user: item.user,
                        features: features
                    }));
                });

                return _call_api(NO_MODULE, "batch", params).then(function() {
                    angular.forEach(items, function(item) {
                        item.auto_ssl_enabled = "inherit";
                    });
                }).finally(function() {
                    angular.forEach(items, function(item) {
                        item.updating = false;
                    });
                });

            };

            AutoSSLConfigureService.get_user_by_username = function(username) {
                var user_i = usermap[username];
                return users[user_i];
            };

            AutoSSLConfigureService.get_users = function() {
                return users;
            };

            AutoSSLConfigureService.fetch_users = function() {

                function _update(data) {
                    users = [];
                    usermap = {};
                    angular.forEach(data, function(user) {
                        usermap[user.user] = users.length;
                        users.push({
                            "user": user.user,
                            "rowSelected": 0,
                            "updating": true,
                            "auto_ssl_settings": {}
                        });

                        /* set to true (has ssl) if not set to false by fetch_disabled */
                    });
                    return AutoSSLConfigureService.get_users();
                }

                if (PAGE.users) {
                    return _update(PAGE.users);
                } else {
                    PAGE.users = [];
                }

            };

            AutoSSLConfigureService.fetch_users_features_settings = function(users) {

                function _update(data) {
                    angular.forEach(data, function(setting) {
                        var user = AutoSSLConfigureService.get_user_by_username(setting.user);
                        user.feature_list = setting.feature_list;
                        user.auto_ssl_settings = setting;
                        user.auto_ssl_enabled = "inherit";
                        if (setting.cpuser_setting === "0" || setting.cpuser_setting === "1") {
                            user.auto_ssl_enabled = setting.cpuser_setting === "1" ? "enabled" : "disabled";
                        }
                    });
                    return AutoSSLConfigureService.get_users();
                }

                /* The API call will fail if no users are provided. */
                if (!users.length) {
                    return $q.reject();
                }

                return _call_api(NO_MODULE, "get_users_features_settings", {
                    "user": users.map(function(user) {
                        return user.user;
                    }),
                    "feature": "autossl"
                }).then(function(result) {
                    _update(result.data);
                }).finally(function() {
                    angular.forEach(users, function(user) {
                        user.updating = false;
                    });
                });

            };

            AutoSSLConfigureService.start_autossl_for_user = function(username) {
                return _call_api(
                    NO_MODULE,
                    "start_autossl_check_for_one_user", {
                        username: username
                    }
                );
            };

            return AutoSSLConfigureService;
        }

        AutoSSLConfigureServiceFactory.$inject = ["$q", "PAGE"];
        return app.factory("AutoSSLConfigureService", AutoSSLConfigureServiceFactory);
    });

/* global define: false */

define(
    'app/views/ManageUsersController',[
        "angular",
        "cjt/util/locale",
        "lodash",
        "uiBootstrap",
        "cjt/directives/toggleSortDirective",
        "cjt/directives/searchDirective",
        "cjt/directives/pageSizeDirective",
        "cjt/directives/toggleSwitchDirective",
        "cjt/filters/startFromFilter",
        "cjt/decorators/paginationDecorator",
        "ngSanitize",
    ],
    function(angular, LOCALE, _) {

        // Retrieve the current application
        var app = angular.module("App");

        // Setup the controller
        var controller = app.controller(
            "ManageUsersController", [
                "$scope", "$filter", "AutoSSLConfigureService", "ssl_users", "growl",
                function($scope, $filter, $service, ssl_users, growl) {
                    function _growl_error(error) {
                        if (!error) {
                            return;
                        }
                        return growl.error(_.escape(error));
                    }

                    $scope.users = ssl_users;
                    $scope.items = $scope.users;
                    $scope.selected_items = [];
                    $scope.filteredList = [];
                    $scope.showPager = true;
                    $scope.all_rows_selected = false;

                    $scope.meta = {

                        // sort settings
                        sortReverse: false,
                        sortBy: "user",
                        sortDirection: "asc",

                        // pager settings
                        maxPages: 0,
                        totalItems: $scope.items.length,
                        currentPage: 1,
                        pageSize: 10,
                        pageSizes: [10, 20, 50, 100],
                        start: 0,
                        limit: 10,

                        filterValue: "",
                    };

                    $scope.fetch = function() {
                        var filteredList = [];

                        // filter list based on search text
                        if ($scope.meta.filterValue !== "") {
                            filteredList = $filter("filter")($scope.items, $scope.meta.filterValue, false);
                        } else {
                            filteredList = $scope.items;
                        }

                        // sort the filtered list
                        if ($scope.meta.sortDirection !== "" && $scope.meta.sortBy !== "") {
                            filteredList = $filter("orderBy")(filteredList, $scope.meta.sortBy, $scope.meta.sortDirection === "asc" ? false : true);
                        }

                        // update the total items after search
                        $scope.meta.totalItems = filteredList.length;

                        // filter list based on page size and pagination
                        if ($scope.meta.totalItems > _.min($scope.meta.pageSizes)) {
                            var start = ($scope.meta.currentPage - 1) * $scope.meta.pageSize;
                            var limit = $scope.meta.pageSize;

                            filteredList = $filter("limitTo")($filter("startFrom")(filteredList, start), limit);
                            $scope.showPager = true;

                            // table statistics
                            $scope.meta.start = start + 1;
                            $scope.meta.limit = start + filteredList.length;

                        } else {

                            // hide pager and pagination
                            $scope.showPager = false;

                            if (filteredList.length === 0) {
                                $scope.meta.start = 0;
                            } else {

                                // table statistics
                                $scope.meta.start = 1;
                            }

                            $scope.meta.limit = filteredList.length;
                        }

                        var countNonSelected = $filter("filter")(filteredList, function(item) {
                            if (item.rowSelected) {
                                return false;
                            }
                            return true;
                        }).length;

                        $scope.filteredList = filteredList;

                        // Clear the 'Select All' checkbox if at least one row is not selected.
                        $scope.all_rows_selected = (filteredList.length > 0) && (countNonSelected === 0);

                        return filteredList;
                    };

                    $scope.can_run_check = function(user) {
                        if (user.auto_ssl_enabled === "enabled" || (user.auto_ssl_enabled === "inherit" && user.auto_ssl_settings.feature_list_setting.toString() === "1")) {
                            return true;
                        }
                    };

                    $scope.filter_table = function() {
                        $scope.fetch();
                        $scope.get_settings_for_current_users();
                    };

                    $scope.sort_table = function() {
                        $scope.fetch();
                        $scope.get_settings_for_current_users();
                    };

                    $scope.set_page = function() {
                        $scope.fetch();
                        $scope.get_settings_for_current_users();
                    };

                    $scope.set_page_size = function() {
                        $scope.fetch();
                        $scope.get_settings_for_current_users();
                    };

                    $scope.get_settings_for_current_users = function() {
                        $service.fetch_users_features_settings($scope.filteredList).then($scope.fetch, _growl_error);
                    };

                    $scope.showing_text = function() {
                        var first_item = ($scope.meta.currentPage - 1) * $scope.meta.pageSize;
                        first_item += 1;
                        var last_item = $scope.meta.currentPage * $scope.meta.pageSize;
                        last_item = Math.min(last_item, $scope.items.length);
                        return LOCALE.maketext("[output,strong,Showing] [numf,_1] - [numf,_2] of [quant,_3,item,items]", first_item, last_item, $scope.items.length);
                    };

                    $scope.enable_auto_ssl = function(items) {

                        // These are items that are "disabled" or "inherit"
                        var not_enabled_items = $filter("filter")(items, function(item) {
                            return item.auto_ssl_enabled !== "enabled";
                        });
                        if (not_enabled_items.length === 0) {
                            growl.info(LOCALE.maketext("No users needed to be updated."));
                            return;
                        }
                        return $service.enable_auto_ssl_for_users(not_enabled_items).then(function() {
                            $scope.items = $scope.users = $service.get_users();
                            var flat_user_list = not_enabled_items.map(function(item) {
                                return item.user;
                            });
                            if (flat_user_list.length > 5) {
                                growl.success(LOCALE.maketext("[quant,_1,user has had its,users have had their] feature list “[asis,autossl]” setting overridden and [numerate,_1,is,are] now set to “[_2]”", flat_user_list.length, LOCALE.maketext("enabled")));
                            } else {
                                growl.success(LOCALE.maketext("You forcibly enabled the [asis,autossl] feature for the following [numerate,_1,user,users]: [list_and_quoted,_2]", flat_user_list.length, flat_user_list));
                            }
                        }, _growl_error);
                    };

                    $scope.disable_auto_ssl = function(items) {

                        // These are items that are "enabled" or "inherit"
                        var not_disabled_items = $filter("filter")(items, function(item) {
                            return item.auto_ssl_enabled !== "disabled";
                        });
                        if (not_disabled_items.length === 0) {
                            growl.info(LOCALE.maketext("No users needed to be updated."));
                            return;
                        }
                        return $service.disable_auto_ssl_for_users(not_disabled_items).then(function() {
                            $scope.items = $scope.users = $service.get_users();
                            var flat_user_list = not_disabled_items.map(function(item) {
                                return item.user;
                            });
                            if (flat_user_list.length > 5) {
                                growl.success(LOCALE.maketext("[quant,_1,user has had its,users have had their] feature list “[asis,autossl]” setting overridden and [numerate,_1,is,are] now set to “[_2]”", flat_user_list.length, LOCALE.maketext("disabled")));
                            } else {
                                growl.success(LOCALE.maketext("You forcibly disabled the [asis,autossl] feature for the following [numerate,_1,user,users]: [list_and_quoted,_2]", flat_user_list.length, flat_user_list));
                            }
                        }, _growl_error);
                    };

                    $scope.reset_auto_ssl = function(items) {
                        items = $filter("filter")(items, function(item) {

                            /* no point in resetting reset ones */
                            if (item.auto_ssl_enabled === "inherit") {
                                return false;
                            }
                            return true;
                        });
                        if (items.length === 0) {
                            growl.info(LOCALE.maketext("No users needed to be updated."));
                            return;
                        }
                        return $service.reset_auto_ssl_for_users(items).then(function() {
                            $scope.items = $scope.users = $service.get_users();
                            var flat_user_list = items.map(function(item) {
                                return item.user;
                            });
                            if (flat_user_list.length > 5) {
                                growl.success(LOCALE.maketext("[quant,_1,user has had its,users have had their] feature list “[asis,autossl]” setting reset to use the setting established by [numerate,_1,its,their] feature [numerate,_1,list,lists]", flat_user_list.length));
                            } else {
                                growl.success(LOCALE.maketext("You reset the [asis,autossl] feature to the feature list setting for the following [numerate,_1,user,users]: [list_and_quoted,_2]", flat_user_list.length, flat_user_list));
                            }
                        }, _growl_error);
                    };

                    $scope.update_auto_ssl_setting = function(user, new_value) {

                        if (user.auto_ssl_enabled === new_value) {
                            return;
                        }

                        if (new_value === "inherit") {
                            $scope.reset_auto_ssl([user]);
                        } else if (new_value === "enabled") {
                            $scope.enable_auto_ssl([user]);
                        } else if (new_value === "disabled") {
                            $scope.disable_auto_ssl([user]);
                        }

                    };

                    $scope.start_autossl_for_user = function(username) {
                        return $service.start_autossl_for_user(username).then(
                            function(result) {
                                growl.success(LOCALE.maketext("The system is checking the “[_1]” account’s domains (process [asis,ID] “[_2]”).", _.escape(username), result.data.pid));
                            },
                            _growl_error
                        );
                    };

                    $scope.select_all_items = function(items, force_on) {

                        if (force_on) {
                            $scope.all_rows_selected = true;
                        }

                        angular.forEach(items, function(item) {
                            item.rowSelected = $scope.all_rows_selected;
                        });

                        $scope.selected_items = $scope.get_selected_items();
                        $scope.fetch();
                        $scope.get_settings_for_current_users();
                    };

                    $scope.clear_all_selections = function() {
                        angular.forEach($scope.items, function(item) {
                            item.rowSelected = 0;
                        });
                        $scope.selected_items = $scope.get_selected_items();
                        $scope.fetch();
                        $scope.get_settings_for_current_users();
                    };

                    $scope.select_item = function() {
                        $scope.selected_items = $scope.get_selected_items();
                        $scope.fetch();
                        $scope.get_settings_for_current_users();
                    };

                    $scope.get_selected_items = function() {
                        return $filter("filter")($scope.items, function(item) {
                            if (item.rowSelected) {
                                return true;
                            }
                        });
                    };

                    $scope.auto_ssl_items = function(items) {
                        return $filter("filter")(items, function(item) {
                            return item.auto_ssl_enabled === "enabled";
                        });
                    };

                    $scope.get_reset_string = function(user) {
                        if (user.auto_ssl_settings.feature_list_setting) {
                            return LOCALE.maketext("Use setting established by the feature list “[_1]” which is currently set to “[_2]”.", user.feature_list, user.auto_ssl_settings.feature_list_setting === "1" ? LOCALE.maketext("enabled") : LOCALE.maketext("disabled"));
                        } else {
                            return "";
                        }
                    };

                    $scope.get_enable_button_label = function() {
                        return LOCALE.maketext("Enable [asis,AutoSSL] on selected [quant,_1,user,users]", $scope.selected_items.length);
                    };

                    $scope.get_disable_button_label = function() {
                        return LOCALE.maketext("Disable [asis,AutoSSL] on selected [quant,_1,user,users]", $scope.selected_items.length);
                    };

                    $scope.get_reset_button_label = function() {
                        return LOCALE.maketext("Reset [asis,AutoSSL] on selected [quant,_1,user,users]", $scope.selected_items.length);
                    };

                    $scope.fetch();
                    $scope.get_settings_for_current_users();

                }
            ]
        );

        return controller;
    }
);

/*
# templates/autossl/views/OptionsController.js    Copyright(c) 2020 cPanel, L.L.C.
#                                                           All rights reserved.
# copyright@cpanel.net                                         http://cpanel.net
# This code is subject to the cPanel license. Unauthorized copying is prohibited
*/

/* global define, PAGE */
/* jshint -W100 */

define(
    'app/views/OptionsController',[
        "lodash",
        "angular",
        "cjt/util/locale",
        "cjt/core",
        "cjt/util/parse",
        "uiBootstrap",
        "cjt/directives/formWaiting",
    ],
    function(_, angular, LOCALE, CJT, CJT_PARSE) {
        "use strict";

        // Retrieve the current application
        var app = angular.module("App");

        var AUTOSSL_NOTIFICATIONS = {
            disable: [ ],
            certFailures: [ "notify_autossl_expiry", "notify_autossl_expiry_coverage", "notify_autossl_renewal_coverage_reduced", "notify_autossl_renewal_coverage" ]
        };

        AUTOSSL_NOTIFICATIONS.failWarnDefer = _.concat( AUTOSSL_NOTIFICATIONS.certFailures, "notify_autossl_renewal_uncovered_domains" );
        AUTOSSL_NOTIFICATIONS.all           = _.concat( AUTOSSL_NOTIFICATIONS.failWarnDefer, "notify_autossl_renewal" );

        // Setup the controller
        return app.controller(
            "OptionsController", [
                "$scope",
                "manageService",
                "growl",
                "PAGE",
                function($scope, manageService, growl, PAGE) {
                    function growlError(result) {
                        return growl.error( _.escape(result.error) );
                    }

                    angular.extend( $scope, {
                        metadata: manageService.metadata,

                        clobber_externally_signed_string: function() {
                            return LOCALE.maketext("This option will allow [asis,AutoSSL] to replace certificates that the [asis,AutoSSL] system did not issue. When you enable this option, [asis,AutoSSL] will install certificates that replace users’ [output,abbr,CA,Certificate Authority]-issued certificates if they are invalid or expire within [quant,_1,day,days].", PAGE.constants.MIN_VALIDITY_DAYS_LEFT_BEFORE_CONSIDERED_ALMOST_EXPIRED);
                        },

                        do_submit: function() {

                            _.each(AUTOSSL_NOTIFICATIONS.all, function(n) {
                                manageService.metadata[n] = 0;
                                manageService.metadata[n + "_user"] = 0;
                            });

                            _.each(AUTOSSL_NOTIFICATIONS[$scope.adminNotifications], function(n) {
                                manageService.metadata[n] = 1;
                            });

                            _.each(AUTOSSL_NOTIFICATIONS[$scope.userNotifications], function(n) {
                                manageService.metadata[n + "_user"] = 1;
                            });

                            return manageService.save_metadata().then(
                                function() {
                                    growl.success( LOCALE.maketext("Success!") );
                                },
                                growlError
                            );
                        }
                    } );

                    if ( manageService.metadata.notify_autossl_renewal ) {
                        $scope.adminNotifications = "all";
                    } else if ( manageService.metadata.notify_autossl_renewal_uncovered_domains ) {
                        $scope.adminNotifications = "failWarnDefer";
                    } else if ( _.find(AUTOSSL_NOTIFICATIONS.certFailures, function(n) {
                        return manageService.metadata[n];
                    }) ) {
                        $scope.adminNotifications = "certFailures";
                    } else {
                        $scope.adminNotifications = "disable";
                    }

                    if ( manageService.metadata.notify_autossl_renewal_user ) {
                        $scope.userNotifications = "all";
                    } else if ( manageService.metadata.notify_autossl_renewal_uncovered_domains_user ) {
                        $scope.userNotifications = "failWarnDefer";
                    } else if ( _.find(AUTOSSL_NOTIFICATIONS.certFailures, function(n) {
                        return manageService.metadata[n + "_user"];
                    }) ) {
                        $scope.userNotifications = "certFailures";
                    } else {
                        $scope.userNotifications = "disable";
                    }

                }
            ]
        );
    }
);

/*
# whostmgr/docroot/templates/autossl/index.js        Copyright 2022 cPanel, L.L.C.
#                                                           All rights reserved.
# copyright@cpanel.net                                         http://cpanel.net
# This code is subject to the cPanel license. Unauthorized copying is prohibited
*/

/* global define, require, PAGE */
/* jshint -W100 */
/* eslint-disable camelcase */

define(
    'app/index',[
        "lodash",
        "angular",
        "cjt/util/locale",
        "cjt/core",
        "cjt/util/parse",
        "cjt/modules",
        "uiBootstrap",
        "cjt/directives/actionButtonDirective",
        "app/directives/starRating",
    ],
    function(_, angular, LOCALE, CJT) {
        "use strict";

        CJT.config.html5Mode = false;

        return function() {
            angular.module("App", [
                "cjt2.config.whm.configProvider", // This needs to load before any of its configured services are used.
                "ngRoute",
                "ui.bootstrap",
                "angular-growl",
                "cjt2.whm",
                "whostmgr.autossl.starRating",
            ]);

            var app = require(
                [
                    "cjt/bootstrap",

                    // Application Modules
                    "uiBootstrap",
                    "app/services/manageService",
                    "app/views/select_provider_controller",
                    "app/views/view_logs_controller",
                    "app/services/AutoSSLConfigureService",
                    "app/views/ManageUsersController",
                    "app/views/OptionsController",
                ],
                function(BOOTSTRAP) {

                    var tab_configs = [{
                        path: "/providers/",
                        label: LOCALE.maketext("Providers"),
                        controller: "select_provider_controller",
                        templateUrl: CJT.buildFullPath("autossl/views/select_provider.ptt"),
                    }, {
                        path: "/options/",
                        label: LOCALE.maketext("Options"),
                        controller: "OptionsController",
                        templateUrl: CJT.buildFullPath("autossl/views/options.ptt"),
                    }, {
                        path: "/view-logs/",
                        label: LOCALE.maketext("Logs"),
                        controller: "view_logs_controller",
                        templateUrl: CJT.buildFullPath("autossl/views/view_logs.ptt"),
                    }, {
                        path: "/manage-users/",
                        label: LOCALE.maketext("Manage Users"),
                        controller: "ManageUsersController",
                        templateUrl: CJT.buildFullPath("autossl/views/manage-users.ptt"),
                        resolve: {
                            "ssl_users": ["AutoSSLConfigureService",
                                function(service) {
                                    return service.fetch_users();
                                },
                            ],
                        },
                    }];
                    var default_tab = tab_configs[0].path;

                    var app = angular.module("App");

                    app.value("PAGE", PAGE);

                    app.controller("BaseController", [
                        "$rootScope",
                        "$scope",
                        "$route",
                        "$location",
                        "manageService",
                        "AutoSSLConfigureService",
                        "growl",
                        function($rootScope, $scope, $route, $location, manageService, AutoSSLConfigureService, growl) {
                            $scope.loading = false;
                            $scope.activeTabs = [];

                            // Convenience functions so we can track changing views for loading purposes
                            $rootScope.$on("$routeChangeStart", function(eo, next) {
                                $scope.onLoadTab(next.path);
                                $scope.active_path = next.path;
                                $scope.loading = true;
                            });
                            $rootScope.$on("$routeChangeSuccess", function() {
                                $scope.loading = false;
                            });
                            $rootScope.$on("$routeChangeError", function() {
                                $scope.loading = false;
                                $scope.go("providers");
                            });

                            $scope.current_route_matches = function(key) {
                                return $location.path().match(key);
                            };

                            $scope.onLoadTab = function(loaded_path) {
                                $scope.activeTabs.forEach(function(value, key) {
                                    if (value.path === loaded_path) {
                                        $scope.currentTab = key;
                                    }
                                });
                            };

                            $scope.updated_current_module = function() {
                                $scope.current_provider_module = manageService.get_saved_provider_module_name();
                            };

                            $scope.$on("provider-module-updated", function() {
                                $scope.updated_current_module();
                            });

                            $scope.go = function(path) {
                                $location.path(path);
                            };

                            function init() {
                                $scope.activeTabs = tab_configs;
                                $scope.updated_current_module();
                            }

                            init();

                            // ----------------------------------------------------------------------
                            // Should the following be in its own view?
                            function _growl_error(result) {
                                return growl.error(_.escape(result.error));
                            }

                            angular.extend($scope, {
                                next_check_time_string: function() {
                                    var time = manageService.get_next_autossl_check_time();
                                    if (time) {

                                        // datetime() always kicks out UTC.
                                        // We could use local_datetime(), but
                                        // that would break compatibility with
                                        // Perl’s Locale, which doesn’t have
                                        // local_datetime(). So, instead we
                                        // “trick” datetime() by feeding it
                                        // an offset epoch seconds count.
                                        var compensated_time = time;
                                        compensated_time -= 60 * 1000 * time.getTimezoneOffset();
                                        compensated_time /= 1000;

                                        return LOCALE.maketext("This system’s next regular [asis,AutoSSL] check will occur at [datetime,_1,time_format_short].", Math.round(compensated_time));
                                    }
                                },

                                getSavedProviderAccountID: manageService.getSavedProviderAccountID.bind(manageService),

                                getCurrentProviderDisplayName: function() {
                                    return manageService.get_provider_display_name(manageService.get_saved_provider_module_name());
                                },

                                get_saved_provider_module_name: manageService.get_saved_provider_module_name,

                                start_autossl_for_all_users: function() {
                                    return manageService.start_autossl_for_all_users().then(
                                        function(result) {
                                            growl.success(LOCALE.maketext("[asis,AutoSSL] is now checking all users. The process has [asis,ID] “[_1]”.", result.data.pid));
                                        },
                                        _growl_error
                                    );
                                },
                            });
                        },
                    ]);

                    app.config(["$routeProvider",
                        function($routeProvider) {

                            tab_configs.forEach(function(tab) {
                                $routeProvider.when(tab.path, tab);
                            });

                            // default route
                            $routeProvider.otherwise({
                                "redirectTo": default_tab,
                            });
                        },
                    ]);

                    BOOTSTRAP();

                });

            return app;
        };
    }
);

Back to Directory File Manager