0

I have a password generator and I was using it in two different controllers so I thought I should move it into a service.

  1. I am not 100% sure a service is the best approach and would like to know what is if it is not.
  2. I am running into one problem. The service sends back a passWord object when I update the password input field I have to use ng-model="passWord.password".

Here is the problem:

Because the form has other fields that use user.VALUE I need to have my password field read ng-model="user.password" but this is breaking in the service. Below is the code.

Service:

app.factory('PassWord', function($resource, $log, $rootScope, $location, $sessionStorage, $q, Data){

    var passWord = {
        inputType:"password",
        showPwTxt:"Show"
    };

    // Hide & show password function
    passWord.hideShowPassword = function(){
        if (passWord.inputType == 'password') {
            type = 'text';
            txt = 'Hide';
        }
        else {
          type = 'password';
          txt = 'Show';
        }

        passWord.inputType = type;
        passWord.showPwTxt = txt;

    };

    // test for medium and strong passwords
    var strongRegex = new RegExp("^(?=.*[a-z])(?=.*[A-Z])(?=.*[0-9])(?=.*[-!@#\"\$%\^&\*()_+|=\\]\\[{}~`:\";\'<>?,.\/])(?=.{8,})");
    var mediumRegex = new RegExp("^(((?=.*[a-z])(?=.*[A-Z]))|((?=.*[a-z])(?=.*[0-9]))|((?=.*[A-Z])(?=.*[0-9])))(?=.{6,})");

    // create an object for the pw strength
    passWord.passwordStrength = {};

    passWord.analyze = function(value) {
        if(strongRegex.test(value)) {
            color = "#57A83F";
            txt = "Strong";
        } else if(mediumRegex.test(value)) {
            color = "#FF9800";
            txt = "Medium";
        } else {
            color = "#E03930";
            txt = "Weak";
        }

        passWord.passwordStrength["color"] = color;
        passWord.pwStrengthTxt = txt;

    };

    // password generator
    passwordLength = 12;
    addUpper       = true;
    addNumbers     = true;
    addSymbols     = true;

    passWord.createPassword = function(){
        var lowerCharacters = ['a', 'b', 'c', 'd', 'e', 'f', 'g', 'h', 'i', 'j', 'k', 'l', 'm', 'n', 'o', 'p', 'q', 'r', 's', 't', 'u', 'v', 'w', 'x', 'y', 'z'];
        var upperCharacters = ['A', 'B', 'C', 'D', 'E', 'F', 'G', 'H', 'I', 'J', 'K', 'L', 'M', 'N', 'O', 'P', 'Q', 'R', 'S', 'T', 'U', 'V', 'W', 'X', 'Y', 'Z'];
        var numbers = ['0','1','2','3','4','5','6','7','8','9'];
        var symbols = ['!', '"', '#', '$', '%', '&', '\'', '(', ')', '*', '+', ',', '-', '.', '/', ':', ';', '<', '=', '>', '?', '@', '[', ']', '^', '_', '`', '{', '|', '}', '~'];
        var finalCharacters = lowerCharacters;
        //if(passWord.addUpper){
            finalCharacters = finalCharacters.concat(upperCharacters);
        //}
        //if(passWord.addNumbers){
            finalCharacters = finalCharacters.concat(numbers);
        //}
        //if(passWord.addSymbols){
            finalCharacters = finalCharacters.concat(symbols);
        //}
        var passwordArray = [];
        for (var i = 1; i < passwordLength; i++) {
            passwordArray.push(finalCharacters[Math.floor(Math.random() * finalCharacters.length)]);
        };

        //update the passwrod input field in the form
        passWord.password = passwordArray.join("");

        //analyze thepassword strength
        passWord.analyze(passWord.password);

        if(passWord.pwStrengthTxt == "Medium" || passWord.pwStrengthTxt == "Weak") {
            passwordArray = [];
            passWord.createPassword();
        }
    };

    return passWord;
});

HTML:

