Last Updated:

Changing the password in the "Ajax registration/authorization system"

Having discovered an article about the Ajax authorization system, I implemented it in my project, everything works just fine, for which special thanks to the author of these scripts.

But after a little digging into the system, I was faced with the fact that this application does not allow you to change the password and decided to try to fix it.

Do not judge strictly, the code turned out to be quite dirty and unprofessional (because I have a very indirect relation to programming), but working, by the way, comments in the code this also applies to ;)

I thank in advance my friends who will detect bugs or suggest code optimization. So there you go.

What will we change and what will we add?

I haven't changed the filenames, so all the names are in accordance with the original project. To add the ability to change the password, you will need changes to the following files:

  • ajax.php
  • Auth.class.php
  • ajax-form.js

And also create a page for changing the password: .return.php

Now, in order.

First things first, let's create where the password change will take place.return.php

<?php

if (!empty($_COOKIE['sid'])) {
    // check session id in cookies
    session_id($_COOKIE['sid']);
}
session_start();
require_once './classes/Auth.class.php';

?><!DOCTYPE html>
<html>
  <head>
    <meta charset="utf-8">
    <title>Password change</title>
    <meta name="viewport" content="width=device-width, initial-scale=0.7">
    <link rel="stylesheet" href="./vendor/bootstrap/css/bootstrap.min.css">
    <link rel="stylesheet" href="./css/style.css">
  </head>
  <body>
    <div class="container">

      <?php if (Auth\User::isAuthorized()): ?>

      <h1>Your are already logined!</h1>

      <form class="ajax" method="post" action="./ajax.php">
          <input type="hidden" name="act" value="logout">
          <div class="form-actions">
              <button class="btn btn-large btn-primary" type="submit">Logout</button>
          </div>
      </form>

      <?php else: ?>

      <form class="form-signin ajax" method="post" action="./ajax.php">
        <div class="main-error alert alert-error hide"></div>
       <h2 class="form-signin-heading">Password Change</h2>
        <input name="username" type="text" class="input-block-level" placeholder="Username" autofocus>
        <p>Enter Your old password or Security code from back side of controller</p>
        <input name="old_password" type="password" class="input-block-level" placeholder="Old Password">
              <input name="new_password" type="password" class="input-block-level" placeholder="New Password">
        <input name="new_password2" type="password" class="input-block-level" placeholder="Confirm new password">
        <input type="hidden" name="act" value="change_password">
        <button class="btn btn-large btn-primary" type="submit">Change password</button>
        <div class="alert alert-info" style="margin-top:15px;">
            <p>Already have account? <a href="/">Sign In.</a>
        </div>
      </form>

      <?php endif; ?>
    </div> <!-- /container -->

    <script src="./vendor/jquery-2.0.3.min.js"></script>
    <script src="./vendor/bootstrap/js/bootstrap.min.js"></script>
    <script src="./js/ajax-form.js"></script>
  </body>
</html>

There is not much to disassemble here, the form is similar. The only difference is the field from which we will take the old password and check it.register.phpold_password

Now you need to shamanize with , or rather announce a new .Auth.class.phppublic function change_password

public function change_password($username, $password)
{
    $user_exists = $this->getSalt($username);
    if (!$user_exists) {
        throw new \Exception("User doesn't exist: " . $username, 1);
    }

    $query = "update users set password = :password where username = :username";
    $salt = $this->getSalt($username);
    $hashes = $this->passwordHash($password, $salt);
    $sth = $this->db->prepare($query);

    $this->db->beginTransaction();
    $result = $sth->execute(  
        array( 
            ':username' => $username,
            ':password' => $hashes['hash'],
        )
    );

    $this->db->commit(); 
    $this->user = $sth->fetch();

    if (!$result) {
        $info = $sth->errorInfo();
        printf("Database w t f error %d %s", $info[1], $info[2]);
        die();
    } 
    return $result;     
}

First, we check whether there is such a user, if not, then throw an exception, if there is, then we send a request to update the database, having previously salted the new password with the old salt. If an error occurs during the execution of the query, print the corresponding message and terminate the script.

Now moving to ajax.php

At the very beginning of the file we find and add .

public $actions"change_password" => "change_password",

public $actions = array(
    "login" => "login",
    "logout" => "logout",
    "register" => "register",
    "change_password" => "change_password",
);

Now you need to create a handler. Inside, let's create .

class AuthorizationAjaxRequest extends AjaxRequestpublic function change_password()

public function change_password()
{
    if ($_SERVER["REQUEST_METHOD"] !== "POST") {
        //  Method Not Allowed
        http_response_code(405);
        header("Allow: POST");
        $this->setFieldError("main", "Method Not Allowed");
        return;
    }
    setcookie("sid", "");

    $username = $this->getRequestParam("username");
    $old_password = $this->getRequestParam("old_password");
    $new_password = $this->getRequestParam("new_password");  
    $new_password2 = $this->getRequestParam("new_password2");

    if (empty($username)) {
        $this->setFieldError("username", "Enter the username");
        return;
    }

    if (empty($old_password))  {
        $this->setFieldError("old_password", "Enter old  password");
        return;
    }

    $user = new Auth\User();
    $pass_check = $user->authorize($username, $old_password);
    if (!$pass_check) {
        $this->setFieldError("password", "Invalid old password");
        return;
    }

    if (empty($new_password)) {
        $this->setFieldError("new_password", "type new password");
        return;
    }

    if (empty($new_password2)) {
        $this->setFieldError("new_password2", "Confirm the password");
        return;
    }

    if ($new_password !== $new_password2) {
        $this->setFieldError("new_password2", "Confirm password is not match");
        return;
    }

    try {   
        $change_password = $user->change_password($username, $new_password);      
    } catch (\Exception $e) {
        $this->setFieldError("username", $e->getMessage());
        return;
    }
    $user->authorize($username, $new_password);

    $this->message = sprintf("Hello, %s! Password had been successfully changed.", $username);
    $this->setResponse("redirect", "/");
    $this->status = "ok";
}

We check the filling in of all the fields, as well as try to log in according to the old password, if everything is OK, then we try to change the password and re-log in with the new password.

Now it remains only a little to shamanize , namely to add to :ajax-form.jscallbacks

change_password: function ($form, data) {
    if (data.status === 'ok') {
        if (data.data && data.data.redirect) {
            window.location.href = data.data.redirect;
        }
    }
}

That's basically it. After all these shenanigans, it should work. I will be glad to constructive criticism and advice on code optimization. If you find an error in the code or text of the article - please write about it in the comments.