Skip to content

Commit dfb9c7d

Browse files
authored
4.4.1 Release
2 parents c62790e + 86b588b commit dfb9c7d

28 files changed

+253
-111
lines changed

.github/CONTRIBUTING.md

Lines changed: 7 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -58,7 +58,7 @@ Contains breaking changes that will need to wait for the next version to be inte
5858
When ready, changes should be merged into both **master** and **hotfix**.
5959

6060
#### `feature-*`
61-
New features that introduce some breaking changes or incomplete code should be committed in a separate `feature-{name}` branch.
61+
New features that introduce some breaking changes or incomplete code should be committed in a separate `feature-{name}` branch.
6262

6363
When ready, the branch should be **[squashed-merged](https://github.com/blog/2141-squash-your-commits)** ([guide](https://stackoverflow.com/a/5309051/445757)) into `develop` (or `hotfix` if it doesn't introduce a breaking change).
6464

@@ -117,11 +117,13 @@ Additionally, the `learn` repository can have `dev-*` for learn specific feature
117117

118118
## Building the API documentation
119119

120-
To build the API documentation, install [ApiGen](http://www.apigen.org/) globally and then run:
120+
To build the API documentation, install [phpDocumentor](https://www.phpdoc.org) globally and then run from the UserFrosting root :
121121

122-
`apigen generate --source UserFrosting/app,userfrosting-assets/src,userfrosting-config/Config,userfrosting-fortress/Fortress,userfrosting-i18n/I18n,userfrosting-session/Session,userfrosting-support/Support --destination userfrosting-api --exclude *vendor*,*_meta* --template-theme "bootstrap"`
122+
```
123+
phpdoc
124+
```
123125

124-
from inside your dev directory.
126+
The resulting documentation will be available in `api/`.
125127

126128
## Automatically fixing coding style with PHP-CS-Fixer
127129

@@ -135,6 +137,6 @@ app/vendor/bin/php-cs-fixer fix
135137

136138
## Useful tools
137139

138-
If you are using **Atom**, be sure to checkout theses useful packages :
140+
If you are using **Atom**, be sure to checkout theses useful packages :
139141
- [Docblockr](https://atom.io/packages/docblockr) : Used to generate [documentation block](https://github.com/userfrosting/UserFrosting/blob/master/STYLE-GUIDE.md#documentation).
140142
- [php-ide-serenata](https://atom.io/packages/php-ide-serenata) : Integrates [Serenata](https://gitlab.com/Serenata/Serenata) as PHP IDE, providing autocompletion, code navigation, refactoring, signature help, linting and annotations.

.gitignore

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -77,6 +77,9 @@ vagrant/Homestead/
7777
.phpunit.result.cache
7878
.php_cs.cache
7979

80+
# Ignore api doc
81+
api/
82+
8083
# Igore npm lockfile
8184
build/package-lock.json
8285
build/package.lock

CHANGELOG.md

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,15 @@ All notable changes to this project will be documented in this file.
55
The format is based on [Keep a Changelog](http://keepachangelog.com/en/1.0.0/)
66
and this project adheres to [Semantic Versioning](http://semver.org/spec/v2.0.0.html).
77

8+
## [v4.4.1]
9+
10+
### Fixed
11+
- Fixed issue where incompatible NPM packages would be browserified, resulting in install failures.
12+
- Replaced deprecated Twig class.
13+
- Fixed issue when compiling assets for production ([#1078]).
14+
- Migration dependencies should work with and without leading `\` ([#1023])
15+
- Throttler don't count successful logins ([#1073])
16+
817
## [v4.4.0]
918

1019
### Changed Requirements
@@ -921,6 +930,7 @@ See [http://learn.userfrosting.com/upgrading/40-to-41](Upgrading 4.0.x to 4.1.x
921930
[#1017]: https://github.com/userfrosting/UserFrosting/issues/1017
922931
[#1018]: https://github.com/userfrosting/UserFrosting/issues/1018
923932
[#1019]: https://github.com/userfrosting/UserFrosting/issues/1019
933+
[#1023]: https://github.com/userfrosting/UserFrosting/issues/1023
924934
[#1027]: https://github.com/userfrosting/UserFrosting/issues/1027
925935
[#1028]: https://github.com/userfrosting/UserFrosting/issues/1028
926936
[#1030]: https://github.com/userfrosting/UserFrosting/issues/1030
@@ -938,6 +948,8 @@ See [http://learn.userfrosting.com/upgrading/40-to-41](Upgrading 4.0.x to 4.1.x
938948
[#1057]: https://github.com/userfrosting/UserFrosting/issues/1057
939949
[#1061]: https://github.com/userfrosting/UserFrosting/issues/1061
940950
[#1062]: https://github.com/userfrosting/UserFrosting/issues/1062
951+
[#1073]: https://github.com/userfrosting/UserFrosting/issues/1073
952+
[#1078]: https://github.com/userfrosting/UserFrosting/issues/1078
941953

942954
[v4.2.0]: https://github.com/userfrosting/UserFrosting/compare/v4.1.22...v4.2.0
943955
[v4.2.1]: https://github.com/userfrosting/UserFrosting/compare/v4.2.0...v.4.2.1

app/defines.php

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -11,7 +11,7 @@
1111
namespace UserFrosting;
1212

1313
// Some standard defines
14-
define('UserFrosting\VERSION', '4.4.0');
14+
define('UserFrosting\VERSION', '4.4.1');
1515
define('UserFrosting\DS', '/');
1616
define('UserFrosting\PHP_MIN_VERSION', '7.1');
1717
define('UserFrosting\PHP_RECOMMENDED_VERSION', '7.3');

app/sprinkles/account/src/Controller/AccountController.php

Lines changed: 10 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -396,13 +396,11 @@ public function login(Request $request, Response $response, $args)
396396
return $response->withJson([], 429);
397397
}
398398

399-
// Log throttleable event
400-
$throttler->logEvent('sign_in_attempt', $throttleData);
401-
402399
// If credential is an email address, but email login is not enabled, raise an error.
403-
// Note that we do this after logging throttle event, so this error counts towards throttling limit.
400+
// Note that this error counts towards the throttling limit.
404401
if ($isEmail && !$config['site.login.enable_email']) {
405402
$ms->addMessageTranslated('danger', 'USER_OR_PASS_INVALID');
403+
$throttler->logEvent('sign_in_attempt', $throttleData);
406404

407405
return $response->withJson([], 403);
408406
}
@@ -411,7 +409,14 @@ public function login(Request $request, Response $response, $args)
411409
/** @var \UserFrosting\Sprinkle\Account\Authenticate\Authenticator $authenticator */
412410
$authenticator = $this->ci->authenticator;
413411

414-
$currentUser = $authenticator->attempt(($isEmail ? 'email' : 'user_name'), $userIdentifier, $data['password'], $data['rememberme']);
412+
try {
413+
$currentUser = $authenticator->attempt(($isEmail ? 'email' : 'user_name'), $userIdentifier, $data['password'], $data['rememberme']);
414+
} catch (\Exception $e) {
415+
// only let unsuccessful logins count toward the throttling limit
416+
$throttler->logEvent('sign_in_attempt', $throttleData);
417+
418+
throw $e;
419+
}
415420

416421
$ms->addMessageTranslated('success', 'WELCOME', $currentUser->export());
417422

app/sprinkles/account/src/Database/Models/Activity.php

Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -21,11 +21,11 @@
2121
*
2222
* @author Alex Weissman (https://alexanderweissman.com)
2323
*
24-
* @property string ip_address
25-
* @property int user_id
26-
* @property string type
27-
* @property datetime occurred_at
28-
* @property string description
24+
* @property string $ip_address
25+
* @property int $user_id
26+
* @property string $type
27+
* @property datetime $occurred_at
28+
* @property string $description
2929
*/
3030
class Activity extends Model
3131
{

app/sprinkles/account/src/Database/Models/Group.php

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -21,10 +21,10 @@
2121
*
2222
* @see http://www.userfrosting.com/tutorials/lesson-3-data-model/
2323
*
24-
* @property string slug
25-
* @property string name
26-
* @property string description
27-
* @property string icon
24+
* @property string $slug
25+
* @property string $name
26+
* @property string $description
27+
* @property string $icon
2828
*/
2929
class Group extends Model
3030
{

app/sprinkles/account/src/Database/Models/PasswordReset.php

Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -19,11 +19,11 @@
1919
*
2020
* @author Alex Weissman (https://alexanderweissman.com)
2121
*
22-
* @property int user_id
23-
* @property hash token
24-
* @property bool completed
25-
* @property datetime expires_at
26-
* @property datetime completed_at
22+
* @property int $user_id
23+
* @property hash $token
24+
* @property bool $completed
25+
* @property datetime $expires_at
26+
* @property datetime $completed_at
2727
*/
2828
class PasswordReset extends Model
2929
{

app/sprinkles/account/src/Database/Models/Permission.php

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -20,10 +20,10 @@
2020
*
2121
* @author Alex Weissman (https://alexanderweissman.com)
2222
*
23-
* @property string slug
24-
* @property string name
25-
* @property string conditions
26-
* @property string description
23+
* @property string $slug
24+
* @property string $name
25+
* @property string $conditions
26+
* @property string $description
2727
*/
2828
class Permission extends Model
2929
{

app/sprinkles/account/src/Database/Models/Persistence.php

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -20,10 +20,10 @@
2020
*
2121
* @author Louis Charette
2222
*
23-
* @property string user_id
24-
* @property string token
25-
* @property string persistent_token
26-
* @property string expires_at
23+
* @property string $user_id
24+
* @property string $token
25+
* @property string $persistent_token
26+
* @property string $expires_at
2727
*/
2828
class Persistence extends Model
2929
{

app/sprinkles/account/src/Database/Models/Role.php

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -20,9 +20,9 @@
2020
*
2121
* @author Alex Weissman (https://alexanderweissman.com)
2222
*
23-
* @property string slug
24-
* @property string name
25-
* @property string description
23+
* @property string $slug
24+
* @property string $name
25+
* @property string $description
2626
*/
2727
class Role extends Model
2828
{

app/sprinkles/account/src/Database/Models/User.php

Lines changed: 15 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -25,21 +25,21 @@
2525
*
2626
* @author Alex Weissman (https://alexanderweissman.com)
2727
*
28-
* @property int id
29-
* @property string user_name
30-
* @property string first_name
31-
* @property string last_name
32-
* @property string email
33-
* @property string locale
34-
* @property string theme
35-
* @property int group_id
36-
* @property bool flag_verified
37-
* @property bool flag_enabled
38-
* @property int last_activity_id
39-
* @property timestamp created_at
40-
* @property timestamp updated_at
41-
* @property string password
42-
* @property timestamp deleted_at
28+
* @property int $id
29+
* @property string $user_name
30+
* @property string $first_name
31+
* @property string $last_name
32+
* @property string $email
33+
* @property string $locale
34+
* @property string $theme
35+
* @property int $group_id
36+
* @property bool $flag_verified
37+
* @property bool $flag_enabled
38+
* @property int $last_activity_id
39+
* @property timestamp $created_at
40+
* @property timestamp $updated_at
41+
* @property string $password
42+
* @property timestamp $deleted_at
4343
*/
4444
class User extends Model implements UserInterface
4545
{

app/sprinkles/account/src/Database/Models/Verification.php

Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -19,11 +19,11 @@
1919
*
2020
* @author Alex Weissman (https://alexanderweissman.com)
2121
*
22-
* @property int user_id
23-
* @property hash token
24-
* @property bool completed
25-
* @property datetime expires_at
26-
* @property datetime completed_at
22+
* @property int $user_id
23+
* @property hash $token
24+
* @property bool $completed
25+
* @property datetime $expires_at
26+
* @property datetime $completed_at
2727
*/
2828
class Verification extends Model
2929
{

app/sprinkles/account/src/Twig/AccountExtension.php

Lines changed: 6 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -11,14 +11,17 @@
1111
namespace UserFrosting\Sprinkle\Account\Twig;
1212

1313
use Psr\Container\ContainerInterface;
14+
use Twig\Extension\AbstractExtension;
15+
use Twig\Extension\GlobalsInterface;
16+
use Twig\TwigFunction;
1417
use UserFrosting\Support\Repository\Repository as Config;
1518

1619
/**
1720
* Extends Twig functionality for the Account sprinkle.
1821
*
1922
* @author Alex Weissman (https://alexanderweissman.com)
2023
*/
21-
class AccountExtension extends \Twig_Extension implements \Twig_Extension_GlobalsInterface
24+
class AccountExtension extends AbstractExtension implements GlobalsInterface
2225
{
2326
/**
2427
* @var ContainerInterface
@@ -48,13 +51,13 @@ public function getFunctions()
4851
{
4952
return [
5053
// Add Twig function for checking permissions during dynamic menu rendering
51-
new \Twig_SimpleFunction('checkAccess', function ($slug, $params = []) {
54+
new TwigFunction('checkAccess', function ($slug, $params = []) {
5255
$authorizer = $this->services->authorizer;
5356
$currentUser = $this->services->currentUser;
5457

5558
return $authorizer->checkAccess($currentUser, $slug, $params);
5659
}),
57-
new \Twig_SimpleFunction('checkAuthenticated', function () {
60+
new TwigFunction('checkAuthenticated', function () {
5861
$authenticator = $this->services->authenticator;
5962

6063
return $authenticator->check();

app/sprinkles/account/tests/Integration/Controller/AccountControllerTest.php

Lines changed: 69 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -11,6 +11,7 @@
1111
namespace UserFrosting\Sprinkle\Account\Tests\Integration\Controller;
1212

1313
use Mockery as m;
14+
use UserFrosting\Sprinkle\Account\Authenticate\Exception;
1415
use UserFrosting\Sprinkle\Account\Controller\AccountController;
1516
use UserFrosting\Sprinkle\Account\Controller\Exception\SpammyRequestException;
1617
use UserFrosting\Sprinkle\Account\Database\Models\Interfaces\UserInterface;
@@ -618,6 +619,74 @@ public function testloginWithThrottler()
618619
$this->assertSame('danger', end($messages)['type']);
619620
}
620621

622+
/**
623+
* @depends testControllerConstructor
624+
*/
625+
public function testloginThrottlerCountsFailedLogins()
626+
{
627+
// Create fake throttler
628+
$throttler = m::mock(Throttler::class);
629+
$throttler->shouldReceive('getDelay')->once()->with('sign_in_attempt', ['user_identifier' => 'foo'])->andReturn(0);
630+
$throttler->shouldReceive('logEvent')->once()->with('sign_in_attempt', ['user_identifier' => 'foo']);
631+
$this->ci->throttler = $throttler;
632+
633+
// Recreate controller to use fake throttler
634+
$controller = $this->getController();
635+
636+
// Set POST
637+
$request = $this->getRequest()->withParsedBody([
638+
'user_name' => 'foo',
639+
'password' => 'bar',
640+
'rememberme' => false,
641+
]);
642+
643+
$this->expectException(Exception\InvalidCredentialsException::class);
644+
645+
$controller->login($request, $this->getResponse(), []);
646+
}
647+
648+
/**
649+
* @depends testControllerConstructor
650+
*/
651+
public function testloginThrottlerDoesntCountSuccessfulLogins()
652+
{
653+
// Create a test user
654+
$testUser = $this->createTestUser();
655+
656+
// Faker doesn't hash the password. Let's do that now
657+
$unhashed = $testUser->password;
658+
$testUser->password = Password::hash($testUser->password);
659+
$testUser->save();
660+
661+
// Create fake throttler
662+
$throttler = m::mock(Throttler::class);
663+
$throttler->shouldReceive('getDelay')->once()->with('sign_in_attempt', ['user_identifier' => $testUser->email])->andReturn(0);
664+
$throttler->shouldNotReceive('logEvent');
665+
$this->ci->throttler = $throttler;
666+
667+
// Recreate controller to use fake throttler and test user
668+
$controller = $this->getController();
669+
670+
// Set POST
671+
$request = $this->getRequest()->withParsedBody([
672+
'user_name' => $testUser->email,
673+
'password' => $unhashed,
674+
'rememberme' => false,
675+
]);
676+
677+
$result = $controller->login($request, $this->getResponse(), []);
678+
$this->assertInstanceOf(\Psr\Http\Message\ResponseInterface::class, $result);
679+
// Can't assert the status code or data, as this can be overwrited by sprinkles
680+
681+
// Test message
682+
$ms = $this->ci->alerts;
683+
$messages = $ms->getAndClearMessages();
684+
$this->assertSame('success', end($messages)['type']);
685+
686+
// We have to logout the user to avoid problem
687+
$this->logoutCurrentUser($testUser);
688+
}
689+
621690
/**
622691
* @depends testControllerConstructor
623692
*/

0 commit comments

Comments
 (0)