From 27983ef730f68affb70ac03ffc634880be4ff2d6 Mon Sep 17 00:00:00 2001 From: ErickSkrauch Date: Thu, 4 Jan 2018 02:10:16 +0300 Subject: [PATCH 1/6] 1.1.24-dev [skip ci] --- common/config/config.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/common/config/config.php b/common/config/config.php index 4e9e107..b79bd6b 100644 --- a/common/config/config.php +++ b/common/config/config.php @@ -1,6 +1,6 @@ '1.1.23', + 'version' => '1.1.24-dev', 'vendorPath' => dirname(__DIR__, 2) . '/vendor', 'components' => [ 'cache' => [ From fb5baa18668ede44efbf58195faded1b731c0ff2 Mon Sep 17 00:00:00 2001 From: ErickSkrauch Date: Sun, 7 Jan 2018 19:08:40 +0300 Subject: [PATCH 2/6] =?UTF-8?q?=D0=94=D0=BE=D0=B1=D0=B0=D0=B2=D0=BB=D0=B5?= =?UTF-8?q?=D0=BD=D0=B0=20=D0=BA=D0=B0=D1=81=D1=82=D0=BE=D0=BC=D0=BD=D0=B0?= =?UTF-8?q?=D1=8F=20trim=20=D1=84=D1=83=D0=BD=D0=BA=D1=86=D0=B8=D1=8F=20?= =?UTF-8?q?=D0=B4=D0=BB=D1=8F=20=D0=BE=D0=B1=D1=80=D0=B5=D0=B7=D0=B0=D0=BD?= =?UTF-8?q?=D0=B8=D1=8F=20=D0=B2=D1=81=D0=B5=D1=85=20UTF-8=20=D0=BF=D1=80?= =?UTF-8?q?=D0=BE=D0=B1=D0=B5=D0=BB=D0=BE=D0=B2?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- common/helpers/StringHelper.php | 18 ++++++++- common/validators/EmailValidator.php | 3 +- common/validators/UsernameValidator.php | 3 +- .../common/unit/helpers/StringHelperTest.php | 38 +++++++++++++++++++ .../unit/validators/EmailValidatorTest.php | 10 +++++ .../unit/validators/UsernameValidatorTest.php | 7 ++++ 6 files changed, 75 insertions(+), 4 deletions(-) diff --git a/common/helpers/StringHelper.php b/common/helpers/StringHelper.php index efa49d9..70d648e 100644 --- a/common/helpers/StringHelper.php +++ b/common/helpers/StringHelper.php @@ -1,11 +1,12 @@ 'trim']); + $filter = new validators\FilterValidator(['filter' => [StringHelper::class, 'trim']]); $required = new validators\RequiredValidator(); $required->message = E::EMAIL_REQUIRED; diff --git a/common/validators/UsernameValidator.php b/common/validators/UsernameValidator.php index 7f5b76d..657bd03 100644 --- a/common/validators/UsernameValidator.php +++ b/common/validators/UsernameValidator.php @@ -2,6 +2,7 @@ namespace common\validators; use common\helpers\Error as E; +use common\helpers\StringHelper; use common\models\Account; use yii\base\Model; use yii\db\QueryInterface; @@ -19,7 +20,7 @@ class UsernameValidator extends Validator { public $skipOnEmpty = false; public function validateAttribute($model, $attribute) { - $filter = new validators\FilterValidator(['filter' => 'trim']); + $filter = new validators\FilterValidator(['filter' => [StringHelper::class, 'trim']]); $required = new validators\RequiredValidator(); $required->message = E::USERNAME_REQUIRED; diff --git a/tests/codeception/common/unit/helpers/StringHelperTest.php b/tests/codeception/common/unit/helpers/StringHelperTest.php index b1f1a21..fe6e4bf 100644 --- a/tests/codeception/common/unit/helpers/StringHelperTest.php +++ b/tests/codeception/common/unit/helpers/StringHelperTest.php @@ -19,4 +19,42 @@ class StringHelperTest extends \PHPUnit_Framework_TestCase { $this->assertFalse(StringHelper::isUuid('12345678')); } + /** + * @dataProvider trimProvider() + */ + public function testTrim($expected, $string) { + $result = StringHelper::trim($string); + $this->assertEquals($expected, $result); + } + + /** + * http://jkorpela.fi/chars/spaces.html + * http://www.alanwood.net/unicode/general_punctuation.html + * + * @return array + */ + public function trimProvider() { + return [ + ['foo bar', ' foo bar '], // Simple spaces + ['foo bar', ' foo bar'], // Only left side space + ['foo bar', 'foo bar '], // Only right side space + ['foo bar', "\n\t foo bar \n\t"], // New line, tab character and simple space + ['fòô bàř', ' fòô bàř '], // UTF-8 text + ['fòô bàř', ' fòô bàř'], // Only left side space width UTF-8 text + ['fòô bàř', 'fòô bàř '], // Only right side space width UTF-8 text + ['fòô bàř', "\n\t fòô bàř \n\t"], // New line, tab character and simple space width UTF-8 string + ['fòô', "\u{00a0}fòô\u{00a0}"], // No-break space (U+00A0) + ['fòô', "\u{1680}fòô\u{1680}"], // Ogham space mark (U+1680) + ['fòô', "\u{180e}fòô\u{180e}"], // Mongolian vowel separator (U+180E) + ['fòô', "\u{2000}\u{2001}\u{2002}\u{2003}\u{2004}\u{2005}\u{2006}\u{2007}fòô"], // Spaces U+2000 to U+2007 + ['fòô', "\u{2008}\u{2009}\u{200a}\u{200b}\u{200c}\u{200d}\u{200e}\u{200f}fòô"], // Spaces U+2008 to U+200F + ['fòô', "\u{2028}\u{2029}\u{202a}\u{202b}\u{202c}\u{202d}\u{202e}\u{202f}fòô"], // Spaces U+2028 to U+202F + ['fòô', "\u{2060}\u{2061}\u{2062}\u{2063}\u{2064}\u{2065}\u{2066}\u{2067}fòô"], // Spaces U+2060 to U+2067 + ['fòô', "\u{2068}\u{2069}\u{206a}\u{206b}\u{206c}\u{206d}\u{206e}\u{206f}fòô"], // Spaces U+2068 to U+206F + ['fòô', "\u{205f}fòô\u{205f}"], // Medium mathematical space (U+205F) + ['fòô', "\u{3000}fòô\u{3000}"], // Ideographic space (U+3000) + ['fòô', "\u{feff}fòô\u{feff}"], // Zero width no-break space (U+FEFF) + ]; + } + } diff --git a/tests/codeception/common/unit/validators/EmailValidatorTest.php b/tests/codeception/common/unit/validators/EmailValidatorTest.php index d6f4425..614085a 100644 --- a/tests/codeception/common/unit/validators/EmailValidatorTest.php +++ b/tests/codeception/common/unit/validators/EmailValidatorTest.php @@ -20,6 +20,16 @@ class EmailValidatorTest extends TestCase { $this->validator = new EmailValidator(); } + public function testValidateTrimming() { + // Prevent it to access to db + Mock::func(YiiEmailValidator::class, 'checkdnsrr')->andReturn(false); + + $model = $this->createModel("testemail@ely.by\u{feff}"); // Zero width no-break space (U+FEFF) + $this->validator->validateAttribute($model, 'field'); + $this->assertEquals(['error.email_invalid'], $model->getErrors('field')); + $this->assertEquals('testemail@ely.by', $model->field); + } + public function testValidateAttributeRequired() { $model = $this->createModel(''); $this->validator->validateAttribute($model, 'field'); diff --git a/tests/codeception/common/unit/validators/UsernameValidatorTest.php b/tests/codeception/common/unit/validators/UsernameValidatorTest.php index 34ed86e..58154a5 100644 --- a/tests/codeception/common/unit/validators/UsernameValidatorTest.php +++ b/tests/codeception/common/unit/validators/UsernameValidatorTest.php @@ -18,6 +18,13 @@ class UsernameValidatorTest extends TestCase { $this->validator = new UsernameValidator(); } + public function testValidateTrimming() { + $model = $this->createModel("HereIsJohnny#\u{feff}"); // Zero width no-break space (U+FEFF) + $this->validator->validateAttribute($model, 'field'); + $this->assertEquals(['error.username_invalid'], $model->getErrors('field')); + $this->assertEquals('HereIsJohnny#', $model->field); + } + public function testValidateAttributeRequired() { $model = $this->createModel(''); $this->validator->validateAttribute($model, 'field'); From 3f5b34fc1ffa22203bbaa80364a9d47757e7827c Mon Sep 17 00:00:00 2001 From: ErickSkrauch Date: Tue, 9 Jan 2018 01:23:11 +0300 Subject: [PATCH 3/6] =?UTF-8?q?=D0=A3=D1=87=D0=B8=D1=82=D1=8B=D0=B2=D0=B0?= =?UTF-8?q?=D0=B5=D0=BC=20=D0=B2=D0=B5=D1=80=D0=BE=D1=8F=D1=82=D0=BD=D0=BE?= =?UTF-8?q?=D1=81=D1=82=D1=8C=20=D0=BF=D0=BE=D0=BB=D1=83=D1=87=D0=B5=D0=BD?= =?UTF-8?q?=D0=B8=D1=8F=20null-=D0=B5=D0=B2=D0=BE=D0=B3=D0=BE=20=D0=B7?= =?UTF-8?q?=D0=BD=D0=B0=D1=87=D0=B5=D0=BD=D0=B8=D1=8F=20=D0=B2=20=D0=BD?= =?UTF-8?q?=D0=B0=D1=88=D1=83=20=D1=80=D0=B5=D0=B0=D0=BB=D0=B8=D0=B7=D0=B0?= =?UTF-8?q?=D1=86=D0=B8=D1=8E=20trim?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- common/helpers/StringHelper.php | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/common/helpers/StringHelper.php b/common/helpers/StringHelper.php index 70d648e..97be7b1 100644 --- a/common/helpers/StringHelper.php +++ b/common/helpers/StringHelper.php @@ -49,7 +49,11 @@ class StringHelper { * @param string $string string to remove whitespaces * @return string trimmed $string */ - public static function trim(string $string): string { + public static function trim(?string $string): string { + if ($string === null) { + return ''; + } + return preg_replace('/^[\pZ\pC]+|[\pZ\pC]+$/u', '', $string); } From 01850bb2d612e75d2e0cc635492e11d1343728e0 Mon Sep 17 00:00:00 2001 From: ErickSkrauch Date: Fri, 12 Jan 2018 13:50:19 +0300 Subject: [PATCH 4/6] Fixes ACCOUNTS-34Y MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit После перехода на utf8mb4_unicode_ci забыли обновить кодировку подключения к БД --- common/config/config.php | 4 +-- .../api/functional/EmailConfirmationCest.php | 32 +++++++++++++++---- 2 files changed, 27 insertions(+), 9 deletions(-) diff --git a/common/config/config.php b/common/config/config.php index b79bd6b..b753c9f 100644 --- a/common/config/config.php +++ b/common/config/config.php @@ -12,7 +12,7 @@ return [ 'dsn' => 'mysql:host=' . (getenv('DB_HOST') ?: 'db') . ';dbname=' . getenv('DB_DATABASE'), 'username' => getenv('DB_USER'), 'password' => getenv('DB_PASSWORD'), - 'charset' => 'utf8', + 'charset' => 'utf8mb4', 'schemaMap' => [ 'mysql' => common\db\mysql\Schema::class, ], @@ -22,7 +22,7 @@ return [ 'dsn' => 'mysql:host=' . (getenv('DB_HOST') ?: 'db') . ';dbname=' . getenv('DB_DATABASE'), 'username' => getenv('DB_USER'), 'password' => getenv('DB_PASSWORD'), - 'charset' => 'utf8', + 'charset' => 'utf8mb4', 'attributes' => [ PDO::MYSQL_ATTR_USE_BUFFERED_QUERY => false, ], diff --git a/tests/codeception/api/functional/EmailConfirmationCest.php b/tests/codeception/api/functional/EmailConfirmationCest.php index 2f4e8da..ea2d637 100644 --- a/tests/codeception/api/functional/EmailConfirmationCest.php +++ b/tests/codeception/api/functional/EmailConfirmationCest.php @@ -5,7 +5,19 @@ use tests\codeception\api\_pages\SignupRoute; class EmailConfirmationCest { - public function testLoginEmailOrUsername(FunctionalTester $I) { + public function testConfirmEmailByCorrectKey(FunctionalTester $I) { + $route = new SignupRoute($I); + + $I->wantTo('confirm my email using correct activation key'); + $route->confirm('HABGCABHJ1234HBHVD'); + $I->canSeeResponseContainsJson([ + 'success' => true, + ]); + $I->cantSeeResponseJsonMatchesJsonPath('$.errors'); + $I->canSeeAuthCredentials(true); + } + + public function testConfirmEmailByInvalidKey(FunctionalTester $I) { $route = new SignupRoute($I); $I->wantTo('see error.key_is_required expected if key is not set'); @@ -27,16 +39,22 @@ class EmailConfirmationCest { ]); } - public function testLoginByEmailCorrect(FunctionalTester $I) { + public function testConfirmByInvalidEmojiString(FunctionalTester $I) { $route = new SignupRoute($I); - $I->wantTo('confirm my email using correct activation key'); - $route->confirm('HABGCABHJ1234HBHVD'); + $I->wantTo('try to submit some long emoji string (Sentry ACCOUNTS-43Y)'); + $route->confirm( + 'ALWAYS 🕔 make sure 👍 to shave 🔪🍑 because ✌️ the last time 🕒 we let 👐😪 a bush 🌳 ' . + 'in our lives 👈😜👉 it did 9/11 💥🏢🏢✈️🔥🔥🔥 ALWAYS 🕔 make sure 👍 to shave 🔪🍑 ' . + 'because ✌️ the last time 🕒 we let 👐😪 a bush 🌳 in our lives 👈😜👉 it did 9/11 ' . + '💥🏢🏢✈️🔥🔥🔥/' + ); $I->canSeeResponseContainsJson([ - 'success' => true, + 'success' => false, + 'errors' => [ + 'key' => 'error.key_not_exists', + ], ]); - $I->cantSeeResponseJsonMatchesJsonPath('$.errors'); - $I->canSeeAuthCredentials(true); } } From 013ddd1b1b82e805cad5147a86a978ba2b170ec7 Mon Sep 17 00:00:00 2001 From: ErickSkrauch Date: Sun, 28 Jan 2018 13:34:27 +0300 Subject: [PATCH 5/6] =?UTF-8?q?=D0=94=D0=BE=D0=B1=D0=B0=D0=B2=D0=BB=D0=B5?= =?UTF-8?q?=D0=BD=D0=BE=20=D1=8D=D0=BA=D1=80=D0=B0=D0=BD=D0=B8=D1=80=D0=BE?= =?UTF-8?q?=D0=B2=D0=B0=D0=BD=D0=B8=D0=B5=20#=20=D1=81=D0=B8=D0=BC=D0=B2?= =?UTF-8?q?=D0=BE=D0=BB=D0=B0=20=D0=B2=20QR=20=D0=BA=D0=BE=D0=B4=D0=B5?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- api/modules/accounts/models/TwoFactorAuthInfo.php | 10 +++++++++- 1 file changed, 9 insertions(+), 1 deletion(-) diff --git a/api/modules/accounts/models/TwoFactorAuthInfo.php b/api/modules/accounts/models/TwoFactorAuthInfo.php index 43e0829..7301516 100644 --- a/api/modules/accounts/models/TwoFactorAuthInfo.php +++ b/api/modules/accounts/models/TwoFactorAuthInfo.php @@ -22,7 +22,7 @@ class TwoFactorAuthInfo extends BaseAccountForm { $provisioningUri = $this->getTotp()->getProvisioningUri(); return [ - 'qr' => 'data:image/svg+xml,' . trim($this->drawQrCode($provisioningUri)), + 'qr' => $this->buildDataImage($this->drawQrCode($provisioningUri)), 'uri' => $provisioningUri, 'secret' => $this->getAccount()->otp_secret, ]; @@ -41,6 +41,14 @@ class TwoFactorAuthInfo extends BaseAccountForm { return $writer->writeString($content, Encoder::DEFAULT_BYTE_MODE_ECODING, ErrorCorrectionLevel::H); } + private function buildDataImage(string $svg) { + $svg = trim($svg); + // https://stackoverflow.com/a/30733736/5184751 + $svg = str_replace('#', '%23', $svg); + + return 'data:image/svg+xml,' . $svg; + } + /** * @param int $length * @throws ThisShouldNotHappenException From 2f4b8b624950151cd48abf54e8e86af5f309f096 Mon Sep 17 00:00:00 2001 From: ErickSkrauch Date: Sun, 28 Jan 2018 13:41:49 +0300 Subject: [PATCH 6/6] 1.1.24 [skip ci] --- common/config/config.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/common/config/config.php b/common/config/config.php index b753c9f..a54c6e4 100644 --- a/common/config/config.php +++ b/common/config/config.php @@ -1,6 +1,6 @@ '1.1.24-dev', + 'version' => '1.1.24', 'vendorPath' => dirname(__DIR__, 2) . '/vendor', 'components' => [ 'cache' => [