diff --git a/app/Containers/AppSection/Authentication/Actions/ApiLoginProxyForWebClientAction.php b/app/Containers/AppSection/Authentication/Actions/ApiLoginProxyForWebClientAction.php index 4ef42efae..d0e651dcc 100644 --- a/app/Containers/AppSection/Authentication/Actions/ApiLoginProxyForWebClientAction.php +++ b/app/Containers/AppSection/Authentication/Actions/ApiLoginProxyForWebClientAction.php @@ -7,11 +7,14 @@ use App\Containers\AppSection\Authentication\Tasks\CallOAuthServerTask; use App\Containers\AppSection\Authentication\Tasks\ExtractLoginCustomAttributeTask; use App\Containers\AppSection\Authentication\Tasks\MakeRefreshCookieTask; +use App\Containers\AppSection\Authentication\Traits\LoginAttributeCaseSensitivityTrait; use App\Containers\AppSection\Authentication\UI\API\Requests\LoginProxyPasswordGrantRequest; use App\Ship\Parents\Actions\Action; class ApiLoginProxyForWebClientAction extends Action { + use LoginAttributeCaseSensitivityTrait; + /** * @param LoginProxyPasswordGrantRequest $request * @return array @@ -27,8 +30,8 @@ public function run(LoginProxyPasswordGrantRequest $request): array ] ); - $loginCustomAttribute = app(ExtractLoginCustomAttributeTask::class)->run($sanitizedData); - $sanitizedData = $this->enrichSanitizedData($loginCustomAttribute['username'], $sanitizedData); + list($username) = app(ExtractLoginCustomAttributeTask::class)->run($sanitizedData); + $sanitizedData = $this->enrichSanitizedData($this->processLoginAttributeCaseSensitivity($username), $sanitizedData); $responseContent = app(CallOAuthServerTask::class)->run($sanitizedData, $request->headers->get('accept-language')); $refreshCookie = app(MakeRefreshCookieTask::class)->run($responseContent['refresh_token']); diff --git a/app/Containers/AppSection/Authentication/Actions/WebLoginAction.php b/app/Containers/AppSection/Authentication/Actions/WebLoginAction.php index 5ffdc41ac..a08ed3727 100644 --- a/app/Containers/AppSection/Authentication/Actions/WebLoginAction.php +++ b/app/Containers/AppSection/Authentication/Actions/WebLoginAction.php @@ -6,6 +6,7 @@ use App\Containers\AppSection\Authentication\Exceptions\LoginFailedException; use App\Containers\AppSection\Authentication\Tasks\ExtractLoginCustomAttributeTask; use App\Containers\AppSection\Authentication\Tasks\LoginTask; +use App\Containers\AppSection\Authentication\Traits\LoginAttributeCaseSensitivityTrait; use App\Containers\AppSection\Authentication\UI\WEB\Requests\LoginRequest; use App\Containers\AppSection\User\Models\User; use App\Ship\Parents\Actions\Action; @@ -14,6 +15,8 @@ class WebLoginAction extends Action { + use LoginAttributeCaseSensitivityTrait; + /** * @param LoginRequest $request * @return User|Authenticatable|null @@ -28,12 +31,12 @@ public function run(LoginRequest $request): User|Authenticatable|null 'remember_me' => false, ]); - $loginCustomAttribute = app(ExtractLoginCustomAttributeTask::class)->run($sanitizedData); + list($username, $loginAttribute) = app(ExtractLoginCustomAttributeTask::class)->run($sanitizedData); $loggedIn = app(LoginTask::class)->run( - $loginCustomAttribute['username'], + $this->processLoginAttributeCaseSensitivity($username), $sanitizedData['password'], - $loginCustomAttribute['loginAttribute'], + $loginAttribute, $sanitizedData['remember_me'] ); diff --git a/app/Containers/AppSection/Authentication/Configs/appSection-authentication.php b/app/Containers/AppSection/Authentication/Configs/appSection-authentication.php index fa8d3f832..e074d81b9 100644 --- a/app/Containers/AppSection/Authentication/Configs/appSection-authentication.php +++ b/app/Containers/AppSection/Authentication/Configs/appSection-authentication.php @@ -64,6 +64,18 @@ 'email' => ['email'], ], + /* + |-------------------------------------------------------------------------- + | Case Sensitive + |-------------------------------------------------------------------------- + | + | This field represents if login attribute should be case-sensitive. + | If false, then user can log in with both `admin@admin.com` and `Admin@Admin.Com` + | + */ + + 'case_sensitive' => false, + /* |-------------------------------------------------------------------------- | Prefix @@ -87,7 +99,7 @@ | */ 'allowed-reset-password-urls' => [ - 'http://api.apiato.test/v1/password/reset', + env('APP_URL', 'http://api.apiato.test/v1') . '/password/reset', ], /* @@ -99,6 +111,6 @@ | */ 'allowed-verify-email-urls' => [ - 'http://api.apiato.test/v1/email/verify', + env('APP_URL', 'http://api.apiato.test/v1') . '/email/verify', ], ]; diff --git a/app/Containers/AppSection/Authentication/Tests/Unit/WebLoginActionTest.php b/app/Containers/AppSection/Authentication/Tests/Unit/WebLoginActionTest.php index 5b37b77a8..a69c23037 100644 --- a/app/Containers/AppSection/Authentication/Tests/Unit/WebLoginActionTest.php +++ b/app/Containers/AppSection/Authentication/Tests/Unit/WebLoginActionTest.php @@ -7,6 +7,7 @@ use App\Containers\AppSection\Authentication\Tests\TestCase; use App\Containers\AppSection\Authentication\UI\WEB\Requests\LoginRequest; use App\Containers\AppSection\User\Models\User; +use Illuminate\Support\Facades\Config; /** * Class WebLoginActionTest. @@ -28,16 +29,36 @@ public function testLogin(): void $this->assertSame($user->name, $this->userDetails['name']); } - public function testLoginWithInvalidCredentialsThrowsAnException(): void + public function testLoginWithInvalidEmailThrowsAnException(): void { $this->expectException(LoginFailedException::class); $this->expectExceptionMessage('Invalid Login Credentials.'); - $this->request = new LoginRequest(['email' => 'wrong@email.com', 'password' => 'wrong_password']); + $this->request = new LoginRequest(['email' => 'wrong@email.com', 'password' => $this->userDetails['password']]); $this->action->run($this->request); } + public function testLoginWithInvalidPasswordThrowsAnException(): void + { + $this->expectException(LoginFailedException::class); + $this->expectExceptionMessage('Invalid Login Credentials.'); + + $this->request = new LoginRequest(['email' => $this->userDetails['email'], 'password' => 'wrong-password']); + + $this->action->run($this->request); + } + + public function testLoginWithUppercaseEmail(): void + { + Config::set('appSection-authentication.login.case_sensitive', false); + + $user = $this->action->run($this->request); + + $this->assertInstanceOf(User::class, $user); + $this->assertSame($user->name, $this->userDetails['name']); + } + protected function setUp(): void { parent::setUp(); diff --git a/app/Containers/AppSection/Authentication/Traits/LoginAttributeCaseSensitivityTrait.php b/app/Containers/AppSection/Authentication/Traits/LoginAttributeCaseSensitivityTrait.php new file mode 100644 index 000000000..840d80aca --- /dev/null +++ b/app/Containers/AppSection/Authentication/Traits/LoginAttributeCaseSensitivityTrait.php @@ -0,0 +1,15 @@ +assertResponseContainKeys(['expires_in', 'access_token']); } + public function testClientWebAdminProxyLoginWithUppercaseEmail(): void + { + $data = [ + 'email' => 'Testing@Mail.Com', + 'password' => 'testiness', + ]; + $this->getTestingUser(['email' => 'testing@mail.com', 'password' => $data['password'],]); + Config::set('appSection-authentication.login.case_sensitive', false); + + $response = $this->makeCall($data); + + $response->assertStatus(200); + $this->assertResponseContainKeyValue([ + 'token_type' => 'Bearer', + ]); + $this->assertResponseContainKeys(['expires_in', 'access_token']); + } + public function testLoginWithNameAttribute(): void { $data = [