Viewing File: /usr/local/cpanel/share/libraries/cjt2/src/directives/displayPasswordStrength.js

/*
# cjt/directives/displayPasswordStrength.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(
    [
        "angular",
        "cjt/core",
        "cjt/templates" // NOTE: Pre-load the template cache
    ],
    function(angular, CJT) {

        var RELATIVE_PATH = "libraries/cjt2/directives/displayPasswordStrength.phtml";

        var DEFAULT_STYLES = [
            "strength-0",
            "strength-1",
            "strength-2",
            "strength-3",
            "strength-4"
        ];

        var module = angular.module("cjt2.directives.displayPasswordStrength", [
            "cjt2.templates"
        ]);

        /**
         * Directive that shows the password strength in a meter bar.
         * @attribute [fieldId] Optional field id, used to correlate the message from the strength service. Not needed
         * if only one password strength field is used on the view.
         * @attribute [styles]  Optional comma delimited list of css class names for the colors. Must be 4 items in the
         * list or the directive will use the defaults.
         * @attribute [calculateColorBreak] Optional function to process the strength increment process. The function should return
         * a structure with the following layout:
         *   {
         *       index: <number>,  // Number 1 to 5 for the slot to fill too.
         *       color: <string>   // CSS class name to use to do the fill for slots 1 to index.
         *   }
         * If not provided, the built in function uses a step-wise linear algorithm breaking every 20 units for 0 to 100.
         * @example
         *
         * <div displayPasswordStrength></div>
         */
        module.directive("displayPasswordStrength", function() {
            return {
                replace: true,
                restrict: "EACM",
                templateUrl: CJT.config.debug ? CJT.buildFullPath(RELATIVE_PATH) : RELATIVE_PATH,
                scope: {
                    fieldId: "@?fieldId",
                    styles: "@?styles",
                    calculateColorBreak: "&calculateColorBreak",
                    testId: "@?testId"
                },
                compile: function(element, attrs) {
                    return {
                        pre: function(scope, element, attrs) {
                            if (!angular.isUndefined(attrs.styles)) {
                                var styles = (attrs.styles + "").split(",");
                                if (styles.length < 5) {
                                    throw "You must provide a list of 5 css class names if you are implementing custom styles";
                                } else {
                                    scope.styles = styles;
                                }
                            }
                        },

                        post: function(scope, el, attrs) {
                            var colors = scope.styles && scope.styles.length === 5 ? scope.styles : DEFAULT_STYLES;
                            var allClasses = colors.join(" ");

                            /**
                             * Get the color related to the indicated password strength. This is the
                             * default implementation. User can override this behavior with their own
                             * method.
                             *
                             * @private
                             * @method calculateColorBreak
                             * @param  {Number} strength - current strength
                             * @param  {Array}  colors - list of css class names
                             * @return {Object}
                             *   {Number} index Position to update: 1 to 5.
                             *   {String} color Color to use with this strength.
                             */
                            var _calculateColorBreak  = function(strength, colors) {
                                var index = 0;
                                if (strength <= 20) {
                                    index = 0;
                                } else if (strength <= 40) {
                                    index = 1;
                                } else if (strength <= 60) {
                                    index = 2;
                                } else if (strength <= 80) {
                                    index = 3;
                                } else {
                                    index = 4;
                                }

                                return {
                                    index: index + 1,
                                    color: colors[index]
                                };
                            };


                            if (scope.calculateColorBreak) {
                                scope.calculateColorBreak = _calculateColorBreak;
                            }

                            // Monitor for the passwordStrengthChange event
                            scope.$on("passwordStrengthChange", function(evt, result) {
                                if ( !angular.isUndefined(scope.fieldId) && scope.fieldId !== result.id ) {

                                    // This is not for us since its a
                                    // message not related to our caller.
                                    return;
                                }

                                var hasPassword = result.hasPassword;
                                var strength = result.strength;

                                if (!hasPassword) {
                                    el.children("li")
                                        .removeClass(allClasses);
                                } else {
                                    var colorBreak = scope.calculateColorBreak(strength, colors);
                                    el.children("li")
                                        .removeClass(allClasses)
                                        .slice(0, colorBreak.index)
                                        .addClass(colorBreak.color);
                                }
                            });
                        }
                    };
                }
            };
        });

        return {
            DEFAULT_STYLES: DEFAULT_STYLES
        };
    }
);
Back to Directory File Manager