Pint linter ran

This commit is contained in:
wess
2023-08-23 13:12:43 -04:00
parent eba91ae55a
commit bf5f0a8419
382 changed files with 10227 additions and 10339 deletions
+69 -48
View File
@@ -9,8 +9,8 @@ use Appwrite\Auth\Hash\Phpass;
use Appwrite\Auth\Hash\Scrypt;
use Appwrite\Auth\Hash\Scryptmodified;
use Appwrite\Auth\Hash\Sha;
use Utopia\Database\Document;
use Utopia\Database\DateTime;
use Utopia\Database\Document;
use Utopia\Database\Helpers\Role;
use Utopia\Database\Validator\Authorization;
use Utopia\Database\Validator\Roles;
@@ -25,49 +25,69 @@ class Auth
'phpass',
'scrypt',
'scryptMod',
'plaintext'
'plaintext',
];
public const DEFAULT_ALGO = 'argon2';
public const DEFAULT_ALGO_OPTIONS = ['type' => 'argon2', 'memoryCost' => 2048, 'timeCost' => 4, 'threads' => 3];
/**
* User Roles.
*/
public const USER_ROLE_ANY = 'any';
public const USER_ROLE_GUESTS = 'guests';
public const USER_ROLE_USERS = 'users';
public const USER_ROLE_ADMIN = 'admin';
public const USER_ROLE_DEVELOPER = 'developer';
public const USER_ROLE_OWNER = 'owner';
public const USER_ROLE_APPS = 'apps';
public const USER_ROLE_SYSTEM = 'system';
/**
* Token Types.
*/
public const TOKEN_TYPE_LOGIN = 1; // Deprecated
public const TOKEN_TYPE_VERIFICATION = 2;
public const TOKEN_TYPE_RECOVERY = 3;
public const TOKEN_TYPE_INVITE = 4;
public const TOKEN_TYPE_MAGIC_URL = 5;
public const TOKEN_TYPE_PHONE = 6;
/**
* Session Providers.
*/
public const SESSION_PROVIDER_EMAIL = 'email';
public const SESSION_PROVIDER_ANONYMOUS = 'anonymous';
public const SESSION_PROVIDER_MAGIC_URL = 'magic-url';
public const SESSION_PROVIDER_PHONE = 'phone';
/**
* Token Expiration times.
*/
public const TOKEN_EXPIRATION_LOGIN_LONG = 31536000; /* 1 year */
public const TOKEN_EXPIRATION_LOGIN_SHORT = 3600; /* 1 hour */
public const TOKEN_EXPIRATION_RECOVERY = 3600; /* 1 hour */
public const TOKEN_EXPIRATION_CONFIRM = 3600 * 24 * 7; /* 7 days */
public const TOKEN_EXPIRATION_PHONE = 60 * 15; /* 15 minutes */
/**
@@ -93,7 +113,6 @@ class Auth
* Set Cookie Name.
*
* @param $string
*
* @return string
*/
public static function setCookieName($string)
@@ -104,9 +123,8 @@ class Auth
/**
* Encode Session.
*
* @param string $id
* @param string $secret
*
* @param string $id
* @param string $secret
* @return string
*/
public static function encodeSession($id, $secret)
@@ -120,8 +138,7 @@ class Auth
/**
* Decode Session.
*
* @param string $session
*
* @param string $session
* @return array
*
* @throws \Exception
@@ -131,7 +148,7 @@ class Auth
$session = \json_decode(\base64_decode($session), true);
$default = ['id' => null, 'secret' => ''];
if (!\is_array($session)) {
if (! \is_array($session)) {
return $default;
}
@@ -144,7 +161,6 @@ class Auth
* One-way encryption
*
* @param $string
*
* @return string
*/
public static function hash(string $string)
@@ -157,10 +173,9 @@ class Auth
*
* One way string hashing for user passwords
*
* @param string $string
* @param string $algo hashing algorithm to use
* @param array $options algo-specific options
*
* @param string $string
* @param string $algo hashing algorithm to use
* @param array $options algo-specific options
* @return bool|string|null
*/
public static function passwordHash(string $string, string $algo, array $options = [])
@@ -171,45 +186,51 @@ class Auth
$options = Auth::DEFAULT_ALGO_OPTIONS;
}
if (!\in_array($algo, Auth::SUPPORTED_ALGOS)) {
throw new \Exception('Hashing algorithm \'' . $algo . '\' is not supported.');
if (! \in_array($algo, Auth::SUPPORTED_ALGOS)) {
throw new \Exception('Hashing algorithm \''.$algo.'\' is not supported.');
}
switch ($algo) {
case 'argon2':
$hasher = new Argon2($options);
return $hasher->hash($string);
case 'bcrypt':
$hasher = new Bcrypt($options);
return $hasher->hash($string);
case 'md5':
$hasher = new Md5($options);
return $hasher->hash($string);
case 'sha':
$hasher = new Sha($options);
return $hasher->hash($string);
case 'phpass':
$hasher = new Phpass($options);
return $hasher->hash($string);
case 'scrypt':
$hasher = new Scrypt($options);
return $hasher->hash($string);
case 'scryptMod':
$hasher = new Scryptmodified($options);
return $hasher->hash($string);
default:
throw new \Exception('Hashing algorithm \'' . $algo . '\' is not supported.');
throw new \Exception('Hashing algorithm \''.$algo.'\' is not supported.');
}
}
/**
* Password verify.
*
* @param string $plain
* @param string $hash
* @param string $algo hashing algorithm used to hash
* @param array $options algo-specific options
*
* @param string $plain
* @param string $hash
* @param string $algo hashing algorithm used to hash
* @param array $options algo-specific options
* @return bool
*/
public static function passwordVerify(string $plain, string $hash, string $algo, array $options = [])
@@ -220,34 +241,41 @@ class Auth
$options = Auth::DEFAULT_ALGO_OPTIONS;
}
if (!\in_array($algo, Auth::SUPPORTED_ALGOS)) {
throw new \Exception('Hashing algorithm \'' . $algo . '\' is not supported.');
if (! \in_array($algo, Auth::SUPPORTED_ALGOS)) {
throw new \Exception('Hashing algorithm \''.$algo.'\' is not supported.');
}
switch ($algo) {
case 'argon2':
$hasher = new Argon2($options);
return $hasher->verify($plain, $hash);
case 'bcrypt':
$hasher = new Bcrypt($options);
return $hasher->verify($plain, $hash);
case 'md5':
$hasher = new Md5($options);
return $hasher->verify($plain, $hash);
case 'sha':
$hasher = new Sha($options);
return $hasher->verify($plain, $hash);
case 'phpass':
$hasher = new Phpass($options);
return $hasher->verify($plain, $hash);
case 'scrypt':
$hasher = new Scrypt($options);
return $hasher->verify($plain, $hash);
case 'scryptMod':
$hasher = new Scryptmodified($options);
return $hasher->verify($plain, $hash);
default:
throw new \Exception('Hashing algorithm \'' . $algo . '\' is not supported.');
throw new \Exception('Hashing algorithm \''.$algo.'\' is not supported.');
}
}
@@ -256,8 +284,7 @@ class Auth
*
* Generate random password string
*
* @param int $length
*
* @param int $length
* @return string
*/
public static function passwordGenerator(int $length = 20): string
@@ -270,8 +297,7 @@ class Auth
*
* Generate random password string
*
* @param int $length
*
* @param int $length
* @return string
*/
public static function tokenGenerator(int $length = 128): string
@@ -284,8 +310,7 @@ class Auth
*
* Generate random code string
*
* @param int $length
*
* @param int $length
* @return string
*/
public static function codeGenerator(int $length = 6): string
@@ -302,10 +327,9 @@ class Auth
/**
* Verify token and check that its not expired.
*
* @param array $tokens
* @param int $type
* @param string $secret
*
* @param array $tokens
* @param int $type
* @param string $secret
* @return bool|string
*/
public static function tokenVerify(array $tokens, int $type, string $secret)
@@ -320,7 +344,7 @@ class Auth
$token->getAttribute('secret') === self::hash($secret) &&
DateTime::formatTz($token->getAttribute('expire')) >= DateTime::formatTz(DateTime::now())
) {
return (string)$token->getId();
return (string) $token->getId();
}
}
@@ -349,10 +373,9 @@ class Auth
/**
* Verify session and check that its not expired.
*
* @param array $sessions
* @param string $secret
* @param string $expires
*
* @param array $sessions
* @param string $secret
* @param string $expires
* @return bool|string
*/
public static function sessionVerify(array $sessions, string $secret, int $expires)
@@ -375,8 +398,7 @@ class Auth
/**
* Is Privileged User?
*
* @param array $roles
*
* @param array $roles
* @return bool
*/
public static function isPrivilegedUser(array $roles): bool
@@ -395,8 +417,7 @@ class Auth
/**
* Is App User?
*
* @param array $roles
*
* @param array $roles
* @return bool
*/
public static function isAppUser(array $roles): bool
@@ -411,14 +432,14 @@ class Auth
/**
* Returns all roles for a user.
*
* @param Document $user
* @param Document $user
* @return array
*/
public static function getRoles(Document $user): array
{
$roles = [];
if (!self::isPrivilegedUser(Authorization::getRoles()) && !self::isAppUser(Authorization::getRoles())) {
if (! self::isPrivilegedUser(Authorization::getRoles()) && ! self::isAppUser(Authorization::getRoles())) {
if ($user->getId()) {
$roles[] = Role::user($user->getId())->toString();
$roles[] = Role::users()->toString();
@@ -439,7 +460,7 @@ class Auth
}
foreach ($user->getAttribute('memberships', []) as $node) {
if (!isset($node['confirm']) || !$node['confirm']) {
if (! isset($node['confirm']) || ! $node['confirm']) {
continue;
}
@@ -456,7 +477,7 @@ class Auth
}
foreach ($user->getAttribute('labels', []) as $label) {
$roles[] = 'label:' . $label;
$roles[] = 'label:'.$label;
}
return $roles;
+12 -13
View File
@@ -5,13 +5,13 @@ namespace Appwrite\Auth;
abstract class Hash
{
/**
* @var array $options Hashing-algo specific options
*/
* @var array Hashing-algo specific options
*/
protected array $options = [];
/**
* @param array $options Hashing-algo specific options
*/
* @param array $options Hashing-algo specific options
*/
public function __construct(array $options = [])
{
$this->setOptions($options);
@@ -20,11 +20,12 @@ abstract class Hash
/**
* Set hashing algo options
*
* @param array $options Hashing-algo specific options
*/
* @param array $options Hashing-algo specific options
*/
public function setOptions(array $options): self
{
$this->options = \array_merge([], $this->getDefaultOptions(), $options);
return $this;
}
@@ -32,24 +33,22 @@ abstract class Hash
* Get hashing algo options
*
* @return array $options Hashing-algo specific options
*/
*/
public function getOptions(): array
{
return $this->options;
}
/**
* @param string $password Input password to hash
*
* @param string $password Input password to hash
* @return string hash
*/
abstract public function hash(string $password): string;
/**
* @param string $password Input password to validate
* @param string $hash Hash to verify password against
*
* @return boolean true if password matches hash
* @param string $password Input password to validate
* @param string $hash Hash to verify password against
* @return bool true if password matches hash
*/
abstract public function verify(string $password, string $hash): bool;
+4 -6
View File
@@ -15,8 +15,7 @@ use Appwrite\Auth\Hash;
class Argon2 extends Hash
{
/**
* @param string $password Input password to hash
*
* @param string $password Input password to hash
* @return string hash
*/
public function hash(string $password): string
@@ -25,10 +24,9 @@ class Argon2 extends Hash
}
/**
* @param string $password Input password to validate
* @param string $hash Hash to verify password against
*
* @return boolean true if password matches hash
* @param string $password Input password to validate
* @param string $hash Hash to verify password against
* @return bool true if password matches hash
*/
public function verify(string $password, string $hash): bool
{
+5 -7
View File
@@ -14,8 +14,7 @@ use Appwrite\Auth\Hash;
class Bcrypt extends Hash
{
/**
* @param string $password Input password to hash
*
* @param string $password Input password to hash
* @return string hash
*/
public function hash(string $password): string
@@ -24,10 +23,9 @@ class Bcrypt extends Hash
}
/**
* @param string $password Input password to validate
* @param string $hash Hash to verify password against
*
* @return boolean true if password matches hash
* @param string $password Input password to validate
* @param string $hash Hash to verify password against
* @return bool true if password matches hash
*/
public function verify(string $password, string $hash): bool
{
@@ -41,6 +39,6 @@ class Bcrypt extends Hash
*/
public function getDefaultOptions(): array
{
return [ 'cost' => 8 ];
return ['cost' => 8];
}
}
+4 -6
View File
@@ -12,8 +12,7 @@ use Appwrite\Auth\Hash;
class Md5 extends Hash
{
/**
* @param string $password Input password to hash
*
* @param string $password Input password to hash
* @return string hash
*/
public function hash(string $password): string
@@ -22,10 +21,9 @@ class Md5 extends Hash
}
/**
* @param string $password Input password to validate
* @param string $hash Hash to verify password against
*
* @return boolean true if password matches hash
* @param string $password Input password to validate
* @param string $hash Hash to verify password against
* @return bool true if password matches hash
*/
public function verify(string $password, string $hash): bool
{
+31 -30
View File
@@ -39,6 +39,7 @@ class Phpass extends Hash
* Alphabet used in itoa64 conversions.
*
* @var string
*
* @since 0.1.0
*/
protected string $itoa64 = './0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz';
@@ -59,8 +60,7 @@ class Phpass extends Hash
}
/**
* @param string $password Input password to hash
*
* @param string $password Input password to hash
* @return string hash
*/
public function hash(string $password): string
@@ -68,7 +68,7 @@ class Phpass extends Hash
$options = $this->getDefaultOptions();
$random = '';
if (CRYPT_BLOWFISH === 1 && !$options['portable_hashes']) {
if (CRYPT_BLOWFISH === 1 && ! $options['portable_hashes']) {
$random = $this->getRandomBytes(16, $options);
$hash = crypt($password, $this->gensaltBlowfish($random, $options));
if (strlen($hash) === 60) {
@@ -92,10 +92,9 @@ class Phpass extends Hash
}
/**
* @param string $password Input password to validate
* @param string $hash Hash to verify password against
*
* @return boolean true if password matches hash
* @param string $password Input password to validate
* @param string $hash Hash to verify password against
* @return bool true if password matches hash
*/
public function verify(string $password, string $hash): bool
{
@@ -114,15 +113,16 @@ class Phpass extends Hash
}
/**
* @param int $count
* @param int $count
* @return string $output
*
* @return String $output
* @since 0.1.0
*
* @throws Exception Thows an Exception if the $count parameter is not a positive integer.
*/
protected function getRandomBytes(int $count, array $options): string
{
if (!is_int($count) || $count < 1) {
if (! is_int($count) || $count < 1) {
throw new \Exception('Argument count must be a positive integer');
}
$output = '';
@@ -135,7 +135,7 @@ class Phpass extends Hash
$output = '';
for ($i = 0; $i < $count; $i += 16) {
$options['iteration_count_log2'] = md5(microtime() . $options['iteration_count_log2']);
$options['iteration_count_log2'] = md5(microtime().$options['iteration_count_log2']);
$output .= md5($options['iteration_count_log2'], true);
}
@@ -146,47 +146,48 @@ class Phpass extends Hash
}
/**
* @param String $input
* @param int $count
* @param string $input
* @param int $count
* @return string $output
*
* @return String $output
* @since 0.1.0
*
* @throws Exception Thows an Exception if the $count parameter is not a positive integer.
*/
protected function encode64($input, $count)
{
if (!is_int($count) || $count < 1) {
if (! is_int($count) || $count < 1) {
throw new \Exception('Argument count must be a positive integer');
}
$output = '';
$i = 0;
do {
$value = ord($input[$i++]);
$output .= $this->itoa64[$value & 0x3f];
$output .= $this->itoa64[$value & 0x3F];
if ($i < $count) {
$value |= ord($input[$i]) << 8;
}
$output .= $this->itoa64[($value >> 6) & 0x3f];
$output .= $this->itoa64[($value >> 6) & 0x3F];
if ($i++ >= $count) {
break;
}
if ($i < $count) {
$value |= ord($input[$i]) << 16;
}
$output .= $this->itoa64[($value >> 12) & 0x3f];
$output .= $this->itoa64[($value >> 12) & 0x3F];
if ($i++ >= $count) {
break;
}
$output .= $this->itoa64[($value >> 18) & 0x3f];
$output .= $this->itoa64[($value >> 18) & 0x3F];
} while ($i < $count);
return $output;
}
/**
* @param String $input
* @param string $input
* @return string $output
*
* @return String $output
* @since 0.1.0
*/
private function gensaltPrivate($input, $options)
@@ -199,10 +200,10 @@ class Phpass extends Hash
}
/**
* @param String $password
* @param String $setting
* @param string $password
* @param string $setting
* @return string $output
*
* @return String $output
* @since 0.1.0
*/
private function cryptPrivate($password, $setting)
@@ -233,9 +234,9 @@ class Phpass extends Hash
* consequently in lower iteration counts and hashes that are
* quicker to crack (by non-PHP code).
*/
$hash = md5($salt . $password, true);
$hash = md5($salt.$password, true);
do {
$hash = md5($hash . $password, true);
$hash = md5($hash.$password, true);
} while (--$count);
$output = substr($setting, 0, 12);
$output .= $this->encode64($hash, 16);
@@ -244,9 +245,9 @@ class Phpass extends Hash
}
/**
* @param String $input
* @param string $input
* @return string $output
*
* @return String $output
* @since 0.1.0
*/
private function gensaltBlowfish($input, $options)
@@ -278,11 +279,11 @@ class Phpass extends Hash
$c2 = ord($input[$i++]);
$c1 |= $c2 >> 4;
$output .= $itoa64[$c1];
$c1 = ($c2 & 0x0f) << 2;
$c1 = ($c2 & 0x0F) << 2;
$c2 = ord($input[$i++]);
$c1 |= $c2 >> 6;
$output .= $itoa64[$c1];
$output .= $itoa64[$c2 & 0x3f];
$output .= $itoa64[$c2 & 0x3F];
} while (1);
return $output;
+5 -7
View File
@@ -17,8 +17,7 @@ use Appwrite\Auth\Hash;
class Scrypt extends Hash
{
/**
* @param string $password Input password to hash
*
* @param string $password Input password to hash
* @return string hash
*/
public function hash(string $password): string
@@ -29,10 +28,9 @@ class Scrypt extends Hash
}
/**
* @param string $password Input password to validate
* @param string $hash Hash to verify password against
*
* @return boolean true if password matches hash
* @param string $password Input password to validate
* @param string $hash Hash to verify password against
* @return bool true if password matches hash
*/
public function verify(string $password, string $hash): bool
{
@@ -46,6 +44,6 @@ class Scrypt extends Hash
*/
public function getDefaultOptions(): array
{
return [ 'costCpu' => 8, 'costMemory' => 14, 'costParallel' => 1, 'length' => 64 ];
return ['costCpu' => 8, 'costMemory' => 14, 'costParallel' => 1, 'length' => 64];
}
}
+6 -8
View File
@@ -16,8 +16,7 @@ use Appwrite\Auth\Hash;
class Scryptmodified extends Hash
{
/**
* @param string $password Input password to hash
*
* @param string $password Input password to hash
* @return string hash
*/
public function hash(string $password): string
@@ -33,10 +32,9 @@ class Scryptmodified extends Hash
}
/**
* @param string $password Input password to validate
* @param string $hash Hash to verify password against
*
* @return boolean true if password matches hash
* @param string $password Input password to validate
* @param string $hash Hash to verify password against
* @return bool true if password matches hash
*/
public function verify(string $password, string $hash): bool
{
@@ -50,7 +48,7 @@ class Scryptmodified extends Hash
*/
public function getDefaultOptions(): array
{
return [ ];
return [];
}
private function generateDerivedKey(string $password)
@@ -60,7 +58,7 @@ class Scryptmodified extends Hash
$saltBytes = \base64_decode($options['salt']);
$saltSeparatorBytes = \base64_decode($options['saltSeparator']);
$derivedKey = \scrypt(\utf8_encode($password), $saltBytes . $saltSeparatorBytes, 16384, 8, 1, 64);
$derivedKey = \scrypt(\utf8_encode($password), $saltBytes.$saltSeparatorBytes, 16384, 8, 1, 64);
$derivedKey = \hex2bin($derivedKey);
return $derivedKey;
+5 -7
View File
@@ -16,8 +16,7 @@ use Appwrite\Auth\Hash;
class Sha extends Hash
{
/**
* @param string $password Input password to hash
*
* @param string $password Input password to hash
* @return string hash
*/
public function hash(string $password): string
@@ -28,10 +27,9 @@ class Sha extends Hash
}
/**
* @param string $password Input password to validate
* @param string $hash Hash to verify password against
*
* @return boolean true if password matches hash
* @param string $password Input password to validate
* @param string $hash Hash to verify password against
* @return bool true if password matches hash
*/
public function verify(string $password, string $hash): bool
{
@@ -45,6 +43,6 @@ class Sha extends Hash
*/
public function getDefaultOptions(): array
{
return [ 'version' => 'sha3-512' ];
return ['version' => 'sha3-512'];
}
}
+22 -34
View File
@@ -34,11 +34,11 @@ abstract class OAuth2
/**
* OAuth2 constructor.
*
* @param string $appId
* @param string $appSecret
* @param string $callback
* @param array $state
* @param array $scopes
* @param string $appId
* @param string $appSecret
* @param string $callback
* @param array $state
* @param array $scopes
*/
public function __construct(string $appId, string $appSecret, string $callback, array $state = [], array $scopes = [])
{
@@ -62,29 +62,25 @@ abstract class OAuth2
abstract public function getLoginURL(): string;
/**
* @param string $code
*
* @param string $code
* @return array
*/
abstract protected function getTokens(string $code): array;
/**
* @param string $refreshToken
*
* @param string $refreshToken
* @return array
*/
abstract public function refreshTokens(string $refreshToken): array;
/**
* @param string $accessToken
*
* @param string $accessToken
* @return string
*/
abstract public function getUserID(string $accessToken): string;
/**
* @param string $accessToken
*
* @param string $accessToken
* @return string
*/
abstract public function getUserEmail(string $accessToken): string;
@@ -92,28 +88,25 @@ abstract class OAuth2
/**
* Check if the OAuth email is verified
*
* @param string $accessToken
*
* @param string $accessToken
* @return bool
*/
abstract public function isEmailVerified(string $accessToken): bool;
/**
* @param string $accessToken
*
* @param string $accessToken
* @return string
*/
abstract public function getUserName(string $accessToken): string;
/**
* @param $scope
*
* @return $this
*/
protected function addScope(string $scope): OAuth2
{
// Add a scope to the scopes array if it isn't already present
if (!\in_array($scope, $this->scopes)) {
if (! \in_array($scope, $this->scopes)) {
$this->scopes[] = $scope;
}
@@ -129,8 +122,7 @@ abstract class OAuth2
}
/**
* @param string $code
*
* @param string $code
* @return string
*/
public function getAccessToken(string $code): string
@@ -141,8 +133,7 @@ abstract class OAuth2
}
/**
* @param string $code
*
* @param string $code
* @return string
*/
public function getRefreshToken(string $code): string
@@ -153,8 +144,7 @@ abstract class OAuth2
}
/**
* @param string $code
*
* @param string $code
* @return string
*/
public function getAccessTokenExpiry(string $code): int
@@ -169,7 +159,6 @@ abstract class OAuth2
// json_decoding
/**
* @param $state
*
* @return array
*/
public function parseState(string $state)
@@ -178,11 +167,10 @@ abstract class OAuth2
}
/**
* @param string $method
* @param string $url
* @param array $headers
* @param string $payload
*
* @param string $method
* @param string $url
* @param array $headers
* @param string $payload
* @return string
*/
protected function request(string $method, string $url = '', array $headers = [], string $payload = ''): string
@@ -194,11 +182,11 @@ abstract class OAuth2
\curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1);
\curl_setopt($ch, CURLOPT_USERAGENT, 'Appwrite OAuth2');
if (!empty($payload)) {
if (! empty($payload)) {
\curl_setopt($ch, CURLOPT_POSTFIELDS, $payload);
}
$headers[] = 'Content-length: ' . \strlen($payload);
$headers[] = 'Content-length: '.\strlen($payload);
\curl_setopt($ch, CURLOPT_HTTPHEADER, $headers);
// Send the request & save response to $response
@@ -212,6 +200,6 @@ abstract class OAuth2
throw new Exception($response, $code);
}
return (string)$response;
return (string) $response;
}
}
+16 -24
View File
@@ -25,7 +25,7 @@ class Amazon extends OAuth2
* @var array
*/
protected array $scopes = [
"profile"
'profile',
];
/**
@@ -37,8 +37,7 @@ class Amazon extends OAuth2
}
/**
* @param string $state
*
* @param string $state
* @return array
*/
public function parseState(string $state)
@@ -46,24 +45,22 @@ class Amazon extends OAuth2
return \json_decode(\html_entity_decode($state), true);
}
/**
* @return string
*/
public function getLoginURL(): string
{
return 'https://www.amazon.com/ap/oa?' . \http_build_query([
return 'https://www.amazon.com/ap/oa?'.\http_build_query([
'response_type' => 'code',
'client_id' => $this->appID,
'scope' => \implode(' ', $this->getScopes()),
'state' => \json_encode($this->state),
'redirect_uri' => $this->callback
'redirect_uri' => $this->callback,
]);
}
/**
* @param string $code
*
* @param string $code
* @return array
*/
protected function getTokens(string $code): array
@@ -79,7 +76,7 @@ class Amazon extends OAuth2
'client_id' => $this->appID,
'client_secret' => $this->appSecret,
'redirect_uri' => $this->callback,
'grant_type' => 'authorization_code'
'grant_type' => 'authorization_code',
])
), true);
}
@@ -88,8 +85,7 @@ class Amazon extends OAuth2
}
/**
* @param string $refreshToken
*
* @param string $refreshToken
* @return array
*/
public function refreshTokens(string $refreshToken): array
@@ -103,7 +99,7 @@ class Amazon extends OAuth2
'client_id' => $this->appID,
'client_secret' => $this->appSecret,
'grant_type' => 'refresh_token',
'refresh_token' => $refreshToken
'refresh_token' => $refreshToken,
])
), true);
@@ -115,8 +111,7 @@ class Amazon extends OAuth2
}
/**
* @param string $accessToken
*
* @param string $accessToken
* @return string
*/
public function getUserID(string $accessToken): string
@@ -127,8 +122,7 @@ class Amazon extends OAuth2
}
/**
* @param string $accessToken
*
* @param string $accessToken
* @return string
*/
public function getUserEmail(string $accessToken): string
@@ -143,20 +137,18 @@ class Amazon extends OAuth2
*
* If present, the email is verified. This was verfied through a manual Amazon sign up process
*
* @param string $accessToken
*
* @param string $accessToken
* @return bool
*/
public function isEmailVerified(string $accessToken): bool
{
$email = $this->getUserEmail($accessToken);
return !empty($email);
return ! empty($email);
}
/**
* @param string $accessToken
*
* @param string $accessToken
* @return string
*/
public function getUserName(string $accessToken): string
@@ -167,16 +159,16 @@ class Amazon extends OAuth2
}
/**
* @param string $accessToken
*
* @param string $accessToken
* @return array
*/
protected function getUser(string $accessToken): array
{
if (empty($this->user)) {
$user = $this->request('GET', 'https://api.amazon.com/user/profile?access_token=' . \urlencode($accessToken));
$user = $this->request('GET', 'https://api.amazon.com/user/profile?access_token='.\urlencode($accessToken));
$this->user = \json_decode($user, true);
}
return $this->user;
}
}
+20 -27
View File
@@ -24,8 +24,8 @@ class Apple extends OAuth2
* @var array
*/
protected array $scopes = [
"name",
"email"
'name',
'email',
];
/**
@@ -46,19 +46,18 @@ class Apple extends OAuth2
*/
public function getLoginURL(): string
{
return 'https://appleid.apple.com/auth/authorize?' . \http_build_query([
return 'https://appleid.apple.com/auth/authorize?'.\http_build_query([
'client_id' => $this->appID,
'redirect_uri' => $this->callback,
'state' => \json_encode($this->state),
'response_type' => 'code',
'response_mode' => 'form_post',
'scope' => \implode(' ', $this->getScopes())
'scope' => \implode(' ', $this->getScopes()),
]);
}
/**
* @param string $code
*
* @param string $code
* @return array
*/
protected function getTokens(string $code): array
@@ -86,8 +85,7 @@ class Apple extends OAuth2
}
/**
* @param string $refreshToken
*
* @param string $refreshToken
* @return array
*/
public function refreshTokens(string $refreshToken): array
@@ -116,8 +114,7 @@ class Apple extends OAuth2
}
/**
* @param string $accessToken
*
* @param string $accessToken
* @return string
*/
public function getUserID(string $accessToken): string
@@ -126,8 +123,7 @@ class Apple extends OAuth2
}
/**
* @param string $accessToken
*
* @param string $accessToken
* @return string
*/
public function getUserEmail(string $accessToken): string
@@ -140,8 +136,7 @@ class Apple extends OAuth2
*
* @link https://developer.apple.com/forums/thread/121411
*
* @param string $accessToken
*
* @param string $accessToken
* @return bool
*/
public function isEmailVerified(string $accessToken): bool
@@ -154,15 +149,14 @@ class Apple extends OAuth2
}
/**
* @param string $accessToken
*
* @param string $accessToken
* @return string
*/
public function getUserName(string $accessToken): string
{
if (
isset($this->claims['email']) &&
!empty($this->claims['email']) &&
! empty($this->claims['email']) &&
isset($this->claims['email_verified']) &&
$this->claims['email_verified'] === 'true'
) {
@@ -183,7 +177,7 @@ class Apple extends OAuth2
$keyfile = (isset($secret['p8'])) ? $secret['p8'] : ''; // Your p8 Key file
$keyID = (isset($secret['keyID'])) ? $secret['keyID'] : ''; // Your Key ID
$teamID = (isset($secret['teamID'])) ? $secret['teamID'] : ''; // Your Team ID (see Developer Portal)
$bundleID = $this->appID; // Your Bundle ID
$bundleID = $this->appID; // Your Bundle ID
$headers = [
'alg' => 'ES256',
@@ -200,22 +194,21 @@ class Apple extends OAuth2
$pkey = \openssl_pkey_get_private($keyfile);
$payload = $this->encode(\json_encode($headers)) . '.' . $this->encode(\json_encode($claims));
$payload = $this->encode(\json_encode($headers)).'.'.$this->encode(\json_encode($claims));
$signature = '';
$success = \openssl_sign($payload, $signature, $pkey, OPENSSL_ALGO_SHA256);
if (!$success) {
if (! $success) {
return '';
}
return $payload . '.' . $this->encode($this->fromDER($signature, 64));
return $payload.'.'.$this->encode($this->fromDER($signature, 64));
}
/**
* @param string $data
*
* @param string $data
* @return string
*/
protected function encode($data): string
@@ -224,7 +217,7 @@ class Apple extends OAuth2
}
/**
* @param string $data
* @param string $data
*/
protected function retrievePositiveInteger(string $data): string
{
@@ -236,8 +229,8 @@ class Apple extends OAuth2
}
/**
* @param string $der
* @param int $partLength
* @param string $der
* @param int $partLength
*/
protected function fromDER(string $der, int $partLength): string
{
@@ -270,6 +263,6 @@ class Apple extends OAuth2
$S = $this->retrievePositiveInteger(\mb_substr($hex, 4, $Sl * 2, '8bit'));
$S = \str_pad($S, $partLength, '0', STR_PAD_LEFT);
return \pack('H*', $R . $S);
return \pack('H*', $R.$S);
}
}
+17 -24
View File
@@ -16,7 +16,7 @@ class Auth0 extends OAuth2
'openid',
'profile',
'email',
'offline_access'
'offline_access',
];
/**
@@ -42,18 +42,17 @@ class Auth0 extends OAuth2
*/
public function getLoginURL(): string
{
return 'https://' . $this->getAuth0Domain() . '/authorize?' . \http_build_query([
return 'https://'.$this->getAuth0Domain().'/authorize?'.\http_build_query([
'client_id' => $this->appID,
'redirect_uri' => $this->callback,
'state' => \json_encode($this->state),
'scope' => \implode(' ', $this->getScopes()),
'response_type' => 'code'
'response_type' => 'code',
]);
}
/**
* @param string $code
*
* @param string $code
* @return array
*/
protected function getTokens(string $code): array
@@ -62,7 +61,7 @@ class Auth0 extends OAuth2
$headers = ['Content-Type: application/x-www-form-urlencoded'];
$this->tokens = \json_decode($this->request(
'POST',
'https://' . $this->getAuth0Domain() . '/oauth/token',
'https://'.$this->getAuth0Domain().'/oauth/token',
$headers,
\http_build_query([
'code' => $code,
@@ -70,7 +69,7 @@ class Auth0 extends OAuth2
'client_secret' => $this->getClientSecret(),
'redirect_uri' => $this->callback,
'scope' => \implode(' ', $this->getScopes()),
'grant_type' => 'authorization_code'
'grant_type' => 'authorization_code',
])
), true);
}
@@ -78,10 +77,8 @@ class Auth0 extends OAuth2
return $this->tokens;
}
/**
* @param string $refreshToken
*
* @param string $refreshToken
* @return array
*/
public function refreshTokens(string $refreshToken): array
@@ -89,13 +86,13 @@ class Auth0 extends OAuth2
$headers = ['Content-Type: application/x-www-form-urlencoded'];
$this->tokens = \json_decode($this->request(
'POST',
'https://' . $this->getAuth0Domain() . '/oauth/token',
'https://'.$this->getAuth0Domain().'/oauth/token',
$headers,
\http_build_query([
'refresh_token' => $refreshToken,
'client_id' => $this->appID,
'client_secret' => $this->getClientSecret(),
'grant_type' => 'refresh_token'
'grant_type' => 'refresh_token',
])
), true);
@@ -107,8 +104,7 @@ class Auth0 extends OAuth2
}
/**
* @param string $accessToken
*
* @param string $accessToken
* @return string
*/
public function getUserID(string $accessToken): string
@@ -119,8 +115,7 @@ class Auth0 extends OAuth2
}
/**
* @param string $accessToken
*
* @param string $accessToken
* @return string
*/
public function getUserEmail(string $accessToken): string
@@ -135,8 +130,7 @@ class Auth0 extends OAuth2
*
* @link https://auth0.com/docs/api/authentication?javascript#user-profile
*
* @param string $accessToken
*
* @param string $accessToken
* @return bool
*/
public function isEmailVerified(string $accessToken): bool
@@ -151,8 +145,7 @@ class Auth0 extends OAuth2
}
/**
* @param string $accessToken
*
* @param string $accessToken
* @return string
*/
public function getUserName(string $accessToken): string
@@ -163,15 +156,14 @@ class Auth0 extends OAuth2
}
/**
* @param string $accessToken
*
* @param string $accessToken
* @return array
*/
protected function getUser(string $accessToken): array
{
if (empty($this->user)) {
$headers = ['Authorization: Bearer ' . \urlencode($accessToken)];
$user = $this->request('GET', 'https://' . $this->getAuth0Domain() . '/userinfo', $headers);
$headers = ['Authorization: Bearer '.\urlencode($accessToken)];
$user = $this->request('GET', 'https://'.$this->getAuth0Domain().'/userinfo', $headers);
$this->user = \json_decode($user, true);
}
@@ -214,6 +206,7 @@ class Auth0 extends OAuth2
} catch (\Throwable $th) {
throw new \Exception('Invalid secret');
}
return $secret;
}
}
+21 -26
View File
@@ -16,7 +16,7 @@ class Authentik extends OAuth2
'openid',
'profile',
'email',
'offline_access'
'offline_access',
];
/**
@@ -42,18 +42,17 @@ class Authentik extends OAuth2
*/
public function getLoginURL(): string
{
return 'https://' . $this->getAuthentikDomain() . '/application/o/authorize?' . \http_build_query([
return 'https://'.$this->getAuthentikDomain().'/application/o/authorize?'.\http_build_query([
'client_id' => $this->appID,
'redirect_uri' => $this->callback,
'state' => \json_encode($this->state),
'scope' => \implode(' ', $this->getScopes()),
'response_type' => 'code'
'response_type' => 'code',
]);
}
/**
* @param string $code
*
* @param string $code
* @return array
*/
protected function getTokens(string $code): array
@@ -62,7 +61,7 @@ class Authentik extends OAuth2
$headers = ['Content-Type: application/x-www-form-urlencoded'];
$this->tokens = \json_decode($this->request(
'POST',
'https://' . $this->getAuthentikDomain() . '/application/o/token/',
'https://'.$this->getAuthentikDomain().'/application/o/token/',
$headers,
\http_build_query([
'code' => $code,
@@ -70,17 +69,16 @@ class Authentik extends OAuth2
'client_secret' => $this->getClientSecret(),
'redirect_uri' => $this->callback,
'scope' => \implode(' ', $this->getScopes()),
'grant_type' => 'authorization_code'
'grant_type' => 'authorization_code',
])
), true);
}
return $this->tokens;
}
/**
* @param string $refreshToken
*
* @param string $refreshToken
* @return array
*/
public function refreshTokens(string $refreshToken): array
@@ -88,13 +86,13 @@ class Authentik extends OAuth2
$headers = ['Content-Type: application/x-www-form-urlencoded'];
$this->tokens = \json_decode($this->request(
'POST',
'https://' . $this->getAuthentikDomain() . '/application/o/token/',
'https://'.$this->getAuthentikDomain().'/application/o/token/',
$headers,
\http_build_query([
'refresh_token' => $refreshToken,
'client_id' => $this->appID,
'client_secret' => $this->getClientSecret(),
'grant_type' => 'refresh_token'
'grant_type' => 'refresh_token',
])
), true);
@@ -106,8 +104,7 @@ class Authentik extends OAuth2
}
/**
* @param string $accessToken
*
* @param string $accessToken
* @return string
*/
public function getUserID(string $accessToken): string
@@ -122,8 +119,7 @@ class Authentik extends OAuth2
}
/**
* @param string $accessToken
*
* @param string $accessToken
* @return string
*/
public function getUserEmail(string $accessToken): string
@@ -140,8 +136,7 @@ class Authentik extends OAuth2
/**
* Check if the User email is verified
*
* @param string $accessToken
*
* @param string $accessToken
* @return bool
*/
public function isEmailVerified(string $accessToken): bool
@@ -156,8 +151,7 @@ class Authentik extends OAuth2
}
/**
* @param string $accessToken
*
* @param string $accessToken
* @return string
*/
public function getUserName(string $accessToken): string
@@ -171,16 +165,15 @@ class Authentik extends OAuth2
return '';
}
/**
* @param string $accessToken
*
/**
* @param string $accessToken
* @return array
*/
protected function getUser(string $accessToken): array
{
if (empty($this->user)) {
$headers = ['Authorization: Bearer ' . \urlencode($accessToken)];
$user = $this->request('GET', 'https://' . $this->getAuthentikDomain() . '/application/o/userinfo/', $headers);
$headers = ['Authorization: Bearer '.\urlencode($accessToken)];
$user = $this->request('GET', 'https://'.$this->getAuthentikDomain().'/application/o/userinfo/', $headers);
$this->user = \json_decode($user, true);
}
@@ -199,7 +192,7 @@ class Authentik extends OAuth2
return $secret['clientSecret'] ?? '';
}
/**
/**
* Extracts the authentik Domain from the JSON stored in appSecret
*
* @return string
@@ -207,6 +200,7 @@ class Authentik extends OAuth2
protected function getAuthentikDomain(): string
{
$secret = $this->getAppSecret();
return $secret['authentikDomain'] ?? '';
}
@@ -222,6 +216,7 @@ class Authentik extends OAuth2
} catch (\Throwable $th) {
throw new \Exception('Invalid secret');
}
return $secret;
}
}
+11 -18
View File
@@ -36,18 +36,17 @@ class Autodesk extends OAuth2
*/
public function getLoginURL(): string
{
return 'https://developer.api.autodesk.com/authentication/v1/authorize?' . \http_build_query([
return 'https://developer.api.autodesk.com/authentication/v1/authorize?'.\http_build_query([
'client_id' => $this->appID,
'scope' => \implode(' ', $this->getScopes()),
'state' => \json_encode($this->state),
'redirect_uri' => $this->callback,
'response_type' => 'code'
'response_type' => 'code',
]);
}
/**
* @param string $code
*
* @param string $code
* @return array
*/
protected function getTokens(string $code): array
@@ -63,7 +62,7 @@ class Autodesk extends OAuth2
'redirect_uri' => $this->callback,
'client_secret' => $this->appSecret,
'code' => $code,
'grant_type' => 'authorization_code'
'grant_type' => 'authorization_code',
])
);
@@ -74,8 +73,7 @@ class Autodesk extends OAuth2
}
/**
* @param string $refreshToken
*
* @param string $refreshToken
* @return array
*/
public function refreshTokens(string $refreshToken): array
@@ -105,8 +103,7 @@ class Autodesk extends OAuth2
}
/**
* @param string $accessToken
*
* @param string $accessToken
* @return string
*/
public function getUserID(string $accessToken): string
@@ -117,8 +114,7 @@ class Autodesk extends OAuth2
}
/**
* @param string $accessToken
*
* @param string $accessToken
* @return string
*/
public function getUserEmail(string $accessToken): string
@@ -133,8 +129,7 @@ class Autodesk extends OAuth2
*
* @link https://docs.github.com/en/rest/users/emails#list-email-addresses-for-the-authenticated-user
*
* @param string $accessToken
*
* @param string $accessToken
* @return bool
*/
public function isEmailVerified(string $accessToken): bool
@@ -149,8 +144,7 @@ class Autodesk extends OAuth2
}
/**
* @param string $accessToken
*
* @param string $accessToken
* @return string
*/
public function getUserName(string $accessToken): string
@@ -161,14 +155,13 @@ class Autodesk extends OAuth2
}
/**
* @param string $accessToken
*
* @param string $accessToken
* @return array
*/
protected function getUser(string $accessToken): array
{
if (empty($this->user)) {
$headers = ['Authorization: Bearer ' . \urlencode($accessToken)];
$headers = ['Authorization: Bearer '.\urlencode($accessToken)];
$user = $this->request('GET', 'https://developer.api.autodesk.com/userprofile/v1/users/@me', $headers);
$this->user = \json_decode($user, true);
}
+13 -19
View File
@@ -37,7 +37,7 @@ class Bitbucket extends OAuth2
*/
public function getLoginURL(): string
{
return 'https://bitbucket.org/site/oauth2/authorize?' . \http_build_query([
return 'https://bitbucket.org/site/oauth2/authorize?'.\http_build_query([
'response_type' => 'code',
'client_id' => $this->appID,
'scope' => \implode(' ', $this->getScopes()),
@@ -46,8 +46,7 @@ class Bitbucket extends OAuth2
}
/**
* @param string $code
*
* @param string $code
* @return array
*/
protected function getTokens(string $code): array
@@ -63,7 +62,7 @@ class Bitbucket extends OAuth2
'code' => $code,
'client_id' => $this->appID,
'client_secret' => $this->appSecret,
'grant_type' => 'authorization_code'
'grant_type' => 'authorization_code',
])
), true);
}
@@ -72,8 +71,7 @@ class Bitbucket extends OAuth2
}
/**
* @param string $refreshToken
*
* @param string $refreshToken
* @return array
*/
public function refreshTokens(string $refreshToken): array
@@ -87,7 +85,7 @@ class Bitbucket extends OAuth2
'client_id' => $this->appID,
'client_secret' => $this->appSecret,
'grant_type' => 'refresh_token',
'refresh_token' => $refreshToken
'refresh_token' => $refreshToken,
])
), true);
@@ -99,8 +97,7 @@ class Bitbucket extends OAuth2
}
/**
* @param string $accessToken
*
* @param string $accessToken
* @return string
*/
public function getUserID(string $accessToken): string
@@ -111,8 +108,7 @@ class Bitbucket extends OAuth2
}
/**
* @param string $accessToken
*
* @param string $accessToken
* @return string
*/
public function getUserEmail(string $accessToken): string
@@ -125,8 +121,7 @@ class Bitbucket extends OAuth2
/**
* Check if the OAuth email is verified
*
* @param string $accessToken
*
* @param string $accessToken
* @return bool
*/
public function isEmailVerified(string $accessToken): bool
@@ -141,8 +136,7 @@ class Bitbucket extends OAuth2
}
/**
* @param string $accessToken
*
* @param string $accessToken
* @return string
*/
public function getUserName(string $accessToken): string
@@ -153,17 +147,16 @@ class Bitbucket extends OAuth2
}
/**
* @param string $accessToken
*
* @param string $accessToken
* @return array
*/
protected function getUser(string $accessToken): array
{
if (empty($this->user)) {
$user = $this->request('GET', 'https://api.bitbucket.org/2.0/user?access_token=' . \urlencode($accessToken));
$user = $this->request('GET', 'https://api.bitbucket.org/2.0/user?access_token='.\urlencode($accessToken));
$this->user = \json_decode($user, true);
$emails = $this->request('GET', 'https://api.bitbucket.org/2.0/user/emails?access_token=' . \urlencode($accessToken));
$emails = $this->request('GET', 'https://api.bitbucket.org/2.0/user/emails?access_token='.\urlencode($accessToken));
$emails = \json_decode($emails, true);
if (isset($emails['values'])) {
foreach ($emails['values'] as $email) {
@@ -175,6 +168,7 @@ class Bitbucket extends OAuth2
}
}
}
return $this->user;
}
}
+25 -32
View File
@@ -47,17 +47,16 @@ class Bitly extends OAuth2
*/
public function getLoginURL(): string
{
return $this->endpoint . 'authorize?' .
return $this->endpoint.'authorize?'.
\http_build_query([
'client_id' => $this->appID,
'redirect_uri' => $this->callback,
'state' => \json_encode($this->state)
'state' => \json_encode($this->state),
]);
}
/**
* @param string $code
*
* @param string $code
* @return array
*/
protected function getTokens(string $code): array
@@ -65,14 +64,14 @@ class Bitly extends OAuth2
if (empty($this->tokens)) {
$response = $this->request(
'POST',
$this->resourceEndpoint . 'oauth/access_token',
["Content-Type: application/x-www-form-urlencoded"],
$this->resourceEndpoint.'oauth/access_token',
['Content-Type: application/x-www-form-urlencoded'],
\http_build_query([
"client_id" => $this->appID,
"client_secret" => $this->appSecret,
"code" => $code,
"redirect_uri" => $this->callback,
"state" => \json_encode($this->state)
'client_id' => $this->appID,
'client_secret' => $this->appSecret,
'code' => $code,
'redirect_uri' => $this->callback,
'state' => \json_encode($this->state),
])
);
@@ -85,21 +84,20 @@ class Bitly extends OAuth2
}
/**
* @param string $refreshToken
*
* @param string $refreshToken
* @return array
*/
public function refreshTokens(string $refreshToken): array
{
$response = $this->request(
'POST',
$this->resourceEndpoint . 'oauth/access_token',
["Content-Type: application/x-www-form-urlencoded"],
$this->resourceEndpoint.'oauth/access_token',
['Content-Type: application/x-www-form-urlencoded'],
\http_build_query([
"client_id" => $this->appID,
"client_secret" => $this->appSecret,
"refresh_token" => $refreshToken,
'grant_type' => 'refresh_token'
'client_id' => $this->appID,
'client_secret' => $this->appSecret,
'refresh_token' => $refreshToken,
'grant_type' => 'refresh_token',
])
);
@@ -115,8 +113,7 @@ class Bitly extends OAuth2
}
/**
* @param string $accessToken
*
* @param string $accessToken
* @return string
*/
public function getUserID(string $accessToken): string
@@ -127,8 +124,7 @@ class Bitly extends OAuth2
}
/**
* @param string $accessToken
*
* @param string $accessToken
* @return string
*/
public function getUserEmail(string $accessToken): string
@@ -151,8 +147,7 @@ class Bitly extends OAuth2
*
* @link https://dev.bitly.com/api-reference#getUser
*
* @param string $accessToken
*
* @param string $accessToken
* @return bool
*/
public function isEmailVerified(string $accessToken): bool
@@ -161,8 +156,7 @@ class Bitly extends OAuth2
}
/**
* @param string $accessToken
*
* @param string $accessToken
* @return string
*/
public function getUserName(string $accessToken): string
@@ -173,19 +167,18 @@ class Bitly extends OAuth2
}
/**
* @param string $accessToken
*
* @param string $accessToken
* @return array
*/
protected function getUser(string $accessToken)
{
$headers = [
'Authorization: Bearer ' . \urlencode($accessToken),
"Accept: application/json"
'Authorization: Bearer '.\urlencode($accessToken),
'Accept: application/json',
];
if (empty($this->user)) {
$this->user = \json_decode($this->request('GET', $this->resourceEndpoint . "v4/user", $headers), true);
$this->user = \json_decode($this->request('GET', $this->resourceEndpoint.'v4/user', $headers), true);
}
return $this->user;
+23 -30
View File
@@ -49,7 +49,7 @@ class Box extends OAuth2
*/
public function getLoginURL(): string
{
$url = $this->endpoint . 'authorize?' .
$url = $this->endpoint.'authorize?'.
\http_build_query([
'response_type' => 'code',
'client_id' => $this->appID,
@@ -62,8 +62,7 @@ class Box extends OAuth2
}
/**
* @param string $code
*
* @param string $code
* @return array
*/
protected function getTokens(string $code): array
@@ -72,15 +71,15 @@ class Box extends OAuth2
$headers = ['Content-Type: application/x-www-form-urlencoded'];
$this->tokens = \json_decode($this->request(
'POST',
$this->endpoint . 'token',
$this->endpoint.'token',
$headers,
\http_build_query([
"client_id" => $this->appID,
"client_secret" => $this->appSecret,
"code" => $code,
"grant_type" => "authorization_code",
"scope" => \implode(',', $this->getScopes()),
"redirect_uri" => $this->callback
'client_id' => $this->appID,
'client_secret' => $this->appSecret,
'code' => $code,
'grant_type' => 'authorization_code',
'scope' => \implode(',', $this->getScopes()),
'redirect_uri' => $this->callback,
])
), true);
}
@@ -89,8 +88,7 @@ class Box extends OAuth2
}
/**
* @param string $refreshToken
*
* @param string $refreshToken
* @return array
*/
public function refreshTokens(string $refreshToken): array
@@ -98,13 +96,13 @@ class Box extends OAuth2
$headers = ['Content-Type: application/x-www-form-urlencoded'];
$this->tokens = \json_decode($this->request(
'POST',
$this->endpoint . 'token',
$this->endpoint.'token',
$headers,
\http_build_query([
"client_id" => $this->appID,
"client_secret" => $this->appSecret,
"refresh_token" => $refreshToken,
"grant_type" => "refresh_token",
'client_id' => $this->appID,
'client_secret' => $this->appSecret,
'refresh_token' => $refreshToken,
'grant_type' => 'refresh_token',
])
), true);
@@ -116,8 +114,7 @@ class Box extends OAuth2
}
/**
* @param string $accessToken
*
* @param string $accessToken
* @return string
*/
public function getUserID(string $accessToken): string
@@ -128,8 +125,7 @@ class Box extends OAuth2
}
/**
* @param string $accessToken
*
* @param string $accessToken
* @return string
*/
public function getUserEmail(string $accessToken): string
@@ -144,20 +140,18 @@ class Box extends OAuth2
*
* If present, the email is verified. This was verfied through a manual Box sign up process
*
* @param string $accessToken
*
* @param string $accessToken
* @return bool
*/
public function isEmailVerified(string $accessToken): bool
{
$email = $this->getUserEmail($accessToken);
return !empty($email);
return ! empty($email);
}
/**
* @param string $accessToken
*
* @param string $accessToken
* @return string
*/
public function getUserName(string $accessToken): string
@@ -168,19 +162,18 @@ class Box extends OAuth2
}
/**
* @param string $accessToken
*
* @param string $accessToken
* @return array
*/
protected function getUser(string $accessToken): array
{
$header = [
'Authorization: Bearer ' . \urlencode($accessToken),
'Authorization: Bearer '.\urlencode($accessToken),
];
if (empty($this->user)) {
$user = $this->request(
'GET',
$this->resourceEndpoint . 'me',
$this->resourceEndpoint.'me',
$header
);
$this->user = \json_decode($user, true);
+20 -30
View File
@@ -24,7 +24,7 @@ class Dailymotion extends OAuth2
*/
protected array $scopes = [
'userinfo',
'email'
'email',
];
/**
@@ -34,7 +34,7 @@ class Dailymotion extends OAuth2
'email',
'id',
'fullname',
'verified'
'verified',
];
/**
@@ -68,21 +68,20 @@ class Dailymotion extends OAuth2
*/
public function getLoginURL(): string
{
$url = $this->authEndpoint . '?' .
$url = $this->authEndpoint.'?'.
\http_build_query([
'response_type' => 'code',
'client_id' => $this->appID,
'state' => \json_encode($this->state),
'redirect_uri' => $this->callback,
'scope' => \implode(' ', $this->getScopes())
'scope' => \implode(' ', $this->getScopes()),
]);
return $url;
}
/**
* @param string $code
*
* @param string $code
* @return array
*/
protected function getTokens(string $code): array
@@ -90,33 +89,31 @@ class Dailymotion extends OAuth2
if (empty($this->tokens)) {
$this->tokens = \json_decode($this->request(
'POST',
$this->endpoint . '/oauth/token',
["Content-Type: application/x-www-form-urlencoded"],
$this->endpoint.'/oauth/token',
['Content-Type: application/x-www-form-urlencoded'],
\http_build_query([
'grant_type' => 'authorization_code',
"client_id" => $this->appID,
"client_secret" => $this->appSecret,
"redirect_uri" => $this->callback,
'client_id' => $this->appID,
'client_secret' => $this->appSecret,
'redirect_uri' => $this->callback,
'code' => $code,
'scope' => \implode(' ', $this->getScopes()),
])
), true);
}
return $this->tokens;
}
/**
* @param string $refreshToken
*
* @param string $refreshToken
* @return array
*/
public function refreshTokens(string $refreshToken): array
{
$this->tokens = \json_decode($this->request(
'POST',
$this->endpoint . '/oauth/token',
$this->endpoint.'/oauth/token',
['Content-Type: application/x-www-form-urlencoded'],
\http_build_query([
'grant_type' => 'refresh_token',
@@ -130,13 +127,11 @@ class Dailymotion extends OAuth2
$this->tokens['refresh_token'] = $refreshToken;
}
return $this->tokens;
}
/**
* @param string $accessToken
*
* @param string $accessToken
* @return string
*/
public function getUserID(string $accessToken): string
@@ -149,8 +144,7 @@ class Dailymotion extends OAuth2
}
/**
* @param string $accessToken
*
* @param string $accessToken
* @return string
*/
public function getUserEmail(string $accessToken): string
@@ -166,8 +160,7 @@ class Dailymotion extends OAuth2
*
* @link https://developers.dailymotion.com/api/#user-fields
*
* @param string $accessToken
*
* @param string $accessToken
* @return bool
*/
public function isEmailVerified(string $accessToken): bool
@@ -178,23 +171,20 @@ class Dailymotion extends OAuth2
}
/**
* @param string $accessToken
*
* @param string $accessToken
* @return string
*/
public function getUserName(string $accessToken): string
{
$user = $this->getUser($accessToken);
$username = $user['fullname'] ?? '';
return $username;
}
/**
* @param string $accessToken
*
* @param string $accessToken
* @return array
*/
protected function getUser(string $accessToken): array
@@ -202,8 +192,8 @@ class Dailymotion extends OAuth2
if (empty($this->user)) {
$user = $this->request(
'GET',
$this->endpoint . '/user/me?fields=' . \implode(',', $this->getFields()),
['Authorization: Bearer ' . \urlencode($accessToken)],
$this->endpoint.'/user/me?fields='.\implode(',', $this->getFields()),
['Authorization: Bearer '.\urlencode($accessToken)],
);
$this->user = \json_decode($user, true);
}
+16 -23
View File
@@ -28,8 +28,8 @@ class Discord extends OAuth2
* @var array
*/
protected array $scopes = [
'identify',
'email'
'identify',
'email',
];
/**
@@ -45,21 +45,20 @@ class Discord extends OAuth2
*/
public function getLoginURL(): string
{
$url = $this->endpoint . '/oauth2/authorize?' .
$url = $this->endpoint.'/oauth2/authorize?'.
\http_build_query([
'response_type' => 'code',
'client_id' => $this->appID,
'state' => \json_encode($this->state),
'scope' => \implode(' ', $this->getScopes()),
'redirect_uri' => $this->callback
'redirect_uri' => $this->callback,
]);
return $url;
}
/**
* @param string $code
*
* @param string $code
* @return array
*/
protected function getTokens(string $code): array
@@ -67,7 +66,7 @@ class Discord extends OAuth2
if (empty($this->tokens)) {
$this->tokens = \json_decode($this->request(
'POST',
$this->endpoint . '/oauth2/token',
$this->endpoint.'/oauth2/token',
['Content-Type: application/x-www-form-urlencoded'],
\http_build_query([
'grant_type' => 'authorization_code',
@@ -75,7 +74,7 @@ class Discord extends OAuth2
'redirect_uri' => $this->callback,
'client_id' => $this->appID,
'client_secret' => $this->appSecret,
'scope' => \implode(' ', $this->getScopes())
'scope' => \implode(' ', $this->getScopes()),
])
), true);
}
@@ -84,15 +83,14 @@ class Discord extends OAuth2
}
/**
* @param string $refreshToken
*
* @param string $refreshToken
* @return array
*/
public function refreshTokens(string $refreshToken): array
{
$this->tokens = \json_decode($this->request(
'POST',
$this->endpoint . '/oauth2/token',
$this->endpoint.'/oauth2/token',
['Content-Type: application/x-www-form-urlencoded'],
\http_build_query([
'grant_type' => 'refresh_token',
@@ -110,8 +108,7 @@ class Discord extends OAuth2
}
/**
* @param string $accessToken
*
* @param string $accessToken
* @return string
*/
public function getUserID(string $accessToken): string
@@ -122,8 +119,7 @@ class Discord extends OAuth2
}
/**
* @param string $accessToken
*
* @param string $accessToken
* @return string
*/
public function getUserEmail(string $accessToken): string
@@ -138,8 +134,7 @@ class Discord extends OAuth2
*
* @link https://discord.com/developers/docs/resources/user
*
* @param string $accessToken
*
* @param string $accessToken
* @return bool
*/
public function isEmailVerified(string $accessToken): bool
@@ -154,8 +149,7 @@ class Discord extends OAuth2
}
/**
* @param string $accessToken
*
* @param string $accessToken
* @return string
*/
public function getUserName(string $accessToken): string
@@ -166,8 +160,7 @@ class Discord extends OAuth2
}
/**
* @param string $accessToken
*
* @param string $accessToken
* @return array
*/
protected function getUser(string $accessToken): array
@@ -175,8 +168,8 @@ class Discord extends OAuth2
if (empty($this->user)) {
$user = $this->request(
'GET',
$this->endpoint . '/users/@me',
['Authorization: Bearer ' . \urlencode($accessToken)]
$this->endpoint.'/users/@me',
['Authorization: Bearer '.\urlencode($accessToken)]
);
$this->user = \json_decode($user, true);
}
+15 -21
View File
@@ -45,21 +45,20 @@ class Disqus extends OAuth2
*/
public function getLoginURL(): string
{
$url = $this->endpoint . 'oauth/2.0/authorize/?' .
$url = $this->endpoint.'oauth/2.0/authorize/?'.
\http_build_query([
'response_type' => 'code',
'client_id' => $this->appID,
'state' => \json_encode($this->state),
'redirect_uri' => $this->callback,
'scope' => \implode(',', $this->getScopes())
'scope' => \implode(',', $this->getScopes()),
]);
return $url;
}
/**
* @param string $code
*
* @param string $code
* @return array
*/
protected function getTokens(string $code): array
@@ -67,7 +66,7 @@ class Disqus extends OAuth2
if (empty($this->tokens)) {
$this->tokens = \json_decode($this->request(
'POST',
$this->endpoint . 'oauth/2.0/access_token/',
$this->endpoint.'oauth/2.0/access_token/',
['Content-Type: application/x-www-form-urlencoded'],
\http_build_query([
'grant_type' => 'authorization_code',
@@ -79,19 +78,19 @@ class Disqus extends OAuth2
])
), true);
}
return $this->tokens;
}
/**
* @param string $refreshToken
*
* @param string $refreshToken
* @return array
*/
public function refreshTokens(string $refreshToken): array
{
$this->tokens = \json_decode($this->request(
'POST',
$this->endpoint . 'oauth/2.0/access_token/?',
$this->endpoint.'oauth/2.0/access_token/?',
['Content-Type: application/x-www-form-urlencoded'],
\http_build_query([
'grant_type' => 'refresh_token',
@@ -104,12 +103,12 @@ class Disqus extends OAuth2
if (empty($this->tokens['refresh_token'])) {
$this->tokens['refresh_token'] = $refreshToken;
}
return $this->tokens;
}
/**
* @param string $token
*
* @param string $token
* @return string
*/
public function getUserID(string $accessToken): string
@@ -122,8 +121,7 @@ class Disqus extends OAuth2
}
/**
* @param string $accessToken
*
* @param string $accessToken
* @return string
*/
public function getUserEmail(string $accessToken): string
@@ -136,13 +134,11 @@ class Disqus extends OAuth2
}
/**
* @param string $accessToken
*
* @param string $accessToken
* @return bool
*/
public function isEmailVerified(string $accessToken): bool
{
// Look out for the change in their enpoint.
// It's in Beta so they may provide a parameter in the future.
// https://disqus.com/api/docs/users/details/
@@ -151,8 +147,7 @@ class Disqus extends OAuth2
}
/**
* @param string $accessToken
*
* @param string $accessToken
* @return string
*/
public function getUserName(string $accessToken): string
@@ -165,8 +160,7 @@ class Disqus extends OAuth2
}
/**
* @param string $accessToken
*
* @param string $accessToken
* @return array
*/
protected function getUser(string $accessToken): array
@@ -174,10 +168,10 @@ class Disqus extends OAuth2
if (empty($this->user)) {
$user = $this->request(
'GET',
$this->endpoint . '3.0/users/details.json?' . \http_build_query([
$this->endpoint.'3.0/users/details.json?'.\http_build_query([
'access_token' => $accessToken,
'api_key' => $this->appID,
'api_secret' => $this->appSecret
'api_secret' => $this->appSecret,
]),
);
$this->user = \json_decode($user, true)['response'];
+12 -19
View File
@@ -38,17 +38,16 @@ class Dropbox extends OAuth2
*/
public function getLoginURL(): string
{
return 'https://www.dropbox.com/oauth2/authorize?' . \http_build_query([
return 'https://www.dropbox.com/oauth2/authorize?'.\http_build_query([
'client_id' => $this->appID,
'redirect_uri' => $this->callback,
'state' => \json_encode($this->state),
'response_type' => 'code'
'response_type' => 'code',
]);
}
/**
* @param string $code
*
* @param string $code
* @return array
*/
protected function getTokens(string $code): array
@@ -64,7 +63,7 @@ class Dropbox extends OAuth2
'client_id' => $this->appID,
'client_secret' => $this->appSecret,
'redirect_uri' => $this->callback,
'grant_type' => 'authorization_code'
'grant_type' => 'authorization_code',
])
), true);
}
@@ -73,8 +72,7 @@ class Dropbox extends OAuth2
}
/**
* @param string $refreshToken
*
* @param string $refreshToken
* @return array
*/
public function refreshTokens(string $refreshToken): array
@@ -88,7 +86,7 @@ class Dropbox extends OAuth2
'refresh_token' => $refreshToken,
'client_id' => $this->appID,
'client_secret' => $this->appSecret,
'grant_type' => 'refresh_token'
'grant_type' => 'refresh_token',
])
), true);
@@ -100,8 +98,7 @@ class Dropbox extends OAuth2
}
/**
* @param string $accessToken
*
* @param string $accessToken
* @return string
*/
public function getUserID(string $accessToken): string
@@ -112,8 +109,7 @@ class Dropbox extends OAuth2
}
/**
* @param string $accessToken
*
* @param string $accessToken
* @return string
*/
public function getUserEmail(string $accessToken): string
@@ -128,8 +124,7 @@ class Dropbox extends OAuth2
*
* @link https://www.dropbox.com/developers/documentation/http/documentation#users-get_current_account
*
* @param string $accessToken
*
* @param string $accessToken
* @return bool
*/
public function isEmailVerified(string $accessToken): bool
@@ -144,8 +139,7 @@ class Dropbox extends OAuth2
}
/**
* @param string $accessToken
*
* @param string $accessToken
* @return string
*/
public function getUserName(string $accessToken): string
@@ -156,14 +150,13 @@ class Dropbox extends OAuth2
}
/**
* @param string $accessToken
*
* @param string $accessToken
* @return array
*/
protected function getUser(string $accessToken): array
{
if (empty($this->user)) {
$headers = ['Authorization: Bearer ' . \urlencode($accessToken)];
$headers = ['Authorization: Bearer '.\urlencode($accessToken)];
$user = $this->request('POST', 'https://api.dropboxapi.com/2/users/get_current_account', $headers);
$this->user = \json_decode($user, true);
}
+13 -20
View File
@@ -30,8 +30,8 @@ class Etsy extends OAuth2
* @var array
*/
protected array $scopes = [
"email_r",
"profile_r",
'email_r',
'profile_r',
];
/**
@@ -64,7 +64,7 @@ class Etsy extends OAuth2
*/
public function getLoginURL(): string
{
return 'https://www.etsy.com/oauth/connect/oauth/authorize?' . \http_build_query([
return 'https://www.etsy.com/oauth/connect/oauth/authorize?'.\http_build_query([
'client_id' => $this->appID,
'redirect_uri' => $this->callback,
'response_type' => 'code',
@@ -76,8 +76,7 @@ class Etsy extends OAuth2
}
/**
* @param string $code
*
* @param string $code
* @return array
*/
protected function getTokens(string $code): array
@@ -87,7 +86,7 @@ class Etsy extends OAuth2
$this->tokens = \json_decode($this->request(
'POST',
$this->endpoint . '/oauth/token',
$this->endpoint.'/oauth/token',
$headers,
\http_build_query([
'grant_type' => 'authorization_code',
@@ -103,8 +102,7 @@ class Etsy extends OAuth2
}
/**
* @param string $refreshToken
*
* @param string $refreshToken
* @return array
*/
public function refreshTokens(string $refreshToken): array
@@ -113,7 +111,7 @@ class Etsy extends OAuth2
$this->tokens = \json_decode($this->request(
'POST',
$this->endpoint . '/oauth/token',
$this->endpoint.'/oauth/token',
$headers,
\http_build_query([
'grant_type' => 'refresh_token',
@@ -131,7 +129,6 @@ class Etsy extends OAuth2
/**
* @param $accessToken
*
* @return string
*/
public function getUserID(string $accessToken): string
@@ -143,7 +140,6 @@ class Etsy extends OAuth2
/**
* @param $accessToken
*
* @return string
*/
public function getUserEmail(string $accessToken): string
@@ -156,20 +152,18 @@ class Etsy extends OAuth2
*
* OAuth is only allowed if account has been verified through Etsy, itself.
*
* @param string $accessToken
*
* @param string $accessToken
* @return bool
*/
public function isEmailVerified(string $accessToken): bool
{
$email = $this->getUserEmail($accessToken);
return !empty($email);
return ! empty($email);
}
/**
* @param $accessToken
*
* @return string
*/
public function getUserName(string $accessToken): string
@@ -178,21 +172,20 @@ class Etsy extends OAuth2
}
/**
* @param string $accessToken
*
* @param string $accessToken
* @return array
*/
protected function getUser(string $accessToken): array
{
if (!empty($this->user)) {
if (! empty($this->user)) {
return $this->user;
}
$headers = ['Authorization: Bearer ' . $accessToken];
$headers = ['Authorization: Bearer '.$accessToken];
$this->user = \json_decode($this->request(
'GET',
'https://api.etsy.com/v3/application/users/' . $this->getUserID($accessToken),
'https://api.etsy.com/v3/application/users/'.$this->getUserID($accessToken),
), true);
return $this->user;
+4 -2
View File
@@ -7,7 +7,9 @@ use Appwrite\Extend\Exception as AppwriteException;
class Exception extends AppwriteException
{
protected string $response = '';
protected string $error = '';
protected string $errorDescription = '';
public function __construct(string $response = '', int $code = 0, \Throwable $previous = null)
@@ -19,11 +21,11 @@ class Exception extends AppwriteException
if (\is_array($decoded['error'])) {
$this->error = $decoded['error']['status'];
$this->errorDescription = $decoded['error']['message'];
$this->message = $this->error . ': ' . $this->errorDescription;
$this->message = $this->error.': '.$this->errorDescription;
} else {
$this->error = $decoded['error'];
$this->errorDescription = $decoded['error_description'];
$this->message = $this->error . ': ' . $this->errorDescription;
$this->message = $this->error.': '.$this->errorDescription;
}
}
$type = match ($code) {
+16 -23
View File
@@ -25,7 +25,7 @@ class Facebook extends OAuth2
* @var array
*/
protected array $scopes = [
'email'
'email',
];
/**
@@ -41,17 +41,16 @@ class Facebook extends OAuth2
*/
public function getLoginURL(): string
{
return 'https://www.facebook.com/' . $this->version . '/dialog/oauth?' . \http_build_query([
return 'https://www.facebook.com/'.$this->version.'/dialog/oauth?'.\http_build_query([
'client_id' => $this->appID,
'redirect_uri' => $this->callback,
'scope' => \implode(' ', $this->getScopes()),
'state' => \json_encode($this->state)
'state' => \json_encode($this->state),
]);
}
/**
* @param string $code
*
* @param string $code
* @return array
*/
protected function getTokens(string $code): array
@@ -59,11 +58,11 @@ class Facebook extends OAuth2
if (empty($this->tokens)) {
$this->tokens = \json_decode($this->request(
'GET',
'https://graph.facebook.com/' . $this->version . '/oauth/access_token?' . \http_build_query([
'https://graph.facebook.com/'.$this->version.'/oauth/access_token?'.\http_build_query([
'client_id' => $this->appID,
'redirect_uri' => $this->callback,
'client_secret' => $this->appSecret,
'code' => $code
'code' => $code,
])
), true);
}
@@ -72,20 +71,19 @@ class Facebook extends OAuth2
}
/**
* @param string $refreshToken
*
* @param string $refreshToken
* @return array
*/
public function refreshTokens(string $refreshToken): array
{
$this->tokens = \json_decode($this->request(
'GET',
'https://graph.facebook.com/' . $this->version . '/oauth/access_token?' . \http_build_query([
'https://graph.facebook.com/'.$this->version.'/oauth/access_token?'.\http_build_query([
'client_id' => $this->appID,
'redirect_uri' => $this->callback,
'client_secret' => $this->appSecret,
'refresh_token' => $refreshToken,
'grant_type' => 'refresh_token'
'grant_type' => 'refresh_token',
])
), true);
@@ -97,8 +95,7 @@ class Facebook extends OAuth2
}
/**
* @param string $accessToken
*
* @param string $accessToken
* @return string
*/
public function getUserID(string $accessToken): string
@@ -109,8 +106,7 @@ class Facebook extends OAuth2
}
/**
* @param string $accessToken
*
* @param string $accessToken
* @return string
*/
public function getUserEmail(string $accessToken): string
@@ -125,20 +121,18 @@ class Facebook extends OAuth2
*
* If present, the email is verified. This was verfied through a manual Facebook sign up process
*
* @param string $accessToken
*
* @param string $accessToken
* @return bool
*/
public function isEmailVerified(string $accessToken): bool
{
$email = $this->getUserEmail($accessToken);
return !empty($email);
return ! empty($email);
}
/**
* @param string $accessToken
*
* @param string $accessToken
* @return string
*/
public function getUserName(string $accessToken): string
@@ -149,14 +143,13 @@ class Facebook extends OAuth2
}
/**
* @param string $accessToken
*
* @param string $accessToken
* @return array
*/
protected function getUser(string $accessToken): array
{
if (empty($this->user)) {
$user = $this->request('GET', 'https://graph.facebook.com/' . $this->version . '/me?fields=email,name&access_token=' . \urlencode($accessToken));
$user = $this->request('GET', 'https://graph.facebook.com/'.$this->version.'/me?fields=email,name&access_token='.\urlencode($accessToken));
$this->user = \json_decode($user, true);
}
+33 -42
View File
@@ -24,7 +24,7 @@ class Firebase extends OAuth2
'https://www.googleapis.com/auth/datastore',
'https://www.googleapis.com/auth/cloud-platform',
'https://www.googleapis.com/auth/identitytoolkit',
'https://www.googleapis.com/auth/userinfo.profile'
'https://www.googleapis.com/auth/userinfo.profile',
];
/**
@@ -40,7 +40,7 @@ class Firebase extends OAuth2
*/
public function getLoginURL(): string
{
return 'https://accounts.google.com/o/oauth2/v2/auth?' . \http_build_query([
return 'https://accounts.google.com/o/oauth2/v2/auth?'.\http_build_query([
'access_type' => 'offline',
'client_id' => $this->appID,
'redirect_uri' => $this->callback,
@@ -52,8 +52,7 @@ class Firebase extends OAuth2
}
/**
* @param string $code
*
* @param string $code
* @return array
*/
protected function getTokens(string $code): array
@@ -68,19 +67,18 @@ class Firebase extends OAuth2
'redirect_uri' => $this->callback,
'client_secret' => $this->appSecret,
'code' => $code,
'grant_type' => 'authorization_code'
'grant_type' => 'authorization_code',
])
);
$this->tokens = \json_decode($response, true);
$this->tokens = \json_decode($response, true);
}
return $this->tokens;
}
/**
* @param string $refreshToken
*
* @param string $refreshToken
* @return array
*/
public function refreshTokens(string $refreshToken): array
@@ -93,7 +91,7 @@ class Firebase extends OAuth2
'client_id' => $this->appID,
'client_secret' => $this->appSecret,
'grant_type' => 'refresh_token',
'refresh_token' => $refreshToken
'refresh_token' => $refreshToken,
])
);
@@ -108,10 +106,8 @@ class Firebase extends OAuth2
return $this->tokens;
}
/**
* @param string $accessToken
*
* @param string $accessToken
* @return string
*/
public function getUserID(string $accessToken): string
@@ -122,8 +118,7 @@ class Firebase extends OAuth2
}
/**
* @param string $accessToken
*
* @param string $accessToken
* @return string
*/
public function getUserEmail(string $accessToken): string
@@ -133,14 +128,12 @@ class Firebase extends OAuth2
return $user['email'] ?? '';
}
/**
* Check if the OAuth email is verified
*
* @link https://docs.github.com/en/rest/users/emails#list-email-addresses-for-the-authenticated-user
*
* @param string $accessToken
*
* @param string $accessToken
* @return bool
*/
public function isEmailVerified(string $accessToken): bool
@@ -155,8 +148,7 @@ class Firebase extends OAuth2
}
/**
* @param string $accessToken
*
* @param string $accessToken
* @return string
*/
public function getUserName(string $accessToken): string
@@ -167,8 +159,7 @@ class Firebase extends OAuth2
}
/**
* @param string $accessToken
*
* @param string $accessToken
* @return array
*/
protected function getUser(string $accessToken)
@@ -176,7 +167,7 @@ class Firebase extends OAuth2
if (empty($this->user)) {
$response = $this->request(
'GET',
'https://www.googleapis.com/oauth2/v1/userinfo?access_token=' . \urlencode($accessToken),
'https://www.googleapis.com/oauth2/v1/userinfo?access_token='.\urlencode($accessToken),
[],
);
@@ -188,7 +179,7 @@ class Firebase extends OAuth2
public function getProjects(string $accessToken): array
{
$projects = $this->request('GET', 'https://firebase.googleapis.com/v1beta1/projects', ['Authorization: Bearer ' . \urlencode($accessToken)]);
$projects = $this->request('GET', 'https://firebase.googleapis.com/v1beta1/projects', ['Authorization: Bearer '.\urlencode($accessToken)]);
$projects = \json_decode($projects, true);
@@ -201,9 +192,9 @@ class Firebase extends OAuth2
public function assignIAMRoles(string $accessToken, string $email, string $projectId)
{
// Get IAM Roles
$iamRoles = $this->request('POST', 'https://cloudresourcemanager.googleapis.com/v1/projects/' . $projectId . ':getIamPolicy', [
'Authorization: Bearer ' . \urlencode($accessToken),
'Content-Type: application/json'
$iamRoles = $this->request('POST', 'https://cloudresourcemanager.googleapis.com/v1/projects/'.$projectId.':getIamPolicy', [
'Authorization: Bearer '.\urlencode($accessToken),
'Content-Type: application/json',
]);
$iamRoles = \json_decode($iamRoles, true);
@@ -211,23 +202,23 @@ class Firebase extends OAuth2
$iamRoles['bindings'][] = [
'role' => 'roles/identitytoolkit.admin',
'members' => [
'serviceAccount:' . $email
]
'serviceAccount:'.$email,
],
];
$iamRoles['bindings'][] = [
'role' => 'roles/firebase.admin',
'members' => [
'serviceAccount:' . $email
]
'serviceAccount:'.$email,
],
];
// Set IAM Roles
$this->request('POST', 'https://cloudresourcemanager.googleapis.com/v1/projects/' . $projectId . ':setIamPolicy', [
'Authorization: Bearer ' . \urlencode($accessToken),
'Content-Type: application/json'
$this->request('POST', 'https://cloudresourcemanager.googleapis.com/v1/projects/'.$projectId.':setIamPolicy', [
'Authorization: Bearer '.\urlencode($accessToken),
'Content-Type: application/json',
], json_encode([
'policy' => $iamRoles
'policy' => $iamRoles,
]));
}
@@ -236,16 +227,16 @@ class Firebase extends OAuth2
// Create Service Account
$response = $this->request(
'POST',
'https://iam.googleapis.com/v1/projects/' . $projectId . '/serviceAccounts',
'https://iam.googleapis.com/v1/projects/'.$projectId.'/serviceAccounts',
[
'Authorization: Bearer ' . \urlencode($accessToken),
'Content-Type: application/json'
'Authorization: Bearer '.\urlencode($accessToken),
'Content-Type: application/json',
],
json_encode([
'accountId' => 'appwrite-migrations',
'serviceAccount' => [
'displayName' => 'Appwrite Migrations'
]
'displayName' => 'Appwrite Migrations',
],
])
);
@@ -256,10 +247,10 @@ class Firebase extends OAuth2
// Create Service Account Key
$responseKey = $this->request(
'POST',
'https://iam.googleapis.com/v1/projects/' . $projectId . '/serviceAccounts/' . $response['email'] . '/keys',
'https://iam.googleapis.com/v1/projects/'.$projectId.'/serviceAccounts/'.$response['email'].'/keys',
[
'Authorization: Bearer ' . \urlencode($accessToken),
'Content-Type: application/json'
'Authorization: Bearer '.\urlencode($accessToken),
'Content-Type: application/json',
]
);
+16 -24
View File
@@ -36,17 +36,16 @@ class Github extends OAuth2
*/
public function getLoginURL(): string
{
return 'https://github.com/login/oauth/authorize?' . \http_build_query([
return 'https://github.com/login/oauth/authorize?'.\http_build_query([
'client_id' => $this->appID,
'redirect_uri' => $this->callback,
'scope' => \implode(' ', $this->getScopes()),
'state' => \json_encode($this->state)
'state' => \json_encode($this->state),
]);
}
/**
* @param string $code
*
* @param string $code
* @return array
*/
protected function getTokens(string $code): array
@@ -60,7 +59,7 @@ class Github extends OAuth2
'client_id' => $this->appID,
'redirect_uri' => $this->callback,
'client_secret' => $this->appSecret,
'code' => $code
'code' => $code,
])
);
@@ -73,8 +72,7 @@ class Github extends OAuth2
}
/**
* @param string $refreshToken
*
* @param string $refreshToken
* @return array
*/
public function refreshTokens(string $refreshToken): array
@@ -87,7 +85,7 @@ class Github extends OAuth2
'client_id' => $this->appID,
'client_secret' => $this->appSecret,
'grant_type' => 'refresh_token',
'refresh_token' => $refreshToken
'refresh_token' => $refreshToken,
])
);
@@ -103,8 +101,7 @@ class Github extends OAuth2
}
/**
* @param string $accessToken
*
* @param string $accessToken
* @return string
*/
public function getUserID(string $accessToken): string
@@ -115,8 +112,7 @@ class Github extends OAuth2
}
/**
* @param string $accessToken
*
* @param string $accessToken
* @return string
*/
public function getUserEmail(string $accessToken): string
@@ -131,8 +127,7 @@ class Github extends OAuth2
*
* @link https://docs.github.com/en/rest/users/emails#list-email-addresses-for-the-authenticated-user
*
* @param string $accessToken
*
* @param string $accessToken
* @return bool
*/
public function isEmailVerified(string $accessToken): bool
@@ -147,8 +142,7 @@ class Github extends OAuth2
}
/**
* @param string $accessToken
*
* @param string $accessToken
* @return string
*/
public function getUserName(string $accessToken): string
@@ -159,8 +153,7 @@ class Github extends OAuth2
}
/**
* @param string $accessToken
*
* @param string $accessToken
* @return string
*/
public function getUserSlug(string $accessToken): string
@@ -171,16 +164,15 @@ class Github extends OAuth2
}
/**
* @param string $accessToken
*
* @param string $accessToken
* @return array
*/
protected function getUser(string $accessToken)
{
if (empty($this->user)) {
$this->user = \json_decode($this->request('GET', 'https://api.github.com/user', ['Authorization: token ' . \urlencode($accessToken)]), true);
$this->user = \json_decode($this->request('GET', 'https://api.github.com/user', ['Authorization: token '.\urlencode($accessToken)]), true);
$emails = $this->request('GET', 'https://api.github.com/user/emails', ['Authorization: token ' . \urlencode($accessToken)]);
$emails = $this->request('GET', 'https://api.github.com/user/emails', ['Authorization: token '.\urlencode($accessToken)]);
$emails = \json_decode($emails, true);
@@ -197,10 +189,10 @@ class Github extends OAuth2
}
}
if (!empty($primaryEmail)) {
if (! empty($primaryEmail)) {
$this->user['email'] = $primaryEmail['email'];
$this->user['verified'] = $primaryEmail['verified'];
} elseif (!empty($verifiedEmail)) {
} elseif (! empty($verifiedEmail)) {
$this->user['email'] = $verifiedEmail['email'];
$this->user['verified'] = $verifiedEmail['verified'];
}
+17 -23
View File
@@ -23,7 +23,7 @@ class Gitlab extends OAuth2
* @var array
*/
protected array $scopes = [
'read_user'
'read_user',
];
/**
@@ -39,18 +39,17 @@ class Gitlab extends OAuth2
*/
public function getLoginURL(): string
{
return $this->getEndpoint() . '/oauth/authorize?' . \http_build_query([
return $this->getEndpoint().'/oauth/authorize?'.\http_build_query([
'client_id' => $this->appID,
'redirect_uri' => $this->callback,
'scope' => \implode(' ', $this->getScopes()),
'state' => \json_encode($this->state),
'response_type' => 'code'
'response_type' => 'code',
]);
}
/**
* @param string $code
*
* @param string $code
* @return array
*/
protected function getTokens(string $code): array
@@ -58,12 +57,12 @@ class Gitlab extends OAuth2
if (empty($this->tokens)) {
$this->tokens = \json_decode($this->request(
'POST',
$this->getEndpoint() . '/oauth/token?' . \http_build_query([
$this->getEndpoint().'/oauth/token?'.\http_build_query([
'code' => $code,
'client_id' => $this->appID,
'client_secret' => $this->getAppSecret()['clientSecret'],
'redirect_uri' => $this->callback,
'grant_type' => 'authorization_code'
'grant_type' => 'authorization_code',
])
), true);
}
@@ -72,19 +71,18 @@ class Gitlab extends OAuth2
}
/**
* @param string $refreshToken
*
* @param string $refreshToken
* @return array
*/
public function refreshTokens(string $refreshToken): array
{
$this->tokens = \json_decode($this->request(
'POST',
$this->getEndpoint() . '/oauth/token?' . \http_build_query([
$this->getEndpoint().'/oauth/token?'.\http_build_query([
'refresh_token' => $refreshToken,
'client_id' => $this->appID,
'client_secret' => $this->getAppSecret()['clientSecret'],
'grant_type' => 'refresh_token'
'grant_type' => 'refresh_token',
])
), true);
@@ -96,8 +94,7 @@ class Gitlab extends OAuth2
}
/**
* @param string $accessToken
*
* @param string $accessToken
* @return string
*/
public function getUserID(string $accessToken): string
@@ -112,8 +109,7 @@ class Gitlab extends OAuth2
}
/**
* @param string $accessToken
*
* @param string $accessToken
* @return string
*/
public function getUserEmail(string $accessToken): string
@@ -128,8 +124,7 @@ class Gitlab extends OAuth2
*
* @link https://docs.gitlab.com/ee/api/users.html#list-current-user-for-normal-users
*
* @param string $accessToken
*
* @param string $accessToken
* @return bool
*/
public function isEmailVerified(string $accessToken): bool
@@ -144,8 +139,7 @@ class Gitlab extends OAuth2
}
/**
* @param string $accessToken
*
* @param string $accessToken
* @return string
*/
public function getUserName(string $accessToken): string
@@ -156,14 +150,13 @@ class Gitlab extends OAuth2
}
/**
* @param string $accessToken
*
* @param string $accessToken
* @return array
*/
protected function getUser(string $accessToken): array
{
if (empty($this->user)) {
$user = $this->request('GET', $this->getEndpoint() . '/api/v4/user?access_token=' . \urlencode($accessToken));
$user = $this->request('GET', $this->getEndpoint().'/api/v4/user?access_token='.\urlencode($accessToken));
$this->user = \json_decode($user, true);
}
@@ -182,10 +175,10 @@ class Gitlab extends OAuth2
} catch (\Throwable $th) {
throw new \Exception('Invalid secret');
}
return $secret;
}
/**
* Extracts the Tenant Id from the JSON stored in appSecret. Defaults to 'common' as a fallback
*
@@ -196,6 +189,7 @@ class Gitlab extends OAuth2
$defaultEndpoint = 'https://gitlab.com';
$secret = $this->getAppSecret();
$endpoint = $secret['endpoint'] ?? $defaultEndpoint;
return empty($endpoint) ? $defaultEndpoint : $endpoint;
}
}
+15 -22
View File
@@ -22,7 +22,7 @@ class Google extends OAuth2
protected array $scopes = [
'https://www.googleapis.com/auth/userinfo.email',
'https://www.googleapis.com/auth/userinfo.profile',
'openid'
'openid',
];
/**
@@ -48,18 +48,17 @@ class Google extends OAuth2
*/
public function getLoginURL(): string
{
return 'https://accounts.google.com/o/oauth2/v2/auth?' . \http_build_query([
return 'https://accounts.google.com/o/oauth2/v2/auth?'.\http_build_query([
'client_id' => $this->appID,
'redirect_uri' => $this->callback,
'scope' => \implode(' ', $this->getScopes()),
'state' => \json_encode($this->state),
'response_type' => 'code'
'response_type' => 'code',
]);
}
/**
* @param string $code
*
* @param string $code
* @return array
*/
protected function getTokens(string $code): array
@@ -67,13 +66,13 @@ class Google extends OAuth2
if (empty($this->tokens)) {
$this->tokens = \json_decode($this->request(
'POST',
'https://oauth2.googleapis.com/token?' . \http_build_query([
'https://oauth2.googleapis.com/token?'.\http_build_query([
'code' => $code,
'client_id' => $this->appID,
'client_secret' => $this->appSecret,
'redirect_uri' => $this->callback,
'scope' => null,
'grant_type' => 'authorization_code'
'grant_type' => 'authorization_code',
])
), true);
}
@@ -82,19 +81,18 @@ class Google extends OAuth2
}
/**
* @param string $refreshToken
*
* @param string $refreshToken
* @return array
*/
public function refreshTokens(string $refreshToken): array
{
$this->tokens = \json_decode($this->request(
'POST',
'https://oauth2.googleapis.com/token?' . \http_build_query([
'https://oauth2.googleapis.com/token?'.\http_build_query([
'refresh_token' => $refreshToken,
'client_id' => $this->appID,
'client_secret' => $this->appSecret,
'grant_type' => 'refresh_token'
'grant_type' => 'refresh_token',
])
), true);
@@ -106,8 +104,7 @@ class Google extends OAuth2
}
/**
* @param string $accessToken
*
* @param string $accessToken
* @return string
*/
public function getUserID(string $accessToken): string
@@ -118,8 +115,7 @@ class Google extends OAuth2
}
/**
* @param string $accessToken
*
* @param string $accessToken
* @return string
*/
public function getUserEmail(string $accessToken): string
@@ -134,8 +130,7 @@ class Google extends OAuth2
*
* @link https://www.oauth.com/oauth2-servers/signing-in-with-google/verifying-the-user-info/
*
* @param string $accessToken
*
* @param string $accessToken
* @return bool
*/
public function isEmailVerified(string $accessToken): bool
@@ -150,8 +145,7 @@ class Google extends OAuth2
}
/**
* @param string $accessToken
*
* @param string $accessToken
* @return string
*/
public function getUserName(string $accessToken): string
@@ -162,14 +156,13 @@ class Google extends OAuth2
}
/**
* @param string $accessToken
*
* @param string $accessToken
* @return array
*/
protected function getUser(string $accessToken): array
{
if (empty($this->user)) {
$user = $this->request('GET', 'https://www.googleapis.com/oauth2/v3/userinfo?access_token=' . \urlencode($accessToken));
$user = $this->request('GET', 'https://www.googleapis.com/oauth2/v3/userinfo?access_token='.\urlencode($accessToken));
$this->user = \json_decode($user, true);
}
+14 -19
View File
@@ -50,7 +50,7 @@ class Linkedin extends OAuth2
*/
public function getLoginURL(): string
{
return 'https://www.linkedin.com/oauth/v2/authorization?' . \http_build_query([
return 'https://www.linkedin.com/oauth/v2/authorization?'.\http_build_query([
'response_type' => 'code',
'client_id' => $this->appID,
'redirect_uri' => $this->callback,
@@ -60,8 +60,7 @@ class Linkedin extends OAuth2
}
/**
* @param string $code
*
* @param string $code
* @return array
*/
protected function getTokens(string $code): array
@@ -80,12 +79,12 @@ class Linkedin extends OAuth2
])
), true);
}
return $this->tokens;
}
/**
* @param string $refreshToken
*
* @param string $refreshToken
* @return array
*/
public function refreshTokens(string $refreshToken): array
@@ -106,12 +105,12 @@ class Linkedin extends OAuth2
if (empty($this->tokens['refresh_token'])) {
$this->tokens['refresh_token'] = $refreshToken;
}
return $this->tokens;
}
/**
* @param string $accessToken
*
* @param string $accessToken
* @return string
*/
public function getUserID(string $accessToken): string
@@ -122,13 +121,12 @@ class Linkedin extends OAuth2
}
/**
* @param string $accessToken
*
* @param string $accessToken
* @return string
*/
public function getUserEmail(string $accessToken): string
{
$email = \json_decode($this->request('GET', 'https://api.linkedin.com/v2/emailAddress?q=members&projection=(elements*(handle~))', ['Authorization: Bearer ' . \urlencode($accessToken)]), true);
$email = \json_decode($this->request('GET', 'https://api.linkedin.com/v2/emailAddress?q=members&projection=(elements*(handle~))', ['Authorization: Bearer '.\urlencode($accessToken)]), true);
return $email['elements'][0]['handle~']['emailAddress'] ?? '';
}
@@ -138,20 +136,18 @@ class Linkedin extends OAuth2
*
* If present, the email is verified. This was verfied through a manual Linkedin sign up process
*
* @param string $accessToken
*
* @param string $accessToken
* @return bool
*/
public function isEmailVerified(string $accessToken): bool
{
$email = $this->getUserEmail($accessToken);
return !empty($email);
return ! empty($email);
}
/**
* @param string $accessToken
*
* @param string $accessToken
* @return string
*/
public function getUserName(string $accessToken): string
@@ -164,21 +160,20 @@ class Linkedin extends OAuth2
}
if (isset($user['localizedLastName'])) {
$name = (empty($name)) ? $user['localizedLastName'] : $name . ' ' . $user['localizedLastName'];
$name = (empty($name)) ? $user['localizedLastName'] : $name.' '.$user['localizedLastName'];
}
return $name;
}
/**
* @param string $accessToken
*
* @param string $accessToken
* @return array
*/
protected function getUser(string $accessToken)
{
if (empty($this->user)) {
$this->user = \json_decode($this->request('GET', 'https://api.linkedin.com/v2/me', ['Authorization: Bearer ' . \urlencode($accessToken)]), true);
$this->user = \json_decode($this->request('GET', 'https://api.linkedin.com/v2/me', ['Authorization: Bearer '.\urlencode($accessToken)]), true);
}
return $this->user;
+17 -23
View File
@@ -25,7 +25,7 @@ class Microsoft extends OAuth2
*/
protected array $scopes = [
'offline_access',
'user.read'
'user.read',
];
/**
@@ -41,19 +41,18 @@ class Microsoft extends OAuth2
*/
public function getLoginURL(): string
{
return 'https://login.microsoftonline.com/' . $this->getTenantID() . '/oauth2/v2.0/authorize?' . \http_build_query([
return 'https://login.microsoftonline.com/'.$this->getTenantID().'/oauth2/v2.0/authorize?'.\http_build_query([
'client_id' => $this->appID,
'redirect_uri' => $this->callback,
'state' => \json_encode($this->state),
'scope' => \implode(' ', $this->getScopes()),
'response_type' => 'code',
'response_mode' => 'query'
'response_mode' => 'query',
]);
}
/**
* @param string $code
*
* @param string $code
* @return array
*/
protected function getTokens(string $code): array
@@ -62,7 +61,7 @@ class Microsoft extends OAuth2
$headers = ['Content-Type: application/x-www-form-urlencoded'];
$this->tokens = \json_decode($this->request(
'POST',
'https://login.microsoftonline.com/' . $this->getTenantID() . '/oauth2/v2.0/token',
'https://login.microsoftonline.com/'.$this->getTenantID().'/oauth2/v2.0/token',
$headers,
\http_build_query([
'code' => $code,
@@ -70,7 +69,7 @@ class Microsoft extends OAuth2
'client_secret' => $this->getClientSecret(),
'redirect_uri' => $this->callback,
'scope' => \implode(' ', $this->getScopes()),
'grant_type' => 'authorization_code'
'grant_type' => 'authorization_code',
])
), true);
}
@@ -79,8 +78,7 @@ class Microsoft extends OAuth2
}
/**
* @param string $refreshToken
*
* @param string $refreshToken
* @return array
*/
public function refreshTokens(string $refreshToken): array
@@ -88,13 +86,13 @@ class Microsoft extends OAuth2
$headers = ['Content-Type: application/x-www-form-urlencoded'];
$this->tokens = \json_decode($this->request(
'POST',
'https://login.microsoftonline.com/' . $this->getTenantID() . '/oauth2/v2.0/token',
'https://login.microsoftonline.com/'.$this->getTenantID().'/oauth2/v2.0/token',
$headers,
\http_build_query([
'refresh_token' => $refreshToken,
'client_id' => $this->appID,
'client_secret' => $this->getClientSecret(),
'grant_type' => 'refresh_token'
'grant_type' => 'refresh_token',
])
), true);
@@ -106,8 +104,7 @@ class Microsoft extends OAuth2
}
/**
* @param string $accessToken
*
* @param string $accessToken
* @return string
*/
public function getUserID(string $accessToken): string
@@ -118,8 +115,7 @@ class Microsoft extends OAuth2
}
/**
* @param string $accessToken
*
* @param string $accessToken
* @return string
*/
public function getUserEmail(string $accessToken): string
@@ -134,20 +130,18 @@ class Microsoft extends OAuth2
*
* If present, the email is verified. This was verfied through a manual Microsoft sign up process
*
* @param string $accessToken
*
* @param string $accessToken
* @return bool
*/
public function isEmailVerified(string $accessToken): bool
{
$email = $this->getUserEmail($accessToken);
return !empty($email);
return ! empty($email);
}
/**
* @param string $accessToken
*
* @param string $accessToken
* @return string
*/
public function getUserName(string $accessToken): string
@@ -158,14 +152,13 @@ class Microsoft extends OAuth2
}
/**
* @param string $accessToken
*
* @param string $accessToken
* @return array
*/
protected function getUser(string $accessToken): array
{
if (empty($this->user)) {
$headers = ['Authorization: Bearer ' . \urlencode($accessToken)];
$headers = ['Authorization: Bearer '.\urlencode($accessToken)];
$user = $this->request('GET', 'https://graph.microsoft.com/v1.0/me', $headers);
$this->user = \json_decode($user, true);
}
@@ -185,6 +178,7 @@ class Microsoft extends OAuth2
} catch (\Throwable $th) {
throw new \Exception('Invalid secret');
}
return $secret;
}
+15 -23
View File
@@ -3,7 +3,6 @@
namespace Appwrite\Auth\OAuth2;
use Appwrite\Auth\OAuth2;
use Utopia\Exception;
class Mock extends OAuth2
{
@@ -16,7 +15,7 @@ class Mock extends OAuth2
* @var array
*/
protected array $scopes = [
'email'
'email',
];
/**
@@ -42,17 +41,16 @@ class Mock extends OAuth2
*/
public function getLoginURL(): string
{
return 'http://localhost/' . $this->version . '/mock/tests/general/oauth2?' . \http_build_query([
return 'http://localhost/'.$this->version.'/mock/tests/general/oauth2?'.\http_build_query([
'client_id' => $this->appID,
'redirect_uri' => $this->callback,
'scope' => \implode(' ', $this->getScopes()),
'state' => \json_encode($this->state)
'state' => \json_encode($this->state),
]);
}
/**
* @param string $code
*
* @param string $code
* @return array
*/
protected function getTokens(string $code): array
@@ -60,12 +58,12 @@ class Mock extends OAuth2
if (empty($this->tokens)) {
$this->tokens = \json_decode($this->request(
'GET',
'http://localhost/' . $this->version . '/mock/tests/general/oauth2/token?' .
'http://localhost/'.$this->version.'/mock/tests/general/oauth2/token?'.
\http_build_query([
'client_id' => $this->appID,
'redirect_uri' => $this->callback,
'client_secret' => $this->appSecret,
'code' => $code
'code' => $code,
])
), true);
}
@@ -74,20 +72,19 @@ class Mock extends OAuth2
}
/**
* @param string $refreshToken
*
* @param string $refreshToken
* @return array
*/
public function refreshTokens(string $refreshToken): array
{
$this->tokens = \json_decode($this->request(
'GET',
'http://localhost/' . $this->version . '/mock/tests/general/oauth2/token?' .
'http://localhost/'.$this->version.'/mock/tests/general/oauth2/token?'.
\http_build_query([
'client_id' => $this->appID,
'client_secret' => $this->appSecret,
'refresh_token' => $refreshToken,
'grant_type' => 'refresh_token'
'grant_type' => 'refresh_token',
])
), true);
@@ -99,8 +96,7 @@ class Mock extends OAuth2
}
/**
* @param string $accessToken
*
* @param string $accessToken
* @return string
*/
public function getUserID(string $accessToken): string
@@ -111,8 +107,7 @@ class Mock extends OAuth2
}
/**
* @param string $accessToken
*
* @param string $accessToken
* @return string
*/
public function getUserEmail(string $accessToken): string
@@ -125,8 +120,7 @@ class Mock extends OAuth2
/**
* Check if the OAuth email is verified
*
* @param string $accessToken
*
* @param string $accessToken
* @return bool
*/
public function isEmailVerified(string $accessToken): bool
@@ -135,8 +129,7 @@ class Mock extends OAuth2
}
/**
* @param string $accessToken
*
* @param string $accessToken
* @return string
*/
public function getUserName(string $accessToken): string
@@ -147,14 +140,13 @@ class Mock extends OAuth2
}
/**
* @param string $accessToken
*
* @param string $accessToken
* @return array
*/
protected function getUser(string $accessToken): array
{
if (empty($this->user)) {
$user = $this->request('GET', 'http://localhost/' . $this->version . '/mock/tests/general/oauth2/user?token=' . \urlencode($accessToken));
$user = $this->request('GET', 'http://localhost/'.$this->version.'/mock/tests/general/oauth2/user?token='.\urlencode($accessToken));
$this->user = \json_decode($user, true);
}
+18 -25
View File
@@ -44,32 +44,31 @@ class Notion extends OAuth2
*/
public function getLoginURL(): string
{
return $this->endpoint . '/oauth/authorize?' . \http_build_query([
return $this->endpoint.'/oauth/authorize?'.\http_build_query([
'client_id' => $this->appID,
'redirect_uri' => $this->callback,
'response_type' => 'code',
'state' => \json_encode($this->state),
'owner' => 'user'
'owner' => 'user',
]);
}
/**
* @param string $code
*
* @param string $code
* @return array
*/
protected function getTokens(string $code): array
{
if (empty($this->tokens)) {
$headers = ['Authorization: Basic ' . \base64_encode($this->appID . ':' . $this->appSecret)];
$headers = ['Authorization: Basic '.\base64_encode($this->appID.':'.$this->appSecret)];
$this->tokens = \json_decode($this->request(
'POST',
$this->endpoint . '/oauth/token',
$this->endpoint.'/oauth/token',
$headers,
\http_build_query([
'grant_type' => 'authorization_code',
'redirect_uri' => $this->callback,
'code' => $code
'code' => $code,
])
), true);
}
@@ -78,16 +77,15 @@ class Notion extends OAuth2
}
/**
* @param string $refreshToken
*
* @param string $refreshToken
* @return array
*/
public function refreshTokens(string $refreshToken): array
{
$headers = ['Authorization: Basic ' . \base64_encode($this->appID . ':' . $this->appSecret)];
$headers = ['Authorization: Basic '.\base64_encode($this->appID.':'.$this->appSecret)];
$this->tokens = \json_decode($this->request(
'POST',
$this->endpoint . '/oauth/token',
$this->endpoint.'/oauth/token',
$headers,
\http_build_query([
'grant_type' => 'refresh_token',
@@ -103,8 +101,7 @@ class Notion extends OAuth2
}
/**
* @param string $accessToken
*
* @param string $accessToken
* @return string
*/
public function getUserID(string $accessToken): string
@@ -115,8 +112,7 @@ class Notion extends OAuth2
}
/**
* @param string $accessToken
*
* @param string $accessToken
* @return string
*/
public function getUserEmail(string $accessToken): string
@@ -131,20 +127,18 @@ class Notion extends OAuth2
*
* If present, the email is verified. This was verfied through a manual Notion sign up process
*
* @param string $accessToken
*
* @param string $accessToken
* @return bool
*/
public function isEmailVerified(string $accessToken): bool
{
$email = $this->getUserEmail($accessToken);
return !empty($email);
return ! empty($email);
}
/**
* @param string $accessToken
*
* @param string $accessToken
* @return string
*/
public function getUserName(string $accessToken): string
@@ -155,19 +149,18 @@ class Notion extends OAuth2
}
/**
* @param string $accessToken
*
* @param string $accessToken
* @return array
*/
protected function getUser(string $accessToken): array
{
$headers = [
'Notion-Version: ' . $this->version,
'Authorization: Bearer ' . \urlencode($accessToken)
'Notion-Version: '.$this->version,
'Authorization: Bearer '.\urlencode($accessToken),
];
if (empty($this->user)) {
$this->user = \json_decode($this->request('GET', $this->endpoint . '/users/me', $headers), true);
$this->user = \json_decode($this->request('GET', $this->endpoint.'/users/me', $headers), true);
}
return $this->user;
+40 -42
View File
@@ -43,7 +43,7 @@ class Oidc extends OAuth2
*/
public function getLoginURL(): string
{
return $this->getAuthorizationEndpoint() . '?' . \http_build_query([
return $this->getAuthorizationEndpoint().'?'.\http_build_query([
'client_id' => $this->appID,
'redirect_uri' => $this->callback,
'state' => \json_encode($this->state),
@@ -53,8 +53,7 @@ class Oidc extends OAuth2
}
/**
* @param string $code
*
* @param string $code
* @return array
*/
protected function getTokens(string $code): array
@@ -71,17 +70,16 @@ class Oidc extends OAuth2
'client_secret' => $this->getClientSecret(),
'redirect_uri' => $this->callback,
'scope' => \implode(' ', $this->getScopes()),
'grant_type' => 'authorization_code'
'grant_type' => 'authorization_code',
])
), true);
}
return $this->tokens;
}
/**
* @param string $refreshToken
*
* @param string $refreshToken
* @return array
*/
public function refreshTokens(string $refreshToken): array
@@ -95,7 +93,7 @@ class Oidc extends OAuth2
'refresh_token' => $refreshToken,
'client_id' => $this->appID,
'client_secret' => $this->getClientSecret(),
'grant_type' => 'refresh_token'
'grant_type' => 'refresh_token',
])
), true);
@@ -107,8 +105,7 @@ class Oidc extends OAuth2
}
/**
* @param string $accessToken
*
* @param string $accessToken
* @return string
*/
public function getUserID(string $accessToken): string
@@ -123,8 +120,7 @@ class Oidc extends OAuth2
}
/**
* @param string $accessToken
*
* @param string $accessToken
* @return string
*/
public function getUserEmail(string $accessToken): string
@@ -141,8 +137,7 @@ class Oidc extends OAuth2
/**
* Check if the User email is verified
*
* @param string $accessToken
*
* @param string $accessToken
* @return bool
*/
public function isEmailVerified(string $accessToken): bool
@@ -153,8 +148,7 @@ class Oidc extends OAuth2
}
/**
* @param string $accessToken
*
* @param string $accessToken
* @return string
*/
public function getUserName(string $accessToken): string
@@ -168,15 +162,14 @@ class Oidc extends OAuth2
return '';
}
/**
* @param string $accessToken
*
/**
* @param string $accessToken
* @return array
*/
protected function getUser(string $accessToken): array
{
if (empty($this->user)) {
$headers = ['Authorization: Bearer ' . \urlencode($accessToken)];
$headers = ['Authorization: Bearer '.\urlencode($accessToken)];
$user = $this->request('GET', $this->getUserinfoEndpoint(), $headers);
$this->user = \json_decode($user, true);
}
@@ -196,7 +189,7 @@ class Oidc extends OAuth2
return $secret['clientSecret'] ?? '';
}
/**
/**
* Extracts the well known endpoint from the JSON stored in appSecret.
*
* @return string
@@ -204,13 +197,14 @@ class Oidc extends OAuth2
protected function getWellKnownEndpoint(): string
{
$secret = $this->getAppSecret();
return $secret['wellKnownEndpoint'] ?? '';
}
/**
* Extracts the authorization endpoint from the JSON stored in appSecret.
*
* If one is not provided, it will be retrieved from the well-known configuration.
* Extracts the authorization endpoint from the JSON stored in appSecret.
*
* If one is not provided, it will be retrieved from the well-known configuration.
*
* @return string
*/
@@ -219,56 +213,59 @@ class Oidc extends OAuth2
$secret = $this->getAppSecret();
$endpoint = $secret['authorizationEndpoint'] ?? '';
if (!empty($endpoint)) {
if (! empty($endpoint)) {
return $endpoint;
}
$wellKnownConfiguration = $this->getWellKnownConfiguration();
return $wellKnownConfiguration['authorization_endpoint'] ?? '';
}
/**
* Extracts the token endpoint from the JSON stored in appSecret.
*
* If one is not provided, it will be retrieved from the well-known configuration.
*
* @return string
*/
* Extracts the token endpoint from the JSON stored in appSecret.
*
* If one is not provided, it will be retrieved from the well-known configuration.
*
* @return string
*/
protected function getTokenEndpoint(): string
{
$secret = $this->getAppSecret();
$endpoint = $secret['tokenEndpoint'] ?? '';
if (!empty($endpoint)) {
if (! empty($endpoint)) {
return $endpoint;
}
$wellKnownConfiguration = $this->getWellKnownConfiguration();
return $wellKnownConfiguration['token_endpoint'] ?? '';
}
/**
* Extracts the userinfo endpoint from the JSON stored in appSecret.
*
* If one is not provided, it will be retrieved from the well-known configuration.
*
* @return string
*/
* Extracts the userinfo endpoint from the JSON stored in appSecret.
*
* If one is not provided, it will be retrieved from the well-known configuration.
*
* @return string
*/
protected function getUserinfoEndpoint(): string
{
$secret = $this->getAppSecret();
$endpoint = $secret['userinfoEndpoint'] ?? '';
if (!empty($endpoint)) {
if (! empty($endpoint)) {
return $endpoint;
}
$wellKnownConfiguration = $this->getWellKnownConfiguration();
return $wellKnownConfiguration['userinfo_endpoint'] ?? '';
}
/**
* Get the well-known configuration using the well known endpoint
*/
/**
* Get the well-known configuration using the well known endpoint
*/
protected function getWellKnownConfiguration(): array
{
if (empty($this->wellKnownConfiguration)) {
@@ -291,6 +288,7 @@ class Oidc extends OAuth2
} catch (\Throwable $th) {
throw new \Exception('Invalid secret');
}
return $secret;
}
}
+17 -24
View File
@@ -16,7 +16,7 @@ class Okta extends OAuth2
'openid',
'profile',
'email',
'offline_access'
'offline_access',
];
/**
@@ -42,18 +42,17 @@ class Okta extends OAuth2
*/
public function getLoginURL(): string
{
return 'https://' . $this->getOktaDomain() . '/oauth2/' . $this->getAuthorizationServerId() . '/v1/authorize?' . \http_build_query([
return 'https://'.$this->getOktaDomain().'/oauth2/'.$this->getAuthorizationServerId().'/v1/authorize?'.\http_build_query([
'client_id' => $this->appID,
'redirect_uri' => $this->callback,
'state' => \json_encode($this->state),
'scope' => \implode(' ', $this->getScopes()),
'response_type' => 'code'
'response_type' => 'code',
]);
}
/**
* @param string $code
*
* @param string $code
* @return array
*/
protected function getTokens(string $code): array
@@ -62,7 +61,7 @@ class Okta extends OAuth2
$headers = ['Content-Type: application/x-www-form-urlencoded'];
$this->tokens = \json_decode($this->request(
'POST',
'https://' . $this->getOktaDomain() . '/oauth2/' . $this->getAuthorizationServerId() . '/v1/token',
'https://'.$this->getOktaDomain().'/oauth2/'.$this->getAuthorizationServerId().'/v1/token',
$headers,
\http_build_query([
'code' => $code,
@@ -70,7 +69,7 @@ class Okta extends OAuth2
'client_secret' => $this->getClientSecret(),
'redirect_uri' => $this->callback,
'scope' => \implode(' ', $this->getScopes()),
'grant_type' => 'authorization_code'
'grant_type' => 'authorization_code',
])
), true);
}
@@ -78,10 +77,8 @@ class Okta extends OAuth2
return $this->tokens;
}
/**
* @param string $refreshToken
*
* @param string $refreshToken
* @return array
*/
public function refreshTokens(string $refreshToken): array
@@ -89,13 +86,13 @@ class Okta extends OAuth2
$headers = ['Content-Type: application/x-www-form-urlencoded'];
$this->tokens = \json_decode($this->request(
'POST',
'https://' . $this->getOktaDomain() . '/oauth2/' . $this->getAuthorizationServerId() . '/v1/token',
'https://'.$this->getOktaDomain().'/oauth2/'.$this->getAuthorizationServerId().'/v1/token',
$headers,
\http_build_query([
'refresh_token' => $refreshToken,
'client_id' => $this->appID,
'client_secret' => $this->getClientSecret(),
'grant_type' => 'refresh_token'
'grant_type' => 'refresh_token',
])
), true);
@@ -107,8 +104,7 @@ class Okta extends OAuth2
}
/**
* @param string $accessToken
*
* @param string $accessToken
* @return string
*/
public function getUserID(string $accessToken): string
@@ -119,8 +115,7 @@ class Okta extends OAuth2
}
/**
* @param string $accessToken
*
* @param string $accessToken
* @return string
*/
public function getUserEmail(string $accessToken): string
@@ -135,8 +130,7 @@ class Okta extends OAuth2
*
* @link https://developer.okta.com/docs/reference/api/oidc/#userinfo
*
* @param string $accessToken
*
* @param string $accessToken
* @return bool
*/
public function isEmailVerified(string $accessToken): bool
@@ -151,8 +145,7 @@ class Okta extends OAuth2
}
/**
* @param string $accessToken
*
* @param string $accessToken
* @return string
*/
public function getUserName(string $accessToken): string
@@ -163,15 +156,14 @@ class Okta extends OAuth2
}
/**
* @param string $accessToken
*
* @param string $accessToken
* @return array
*/
protected function getUser(string $accessToken): array
{
if (empty($this->user)) {
$headers = ['Authorization: Bearer ' . \urlencode($accessToken)];
$user = $this->request('GET', 'https://' . $this->getOktaDomain() . '/oauth2/' . $this->getAuthorizationServerId() . '/v1/userinfo', $headers);
$headers = ['Authorization: Bearer '.\urlencode($accessToken)];
$user = $this->request('GET', 'https://'.$this->getOktaDomain().'/oauth2/'.$this->getAuthorizationServerId().'/v1/userinfo', $headers);
$this->user = \json_decode($user, true);
}
@@ -226,6 +218,7 @@ class Okta extends OAuth2
} catch (\Throwable $th) {
throw new \Exception('Invalid secret');
}
return $secret;
}
}
+17 -24
View File
@@ -46,7 +46,7 @@ class Paypal extends OAuth2
protected array $scopes = [
'openid',
'profile',
'email'
'email',
];
/**
@@ -62,14 +62,14 @@ class Paypal extends OAuth2
*/
public function getLoginURL(): string
{
$url = $this->endpoint[$this->environment] . 'connect/?' .
$url = $this->endpoint[$this->environment].'connect/?'.
\http_build_query([
'flowEntry' => 'static',
'response_type' => 'code',
'client_id' => $this->appID,
'scope' => \implode(' ', $this->getScopes()),
// paypal is not accepting localhost string into return uri
'redirect_uri' => \str_replace("localhost", "127.0.0.1", $this->callback),
'redirect_uri' => \str_replace('localhost', '127.0.0.1', $this->callback),
'state' => \json_encode($this->state),
]);
@@ -77,8 +77,7 @@ class Paypal extends OAuth2
}
/**
* @param string $code
*
* @param string $code
* @return array
*/
protected function getTokens(string $code): array
@@ -86,8 +85,8 @@ class Paypal extends OAuth2
if (empty($this->tokens)) {
$this->tokens = \json_decode($this->request(
'POST',
$this->resourceEndpoint[$this->environment] . 'oauth2/token',
['Authorization: Basic ' . \base64_encode($this->appID . ':' . $this->appSecret)],
$this->resourceEndpoint[$this->environment].'oauth2/token',
['Authorization: Basic '.\base64_encode($this->appID.':'.$this->appSecret)],
\http_build_query([
'code' => $code,
'grant_type' => 'authorization_code',
@@ -99,16 +98,15 @@ class Paypal extends OAuth2
}
/**
* @param string $refreshToken
*
* @param string $refreshToken
* @return array
*/
public function refreshTokens(string $refreshToken): array
{
$this->tokens = \json_decode($this->request(
'POST',
$this->resourceEndpoint[$this->environment] . 'oauth2/token',
['Authorization: Basic ' . \base64_encode($this->appID . ':' . $this->appSecret)],
$this->resourceEndpoint[$this->environment].'oauth2/token',
['Authorization: Basic '.\base64_encode($this->appID.':'.$this->appSecret)],
\http_build_query([
'refresh_token' => $refreshToken,
'grant_type' => 'refresh_token',
@@ -123,8 +121,7 @@ class Paypal extends OAuth2
}
/**
* @param string $accessToken
*
* @param string $accessToken
* @return string
*/
public function getUserID(string $accessToken): string
@@ -135,8 +132,7 @@ class Paypal extends OAuth2
}
/**
* @param string $accessToken
*
* @param string $accessToken
* @return string
*/
public function getUserEmail(string $accessToken): string
@@ -148,7 +144,7 @@ class Paypal extends OAuth2
return $email['primary'] === true;
});
if (!empty($email)) {
if (! empty($email)) {
return $email[0]['value'];
}
}
@@ -161,8 +157,7 @@ class Paypal extends OAuth2
*
* @link https://developer.paypal.com/docs/api/identity/v1/#userinfo_get
*
* @param string $accessToken
*
* @param string $accessToken
* @return bool
*/
public function isEmailVerified(string $accessToken): bool
@@ -177,8 +172,7 @@ class Paypal extends OAuth2
}
/**
* @param string $accessToken
*
* @param string $accessToken
* @return string
*/
public function getUserName(string $accessToken): string
@@ -189,20 +183,19 @@ class Paypal extends OAuth2
}
/**
* @param string $accessToken
*
* @param string $accessToken
* @return array
*/
protected function getUser(string $accessToken): array
{
$header = [
'Content-Type: application/json',
'Authorization: Bearer ' . \urlencode($accessToken),
'Authorization: Bearer '.\urlencode($accessToken),
];
if (empty($this->user)) {
$user = $this->request(
'GET',
$this->resourceEndpoint[$this->environment] . 'identity/oauth2/userinfo?schema=paypalv1.1',
$this->resourceEndpoint[$this->environment].'identity/oauth2/userinfo?schema=paypalv1.1',
$header
);
$this->user = \json_decode($user, true);
@@ -2,8 +2,6 @@
namespace Appwrite\Auth\OAuth2;
use Appwrite\Auth\OAuth2\Paypal;
class PaypalSandbox extends Paypal
{
protected string $environment = 'sandbox';
+17 -24
View File
@@ -51,19 +51,18 @@ class Podio extends OAuth2
*/
public function getLoginURL(): string
{
$url = $this->endpoint . '/authorize?' .
$url = $this->endpoint.'/authorize?'.
\http_build_query([
'client_id' => $this->appID,
'state' => \json_encode($this->state),
'redirect_uri' => $this->callback
'redirect_uri' => $this->callback,
]);
return $url;
}
/**
* @param string $code
*
* @param string $code
* @return array
*/
protected function getTokens(string $code): array
@@ -71,14 +70,14 @@ class Podio extends OAuth2
if (empty($this->tokens)) {
$this->tokens = \json_decode($this->request(
'POST',
$this->apiEndpoint . '/oauth/token',
$this->apiEndpoint.'/oauth/token',
['Content-Type: application/x-www-form-urlencoded'],
\http_build_query([
'grant_type' => 'authorization_code',
'code' => $code,
'redirect_uri' => $this->callback,
'client_id' => $this->appID,
'client_secret' => $this->appSecret
'client_secret' => $this->appSecret,
])
), true);
}
@@ -87,15 +86,14 @@ class Podio extends OAuth2
}
/**
* @param string $refreshToken
*
* @param string $refreshToken
* @return array
*/
public function refreshTokens(string $refreshToken): array
{
$this->tokens = \json_decode($this->request(
'POST',
$this->apiEndpoint . '/oauth/token',
$this->apiEndpoint.'/oauth/token',
['Content-Type: application/x-www-form-urlencoded'],
\http_build_query([
'grant_type' => 'refresh_token',
@@ -113,8 +111,7 @@ class Podio extends OAuth2
}
/**
* @param string $accessToken
*
* @param string $accessToken
* @return string
*/
public function getUserID(string $accessToken): string
@@ -125,8 +122,7 @@ class Podio extends OAuth2
}
/**
* @param string $accessToken
*
* @param string $accessToken
* @return string
*/
public function getUserEmail(string $accessToken): string
@@ -139,8 +135,7 @@ class Podio extends OAuth2
/**
* Check if the OAuth email is verified
*
* @param string $accessToken
*
* @param string $accessToken
* @return bool
*/
public function isEmailVerified(string $accessToken): bool
@@ -148,7 +143,7 @@ class Podio extends OAuth2
$user = $this->getUser($accessToken);
$mails = $user['mails'];
$mainMailIndex = \array_search($user['mail'], \array_map(fn($m) => $m['mail'], $mails));
$mainMailIndex = \array_search($user['mail'], \array_map(fn ($m) => $m['mail'], $mails));
$mainMain = $mails[$mainMailIndex];
if ($mainMain['verified'] ?? false) {
@@ -159,8 +154,7 @@ class Podio extends OAuth2
}
/**
* @param string $accessToken
*
* @param string $accessToken
* @return string
*/
public function getUserName(string $accessToken): string
@@ -171,8 +165,7 @@ class Podio extends OAuth2
}
/**
* @param string $accessToken
*
* @param string $accessToken
* @return array
*/
protected function getUser(string $accessToken): array
@@ -180,14 +173,14 @@ class Podio extends OAuth2
if (empty($this->user)) {
$user = \json_decode($this->request(
'GET',
$this->apiEndpoint . '/user',
['Authorization: Bearer ' . \urlencode($accessToken)]
$this->apiEndpoint.'/user',
['Authorization: Bearer '.\urlencode($accessToken)]
), true);
$profile = \json_decode($this->request(
'GET',
$this->apiEndpoint . '/user/profile',
['Authorization: Bearer ' . \urlencode($accessToken)]
$this->apiEndpoint.'/user/profile',
['Authorization: Bearer '.\urlencode($accessToken)]
), true);
$this->user = $user;
+17 -25
View File
@@ -25,7 +25,7 @@ class Salesforce extends OAuth2
* @var array
*/
protected array $scopes = [
"openid"
'openid',
];
/**
@@ -37,8 +37,7 @@ class Salesforce extends OAuth2
}
/**
* @param string $state
*
* @param string $state
* @return array
*/
public function parseState(string $state)
@@ -46,31 +45,29 @@ class Salesforce extends OAuth2
return \json_decode(\html_entity_decode($state), true);
}
/**
* @return string
*/
public function getLoginURL(): string
{
return 'https://login.salesforce.com/services/oauth2/authorize?' . \http_build_query([
return 'https://login.salesforce.com/services/oauth2/authorize?'.\http_build_query([
'response_type' => 'code',
'client_id' => $this->appID,
'redirect_uri' => $this->callback,
'scope' => \implode(' ', $this->getScopes()),
'state' => \json_encode($this->state)
'state' => \json_encode($this->state),
]);
}
/**
* @param string $code
*
* @param string $code
* @return array
*/
protected function getTokens(string $code): array
{
if (empty($this->tokens)) {
$headers = [
'Authorization: Basic ' . \base64_encode($this->appID . ':' . $this->appSecret),
'Authorization: Basic '.\base64_encode($this->appID.':'.$this->appSecret),
'Content-Type: application/x-www-form-urlencoded',
];
$this->tokens = \json_decode($this->request(
@@ -80,7 +77,7 @@ class Salesforce extends OAuth2
\http_build_query([
'code' => $code,
'redirect_uri' => $this->callback,
'grant_type' => 'authorization_code'
'grant_type' => 'authorization_code',
])
), true);
}
@@ -89,14 +86,13 @@ class Salesforce extends OAuth2
}
/**
* @param string $refreshToken
*
* @param string $refreshToken
* @return array
*/
public function refreshTokens(string $refreshToken): array
{
$headers = [
'Authorization: Basic ' . \base64_encode($this->appID . ':' . $this->appSecret),
'Authorization: Basic '.\base64_encode($this->appID.':'.$this->appSecret),
'Content-Type: application/x-www-form-urlencoded',
];
$this->tokens = \json_decode($this->request(
@@ -105,7 +101,7 @@ class Salesforce extends OAuth2
$headers,
\http_build_query([
'refresh_token' => $refreshToken,
'grant_type' => 'refresh_token'
'grant_type' => 'refresh_token',
])
), true);
@@ -117,8 +113,7 @@ class Salesforce extends OAuth2
}
/**
* @param string $accessToken
*
* @param string $accessToken
* @return string
*/
public function getUserID(string $accessToken): string
@@ -129,8 +124,7 @@ class Salesforce extends OAuth2
}
/**
* @param string $accessToken
*
* @param string $accessToken
* @return string
*/
public function getUserEmail(string $accessToken): string
@@ -145,8 +139,7 @@ class Salesforce extends OAuth2
*
* @link https://help.salesforce.com/s/articleView?id=sf.remoteaccess_using_userinfo_endpoint.htm&type=5
*
* @param string $accessToken
*
* @param string $accessToken
* @return bool
*/
public function isEmailVerified(string $accessToken): bool
@@ -161,8 +154,7 @@ class Salesforce extends OAuth2
}
/**
* @param string $accessToken
*
* @param string $accessToken
* @return string
*/
public function getUserName(string $accessToken): string
@@ -173,16 +165,16 @@ class Salesforce extends OAuth2
}
/**
* @param string $accessToken
*
* @param string $accessToken
* @return array
*/
protected function getUser(string $accessToken): array
{
if (empty($this->user)) {
$user = $this->request('GET', 'https://login.salesforce.com/services/oauth2/userinfo?access_token=' . \urlencode($accessToken));
$user = $this->request('GET', 'https://login.salesforce.com/services/oauth2/userinfo?access_token='.\urlencode($accessToken));
$this->user = \json_decode($user, true);
}
return $this->user;
}
}
+16 -23
View File
@@ -23,7 +23,7 @@ class Slack extends OAuth2
'identity.avatar',
'identity.basic',
'identity.email',
'identity.team'
'identity.team',
];
/**
@@ -40,17 +40,16 @@ class Slack extends OAuth2
public function getLoginURL(): string
{
// https://api.slack.com/docs/oauth#step_1_-_sending_users_to_authorize_and_or_install
return 'https://slack.com/oauth/authorize?' . \http_build_query([
return 'https://slack.com/oauth/authorize?'.\http_build_query([
'client_id' => $this->appID,
'scope' => \implode(' ', $this->getScopes()),
'redirect_uri' => $this->callback,
'state' => \json_encode($this->state)
'state' => \json_encode($this->state),
]);
}
/**
* @param string $code
*
* @param string $code
* @return array
*/
protected function getTokens(string $code): array
@@ -59,11 +58,11 @@ class Slack extends OAuth2
// https://api.slack.com/docs/oauth#step_3_-_exchanging_a_verification_code_for_an_access_token
$this->tokens = \json_decode($this->request(
'GET',
'https://slack.com/api/oauth.access?' . \http_build_query([
'https://slack.com/api/oauth.access?'.\http_build_query([
'client_id' => $this->appID,
'client_secret' => $this->appSecret,
'code' => $code,
'redirect_uri' => $this->callback
'redirect_uri' => $this->callback,
])
), true);
}
@@ -72,19 +71,18 @@ class Slack extends OAuth2
}
/**
* @param string $refreshToken
*
* @param string $refreshToken
* @return array
*/
public function refreshTokens(string $refreshToken): array
{
$this->tokens = \json_decode($this->request(
'GET',
'https://slack.com/api/oauth.access?' . \http_build_query([
'https://slack.com/api/oauth.access?'.\http_build_query([
'client_id' => $this->appID,
'client_secret' => $this->appSecret,
'refresh_token' => $refreshToken,
'grant_type' => 'refresh_token'
'grant_type' => 'refresh_token',
])
), true);
@@ -96,8 +94,7 @@ class Slack extends OAuth2
}
/**
* @param string $accessToken
*
* @param string $accessToken
* @return string
*/
public function getUserID(string $accessToken): string
@@ -108,8 +105,7 @@ class Slack extends OAuth2
}
/**
* @param string $accessToken
*
* @param string $accessToken
* @return string
*/
public function getUserEmail(string $accessToken): string
@@ -126,20 +122,18 @@ class Slack extends OAuth2
*
* @link https://slack.com/help/articles/207262907-Change-your-email-address
*
* @param string $accessToken
*
* @param string $accessToken
* @return bool
*/
public function isEmailVerified(string $accessToken): bool
{
$email = $this->getUserEmail($accessToken);
return !empty($email);
return ! empty($email);
}
/**
* @param string $accessToken
*
* @param string $accessToken
* @return string
*/
public function getUserName(string $accessToken): string
@@ -152,8 +146,7 @@ class Slack extends OAuth2
/**
* @link https://api.slack.com/methods/users.identity
*
* @param string $accessToken
*
* @param string $accessToken
* @return array
*/
protected function getUser(string $accessToken): array
@@ -161,7 +154,7 @@ class Slack extends OAuth2
if (empty($this->user)) {
$user = $this->request(
'GET',
'https://slack.com/api/users.identity?token=' . \urlencode($accessToken)
'https://slack.com/api/users.identity?token='.\urlencode($accessToken)
);
$this->user = \json_decode($user, true);
+20 -27
View File
@@ -49,33 +49,32 @@ class Spotify extends OAuth2
*/
public function getLoginURL(): string
{
return $this->endpoint . 'authorize?' .
return $this->endpoint.'authorize?'.
\http_build_query([
'response_type' => 'code',
'client_id' => $this->appID,
'scope' => \implode(' ', $this->getScopes()),
'redirect_uri' => $this->callback,
'state' => \json_encode($this->state)
'state' => \json_encode($this->state),
]);
}
/**
* @param string $code
*
* @param string $code
* @return array
*/
protected function getTokens(string $code): array
{
if (empty($this->tokens)) {
$headers = ['Authorization: Basic ' . \base64_encode($this->appID . ':' . $this->appSecret)];
$headers = ['Authorization: Basic '.\base64_encode($this->appID.':'.$this->appSecret)];
$this->tokens = \json_decode($this->request(
'POST',
$this->endpoint . 'api/token',
$this->endpoint.'api/token',
$headers,
\http_build_query([
"code" => $code,
"grant_type" => "authorization_code",
"redirect_uri" => $this->callback
'code' => $code,
'grant_type' => 'authorization_code',
'redirect_uri' => $this->callback,
])
), true);
}
@@ -84,20 +83,19 @@ class Spotify extends OAuth2
}
/**
* @param string $refreshToken
*
* @param string $refreshToken
* @return array
*/
public function refreshTokens(string $refreshToken): array
{
$headers = ['Authorization: Basic ' . \base64_encode($this->appID . ':' . $this->appSecret)];
$headers = ['Authorization: Basic '.\base64_encode($this->appID.':'.$this->appSecret)];
$this->tokens = \json_decode($this->request(
'POST',
$this->endpoint . 'api/token',
$this->endpoint.'api/token',
$headers,
\http_build_query([
"refresh_token" => $refreshToken,
"grant_type" => "refresh_token",
'refresh_token' => $refreshToken,
'grant_type' => 'refresh_token',
])
), true);
@@ -109,8 +107,7 @@ class Spotify extends OAuth2
}
/**
* @param string $accessToken
*
* @param string $accessToken
* @return string
*/
public function getUserID(string $accessToken): string
@@ -121,8 +118,7 @@ class Spotify extends OAuth2
}
/**
* @param string $accessToken
*
* @param string $accessToken
* @return string
*/
public function getUserEmail(string $accessToken): string
@@ -139,8 +135,7 @@ class Spotify extends OAuth2
*
* @link https://developer.spotify.com/documentation/web-api/reference/#/operations/get-current-users-profile
*
* @param string $accessToken
*
* @param string $accessToken
* @return bool
*/
public function isEmailVerified(string $accessToken): bool
@@ -149,8 +144,7 @@ class Spotify extends OAuth2
}
/**
* @param string $accessToken
*
* @param string $accessToken
* @return string
*/
public function getUserName(string $accessToken): string
@@ -161,8 +155,7 @@ class Spotify extends OAuth2
}
/**
* @param string $accessToken
*
* @param string $accessToken
* @return array
*/
protected function getUser(string $accessToken)
@@ -170,8 +163,8 @@ class Spotify extends OAuth2
if (empty($this->user)) {
$this->user = \json_decode($this->request(
'GET',
$this->resourceEndpoint . 'me',
['Authorization: Bearer ' . \urlencode($accessToken)]
$this->resourceEndpoint.'me',
['Authorization: Bearer '.\urlencode($accessToken)]
), true);
}
+15 -22
View File
@@ -3,7 +3,6 @@
namespace Appwrite\Auth\OAuth2;
use Appwrite\Auth\OAuth2;
use Utopia\Exception;
class Stripe extends OAuth2
{
@@ -50,18 +49,17 @@ class Stripe extends OAuth2
*/
public function getLoginURL(): string
{
return 'https://connect.stripe.com/oauth/authorize?' . \http_build_query([
return 'https://connect.stripe.com/oauth/authorize?'.\http_build_query([
'response_type' => 'code', // The only option at the moment is "code."
'client_id' => $this->appID,
'redirect_uri' => $this->callback,
'scope' => \implode(' ', $this->getScopes()),
'state' => \json_encode($this->state)
'state' => \json_encode($this->state),
]);
}
/**
* @param string $code
*
* @param string $code
* @return array
*/
protected function getTokens(string $code): array
@@ -73,7 +71,7 @@ class Stripe extends OAuth2
[],
\http_build_query([
'grant_type' => $this->grantType['authorize'],
'code' => $code
'code' => $code,
])
), true);
@@ -84,8 +82,7 @@ class Stripe extends OAuth2
}
/**
* @param string $refreshToken
*
* @param string $refreshToken
* @return array
*/
public function refreshTokens(string $refreshToken): array
@@ -105,12 +102,12 @@ class Stripe extends OAuth2
}
$this->stripeAccountId = $this->tokens['stripe_user_id'];
return $this->tokens;
}
/**
* @param string $accessToken
*
* @param string $accessToken
* @return string
*/
public function getUserID(string $accessToken): string
@@ -121,8 +118,7 @@ class Stripe extends OAuth2
}
/**
* @param string $accessToken
*
* @param string $accessToken
* @return string
*/
public function getUserEmail(string $accessToken): string
@@ -141,20 +137,18 @@ class Stripe extends OAuth2
*
* If present, the email is verified. This was verfied through a manual Stripe sign up process
*
* @param string $accessToken
*
* @param string $accessToken
* @return bool
*/
public function isEmailVerified(string $accessToken): bool
{
$email = $this->getUserEmail($accessToken);
return !empty($email);
return ! empty($email);
}
/**
* @param string $accessToken
*
* @param string $accessToken
* @return string
*/
public function getUserName(string $accessToken): string
@@ -165,18 +159,17 @@ class Stripe extends OAuth2
}
/**
* @param string $accessToken
*
* @param string $accessToken
* @return array
*/
protected function getUser(string $accessToken)
{
if (empty($this->user) && !empty($this->stripeAccountId)) {
if (empty($this->user) && ! empty($this->stripeAccountId)) {
$this->user = \json_decode(
$this->request(
'GET',
'https://api.stripe.com/v1/accounts/' . $this->stripeAccountId,
['Authorization: Bearer ' . \urlencode($accessToken)]
'https://api.stripe.com/v1/accounts/'.$this->stripeAccountId,
['Authorization: Bearer '.\urlencode($accessToken)]
),
true
);
+23 -29
View File
@@ -10,6 +10,7 @@ use Appwrite\Auth\OAuth2;
class Tradeshift extends OAuth2
{
public const TRADESHIFT_SANDBOX_API_DOMAIN = 'api-sandbox.tradeshift.com';
public const TRADESHIFT_API_DOMAIN = 'api.tradeshift.com';
private array $apiDomain = [
@@ -18,13 +19,13 @@ class Tradeshift extends OAuth2
];
private array $endpoint = [
'sandbox' => 'https://' . self::TRADESHIFT_SANDBOX_API_DOMAIN . '/tradeshift/',
'live' => 'https://' . self::TRADESHIFT_API_DOMAIN . '/tradeshift/',
'sandbox' => 'https://'.self::TRADESHIFT_SANDBOX_API_DOMAIN.'/tradeshift/',
'live' => 'https://'.self::TRADESHIFT_API_DOMAIN.'/tradeshift/',
];
private array $resourceEndpoint = [
'sandbox' => 'https://' . self::TRADESHIFT_SANDBOX_API_DOMAIN . '/tradeshift/rest/external/',
'live' => 'https://' . self::TRADESHIFT_API_DOMAIN . '/tradeshift/rest/external/',
'sandbox' => 'https://'.self::TRADESHIFT_SANDBOX_API_DOMAIN.'/tradeshift/rest/external/',
'live' => 'https://'.self::TRADESHIFT_API_DOMAIN.'/tradeshift/rest/external/',
];
protected string $environment = 'live';
@@ -64,18 +65,17 @@ class Tradeshift extends OAuth2
'response_type' => 'code',
'client_id' => $this->appID,
'scope' => \implode(' ', $this->getScopes()),
'redirect_uri' => \str_replace("localhost", "127.0.0.1", $this->callback),
'redirect_uri' => \str_replace('localhost', '127.0.0.1', $this->callback),
'state' => \json_encode($this->state),
]);
$url = $this->endpoint[$this->environment] . 'auth/login?' . $httpQuery;
$url = $this->endpoint[$this->environment].'auth/login?'.$httpQuery;
return $url;
}
/**
* @param string $code
*
* @param string $code
* @return array
*/
protected function getTokens(string $code): array
@@ -83,8 +83,8 @@ class Tradeshift extends OAuth2
if (empty($this->tokens)) {
$this->tokens = \json_decode($this->request(
'POST',
$this->endpoint[$this->environment] . 'auth/token',
['Authorization: Basic ' . \base64_encode($this->appID . ':' . $this->appSecret)],
$this->endpoint[$this->environment].'auth/token',
['Authorization: Basic '.\base64_encode($this->appID.':'.$this->appSecret)],
\http_build_query([
'grant_type' => 'authorization_code',
'code' => $code,
@@ -96,16 +96,15 @@ class Tradeshift extends OAuth2
}
/**
* @param string $refreshToken
*
* @param string $refreshToken
* @return array
*/
public function refreshTokens(string $refreshToken): array
{
$this->tokens = \json_decode($this->request(
'POST',
$this->endpoint[$this->environment] . 'auth/token',
['Authorization: Basic ' . \base64_encode($this->appID . ':' . $this->appSecret)],
$this->endpoint[$this->environment].'auth/token',
['Authorization: Basic '.\base64_encode($this->appID.':'.$this->appSecret)],
\http_build_query([
'grant_type' => 'refresh_token',
'refresh_token' => $refreshToken,
@@ -120,8 +119,7 @@ class Tradeshift extends OAuth2
}
/**
* @param string $accessToken
*
* @param string $accessToken
* @return string
*/
public function getUserID(string $accessToken): string
@@ -132,8 +130,7 @@ class Tradeshift extends OAuth2
}
/**
* @param string $accessToken
*
* @param string $accessToken
* @return string
*/
public function getUserEmail(string $accessToken): string
@@ -148,20 +145,18 @@ class Tradeshift extends OAuth2
*
* If present, the email is verified. This was verfied through a manual Tradeshift sign up process
*
* @param string $accessToken
*
* @param string $accessToken
* @return bool
*/
public function isEmailVerified(string $accessToken): bool
{
$email = $this->getUser($accessToken);
return !empty($email);
return ! empty($email);
}
/**
* @param string $accessToken
*
* @param string $accessToken
* @return string
*/
public function getUserName(string $accessToken): string
@@ -171,12 +166,11 @@ class Tradeshift extends OAuth2
$firstName = $user['FirstName'] ?? '';
$lastName = $user['LastName'] ?? '';
return $firstName . ' ' . $lastName;
return $firstName.' '.$lastName;
}
/**
* @param string $accessToken
*
* @param string $accessToken
* @return array
*/
protected function getUser(string $accessToken): array
@@ -184,14 +178,14 @@ class Tradeshift extends OAuth2
$header = [
'Content-Type: application/json',
'Accept: application/json',
'Host: ' . urlencode($this->apiDomain[$this->environment]),
'Authorization: Bearer ' . $accessToken,
'Host: '.urlencode($this->apiDomain[$this->environment]),
'Authorization: Bearer '.$accessToken,
];
if (empty($this->user)) {
$response = $this->request(
'GET',
$this->resourceEndpoint[$this->environment] . 'account/info/user',
$this->resourceEndpoint[$this->environment].'account/info/user',
$header
);
$this->user = \json_decode($response, true);
@@ -2,8 +2,6 @@
namespace Appwrite\Auth\OAuth2;
use Appwrite\Auth\OAuth2\Tradeshift;
class TradeshiftBox extends Tradeshift
{
protected string $environment = 'sandbox';
+23 -30
View File
@@ -49,20 +49,19 @@ class Twitch extends OAuth2
*/
public function getLoginURL(): string
{
return $this->endpoint . 'authorize?' .
return $this->endpoint.'authorize?'.
\http_build_query([
'response_type' => 'code',
'client_id' => $this->appID,
'scope' => \implode(' ', $this->getScopes()),
'redirect_uri' => $this->callback,
'force_verify' => true,
'state' => \json_encode($this->state)
'state' => \json_encode($this->state),
]);
}
/**
* @param string $code
*
* @param string $code
* @return array
*/
protected function getTokens(string $code): array
@@ -70,12 +69,12 @@ class Twitch extends OAuth2
if (empty($this->tokens)) {
$this->tokens = \json_decode($this->request(
'POST',
$this->endpoint . 'token?' . \http_build_query([
"client_id" => $this->appID,
"client_secret" => $this->appSecret,
"code" => $code,
"grant_type" => "authorization_code",
"redirect_uri" => $this->callback
$this->endpoint.'token?'.\http_build_query([
'client_id' => $this->appID,
'client_secret' => $this->appSecret,
'code' => $code,
'grant_type' => 'authorization_code',
'redirect_uri' => $this->callback,
])
), true);
}
@@ -84,19 +83,18 @@ class Twitch extends OAuth2
}
/**
* @param string $refreshToken
*
* @param string $refreshToken
* @return array
*/
public function refreshTokens(string $refreshToken): array
{
$this->tokens = \json_decode($this->request(
'POST',
$this->endpoint . 'token?' . \http_build_query([
"client_id" => $this->appID,
"client_secret" => $this->appSecret,
"refresh_token" => $refreshToken,
"grant_type" => "refresh_token",
$this->endpoint.'token?'.\http_build_query([
'client_id' => $this->appID,
'client_secret' => $this->appSecret,
'refresh_token' => $refreshToken,
'grant_type' => 'refresh_token',
])
), true);
@@ -108,8 +106,7 @@ class Twitch extends OAuth2
}
/**
* @param string $accessToken
*
* @param string $accessToken
* @return string
*/
public function getUserID(string $accessToken): string
@@ -120,8 +117,7 @@ class Twitch extends OAuth2
}
/**
* @param string $accessToken
*
* @param string $accessToken
* @return string
*/
public function getUserEmail(string $accessToken): string
@@ -138,20 +134,18 @@ class Twitch extends OAuth2
*
* @link https://dev.twitch.tv/docs/api/reference#get-users
*
* @param string $accessToken
*
* @param string $accessToken
* @return bool
*/
public function isEmailVerified(string $accessToken): bool
{
$email = $this->getUserEmail($accessToken);
return !empty($email);
return ! empty($email);
}
/**
* @param string $accessToken
*
* @param string $accessToken
* @return string
*/
public function getUserName(string $accessToken): string
@@ -162,8 +156,7 @@ class Twitch extends OAuth2
}
/**
* @param string $accessToken
*
* @param string $accessToken
* @return array
*/
protected function getUser(string $accessToken)
@@ -173,8 +166,8 @@ class Twitch extends OAuth2
'GET',
$this->resourceEndpoint,
[
'Authorization: Bearer ' . \urlencode($accessToken),
'Client-Id: ' . \urlencode($this->appID)
'Authorization: Bearer '.\urlencode($accessToken),
'Client-Id: '.\urlencode($this->appID),
]
), true);
+12 -19
View File
@@ -39,18 +39,17 @@ class WordPress extends OAuth2
*/
public function getLoginURL(): string
{
return 'https://public-api.wordpress.com/oauth2/authorize?' . \http_build_query([
return 'https://public-api.wordpress.com/oauth2/authorize?'.\http_build_query([
'client_id' => $this->appID,
'redirect_uri' => $this->callback,
'response_type' => 'code',
'scope' => $this->getScopes(),
'state' => \json_encode($this->state)
'state' => \json_encode($this->state),
]);
}
/**
* @param string $code
*
* @param string $code
* @return array
*/
protected function getTokens(string $code): array
@@ -65,7 +64,7 @@ class WordPress extends OAuth2
'redirect_uri' => $this->callback,
'client_secret' => $this->appSecret,
'grant_type' => 'authorization_code',
'code' => $code
'code' => $code,
])
), true);
}
@@ -74,8 +73,7 @@ class WordPress extends OAuth2
}
/**
* @param string $refreshToken
*
* @param string $refreshToken
* @return array
*/
public function refreshTokens(string $refreshToken): array
@@ -88,7 +86,7 @@ class WordPress extends OAuth2
'client_id' => $this->appID,
'client_secret' => $this->appSecret,
'grant_type' => 'refresh_token',
'refresh_token' => $refreshToken
'refresh_token' => $refreshToken,
])
), true);
@@ -100,8 +98,7 @@ class WordPress extends OAuth2
}
/**
* @param string $accessToken
*
* @param string $accessToken
* @return string
*/
public function getUserID(string $accessToken): string
@@ -112,8 +109,7 @@ class WordPress extends OAuth2
}
/**
* @param string $accessToken
*
* @param string $accessToken
* @return string
*/
public function getUserEmail(string $accessToken): string
@@ -132,8 +128,7 @@ class WordPress extends OAuth2
*
* @link https://developer.wordpress.com/docs/api/1.1/get/me/
*
* @param string $accessToken
*
* @param string $accessToken
* @return bool
*/
public function isEmailVerified(string $accessToken): bool
@@ -148,8 +143,7 @@ class WordPress extends OAuth2
}
/**
* @param string $accessToken
*
* @param string $accessToken
* @return string
*/
public function getUserName(string $accessToken): string
@@ -160,14 +154,13 @@ class WordPress extends OAuth2
}
/**
* @param string $accessToken
*
* @param string $accessToken
* @return array
*/
protected function getUser(string $accessToken)
{
if (empty($this->user)) {
$this->user = \json_decode($this->request('GET', 'https://public-api.wordpress.com/rest/v1/me', ['Authorization: Bearer ' . $accessToken]), true);
$this->user = \json_decode($this->request('GET', 'https://public-api.wordpress.com/rest/v1/me', ['Authorization: Bearer '.$accessToken]), true);
}
return $this->user;
+20 -29
View File
@@ -45,10 +45,8 @@ class Yahoo extends OAuth2
return 'yahoo';
}
/**
* @param $state
*
* @return array
*/
public function parseState(string $state)
@@ -61,37 +59,36 @@ class Yahoo extends OAuth2
*/
public function getLoginURL(): string
{
return $this->endpoint . 'request_auth?' .
return $this->endpoint.'request_auth?'.
\http_build_query([
'response_type' => 'code',
'client_id' => $this->appID,
'scope' => \implode(' ', $this->getScopes()),
'redirect_uri' => $this->callback,
'state' => \json_encode($this->state)
'state' => \json_encode($this->state),
]);
}
/**
* @param string $code
*
* @param string $code
* @return array
*/
protected function getTokens(string $code): array
{
if (empty($this->tokens)) {
$headers = [
'Authorization: Basic ' . \base64_encode($this->appID . ':' . $this->appSecret),
'Authorization: Basic '.\base64_encode($this->appID.':'.$this->appSecret),
'Content-Type: application/x-www-form-urlencoded',
];
$this->tokens = \json_decode($this->request(
'POST',
$this->endpoint . 'get_token',
$this->endpoint.'get_token',
$headers,
\http_build_query([
"code" => $code,
"grant_type" => "authorization_code",
"redirect_uri" => $this->callback
'code' => $code,
'grant_type' => 'authorization_code',
'redirect_uri' => $this->callback,
])
), true);
}
@@ -100,24 +97,23 @@ class Yahoo extends OAuth2
}
/**
* @param string $refreshToken
*
* @param string $refreshToken
* @return array
*/
public function refreshTokens(string $refreshToken): array
{
$headers = [
'Authorization: Basic ' . \base64_encode($this->appID . ':' . $this->appSecret),
'Authorization: Basic '.\base64_encode($this->appID.':'.$this->appSecret),
'Content-Type: application/x-www-form-urlencoded',
];
$this->tokens = \json_decode($this->request(
'POST',
$this->endpoint . 'get_token',
$this->endpoint.'get_token',
$headers,
\http_build_query([
"refresh_token" => $refreshToken,
"grant_type" => "refresh_token",
'refresh_token' => $refreshToken,
'grant_type' => 'refresh_token',
])
), true);
@@ -129,8 +125,7 @@ class Yahoo extends OAuth2
}
/**
* @param string $accessToken
*
* @param string $accessToken
* @return string
*/
public function getUserID(string $accessToken): string
@@ -141,8 +136,7 @@ class Yahoo extends OAuth2
}
/**
* @param string $accessToken
*
* @param string $accessToken
* @return string
*/
public function getUserEmail(string $accessToken): string
@@ -157,20 +151,18 @@ class Yahoo extends OAuth2
*
* If present, the email is verified. This was verfied through a manual Yahoo sign up process
*
* @param string $accessToken
*
* @param string $accessToken
* @return bool
*/
public function isEmailVerified(string $accessToken): bool
{
$email = $this->getUserEmail($accessToken);
return !empty($email);
return ! empty($email);
}
/**
* @param string $accessToken
*
* @param string $accessToken
* @return string
*/
public function getUserName(string $accessToken): string
@@ -181,8 +173,7 @@ class Yahoo extends OAuth2
}
/**
* @param string $accessToken
*
* @param string $accessToken
* @return array
*/
protected function getUser(string $accessToken)
@@ -191,7 +182,7 @@ class Yahoo extends OAuth2
$this->user = \json_decode($this->request(
'GET',
$this->resourceEndpoint,
['Authorization: Bearer ' . \urlencode($accessToken)]
['Authorization: Bearer '.\urlencode($accessToken)]
), true);
}
+15 -22
View File
@@ -37,18 +37,17 @@ class Yammer extends OAuth2
*/
public function getLoginURL(): string
{
return $this->endpoint . 'oauth2/authorize?' .
return $this->endpoint.'oauth2/authorize?'.
\http_build_query([
'client_id' => $this->appID,
'response_type' => 'code',
'redirect_uri' => $this->callback,
'state' => \json_encode($this->state)
'state' => \json_encode($this->state),
]);
}
/**
* @param string $code
*
* @param string $code
* @return array
*/
protected function getTokens(string $code): array
@@ -57,13 +56,13 @@ class Yammer extends OAuth2
$headers = ['Content-Type: application/x-www-form-urlencoded'];
$this->tokens = \json_decode($this->request(
'POST',
$this->endpoint . 'access_token?',
$this->endpoint.'access_token?',
$headers,
\http_build_query([
'client_id' => $this->appID,
'client_secret' => $this->appSecret,
'code' => $code,
'grant_type' => 'authorization_code'
'grant_type' => 'authorization_code',
])
), true);
}
@@ -72,8 +71,7 @@ class Yammer extends OAuth2
}
/**
* @param string $refreshToken
*
* @param string $refreshToken
* @return array
*/
public function refreshTokens(string $refreshToken): array
@@ -81,13 +79,13 @@ class Yammer extends OAuth2
$headers = ['Content-Type: application/x-www-form-urlencoded'];
$this->tokens = \json_decode($this->request(
'POST',
$this->endpoint . 'access_token?',
$this->endpoint.'access_token?',
$headers,
\http_build_query([
'client_id' => $this->appID,
'client_secret' => $this->appSecret,
'refresh_token' => $refreshToken,
'grant_type' => 'refresh_token'
'grant_type' => 'refresh_token',
])
), true);
@@ -99,8 +97,7 @@ class Yammer extends OAuth2
}
/**
* @param string $accessToken
*
* @param string $accessToken
* @return string
*/
public function getUserID(string $accessToken): string
@@ -111,8 +108,7 @@ class Yammer extends OAuth2
}
/**
* @param string $accessToken
*
* @param string $accessToken
* @return string
*/
public function getUserEmail(string $accessToken): string
@@ -127,20 +123,18 @@ class Yammer extends OAuth2
*
* If present, the email is verified. This was verfied through a manual Yammer sign up process
*
* @param string $accessToken
*
* @param string $accessToken
* @return bool
*/
public function isEmailVerified(string $accessToken): bool
{
$email = $this->getUserEmail($accessToken);
return !empty($email);
return ! empty($email);
}
/**
* @param string $accessToken
*
* @param string $accessToken
* @return string
*/
public function getUserName(string $accessToken): string
@@ -151,14 +145,13 @@ class Yammer extends OAuth2
}
/**
* @param string $accessToken
*
* @param string $accessToken
* @return array
*/
protected function getUser(string $accessToken): array
{
if (empty($this->user)) {
$headers = ['Authorization: Bearer ' . \urlencode($accessToken)];
$headers = ['Authorization: Bearer '.\urlencode($accessToken)];
$user = $this->request('GET', 'https://www.yammer.com/api/v1/users/current.json', $headers);
$this->user = \json_decode($user, true);
}
+17 -26
View File
@@ -8,7 +8,6 @@ use Appwrite\Auth\OAuth2;
// https://tech.yandex.com/passport/doc/dg/reference/request-docpage/
// https://tech.yandex.com/oauth/doc/dg/reference/web-client-docpage/
class Yandex extends OAuth2
{
/**
@@ -35,8 +34,7 @@ class Yandex extends OAuth2
}
/**
* @param string $state
*
* @param string $state
* @return array
*/
public function parseState(string $state)
@@ -44,30 +42,28 @@ class Yandex extends OAuth2
return \json_decode(\html_entity_decode($state), true);
}
/**
* @return string
*/
public function getLoginURL(): string
{
return 'https://oauth.yandex.com/authorize?' . \http_build_query([
return 'https://oauth.yandex.com/authorize?'.\http_build_query([
'response_type' => 'code',
'client_id' => $this->appID,
'scope' => \implode(' ', $this->getScopes()),
'state' => \json_encode($this->state)
'state' => \json_encode($this->state),
]);
}
/**
* @param string $code
*
* @param string $code
* @return array
*/
protected function getTokens(string $code): array
{
if (empty($this->tokens)) {
$headers = [
'Authorization: Basic ' . \base64_encode($this->appID . ':' . $this->appSecret),
'Authorization: Basic '.\base64_encode($this->appID.':'.$this->appSecret),
'Content-Type: application/x-www-form-urlencoded',
];
$this->tokens = \json_decode($this->request(
@@ -76,7 +72,7 @@ class Yandex extends OAuth2
$headers,
\http_build_query([
'code' => $code,
'grant_type' => 'authorization_code'
'grant_type' => 'authorization_code',
])
), true);
}
@@ -85,14 +81,13 @@ class Yandex extends OAuth2
}
/**
* @param string $refreshToken
*
* @param string $refreshToken
* @return array
*/
public function refreshTokens(string $refreshToken): array
{
$headers = [
'Authorization: Basic ' . \base64_encode($this->appID . ':' . $this->appSecret),
'Authorization: Basic '.\base64_encode($this->appID.':'.$this->appSecret),
'Content-Type: application/x-www-form-urlencoded',
];
$this->tokens = \json_decode($this->request(
@@ -101,7 +96,7 @@ class Yandex extends OAuth2
$headers,
\http_build_query([
'refresh_token' => $refreshToken,
'grant_type' => 'authorization_code'
'grant_type' => 'authorization_code',
])
), true);
@@ -113,8 +108,7 @@ class Yandex extends OAuth2
}
/**
* @param string $accessToken
*
* @param string $accessToken
* @return string
*/
public function getUserID(string $accessToken): string
@@ -125,8 +119,7 @@ class Yandex extends OAuth2
}
/**
* @param string $accessToken
*
* @param string $accessToken
* @return string
*/
public function getUserEmail(string $accessToken): string
@@ -139,8 +132,7 @@ class Yandex extends OAuth2
/**
* Check if the OAuth email is verified
*
* @param string $accessToken
*
* @param string $accessToken
* @return bool
*/
public function isEmailVerified(string $accessToken): bool
@@ -149,8 +141,7 @@ class Yandex extends OAuth2
}
/**
* @param string $accessToken
*
* @param string $accessToken
* @return string
*/
public function getUserName(string $accessToken): string
@@ -161,19 +152,19 @@ class Yandex extends OAuth2
}
/**
* @param string $accessToken
*
* @param string $accessToken
* @return array
*/
protected function getUser(string $accessToken): array
{
if (empty($this->user)) {
$user = $this->request('GET', 'https://login.yandex.ru/info?' . \http_build_query([
$user = $this->request('GET', 'https://login.yandex.ru/info?'.\http_build_query([
'format' => 'json',
'oauth_token' => $accessToken
'oauth_token' => $accessToken,
]));
$this->user = \json_decode($user, true);
}
return $this->user;
}
}
+16 -23
View File
@@ -30,7 +30,7 @@ class Zoom extends OAuth2
* @var array
*/
protected array $scopes = [
'user_info:read'
'user_info:read',
];
/**
@@ -46,7 +46,7 @@ class Zoom extends OAuth2
*/
public function getLoginURL(): string
{
return $this->endpoint . '/oauth/authorize?' . \http_build_query([
return $this->endpoint.'/oauth/authorize?'.\http_build_query([
'client_id' => $this->appID,
'redirect_uri' => $this->callback,
'response_type' => 'code',
@@ -56,22 +56,21 @@ class Zoom extends OAuth2
}
/**
* @param string $code
*
* @param string $code
* @return array
*/
protected function getTokens(string $code): array
{
if (empty($this->tokens)) {
$headers = ['Authorization: Basic ' . \base64_encode($this->appID . ':' . $this->appSecret), 'Content-Type: application/x-www-form-urlencoded'];
$headers = ['Authorization: Basic '.\base64_encode($this->appID.':'.$this->appSecret), 'Content-Type: application/x-www-form-urlencoded'];
$this->tokens = \json_decode($this->request(
'POST',
$this->endpoint . '/oauth/token',
$this->endpoint.'/oauth/token',
$headers,
\http_build_query([
'grant_type' => 'authorization_code',
'redirect_uri' => $this->callback,
'code' => $code
'code' => $code,
])
), true);
}
@@ -80,16 +79,15 @@ class Zoom extends OAuth2
}
/**
* @param string $refreshToken
*
* @param string $refreshToken
* @return array
*/
public function refreshTokens(string $refreshToken): array
{
$headers = ['Authorization: Basic ' . \base64_encode($this->appID . ':' . $this->appSecret), 'Content-Type: application/x-www-form-urlencoded'];
$headers = ['Authorization: Basic '.\base64_encode($this->appID.':'.$this->appSecret), 'Content-Type: application/x-www-form-urlencoded'];
$this->tokens = \json_decode($this->request(
'POST',
$this->endpoint . '/oauth/token',
$this->endpoint.'/oauth/token',
$headers,
\http_build_query([
'grant_type' => 'refresh_token',
@@ -105,8 +103,7 @@ class Zoom extends OAuth2
}
/**
* @param string $accessToken
*
* @param string $accessToken
* @return string
*/
public function getUserID(string $accessToken): string
@@ -117,8 +114,7 @@ class Zoom extends OAuth2
}
/**
* @param string $accessToken
*
* @param string $accessToken
* @return string
*/
public function getUserEmail(string $accessToken): string
@@ -133,8 +129,7 @@ class Zoom extends OAuth2
*
* @link https://marketplace.zoom.us/docs/api-reference/zoom-api/methods/#operation/user
*
* @param string $accessToken
*
* @param string $accessToken
* @return bool
*/
public function isEmailVerified(string $accessToken): bool
@@ -149,26 +144,24 @@ class Zoom extends OAuth2
}
/**
* @param string $accessToken
*
* @param string $accessToken
* @return string
*/
public function getUserName(string $accessToken): string
{
$response = $this->getUser($accessToken);
return ($response['first_name'] ?? '') . ' ' . ($response['last_name'] ?? '');
return ($response['first_name'] ?? '').' '.($response['last_name'] ?? '');
}
/**
* @param string $accessToken
*
* @param string $accessToken
* @return array
*/
protected function getUser(string $accessToken)
{
$headers = [
'Authorization: Bearer ' . \urlencode($accessToken)
'Authorization: Bearer '.\urlencode($accessToken),
];
if (empty($this->user)) {
+2 -3
View File
@@ -26,13 +26,12 @@ class Password extends Validator
/**
* Is valid.
*
* @param mixed $value
*
* @param mixed $value
* @return bool
*/
public function isValid($value): bool
{
if (!\is_string($value)) {
if (! \is_string($value)) {
return false;
}
@@ -10,6 +10,7 @@ namespace Appwrite\Auth\Validator;
class PasswordDictionary extends Password
{
protected array $dictionary;
protected bool $enabled;
public function __construct(array $dictionary, bool $enabled = false)
@@ -33,19 +34,19 @@ class PasswordDictionary extends Password
/**
* Is valid.
*
* @param mixed $value
*
* @param mixed $value
* @return bool
*/
public function isValid($value): bool
{
if (!parent::isValid($value)) {
if (! parent::isValid($value)) {
return false;
}
if ($this->enabled && array_key_exists($value, $this->dictionary)) {
return false;
}
return true;
}
@@ -12,7 +12,9 @@ use Appwrite\Auth\Auth;
class PasswordHistory extends Password
{
protected array $history;
protected string $algo;
protected array $algoOptions;
public function __construct(array $history, string $algo, array $algoOptions = [])
@@ -37,8 +39,7 @@ class PasswordHistory extends Password
/**
* Is valid.
*
* @param mixed $value
*
* @param mixed $value
* @return bool
*/
public function isValid($value): bool
@@ -48,6 +49,7 @@ class PasswordHistory extends Password
return false;
}
}
return true;
}
+3 -4
View File
@@ -31,17 +31,16 @@ class PersonalData extends Password
/**
* Is valid.
*
* @param mixed $value
*
* @param mixed $value
* @return bool
*/
public function isValid($password): bool
{
if (!parent::isValid($password)) {
if (! parent::isValid($password)) {
return false;
}
if (!$this->strict) {
if (! $this->strict) {
$password = strtolower($password);
$this->userId = strtolower($this->userId);
$this->email = strtolower($this->email);
+2 -3
View File
@@ -26,13 +26,12 @@ class Phone extends Validator
/**
* Is valid.
*
* @param mixed $value
*
* @param mixed $value
* @return bool
*/
public function isValid($value): bool
{
return is_string($value) && !!\preg_match('/^\+[1-9]\d{1,14}$/', $value);
return is_string($value) && (bool) \preg_match('/^\+[1-9]\d{1,14}$/', $value);
}
/**
+4 -4
View File
@@ -17,7 +17,7 @@ class Detector
protected $detctor;
/**
* @param string $userAgent
* @param string $userAgent
*/
public function __construct(string $userAgent)
{
@@ -54,7 +54,7 @@ class Detector
'type' => 'desktop',
'short_name' => 'cli',
'name' => 'Appwrite CLI',
'version' => $version
'version' => $version,
];
} else {
$client = $this->getDetector()->getClient();
@@ -89,7 +89,7 @@ class Detector
*/
protected function getDetector(): DeviceDetector
{
if (!$this->detctor) {
if (! $this->detctor) {
$this->detctor = new DeviceDetector($this->userAgent);
$this->detctor->skipBotDetection(); // OPTIONAL: If called, bot detection will completely be skipped (bots will be detected as regular devices then)
$this->detctor->parse();
@@ -103,7 +103,7 @@ class Detector
* It is needed if we want bots to be processed as a simple clients. So we can detect if it is mobile client,
* or desktop, or enything else. By default all this information is not retrieved for the bots.
*
* @param bool $skip
* @param bool $skip
*/
public function skipBotDetection(bool $skip = true): void
{
+2 -2
View File
@@ -13,7 +13,7 @@ class Compose
protected $compose = [];
/**
* @var string $data
* @var string
*/
public function __construct(string $data)
{
@@ -48,7 +48,7 @@ class Compose
*/
public function getService(string $name): Service
{
if (!isset($this->compose['services'][$name])) {
if (! isset($this->compose['services'][$name])) {
throw new Exception('Service not found');
}
+3 -2
View File
@@ -12,7 +12,7 @@ class Service
protected $service = [];
/**
* @var string $path
* @var string
*/
public function __construct(array $service)
{
@@ -54,7 +54,8 @@ class Service
public function getImageVersion(): string
{
$image = $this->getImage();
return substr($image, ((int)strpos($image, ':')) + 1);
return substr($image, ((int) strpos($image, ':')) + 1);
}
/**
+5 -9
View File
@@ -2,8 +2,6 @@
namespace Appwrite\Docker;
use Exception;
class Env
{
/**
@@ -12,7 +10,7 @@ class Env
protected $vars = [];
/**
* @var string $data
* @var string
*/
public function __construct(string $data)
{
@@ -30,9 +28,8 @@ class Env
}
/**
* @param string $key
* @param mixed $value
*
* @param string $key
* @param mixed $value
* @return $this
*/
public function setVar(string $key, $value): self
@@ -43,8 +40,7 @@ class Env
}
/**
* @param string $key
*
* @param string $key
* @return string
*/
public function getVar(string $key): string
@@ -70,7 +66,7 @@ class Env
$output = '';
foreach ($this->vars as $key => $value) {
$output .= $key . '=' . $value . "\n";
$output .= $key.'='.$value."\n";
}
return $output;
+8 -4
View File
@@ -7,8 +7,11 @@ use Resque;
class Audit extends Event
{
protected string $resource = '';
protected string $mode = '';
protected string $userAgent = '';
protected string $ip = '';
public function __construct()
@@ -19,7 +22,7 @@ class Audit extends Event
/**
* Set resource for this audit event.
*
* @param string $resource
* @param string $resource
* @return self
*/
public function setResource(string $resource): self
@@ -42,7 +45,7 @@ class Audit extends Event
/**
* Set mode for this audit event
*
* @param string $mode
* @param string $mode
* @return self
*/
public function setMode(string $mode): self
@@ -65,7 +68,7 @@ class Audit extends Event
/**
* Set user agent for this audit event.
*
* @param string $userAgent
* @param string $userAgent
* @return self
*/
public function setUserAgent(string $userAgent): self
@@ -88,7 +91,7 @@ class Audit extends Event
/**
* Set IP for this audit event.
*
* @param string $ip
* @param string $ip
* @return self
*/
public function setIP(string $ip): self
@@ -112,6 +115,7 @@ class Audit extends Event
* Executes the event and sends it to the audit worker.
*
* @return string|bool
*
* @throws \InvalidArgumentException
*/
public function trigger(): string|bool
+7 -4
View File
@@ -8,7 +8,9 @@ use Utopia\Database\Document;
class Build extends Event
{
protected string $type = '';
protected ?Document $resource = null;
protected ?Document $deployment = null;
public function __construct()
@@ -19,7 +21,7 @@ class Build extends Event
/**
* Sets resource document for the build event.
*
* @param Document $resource
* @param Document $resource
* @return self
*/
public function setResource(Document $resource): self
@@ -42,7 +44,7 @@ class Build extends Event
/**
* Sets deployment for the build event.
*
* @param Document $deployment
* @param Document $deployment
* @return self
*/
public function setDeployment(Document $deployment): self
@@ -65,7 +67,7 @@ class Build extends Event
/**
* Sets type for the build event.
*
* @param string $type Can be `BUILD_TYPE_DEPLOYMENT` or `BUILD_TYPE_RETRY`.
* @param string $type Can be `BUILD_TYPE_DEPLOYMENT` or `BUILD_TYPE_RETRY`.
* @return self
*/
public function setType(string $type): self
@@ -89,6 +91,7 @@ class Build extends Event
* Executes the function event and sends it to the functions worker.
*
* @return string|bool
*
* @throws \InvalidArgumentException
*/
public function trigger(): string|bool
@@ -97,7 +100,7 @@ class Build extends Event
'project' => $this->project,
'resource' => $this->resource,
'deployment' => $this->deployment,
'type' => $this->type
'type' => $this->type,
]);
}
}
+5 -3
View File
@@ -8,6 +8,7 @@ use Utopia\Database\Document;
class Certificate extends Event
{
protected bool $skipRenewCheck = false;
protected ?Document $domain = null;
public function __construct()
@@ -18,7 +19,7 @@ class Certificate extends Event
/**
* Set domain for this certificates event.
*
* @param Document $domain
* @param Document $domain
* @return self
*/
public function setDomain(Document $domain): self
@@ -41,7 +42,7 @@ class Certificate extends Event
/**
* Set if the certificate needs to be validated.
*
* @param bool $skipRenewCheck
* @param bool $skipRenewCheck
* @return self
*/
public function setSkipRenewCheck(bool $skipRenewCheck): self
@@ -65,6 +66,7 @@ class Certificate extends Event
* Executes the event and sends it to the certificates worker.
*
* @return string|bool
*
* @throws \InvalidArgumentException
*/
public function trigger(): string|bool
@@ -72,7 +74,7 @@ class Certificate extends Event
return Resque::enqueue($this->queue, $this->class, [
'project' => $this->project,
'domain' => $this->domain,
'skipRenewCheck' => $this->skipRenewCheck
'skipRenewCheck' => $this->skipRenewCheck,
]);
}
}
+12 -5
View File
@@ -8,8 +8,11 @@ use Utopia\Database\Document;
class Database extends Event
{
protected string $type = '';
protected ?Document $database = null;
protected ?Document $collection = null;
protected ?Document $document = null;
public function __construct()
@@ -20,7 +23,7 @@ class Database extends Event
/**
* Sets the type for this database event (use the constants starting with DATABASE_TYPE_*).
*
* @param string $type
* @param string $type
* @return self
*/
public function setType(string $type): self
@@ -32,6 +35,7 @@ class Database extends Event
/**
* Returns the set type for the database event.
*
* @return string
*/
public function getType(): string
@@ -42,19 +46,20 @@ class Database extends Event
/**
* Set the database for this event
*
* @param Document $database
* @param Document $database
* @return self
*/
public function setDatabase(Document $database): self
{
$this->database = $database;
return $this;
}
/**
* Set the collection for this database event.
*
* @param Document $collection
* @param Document $collection
* @return self
*/
public function setCollection(Document $collection): self
@@ -77,7 +82,7 @@ class Database extends Event
/**
* Set the document for this database event.
*
* @param Document $document
* @param Document $document
* @return self
*/
public function setDocument(Document $document): self
@@ -89,6 +94,7 @@ class Database extends Event
/**
* Returns set document for this database event.
*
* @return null|Document
*/
public function getDocument(): ?Document
@@ -100,6 +106,7 @@ class Database extends Event
* Executes the event and send it to the database worker.
*
* @return string|bool
*
* @throws \InvalidArgumentException
*/
public function trigger(): string|bool
@@ -111,7 +118,7 @@ class Database extends Event
'collection' => $this->collection,
'document' => $this->document,
'database' => $this->database,
'events' => Event::generateEvents($this->getEvent(), $this->getParams())
'events' => Event::generateEvents($this->getEvent(), $this->getParams()),
]);
}
}
+15 -10
View File
@@ -8,11 +8,14 @@ use Utopia\Database\Document;
class Delete extends Event
{
protected string $type = '';
protected ?Document $document = null;
protected ?string $resource = null;
protected ?string $datetime = null;
protected ?string $hourlyUsageRetentionDatetime = null;
protected ?Document $document = null;
protected ?string $resource = null;
protected ?string $datetime = null;
protected ?string $hourlyUsageRetentionDatetime = null;
public function __construct()
{
@@ -22,7 +25,7 @@ class Delete extends Event
/**
* Sets the type for the delete event (use the constants starting with DELETE_TYPE_*).
*
* @param string $type
* @param string $type
* @return self
*/
public function setType(string $type): self
@@ -45,31 +48,33 @@ class Delete extends Event
/**
* set Datetime.
*
* @param string $datetime
* @param string $datetime
* @return self
*/
public function setDatetime(string $datetime): self
{
$this->datetime = $datetime;
return $this;
}
/**
* Sets datetime for 1h interval.
*
* @param string $datetime
* @param string $datetime
* @return self
*/
public function setUsageRetentionHourlyDateTime(string $datetime): self
{
$this->hourlyUsageRetentionDatetime = $datetime;
return $this;
}
/**
* Sets the document for the delete event.
*
* @param Document $document
* @param Document $document
* @return self
*/
public function setDocument(Document $document): self
@@ -92,7 +97,7 @@ class Delete extends Event
/**
* Sets the resource for the delete event.
*
* @param string $resource
* @param string $resource
* @return self
*/
public function setResource(string $resource): self
@@ -112,11 +117,11 @@ class Delete extends Event
return $this->document;
}
/**
* Executes this event and sends it to the deletes worker.
*
* @return string|bool
*
* @throws \InvalidArgumentException
*/
public function trigger(): string|bool
+50 -28
View File
@@ -9,51 +9,70 @@ use Utopia\Database\Document;
class Event
{
public const DATABASE_QUEUE_NAME = 'v1-database';
public const DATABASE_CLASS_NAME = 'DatabaseV1';
public const DELETE_QUEUE_NAME = 'v1-deletes';
public const DELETE_CLASS_NAME = 'DeletesV1';
public const AUDITS_QUEUE_NAME = 'v1-audits';
public const AUDITS_CLASS_NAME = 'AuditsV1';
public const MAILS_QUEUE_NAME = 'v1-mails';
public const MAILS_CLASS_NAME = 'MailsV1';
public const FUNCTIONS_QUEUE_NAME = 'v1-functions';
public const FUNCTIONS_CLASS_NAME = 'FunctionsV1';
public const USAGE_QUEUE_NAME = 'v1-usage';
public const USAGE_CLASS_NAME = 'UsageV1';
public const WEBHOOK_QUEUE_NAME = 'v1-webhooks';
public const WEBHOOK_CLASS_NAME = 'WebhooksV1';
public const CERTIFICATES_QUEUE_NAME = 'v1-certificates';
public const CERTIFICATES_CLASS_NAME = 'CertificatesV1';
public const BUILDS_QUEUE_NAME = 'v1-builds';
public const BUILDS_CLASS_NAME = 'BuildsV1';
public const MESSAGING_QUEUE_NAME = 'v1-messaging';
public const MESSAGING_CLASS_NAME = 'MessagingV1';
public const MIGRATIONS_QUEUE_NAME = 'v1-migrations';
public const MIGRATIONS_CLASS_NAME = 'MigrationsV1';
protected string $queue = '';
protected string $class = '';
protected string $event = '';
protected array $params = [];
protected array $payload = [];
protected array $context = [];
protected ?Document $project = null;
protected ?Document $user = null;
protected bool $paused = false;
/**
* @param string $queue
* @param string $class
* @param string $queue
* @param string $class
* @return void
*/
public function __construct(string $queue, string $class)
@@ -65,7 +84,7 @@ class Event
/**
* Set queue used for this event.
*
* @param string $queue
* @param string $queue
* @return Event
*/
public function setQueue(string $queue): self
@@ -87,7 +106,8 @@ class Event
/**
* Set event name used for this event.
* @param string $event
*
* @param string $event
* @return Event
*/
public function setEvent(string $event): self
@@ -110,7 +130,7 @@ class Event
/**
* Set project for this event.
*
* @param Document $project
* @param Document $project
* @return self
*/
public function setProject(Document $project): self
@@ -133,7 +153,7 @@ class Event
/**
* Set user for this event.
*
* @param Document $user
* @param Document $user
* @return self
*/
public function setUser(Document $user): self
@@ -156,7 +176,7 @@ class Event
/**
* Set payload for this event.
*
* @param array $payload
* @param array $payload
* @return self
*/
public function setPayload(array $payload): self
@@ -179,8 +199,8 @@ class Event
/**
* Set context for this event.
*
* @param string $key
* @param Document $context
* @param string $key
* @param Document $context
* @return self
*/
public function setContext(string $key, Document $context): self
@@ -193,8 +213,7 @@ class Event
/**
* Get context for this event.
*
* @param string $key
*
* @param string $key
* @return null|Document
*/
public function getContext(string $key): ?Document
@@ -204,7 +223,8 @@ class Event
/**
* Set class used for this event.
* @param string $class
*
* @param string $class
* @return self
*/
public function setClass(string $class): self
@@ -227,8 +247,8 @@ class Event
/**
* Set param of event.
*
* @param string $key
* @param mixed $value
* @param string $key
* @param mixed $value
* @return self
*/
public function setParam(string $key, mixed $value): self
@@ -241,7 +261,7 @@ class Event
/**
* Get param of event.
*
* @param string $key
* @param string $key
* @return mixed
*/
public function getParam(string $key): mixed
@@ -263,6 +283,7 @@ class Event
* Execute Event.
*
* @return string|bool
*
* @throws InvalidArgumentException
*/
public function trigger(): string|bool
@@ -276,7 +297,7 @@ class Event
'user' => $this->user,
'payload' => $this->payload,
'context' => $this->context,
'events' => Event::generateEvents($this->getEvent(), $this->getParams())
'events' => Event::generateEvents($this->getEvent(), $this->getParams()),
]);
}
@@ -295,7 +316,7 @@ class Event
/**
* Parses event pattern and returns the parts in their respective section.
*
* @param string $pattern
* @param string $pattern
* @return array
*/
public static function parseEventPattern(string $pattern): array
@@ -324,13 +345,13 @@ class Event
}
}
if ($hasSubResource && !$hasSubSubResource) {
if ($hasSubResource && ! $hasSubSubResource) {
if ($count === 6) {
$attribute = $parts[5];
}
}
if (!$hasSubResource) {
if (! $hasSubResource) {
if ($count === 4) {
$attribute = $parts[3];
}
@@ -342,7 +363,7 @@ class Event
$subSubResource ??= false;
$attribute ??= false;
$action = match (true) {
!$hasSubResource && $count > 2 => $parts[2],
! $hasSubResource && $count > 2 => $parts[2],
$hasSubSubResource => $parts[6] ?? false,
$hasSubResource && $count > 4 => $parts[4],
default => false
@@ -363,9 +384,10 @@ class Event
/**
* Generates all possible events from a pattern.
*
* @param string $pattern
* @param array $params
* @param string $pattern
* @param array $params
* @return array
*
* @throws \InvalidArgumentException
*/
public static function generateEvents(string $pattern, array $params = []): array
@@ -386,15 +408,15 @@ class Event
$action = $parsed['action'];
$attribute = $parsed['attribute'];
if ($resource && !\in_array(\trim($resource, "\[\]"), $paramKeys)) {
if ($resource && ! \in_array(\trim($resource, "\[\]"), $paramKeys)) {
throw new InvalidArgumentException("{$resource} is missing from the params.");
}
if ($subResource && !\in_array(\trim($subResource, "\[\]"), $paramKeys)) {
if ($subResource && ! \in_array(\trim($subResource, "\[\]"), $paramKeys)) {
throw new InvalidArgumentException("{$subResource} is missing from the params.");
}
if ($subSubResource && !\in_array(\trim($subSubResource, "\[\]"), $paramKeys)) {
if ($subSubResource && ! \in_array(\trim($subSubResource, "\[\]"), $paramKeys)) {
throw new InvalidArgumentException("{$subSubResource} is missing from the params.");
}
@@ -448,9 +470,9 @@ class Event
if ($subCurrent === $current || $subCurrent === $key) {
continue;
}
$filtered1 = \array_filter($paramKeys, fn(string $k) => $k === $subCurrent);
$filtered1 = \array_filter($paramKeys, fn (string $k) => $k === $subCurrent);
$events[] = \str_replace($paramKeys, $paramValues, \str_replace($filtered1, '*', $eventPattern));
$filtered2 = \array_filter($paramKeys, fn(string $k) => $k === $current);
$filtered2 = \array_filter($paramKeys, fn (string $k) => $k === $current);
$events[] = \str_replace($paramKeys, $paramValues, \str_replace($filtered2, '*', \str_replace($filtered1, '*', $eventPattern)));
$events[] = \str_replace($paramKeys, $paramValues, \str_replace($filtered2, '*', $eventPattern));
}
@@ -458,7 +480,7 @@ class Event
if ($current === $key) {
continue;
}
$filtered = \array_filter($paramKeys, fn(string $k) => $k === $current);
$filtered = \array_filter($paramKeys, fn (string $k) => $k === $current);
$events[] = \str_replace($paramKeys, $paramValues, \str_replace($filtered, '*', $eventPattern));
}
}
+12 -8
View File
@@ -9,9 +9,13 @@ use Utopia\Queue\Connection;
class Func extends Event
{
protected string $jwt = '';
protected string $type = '';
protected string $data = '';
protected ?Document $function = null;
protected ?Document $execution = null;
public function __construct(protected Connection $connection)
@@ -22,7 +26,7 @@ class Func extends Event
/**
* Sets function document for the function event.
*
* @param Document $function
* @param Document $function
* @return self
*/
public function setFunction(Document $function): self
@@ -45,7 +49,7 @@ class Func extends Event
/**
* Sets execution for the function event.
*
* @param Document $execution
* @param Document $execution
* @return self
*/
public function setExecution(Document $execution): self
@@ -68,7 +72,7 @@ class Func extends Event
/**
* Sets type for the function event.
*
* @param string $type Can be `schedule`, `event` or `http`.
* @param string $type Can be `schedule`, `event` or `http`.
* @return self
*/
public function setType(string $type): self
@@ -91,7 +95,7 @@ class Func extends Event
/**
* Sets custom data for the function event.
*
* @param string $data
* @param string $data
* @return self
*/
public function setData(string $data): self
@@ -114,7 +118,7 @@ class Func extends Event
/**
* Sets JWT for the function event.
*
* @param string $jwt
* @param string $jwt
* @return self
*/
public function setJWT(string $jwt): self
@@ -138,6 +142,7 @@ class Func extends Event
* Executes the function event and sends it to the functions worker.
*
* @return string|bool
*
* @throws \InvalidArgumentException
*/
public function trigger(): string|bool
@@ -166,10 +171,8 @@ class Func extends Event
/**
* Generate a function event from a base event
*
* @param Event $event
*
* @param Event $event
* @return self
*
*/
public function from(Event $event): self
{
@@ -178,6 +181,7 @@ class Func extends Event
$this->payload = $event->getPayload();
$this->event = $event->getEvent();
$this->params = $event->getParams();
return $this;
}
}
+24 -13
View File
@@ -3,15 +3,19 @@
namespace Appwrite\Event;
use Resque;
use Utopia\Database\Document;
class Mail extends Event
{
protected string $recipient = '';
protected string $from = '';
protected string $name = '';
protected string $subject = '';
protected string $body = '';
protected array $smtp = [];
public function __construct()
@@ -22,7 +26,7 @@ class Mail extends Event
/**
* Sets subject for the mail event.
*
* @param string $subject
* @param string $subject
* @return self
*/
public function setSubject(string $subject): self
@@ -45,7 +49,7 @@ class Mail extends Event
/**
* Sets recipient for the mail event.
*
* @param string $recipient
* @param string $recipient
* @return self
*/
public function setRecipient(string $recipient): self
@@ -68,7 +72,7 @@ class Mail extends Event
/**
* Sets from for the mail event.
*
* @param string $from
* @param string $from
* @return self
*/
public function setFrom(string $from): self
@@ -91,7 +95,7 @@ class Mail extends Event
/**
* Sets body for the mail event.
*
* @param string $body
* @param string $body
* @return self
*/
public function setBody(string $body): self
@@ -114,7 +118,7 @@ class Mail extends Event
/**
* Sets name for the mail event.
*
* @param string $name
* @param string $name
* @return self
*/
public function setName(string $name): self
@@ -137,12 +141,13 @@ class Mail extends Event
/**
* Set SMTP Host
*
* @param string $host
* @param string $host
* @return self
*/
public function setSmtpHost(string $host): self
{
$this->smtp['host'] = $host;
return $this;
}
@@ -155,54 +160,59 @@ class Mail extends Event
public function setSmtpPort(int $port): self
{
$this->smtp['port'] = $port;
return $this;
}
/**
* Set SMTP username
*
* @param string $username
* @param string $username
* @return self
*/
public function setSmtpUsername(string $username): self
{
$this->smtp['username'];
return $this;
}
/**
* Set SMTP password
*
* @param string $password
* @param string $password
* @return self
*/
public function setSmtpPassword(string $password): self
{
$this->smtp['password'];
return $this;
}
/**
* Set SMTP sender email
*
* @param string $senderEmail
* @param string $senderEmail
* @return self
*/
public function setSmtpSenderEmail(string $senderEmail): self
{
$this->smtp['senderEmail'] = $senderEmail;
return $this;
}
/**
* Set SMTP reply to
*
* @param string $replyTo
* @param string $replyTo
* @return self
*/
public function setSmtpReplyTo(string $replyTo): self
{
$this->smtp['replyTo'] = $replyTo;
return $this;
}
@@ -219,7 +229,7 @@ class Mail extends Event
/**
* Get SMTP port
*
* @return integer
* @return int
*/
public function getSmtpPort(): int
{
@@ -270,6 +280,7 @@ class Mail extends Event
* Executes the event and sends it to the mails worker.
*
* @return string|bool
*
* @throws \InvalidArgumentException
*/
public function trigger(): string|bool
@@ -281,7 +292,7 @@ class Mail extends Event
'subject' => $this->subject,
'body' => $this->body,
'smtp' => $this->smtp,
'events' => Event::generateEvents($this->getEvent(), $this->getParams())
'events' => Event::generateEvents($this->getEvent(), $this->getParams()),
]);
}
}
+8 -6
View File
@@ -10,6 +10,7 @@ use Utopia\Database\Document;
class Migration extends Event
{
protected string $type = '';
protected ?Document $migration = null;
public function __construct()
@@ -20,7 +21,7 @@ class Migration extends Event
/**
* Sets migration document for the migration event.
*
* @param Document $migration
* @param Document $migration
* @return self
*/
public function setMigration(Document $migration): self
@@ -43,8 +44,7 @@ class Migration extends Event
/**
* Sets migration type for the migration event.
*
* @param string $type
*
* @param string $type
* @return self
*/
public function setType(string $type): self
@@ -68,6 +68,7 @@ class Migration extends Event
* Executes the migration event and sends it to the migrations worker.
*
* @return string|bool
*
* @throws \InvalidArgumentException
*/
public function trigger(): string|bool
@@ -75,15 +76,16 @@ class Migration extends Event
return Resque::enqueue($this->queue, $this->class, [
'project' => $this->project,
'user' => $this->user,
'migration' => $this->migration
'migration' => $this->migration,
]);
}
/**
* Schedules the migration event and schedules it in the migrations worker queue.
*
* @param \DateTime|int $at
* @param \DateTime|int $at
* @return void
*
* @throws \Resque_Exception
* @throws \ResqueScheduler_InvalidTimestampException
*/
@@ -92,7 +94,7 @@ class Migration extends Event
ResqueScheduler::enqueueAt($at, $this->queue, $this->class, [
'project' => $this->project,
'user' => $this->user,
'migration' => $this->migration
'migration' => $this->migration,
]);
}
}
+5 -3
View File
@@ -7,6 +7,7 @@ use Resque;
class Phone extends Event
{
protected string $recipient = '';
protected string $message = '';
public function __construct()
@@ -17,7 +18,7 @@ class Phone extends Event
/**
* Sets recipient for the messaging event.
*
* @param string $recipient
* @param string $recipient
* @return self
*/
public function setRecipient(string $recipient): self
@@ -40,7 +41,7 @@ class Phone extends Event
/**
* Sets url for the messaging event.
*
* @param string $message
* @param string $message
* @return self
*/
public function setMessage(string $message): self
@@ -64,6 +65,7 @@ class Phone extends Event
* Executes the event and sends it to the messaging worker.
*
* @return string|bool
*
* @throws \InvalidArgumentException
*/
public function trigger(): string|bool
@@ -74,7 +76,7 @@ class Phone extends Event
'payload' => $this->payload,
'recipient' => $this->recipient,
'message' => $this->message,
'events' => Event::generateEvents($this->getEvent(), $this->getParams())
'events' => Event::generateEvents($this->getEvent(), $this->getParams()),
]);
}
}
+7 -6
View File
@@ -2,14 +2,15 @@
namespace Appwrite\Event;
use Utopia\Database\Document;
use Utopia\Queue\Client;
use Utopia\Queue\Connection;
use Utopia\Database\Document;
class Usage extends Event
{
protected array $metrics = [];
protected array $reduce = [];
protected array $reduce = [];
public function __construct(protected Connection $connection)
{
@@ -19,7 +20,7 @@ class Usage extends Event
/**
* Add reduce.
*
* @param Document $document
* @param Document $document
* @return self
*/
public function addReduce(Document $document): self
@@ -32,8 +33,8 @@ class Usage extends Event
/**
* Add metric.
*
* @param string $key
* @param int $value
* @param string $key
* @param int $value
* @return self
*/
public function addMetric(string $key, int $value): self
@@ -57,7 +58,7 @@ class Usage extends Event
return $client->enqueue([
'project' => $this->getProject(),
'reduce' => $this->reduce,
'reduce' => $this->reduce,
'metrics' => $this->metrics,
]);
}
+12 -12
View File
@@ -27,8 +27,7 @@ class Event extends Validator
/**
* Is valid.
*
* @param mixed $value
*
* @param mixed $value
* @return bool
*/
public function isValid($value): bool
@@ -48,6 +47,7 @@ class Event extends Validator
if ($type == 'functions') {
$this->message = 'Triggering a function on a function event is not allowed.';
return false;
}
@@ -55,7 +55,7 @@ class Event extends Validator
$hasSubResource = $count > 3 && ($events[$type]['$resource'] ?? false) && ($events[$type][$parts[2]]['$resource'] ?? false);
$hasSubSubResource = $count > 5 && $hasSubResource && ($events[$type][$parts[2]][$parts[4]]['$resource'] ?? false);
if (!$type || !$resource) {
if (! $type || ! $resource) {
return false;
}
@@ -72,13 +72,13 @@ class Event extends Validator
}
}
if ($hasSubResource && !$hasSubSubResource) {
if ($hasSubResource && ! $hasSubSubResource) {
if ($count === 6) {
$attribute = $parts[5];
}
}
if (!$hasSubResource) {
if (! $hasSubResource) {
if ($count === 4) {
$attribute = $parts[3];
}
@@ -91,36 +91,36 @@ class Event extends Validator
$attribute ??= false;
$action = match (true) {
!$hasSubResource && $count > 2 => $parts[2],
! $hasSubResource && $count > 2 => $parts[2],
$hasSubSubResource => $parts[6] ?? false,
$hasSubResource && $count > 4 => $parts[4],
default => false
};
if (!\array_key_exists($type, $events)) {
if (! \array_key_exists($type, $events)) {
return false;
}
if ($subType) {
if ($action && !\array_key_exists($action, $events[$type][$subType])) {
if ($action && ! \array_key_exists($action, $events[$type][$subType])) {
return false;
}
if (!($subResource) || !\array_key_exists($subType, $events[$type])) {
if (! ($subResource) || ! \array_key_exists($subType, $events[$type])) {
return false;
}
} else {
if ($action && !\array_key_exists($action, $events[$type])) {
if ($action && ! \array_key_exists($action, $events[$type])) {
return false;
}
}
if ($attribute) {
if (($subType)) {
if (!\array_key_exists($attribute, $events[$type][$subType][$action])) {
if (! \array_key_exists($attribute, $events[$type][$subType][$action])) {
return false;
}
} else {
if (!\array_key_exists($attribute, $events[$type][$action])) {
if (! \array_key_exists($attribute, $events[$type][$action])) {
return false;
}
}
+239 -132
View File
@@ -36,187 +36,295 @@ class Exception extends \Exception
*/
/** General */
public const GENERAL_UNKNOWN = 'general_unknown';
public const GENERAL_MOCK = 'general_mock';
public const GENERAL_ACCESS_FORBIDDEN = 'general_access_forbidden';
public const GENERAL_UNKNOWN_ORIGIN = 'general_unknown_origin';
public const GENERAL_SERVICE_DISABLED = 'general_service_disabled';
public const GENERAL_UNAUTHORIZED_SCOPE = 'general_unauthorized_scope';
public const GENERAL_RATE_LIMIT_EXCEEDED = 'general_rate_limit_exceeded';
public const GENERAL_SMTP_DISABLED = 'general_smtp_disabled';
public const GENERAL_PHONE_DISABLED = 'general_phone_disabled';
public const GENERAL_ARGUMENT_INVALID = 'general_argument_invalid';
public const GENERAL_QUERY_LIMIT_EXCEEDED = 'general_query_limit_exceeded';
public const GENERAL_QUERY_INVALID = 'general_query_invalid';
public const GENERAL_ROUTE_NOT_FOUND = 'general_route_not_found';
public const GENERAL_CURSOR_NOT_FOUND = 'general_cursor_not_found';
public const GENERAL_SERVER_ERROR = 'general_server_error';
public const GENERAL_PROTOCOL_UNSUPPORTED = 'general_protocol_unsupported';
public const GENERAL_CODES_DISABLED = 'general_codes_disabled';
public const GENERAL_USAGE_DISABLED = 'general_usage_disabled';
public const GENERAL_UNKNOWN = 'general_unknown';
public const GENERAL_MOCK = 'general_mock';
public const GENERAL_ACCESS_FORBIDDEN = 'general_access_forbidden';
public const GENERAL_UNKNOWN_ORIGIN = 'general_unknown_origin';
public const GENERAL_SERVICE_DISABLED = 'general_service_disabled';
public const GENERAL_UNAUTHORIZED_SCOPE = 'general_unauthorized_scope';
public const GENERAL_RATE_LIMIT_EXCEEDED = 'general_rate_limit_exceeded';
public const GENERAL_SMTP_DISABLED = 'general_smtp_disabled';
public const GENERAL_PHONE_DISABLED = 'general_phone_disabled';
public const GENERAL_ARGUMENT_INVALID = 'general_argument_invalid';
public const GENERAL_QUERY_LIMIT_EXCEEDED = 'general_query_limit_exceeded';
public const GENERAL_QUERY_INVALID = 'general_query_invalid';
public const GENERAL_ROUTE_NOT_FOUND = 'general_route_not_found';
public const GENERAL_CURSOR_NOT_FOUND = 'general_cursor_not_found';
public const GENERAL_SERVER_ERROR = 'general_server_error';
public const GENERAL_PROTOCOL_UNSUPPORTED = 'general_protocol_unsupported';
public const GENERAL_CODES_DISABLED = 'general_codes_disabled';
public const GENERAL_USAGE_DISABLED = 'general_usage_disabled';
/** Users */
public const USER_COUNT_EXCEEDED = 'user_count_exceeded';
public const USER_JWT_INVALID = 'user_jwt_invalid';
public const USER_ALREADY_EXISTS = 'user_already_exists';
public const USER_BLOCKED = 'user_blocked';
public const USER_INVALID_TOKEN = 'user_invalid_token';
public const USER_PASSWORD_RESET_REQUIRED = 'user_password_reset_required';
public const USER_EMAIL_NOT_WHITELISTED = 'user_email_not_whitelisted';
public const USER_IP_NOT_WHITELISTED = 'user_ip_not_whitelisted';
public const USER_INVALID_CODE = 'user_invalid_code';
public const USER_INVALID_CREDENTIALS = 'user_invalid_credentials';
public const USER_COUNT_EXCEEDED = 'user_count_exceeded';
public const USER_JWT_INVALID = 'user_jwt_invalid';
public const USER_ALREADY_EXISTS = 'user_already_exists';
public const USER_BLOCKED = 'user_blocked';
public const USER_INVALID_TOKEN = 'user_invalid_token';
public const USER_PASSWORD_RESET_REQUIRED = 'user_password_reset_required';
public const USER_EMAIL_NOT_WHITELISTED = 'user_email_not_whitelisted';
public const USER_IP_NOT_WHITELISTED = 'user_ip_not_whitelisted';
public const USER_INVALID_CODE = 'user_invalid_code';
public const USER_INVALID_CREDENTIALS = 'user_invalid_credentials';
public const USER_ANONYMOUS_CONSOLE_PROHIBITED = 'user_anonymous_console_prohibited';
public const USER_SESSION_ALREADY_EXISTS = 'user_session_already_exists';
public const USER_NOT_FOUND = 'user_not_found';
public const USER_PASSWORD_RECENTLY_USED = 'password_recently_used';
public const USER_PASSWORD_PERSONAL_DATA = 'password_personal_data';
public const USER_EMAIL_ALREADY_EXISTS = 'user_email_already_exists';
public const USER_PASSWORD_MISMATCH = 'user_password_mismatch';
public const USER_SESSION_NOT_FOUND = 'user_session_not_found';
public const USER_IDENTITY_NOT_FOUND = 'user_identity_not_found';
public const USER_UNAUTHORIZED = 'user_unauthorized';
public const USER_AUTH_METHOD_UNSUPPORTED = 'user_auth_method_unsupported';
public const USER_PHONE_ALREADY_EXISTS = 'user_phone_already_exists';
public const USER_PHONE_NOT_FOUND = 'user_phone_not_found';
public const USER_MISSING_ID = 'user_missing_id';
public const USER_OAUTH2_BAD_REQUEST = 'user_oauth2_bad_request';
public const USER_OAUTH2_UNAUTHORIZED = 'user_oauth2_unauthorized';
public const USER_OAUTH2_PROVIDER_ERROR = 'user_oauth2_provider_error';
public const USER_TARGET_NOT_FOUND = 'user_target_not_found';
public const USER_TARGET_ALREADY_EXISTS = 'user_target_already_exists';
public const USER_SESSION_ALREADY_EXISTS = 'user_session_already_exists';
public const USER_NOT_FOUND = 'user_not_found';
public const USER_PASSWORD_RECENTLY_USED = 'password_recently_used';
public const USER_PASSWORD_PERSONAL_DATA = 'password_personal_data';
public const USER_EMAIL_ALREADY_EXISTS = 'user_email_already_exists';
public const USER_PASSWORD_MISMATCH = 'user_password_mismatch';
public const USER_SESSION_NOT_FOUND = 'user_session_not_found';
public const USER_IDENTITY_NOT_FOUND = 'user_identity_not_found';
public const USER_UNAUTHORIZED = 'user_unauthorized';
public const USER_AUTH_METHOD_UNSUPPORTED = 'user_auth_method_unsupported';
public const USER_PHONE_ALREADY_EXISTS = 'user_phone_already_exists';
public const USER_PHONE_NOT_FOUND = 'user_phone_not_found';
public const USER_MISSING_ID = 'user_missing_id';
public const USER_OAUTH2_BAD_REQUEST = 'user_oauth2_bad_request';
public const USER_OAUTH2_UNAUTHORIZED = 'user_oauth2_unauthorized';
public const USER_OAUTH2_PROVIDER_ERROR = 'user_oauth2_provider_error';
public const USER_TARGET_NOT_FOUND = 'user_target_not_found';
public const USER_TARGET_ALREADY_EXISTS = 'user_target_already_exists';
/** Teams */
public const TEAM_NOT_FOUND = 'team_not_found';
public const TEAM_INVITE_ALREADY_EXISTS = 'team_invite_already_exists';
public const TEAM_INVITE_NOT_FOUND = 'team_invite_not_found';
public const TEAM_INVALID_SECRET = 'team_invalid_secret';
public const TEAM_MEMBERSHIP_MISMATCH = 'team_membership_mismatch';
public const TEAM_INVITE_MISMATCH = 'team_invite_mismatch';
public const TEAM_ALREADY_EXISTS = 'team_already_exists';
public const TEAM_NOT_FOUND = 'team_not_found';
public const TEAM_INVITE_ALREADY_EXISTS = 'team_invite_already_exists';
public const TEAM_INVITE_NOT_FOUND = 'team_invite_not_found';
public const TEAM_INVALID_SECRET = 'team_invalid_secret';
public const TEAM_MEMBERSHIP_MISMATCH = 'team_membership_mismatch';
public const TEAM_INVITE_MISMATCH = 'team_invite_mismatch';
public const TEAM_ALREADY_EXISTS = 'team_already_exists';
/** Membership */
public const MEMBERSHIP_NOT_FOUND = 'membership_not_found';
public const MEMBERSHIP_ALREADY_CONFIRMED = 'membership_already_confirmed';
public const MEMBERSHIP_NOT_FOUND = 'membership_not_found';
public const MEMBERSHIP_ALREADY_CONFIRMED = 'membership_already_confirmed';
/** Avatars */
public const AVATAR_SET_NOT_FOUND = 'avatar_set_not_found';
public const AVATAR_NOT_FOUND = 'avatar_not_found';
public const AVATAR_IMAGE_NOT_FOUND = 'avatar_image_not_found';
public const AVATAR_REMOTE_URL_FAILED = 'avatar_remote_url_failed';
public const AVATAR_ICON_NOT_FOUND = 'avatar_icon_not_found';
public const AVATAR_SET_NOT_FOUND = 'avatar_set_not_found';
public const AVATAR_NOT_FOUND = 'avatar_not_found';
public const AVATAR_IMAGE_NOT_FOUND = 'avatar_image_not_found';
public const AVATAR_REMOTE_URL_FAILED = 'avatar_remote_url_failed';
public const AVATAR_ICON_NOT_FOUND = 'avatar_icon_not_found';
/** Storage */
public const STORAGE_FILE_NOT_FOUND = 'storage_file_not_found';
public const STORAGE_DEVICE_NOT_FOUND = 'storage_device_not_found';
public const STORAGE_FILE_EMPTY = 'storage_file_empty';
public const STORAGE_FILE_TYPE_UNSUPPORTED = 'storage_file_type_unsupported';
public const STORAGE_INVALID_FILE_SIZE = 'storage_invalid_file_size';
public const STORAGE_INVALID_FILE = 'storage_invalid_file';
public const STORAGE_BUCKET_ALREADY_EXISTS = 'storage_bucket_already_exists';
public const STORAGE_BUCKET_NOT_FOUND = 'storage_bucket_not_found';
public const STORAGE_INVALID_CONTENT_RANGE = 'storage_invalid_content_range';
public const STORAGE_INVALID_RANGE = 'storage_invalid_range';
public const STORAGE_INVALID_APPWRITE_ID = 'storage_invalid_appwrite_id';
public const STORAGE_FILE_NOT_FOUND = 'storage_file_not_found';
public const STORAGE_DEVICE_NOT_FOUND = 'storage_device_not_found';
public const STORAGE_FILE_EMPTY = 'storage_file_empty';
public const STORAGE_FILE_TYPE_UNSUPPORTED = 'storage_file_type_unsupported';
public const STORAGE_INVALID_FILE_SIZE = 'storage_invalid_file_size';
public const STORAGE_INVALID_FILE = 'storage_invalid_file';
public const STORAGE_BUCKET_ALREADY_EXISTS = 'storage_bucket_already_exists';
public const STORAGE_BUCKET_NOT_FOUND = 'storage_bucket_not_found';
public const STORAGE_INVALID_CONTENT_RANGE = 'storage_invalid_content_range';
public const STORAGE_INVALID_RANGE = 'storage_invalid_range';
public const STORAGE_INVALID_APPWRITE_ID = 'storage_invalid_appwrite_id';
/** Functions */
public const FUNCTION_NOT_FOUND = 'function_not_found';
public const FUNCTION_RUNTIME_UNSUPPORTED = 'function_runtime_unsupported';
public const FUNCTION_NOT_FOUND = 'function_not_found';
public const FUNCTION_RUNTIME_UNSUPPORTED = 'function_runtime_unsupported';
/** Deployments */
public const DEPLOYMENT_NOT_FOUND = 'deployment_not_found';
public const DEPLOYMENT_NOT_FOUND = 'deployment_not_found';
/** Builds */
public const BUILD_NOT_FOUND = 'build_not_found';
public const BUILD_NOT_READY = 'build_not_ready';
public const BUILD_IN_PROGRESS = 'build_in_progress';
public const BUILD_NOT_FOUND = 'build_not_found';
public const BUILD_NOT_READY = 'build_not_ready';
public const BUILD_IN_PROGRESS = 'build_in_progress';
/** Execution */
public const EXECUTION_NOT_FOUND = 'execution_not_found';
public const EXECUTION_NOT_FOUND = 'execution_not_found';
/** Databases */
public const DATABASE_NOT_FOUND = 'database_not_found';
public const DATABASE_ALREADY_EXISTS = 'database_already_exists';
public const DATABASE_NOT_FOUND = 'database_not_found';
public const DATABASE_ALREADY_EXISTS = 'database_already_exists';
/** Collections */
public const COLLECTION_NOT_FOUND = 'collection_not_found';
public const COLLECTION_ALREADY_EXISTS = 'collection_already_exists';
public const COLLECTION_LIMIT_EXCEEDED = 'collection_limit_exceeded';
public const COLLECTION_NOT_FOUND = 'collection_not_found';
public const COLLECTION_ALREADY_EXISTS = 'collection_already_exists';
public const COLLECTION_LIMIT_EXCEEDED = 'collection_limit_exceeded';
/** Documents */
public const DOCUMENT_NOT_FOUND = 'document_not_found';
public const DOCUMENT_INVALID_STRUCTURE = 'document_invalid_structure';
public const DOCUMENT_MISSING_DATA = 'document_missing_data';
public const DOCUMENT_MISSING_PAYLOAD = 'document_missing_payload';
public const DOCUMENT_ALREADY_EXISTS = 'document_already_exists';
public const DOCUMENT_UPDATE_CONFLICT = 'document_update_conflict';
public const DOCUMENT_DELETE_RESTRICTED = 'document_delete_restricted';
public const DOCUMENT_NOT_FOUND = 'document_not_found';
public const DOCUMENT_INVALID_STRUCTURE = 'document_invalid_structure';
public const DOCUMENT_MISSING_DATA = 'document_missing_data';
public const DOCUMENT_MISSING_PAYLOAD = 'document_missing_payload';
public const DOCUMENT_ALREADY_EXISTS = 'document_already_exists';
public const DOCUMENT_UPDATE_CONFLICT = 'document_update_conflict';
public const DOCUMENT_DELETE_RESTRICTED = 'document_delete_restricted';
/** Attribute */
public const ATTRIBUTE_NOT_FOUND = 'attribute_not_found';
public const ATTRIBUTE_UNKNOWN = 'attribute_unknown';
public const ATTRIBUTE_NOT_AVAILABLE = 'attribute_not_available';
public const ATTRIBUTE_FORMAT_UNSUPPORTED = 'attribute_format_unsupported';
public const ATTRIBUTE_DEFAULT_UNSUPPORTED = 'attribute_default_unsupported';
public const ATTRIBUTE_ALREADY_EXISTS = 'attribute_already_exists';
public const ATTRIBUTE_LIMIT_EXCEEDED = 'attribute_limit_exceeded';
public const ATTRIBUTE_VALUE_INVALID = 'attribute_value_invalid';
public const ATTRIBUTE_TYPE_INVALID = 'attribute_type_invalid';
public const ATTRIBUTE_NOT_FOUND = 'attribute_not_found';
public const ATTRIBUTE_UNKNOWN = 'attribute_unknown';
public const ATTRIBUTE_NOT_AVAILABLE = 'attribute_not_available';
public const ATTRIBUTE_FORMAT_UNSUPPORTED = 'attribute_format_unsupported';
public const ATTRIBUTE_DEFAULT_UNSUPPORTED = 'attribute_default_unsupported';
public const ATTRIBUTE_ALREADY_EXISTS = 'attribute_already_exists';
public const ATTRIBUTE_LIMIT_EXCEEDED = 'attribute_limit_exceeded';
public const ATTRIBUTE_VALUE_INVALID = 'attribute_value_invalid';
public const ATTRIBUTE_TYPE_INVALID = 'attribute_type_invalid';
/** Indexes */
public const INDEX_NOT_FOUND = 'index_not_found';
public const INDEX_LIMIT_EXCEEDED = 'index_limit_exceeded';
public const INDEX_ALREADY_EXISTS = 'index_already_exists';
public const INDEX_INVALID = 'index_invalid';
public const INDEX_NOT_FOUND = 'index_not_found';
public const INDEX_LIMIT_EXCEEDED = 'index_limit_exceeded';
public const INDEX_ALREADY_EXISTS = 'index_already_exists';
public const INDEX_INVALID = 'index_invalid';
/** Projects */
public const PROJECT_NOT_FOUND = 'project_not_found';
public const PROJECT_UNKNOWN = 'project_unknown';
public const PROJECT_PROVIDER_DISABLED = 'project_provider_disabled';
public const PROJECT_PROVIDER_UNSUPPORTED = 'project_provider_unsupported';
public const PROJECT_ALREADY_EXISTS = 'project_already_exists';
public const PROJECT_INVALID_SUCCESS_URL = 'project_invalid_success_url';
public const PROJECT_INVALID_FAILURE_URL = 'project_invalid_failure_url';
public const PROJECT_RESERVED_PROJECT = 'project_reserved_project';
public const PROJECT_KEY_EXPIRED = 'project_key_expired';
public const PROJECT_NOT_FOUND = 'project_not_found';
public const PROJECT_SMTP_CONFIG_INVALID = 'project_smtp_config_invalid';
public const PROJECT_UNKNOWN = 'project_unknown';
public const PROJECT_PROVIDER_DISABLED = 'project_provider_disabled';
public const PROJECT_PROVIDER_UNSUPPORTED = 'project_provider_unsupported';
public const PROJECT_ALREADY_EXISTS = 'project_already_exists';
public const PROJECT_INVALID_SUCCESS_URL = 'project_invalid_success_url';
public const PROJECT_INVALID_FAILURE_URL = 'project_invalid_failure_url';
public const PROJECT_RESERVED_PROJECT = 'project_reserved_project';
public const PROJECT_KEY_EXPIRED = 'project_key_expired';
public const PROJECT_SMTP_CONFIG_INVALID = 'project_smtp_config_invalid';
public const PROJECT_TEMPLATE_DEFAULT_DELETION = 'project_template_default_deletion';
/** Webhooks */
public const WEBHOOK_NOT_FOUND = 'webhook_not_found';
public const WEBHOOK_NOT_FOUND = 'webhook_not_found';
/** Keys */
public const KEY_NOT_FOUND = 'key_not_found';
public const KEY_NOT_FOUND = 'key_not_found';
/** Variables */
public const VARIABLE_NOT_FOUND = 'variable_not_found';
public const VARIABLE_ALREADY_EXISTS = 'variable_already_exists';
public const VARIABLE_NOT_FOUND = 'variable_not_found';
public const VARIABLE_ALREADY_EXISTS = 'variable_already_exists';
/** Platform */
public const PLATFORM_NOT_FOUND = 'platform_not_found';
public const PLATFORM_NOT_FOUND = 'platform_not_found';
/** Domain */
public const DOMAIN_NOT_FOUND = 'domain_not_found';
public const DOMAIN_ALREADY_EXISTS = 'domain_already_exists';
public const DOMAIN_FORBIDDEN = 'domain_forbidden';
public const DOMAIN_VERIFICATION_FAILED = 'domain_verification_failed';
public const DOMAIN_TARGET_INVALID = 'domain_target_invalid';
public const DOMAIN_NOT_FOUND = 'domain_not_found';
public const DOMAIN_ALREADY_EXISTS = 'domain_already_exists';
public const DOMAIN_FORBIDDEN = 'domain_forbidden';
public const DOMAIN_VERIFICATION_FAILED = 'domain_verification_failed';
public const DOMAIN_TARGET_INVALID = 'domain_target_invalid';
/** GraphqQL */
public const GRAPHQL_NO_QUERY = 'graphql_no_query';
public const GRAPHQL_TOO_MANY_QUERIES = 'graphql_too_many_queries';
public const GRAPHQL_NO_QUERY = 'graphql_no_query';
public const GRAPHQL_TOO_MANY_QUERIES = 'graphql_too_many_queries';
/** Migrations */
public const MIGRATION_NOT_FOUND = 'migration_not_found';
public const MIGRATION_ALREADY_EXISTS = 'migration_already_exists';
public const MIGRATION_IN_PROGRESS = 'migration_in_progress';
public const MIGRATION_NOT_FOUND = 'migration_not_found';
public const MIGRATION_ALREADY_EXISTS = 'migration_already_exists';
public const MIGRATION_IN_PROGRESS = 'migration_in_progress';
/** Provider */
public const PROVIDER_NOT_FOUND = 'provider_not_found';
public const PROVIDER_INCORRECT_TYPE = 'provider_incorrect_type';
public const PROVIDER_NOT_FOUND = 'provider_not_found';
public const PROVIDER_INCORRECT_TYPE = 'provider_incorrect_type';
protected $type = '';
protected $errors = [];
public function __construct(string $type = Exception::GENERAL_UNKNOWN, string $message = null, int $code = null, \Throwable $previous = null)
@@ -248,8 +356,7 @@ class Exception extends \Exception
/**
* Set the type of the exception.
*
* @param string $type
*
* @param string $type
* @return void
*/
public function setType(string $type): void
+11 -10
View File
@@ -22,14 +22,15 @@ abstract class Adapter implements PromiseAdapter
/**
* Converts a {@see Promise} into a {@see GQLPromise}
*
* @param mixed $thenable
* @param mixed $thenable
* @return GQLPromise
*
* @throws \Exception
*/
public function convertThenable(mixed $thenable): GQLPromise
{
if (!$thenable instanceof Promise) {
throw new \Exception('Expected instance of Promise got: ' . \gettype($thenable));
if (! $thenable instanceof Promise) {
throw new \Exception('Expected instance of Promise got: '.\gettype($thenable));
}
return new GQLPromise($thenable, $this);
@@ -38,9 +39,9 @@ abstract class Adapter implements PromiseAdapter
/**
* Returns a promise that resolves when the passed in promise resolves.
*
* @param GQLPromise $promise
* @param callable|null $onFulfilled
* @param callable|null $onRejected
* @param GQLPromise $promise
* @param callable|null $onFulfilled
* @param callable|null $onRejected
* @return GQLPromise
*/
public function then(
@@ -57,7 +58,7 @@ abstract class Adapter implements PromiseAdapter
/**
* Create a new promise with the given resolver function.
*
* @param callable $resolver
* @param callable $resolver
* @return GQLPromise
*/
abstract public function create(callable $resolver): GQLPromise;
@@ -65,7 +66,7 @@ abstract class Adapter implements PromiseAdapter
/**
* Create a new promise that is fulfilled with the given value.
*
* @param mixed $value
* @param mixed $value
* @return GQLPromise
*/
abstract public function createFulfilled(mixed $value = null): GQLPromise;
@@ -73,7 +74,7 @@ abstract class Adapter implements PromiseAdapter
/**
* Create a new promise that is rejected with the given reason.
*
* @param mixed $reason
* @param mixed $reason
* @return GQLPromise
*/
abstract public function createRejected(mixed $reason): GQLPromise;
@@ -81,7 +82,7 @@ abstract class Adapter implements PromiseAdapter
/**
* Create a new promise that resolves when all passed in promises resolve.
*
* @param array $promisesOrValues
* @param array $promisesOrValues
* @return GQLPromise
*/
abstract public function all(array $promisesOrValues): GQLPromise;
+69 -60
View File
@@ -15,28 +15,28 @@ class Resolvers
/**
* Create a resolver for a given API {@see Route}.
*
* @param App $utopia
* @param ?Route $route
* @param App $utopia
* @param ?Route $route
* @return callable
*/
public static function api(
App $utopia,
?Route $route,
): callable {
return static fn($type, $args, $context, $info) => new Swoole(
function (callable $resolve, callable $reject) use ($utopia, $route, $args, $context, $info) {
): callable
{
return static fn ($type, $args, $context, $info) => new Swoole(
function (callable $resolve, callable $reject) use ($utopia, $route, $args) {
/** @var App $utopia */
/** @var Response $response */
/** @var Request $request */
$utopia = $utopia->getResource('utopia:graphql', true);
$request = $utopia->getResource('request', true);
$response = $utopia->getResource('response', true);
$path = $route->getPath();
foreach ($args as $key => $value) {
if (\str_contains($path, '/:' . $key)) {
$path = \str_replace(':' . $key, $value, $path);
if (\str_contains($path, '/:'.$key)) {
$path = \str_replace(':'.$key, $value, $path);
}
}
@@ -60,10 +60,10 @@ class Resolvers
/**
* Create a resolver for a document in a specified database and collection with a specific method type.
*
* @param App $utopia
* @param string $databaseId
* @param string $collectionId
* @param string $methodType
* @param App $utopia
* @param string $databaseId
* @param string $collectionId
* @param string $methodType
* @return callable
*/
public static function document(
@@ -71,8 +71,9 @@ class Resolvers
string $databaseId,
string $collectionId,
string $methodType,
): callable {
return [self::class, 'document' . \ucfirst($methodType)](
): callable
{
return [self::class, 'document'.\ucfirst($methodType)](
$utopia,
$databaseId,
$collectionId
@@ -82,10 +83,10 @@ class Resolvers
/**
* Create a resolver for getting a document in a specified database and collection.
*
* @param App $utopia
* @param string $databaseId
* @param string $collectionId
* @param callable $url
* @param App $utopia
* @param string $databaseId
* @param string $collectionId
* @param callable $url
* @return callable
*/
public static function documentGet(
@@ -93,9 +94,10 @@ class Resolvers
string $databaseId,
string $collectionId,
callable $url,
): callable {
return static fn($type, $args, $context, $info) => new Swoole(
function (callable $resolve, callable $reject) use ($utopia, $databaseId, $collectionId, $url, $type, $args) {
): callable
{
return static fn ($type, $args, $context, $info) => new Swoole(
function (callable $resolve, callable $reject) use ($utopia, $databaseId, $collectionId, $url, $args) {
$utopia = $utopia->getResource('utopia:graphql', true);
$request = $utopia->getResource('request', true);
$response = $utopia->getResource('response', true);
@@ -111,11 +113,11 @@ class Resolvers
/**
* Create a resolver for listing documents in a specified database and collection.
*
* @param App $utopia
* @param string $databaseId
* @param string $collectionId
* @param callable $url
* @param callable $params
* @param App $utopia
* @param string $databaseId
* @param string $collectionId
* @param callable $url
* @param callable $params
* @return callable
*/
public static function documentList(
@@ -124,9 +126,10 @@ class Resolvers
string $collectionId,
callable $url,
callable $params,
): callable {
return static fn($type, $args, $context, $info) => new Swoole(
function (callable $resolve, callable $reject) use ($utopia, $databaseId, $collectionId, $url, $params, $type, $args) {
): callable
{
return static fn ($type, $args, $context, $info) => new Swoole(
function (callable $resolve, callable $reject) use ($utopia, $databaseId, $collectionId, $url, $params, $args) {
$utopia = $utopia->getResource('utopia:graphql', true);
$request = $utopia->getResource('request', true);
$response = $utopia->getResource('response', true);
@@ -147,11 +150,11 @@ class Resolvers
/**
* Create a resolver for creating a document in a specified database and collection.
*
* @param App $utopia
* @param string $databaseId
* @param string $collectionId
* @param callable $url
* @param callable $params
* @param App $utopia
* @param string $databaseId
* @param string $collectionId
* @param callable $url
* @param callable $params
* @return callable
*/
public static function documentCreate(
@@ -160,9 +163,10 @@ class Resolvers
string $collectionId,
callable $url,
callable $params,
): callable {
return static fn($type, $args, $context, $info) => new Swoole(
function (callable $resolve, callable $reject) use ($utopia, $databaseId, $collectionId, $url, $params, $type, $args) {
): callable
{
return static fn ($type, $args, $context, $info) => new Swoole(
function (callable $resolve, callable $reject) use ($utopia, $databaseId, $collectionId, $url, $params, $args) {
$utopia = $utopia->getResource('utopia:graphql', true);
$request = $utopia->getResource('request', true);
$response = $utopia->getResource('response', true);
@@ -179,11 +183,11 @@ class Resolvers
/**
* Create a resolver for updating a document in a specified database and collection.
*
* @param App $utopia
* @param string $databaseId
* @param string $collectionId
* @param callable $url
* @param callable $params
* @param App $utopia
* @param string $databaseId
* @param string $collectionId
* @param callable $url
* @param callable $params
* @return callable
*/
public static function documentUpdate(
@@ -192,9 +196,10 @@ class Resolvers
string $collectionId,
callable $url,
callable $params,
): callable {
return static fn($type, $args, $context, $info) => new Swoole(
function (callable $resolve, callable $reject) use ($utopia, $databaseId, $collectionId, $url, $params, $type, $args) {
): callable
{
return static fn ($type, $args, $context, $info) => new Swoole(
function (callable $resolve, callable $reject) use ($utopia, $databaseId, $collectionId, $url, $params, $args) {
$utopia = $utopia->getResource('utopia:graphql', true);
$request = $utopia->getResource('request', true);
$response = $utopia->getResource('response', true);
@@ -211,10 +216,10 @@ class Resolvers
/**
* Create a resolver for deleting a document in a specified database and collection.
*
* @param App $utopia
* @param string $databaseId
* @param string $collectionId
* @param callable $url
* @param App $utopia
* @param string $databaseId
* @param string $collectionId
* @param callable $url
* @return callable
*/
public static function documentDelete(
@@ -222,9 +227,10 @@ class Resolvers
string $databaseId,
string $collectionId,
callable $url,
): callable {
return static fn($type, $args, $context, $info) => new Swoole(
function (callable $resolve, callable $reject) use ($utopia, $databaseId, $collectionId, $url, $type, $args) {
): callable
{
return static fn ($type, $args, $context, $info) => new Swoole(
function (callable $resolve, callable $reject) use ($utopia, $databaseId, $collectionId, $url, $args) {
$utopia = $utopia->getResource('utopia:graphql', true);
$request = $utopia->getResource('request', true);
$response = $utopia->getResource('response', true);
@@ -238,14 +244,15 @@ class Resolvers
}
/**
* @param App $utopia
* @param Request $request
* @param Response $response
* @param callable $resolve
* @param callable $reject
* @param callable|null $beforeResolve
* @param callable|null $beforeReject
* @param App $utopia
* @param Request $request
* @param Response $response
* @param callable $resolve
* @param callable $reject
* @param callable|null $beforeResolve
* @param callable|null $beforeReject
* @return void
*
* @throws Exception
*/
private static function resolve(
@@ -263,7 +270,7 @@ class Resolvers
}
$request = clone $request;
$utopia->setResource('request', static fn() => $request);
$utopia->setResource('request', static fn () => $request);
$response->setContentType(Response::CONTENT_TYPE_NULL);
try {
@@ -275,6 +282,7 @@ class Resolvers
$e = $beforeReject($e);
}
$reject($e);
return;
}
@@ -288,6 +296,7 @@ class Resolvers
message: $payload['message'],
code: $response->getStatusCode()
));
return;
}
+35 -33
View File
@@ -13,16 +13,17 @@ use Utopia\Route;
class Schema
{
protected static ?GQLSchema $schema = null;
protected static array $dirty = [];
/**
*
* @param App $utopia
* @param callable $complexity Function to calculate complexity
* @param callable $attributes Function to get attributes
* @param array $urls Array of functions to get urls for specific method types
* @param array $params Array of functions to build parameters for specific method types
* @param App $utopia
* @param callable $complexity Function to calculate complexity
* @param callable $attributes Function to get attributes
* @param array $urls Array of functions to get urls for specific method types
* @param array $params Array of functions to build parameters for specific method types
* @return GQLSchema
*
* @throws Exception
*/
public static function build(
@@ -36,7 +37,7 @@ class Schema
return $utopia;
});
if (!empty(self::$schema)) {
if (! empty(self::$schema)) {
return self::$schema;
}
@@ -67,12 +68,12 @@ class Schema
return static::$schema = new GQLSchema([
'query' => new ObjectType([
'name' => 'Query',
'fields' => $queries
'fields' => $queries,
]),
'mutation' => new ObjectType([
'name' => 'Mutation',
'fields' => $mutations
])
'fields' => $mutations,
]),
]);
}
@@ -80,9 +81,10 @@ class Schema
* This function iterates all API routes and builds a GraphQL
* schema defining types and resolvers for all response models.
*
* @param App $utopia
* @param callable $complexity
* @param App $utopia
* @param callable $complexity
* @return array
*
* @throws Exception
*/
protected static function api(App $utopia, callable $complexity): array
@@ -97,10 +99,9 @@ class Schema
foreach ($utopia->getRoutes() as $routes) {
foreach ($routes as $route) {
/** @var Route $route */
$namespace = $route->getLabel('sdk.namespace', '');
$method = $route->getLabel('sdk.method', '');
$name = $namespace . \ucfirst($method);
$name = $namespace.\ucfirst($method);
if (empty($name)) {
continue;
@@ -126,7 +127,7 @@ class Schema
return [
'query' => $queries,
'mutation' => $mutations
'mutation' => $mutations,
];
}
@@ -134,12 +135,13 @@ class Schema
* Iterates all of a projects attributes and builds GraphQL
* queries and mutations for the collections they make up.
*
* @param App $utopia
* @param callable $complexity
* @param callable $attributes
* @param array $urls
* @param array $params
* @param App $utopia
* @param callable $complexity
* @param callable $attributes
* @param array $urls
* @param array $params
* @return array
*
* @throws \Exception
*/
protected static function collections(
@@ -155,7 +157,7 @@ class Schema
$limit = 1000;
$offset = 0;
while (!empty($attrs = $attributes($limit, $offset))) {
while (! empty($attrs = $attributes($limit, $offset))) {
foreach ($attrs as $attr) {
if ($attr['status'] !== 'available') {
continue;
@@ -182,7 +184,7 @@ class Schema
$objectType = new ObjectType([
'name' => $collectionId,
'fields' => \array_merge(
["_id" => ['type' => Type::string()]],
['_id' => ['type' => Type::string()]],
$attributes
),
]);
@@ -191,7 +193,7 @@ class Schema
Mapper::args('mutate')
);
$queryFields[$collectionId . 'Get'] = [
$queryFields[$collectionId.'Get'] = [
'type' => $objectType,
'args' => Mapper::args('id'),
'resolve' => Resolvers::documentGet(
@@ -199,9 +201,9 @@ class Schema
$databaseId,
$collectionId,
$urls['get'],
)
),
];
$queryFields[$collectionId . 'List'] = [
$queryFields[$collectionId.'List'] = [
'type' => Type::listOf($objectType),
'args' => Mapper::args('list'),
'resolve' => Resolvers::documentList(
@@ -214,7 +216,7 @@ class Schema
'complexity' => $complexity,
];
$mutationFields[$collectionId . 'Create'] = [
$mutationFields[$collectionId.'Create'] = [
'type' => $objectType,
'args' => $attributes,
'resolve' => Resolvers::documentCreate(
@@ -223,14 +225,14 @@ class Schema
$collectionId,
$urls['create'],
$params['create'],
)
),
];
$mutationFields[$collectionId . 'Update'] = [
$mutationFields[$collectionId.'Update'] = [
'type' => $objectType,
'args' => \array_merge(
Mapper::args('id'),
\array_map(
fn($attr) => $attr['type'] = Type::getNullableType($attr['type']),
fn ($attr) => $attr['type'] = Type::getNullableType($attr['type']),
$attributes
)
),
@@ -240,9 +242,9 @@ class Schema
$collectionId,
$urls['update'],
$params['update'],
)
),
];
$mutationFields[$collectionId . 'Delete'] = [
$mutationFields[$collectionId.'Delete'] = [
'type' => Mapper::model('none'),
'args' => Mapper::args('id'),
'resolve' => Resolvers::documentDelete(
@@ -250,7 +252,7 @@ class Schema
$databaseId,
$collectionId,
$urls['delete'],
)
),
];
}
$offset += $limit;
@@ -258,7 +260,7 @@ class Schema
return [
'query' => $queryFields,
'mutation' => $mutationFields
'mutation' => $mutationFields,
];
}
+3
View File
@@ -22,6 +22,7 @@ class Types
}
$type = new Json();
Registry::set(Json::class, $type);
return $type;
}
@@ -37,6 +38,7 @@ class Types
}
$type = new Assoc();
Registry::set(Assoc::class, $type);
return $type;
}
@@ -52,6 +54,7 @@ class Types
}
$type = new InputFile();
Registry::set(InputFile::class, $type);
return $type;
}
}
+1 -7
View File
@@ -2,19 +2,13 @@
namespace Appwrite\GraphQL\Types;
use GraphQL\Language\AST\BooleanValueNode;
use GraphQL\Language\AST\FloatValueNode;
use GraphQL\Language\AST\IntValueNode;
use GraphQL\Language\AST\ListValueNode;
use GraphQL\Language\AST\Node;
use GraphQL\Language\AST\ObjectValueNode;
use GraphQL\Language\AST\StringValueNode;
use GraphQL\Type\Definition\ScalarType;
// https://github.com/webonyx/graphql-php/issues/129#issuecomment-309366803
class Assoc extends Json
{
public $name = 'Assoc';
public $description = 'The `Assoc` scalar type represents associative array values.';
public function serialize($value)
+2 -1
View File
@@ -9,6 +9,7 @@ use GraphQL\Type\Definition\ScalarType;
class InputFile extends ScalarType
{
public $name = 'InputFile';
public $description = 'The `InputFile` special type represents a file to be uploaded in the same HTTP request as specified by
[graphql-multipart-request-spec](https://github.com/jaydenseric/graphql-multipart-request-spec).';
@@ -24,6 +25,6 @@ class InputFile extends ScalarType
public function parseLiteral(Node $valueNode, ?array $variables = null)
{
throw new Error('`InputFile` cannot be hardcoded in query, be sure to conform to GraphQL multipart request specification. Instead got: ' . $valueNode->kind, $valueNode);
throw new Error('`InputFile` cannot be hardcoded in query, be sure to conform to GraphQL multipart request specification. Instead got: '.$valueNode->kind, $valueNode);
}
}
+3 -1
View File
@@ -15,6 +15,7 @@ use GraphQL\Type\Definition\ScalarType;
class Json extends ScalarType
{
public $name = 'Json';
public $description = 'The `JSON` scalar type represents JSON values as specified by
[ECMA-404](https://www.ecma-international.org/publications/files/ECMA-ST/ECMA-404.pdf).';
@@ -43,8 +44,9 @@ class Json extends ScalarType
$value[$field->name->value] =
$this->parseLiteral($field->value);
}
return $value;
case ($valueNode instanceof ListValueNode):
case $valueNode instanceof ListValueNode:
return array_map([$this, 'parseLiteral'], $valueNode->values);
default:
return null;
+27 -22
View File
@@ -16,7 +16,9 @@ use Utopia\Validator\Nullable;
class Mapper
{
private static array $models = [];
private static array $args = [];
private static array $blacklist = [
'/v1/mock',
'/v1/graphql',
@@ -43,7 +45,7 @@ class Mapper
'permissions' => [
'type' => Type::listOf(Type::nonNull(Type::string())),
'defaultValue' => [],
]
],
],
];
@@ -66,7 +68,7 @@ class Mapper
/**
* Get the registered default arguments for a given key.
*
* @param string $key
* @param string $key
* @return array
*/
public static function args(string $key): array
@@ -87,7 +89,7 @@ class Mapper
$names = $route->getLabel('sdk.response.model', 'none');
$models = \is_array($names)
? \array_map(static fn($m) => static::$models[$m], $names)
? \array_map(static fn ($m) => static::$models[$m], $names)
: [static::$models[$names]];
foreach ($models as $model) {
@@ -103,7 +105,7 @@ class Mapper
$parameterType = Mapper::param(
$utopia,
$parameter['validator'],
!$parameter['optional'],
! $parameter['optional'],
$parameter['injections']
);
$params[$name] = [
@@ -116,7 +118,7 @@ class Mapper
'type' => $type,
'description' => $description,
'args' => $params,
'resolve' => Resolvers::api($utopia, $route)
'resolve' => Resolvers::api($utopia, $route),
];
if ($list) {
@@ -130,7 +132,7 @@ class Mapper
/**
* Get a type from the registry, creating it if it does not already exist.
*
* @param string $name
* @param string $name
* @return Type
*/
public static function model(string $name): Type
@@ -149,23 +151,23 @@ class Mapper
'description' => 'Additional data',
'resolve' => static function ($object, $args, $context, $info) {
$data = \array_filter(
(array)$object,
fn($key) => !\str_starts_with($key, '_'),
(array) $object,
fn ($key) => ! \str_starts_with($key, '_'),
ARRAY_FILTER_USE_KEY
);
return \json_encode($data, JSON_FORCE_OBJECT);
}
},
];
}
// If model has no properties, explicitly add a 'status' field
// because GraphQL requires at least 1 field per type.
if (!$model->isAny() && empty($model->getRules())) {
if (! $model->isAny() && empty($model->getRules())) {
$fields['status'] = [
'type' => Type::string(),
'description' => 'Status',
'resolve' => static fn($object, $args, $context, $info) => 'OK',
'resolve' => static fn ($object, $args, $context, $info) => 'OK',
];
}
@@ -187,7 +189,7 @@ class Mapper
'description' => $rule['description'],
];
if (!$rule['required']) {
if (! $rule['required']) {
$fields[$escapedKey]['defaultValue'] = $rule['default'];
}
}
@@ -205,11 +207,12 @@ class Mapper
/**
* Map a {@see Route} parameter to a GraphQL Type
*
* @param App $utopia
* @param Validator|callable $validator
* @param bool $required
* @param array $injections
* @param App $utopia
* @param Validator|callable $validator
* @param bool $required
* @param array $injections
* @return Type
*
* @throws Exception
*/
public static function param(
@@ -228,7 +231,7 @@ class Mapper
$validator = $validator->getValidator();
}
switch ((!empty($validator)) ? $validator::class : '') {
switch ((! empty($validator)) ? $validator::class : '') {
case 'Appwrite\Network\Validator\CNAME':
case 'Appwrite\Task\Validator\Cron':
case 'Appwrite\Utopia\Database\Validator\CustomId':
@@ -300,7 +303,7 @@ class Mapper
break;
}
if ($required && !$isNullable) {
if ($required && ! $isNullable) {
$type = Type::nonNull($type);
}
@@ -310,10 +313,11 @@ class Mapper
/**
* Map an {@see Attribute} to a GraphQL Type
*
* @param string $type
* @param bool $array
* @param bool $required
* @param string $type
* @param bool $array
* @param bool $required
* @return Type
*
* @throws Exception
*/
public static function attribute(string $type, bool $array, bool $required): Type
@@ -349,6 +353,7 @@ class Mapper
}
$complexModel = self::$models[$type];
return self::model(\ucfirst($complexModel->getType()));
}
@@ -389,7 +394,7 @@ class Mapper
return static::getHashOptionsImplementation($object);
}
throw new Exception('Unknown union type: ' . $name);
throw new Exception('Unknown union type: '.$name);
}
private static function getAttributeImplementation(array $object): Type
+4 -4
View File
@@ -11,7 +11,7 @@ class Registry
/**
* Check if a type exists in the registry.
*
* @param string $type
* @param string $type
* @return bool
*/
public static function has(string $type): bool
@@ -22,7 +22,7 @@ class Registry
/**
* Get a type from the registry.
*
* @param string $type
* @param string $type
* @return Type
*/
public static function get(string $type): Type
@@ -33,8 +33,8 @@ class Registry
/**
* Set a type in the registry.
*
* @param string $type
* @param Type $typeObject
* @param string $type
* @param Type $typeObject
*/
public static function set(string $type, Type $typeObject): void
{
+2
View File
@@ -5,6 +5,8 @@ namespace Appwrite\Messaging;
abstract class Adapter
{
abstract public function subscribe(string $projectId, mixed $identifier, array $roles, array $channels): void;
abstract public function unsubscribe(mixed $identifier): void;
abstract public static function send(string $projectId, array $payload, array $events, array $channels, array $roles, array $options): void;
}
+43 -41
View File
@@ -2,10 +2,10 @@
namespace Appwrite\Messaging\Adapter;
use Utopia\Database\DateTime;
use Utopia\Database\Document;
use Appwrite\Messaging\Adapter;
use Utopia\App;
use Utopia\Database\DateTime;
use Utopia\Database\Document;
use Utopia\Database\Helpers\ID;
use Utopia\Database\Helpers\Role;
@@ -39,20 +39,20 @@ class Realtime extends Adapter
/**
* Adds a subscription.
*
* @param string $projectId
* @param mixed $identifier
* @param array $roles
* @param array $channels
* @param string $projectId
* @param mixed $identifier
* @param array $roles
* @param array $channels
* @return void
*/
public function subscribe(string $projectId, mixed $identifier, array $roles, array $channels): void
{
if (!isset($this->subscriptions[$projectId])) { // Init Project
if (! isset($this->subscriptions[$projectId])) { // Init Project
$this->subscriptions[$projectId] = [];
}
foreach ($roles as $role) {
if (!isset($this->subscriptions[$projectId][$role])) { // Add user first connection
if (! isset($this->subscriptions[$projectId][$role])) { // Add user first connection
$this->subscriptions[$projectId][$role] = [];
}
@@ -64,14 +64,14 @@ class Realtime extends Adapter
$this->connections[$identifier] = [
'projectId' => $projectId,
'roles' => $roles,
'channels' => $channels
'channels' => $channels,
];
}
/**
* Removes Subscription.
*
* @param mixed $connection
* @param mixed $connection
* @return void
*/
public function unsubscribe(mixed $connection): void
@@ -102,9 +102,10 @@ class Realtime extends Adapter
/**
* Checks if Channel has a subscriber.
* @param string $projectId
* @param string $role
* @param string $channel
*
* @param string $projectId
* @param string $role
* @param string $channel
* @return bool
*/
public function hasSubscriber(string $projectId, string $role, string $channel = ''): bool
@@ -122,12 +123,13 @@ class Realtime extends Adapter
/**
* Sends an event to the Realtime Server
* @param string $projectId
* @param array $payload
* @param string $event
* @param array $channels
* @param array $roles
* @param array $options
*
* @param string $projectId
* @param array $payload
* @param string $event
* @param array $channels
* @param array $roles
* @param array $options
* @return void
*/
public static function send(string $projectId, array $payload, array $events, array $channels, array $roles, array $options = []): void
@@ -150,8 +152,8 @@ class Realtime extends Adapter
'events' => $events,
'channels' => $channels,
'timestamp' => DateTime::formatTz(DateTime::now()),
'payload' => $payload
]
'payload' => $payload,
],
]));
}
@@ -166,11 +168,10 @@ class Realtime extends Adapter
* - 110.201 ms (±2.32%) | 100,000 Connections / 1,000,000 Subscriptions
* - 1,121.328 ms (±0.84%) | 1,000,000 Connections / 10,000,000 Subscriptions
*
* @param array $event
* @param array $event
*/
public function getSubscribers(array $event)
{
$receivers = [];
/**
* Check if project has subscriber.
@@ -212,8 +213,9 @@ class Realtime extends Adapter
/**
* Converts the channels from the Query Params into an array.
* Also renames the account channel to account.USER_ID and removes all illegal account channel variations.
* @param array $channels
* @param string $userId
*
* @param array $channels
* @param string $userId
* @return array
*/
public static function convertChannels(array $channels, string $userId): array
@@ -227,8 +229,8 @@ class Realtime extends Adapter
break;
case $key === 'account':
if (!empty($userId)) {
$channels['account.' . $userId] = $value;
if (! empty($userId)) {
$channels['account.'.$userId] = $value;
}
break;
}
@@ -240,9 +242,9 @@ class Realtime extends Adapter
/**
* Create channels array based on the event name and payload.
*
* @param string $event
* @param Document $payload
* @param Document|null $project
* @param string $event
* @param Document $payload
* @param Document|null $project
* @return array
*/
public static function fromPayload(string $event, Document $payload, Document $project = null, Document $database = null, Document $collection = null, Document $bucket = null): array
@@ -257,18 +259,18 @@ class Realtime extends Adapter
switch ($parts[0]) {
case 'users':
$channels[] = 'account';
$channels[] = 'account.' . $parts[1];
$channels[] = 'account.'.$parts[1];
$roles = [Role::user(ID::custom($parts[1]))->toString()];
break;
case 'teams':
if ($parts[2] === 'memberships') {
$permissionsChanged = $parts[4] ?? false;
$channels[] = 'memberships';
$channels[] = 'memberships.' . $parts[3];
$channels[] = 'memberships.'.$parts[3];
} else {
$permissionsChanged = $parts[2] === 'create';
$channels[] = 'teams';
$channels[] = 'teams.' . $parts[1];
$channels[] = 'teams.'.$parts[1];
}
$roles = [Role::team(ID::custom($parts[1]))->toString()];
break;
@@ -286,8 +288,8 @@ class Realtime extends Adapter
}
$channels[] = 'documents';
$channels[] = 'databases.' . $database->getId() . '.collections.' . $payload->getAttribute('$collectionId') . '.documents';
$channels[] = 'databases.' . $database->getId() . '.collections.' . $payload->getAttribute('$collectionId') . '.documents.' . $payload->getId();
$channels[] = 'databases.'.$database->getId().'.collections.'.$payload->getAttribute('$collectionId').'.documents';
$channels[] = 'databases.'.$database->getId().'.collections.'.$payload->getAttribute('$collectionId').'.documents.'.$payload->getId();
$roles = $collection->getAttribute('documentSecurity', false)
? \array_merge($collection->getRead(), $payload->getRead())
@@ -300,8 +302,8 @@ class Realtime extends Adapter
throw new \Exception('Bucket needs to be passed to Realtime for File events in the Storage.');
}
$channels[] = 'files';
$channels[] = 'buckets.' . $payload->getAttribute('bucketId') . '.files';
$channels[] = 'buckets.' . $payload->getAttribute('bucketId') . '.files.' . $payload->getId();
$channels[] = 'buckets.'.$payload->getAttribute('bucketId').'.files';
$channels[] = 'buckets.'.$payload->getAttribute('bucketId').'.files.'.$payload->getId();
$roles = $bucket->getAttribute('fileSecurity', false)
? \array_merge($bucket->getRead(), $payload->getRead())
@@ -312,11 +314,11 @@ class Realtime extends Adapter
case 'functions':
if ($parts[2] === 'executions') {
if (!empty($payload->getRead())) {
if (! empty($payload->getRead())) {
$channels[] = 'console';
$channels[] = 'executions';
$channels[] = 'executions.' . $payload->getId();
$channels[] = 'functions.' . $payload->getAttribute('functionId');
$channels[] = 'executions.'.$payload->getId();
$channels[] = 'functions.'.$payload->getAttribute('functionId');
$roles = $payload->getRead();
}
} elseif ($parts[2] === 'deployments') {
@@ -332,7 +334,7 @@ class Realtime extends Adapter
'channels' => $channels,
'roles' => $roles,
'permissionsChanged' => $permissionsChanged,
'projectId' => $projectId
'projectId' => $projectId,
];
}
}
+42 -38
View File
@@ -2,15 +2,15 @@
namespace Appwrite\Migration;
use Exception;
use Swoole\Runtime;
use Utopia\Database\Document;
use Utopia\Database\Database;
use Utopia\Database\Query;
use Utopia\App;
use Utopia\CLI\Console;
use Utopia\Config\Config;
use Exception;
use Utopia\App;
use Utopia\Database\Database;
use Utopia\Database\Document;
use Utopia\Database\Helpers\ID;
use Utopia\Database\Query;
use Utopia\Database\Validator\Authorization;
Runtime::enableCoroutine(SWOOLE_HOOK_ALL);
@@ -80,26 +80,25 @@ abstract class Migration
$this->collections = array_merge([
'_metadata' => [
'$id' => ID::custom('_metadata'),
'$collection' => Database::METADATA
'$collection' => Database::METADATA,
],
'audit' => [
'$id' => ID::custom('audit'),
'$collection' => Database::METADATA
'$collection' => Database::METADATA,
],
'abuse' => [
'$id' => ID::custom('abuse'),
'$collection' => Database::METADATA
]
'$collection' => Database::METADATA,
],
], Config::getParam('collections', []));
}
/**
* Set project for migration.
*
* @param Document $project
* @param Database $projectDB
* @param Database $oldConsoleDB
*
* @param Document $project
* @param Database $projectDB
* @param Database $oldConsoleDB
* @return self
*/
public function setProject(Document $project, Database $projectDB, Database $consoleDB): self
@@ -114,7 +113,7 @@ abstract class Migration
/**
* Set PDO for Migration.
*
* @param \PDO $pdo
* @param \PDO $pdo
* @return \Appwrite\Migration\Migration
*/
public function setPDO(\PDO $pdo): self
@@ -127,7 +126,7 @@ abstract class Migration
/**
* Iterates through every document.
*
* @param callable $callback
* @param callable $callback
*/
public function forEachDocument(callable $callback): void
{
@@ -136,7 +135,7 @@ abstract class Migration
continue;
}
Console::log('Migrating Collection ' . $collection['$id'] . ':');
Console::log('Migrating Collection '.$collection['$id'].':');
\Co\run(function (array $collection, callable $callback) {
foreach ($this->documentsIterator($collection['$id']) as $document) {
@@ -148,14 +147,15 @@ abstract class Migration
$old = $document->getArrayCopy();
$new = call_user_func($callback, $document);
if (is_null($new) || !self::hasDifference($new->getArrayCopy(), $old)) {
if (is_null($new) || ! self::hasDifference($new->getArrayCopy(), $old)) {
return;
}
try {
$new = $this->projectDB->updateDocument($document->getCollection(), $document->getId(), $document);
} catch (\Throwable $th) {
Console::error('Failed to update document: ' . $th->getMessage());
Console::error('Failed to update document: '.$th->getMessage());
return;
}
}, $document, $callback);
@@ -167,8 +167,9 @@ abstract class Migration
/**
* Provides an iterator for all documents on a collection.
*
* @param string $collectionId
* @param string $collectionId
* @return iterable<Document>
*
* @throws \Exception
*/
public function documentsIterator(string $collectionId): iterable
@@ -186,7 +187,7 @@ abstract class Migration
$count = count($documents);
$sum += $count;
Console::log($sum . ' / ' . $collectionCount);
Console::log($sum.' / '.$collectionCount);
foreach ($documents as $document) {
yield $document;
}
@@ -196,28 +197,28 @@ abstract class Migration
} else {
$nextDocument = end($documents);
}
} while (!is_null($nextDocument));
} while (! is_null($nextDocument));
}
/**
* Checks 2 arrays for differences.
*
* @param array $array1
* @param array $array2
* @param array $array1
* @param array $array2
* @return bool
*/
public static function hasDifference(array $array1, array $array2): bool
{
foreach ($array1 as $key => $value) {
if (is_array($value)) {
if (!isset($array2[$key]) || !is_array($array2[$key])) {
if (! isset($array2[$key]) || ! is_array($array2[$key])) {
return true;
} else {
if (self::hasDifference($value, $array2[$key])) {
return true;
}
}
} elseif (!array_key_exists($key, $array2) || $array2[$key] !== $value) {
} elseif (! array_key_exists($key, $array2) || $array2[$key] !== $value) {
return true;
}
}
@@ -228,16 +229,17 @@ abstract class Migration
/**
* Creates colletion from the config collection.
*
* @param string $id
* @param string|null $name
* @param string $id
* @param string|null $name
* @return void
*
* @throws \Throwable
*/
protected function createCollection(string $id, string $name = null): void
{
$name ??= $id;
if (!$this->projectDB->exists(App::getEnv('_APP_DB_SCHEMA', 'appwrite'), $name)) {
if (! $this->projectDB->exists(App::getEnv('_APP_DB_SCHEMA', 'appwrite'), $name)) {
$attributes = [];
$indexes = [];
$collection = $this->collections[$id];
@@ -275,10 +277,11 @@ abstract class Migration
/**
* Creates attribute from collections.php
*
* @param \Utopia\Database\Database $database
* @param string $collectionId
* @param string $attributeId
* @param \Utopia\Database\Database $database
* @param string $collectionId
* @param string $attributeId
* @return void
*
* @throws \Exception
* @throws \Utopia\Database\Exception\Duplicate
* @throws \Utopia\Database\Exception\Limit
@@ -320,11 +323,12 @@ abstract class Migration
/**
* Creates index from collections.php
*
* @param \Utopia\Database\Database $database
* @param string $collectionId
* @param string $indexId
* @param string|null $from
* @param \Utopia\Database\Database $database
* @param string $collectionId
* @param string $indexId
* @param string|null $from
* @return void
*
* @throws \Exception
* @throws \Utopia\Database\Exception\Duplicate
* @throws \Utopia\Database\Exception\Limit
@@ -360,9 +364,9 @@ abstract class Migration
/**
* Change a collection attribute's internal type
*
* @param string $collection
* @param string $attribute
* @param string $type
* @param string $collection
* @param string $attribute
* @param string $type
* @return void
*/
protected function changeAttributeInternalType(string $collection, string $attribute, string $type): void
+26 -21
View File
@@ -4,8 +4,6 @@ namespace Appwrite\Migration\Version;
use Appwrite\Migration\Migration;
use Appwrite\OpenSSL\OpenSSL;
use Exception;
use PDO;
use Utopia\App;
use Utopia\CLI\Console;
use Utopia\Config\Config;
@@ -33,7 +31,7 @@ class V15 extends Migration
$this->providers = \array_merge(
['email', 'anonymous'],
\array_map(
fn ($value) => "oauth-" . $value,
fn ($value) => 'oauth-'.$value,
\array_keys(Config::getParam('authProviders', []))
)
);
@@ -49,7 +47,7 @@ class V15 extends Migration
);
}
Console::log('Migrating Project: ' . $this->project->getAttribute('name') . ' (' . $this->project->getId() . ')');
Console::log('Migrating Project: '.$this->project->getAttribute('name').' ('.$this->project->getId().')');
Console::info('Migrating Stats');
$this->migrateStatsMetric('requests', 'project.$all.network.requests');
$this->migrateStatsMetric('network', 'project.$all.network.bandwidth');
@@ -76,6 +74,7 @@ class V15 extends Migration
* Migrating all Bucket tables.
*
* @return void
*
* @throws \Exception
* @throws \PDOException
*/
@@ -108,7 +107,7 @@ class V15 extends Migration
addCreatePermission: true
);
if (!is_null($bucket->getAttribute('permission'))) {
if (! is_null($bucket->getAttribute('permission'))) {
$bucket->setAttribute('fileSecurity', $bucket->getAttribute('permissions') === 'document');
}
@@ -152,6 +151,7 @@ class V15 extends Migration
* Migrating all Database and Collection tables.
*
* @return void
*
* @throws \Exception
* @throws \PDOException
*/
@@ -229,7 +229,7 @@ class V15 extends Migration
addCreatePermission: true
);
if (!is_null($collection->getAttribute('permission'))) {
if (! is_null($collection->getAttribute('permission'))) {
$collection->setAttribute('documentSecurity', $collection->getAttribute('permissions') === 'document');
}
@@ -249,9 +249,10 @@ class V15 extends Migration
$requiredAttributes = array_reduce($collection->getAttribute('attributes', []), function (array $carry, Document $item) {
if ($item->getAttribute('required', false)) {
$carry = array_merge($carry, [
$item->getAttribute('key') => $item->getAttribute('default')
$item->getAttribute('key') => $item->getAttribute('default'),
]);
}
return $carry;
}, []);
@@ -289,7 +290,7 @@ class V15 extends Migration
/**
* Removes all 'write' permissions from a table.
*
* @param string $table
* @param string $table
* @return void
*/
protected function removeWritePermissions(string $table): void
@@ -304,8 +305,9 @@ class V15 extends Migration
/**
* Returns all columns from the Table.
*
* @param string $table
* @param string $table
* @return array
*
* @throws \Exception
* @throws \PDOException
*/
@@ -325,6 +327,7 @@ class V15 extends Migration
* Migrates all Integer colums for timestamps to DateTime.
*
* @return void
*
* @throws \Exception
*/
protected function migrateDateTimeAttribute(string $table, string $attribute): void
@@ -352,7 +355,7 @@ class V15 extends Migration
/**
* Skip adding filter on internal attributes.
*/
if (!str_starts_with($attribute, '_')) {
if (! str_starts_with($attribute, '_')) {
try {
/**
* Add datetime filter.
@@ -378,8 +381,9 @@ class V15 extends Migration
/**
* Create the '_permissions' column to a table.
*
* @param string $table
* @param string $table
* @return void
*
* @throws \Exception
* @throws \PDOException
*/
@@ -387,7 +391,7 @@ class V15 extends Migration
{
$columns = $this->getSQLColumnTypes($table);
if (!array_key_exists('_permissions', $columns)) {
if (! array_key_exists('_permissions', $columns)) {
try {
$this->pdo->prepare("ALTER TABLE IF EXISTS `{$this->projectDB->getDefaultDatabase()}`.`_{$this->project->getInternalId()}_{$table}` ADD `_permissions` MEDIUMTEXT DEFAULT NULL")->execute();
} catch (\Throwable $th) {
@@ -399,10 +403,11 @@ class V15 extends Migration
/**
* Populate '$permissions' from '$read' and '$write'.
*
* @param \Utopia\Database\Document $document
* @param null|string $table
* @param bool $addCreatePermission
* @param \Utopia\Database\Document $document
* @param null|string $table
* @param bool $addCreatePermission
* @return void
*
* @throws \Exception
* @throws \PDOException
*/
@@ -443,7 +448,7 @@ class V15 extends Migration
/**
* Migrates a permission string
*
* @param string $permission
* @param string $permission
* @return string
*/
protected function migratePermission(string $permission): string
@@ -730,7 +735,7 @@ class V15 extends Migration
foreach ($this->documentsIterator($id) as $function) {
$vars = $function->getAttribute('vars', []);
if (!is_array($vars)) {
if (! is_array($vars)) {
continue;
}
@@ -751,7 +756,7 @@ class V15 extends Migration
'functionInternalId' => $function->getInternalId(),
'key' => (string) $key,
'value' => (string) $value,
'search' => implode(' ', [$variableId, $key, $function->getId()])
'search' => implode(' ', [$variableId, $key, $function->getId()]),
]);
$this->projectDB->createDocument('variables', $variable);
}
@@ -1223,7 +1228,7 @@ class V15 extends Migration
/**
* Fix run on each document
*
* @param \Utopia\Database\Document $document
* @param \Utopia\Database\Document $document
* @return \Utopia\Database\Document
*/
protected function fixDocument(Document $document)
@@ -1474,14 +1479,14 @@ class V15 extends Migration
$this->pdo->prepare("UPDATE `{$this->projectDB->getDefaultDatabase()}`.`_{$this->project->getInternalId()}_stats` SET metric = {$to} WHERE metric = {$from}")->execute();
} catch (\Throwable $th) {
Console::warning("Migrating steps from {$this->projectDB->getDefaultDatabase()}`.`_{$this->project->getInternalId()}_stats:" . $th->getMessage());
Console::warning("Migrating steps from {$this->projectDB->getDefaultDatabase()}`.`_{$this->project->getInternalId()}_stats:".$th->getMessage());
}
}
/**
* Filter from the 'encrypt' filter.
*
* @param string $value
* @param string $value
* @return string|false
*/
protected function encryptFilter(string $value): string
+7 -7
View File
@@ -24,7 +24,7 @@ class V16 extends Migration
);
}
Console::log('Migrating Project: ' . $this->project->getAttribute('name') . ' (' . $this->project->getId() . ')');
Console::log('Migrating Project: '.$this->project->getAttribute('name').' ('.$this->project->getId().')');
Console::info('Migrating Collections');
$this->migrateCollections();
@@ -102,7 +102,7 @@ class V16 extends Migration
/**
* Fix run on each document
*
* @param \Utopia\Database\Document $document
* @param \Utopia\Database\Document $document
* @return \Utopia\Database\Document
*/
protected function fixDocument(Document $document)
@@ -118,7 +118,7 @@ class V16 extends Migration
* Set default authDuration
*/
$document->setAttribute('auths', array_merge($document->getAttribute('auths', []), [
'duration' => Auth::TOKEN_EXPIRATION_LOGIN_LONG
'duration' => Auth::TOKEN_EXPIRATION_LOGIN_LONG,
]));
/**
@@ -127,16 +127,16 @@ class V16 extends Migration
$authProviders = $document->getAttribute('authProviders', []);
foreach (Config::getParam('authProviders') as $provider => $value) {
if (!$value['enabled']) {
if (! $value['enabled']) {
continue;
}
if (($authProviders[$provider . 'Appid'] ?? false) && ($authProviders[$provider . 'Secret'] ?? false)) {
if (array_key_exists($provider . 'Enabled', $authProviders)) {
if (($authProviders[$provider.'Appid'] ?? false) && ($authProviders[$provider.'Secret'] ?? false)) {
if (array_key_exists($provider.'Enabled', $authProviders)) {
continue;
}
$authProviders[$provider . 'Enabled'] = true;
$authProviders[$provider.'Enabled'] = true;
}
}
+6 -6
View File
@@ -23,7 +23,7 @@ class V17 extends Migration
);
}
Console::log('Migrating Project: ' . $this->project->getAttribute('name') . ' (' . $this->project->getId() . ')');
Console::log('Migrating Project: '.$this->project->getAttribute('name').' ('.$this->project->getId().')');
Console::info('Migrating Collections');
$this->migrateCollections();
@@ -33,11 +33,11 @@ class V17 extends Migration
$this->forEachDocument([$this, 'fixDocument']);
}
/**
* Migrating all Bucket tables.
*
* @return void
*
* @throws \Exception
* @throws \PDOException
*/
@@ -234,7 +234,7 @@ class V17 extends Migration
/**
* Fix run on each document
*
* @param \Utopia\Database\Document $document
* @param \Utopia\Database\Document $document
* @return \Utopia\Database\Document
*/
protected function fixDocument(Document $document)
@@ -250,15 +250,15 @@ class V17 extends Migration
* Set default maxSessions
*/
$document->setAttribute('auths', array_merge($document->getAttribute('auths', []), [
'maxSessions' => APP_LIMIT_USER_SESSIONS_DEFAULT
'maxSessions' => APP_LIMIT_USER_SESSIONS_DEFAULT,
]));
break;
case 'users':
/**
/**
* Set hashOptions type
*/
$document->setAttribute('hashOptions', array_merge($document->getAttribute('hashOptions', []), [
'type' => $document->getAttribute('hash', Auth::DEFAULT_ALGO)
'type' => $document->getAttribute('hash', Auth::DEFAULT_ALGO),
]));
break;
}
+3 -3
View File
@@ -13,7 +13,6 @@ class V18 extends Migration
{
public function execute(): void
{
/**
* Disable SubQueries for Performance.
*/
@@ -25,7 +24,7 @@ class V18 extends Migration
);
}
Console::log('Migrating Project: ' . $this->project->getAttribute('name') . ' (' . $this->project->getId() . ')');
Console::log('Migrating Project: '.$this->project->getAttribute('name').' ('.$this->project->getId().')');
$this->projectDB->setNamespace("_{$this->project->getInternalId()}");
$this->addDocumentSecurityToProject();
@@ -43,6 +42,7 @@ class V18 extends Migration
* Migrate all Databases.
*
* @return void
*
* @throws \Exception
*/
private function migrateDatabases(): void
@@ -154,7 +154,7 @@ class V18 extends Migration
/**
* Fix run on each document
*
* @param Document $document
* @param Document $document
* @return Document
*/
protected function fixDocument(Document $document): Document
+5 -6
View File
@@ -2,8 +2,6 @@
namespace Appwrite\Migration\Version;
use Appwrite\Auth\Auth;
use Utopia\Config\Config;
use Appwrite\Migration\Migration;
use Utopia\CLI\Console;
use Utopia\Database\Database;
@@ -13,7 +11,6 @@ class V19 extends Migration
{
public function execute(): void
{
/**
* Disable SubQueries for Performance.
*/
@@ -25,7 +22,7 @@ class V19 extends Migration
);
}
Console::log('Migrating Project: ' . $this->project->getAttribute('name') . ' (' . $this->project->getId() . ')');
Console::log('Migrating Project: '.$this->project->getAttribute('name').' ('.$this->project->getId().')');
$this->projectDB->setNamespace("_{$this->project->getInternalId()}");
$this->alterPermissionIndex('_metadata');
@@ -48,6 +45,7 @@ class V19 extends Migration
* Migrate all Databases.
*
* @return void
*
* @throws \Exception
*/
private function migrateDatabases(): void
@@ -99,7 +97,7 @@ class V19 extends Migration
default:
break;
}
if (!in_array($id, ['files', 'collections'])) {
if (! in_array($id, ['files', 'collections'])) {
$this->alterPermissionIndex($id);
$this->alterUidType($id);
}
@@ -111,7 +109,7 @@ class V19 extends Migration
/**
* Fix run on each document
*
* @param Document $document
* @param Document $document
* @return Document
*/
protected function fixDocument(Document $document): Document
@@ -163,6 +161,7 @@ class V19 extends Migration
* Migrating all Bucket tables.
*
* @return void
*
* @throws \Exception
* @throws \PDOException
*/
+4 -5
View File
@@ -12,7 +12,7 @@ class CNAME extends Validator
protected $target;
/**
* @param string $target
* @param string $target
*/
public function __construct($target)
{
@@ -30,13 +30,12 @@ class CNAME extends Validator
/**
* Check if CNAME record target value matches selected target
*
* @param mixed $domain
*
* @param mixed $domain
* @return bool
*/
public function isValid($domain): bool
{
if (!is_string($domain)) {
if (! is_string($domain)) {
return false;
}
@@ -46,7 +45,7 @@ class CNAME extends Validator
return false;
}
if (!$records) {
if (! $records) {
return false;
}
+2 -4
View File
@@ -8,8 +8,6 @@ use Utopia\Validator;
* Email
*
* Validate that an variable is a valid email address
*
* @package Utopia\Validator
*/
class Email extends Validator
{
@@ -30,12 +28,12 @@ class Email extends Validator
*
* Validation will pass when $value is valid email address.
*
* @param mixed $value
* @param mixed $value
* @return bool
*/
public function isValid($value): bool
{
if (!\filter_var($value, FILTER_VALIDATE_EMAIL)) {
if (! \filter_var($value, FILTER_VALIDATE_EMAIL)) {
return false;
}
+29 -10
View File
@@ -2,35 +2,55 @@
namespace Appwrite\Network\Validator;
use Utopia\Validator\Hostname;
use Utopia\Validator;
use Utopia\Validator\Hostname;
class Origin extends Validator
{
public const CLIENT_TYPE_UNKNOWN = 'unknown';
public const CLIENT_TYPE_WEB = 'web';
public const CLIENT_TYPE_FLUTTER_IOS = 'flutter-ios';
public const CLIENT_TYPE_FLUTTER_ANDROID = 'flutter-android';
public const CLIENT_TYPE_FLUTTER_MACOS = 'flutter-macos';
public const CLIENT_TYPE_FLUTTER_WINDOWS = 'flutter-windows';
public const CLIENT_TYPE_FLUTTER_LINUX = 'flutter-linux';
public const CLIENT_TYPE_FLUTTER_WEB = 'flutter-web';
public const CLIENT_TYPE_APPLE_IOS = 'apple-ios';
public const CLIENT_TYPE_APPLE_MACOS = 'apple-macos';
public const CLIENT_TYPE_APPLE_WATCHOS = 'apple-watchos';
public const CLIENT_TYPE_APPLE_TVOS = 'apple-tvos';
public const CLIENT_TYPE_ANDROID = 'android';
public const CLIENT_TYPE_UNITY = 'unity';
public const SCHEME_TYPE_HTTP = 'http';
public const SCHEME_TYPE_HTTPS = 'https';
public const SCHEME_TYPE_IOS = 'appwrite-ios';
public const SCHEME_TYPE_MACOS = 'appwrite-macos';
public const SCHEME_TYPE_WATCHOS = 'appwrite-watchos';
public const SCHEME_TYPE_TVOS = 'appwrite-tvos';
public const SCHEME_TYPE_ANDROID = 'appwrite-android';
public const SCHEME_TYPE_WINDOWS = 'appwrite-windows';
public const SCHEME_TYPE_LINUX = 'appwrite-linux';
/**
@@ -65,7 +85,7 @@ class Origin extends Validator
protected $host = '';
/**
* @param string $target
* @param string $target
*/
public function __construct($platforms)
{
@@ -92,7 +112,7 @@ class Origin extends Validator
break;
default:
# code...
// code...
break;
}
}
@@ -100,25 +120,24 @@ class Origin extends Validator
public function getDescription(): string
{
if (!\array_key_exists($this->client, $this->platforms)) {
if (! \array_key_exists($this->client, $this->platforms)) {
return 'Unsupported platform';
}
return 'Invalid Origin. Register your new client (' . $this->host . ') as a new '
. $this->platforms[$this->client] . ' platform on your project console dashboard';
return 'Invalid Origin. Register your new client ('.$this->host.') as a new '
.$this->platforms[$this->client].' platform on your project console dashboard';
}
/**
* Check if Origin has been allowed
* for access to the API
*
* @param mixed $origin
*
* @param mixed $origin
* @return bool
*/
public function isValid($origin): bool
{
if (!is_string($origin)) {
if (! is_string($origin)) {
return false;
}
+11 -15
View File
@@ -10,12 +10,11 @@ class OpenSSL
* @param $data
* @param $method
* @param $key
* @param int $options
* @param string $iv
* @param null $tag
* @param string $aad
* @param int $tag_length
*
* @param int $options
* @param string $iv
* @param null $tag
* @param string $aad
* @param int $tag_length
* @return string
*/
public static function encrypt($data, $method, $key, $options = 0, $iv = '', &$tag = null, $aad = '', $tag_length = 16)
@@ -27,11 +26,10 @@ class OpenSSL
* @param $data
* @param $method
* @param $password
* @param int $options
* @param string $iv
* @param string $tag
* @param string $aad
*
* @param int $options
* @param string $iv
* @param string $tag
* @param string $aad
* @return string
*/
public static function decrypt($data, $method, $password, $options = 1, $iv = '', $tag = '', $aad = '')
@@ -40,8 +38,7 @@ class OpenSSL
}
/**
* @param string $method
*
* @param string $method
* @return int
*/
public static function cipherIVLength($method)
@@ -51,8 +48,7 @@ class OpenSSL
/**
* @param $length
* @param null $crypto_strong
*
* @param null $crypto_strong
* @return false|string
*/
public static function randomPseudoBytes($length, &$crypto_strong = null)
+9 -11
View File
@@ -2,26 +2,25 @@
namespace Appwrite\Platform\Services;
use Utopia\Platform\Service;
use Appwrite\Platform\Tasks\CalcTierStats;
use Appwrite\Platform\Tasks\CalcUsersStats;
use Appwrite\Platform\Tasks\ClearCardCache;
use Appwrite\Platform\Tasks\Doctor;
use Appwrite\Platform\Tasks\Hamster;
use Appwrite\Platform\Tasks\Install;
use Appwrite\Platform\Tasks\Maintenance;
use Appwrite\Platform\Tasks\Migrate;
use Appwrite\Platform\Tasks\Schedule;
use Appwrite\Platform\Tasks\PatchCreateMissingSchedules;
use Appwrite\Platform\Tasks\PatchDeleteProjectCollections;
use Appwrite\Platform\Tasks\PatchDeleteScheduleUpdatedAtAttribute;
use Appwrite\Platform\Tasks\Schedule;
use Appwrite\Platform\Tasks\SDKs;
use Appwrite\Platform\Tasks\Specs;
use Appwrite\Platform\Tasks\SSL;
use Appwrite\Platform\Tasks\Hamster;
use Appwrite\Platform\Tasks\PatchDeleteScheduleUpdatedAtAttribute;
use Appwrite\Platform\Tasks\ClearCardCache;
use Appwrite\Platform\Tasks\Usage;
use Appwrite\Platform\Tasks\Vars;
use Appwrite\Platform\Tasks\Version;
use Appwrite\Platform\Tasks\VolumeSync;
use Appwrite\Platform\Tasks\CalcUsersStats;
use Appwrite\Platform\Tasks\CalcTierStats;
use Appwrite\Platform\Tasks\PatchDeleteProjectCollections;
use Utopia\Platform\Service;
class Tasks extends Service
{
@@ -46,7 +45,6 @@ class Tasks extends Service
->addAction(Specs::getName(), new Specs())
->addAction(CalcUsersStats::getName(), new CalcUsersStats())
->addAction(CalcTierStats::getName(), new CalcTierStats())
->addAction(PatchDeleteProjectCollections::getName(), new PatchDeleteProjectCollections())
;
->addAction(PatchDeleteProjectCollections::getName(), new PatchDeleteProjectCollections());
}
}
+26 -28
View File
@@ -4,15 +4,15 @@ namespace Appwrite\Platform\Tasks;
use Exception;
use League\Csv\CannotInsertRecord;
use League\Csv\Writer;
use PHPMailer\PHPMailer\PHPMailer;
use Utopia\App;
use Utopia\Database\Validator\Authorization;
use Utopia\Platform\Action;
use Utopia\Cache\Cache;
use Utopia\CLI\Console;
use Utopia\Database\Database;
use Utopia\Database\Query;
use League\Csv\Writer;
use PHPMailer\PHPMailer\PHPMailer;
use Utopia\Database\Validator\Authorization;
use Utopia\Platform\Action;
use Utopia\Pools\Group;
use Utopia\Registry\Registry;
@@ -44,11 +44,13 @@ class CalcTierStats extends Action
];
protected string $directory = '/usr/local';
protected string $path;
protected string $date;
private array $usageStats = [
'project.$all.network.requests' => 'Requests',
'project.$all.network.requests' => 'Requests',
'project.$all.network.bandwidth' => 'Bandwidth',
];
@@ -60,7 +62,6 @@ class CalcTierStats extends Action
public function __construct()
{
$this
->desc('Get stats for projects')
->inject('pools')
@@ -81,7 +82,7 @@ class CalcTierStats extends Action
//docker compose exec -t appwrite calc-tier-stats
Console::title('Cloud free tier stats calculation V1');
Console::success(APP_NAME . ' cloud free tier stats calculation has started');
Console::success(APP_NAME.' cloud free tier stats calculation has started');
/* Initialise new Utopia app */
$app = new App('UTC');
@@ -102,9 +103,8 @@ class CalcTierStats extends Action
$limit = 30;
$sum = 30;
$offset = 0;
while (!empty($projects)) {
while (! empty($projects)) {
foreach ($projects as $project) {
/**
* Skip user projects with id 'console'
*/
@@ -123,18 +123,18 @@ class CalcTierStats extends Action
$dbForProject = new Database($adapter, $cache);
$dbForProject->setDefaultDatabase('appwrite');
$dbForProject->setNamespace('_' . $project->getInternalId());
$dbForProject->setNamespace('_'.$project->getInternalId());
/** Get Project ID */
$stats['Project ID'] = $project->getId();
$stats['Organization ID'] = $project->getAttribute('teamId', null);
$stats['Organization ID'] = $project->getAttribute('teamId', null);
/** Get Total Members */
$teamInternalId = $project->getAttribute('teamInternalId', null);
if ($teamInternalId) {
$stats['Organization Members'] = $dbForConsole->count('memberships', [
Query::equal('teamInternalId', [$teamInternalId])
Query::equal('teamInternalId', [$teamInternalId]),
]);
} else {
$stats['Organization Members'] = 0;
@@ -195,7 +195,7 @@ class CalcTierStats extends Action
});
foreach ($tmp as $key => $value) {
$stats[$metrics[$key]] = $value;
$stats[$metrics[$key]] = $value;
}
try {
@@ -208,27 +208,27 @@ class CalcTierStats extends Action
}
try {
/** Get Api keys */
/** Get Api keys */
$stats['Api keys'] = $dbForConsole->count('keys', [
Query::equal('projectInternalId', [$project->getInternalId()]),
Query::equal('projectInternalId', [$project->getInternalId()]),
]);
} catch (\Throwable) {
$stats['Api keys'] = 0;
}
try {
/** Get Webhooks */
/** Get Webhooks */
$stats['Webhooks'] = $dbForConsole->count('webhooks', [
Query::equal('projectInternalId', [$project->getInternalId()]),
Query::equal('projectInternalId', [$project->getInternalId()]),
]);
} catch (\Throwable) {
$stats['Webhooks'] = 0;
}
try {
/** Get Platforms */
/** Get Platforms */
$stats['Platforms'] = $dbForConsole->count('platforms', [
Query::equal('projectInternalId', [$project->getInternalId()]),
Query::equal('projectInternalId', [$project->getInternalId()]),
]);
} catch (\Throwable) {
$stats['Platforms'] = 0;
@@ -242,28 +242,26 @@ class CalcTierStats extends Action
try {
$buckets = $dbForProject->find('buckets', []);
foreach ($buckets as $bucket) {
$file = $dbForProject->findOne('bucket_' . $bucket->getInternalId(), [Query::orderDesc('sizeOriginal'),]);
$file = $dbForProject->findOne('bucket_'.$bucket->getInternalId(), [Query::orderDesc('sizeOriginal')]);
if (empty($file)) {
continue;
}
$filesSum += $dbForProject->sum('bucket_' . $bucket->getInternalId(), 'sizeOriginal', [], 0);
$filesCount += $dbForProject->count('bucket_' . $bucket->getInternalId(), []);
$filesSum += $dbForProject->sum('bucket_'.$bucket->getInternalId(), 'sizeOriginal', [], 0);
$filesCount += $dbForProject->count('bucket_'.$bucket->getInternalId(), []);
if ($file->getAttribute('sizeOriginal') > $maxFileSize) {
$maxFileSize = $file->getAttribute('sizeOriginal');
}
$counter++;
}
} catch (\Throwable) {
;
}
$stats['Buckets'] = $counter;
$stats['Files'] = $filesCount;
$stats['Storage (bytes)'] = $filesSum;
$stats['Max File Size (bytes)'] = $maxFileSize;
try {
/** Get Total Functions */
/** Get Total Functions */
$stats['Databases'] = $dbForProject->count('databases', []);
} catch (\Throwable) {
$stats['Databases'] = 0;
@@ -292,7 +290,7 @@ class CalcTierStats extends Action
$csv->insertOne(array_values($stats));
} catch (\Throwable $th) {
Console::error('Failed on project ("' . $project->getId() . '") version with error on File: ' . $th->getFile() . ' line no: ' . $th->getline() . ' with message: ' . $th->getMessage());
Console::error('Failed on project ("'.$project->getId().'") version with error on File: '.$th->getFile().' line no: '.$th->getline().' with message: '.$th->getMessage());
} finally {
$pools
->get($db)
@@ -311,7 +309,7 @@ class CalcTierStats extends Action
$count = $count + $sum;
}
Console::log('Iterated through ' . $count - 1 . '/' . $totalProjects . ' projects...');
Console::log('Iterated through '.$count - 1 .'/'.$totalProjects.' projects...');
$pools
->get('console')
@@ -341,7 +339,7 @@ class CalcTierStats extends Action
/** Content */
$mail->Subject = "Cloud Report for {$this->date}";
$mail->Body = "Please find the daily cloud report atttached";
$mail->Body = 'Please find the daily cloud report atttached';
$mail->send();
Console::success('Email has been sent!');
} catch (Exception $e) {
+13 -14
View File
@@ -3,14 +3,14 @@
namespace Appwrite\Platform\Tasks;
use Exception;
use League\Csv\Writer;
use PHPMailer\PHPMailer\PHPMailer;
use Utopia\App;
use Utopia\Platform\Action;
use Utopia\Cache\Cache;
use Utopia\CLI\Console;
use Utopia\Database\Database;
use Utopia\Database\Query;
use League\Csv\Writer;
use PHPMailer\PHPMailer\PHPMailer;
use Utopia\Platform\Action;
use Utopia\Pools\Group;
use Utopia\Registry\Registry;
@@ -21,11 +21,13 @@ class CalcUsersStats extends Action
'Project Name',
'Team ID',
'Team name',
'Users'
'Users',
];
protected string $directory = '/usr/local';
protected string $path;
protected string $date;
public static function getName(): string
@@ -35,7 +37,6 @@ class CalcUsersStats extends Action
public function __construct()
{
$this
->desc('Get stats for projects')
->inject('pools')
@@ -52,7 +53,7 @@ class CalcUsersStats extends Action
//docker compose exec -t appwrite calc-users-stats
Console::title('Cloud Users calculation V1');
Console::success(APP_NAME . ' cloud Users calculation has started');
Console::success(APP_NAME.' cloud Users calculation has started');
/* Initialise new Utopia app */
$app = new App('UTC');
@@ -73,9 +74,8 @@ class CalcUsersStats extends Action
$limit = 30;
$sum = 30;
$offset = 0;
while (!empty($projects)) {
while (! empty($projects)) {
foreach ($projects as $project) {
/**
* Skip user projects with id 'console'
*/
@@ -94,7 +94,7 @@ class CalcUsersStats extends Action
$dbForProject = new Database($adapter, $cache);
$dbForProject->setDefaultDatabase('appwrite');
$dbForProject->setNamespace('_' . $project->getInternalId());
$dbForProject->setNamespace('_'.$project->getInternalId());
/** Get Project ID */
$stats['Project ID'] = $project->getId();
@@ -102,7 +102,6 @@ class CalcUsersStats extends Action
/** Get Project Name */
$stats['Project Name'] = $project->getAttribute('name');
/** Get Team Name and Id */
$teamId = $project->getAttribute('teamId', null);
$teamName = null;
@@ -111,7 +110,7 @@ class CalcUsersStats extends Action
$teamName = $team->getAttribute('name');
}
$stats['Team ID'] = $teamId;
$stats['Team ID'] = $teamId;
$stats['Team name'] = $teamName;
/** Get Total Users */
@@ -119,7 +118,7 @@ class CalcUsersStats extends Action
$csv->insertOne(array_values($stats));
} catch (\Throwable $th) {
Console::error('Failed to update project ("' . $project->getId() . '") version with error: ' . $th->getMessage());
Console::error('Failed to update project ("'.$project->getId().'") version with error: '.$th->getMessage());
} finally {
$pools
->get($db)
@@ -137,7 +136,7 @@ class CalcUsersStats extends Action
$offset = $offset + $limit;
$count = $count + $sum;
}
Console::log('Iterated through ' . $count - 1 . '/' . $totalProjects . ' projects...');
Console::log('Iterated through '.$count - 1 .'/'.$totalProjects.' projects...');
$pools
->get('console')
->reclaim();
@@ -166,7 +165,7 @@ class CalcUsersStats extends Action
/** Content */
$mail->Subject = "Cloud Report for {$this->date}";
$mail->Body = "Please find the daily cloud report atttached";
$mail->Body = 'Please find the daily cloud report atttached';
$mail->send();
Console::success('Email has been sent!');
} catch (Exception $e) {
@@ -4,12 +4,12 @@ namespace Appwrite\Platform\Tasks;
use Utopia\Cache\Adapter\Filesystem;
use Utopia\Cache\Cache;
use Utopia\Platform\Action;
use Utopia\CLI\Console;
use Utopia\Database\Query;
use Utopia\Database\Database;
use Utopia\Database\Query;
use Utopia\Database\Validator\Authorization;
use Utopia\Database\Validator\UID;
use Utopia\Platform\Action;
class ClearCardCache extends Action
{
@@ -33,12 +33,12 @@ class ClearCardCache extends Action
Authorization::setDefaultStatus(false);
Console::title('ClearCardCache V1');
Console::success(APP_NAME . ' ClearCardCache v1 has started');
$resources = ['card/' . $userId, 'card-back/' . $userId, 'card-og/' . $userId];
Console::success(APP_NAME.' ClearCardCache v1 has started');
$resources = ['card/'.$userId, 'card-back/'.$userId, 'card-og/'.$userId];
$caches = Authorization::skip(fn () => $dbForConsole->find('cache', [
Query::equal('resource', $resources),
Query::limit(100)
Query::limit(100),
]));
$count = \count($caches);
@@ -49,7 +49,7 @@ class ClearCardCache extends Action
$key = $cache->getId();
$cacheFolder = new Cache(
new Filesystem(APP_STORAGE_CACHE . DIRECTORY_SEPARATOR . 'app-console')
new Filesystem(APP_STORAGE_CACHE.DIRECTORY_SEPARATOR.'app-console')
);
$cacheFolder->purge($key);
@@ -57,6 +57,6 @@ class ClearCardCache extends Action
Authorization::skip(fn () => $dbForConsole->deleteDocument('cache', $cache->getId()));
}
Console::success(APP_NAME . ' ClearCardCache v1 has finished');
Console::success(APP_NAME.' ClearCardCache v1 has finished');
}
}
+45 -46
View File
@@ -2,16 +2,16 @@
namespace Appwrite\Platform\Tasks;
use Appwrite\ClamAV\Network;
use Utopia\App;
use Utopia\CLI\Console;
use Appwrite\ClamAV\Network;
use Utopia\Logger\Logger;
use Utopia\Storage\Device\Local;
use Utopia\Storage\Storage;
use Utopia\Config\Config;
use Utopia\Domains\Domain;
use Utopia\Logger\Logger;
use Utopia\Platform\Action;
use Utopia\Registry\Registry;
use Utopia\Storage\Device\Local;
use Utopia\Storage\Storage;
class Doctor extends Action
{
@@ -35,24 +35,24 @@ class Doctor extends Action
/ \ ) __/ ) __/\ /\ / ) / )( )( ) _) _ )(( O )
\_/\_/(__) (__) (_/\_)(__\_)(__) (__) (____)(_)(__)\__/ ");
Console::log("\n" . '👩‍⚕️ Running ' . APP_NAME . ' Doctor for version ' . App::getEnv('_APP_VERSION', 'UNKNOWN') . ' ...' . "\n");
Console::log("\n".'👩‍⚕️ Running '.APP_NAME.' Doctor for version '.App::getEnv('_APP_VERSION', 'UNKNOWN').' ...'."\n");
Console::log('[Settings]');
$domain = new Domain(App::getEnv('_APP_DOMAIN'));
if (!$domain->isKnown() || $domain->isTest()) {
Console::log('🔴 Hostname has no public suffix (' . $domain->get() . ')');
if (! $domain->isKnown() || $domain->isTest()) {
Console::log('🔴 Hostname has no public suffix ('.$domain->get().')');
} else {
Console::log('🟢 Hostname has a public suffix (' . $domain->get() . ')');
Console::log('🟢 Hostname has a public suffix ('.$domain->get().')');
}
$domain = new Domain(App::getEnv('_APP_DOMAIN_TARGET'));
if (!$domain->isKnown() || $domain->isTest()) {
Console::log('🔴 CNAME target has no public suffix (' . $domain->get() . ')');
if (! $domain->isKnown() || $domain->isTest()) {
Console::log('🔴 CNAME target has no public suffix ('.$domain->get().')');
} else {
Console::log('🟢 CNAME target has a public suffix (' . $domain->get() . ')');
Console::log('🟢 CNAME target has a public suffix ('.$domain->get().')');
}
if (App::getEnv('_APP_OPENSSL_KEY_V1') === 'your-secret-key' || empty(App::getEnv('_APP_OPENSSL_KEY_V1'))) {
@@ -96,22 +96,21 @@ class Doctor extends Action
$providerName = App::getEnv('_APP_LOGGING_PROVIDER', '');
$providerConfig = App::getEnv('_APP_LOGGING_CONFIG', '');
if (empty($providerName) || empty($providerConfig) || !Logger::hasProvider($providerName)) {
if (empty($providerName) || empty($providerConfig) || ! Logger::hasProvider($providerName)) {
Console::log('🔴 Logging adapter is disabled');
} else {
Console::log('🟢 Logging adapter is enabled (' . $providerName . ')');
Console::log('🟢 Logging adapter is enabled ('.$providerName.')');
}
\sleep(0.2);
try {
Console::log("\n" . '[Connectivity]');
Console::log("\n".'[Connectivity]');
} catch (\Throwable $th) {
//throw $th;
}
$pools = $register->get('pools'); /** @var \Utopia\Pools\Group $pools */
$configs = [
'Console.DB' => Config::getParam('pools-console'),
'Projects.DB' => Config::getParam('pools-database'),
@@ -123,12 +122,12 @@ class Doctor extends Action
$adapter = $pools->get($database)->pop()->getResource();
if ($adapter->ping()) {
Console::success('🟢 ' . str_pad("{$key}({$database})", 50, '.') . 'connected');
Console::success('🟢 '.str_pad("{$key}({$database})", 50, '.').'connected');
} else {
Console::error('🔴 ' . str_pad("{$key}({$database})", 47, '.') . 'disconnected');
Console::error('🔴 '.str_pad("{$key}({$database})", 47, '.').'disconnected');
}
} catch (\Throwable $th) {
Console::error('🔴 ' . str_pad("{$key}.({$database})", 47, '.') . 'disconnected');
Console::error('🔴 '.str_pad("{$key}.({$database})", 47, '.').'disconnected');
}
}
}
@@ -146,12 +145,12 @@ class Doctor extends Action
$adapter = $pools->get($pool)->pop()->getResource();
if ($adapter->ping()) {
Console::success('🟢 ' . str_pad("{$key}({$pool})", 50, '.') . 'connected');
Console::success('🟢 '.str_pad("{$key}({$pool})", 50, '.').'connected');
} else {
Console::error('🔴 ' . str_pad("{$key}({$pool})", 47, '.') . 'disconnected');
Console::error('🔴 '.str_pad("{$key}({$pool})", 47, '.').'disconnected');
}
} catch (\Throwable $th) {
Console::error('🔴 ' . str_pad("{$key}({$pool})", 47, '.') . 'disconnected');
Console::error('🔴 '.str_pad("{$key}({$pool})", 47, '.').'disconnected');
}
}
}
@@ -164,12 +163,12 @@ class Doctor extends Action
);
if ((@$antivirus->ping())) {
Console::success('🟢 ' . str_pad("Antivirus", 50, '.') . 'connected');
Console::success('🟢 '.str_pad('Antivirus', 50, '.').'connected');
} else {
Console::error('🔴 ' . str_pad("Antivirus", 47, '.') . 'disconnected');
Console::error('🔴 '.str_pad('Antivirus', 47, '.').'disconnected');
}
} catch (\Throwable $th) {
Console::error('🔴 ' . str_pad("Antivirus", 47, '.') . 'disconnected');
Console::error('🔴 '.str_pad('Antivirus', 47, '.').'disconnected');
}
}
@@ -182,9 +181,9 @@ class Doctor extends Action
$mail->AltBody = 'Hello World';
$mail->send();
Console::success('🟢 ' . str_pad("SMTP", 50, '.') . 'connected');
Console::success('🟢 '.str_pad('SMTP', 50, '.').'connected');
} catch (\Throwable $th) {
Console::error('🔴 ' . str_pad("SMTP", 47, '.') . 'disconnected');
Console::error('🔴 '.str_pad('SMTP', 47, '.').'disconnected');
}
\sleep(0.2);
@@ -194,24 +193,24 @@ class Doctor extends Action
foreach (
[
'Uploads' => APP_STORAGE_UPLOADS,
'Cache' => APP_STORAGE_CACHE,
'Config' => APP_STORAGE_CONFIG,
'Certs' => APP_STORAGE_CERTIFICATES
'Uploads' => APP_STORAGE_UPLOADS,
'Cache' => APP_STORAGE_CACHE,
'Config' => APP_STORAGE_CONFIG,
'Certs' => APP_STORAGE_CERTIFICATES,
] as $key => $volume
) {
$device = new Local($volume);
if (\is_readable($device->getRoot())) {
Console::success('🟢 ' . $key . ' Volume is readable');
Console::success('🟢 '.$key.' Volume is readable');
} else {
Console::error('🔴 ' . $key . ' Volume is unreadable');
Console::error('🔴 '.$key.' Volume is unreadable');
}
if (\is_writable($device->getRoot())) {
Console::success('🟢 ' . $key . ' Volume is writeable');
Console::success('🟢 '.$key.' Volume is writeable');
} else {
Console::error('🔴 ' . $key . ' Volume is unwriteable');
Console::error('🔴 '.$key.' Volume is unwriteable');
}
}
@@ -222,10 +221,10 @@ class Doctor extends Action
foreach (
[
'Uploads' => APP_STORAGE_UPLOADS,
'Cache' => APP_STORAGE_CACHE,
'Config' => APP_STORAGE_CONFIG,
'Certs' => APP_STORAGE_CERTIFICATES
'Uploads' => APP_STORAGE_UPLOADS,
'Cache' => APP_STORAGE_CACHE,
'Config' => APP_STORAGE_CONFIG,
'Certs' => APP_STORAGE_CERTIFICATES,
] as $key => $volume
) {
$device = new Local($volume);
@@ -233,32 +232,32 @@ class Doctor extends Action
$percentage = (($device->getPartitionTotalSpace() - $device->getPartitionFreeSpace())
/ $device->getPartitionTotalSpace()) * 100;
$message = $key . ' Volume has ' . Storage::human($device->getPartitionFreeSpace()) . ' free space (' . \round($percentage, 2) . '% used)';
$message = $key.' Volume has '.Storage::human($device->getPartitionFreeSpace()).' free space ('.\round($percentage, 2).'% used)';
if ($percentage < 80) {
Console::success('🟢 ' . $message);
Console::success('🟢 '.$message);
} else {
Console::error('🔴 ' . $message);
Console::error('🔴 '.$message);
}
}
try {
if (App::isProduction()) {
Console::log('');
$version = \json_decode(@\file_get_contents(App::getEnv('_APP_HOME', 'http://localhost') . '/v1/health/version'), true);
$version = \json_decode(@\file_get_contents(App::getEnv('_APP_HOME', 'http://localhost').'/v1/health/version'), true);
if ($version && isset($version['version'])) {
if (\version_compare($version['version'], App::getEnv('_APP_VERSION', 'UNKNOWN')) === 0) {
Console::info('You are running the latest version of ' . APP_NAME . '! 🥳');
Console::info('You are running the latest version of '.APP_NAME.'! 🥳');
} else {
Console::info('A new version (' . $version['version'] . ') is available! 🥳' . "\n");
Console::info('A new version ('.$version['version'].') is available! 🥳'."\n");
}
} else {
Console::error('Failed to check for a newer version' . "\n");
Console::error('Failed to check for a newer version'."\n");
}
}
} catch (\Throwable $th) {
Console::error('Failed to check for a newer version' . "\n");
Console::error('Failed to check for a newer version'."\n");
}
}
}
+49 -50
View File
@@ -4,17 +4,17 @@ namespace Appwrite\Platform\Tasks;
use Appwrite\Network\Validator\Origin;
use Exception;
use Utopia\App;
use Utopia\Platform\Action;
use Utopia\Cache\Cache;
use Utopia\CLI\Console;
use Utopia\Database\Database;
use Utopia\Database\Query;
use Utopia\Database\Validator\Authorization;
use Utopia\Analytics\Adapter\Mixpanel;
use Utopia\Analytics\Event;
use Utopia\App;
use Utopia\Cache\Cache;
use Utopia\CLI\Console;
use Utopia\Config\Config;
use Utopia\Database\Database;
use Utopia\Database\Document;
use Utopia\Database\Query;
use Utopia\Database\Validator\Authorization;
use Utopia\Platform\Action;
use Utopia\Pools\Group;
class Hamster extends Action
@@ -67,7 +67,8 @@ class Hamster extends Action
* Skip user projects with id 'console'
*/
if ($project->getId() === 'console') {
Console::info("Skipping project console");
Console::info('Skipping project console');
return;
}
@@ -82,7 +83,7 @@ class Hamster extends Action
$dbForProject = new Database($adapter, $cache);
$dbForProject->setDefaultDatabase('appwrite');
$dbForProject->setNamespace('_' . $project->getInternalId());
$dbForProject->setNamespace('_'.$project->getInternalId());
$statsPerProject = [];
@@ -101,7 +102,7 @@ class Hamster extends Action
$statsPerProject['custom_functions'] = $dbForProject->count('functions', [], APP_LIMIT_COUNT);
foreach (\array_keys(Config::getParam('runtimes')) as $runtime) {
$statsPerProject['custom_functions_' . $runtime] = $dbForProject->count('functions', [
$statsPerProject['custom_functions_'.$runtime] = $dbForProject->count('functions', [
Query::equal('runtime', [$runtime]),
], APP_LIMIT_COUNT);
}
@@ -116,7 +117,7 @@ class Hamster extends Action
$teamInternalId = $project->getAttribute('teamInternalId', null);
if ($teamInternalId) {
$statsPerProject['custom_organization_members'] = $dbForConsole->count('memberships', [
Query::equal('teamInternalId', [$teamInternalId])
Query::equal('teamInternalId', [$teamInternalId]),
], APP_LIMIT_COUNT);
} else {
$statsPerProject['custom_organization_members'] = 0;
@@ -128,8 +129,8 @@ class Hamster extends Action
Query::equal('teamInternalId', [$teamInternalId]),
]);
if (!$membership || $membership->isEmpty()) {
throw new Exception('Membership not found. Skipping project : ' . $project->getId());
if (! $membership || $membership->isEmpty()) {
throw new Exception('Membership not found. Skipping project : '.$project->getId());
}
$userInternalId = $membership->getAttribute('userInternalId', null);
@@ -146,42 +147,42 @@ class Hamster extends Action
/** Get Domains */
$statsPerProject['custom_domains'] = $dbForConsole->count('domains', [
Query::equal('projectInternalId', [$project->getInternalId()]),
Query::limit(APP_LIMIT_COUNT)
Query::limit(APP_LIMIT_COUNT),
]);
/** Get Platforms */
$platforms = $dbForConsole->find('platforms', [
Query::equal('projectInternalId', [$project->getInternalId()]),
Query::limit(APP_LIMIT_COUNT)
Query::limit(APP_LIMIT_COUNT),
]);
$statsPerProject['custom_platforms_web'] = sizeof(array_filter($platforms, function ($platform) {
$statsPerProject['custom_platforms_web'] = count(array_filter($platforms, function ($platform) {
return $platform['type'] === 'web';
}));
$statsPerProject['custom_platforms_android'] = sizeof(array_filter($platforms, function ($platform) {
$statsPerProject['custom_platforms_android'] = count(array_filter($platforms, function ($platform) {
return $platform['type'] === 'android';
}));
$statsPerProject['custom_platforms_apple'] = sizeof(array_filter($platforms, function ($platform) {
$statsPerProject['custom_platforms_apple'] = count(array_filter($platforms, function ($platform) {
return str_contains($platform['type'], 'apple');
}));
$statsPerProject['custom_platforms_flutter'] = sizeof(array_filter($platforms, function ($platform) {
$statsPerProject['custom_platforms_flutter'] = count(array_filter($platforms, function ($platform) {
return str_contains($platform['type'], 'flutter');
}));
$flutterPlatforms = [Origin::CLIENT_TYPE_FLUTTER_ANDROID, Origin::CLIENT_TYPE_FLUTTER_IOS, Origin::CLIENT_TYPE_FLUTTER_MACOS, Origin::CLIENT_TYPE_FLUTTER_WINDOWS, Origin::CLIENT_TYPE_FLUTTER_LINUX];
foreach ($flutterPlatforms as $flutterPlatform) {
$statsPerProject['custom_platforms_' . $flutterPlatform] = sizeof(array_filter($platforms, function ($platform) use ($flutterPlatform) {
$statsPerProject['custom_platforms_'.$flutterPlatform] = count(array_filter($platforms, function ($platform) use ($flutterPlatform) {
return $platform['type'] === $flutterPlatform;
}));
}
$statsPerProject['custom_platforms_api_keys'] = $dbForConsole->count('keys', [
Query::equal('projectInternalId', [$project->getInternalId()]),
Query::limit(APP_LIMIT_COUNT)
Query::limit(APP_LIMIT_COUNT),
]);
/** Get Usage $statsPerProject */
@@ -209,17 +210,17 @@ class Hamster extends Action
Query::orderDesc('time'),
]);
$statsPerProject[$key . '_' . $periodKey] = [];
$statsPerProject[$key.'_'.$periodKey] = [];
foreach ($requestDocs as $requestDoc) {
$statsPerProject[$key . '_' . $periodKey][] = [
$statsPerProject[$key.'_'.$periodKey][] = [
'value' => $requestDoc->getAttribute('value'),
'date' => $requestDoc->getAttribute('time'),
];
}
$statsPerProject[$key . '_' . $periodKey] = array_reverse($statsPerProject[$key . '_' . $periodKey]);
$statsPerProject[$key.'_'.$periodKey] = array_reverse($statsPerProject[$key.'_'.$periodKey]);
// Calculate aggregate of each metric
$statsPerProject[$key . '_' . $periodKey] = array_sum(array_column($statsPerProject[$key . '_' . $periodKey], 'value'));
$statsPerProject[$key.'_'.$periodKey] = array_sum(array_column($statsPerProject[$key.'_'.$periodKey], 'value'));
}
}
});
@@ -228,11 +229,11 @@ class Hamster extends Action
/** Send data to mixpanel */
$res = $this->mixpanel->createProfile($statsPerProject['email'], '', [
'name' => $statsPerProject['name'],
'email' => $statsPerProject['email']
'email' => $statsPerProject['email'],
]);
if (!$res) {
Console::error('Failed to create user profile for project: ' . $project->getId());
if (! $res) {
Console::error('Failed to create user profile for project: '.$project->getId());
}
$event = new Event();
@@ -240,12 +241,12 @@ class Hamster extends Action
->setName('Project Daily Usage')
->setProps($statsPerProject);
$res = $this->mixpanel->createEvent($event);
if (!$res) {
Console::error('Failed to create event for project: ' . $project->getId());
if (! $res) {
Console::error('Failed to create event for project: '.$project->getId());
}
}
} catch (Exception $e) {
Console::error('Failed to send stats for project: ' . $project->getId());
Console::error('Failed to send stats for project: '.$project->getId());
Console::error($e->getMessage());
} finally {
$pools
@@ -257,9 +258,8 @@ class Hamster extends Action
public function action(Group $pools, Cache $cache, Database $dbForConsole): void
{
Console::title('Cloud Hamster V1');
Console::success(APP_NAME . ' cloud hamster process has started');
Console::success(APP_NAME.' cloud hamster process has started');
$sleep = (int) App::getEnv('_APP_HAMSTER_INTERVAL', '30'); // 30 seconds (by default)
@@ -278,7 +278,7 @@ class Hamster extends Action
$delay = $next->getTimestamp() - $now->getTimestamp();
}
Console::log('[' . $now->format("Y-m-d H:i:s.v") . '] Delaying for ' . $delay . ' setting loop to [' . $next->format("Y-m-d H:i:s.v") . ']');
Console::log('['.$now->format('Y-m-d H:i:s.v').'] Delaying for '.$delay.' setting loop to ['.$next->format('Y-m-d H:i:s.v').']');
Console::loop(function () use ($pools, $cache, $dbForConsole, $sleep) {
$now = date('d-m-Y H:i:s', time());
@@ -325,12 +325,12 @@ class Hamster extends Action
$results = $dbForConsole->find($collection, \array_merge([
Query::limit($limit),
Query::offset($count)
Query::offset($count),
]));
$sum = count($results);
Console::log('Processing chunk #' . $chunk . '. Found ' . $sum . ' documents');
Console::log('Processing chunk #'.$chunk.'. Found '.$sum.' documents');
foreach ($results as $document) {
call_user_func($callback, $dbForConsole, $document);
@@ -340,12 +340,11 @@ class Hamster extends Action
$executionEnd = \microtime(true);
Console::log("Processed {$count} document by group in " . ($executionEnd - $executionStart) . " seconds");
Console::log("Processed {$count} document by group in ".($executionEnd - $executionStart).' seconds');
}
protected function getStatsPerOrganization(Database $dbForConsole)
{
$this->calculateByGroup('teams', $dbForConsole, function (Database $dbForConsole, Document $document) {
try {
$statsPerOrganization = [];
@@ -358,8 +357,8 @@ class Hamster extends Action
Query::equal('teamInternalId', [$document->getInternalId()]),
]);
if (!$membership || $membership->isEmpty()) {
throw new Exception('Membership not found. Skipping organization : ' . $document->getId());
if (! $membership || $membership->isEmpty()) {
throw new Exception('Membership not found. Skipping organization : '.$document->getId());
}
$userInternalId = $membership->getAttribute('userInternalId', null);
@@ -380,11 +379,11 @@ class Hamster extends Action
/** Number of projects in this organization */
$statsPerOrganization['projects'] = $dbForConsole->count('projects', [
Query::equal('teamId', [$document->getId()]),
Query::limit(APP_LIMIT_COUNT)
Query::limit(APP_LIMIT_COUNT),
]);
if (!isset($statsPerOrganization['email'])) {
throw new Exception('Email not found. Skipping organization : ' . $document->getId());
if (! isset($statsPerOrganization['email'])) {
throw new Exception('Email not found. Skipping organization : '.$document->getId());
}
$event = new Event();
@@ -392,8 +391,8 @@ class Hamster extends Action
->setName('Organization Daily Usage')
->setProps($statsPerOrganization);
$res = $this->mixpanel->createEvent($event);
if (!$res) {
throw new Exception('Failed to create event for organization : ' . $document->getId());
if (! $res) {
throw new Exception('Failed to create event for organization : '.$document->getId());
}
} catch (Exception $e) {
Console::error($e->getMessage());
@@ -419,11 +418,11 @@ class Hamster extends Action
/** Number of teams this user is a part of */
$statsPerUser['memberships'] = $dbForConsole->count('memberships', [
Query::equal('userInternalId', [$document->getInternalId()]),
Query::limit(APP_LIMIT_COUNT)
Query::limit(APP_LIMIT_COUNT),
]);
if (!isset($statsPerUser['email'])) {
throw new Exception('User has no email: ' . $document->getId());
if (! isset($statsPerUser['email'])) {
throw new Exception('User has no email: '.$document->getId());
}
/** Send data to mixpanel */
@@ -433,8 +432,8 @@ class Hamster extends Action
->setProps($statsPerUser);
$res = $this->mixpanel->createEvent($event);
if (!$res) {
throw new Exception('Failed to create user profile for user: ' . $document->getId());
if (! $res) {
throw new Exception('Failed to create user profile for user: '.$document->getId());
}
} catch (Exception $e) {
Console::error($e->getMessage());
+35 -33
View File
@@ -9,8 +9,8 @@ use Appwrite\Utopia\View;
use Utopia\Analytics\GoogleAnalytics;
use Utopia\CLI\Console;
use Utopia\Config\Config;
use Utopia\Validator\Text;
use Utopia\Platform\Action;
use Utopia\Validator\Text;
class Install extends Action
{
@@ -70,19 +70,19 @@ class Install extends Action
Console::success('Starting Appwrite installation...');
// Create directory with write permissions
if (null !== $path && !\file_exists(\dirname($path))) {
if (!@\mkdir(\dirname($path), 0755, true)) {
Console::error('Can\'t create directory ' . \dirname($path));
if (null !== $path && ! \file_exists(\dirname($path))) {
if (! @\mkdir(\dirname($path), 0755, true)) {
Console::error('Can\'t create directory '.\dirname($path));
Console::exit(1);
}
}
$data = @file_get_contents($path . '/docker-compose.yml');
$data = @file_get_contents($path.'/docker-compose.yml');
if ($data !== false) {
$time = \time();
Console::info('Compose file found, creating backup: docker-compose.yml.' . $time . '.backup');
file_put_contents($path . '/docker-compose.yml.' . $time . '.backup', $data);
Console::info('Compose file found, creating backup: docker-compose.yml.'.$time.'.backup');
file_put_contents($path.'/docker-compose.yml.'.$time.'.backup', $data);
$compose = new Compose($data);
$appwrite = $compose->getService('appwrite');
$oldVersion = ($appwrite) ? $appwrite->getImageVersion() : null;
@@ -91,14 +91,14 @@ class Install extends Action
} catch (\Throwable $th) {
$ports = [
$defaultHTTPPort => $defaultHTTPPort,
$defaultHTTPSPort => $defaultHTTPSPort
$defaultHTTPSPort => $defaultHTTPSPort,
];
Console::warning('Traefik not found. Falling back to default ports.');
}
if ($oldVersion) {
foreach ($compose->getServices() as $service) { // Fetch all env vars from previous compose file
if (!$service) {
if (! $service) {
continue;
}
@@ -116,11 +116,11 @@ class Install extends Action
}
}
$data = @file_get_contents($path . '/.env');
$data = @file_get_contents($path.'/.env');
if ($data !== false) { // Fetch all env vars from previous .env file
Console::info('Env file found, creating backup: .env.' . $time . '.backup');
file_put_contents($path . '/.env.' . $time . '.backup', $data);
Console::info('Env file found, creating backup: .env.'.$time.'.backup');
file_put_contents($path.'/.env.'.$time.'.backup', $data);
$env = new Env($data);
foreach ($env->list() as $key => $value) {
@@ -148,40 +148,44 @@ class Install extends Action
}
if (empty($httpPort)) {
$httpPort = Console::confirm('Choose your server HTTP port: (default: ' . $defaultHTTPPort . ')');
$httpPort = Console::confirm('Choose your server HTTP port: (default: '.$defaultHTTPPort.')');
$httpPort = ($httpPort) ? $httpPort : $defaultHTTPPort;
}
if (empty($httpsPort)) {
$httpsPort = Console::confirm('Choose your server HTTPS port: (default: ' . $defaultHTTPSPort . ')');
$httpsPort = Console::confirm('Choose your server HTTPS port: (default: '.$defaultHTTPSPort.')');
$httpsPort = ($httpsPort) ? $httpsPort : $defaultHTTPSPort;
}
$input = [];
foreach ($vars as $var) {
if (!empty($var['filter']) && ($interactive !== 'Y' || !Console::isInteractive())) {
if (! empty($var['filter']) && ($interactive !== 'Y' || ! Console::isInteractive())) {
if ($data && $var['default'] !== null) {
$input[$var['name']] = $var['default'];
continue;
}
if ($var['filter'] === 'token') {
$input[$var['name']] = Auth::tokenGenerator();
continue;
}
if ($var['filter'] === 'password') {
$input[$var['name']] = Auth::passwordGenerator();
continue;
}
}
if (!$var['required'] || !Console::isInteractive() || $interactive !== 'Y') {
if (! $var['required'] || ! Console::isInteractive() || $interactive !== 'Y') {
$input[$var['name']] = $var['default'];
continue;
}
$input[$var['name']] = Console::confirm($var['question'] . ' (default: \'' . $var['default'] . '\')');
$input[$var['name']] = Console::confirm($var['question'].' (default: \''.$var['default'].'\')');
if (empty($input[$var['name']])) {
$input[$var['name']] = $var['default'];
@@ -191,38 +195,36 @@ class Install extends Action
if ($input[$var['name']] !== 'localhost') {
Console::warning("\nIf you haven't already done so, set the following record for {$input[$var['name']]} on your DNS provider:\n");
$mask = "%-15.15s %-10.10s %-30.30s\n";
printf($mask, "Type", "Name", "Value");
printf($mask, "A or AAAA", "@", "<YOUR PUBLIC IP>");
printf($mask, 'Type', 'Name', 'Value');
printf($mask, 'A or AAAA', '@', '<YOUR PUBLIC IP>');
Console::warning("\nUse 'AAAA' if you're using an IPv6 address and 'A' if you're using an IPv4 address.\n");
}
}
}
$templateForCompose = new View(__DIR__ . '/../views/install/compose.phtml');
$templateForEnv = new View(__DIR__ . '/../views/install/env.phtml');
$templateForCompose = new View(__DIR__.'/../views/install/compose.phtml');
$templateForEnv = new View(__DIR__.'/../views/install/env.phtml');
$templateForCompose
->setParam('httpPort', $httpPort)
->setParam('httpsPort', $httpsPort)
->setParam('version', APP_VERSION_STABLE)
->setParam('organization', $organization)
->setParam('image', $image)
;
->setParam('image', $image);
$templateForEnv
->setParam('vars', $input)
;
->setParam('vars', $input);
if (!file_put_contents($path . '/docker-compose.yml', $templateForCompose->render(false))) {
if (! file_put_contents($path.'/docker-compose.yml', $templateForCompose->render(false))) {
$message = 'Failed to save Docker Compose file';
$analytics->createEvent('install/server', 'install', APP_VERSION_STABLE . ' - ' . $message);
$analytics->createEvent('install/server', 'install', APP_VERSION_STABLE.' - '.$message);
Console::error($message);
Console::exit(1);
}
if (!file_put_contents($path . '/.env', $templateForEnv->render(false))) {
if (! file_put_contents($path.'/.env', $templateForEnv->render(false))) {
$message = 'Failed to save environment variables file';
$analytics->createEvent('install/server', 'install', APP_VERSION_STABLE . ' - ' . $message);
$analytics->createEvent('install/server', 'install', APP_VERSION_STABLE.' - '.$message);
Console::error($message);
Console::exit(1);
}
@@ -233,23 +235,23 @@ class Install extends Action
foreach ($input as $key => $value) {
if ($value) {
$env .= $key . '=' . \escapeshellarg($value) . ' ';
$env .= $key.'='.\escapeshellarg($value).' ';
}
}
Console::log("Running \"docker compose up -d --remove-orphans --renew-anon-volumes\"");
Console::log('Running "docker compose up -d --remove-orphans --renew-anon-volumes"');
$exit = Console::execute("${env} docker compose --project-directory {$path} up -d --remove-orphans --renew-anon-volumes", '', $stdout, $stderr);
if ($exit !== 0) {
$message = 'Failed to install Appwrite dockers';
$analytics->createEvent('install/server', 'install', APP_VERSION_STABLE . ' - ' . $message);
$analytics->createEvent('install/server', 'install', APP_VERSION_STABLE.' - '.$message);
Console::error($message);
Console::error($stderr);
Console::exit($exit);
} else {
$message = 'Appwrite installed successfully';
$analytics->createEvent('install/server', 'install', APP_VERSION_STABLE . ' - ' . $message);
$analytics->createEvent('install/server', 'install', APP_VERSION_STABLE.' - '.$message);
Console::success($message);
}
}

Some files were not shown because too many files have changed in this diff Show More