diff --git a/app/controllers/api/account.php b/app/controllers/api/account.php index 3e7a42f0f..a65422ea1 100644 --- a/app/controllers/api/account.php +++ b/app/controllers/api/account.php @@ -33,7 +33,6 @@ use Utopia\Validator\ArrayList; use Utopia\Validator\Assoc; use Utopia\Validator\Range; use Utopia\Validator\Text; -use Utopia\Validator\JSON; use Utopia\Validator\WhiteList; $oauthDefaultSuccess = '/v1/auth/oauth2/success'; diff --git a/composer.lock b/composer.lock index 8c2939825..4e32ff04f 100644 --- a/composer.lock +++ b/composer.lock @@ -300,16 +300,16 @@ }, { "name": "colinmollenhour/credis", - "version": "v1.13.0", + "version": "v1.13.1", "source": { "type": "git", "url": "https://github.com/colinmollenhour/credis.git", - "reference": "afec8e58ec93d2291c127fa19709a048f28641e5" + "reference": "85df015088e00daf8ce395189de22c8eb45c8d49" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/colinmollenhour/credis/zipball/afec8e58ec93d2291c127fa19709a048f28641e5", - "reference": "afec8e58ec93d2291c127fa19709a048f28641e5", + "url": "https://api.github.com/repos/colinmollenhour/credis/zipball/85df015088e00daf8ce395189de22c8eb45c8d49", + "reference": "85df015088e00daf8ce395189de22c8eb45c8d49", "shasum": "" }, "require": { @@ -341,9 +341,9 @@ "homepage": "https://github.com/colinmollenhour/credis", "support": { "issues": "https://github.com/colinmollenhour/credis/issues", - "source": "https://github.com/colinmollenhour/credis/tree/v1.13.0" + "source": "https://github.com/colinmollenhour/credis/tree/v1.13.1" }, - "time": "2022-04-07T14:57:22+00:00" + "time": "2022-06-20T22:56:59+00:00" }, { "name": "composer/package-versions-deprecated", @@ -481,22 +481,22 @@ }, { "name": "guzzlehttp/guzzle", - "version": "7.4.4", + "version": "7.4.5", "source": { "type": "git", "url": "https://github.com/guzzle/guzzle.git", - "reference": "e3ff079b22820c2029d4c2a87796b6a0b8716ad8" + "reference": "1dd98b0564cb3f6bd16ce683cb755f94c10fbd82" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/guzzle/guzzle/zipball/e3ff079b22820c2029d4c2a87796b6a0b8716ad8", - "reference": "e3ff079b22820c2029d4c2a87796b6a0b8716ad8", + "url": "https://api.github.com/repos/guzzle/guzzle/zipball/1dd98b0564cb3f6bd16ce683cb755f94c10fbd82", + "reference": "1dd98b0564cb3f6bd16ce683cb755f94c10fbd82", "shasum": "" }, "require": { "ext-json": "*", "guzzlehttp/promises": "^1.5", - "guzzlehttp/psr7": "^1.8.3 || ^2.1", + "guzzlehttp/psr7": "^1.9 || ^2.4", "php": "^7.2.5 || ^8.0", "psr/http-client": "^1.0", "symfony/deprecation-contracts": "^2.2 || ^3.0" @@ -585,7 +585,7 @@ ], "support": { "issues": "https://github.com/guzzle/guzzle/issues", - "source": "https://github.com/guzzle/guzzle/tree/7.4.4" + "source": "https://github.com/guzzle/guzzle/tree/7.4.5" }, "funding": [ { @@ -601,7 +601,7 @@ "type": "tidelift" } ], - "time": "2022-06-09T21:39:15+00:00" + "time": "2022-06-20T22:16:13+00:00" }, { "name": "guzzlehttp/promises", @@ -689,16 +689,16 @@ }, { "name": "guzzlehttp/psr7", - "version": "2.3.0", + "version": "2.4.0", "source": { "type": "git", "url": "https://github.com/guzzle/psr7.git", - "reference": "83260bb50b8fc753c72d14dc1621a2dac31877ee" + "reference": "13388f00956b1503577598873fffb5ae994b5737" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/guzzle/psr7/zipball/83260bb50b8fc753c72d14dc1621a2dac31877ee", - "reference": "83260bb50b8fc753c72d14dc1621a2dac31877ee", + "url": "https://api.github.com/repos/guzzle/psr7/zipball/13388f00956b1503577598873fffb5ae994b5737", + "reference": "13388f00956b1503577598873fffb5ae994b5737", "shasum": "" }, "require": { @@ -722,7 +722,7 @@ "type": "library", "extra": { "branch-alias": { - "dev-master": "2.3-dev" + "dev-master": "2.4-dev" } }, "autoload": { @@ -784,7 +784,7 @@ ], "support": { "issues": "https://github.com/guzzle/psr7/issues", - "source": "https://github.com/guzzle/psr7/tree/2.3.0" + "source": "https://github.com/guzzle/psr7/tree/2.4.0" }, "funding": [ { @@ -800,7 +800,7 @@ "type": "tidelift" } ], - "time": "2022-06-09T08:26:02+00:00" + "time": "2022-06-20T21:43:11+00:00" }, { "name": "influxdb/influxdb-php", diff --git a/src/Appwrite/Auth/Auth.php b/src/Appwrite/Auth/Auth.php index 14c6ab6bd..eb6775582 100644 --- a/src/Appwrite/Auth/Auth.php +++ b/src/Appwrite/Auth/Auth.php @@ -153,11 +153,11 @@ class Auth * * @param string $string * @param string $algo hashing algorithm to use - * @param string $options algo-specific options + * @param array $options algo-specific options * * @return bool|string|null */ - public static function passwordHash(string $string, string $algo, mixed $options = []) + public static function passwordHash(string $string, string $algo, array $options = []) { // Plain text not supported, just an alias. Switch to recommended algo if ($algo === 'plaintext') { @@ -209,11 +209,11 @@ class Auth * @param string $plain * @param string $hash * @param string $algo hashing algorithm used to hash - * @param string $options algo-specific options + * @param array $options algo-specific options * * @return bool */ - public static function passwordVerify(string $plain, string $hash, string $algo, mixed $options = []) + public static function passwordVerify(string $plain, string $hash, string $algo, array $options = []) { // Plain text not supported, just an alias. Switch to recommended algo if ($algo === 'plaintext') { diff --git a/src/Appwrite/Auth/Hash.php b/src/Appwrite/Auth/Hash.php index bf2ab0480..713405758 100644 --- a/src/Appwrite/Auth/Hash.php +++ b/src/Appwrite/Auth/Hash.php @@ -5,14 +5,14 @@ namespace Appwrite\Auth; abstract class Hash { /** - * @var mixed $options Hashing-algo specific options + * @var array $options Hashing-algo specific options */ - protected mixed $options = []; + protected array $options = []; /** - * @param mixed $options Hashing-algo specific options + * @param array $options Hashing-algo specific options */ - public function __construct(mixed $options = []) + public function __construct(array $options = []) { $this->setOptions($options); } @@ -20,9 +20,9 @@ abstract class Hash /** * Set hashing algo options * - * @param mixed $options Hashing-algo specific options + * @param array $options Hashing-algo specific options */ - public function setOptions(mixed $options): self + public function setOptions(array $options): self { $this->options = \array_merge([], $this->getDefaultOptions(), $options); return $this; @@ -31,9 +31,9 @@ abstract class Hash /** * Get hashing algo options * - * @return mixed $options Hashing-algo specific options + * @return array $options Hashing-algo specific options */ - public function getOptions(): mixed + public function getOptions(): array { return $this->options; } @@ -56,7 +56,7 @@ abstract class Hash /** * Get default options for specific hashing algo * - * @return mixed options named array + * @return array options named array */ - abstract public function getDefaultOptions(): mixed; + abstract public function getDefaultOptions(): array; } diff --git a/src/Appwrite/Auth/Hash/Argon2.php b/src/Appwrite/Auth/Hash/Argon2.php index 12e7f0d85..c723b077b 100644 --- a/src/Appwrite/Auth/Hash/Argon2.php +++ b/src/Appwrite/Auth/Hash/Argon2.php @@ -10,7 +10,7 @@ use Appwrite\Auth\Hash; * int time_cost * int memory_cost * - * Refference: https://www.php.net/manual/en/function.password-hash.php#example-983 + * Reference: https://www.php.net/manual/en/function.password-hash.php#example-983 */ class Argon2 extends Hash { @@ -38,9 +38,9 @@ class Argon2 extends Hash /** * Get default options for specific hashing algo * - * @return mixed options named array + * @return array options named array */ - public function getDefaultOptions(): mixed + public function getDefaultOptions(): array { return ['memory_cost' => 65536, 'time_cost' => 4, 'threads' => 3]; } diff --git a/src/Appwrite/Auth/Hash/Bcrypt.php b/src/Appwrite/Auth/Hash/Bcrypt.php index 27928e5cf..8b6177f33 100644 --- a/src/Appwrite/Auth/Hash/Bcrypt.php +++ b/src/Appwrite/Auth/Hash/Bcrypt.php @@ -9,7 +9,7 @@ use Appwrite\Auth\Hash; * int cost * string? salt; auto-generated if empty * - * Refference: https://www.php.net/manual/en/password.constants.php + * Reference: https://www.php.net/manual/en/password.constants.php */ class Bcrypt extends Hash { @@ -37,9 +37,9 @@ class Bcrypt extends Hash /** * Get default options for specific hashing algo * - * @return mixed options named array + * @return array options named array */ - public function getDefaultOptions(): mixed + public function getDefaultOptions(): array { return [ 'cost' => 8 ]; } diff --git a/src/Appwrite/Auth/Hash/Md5.php b/src/Appwrite/Auth/Hash/Md5.php index 366de5e96..8ade3dd5e 100644 --- a/src/Appwrite/Auth/Hash/Md5.php +++ b/src/Appwrite/Auth/Hash/Md5.php @@ -7,7 +7,7 @@ use Appwrite\Auth\Hash; /* * MD5 does not accept any options. * - * Refference: https://www.php.net/manual/en/function.md5.php + * Reference: https://www.php.net/manual/en/function.md5.php */ class Md5 extends Hash { @@ -35,9 +35,9 @@ class Md5 extends Hash /** * Get default options for specific hashing algo * - * @return mixed options named array + * @return array options named array */ - public function getDefaultOptions(): mixed + public function getDefaultOptions(): array { return []; } diff --git a/src/Appwrite/Auth/Hash/Phpass.php b/src/Appwrite/Auth/Hash/Phpass.php index 4ffb9db82..187e4a27a 100644 --- a/src/Appwrite/Auth/Hash/Phpass.php +++ b/src/Appwrite/Auth/Hash/Phpass.php @@ -31,7 +31,7 @@ use Appwrite\Auth\Hash; * string portable_hashes * string random_state; The cached random state * - * Refference: https://github.com/photodude/phpass + * Reference: https://github.com/photodude/phpass */ class Phpass extends Hash { @@ -41,14 +41,14 @@ class Phpass extends Hash * @var string * @since 0.1.0 */ - protected $itoa64 = './0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz'; + protected string $itoa64 = './0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz'; /** * Get default options for specific hashing algo * - * @return mixed options named array + * @return array options named array */ - public function getDefaultOptions(): mixed + public function getDefaultOptions(): array { $randomState = \microtime(); if (\function_exists('getmypid')) { @@ -99,9 +99,9 @@ class Phpass extends Hash */ public function verify(string $password, string $hash): bool { - $hash = $this->cryptPrivate($password, $hash); - if ($hash[0] === '*') { - $hash = crypt($password, $hash); + $verificationHash = $this->cryptPrivate($password, $hash); + if ($verificationHash[0] === '*') { + $verificationHash = crypt($password, $hash); } /** @@ -110,7 +110,7 @@ class Phpass extends Hash * unpredictable, which they are at least in the non-fallback * cases (that is, when we use /dev/urandom and bcrypt). */ - return $hash === $hash; + return $hash === $verificationHash; } /** @@ -120,7 +120,7 @@ class Phpass extends Hash * @since 0.1.0 * @throws Exception Thows an Exception if the $count parameter is not a positive integer. */ - protected function getRandomBytes($count, $options) + protected function getRandomBytes(int $count, array $options): string { if (!is_int($count) || $count < 1) { throw new \Exception('Argument count must be a positive integer'); diff --git a/src/Appwrite/Auth/Hash/Scrypt.php b/src/Appwrite/Auth/Hash/Scrypt.php index e144d92ad..bd6df8ae3 100644 --- a/src/Appwrite/Auth/Hash/Scrypt.php +++ b/src/Appwrite/Auth/Hash/Scrypt.php @@ -12,7 +12,7 @@ use Appwrite\Auth\Hash; * int costParallel * int length * - * Refference: https://github.com/DomBlack/php-scrypt/blob/master/scrypt.php#L112-L116 + * Reference: https://github.com/DomBlack/php-scrypt/blob/master/scrypt.php#L112-L116 */ class Scrypt extends Hash { @@ -42,9 +42,9 @@ class Scrypt extends Hash /** * Get default options for specific hashing algo * - * @return mixed options named array + * @return array options named array */ - public function getDefaultOptions(): mixed + public function getDefaultOptions(): array { return [ 'costCpu' => 8, 'costMemory' => 14, 'costParallel' => 1, 'length' => 64 ]; } diff --git a/src/Appwrite/Auth/Hash/Scryptmodified.php b/src/Appwrite/Auth/Hash/Scryptmodified.php index 012084288..f41937332 100644 --- a/src/Appwrite/Auth/Hash/Scryptmodified.php +++ b/src/Appwrite/Auth/Hash/Scryptmodified.php @@ -11,7 +11,7 @@ use Appwrite\Auth\Hash; * string saltSeparator * strin signerKey * - * Refference: https://github.com/DomBlack/php-scrypt/blob/master/scrypt.php#L112-L116 + * Reference: https://github.com/DomBlack/php-scrypt/blob/master/scrypt.php#L112-L116 */ class Scryptmodified extends Hash { @@ -46,9 +46,9 @@ class Scryptmodified extends Hash /** * Get default options for specific hashing algo * - * @return mixed options named array + * @return array options named array */ - public function getDefaultOptions(): mixed + public function getDefaultOptions(): array { return [ ]; } diff --git a/src/Appwrite/Auth/Hash/Sha.php b/src/Appwrite/Auth/Hash/Sha.php index 1c9605773..c2ae3b52c 100644 --- a/src/Appwrite/Auth/Hash/Sha.php +++ b/src/Appwrite/Auth/Hash/Sha.php @@ -11,7 +11,7 @@ use Appwrite\Auth\Hash; * - Version 2: sha224, sha256, sha384, sha512/224, sha512/256, sha512 * - Version 3: sha3-224, sha3-256, sha3-384, sha3-512 * - * Refference: https://www.php.net/manual/en/function.hash-algos.php + * Reference: https://www.php.net/manual/en/function.hash-algos.php */ class Sha extends Hash { @@ -41,9 +41,9 @@ class Sha extends Hash /** * Get default options for specific hashing algo * - * @return mixed options named array + * @return array options named array */ - public function getDefaultOptions(): mixed + public function getDefaultOptions(): array { return [ 'version' => 'sha3-512' ]; } diff --git a/src/Appwrite/Specification/Format/Swagger2.php b/src/Appwrite/Specification/Format/Swagger2.php index 68bf2f575..7baa01703 100644 --- a/src/Appwrite/Specification/Format/Swagger2.php +++ b/src/Appwrite/Specification/Format/Swagger2.php @@ -407,12 +407,12 @@ class Swagger2 extends Format if (\is_array($rule['type'])) { foreach ($rule['type'] as $ruleType) { - if (!in_array($ruleType, ['string', 'integer', 'boolean', 'json', 'float']) ) { + if (!in_array($ruleType, ['string', 'integer', 'boolean', 'json', 'float'])) { $usedModels[] = $ruleType; } } } else { - if (!in_array($rule['type'], ['string', 'integer', 'boolean', 'json', 'float']) ) { + if (!in_array($rule['type'], ['string', 'integer', 'boolean', 'json', 'float'])) { $usedModels[] = $rule['type']; } } diff --git a/tests/unit/Auth/AuthTest.php b/tests/unit/Auth/AuthTest.php index 27e50609a..2f201a59e 100644 --- a/tests/unit/Auth/AuthTest.php +++ b/tests/unit/Auth/AuthTest.php @@ -58,6 +58,7 @@ class AuthTest extends TestCase $generatedHash = Auth::passwordHash($plain, 'bcrypt'); $this->assertEquals(true, Auth::passwordVerify($plain, $generatedHash, 'bcrypt')); $this->assertEquals(true, Auth::passwordVerify($plain, $hash, 'bcrypt')); + $this->assertEquals(false, Auth::passwordVerify('wrongPassword', $hash, 'bcrypt')); // Bcrypt - Version A $plain = 'test123'; @@ -65,6 +66,7 @@ class AuthTest extends TestCase $generatedHash = Auth::passwordHash($plain, 'bcrypt'); $this->assertEquals(true, Auth::passwordVerify($plain, $generatedHash, 'bcrypt')); $this->assertEquals(true, Auth::passwordVerify($plain, $hash, 'bcrypt')); + $this->assertEquals(false, Auth::passwordVerify('wrongPassword', $hash, 'bcrypt')); // Bcrypt - Cost 5 $plain = 'hello-world'; @@ -72,6 +74,7 @@ class AuthTest extends TestCase $generatedHash = Auth::passwordHash($plain, 'bcrypt'); $this->assertEquals(true, Auth::passwordVerify($plain, $generatedHash, 'bcrypt')); $this->assertEquals(true, Auth::passwordVerify($plain, $hash, 'bcrypt')); + $this->assertEquals(false, Auth::passwordVerify('wrongPassword', $hash, 'bcrypt')); // Bcrypt - Cost 15 $plain = 'super-secret-password'; @@ -79,6 +82,7 @@ class AuthTest extends TestCase $generatedHash = Auth::passwordHash($plain, 'bcrypt'); $this->assertEquals(true, Auth::passwordVerify($plain, $generatedHash, 'bcrypt')); $this->assertEquals(true, Auth::passwordVerify($plain, $hash, 'bcrypt')); + $this->assertEquals(false, Auth::passwordVerify('wrongPassword', $hash, 'bcrypt')); // MD5 - Short $plain = 'appwrite'; @@ -86,6 +90,7 @@ class AuthTest extends TestCase $generatedHash = Auth::passwordHash($plain, 'md5'); $this->assertEquals(true, Auth::passwordVerify($plain, $generatedHash, 'md5')); $this->assertEquals(true, Auth::passwordVerify($plain, $hash, 'md5')); + $this->assertEquals(false, Auth::passwordVerify('wrongPassword', $hash, 'md5')); // MD5 - Long $plain = 'AppwriteIsAwesomeBackendAsAServiceThatIsAlsoOpenSourced'; @@ -93,6 +98,7 @@ class AuthTest extends TestCase $generatedHash = Auth::passwordHash($plain, 'md5'); $this->assertEquals(true, Auth::passwordVerify($plain, $generatedHash, 'md5')); $this->assertEquals(true, Auth::passwordVerify($plain, $hash, 'md5')); + $this->assertEquals(false, Auth::passwordVerify('wrongPassword', $hash, 'md5')); // PHPass $plain = 'pass123'; @@ -100,6 +106,7 @@ class AuthTest extends TestCase $generatedHash = Auth::passwordHash($plain, 'phpass'); $this->assertEquals(true, Auth::passwordVerify($plain, $generatedHash, 'phpass')); $this->assertEquals(true, Auth::passwordVerify($plain, $hash, 'phpass')); + $this->assertEquals(false, Auth::passwordVerify('wrongPassword', $hash, 'phpass')); // SHA $plain = 'developersAreAwesome!'; @@ -107,6 +114,7 @@ class AuthTest extends TestCase $generatedHash = Auth::passwordHash($plain, 'sha'); $this->assertEquals(true, Auth::passwordVerify($plain, $generatedHash, 'sha')); $this->assertEquals(true, Auth::passwordVerify($plain, $hash, 'sha')); + $this->assertEquals(false, Auth::passwordVerify('wrongPassword', $hash, 'sha')); // Argon2 $plain = 'safe-argon-password'; @@ -114,6 +122,7 @@ class AuthTest extends TestCase $generatedHash = Auth::passwordHash($plain, 'argon2'); $this->assertEquals(true, Auth::passwordVerify($plain, $generatedHash, 'argon2')); $this->assertEquals(true, Auth::passwordVerify($plain, $hash, 'argon2')); + $this->assertEquals(false, Auth::passwordVerify('wrongPassword', $hash, 'argon2')); // Scrypt $plain = 'some-scrypt-password'; @@ -121,6 +130,8 @@ class AuthTest extends TestCase $generatedHash = Auth::passwordHash($plain, 'scrypt'); $this->assertEquals(true, Auth::passwordVerify($plain, $generatedHash, 'scrypt')); $this->assertEquals(true, Auth::passwordVerify($plain, $hash, 'scrypt', ['length' => 64, 'costCpu' => 16384, 'costMemory' => 12, 'costParallel' => 2])); + $this->assertEquals(false, Auth::passwordVerify($plain, $hash, 'scrypt', ['length' => 64, 'costCpu' => 16384, 'costMemory' => 10, 'costParallel' => 2])); + $this->assertEquals(false, Auth::passwordVerify('wrongPassword', $hash, 'scrypt', ['length' => 64, 'costCpu' => 16384, 'costMemory' => 12, 'costParallel' => 2])); // ScryptModified tested are in provider-specific tests below @@ -134,6 +145,7 @@ class AuthTest extends TestCase $generatedHash = Auth::passwordHash($plain, 'bcrypt'); $this->assertEquals(true, Auth::passwordVerify($plain, $generatedHash, 'bcrypt')); $this->assertEquals(true, Auth::passwordVerify($plain, $hash, 'bcrypt')); + $this->assertEquals(false, Auth::passwordVerify('wrongPassword', $hash, 'bcrypt')); // Provider #2 (Blog) $plain = 'your-password'; @@ -141,6 +153,7 @@ class AuthTest extends TestCase $generatedHash = Auth::passwordHash($plain, 'phpass'); $this->assertEquals(true, Auth::passwordVerify($plain, $generatedHash, 'phpass')); $this->assertEquals(true, Auth::passwordVerify($plain, $hash, 'phpass')); + $this->assertEquals(false, Auth::passwordVerify('wrongPassword', $hash, 'phpass')); // Provider #2 (Google) $plain = 'users-password'; @@ -153,6 +166,7 @@ class AuthTest extends TestCase $generatedHash = Auth::passwordHash($plain, 'scryptMod', $options); $this->assertEquals(true, Auth::passwordVerify($plain, $generatedHash, 'scryptMod', $options)); $this->assertEquals(true, Auth::passwordVerify($plain, $hash, 'scryptMod', $options)); + $this->assertEquals(false, Auth::passwordVerify('wrongPassword', $hash, 'scryptMod', $options)); } public function testUnknownAlgo()