From d37cf146f9b2413411fd4572782b65318f510c91 Mon Sep 17 00:00:00 2001 From: Lonnie Ezell Date: Tue, 3 Jan 2023 23:04:41 -0600 Subject: [PATCH 1/5] User activation checks and utility functions. Fixes #459 --- docs/authentication.md | 2 +- docs/authorization.md | 44 ++++++++++ src/Auth.php | 1 - src/Authentication/Actions/EmailActivator.php | 2 +- src/Authentication/Authenticators/Session.php | 8 -- src/Controllers/RegisterController.php | 2 +- src/Entities/User.php | 2 + src/Filters/SessionAuth.php | 9 ++ src/Filters/TokenAuth.php | 14 ++- src/Language/de/Auth.php | 1 + src/Language/en/Auth.php | 3 +- src/Language/es/Auth.php | 1 + src/Language/fa/Auth.php | 1 + src/Language/fr/Auth.php | 1 + src/Language/id/Auth.php | 1 + src/Language/it/Auth.php | 1 + src/Language/ja/Auth.php | 1 + src/Language/sk/Auth.php | 1 + src/Language/tr/Auth.php | 1 + src/Traits/Activatable.php | 58 +++++++++++++ .../Filters/SessionFilterTest.php | 26 ++++++ .../Filters/TokenFilterTest.php | 30 ++++++- tests/Unit/UserTest.php | 87 +++++++++++++++++++ 23 files changed, 281 insertions(+), 16 deletions(-) create mode 100644 src/Traits/Activatable.php diff --git a/docs/authentication.md b/docs/authentication.md index 4eeef20bc..933335f33 100644 --- a/docs/authentication.md +++ b/docs/authentication.md @@ -70,7 +70,7 @@ user_id(); ## Authenticator Responses Many of the authenticator methods will return a `CodeIgniter\Shield\Result` class. This provides a consistent -way of checking the results and can have additional information return along with it. The class +way of checking the results and can have additional information returned along with it. The class has the following methods: ### isOK() diff --git a/docs/authorization.md b/docs/authorization.md index 977884adc..5d089eb62 100644 --- a/docs/authorization.md +++ b/docs/authorization.md @@ -20,6 +20,10 @@ - [removeGroup()](#removegroup) - [syncGroups()](#syncgroups) - [getGroups()](#getgroups) + - [User Activation](#user-activation) + - [Checking Activation Status](#checking-activation-status) + - [Activating a User](#activating-a-user) + - [Deactivating a User](#deactivating-a-user) Authorization happens once a user has been identified through authentication. It is the process of determining what actions a user is allowed to do within your site. @@ -233,3 +237,43 @@ Returns all groups this user is a part of. ```php $user->getGroups(); ``` + +## User Activation + +All users have an `active` flag. This is only used when the [`EmailActivation` action](./auth_actions.md), or a custom action used to activate a user, is enabled. + +### Checking Activation Status + +You can determine if a user has been activated with the `isActivated()` method. + +```php +if ($user->isActivated()) { + // +} +``` + +Note: If no activator is specified in the `Auth` config file, `actions['register']` property, then this will always return `true`. + +You can check if a user has not been activated yet via the `isNotActivated()` method. + +```php +if ($user->isNotActivated()) { + // +} +``` + +## Activating a User + +Users are automatically activated withih the `EmailActivator` action. They can be manually activated via the `activate()` method on the User entity. + +```php +$user->activate(); +``` + +## Deactivating a User + +Users can be manually deactivated via the `deactivate()` method on the User entity. + +```php +$user->deactivate(); +``` diff --git a/src/Auth.php b/src/Auth.php index fae81dff3..35e5bd30f 100644 --- a/src/Auth.php +++ b/src/Auth.php @@ -12,7 +12,6 @@ use CodeIgniter\Shield\Models\UserModel; /** - * @method void activateUser(User $user) [Session] * @method Result attempt(array $credentials) * @method Result check(array $credentials) * @method bool checkAction(string $token, string $type) [Session] diff --git a/src/Authentication/Actions/EmailActivator.php b/src/Authentication/Actions/EmailActivator.php index e64493d1e..8e5216074 100644 --- a/src/Authentication/Actions/EmailActivator.php +++ b/src/Authentication/Actions/EmailActivator.php @@ -111,7 +111,7 @@ public function verify(IncomingRequest $request) $user = $authenticator->getUser(); // Set the user active now - $authenticator->activateUser($user); + $user->activate(); // Success! return redirect()->to(config('Auth')->registerRedirect()) diff --git a/src/Authentication/Authenticators/Session.php b/src/Authentication/Authenticators/Session.php index a4ada2473..923d04cac 100644 --- a/src/Authentication/Authenticators/Session.php +++ b/src/Authentication/Authenticators/Session.php @@ -254,14 +254,6 @@ public function completeLogin(User $user): void Events::trigger('login', $user); } - /** - * Activate a User - */ - public function activateUser(User $user): void - { - $this->provider->activate($user); - } - /** * @param int|string|null $userId */ diff --git a/src/Controllers/RegisterController.php b/src/Controllers/RegisterController.php index 5b921e13b..784f785bd 100644 --- a/src/Controllers/RegisterController.php +++ b/src/Controllers/RegisterController.php @@ -114,7 +114,7 @@ public function registerAction(): RedirectResponse } // Set the user active - $authenticator->activateUser($user); + $user->activate(); $authenticator->completeLogin($user); diff --git a/src/Entities/User.php b/src/Entities/User.php index 7dfba8c89..f7c7b3112 100644 --- a/src/Entities/User.php +++ b/src/Entities/User.php @@ -12,6 +12,7 @@ use CodeIgniter\Shield\Models\LoginModel; use CodeIgniter\Shield\Models\UserIdentityModel; use CodeIgniter\Shield\Traits\Resettable; +use CodeIgniter\Shield\Traits\Activatable; /** * @property string|null $email @@ -27,6 +28,7 @@ class User extends Entity use Authorizable; use HasAccessTokens; use Resettable; + use Activatable; /** * @var UserIdentity[]|null diff --git a/src/Filters/SessionAuth.php b/src/Filters/SessionAuth.php index e518ced19..294773c7d 100644 --- a/src/Filters/SessionAuth.php +++ b/src/Filters/SessionAuth.php @@ -49,6 +49,15 @@ public function before(RequestInterface $request, $arguments = null) $authenticator->recordActiveDate(); } + // Block inactive users when Email Activation is enabled + $user = $authenticator->getUser(); + if ($user !== null && ! $user->isActivated()) { + $authenticator->logout(); + + return redirect()->route('login') + ->with('error', lang('Auth.activationBlocked')); + } + return; } diff --git a/src/Filters/TokenAuth.php b/src/Filters/TokenAuth.php index a877f9064..d141bda46 100644 --- a/src/Filters/TokenAuth.php +++ b/src/Filters/TokenAuth.php @@ -49,12 +49,24 @@ public function before(RequestInterface $request, $arguments = null) ]); if (! $result->isOK() || (! empty($arguments) && $result->extraInfo()->tokenCant($arguments[0]))) { - return redirect()->to('/login'); + return service('response') + ->setStatusCode(Response::HTTP_FORBIDDEN) + ->setJson(['message' => lang('Auth.badToken')]); } if (setting('Auth.recordActiveDate')) { $authenticator->recordActiveDate(); } + + // Block inactive users when Email Activation is enabled + $user = $authenticator->getUser(); + if ($user !== null && ! $user->isActivated()) { + $authenticator->logout(); + + return service('response') + ->setStatusCode(Response::HTTP_FORBIDDEN) + ->setJson(['message' => lang('Auth.activationBlocked')]); + } } /** diff --git a/src/Language/de/Auth.php b/src/Language/de/Auth.php index 5fb930501..1afb6f91b 100644 --- a/src/Language/de/Auth.php +++ b/src/Language/de/Auth.php @@ -87,6 +87,7 @@ 'emailActivateMailBody' => 'Bitte verwenden Sie den unten stehenden Code, um Ihr Konto zu aktivieren und die Website zu nutzen.', 'invalidActivateToken' => 'Der Code war falsch.', 'needActivate' => '(To be translated) You must complete your registration by confirming the code sent to your email address.', + 'activationBlocked' => '(to be translated) You must activate your account before logging in.', // Groups 'unknownGroup' => '{0} ist eine ungültige Gruppe.', diff --git a/src/Language/en/Auth.php b/src/Language/en/Auth.php index 26dcce1aa..bb55db96a 100644 --- a/src/Language/en/Auth.php +++ b/src/Language/en/Auth.php @@ -48,7 +48,7 @@ 'successLogout' => 'You have successfully logged out.', // Passwords - 'errorPasswordLength' => 'Passwords must be at least {0, number} characters long.', + 'errorPasswordLength' => 'Passwords must be at least {0activationBlocked, number} characters long.', 'suggestPasswordLength' => 'Pass phrases - up to 255 characters long - make more secure passwords that are easy to remember.', 'errorPasswordCommon' => 'Password must not be a common password.', 'suggestPasswordCommon' => 'The password was checked against over 65k commonly used passwords or passwords that have been leaked through hacks.', @@ -87,6 +87,7 @@ 'emailActivateMailBody' => 'Please use the code below to activate your account and start using the site.', 'invalidActivateToken' => 'The code was incorrect.', 'needActivate' => 'You must complete your registration by confirming the code sent to your email address.', + 'activationBlocked' => 'You must activate your account before logging in.', // Groups 'unknownGroup' => '{0} is not a valid group.', diff --git a/src/Language/es/Auth.php b/src/Language/es/Auth.php index 9df966a33..869b0853f 100644 --- a/src/Language/es/Auth.php +++ b/src/Language/es/Auth.php @@ -87,6 +87,7 @@ 'emailActivateMailBody' => 'Por favor, usa el código de abajo para activar tu cuenta y empezar a usar el sitio.', 'invalidActivateToken' => 'El código no es correcto.', 'needActivate' => '(To be translated) You must complete your registration by confirming the code sent to your email address.', + 'activationBlocked' => '(to be translated) You must activate your account before logging in.', // Grupos 'unknownGroup' => '{0} no es un grupo válido.', diff --git a/src/Language/fa/Auth.php b/src/Language/fa/Auth.php index 2463da295..0a996bcbe 100644 --- a/src/Language/fa/Auth.php +++ b/src/Language/fa/Auth.php @@ -87,6 +87,7 @@ 'emailActivateMailBody' => 'لطفا برای فعالسازی حساب کاربری و استفاده از سایت از کد زیر استفاده کنید.', 'invalidActivateToken' => 'کد صحیح نمی باشد.', 'needActivate' => 'شما باید با ارائه کد ارسال شده به ایمیلتان، ثبت نام را تکمیل کنید.', + 'activationBlocked' => '(to be translated) You must activate your account before logging in.', // Groups 'unknownGroup' => '{0} گروهی معتبر نیست.', diff --git a/src/Language/fr/Auth.php b/src/Language/fr/Auth.php index a80b77ad1..ee80e4d0e 100644 --- a/src/Language/fr/Auth.php +++ b/src/Language/fr/Auth.php @@ -87,6 +87,7 @@ 'emailActivateMailBody' => 'Veuillez utiliser le code suivant pour activer votre compte et commencer à utiliser le site.', 'invalidActivateToken' => 'Le code était incorrect.', 'needActivate' => 'Complétez votre inscription en confirmant le code envoyé à votre email.', + 'activationBlocked' => '(to be translated) You must activate your account before logging in.', // Groups 'unknownGroup' => '{0} n\'est pas un groupe valide.', diff --git a/src/Language/id/Auth.php b/src/Language/id/Auth.php index e407df6a5..b5afa7918 100644 --- a/src/Language/id/Auth.php +++ b/src/Language/id/Auth.php @@ -87,6 +87,7 @@ 'emailActivateMailBody' => 'Silahkan gunakan kode dibawah ini untuk mengaktivasi akun Anda.', 'invalidActivateToken' => 'Kode tidak sesuai.', 'needActivate' => 'Anda harus menyelesaikan registrasi Anda dengan mengonfirmasi kode yang dikirim ke alamat email Anda.', + 'activationBlocked' => '(to be translated) You must activate your account before logging in.', // Groups 'unknownGroup' => '{0} bukan grup yang sah.', diff --git a/src/Language/it/Auth.php b/src/Language/it/Auth.php index 641713de8..d3fb2b432 100644 --- a/src/Language/it/Auth.php +++ b/src/Language/it/Auth.php @@ -87,6 +87,7 @@ 'emailActivateMailBody' => 'Perfavore usa il codice qui sotto per attivare il tuo acccount ed iniziare ad usare il sito.', 'invalidActivateToken' => 'Il codice era sbagliato.', 'needActivate' => 'Devi completare la registrazione confermando il codice inviato al tuo indrizzo email.', + 'activationBlocked' => '(to be translated) You must activate your account before logging in.', // Groups 'unknownGroup' => '{0} non è un gruppo valido.', diff --git a/src/Language/ja/Auth.php b/src/Language/ja/Auth.php index a30ef6755..30f556110 100644 --- a/src/Language/ja/Auth.php +++ b/src/Language/ja/Auth.php @@ -87,6 +87,7 @@ 'emailActivateMailBody' => '以下のコードを使用してアカウントを有効化し、サイトの利用を開始してください。', // 'Please use the code below to activate your account and start using the site.', 'invalidActivateToken' => 'コードが間違っています。', // 'The code was incorrect.', 'needActivate' => 'メールアドレスに送信されたコードを確認し、登録を完了する必要があります。', // 'You must complete your registration by confirming the code sent to your email address.', + 'activationBlocked' => '(to be translated) You must activate your account before logging in.', // Groups 'unknownGroup' => '{0} は有効なグループではありません。', // '{0} is not a valid group.', diff --git a/src/Language/sk/Auth.php b/src/Language/sk/Auth.php index abea16fd3..74df1dbe6 100644 --- a/src/Language/sk/Auth.php +++ b/src/Language/sk/Auth.php @@ -87,6 +87,7 @@ 'emailActivateMailBody' => 'Pomocou nižšie uvedeného kódu aktivujte svoj účet a môžete začať používať stránku.', 'invalidActivateToken' => 'Kód bol nesprávny', 'needActivate' => 'Registráciu musíte dokončiť potvrdením kódu zaslaného na vašu e-mailovú adresu.', + 'activationBlocked' => '(to be translated) You must activate your account before logging in.', // Groups 'unknownGroup' => '{0} nie je platná skupina.', diff --git a/src/Language/tr/Auth.php b/src/Language/tr/Auth.php index e65c75a3f..70b924652 100644 --- a/src/Language/tr/Auth.php +++ b/src/Language/tr/Auth.php @@ -87,6 +87,7 @@ 'emailActivateMailBody' => 'Hesabınızı etkinleştirmek ve siteyi kullanmaya başlamak için lütfen aşağıdaki kodu kullanın.', 'invalidActivateToken' => 'Kod yanlıştı.', 'needActivate' => 'E-posta adresinize gönderilen kodu onaylayarak kaydınızı tamamlamanız gerekmektedir.', + 'activationBlocked' => '(to be translated) You must activate your account before logging in.', // Groups 'unknownGroup' => '{0} geçerli bir grup değil.', diff --git a/src/Traits/Activatable.php b/src/Traits/Activatable.php new file mode 100644 index 000000000..e697a7357 --- /dev/null +++ b/src/Traits/Activatable.php @@ -0,0 +1,58 @@ +shouldActivate() || $this->active; + } + + /** + * Returns true if the user has not been activated. + */ + public function isNotActivated(): bool + { + return ! $this->isActivated(); + } + + /** + * Activates the user. + */ + public function activate(): bool + { + helper('auth'); + $model = auth()->getProvider(); + + return $model->update($this->id, ['active' => 1]); + } + + /** + * Deactivates the user. + */ + public function deactivate(): bool + { + helper('auth'); + $model = auth()->getProvider(); + + return $model->update($this->id, ['active' => 0]); + } + + /** + * Does the Auth actions require activation? + * Check for the generic 'Activator' class name to allow + * for custom implementations, provided they follow the naming convention. + */ + private function shouldActivate(): bool + { + return strpos(setting('Auth.actions')['register'] ?? '', 'Activator') !== false; + } +} diff --git a/tests/Authentication/Filters/SessionFilterTest.php b/tests/Authentication/Filters/SessionFilterTest.php index a42609864..b9ec087eb 100644 --- a/tests/Authentication/Filters/SessionFilterTest.php +++ b/tests/Authentication/Filters/SessionFilterTest.php @@ -57,4 +57,30 @@ public function testRecordActiveDate(): void // Last Active should be greater than 'updated_at' column $this->assertGreaterThan(auth('session')->user()->updated_at, auth('session')->user()->last_active); } + + public function testBlocksInactiveUsers(): void + { + $user = fake(UserModel::class, ['active' => false]); + + // Activation only required with email activation + setting('Auth.actions', ['register' => null]); + + $result = $this->actingAs($user) + ->get('protected-route'); + + $result->assertStatus(200); + $result->assertSee('Protected'); + + // Now require user activation and try again + setting('Auth.actions', ['register' => '\CodeIgniter\Shield\Authentication\Actions\EmailActivator']); + + $result = $this->actingAs($user) + ->get('protected-route'); + + $result->assertRedirectTo('/login'); + // User should be logged out + $this->assertNull(auth('session')->id()); + + setting('Auth.actions', ['register' => null]); + } } diff --git a/tests/Authentication/Filters/TokenFilterTest.php b/tests/Authentication/Filters/TokenFilterTest.php index a7cc8080b..9c922b56c 100644 --- a/tests/Authentication/Filters/TokenFilterTest.php +++ b/tests/Authentication/Filters/TokenFilterTest.php @@ -24,7 +24,7 @@ public function testFilterNotAuthorized(): void { $result = $this->call('get', 'protected-route'); - $result->assertRedirectTo('/login'); + $result->assertStatus(403); $result = $this->get('open-route'); $result->assertStatus(200); @@ -84,6 +84,32 @@ public function testFiltersProtectsWithScopes(): void $result = $this->withHeaders(['Authorization' => 'Bearer ' . $token2->raw_token]) ->get('protected-user-route'); - $result->assertRedirectTo('/login'); + $result->assertStatus(403); + } + + public function testBlocksInactiveUsers(): void + { + /** @var User $user */ + $user = fake(UserModel::class, ['active' => false]); + $token = $user->generateAccessToken('foo'); + + // Activation only required with email activation + setting('Auth.actions', ['register' => null]); + + $result = $this->withHeaders(['Authorization' => 'Bearer ' . $token->raw_token]) + ->get('protected-route'); + + $result->assertStatus(200); + $result->assertSee('Protected'); + + // Now require user activation and try again + setting('Auth.actions', ['register' => '\CodeIgniter\Shield\Authentication\Actions\EmailActivator']); + + $result = $this->withHeaders(['Authorization' => 'Bearer ' . $token->raw_token]) + ->get('protected-route'); + + $result->assertStatus(403); + + setting('Auth.actions', ['register' => null]); } } diff --git a/tests/Unit/UserTest.php b/tests/Unit/UserTest.php index 494476f24..311105db7 100644 --- a/tests/Unit/UserTest.php +++ b/tests/Unit/UserTest.php @@ -7,6 +7,7 @@ use CodeIgniter\I18n\Time; use CodeIgniter\Shield\Authentication\Authenticators\Session; use CodeIgniter\Shield\Entities\Login; +use CodeIgniter\Shield\Entities\User; use CodeIgniter\Shield\Entities\UserIdentity; use CodeIgniter\Shield\Models\LoginModel; use CodeIgniter\Shield\Models\UserIdentityModel; @@ -256,4 +257,90 @@ public function testSaveEmailIdentity(): void $identity = $this->user->getEmailIdentity(); $this->assertSame('foo@example.com', $identity->secret); } + + public function testActivate(): void + { + $this->user->active = false; + model(UserModel::class)->save($this->user); + + $this->seeInDatabase('users', [ + 'id' => $this->user->id, + 'active' => 0, + ]); + + $this->user->activate(); + + // Refresh user + $this->user = model(UserModel::class)->find($this->user->id); + + $this->assertTrue($this->user->active); + $this->seeInDatabase('users', [ + 'id' => $this->user->id, + 'active' => 1, + ]); + } + + public function testDeactivate(): void + { + $this->user->active = true; + model(UserModel::class)->save($this->user); + + $this->seeInDatabase('users', [ + 'id' => $this->user->id, + 'active' => 1, + ]); + + $this->user->deactivate(); + + // Refresh user + $this->user = model(UserModel::class)->find($this->user->id); + + $this->assertFalse($this->user->active); + $this->seeInDatabase('users', [ + 'id' => $this->user->id, + 'active' => 0, + ]); + } + + public function testIsActivatedSuccessWhenNotRequired(): void + { + $this->user->active = false; + model(UserModel::class)->save($this->user); + + setting('Auth.actions', ['register' => null]); + + $this->assertTrue($this->user->isActivated()); + } + + public function testIsActivatedWhenRequired(): void + { + setting('Auth.actions', ['register' => '\CodeIgniter\Shield\Authentication\Actions\EmailActivator']); + $user = $this->user; + + $user->deactivate(); + /** @var User $user */ + $user = model(UserModel::class)->find($user->id); + + $this->assertFalse($user->isActivated()); + + $user->activate(); + /** @var User $user */ + $user = model(UserModel::class)->find($user->id); + + $this->assertTrue($user->isActivated()); + } + + public function testIsNotActivated(): void + { + setting('Auth.actions', ['register' => '\CodeIgniter\Shield\Authentication\Actions\EmailActivator']); + $user = $this->user; + + $user->active = false; + model(UserModel::class)->save($user); + + /** @var User $user */ + $user = model(UserModel::class)->find($user->id); + + $this->assertFalse($user->isActivated()); + } } From 7d3bc7a6ee2aa244d4ab75baaf136532410681be Mon Sep 17 00:00:00 2001 From: Lonnie Ezell Date: Wed, 4 Jan 2023 21:59:22 -0600 Subject: [PATCH 2/5] Apply suggestions from code review Co-authored-by: Pooya Parsa Dadashi --- docs/authorization.md | 2 +- src/Language/en/Auth.php | 2 +- src/Language/fa/Auth.php | 2 +- src/Traits/Activatable.php | 2 -- 4 files changed, 3 insertions(+), 5 deletions(-) diff --git a/docs/authorization.md b/docs/authorization.md index 5d089eb62..4268cc81d 100644 --- a/docs/authorization.md +++ b/docs/authorization.md @@ -252,7 +252,7 @@ if ($user->isActivated()) { } ``` -Note: If no activator is specified in the `Auth` config file, `actions['register']` property, then this will always return `true`. +> **Note** If no activator is specified in the `Auth` config file, `actions['register']` property, then this will always return `true`. You can check if a user has not been activated yet via the `isNotActivated()` method. diff --git a/src/Language/en/Auth.php b/src/Language/en/Auth.php index bb55db96a..1e58cc6e0 100644 --- a/src/Language/en/Auth.php +++ b/src/Language/en/Auth.php @@ -48,7 +48,7 @@ 'successLogout' => 'You have successfully logged out.', // Passwords - 'errorPasswordLength' => 'Passwords must be at least {0activationBlocked, number} characters long.', + 'errorPasswordLength' => 'Passwords must be at least {0, number} characters long.', 'suggestPasswordLength' => 'Pass phrases - up to 255 characters long - make more secure passwords that are easy to remember.', 'errorPasswordCommon' => 'Password must not be a common password.', 'suggestPasswordCommon' => 'The password was checked against over 65k commonly used passwords or passwords that have been leaked through hacks.', diff --git a/src/Language/fa/Auth.php b/src/Language/fa/Auth.php index 0a996bcbe..62a80d8e5 100644 --- a/src/Language/fa/Auth.php +++ b/src/Language/fa/Auth.php @@ -87,7 +87,7 @@ 'emailActivateMailBody' => 'لطفا برای فعالسازی حساب کاربری و استفاده از سایت از کد زیر استفاده کنید.', 'invalidActivateToken' => 'کد صحیح نمی باشد.', 'needActivate' => 'شما باید با ارائه کد ارسال شده به ایمیلتان، ثبت نام را تکمیل کنید.', - 'activationBlocked' => '(to be translated) You must activate your account before logging in.', + 'activationBlocked' => 'قبل از تلاش برای ورود، باید اکانت خود را فعال کنید.', // Groups 'unknownGroup' => '{0} گروهی معتبر نیست.', diff --git a/src/Traits/Activatable.php b/src/Traits/Activatable.php index e697a7357..f7629ec2c 100644 --- a/src/Traits/Activatable.php +++ b/src/Traits/Activatable.php @@ -29,7 +29,6 @@ public function isNotActivated(): bool */ public function activate(): bool { - helper('auth'); $model = auth()->getProvider(); return $model->update($this->id, ['active' => 1]); @@ -40,7 +39,6 @@ public function activate(): bool */ public function deactivate(): bool { - helper('auth'); $model = auth()->getProvider(); return $model->update($this->id, ['active' => 0]); From d1b3afce16b473bd24e84447b9b80069a1d912cd Mon Sep 17 00:00:00 2001 From: Lonnie Ezell Date: Sun, 29 Jan 2023 22:50:12 -0600 Subject: [PATCH 3/5] Update src/Language/ja/Auth.php Co-authored-by: kenjis --- src/Language/ja/Auth.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/Language/ja/Auth.php b/src/Language/ja/Auth.php index 30f556110..eff2edccf 100644 --- a/src/Language/ja/Auth.php +++ b/src/Language/ja/Auth.php @@ -87,7 +87,7 @@ 'emailActivateMailBody' => '以下のコードを使用してアカウントを有効化し、サイトの利用を開始してください。', // 'Please use the code below to activate your account and start using the site.', 'invalidActivateToken' => 'コードが間違っています。', // 'The code was incorrect.', 'needActivate' => 'メールアドレスに送信されたコードを確認し、登録を完了する必要があります。', // 'You must complete your registration by confirming the code sent to your email address.', - 'activationBlocked' => '(to be translated) You must activate your account before logging in.', + 'activationBlocked' => 'ログインする前にアカウントを有効化する必要があります。', // Groups 'unknownGroup' => '{0} は有効なグループではありません。', // '{0} is not a valid group.', From 62b60a91f6900e0e2f05fcaaf85c7ee3b2535609 Mon Sep 17 00:00:00 2001 From: Lonnie Ezell Date: Sun, 29 Jan 2023 22:58:57 -0600 Subject: [PATCH 4/5] Addressing comments --- src/Filters/TokenAuth.php | 2 +- tests/Authentication/Filters/TokenFilterTest.php | 4 ++-- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/src/Filters/TokenAuth.php b/src/Filters/TokenAuth.php index d141bda46..ee504cbd5 100644 --- a/src/Filters/TokenAuth.php +++ b/src/Filters/TokenAuth.php @@ -50,7 +50,7 @@ public function before(RequestInterface $request, $arguments = null) if (! $result->isOK() || (! empty($arguments) && $result->extraInfo()->tokenCant($arguments[0]))) { return service('response') - ->setStatusCode(Response::HTTP_FORBIDDEN) + ->setStatusCode(Response::HTTP_UNAUTHORIZED) ->setJson(['message' => lang('Auth.badToken')]); } diff --git a/tests/Authentication/Filters/TokenFilterTest.php b/tests/Authentication/Filters/TokenFilterTest.php index 9c922b56c..6efcfc93a 100644 --- a/tests/Authentication/Filters/TokenFilterTest.php +++ b/tests/Authentication/Filters/TokenFilterTest.php @@ -24,7 +24,7 @@ public function testFilterNotAuthorized(): void { $result = $this->call('get', 'protected-route'); - $result->assertStatus(403); + $result->assertStatus(401); $result = $this->get('open-route'); $result->assertStatus(200); @@ -84,7 +84,7 @@ public function testFiltersProtectsWithScopes(): void $result = $this->withHeaders(['Authorization' => 'Bearer ' . $token2->raw_token]) ->get('protected-user-route'); - $result->assertStatus(403); + $result->assertStatus(401); } public function testBlocksInactiveUsers(): void From 8ab2d6f973c653c5a091cab0772df9b37d5e5a0a Mon Sep 17 00:00:00 2001 From: Lonnie Ezell Date: Fri, 3 Feb 2023 22:11:54 -0600 Subject: [PATCH 5/5] Adding text for pt-BR language. --- src/Entities/User.php | 2 +- src/Language/pt-BR/Auth.php | 1 + 2 files changed, 2 insertions(+), 1 deletion(-) diff --git a/src/Entities/User.php b/src/Entities/User.php index f7c7b3112..ca0fc96ae 100644 --- a/src/Entities/User.php +++ b/src/Entities/User.php @@ -11,8 +11,8 @@ use CodeIgniter\Shield\Authorization\Traits\Authorizable; use CodeIgniter\Shield\Models\LoginModel; use CodeIgniter\Shield\Models\UserIdentityModel; -use CodeIgniter\Shield\Traits\Resettable; use CodeIgniter\Shield\Traits\Activatable; +use CodeIgniter\Shield\Traits\Resettable; /** * @property string|null $email diff --git a/src/Language/pt-BR/Auth.php b/src/Language/pt-BR/Auth.php index 3afcb3837..7e078617a 100644 --- a/src/Language/pt-BR/Auth.php +++ b/src/Language/pt-BR/Auth.php @@ -87,6 +87,7 @@ 'emailActivateMailBody' => 'Use o código abaixo para ativar sua conta e começar a usar o site.', 'invalidActivateToken' => 'O código estava incorreto.', 'needActivate' => 'Você deve concluir seu registro confirmando o código enviado para seu endereço de e-mail.', + 'activationBlocked' => '(to be translated) You must activate your account before logging in.', // Grupos 'unknownGroup' => '{0} não é um grupo válido.',