<form name="resetForm" class="" role="form">

    <div class="form-group row" ng-show="!uid">

        <div class="col-sm-12">

            <input type="email" class="form-control" placeholder="Email" name="email" ng-model="user.email" ng-required="!uid"/>

            <span ng-show="!resetForm.email.$error.required && !resetForm.email.$error.email" class="glyphicon glyphicon-ok form-control-feedback" ></span>

            <span ng-show="resetForm.email.$touched">
                <small class="errorMessage" data-ng-show="resetForm.email.$error.required">Email is required.</small>
            </span>

            <small class="errorMessage" ng-show="resetForm.email.$error.email">Email is not valid</small>

        </div>

    </div>

    <div class="form-group row" ng-hide="!uid">
        <div class="col-sm-12">
            <span class="block input-icon input-icon-right">
                <div class="input-group">
                <input type="{{passWord.inputType}}" class="form-control" name="password" placeholder="Password" ng-minlength="6" ng-model="passWord.password" ng-change="passWord.analyze(passWord.password)" ng-required="uid"/>
                <span id="spnPassword" class="add-on input-group-addon" ng-click="passWord.hideShowPassword()" style="cursor:pointer;">{{passWord.showPwTxt}}</span>
                </div>
                <span ng-hide="resetForm.password.$error.required || resetForm.password.$error.minlength" class="glyphicon glyphicon-ok form-control-feedback" ></span>
                <small class="errorMessage" ng-show="resetForm.password.$error.minlength">Too short! Minimum 6 characers</small>
            </span>
            <div ng-show="passWord.password.length">
                <small>Password strength: <span ng-style="passWord.passwordStrength">{{passWord.pwStrengthTxt}}</span></small>
            </div>
            <br>
            <button type="button" class="btn btn-sm btn-primary" data-ng-click="passWord.createPassword()">Generate Password</button>
        </div>
    </div>

    <div class="clearfix">
        <div class="row">

            <span class="lbl col-sm-7"><span ng-show="!uid">Remembered your password? <a href="login">SignIn</a></span></span>

            <div class="col-sm-5 text-right">
                <button type="submit" class="btn btn-info" ng-click="resetPassword(user)" data-ng-disabled="resetForm.$invalid">Reset Password</button>
            </div>

        </div>
    </div>

</form>

CONTROLLER:

app.controller('resetCtrl', function ($scope, $rootScope, $log, $routeParams, $location, $http, Data, PassWord) {

    $scope.user = {email:'',password:''};

    $scope.passWord = PassWord;

    $scope.resetPassword = function (user) {
        $log.log('user is - ',user);
        // Do Stuff
    };

});
4
  • why not $scope.user.password = PassWord.createPassword() then in your template change ng-model="passWord.password" to ng-model="user.password" Commented May 19, 2016 at 16:54
  • 1
    <button type="button" class="btn btn-sm btn-primary" data-ng-click="passWord.createPassword()">Generate Password</button> should be <button type="button" class="btn btn-sm btn-primary" data-ng-click="generateNew()">Generate Password</button> then in scope $scope.createPassword = function(){ $scope.user.password = PassWordcreatePassword() } Commented May 19, 2016 at 16:56
  • Thank you @d3l33t that worked. Commented May 19, 2016 at 18:19
  • No problem! I posted an answer so we can mark resolved. Commented May 19, 2016 at 18:33

1 Answer 1

1

Services seem like a good way to handle this. Just adjust your code slightly to support the password field on the user object. then abstract the service method in the controller so you can update your scope.

app.controller('resetCtrl', function ($scope, $rootScope, $log, $routeParams, $location, $http, Data, PassWord) {

    $scope.user = {email:'',password:''};

    $scope.user.password = PassWord.createPassword();

    $scope.generateNewPassword = function() {
        $scope.user.password = PassWord.createPassword();
    }
});

Then update template with new generate password function

<button type="button" class="btn btn-sm btn-primary" data-ng-click="generateNewPassword()">Generate Password</button>

Also update the password model in your input box to match the user object ng-model="passWord.password" to ng-model="user.password"

Sign up to request clarification or add additional context in comments.

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.