Jason
Jason

Reputation: 1151

Angular password generator service

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
    };

});

Upvotes: 0

Views: 1751

Answers (1)

d3l33t
d3l33t

Reputation: 890

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"

Upvotes: 1

Related Questions