mirror of
https://github.com/elyby/accounts.git
synced 2024-11-23 05:33:20 +05:30
Merge branch 'develop'
This commit is contained in:
commit
d1506734ab
@ -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
|
||||
|
@ -1,6 +1,6 @@
|
||||
<?php
|
||||
return [
|
||||
'version' => '1.1.23',
|
||||
'version' => '1.1.24',
|
||||
'vendorPath' => dirname(__DIR__, 2) . '/vendor',
|
||||
'components' => [
|
||||
'cache' => [
|
||||
@ -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,
|
||||
],
|
||||
|
@ -1,11 +1,12 @@
|
||||
<?php
|
||||
declare(strict_types=1);
|
||||
namespace common\helpers;
|
||||
|
||||
use Ramsey\Uuid\Uuid;
|
||||
|
||||
class StringHelper {
|
||||
|
||||
public static function getEmailMask(string $email) : string {
|
||||
public static function getEmailMask(string $email): string {
|
||||
$username = explode('@', $email)[0];
|
||||
$usernameLength = mb_strlen($username);
|
||||
$maskChars = '**';
|
||||
@ -29,7 +30,7 @@ class StringHelper {
|
||||
* @param string $uuid
|
||||
* @return bool
|
||||
*/
|
||||
public static function isUuid(string $uuid) : bool {
|
||||
public static function isUuid(string $uuid): bool {
|
||||
try {
|
||||
Uuid::fromString($uuid);
|
||||
} catch (\InvalidArgumentException $e) {
|
||||
@ -39,4 +40,21 @@ class StringHelper {
|
||||
return true;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns a string with whitespace removed from the start and end of the
|
||||
* string. Supports the removal of unicode whitespace.
|
||||
*
|
||||
* Based on the http://markushedlund.com/dev/trim-unicodeutf-8-whitespace-in-php
|
||||
*
|
||||
* @param string $string string to remove whitespaces
|
||||
* @return string trimmed $string
|
||||
*/
|
||||
public static function trim(?string $string): string {
|
||||
if ($string === null) {
|
||||
return '';
|
||||
}
|
||||
|
||||
return preg_replace('/^[\pZ\pC]+|[\pZ\pC]+$/u', '', $string);
|
||||
}
|
||||
|
||||
}
|
||||
|
@ -2,6 +2,7 @@
|
||||
namespace common\validators;
|
||||
|
||||
use common\helpers\Error as E;
|
||||
use common\helpers\StringHelper;
|
||||
use common\models\Account;
|
||||
use Ely\Yii2\TempmailValidator;
|
||||
use yii\base\Model;
|
||||
@ -20,7 +21,7 @@ class EmailValidator 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::EMAIL_REQUIRED;
|
||||
|
@ -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;
|
||||
|
@ -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);
|
||||
}
|
||||
|
||||
}
|
||||
|
@ -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)
|
||||
];
|
||||
}
|
||||
|
||||
}
|
||||
|
@ -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');
|
||||
|
@ -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');
|
||||
|
Loading…
Reference in New Issue
Block a user