Skip to content

Commit

Permalink
update and tighten password validation rules
Browse files Browse the repository at this point in the history
  • Loading branch information
Mohammad-Alavi committed Dec 15, 2021
1 parent a074e65 commit ff32b1d
Show file tree
Hide file tree
Showing 6 changed files with 131 additions and 32 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@

use App\Ship\Parents\Requests\Request;
use Illuminate\Validation\Rule;
use Illuminate\Validation\Rules\Password;

class RegisterUserRequest extends Request
{
Expand Down Expand Up @@ -33,14 +34,25 @@ class RegisterUserRequest extends Request
public function rules(): array
{
return [
'email' => 'required|email|max:40|unique:users,email',
'password' => 'required|min:6|max:32',
'email' => 'required|email|unique:users,email',
'password' => [
'required',
Password::min(8)
->letters()
->mixedCase()
->numbers()
->symbols(),
],
'name' => 'min:2|max:50',
'gender' => 'in:male,female,unspecified',
'birth' => 'date',
'verification_url' => Rule::requiredIf(function () {
return config('appSection-authentication.require_email_verification');
}) . '|url|' . Rule::in(config('appSection-authentication.allowed-verify-email-urls')),
'verification_url' => [
'url',
Rule::requiredIf(function () {
return config('appSection-authentication.require_email_verification');
}),
Rule::in(config('appSection-authentication.allowed-verify-email-urls')),
],
];
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@
namespace App\Containers\AppSection\Authentication\UI\API\Requests;

use App\Ship\Parents\Requests\Request;
use Illuminate\Validation\Rules\Password;

class ResetPasswordRequest extends Request
{
Expand Down Expand Up @@ -32,9 +33,16 @@ class ResetPasswordRequest extends Request
public function rules(): array
{
return [
'token' => 'required|max:255',
'email' => 'required|email|max:255',
'password' => 'required|min:6|max:255',
'token' => 'required',
'email' => 'required|email',
'password' => [
'required',
Password::min(8)
->letters()
->mixedCase()
->numbers()
->symbols(),
],
];
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,18 @@
* @apiPermission none
*
* @apiParam {String} email
* @apiParam {String} password min:6|max:40
* @apiParam {String} password min: 8
*
* at least one character of the following:
*
* upper case letter
*
* lower case letter
*
* number
*
* special character
*
* @apiParam {String} [name] min:2|max:50
* @apiParam {String="male,female,unspecified"} [gender]
* @apiParam {Date} [birth] format: Y-m-d / e.g. 2015-10-15
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -10,9 +10,19 @@
* @apiVersion 1.0.0
* @apiPermission none
*
* @apiParam {String} email
* @apiParam {String} token from the forgot password email
* @apiParam {String} password min:6|max:255 the new password
* @apiParam {String} email
* @apiParam {String} token from the forgot password email
* @apiParam {String} password min: 8
*
* at least one character of the following:
*
* upper case letter
*
* lower case letter
*
* number
*
* special character
*
* @apiSuccessExample {json} Success-Response:
* HTTP/1.1 204 No Content
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -29,15 +29,15 @@ public function testGivenEmailVerificationEnabled_RegisterNewUserWithCredentials

$data = [
'email' => '[email protected]',
'password' => 'secretpass',
'password' => 's3cr3tPa$$',
'verification_url' => 'http://some.test/known/url',
];

$response = $this->makeCall($data);

$response->assertStatus(200);
$response->assertJson(
fn (AssertableJson $json) => $json->has('data')
fn(AssertableJson $json) => $json->has('data')
->where('data.email', $data['email'])
->etc()
);
Expand All @@ -48,14 +48,14 @@ public function testGivenEmailVerificationDisabled_RegisterNewUserWithCredential
config(['appSection-authentication.require_email_verification' => false]);
$data = [
'email' => '[email protected]',
'password' => 'secretpass',
'password' => 's3cr3tPa$$',
];

$response = $this->makeCall($data);

$response->assertStatus(200);
$response->assertJson(
fn (AssertableJson $json) => $json->has('data')
fn(AssertableJson $json) => $json->has('data')
->where('data.email', $data['email'])
->etc()
);
Expand All @@ -72,7 +72,7 @@ public function testRegisterNewUserUsingGetVerb(): void

$response->assertStatus(405);
$response->assertJson(
fn (AssertableJson $json) => $json->has('message')
fn(AssertableJson $json) => $json->has('message')
->where('message', 'The GET method is not supported for this route. Supported methods: POST.')
->etc()
);
Expand All @@ -96,7 +96,7 @@ public function testRegisterExistingUser(): void

$response->assertStatus(422);
$response->assertJson(
fn (AssertableJson $json) => $json->has('errors')
fn(AssertableJson $json) => $json->has('errors')
->where('errors.email.0', 'The email has already been taken.')
->etc()
);
Expand All @@ -112,23 +112,21 @@ public function testRegisterNewUserWithoutData(): void

if (config('appSection-authentication.require_email_verification')) {
$response->assertJson(
fn (AssertableJson $json) => $json->hasAll(['message', 'errors' => 3])
fn(AssertableJson $json) => $json->hasAll(['message', 'errors' => 3])
->has(
'errors',
fn (AssertableJson $json) =>
$json->where('email.0', 'The email field is required.')
->where('password.0', 'The password field is required.')
->where('verification_url.0', 'The verification url field is required.')
fn(AssertableJson $json) => $json->where('email.0', 'The email field is required.')
->where('password.0', 'The password field is required.')
->where('verification_url.0', 'The verification url field is required.')
)
);
} else {
$response->assertJson(
fn (AssertableJson $json) => $json->hasAll(['message', 'errors' => 2])
fn(AssertableJson $json) => $json->hasAll(['message', 'errors' => 2])
->has(
'errors',
fn (AssertableJson $json) =>
$json->where('email.0', 'The email field is required.')
->where('password.0', 'The password field is required.')
fn(AssertableJson $json) => $json->where('email.0', 'The email field is required.')
->where('password.0', 'The password field is required.')
)
);
}
Expand All @@ -138,19 +136,40 @@ public function testRegisterNewUserWithInvalidEmail(): void
{
$data = [
'email' => 'missing-at.test',
'password' => 'secret',
];

$response = $this->makeCall($data);

$response->assertStatus(422);
$response->assertJson(
fn (AssertableJson $json) => $json->has('errors')
fn(AssertableJson $json) => $json->has('errors')
->where('errors.email.0', 'The email must be a valid email address.')
->etc()
);
}

public function testRegisterNewUserWithInvalidPassword(): void
{
$data = [
'password' => '((((()))))',
];

$response = $this->makeCall($data);

$response->assertStatus(422);
$response->assertJson(
fn(AssertableJson $json) => $json->has('errors')
->has(
'errors.password',
fn(AssertableJson $json) => $json
->where('0', 'The password must contain at least one uppercase and one lowercase letter.')
->where('1', 'The password must contain at least one letter.')
->where('2', 'The password must contain at least one number.')
)
->etc()
);
}

public function testRegisterNewUserWithNotAllowedVerificationUrl(): void
{
if (!config('appSection-authentication.require_email_verification')) {
Expand All @@ -161,15 +180,15 @@ public function testRegisterNewUserWithNotAllowedVerificationUrl(): void

$data = [
'email' => '[email protected]',
'password' => 'secret',
'password' => 's3cr3tPa$$',
'verification_url' => 'http://notallowed.test/wrong',
];

$response = $this->makeCall($data);

$response->assertStatus(422);
$response->assertJson(
fn (AssertableJson $json) => $json->hasAll(['message', 'errors' => 1])
fn(AssertableJson $json) => $json->hasAll(['message', 'errors' => 1])
->where('errors.verification_url.0', 'The selected verification url is invalid.')
);
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@

use App\Containers\AppSection\Authentication\Tasks\CreatePasswordResetTokenTask;
use App\Containers\AppSection\Authentication\UI\API\Tests\ApiTestCase;
use Illuminate\Testing\Fluent\AssertableJson;

/**
* Class ResetPasswordTest.
Expand All @@ -29,12 +30,50 @@ public function testResetPassword(): void
$token = app(CreatePasswordResetTokenTask::class)->run($this->testingUser);
$data = [
'email' => $this->testingUser->email,
'password' => 'new pass',
'password' => 's3cr3tPa$$',
'token' => $token,
];

$response = $this->makeCall($data);

$response->assertStatus(204);
}

public function testResetPasswordWithInvalidEmail(): void
{
$data = [
'email' => 'missing-at.test',
];

$response = $this->makeCall($data);

$response->assertStatus(422);
$response->assertJson(
fn(AssertableJson $json) => $json->has('errors')
->where('errors.email.0', 'The email must be a valid email address.')
->etc()
);
}

public function testResetPasswordWithInvalidPassword(): void
{
$data = [
'password' => '((((()))))',
];

$response = $this->makeCall($data);

$response->assertStatus(422);
$response->assertJson(
fn(AssertableJson $json) => $json->has('errors')
->has(
'errors.password',
fn(AssertableJson $json) => $json
->where('0', 'The password must contain at least one uppercase and one lowercase letter.')
->where('1', 'The password must contain at least one letter.')
->where('2', 'The password must contain at least one number.')
)
->etc()
);
}
}

0 comments on commit ff32b1d

Please sign in to comment.