-3

I wrote a regex in javascript for password validation but it works also for non valid passwords. The password must be 8 chars long, contain one letter , one number and one special character but when I enter something like "abcd" it also works. Here is the code :

function nonValidPassword(e){

    let userPassword = document.getElementById("register-password").value;
    const passwdMessage = document.getElementById("password-validation-message");
    const registerButton = document.getElementById("register-button");
    let validPassword = new RegExp("^(?=.*[a-zA-Z])(?=.*[0-9])(?=.*[!@#\$%\^&\*])(?=.{8,})");
    let passwordChecker = validPassword.test(userPassword);
    
    if (passwordChecker==false){
        e.preventDefault();
        alert("PLEASE ENTER A VALID PASSWORD!");
        
    }
    
    else
    {
        document.form.submit();
        
    }
}


registerButton.addEventListener('click',nonValidPassword);

The backend is flask :

from flask import Flask,render_template,request,redirect,url_for
import model
import datetime

app = Flask(__name__)


@app.route("/",methods=["POST","GET"])
def login():
    if request.method == "GET":
        return render_template("login.html")
    else:
        email = request.form["email"]
        username= request.form["username"]
        password = request.form["password"]
        username_exists = model.check_if_username_exists(username)
        if username_exists:
            return render_template("register.html",infoMsg=f"sorry, the username {username} already exists! ")
        else:
            model.register_new_user(email,username,password)
            return render_template("login.html",infoMsg=f"{username} successfully registered!")

@app.route("/register")
def register():
    return render_template("register.html")

this is the template:

<!DOCTYPE html>
<html lang="en">
<head>
   
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <link rel="stylesheet" href="static/style.css">
    <link href="https://fonts.googleapis.com/css2?family=Jua&display=swap" rel="stylesheet">
    <title>Calendar Lite</title>
</head>
<body>
    
    <div class="login-container">
       
        
    
    <div class="login-field">
        
     <form method="POST" action="/" id="login-form">
            {{infoMsg}}
            <div id="password-validation-message"></div>
            <h1>Please enter the following parameters: </h1>
            <label for="username">Username:</label>
            <input type="text" name="username" ><br><br>
            <label for="username">Email:</label>
            <input type="text" name="email" ><br><br>
            <label for="password">Password (must at least 8 characters long, should have at least one alphabet letter, one special character and at least one number.):</label><br>
            <input type="password" name="password" id="register-password"><br><br>
            <button type="submit" class="btn-submit" id="register-button">REGISTER</button><br><br>

            <h4><a href="/" class="btn"> I have an account</a></h4>
          </form>

    
          
            
    </div>

    <img src="static/login-picture.png" alt="pic" class="login-picture" width="1000px">
    </div>

    <script src="static/register.js"></script>
</body>
</html>
outlier11
  • 1
  • 1
  • 1
    It seems that your Regex is fine and I was able to [validate your code](https://jsfiddle.net/h10Lucxz/) running as is. Can you be more specific on what you mean by "it also works"? Thanks – Matt Newelski Jul 04 '20 at 08:39
  • @MattNewelski It doesn't appear to be working in [this demo](https://regex101.com/r/BQ3FTw/1). I mean, the demo reports one match, but it is a zero width match, the password entered does not match the regex, because the pattern matches nothing. – Tim Biegeleisen Jul 04 '20 at 08:41

1 Answers1

3

The problem with your regex borders on being a typo, but it is missing a closing anchor. Use this version:

^(?=.*[a-zA-Z])(?=.*[0-9])(?=.*[!@#\$%\^&\*]).{8,}$

Updated code:

let validPassword = new RegExp("^(?=.*[a-zA-Z])(?=.*[0-9])(?=.*[!@#\$%\^&\*]).{8,}$");

The above updated regex says to:

^                        from the start of the password
    (?=.*[a-zA-Z])       assert that one letter is present
    (?=.*[0-9])          assert that one number is present
    (?=.*[!@#\$%\^&\*])  assert one symbol
    .{8,}                then match any 8 or more characters
                         (this also contains the length requirement)
$                        end of the password
Tim Biegeleisen
  • 387,723
  • 20
  • 200
  • 263
  • I solved it . The problem was that const registerButton was inside of the function scope so when I gave it an eventlistener it reported an error. Once I put it in the global scope it worked fine. – outlier11 Jul 05 '20 at 07:58