Skip to content

Passwords

The password management is handled by the PasswordController.php and Password.php model.

A password is set by the admin when a user is created. The user can change password by itsel by accessing its profile page. An admin can also change tha password using the edit page for the user.

Forgot password?

If your users have forgotten their password, they can reset it by themselves easily by using the "forgot password?" feature. There is a link in the login form to the page /reset-password.

Forgot password page

The user enters its registered email addres and an email with instructions will be sent to that email address if it exists. For security reasons there is no error message if the email does not exist so the user must keep an eye out in its inbox.

The email contains a link with a token that is used to connect the email recipient with the user account. By visiting the link the user can select a new password. When it is done, the token is deleted and the link is not accessible any more.

The token and link is only enabled for a limited time (default = 1 hour). If you want to change this, you can do it by changing the php constant PASSWORD_RESET_TOKEN_EXPIRATION in ~/config/config.php.

Password.php

Location
~/App/Models/Authenticate/Password.php
Namespace
namespace App\Models\Authenticate;
Import
use App\Models\Authenticate\Password;

Password reset token

When a user wants to reset its password, a token is saved to the users post in the database along with a timestamp. The timestamp is used to determine if the token is still valid or not.

Generate a new token

A new password reset token is generated by running the generateToken() method. The methods will generate a token that is unique (that doeas note already exists in the database). The user ID is passed so that the token can be saved to the database.

$token = Password::generateToken($userId);

Example of a token:

f0621c42dfd2e0ac3969b97d02a38807

Check token validity

When the user tries to access the form to select a new password, the token is checked so that it is still valid. The default length is 1 hour but can be changed in ~/config/config.php (PASSWORD_RESET_TOKEN_EXPIRATION).

If the expiration time has passed the token is deleted and the method returns false.

if (! Password::checkToken($token)) {
    App::abort();
}

Delete token

The token is deleted by overwriting it with null in the database along with its created date. The user ID is used to fint the correct row.

Password::deleteToken($userId);

Get token expiration

You can use the expiresAt() method to show the user or admin when a token expires.

$expiration = Password::expiresAt($tokenId);

Update a password

The update() method will compare the new password with the second entry, hash it and store it in the database. Any errors will be flashed.

The method takes the new and repeated password, the user ID (that owns the pasword) and the ID of the user that changes the password. The same method is used through out the whole app so when an admin changes the password for a user, the admin's ID is stored in the database for latest update. If the user is using the "forgot password?" feature or is changing it via the profile, the same use ID is passed.

We get the user ID that belongs to the token using the getUserId() method.

$userId = Password::getUserId($token);

if (! Password::update($passwordNew, $passwordRepeat, $userId, $userId)) {
    Redirect::to("/reset-password/new?token=$token")->with('feedback', 'password_update_failed');
}

Emails

Emails are sent to the user when the password is changed using the "forgot password?" feature.

In development we use MailHog to "send" the emails. Access MailHog by visiting http://localhost:8025. The setup is done in Dockerfile and docker-compose.yml.

Check if email exists

Before generating a token and sending an email we must check if the email exists in the database. You can use the checkEmail() method for this.

$userId = Password::checkEmail($email);

if (! $userId) {
    // Redirect back
}

Reset email

The email that contains the link and token for the new password form is sent using the sendResetEmail() method. The mathod takes the user's email address and the token.

Password::sendResetEmail($email, $token);

Password reset email 1

Confirmation email

When the password has changed we can send a confirmation email to the user. If we don't have the user email at this point we can use the getEmail() method.

$email = Password::getEmail($userId);

Password::sendConfirmationEmail($email);

Password reset email 2