We launched new forums in March 2019—join us there. In a hurry for help with your website? Get Help Now!
    • 21459
    • 10 Posts
    I was looking for a way to check (and force) the strength of new passwords when manager users change their password. Since I didn’t find anything in the forums, I implemented one myself, and here it is. It’s all javascript. The code is probably ugly - all comments are welcome!

    Context: When you’re logged in as a manager user, you can change your password by clicking on the "Change password" link at the manager’s top right corner. You arrive to a page asking you to type your new password in the first field and to type it again in the second field as confirmation.

    This modification does the following:
    - First of all, it hides the "Save" Button at the top right to prevent the manager user from trying to save a bad password.
    - As the manager user types its password in the first field, the script checks the string upon specific schemes (password long enough, at least one digit, at least one punctuation mark, mix of uppercase/lowercase, and no forbidden characters) and displays the relevant comment: "Type a password" (default), "More characters needed", "Weak", "Medium", "Strong enough" or "Character not allowed".
    - As the manager user types the password in the second field again, the script checks if the second password equals the first one. If it does, a message "OK" appears next to it, the "Save" button is displayed again and the manager user can save the new password.

    By the way, it makes the small verifications included in "manager/processors/save_password.processor.php" unnecessary.

    Here are the modifications. It looks big, but it is quite straightforward.
    I grabbed the javascript password strentgh checker from this page: http://marketingtechblog.com/programming/javascript-password-strength/ and adapted it a bit.

    Everything happens in the file "/manager/actions/mutate_password.dynamic.php".

    1- Before line 14:
    <h1><?php echo $_lang['change_password']?></h1>

    we insert most of the javascript code:
    <script type="text/javascript">
    // Define the various messages
    var msgDefault = '<span>Type your password</span>';
    var msgMore = '<span>More characters needed</span>';
    var msgWeak = '<span style="color: red;">Weak...</span>';
    var msgMedium = '<span style="color: orange;">Medium...</span>';
    var msgStrong = '<span style="color: green;">Strong enough!</span>';
    var msgWrong = '<span style="font-weight: bolder;">Character not allowed!</span>';
    
    // start with a wrong password
    var goodPassword = false;
    
    // Hide the Save button
    function hideSave() {
      var saveButton = document.getElementById("save_icon");
      saveButton.style.visibility = "hidden";
    }
    
    // Show the save button
    function showSave() {
      var saveButton = document.getElementById("save_icon");
      saveButton.style.visibility = "visible";
    }
    
    // Check the password
    function passwordChanged() {
      var strength = document.getElementById('strength');
      var wrongRegex = new RegExp ("['|\"|\\\\]");
      var strongRegex = new RegExp("^(?=.{8,})(?=.*[A-Z])(?=.*[a-z])(?=.*[0-9])(?=.*\\W).*$", "g");
      var mediumRegex = new RegExp("^(?=.{7,})(((?=.*[A-Z])(?=.*[a-z]))|((?=.*[A-Z])(?=.*[0-9]))|((?=.*[a-z])(?=.*[0-9]))).*$", "g");
      var enoughRegex = new RegExp("(?=.{6,}).*", "g");
      var pwd = document.getElementById("pass1");
      var saveButton = document.getElementById("save_icon");
      goodPassword = false;
      hideSave();
      if (false == wrongRegex.test(pwd.value)) {
        if (pwd.value.length==0) {
          strength.innerHTML = msgDefault;
        } else if (false == enoughRegex.test(pwd.value)) {
          strength.innerHTML = msgMore;
        } else if (strongRegex.test(pwd.value)) {
          strength.innerHTML = msgStrong;
          goodPassword = true;
        } else if (mediumRegex.test(pwd.value)) {
          strength.innerHTML = msgMedium;
        } else {
          strength.innerHTML = msgWeak;
        }
      } else {
        strength.innerHTML = msgWrong;
      }
    }
    
    // Check the confirmation password
    function confirmChanged() {
      var pwd1 = document.getElementById("pass1");
      var pwd2 = document.getElementById("pass2");
      var confirm = document.getElementById("confirmation");
      confirm.innerHTML = "";
      hideSave();
      if ((pwd1.value == pwd2.value) && (goodPassword == true)) {
        confirm.innerHTML = "OK";
        showSave();
      }
    }
    
    </script>
    


    2 - Within the html form, we add the necessary "id" and "name" tags to the elements that we are going to handle with javascript, along with the spans displaying the messages next to each field:

    For the Save button, replace the line:
    <li><a href="#" onclick="documentDirty=false; document.userform.save.click();"><img src="<?php echo $_style["icons_save"]?>" /> <?php echo $_lang['save']?></a></li>
    

    with the line:
    <li><a id="save_icon" name="save_icon" href="#" onclick="documentDirty=false; document.userform.save.click();"><img src="<?php echo $_style["icons_save"]?>" /> <?php echo $_lang['save']?></a></li>
    


    For the first password, replace the line:
    <td><input type="password" name="pass1" class="inputBox" style="width:150px" value=""></td>
    

    with the line:
    <td><input type="password" name="pass1" id="pass1" class="inputBox" style="width:150px" value="" onkeyup="return passwordChanged();"><span id="strength" style="margin-left: 10px;">Type your password</span></td>
    


    For the confirmation password, replace the line:
    <td><input type="password" name="pass2" class="inputBox" style="width:150px" value=""></td>
    

    with the line:
    <td><input type="password" name="pass2" id="pass2" class="inputBox" style="width:150px" value="" onkeyup="return confirmChanged();"><span id="confirmation" style="margin-left: 10px;"> </span></td>
    


    3 - At the end of the file, insert a call to the hideSave() function:
    <script type="text/javascript">
    // hide the Save button when page is loaded
    hideSave();
    </script>
    


    4 - One last thing: we insert a comment explaining the password requirements:
    After the line:
    <p><?php echo $_lang['change_password_message']?></p>
    

    insert the line:
    <p><?php echo $_lang['change_password_message_comment']?></p>
    


    and add the corresponding string to "/manager/includes/lang/english.inc.php" (or the language you use):
    $_lang["change_password_message_comment"] = '<strong>Notice:</strong> Your password needs to be between 8 and 15 characters long. It must contain at least one digit, a mix of uppercase and lowercase letters, and at least one punctuation mark. Please note that the single quote (\'), double quote (") and backslash (\) are not allowed.';
    


    Note: I added the "forbidden characters" (single quote, double quote and backslash) because the password is then directly inserted into the MySQL database - see the file "manager/processors/save_password.processor.php". By the way, this would allow some SQL injection, wouldn’t it? I guess this is not a serious risk since we are already in the manager!? (In your non-modified "Change password" page, try a new password with a single quote in it...)

    That’s it, it works here with IE8, FF3.6 and Safari 4 (all Win32).
    The modified file "/manager/actions/mutate_password.dynamic.php" is attached (but don’t forget to add the new string in your language file, see step 4 above).

    [EDIT 2/18/10] corrected function confirmChanged() to hide confirmation message if necessary.

    Nicochto
    --
    MODx Evo 1.0.2