diff --git a/.gitignore b/.gitignore index 83cfd4a1ee..16ce41ad7f 100644 --- a/.gitignore +++ b/.gitignore @@ -2,6 +2,9 @@ /vendor/ /node_modules/ /storage/uploads/ +/storage/cache +/storage/db +/storage/influxdb /tests/resources/storage/ /.idea/ .DS_Store diff --git a/app/config/providers.php b/app/config/providers.php index 58c29e05c6..5dc43e8e56 100644 --- a/app/config/providers.php +++ b/app/config/providers.php @@ -109,11 +109,17 @@ return [ 'enabled' => true, 'mock' => false, ], + 'twitter' => [ + 'developers' => 'https://developer.twitter.com/', + 'icon' => 'icon-twitter', + 'enabled' => false, + 'mock' => false + ], // Keep Last 'mock' => [ 'developers' => 'https://appwrite.io', 'icon' => 'icon-appwrite', 'enabled' => true, 'mock' => true, - ], + ] ]; diff --git a/app/controllers/auth.php b/app/controllers/auth.php index 0c8bbab205..253b478470 100644 --- a/app/controllers/auth.php +++ b/app/controllers/auth.php @@ -4,6 +4,7 @@ global $utopia, $register, $request, $response, $user, $audit, $webhook, $projec use Utopia\Exception; use Utopia\Validator\WhiteList; +use Utopia\Validator\ArrayList; use Utopia\Validator\Text; use Utopia\Validator\Email; use Utopia\Validator\Host; @@ -400,8 +401,9 @@ $utopia->get('/v1/auth/login/oauth/:provider') ->param('provider', '', function () use ($providers) { return new WhiteList(array_keys($providers)); }, 'OAuth Provider. Currently, supported providers are: ' . implode(', ', array_keys($providers))) ->param('success', '', function () use ($clients) { return new Host($clients); }, 'URL to redirect back to your app after a successful login attempt.') ->param('failure', '', function () use ($clients) { return new Host($clients); }, 'URL to redirect back to your app after a failed login attempt.') + ->param('scopes', [], function () { return new ArrayList(new Text(128)); }, 'An array of string where each can be max 128 chars', true) ->action( - function ($provider, $success, $failure) use ($response, $request, $project) { + function ($provider, $success, $failure, $scopes) use ($response, $request, $project) { $callback = $request->getServer('REQUEST_SCHEME', 'https').'://'.$request->getServer('HTTP_HOST').'/v1/auth/login/oauth/callback/'.$provider.'/'.$project->getUid(); $appId = $project->getAttribute('usersOauth'.ucfirst($provider).'Appid', ''); $appSecret = $project->getAttribute('usersOauth'.ucfirst($provider).'Secret', '{}'); @@ -423,7 +425,7 @@ $utopia->get('/v1/auth/login/oauth/:provider') throw new Exception('Provider is not supported', 501); } - $oauth = new $classname($appId, $appSecret, $callback, ['success' => $success, 'failure' => $failure]); + $oauth = new $classname($appId, $appSecret, $callback, ['success' => $success, 'failure' => $failure], $scopes); $response->redirect($oauth->getLoginURL()); } @@ -462,9 +464,6 @@ $utopia->get('/v1/auth/login/oauth/:provider/redirect') $defaultState = ['success' => $project->getAttribute('url', ''), 'failure' => '']; $validateURL = new URL(); - // Uncomment this while testing amazon oAuth - // $state = html_entity_decode($state); - $appId = $project->getAttribute('usersOauth'.ucfirst($provider).'Appid', ''); $appSecret = $project->getAttribute('usersOauth'.ucfirst($provider).'Secret', '{}'); diff --git a/app/controllers/shared/api.php b/app/controllers/shared/api.php index fef57029ca..1d95f5fada 100644 --- a/app/controllers/shared/api.php +++ b/app/controllers/shared/api.php @@ -8,9 +8,6 @@ use Database\Database; global $utopia, $request, $response, $register, $user, $project; $utopia->init(function () use ($utopia, $request, $response, $register, $user, $project) { - // if (is_null($project->getUid()) || Database::SYSTEM_COLLECTION_PROJECTS !== $project->getCollection()) { - // throw new Exception('Missing Project UID', 400); - // } $route = $utopia->match($request); diff --git a/public/images/oauth/twitter.png b/public/images/oauth/twitter.png new file mode 100644 index 0000000000..320a807f71 Binary files /dev/null and b/public/images/oauth/twitter.png differ diff --git a/src/Auth/OAuth.php b/src/Auth/OAuth.php index a96ebb7a68..89dde432f1 100644 --- a/src/Auth/OAuth.php +++ b/src/Auth/OAuth.php @@ -24,6 +24,11 @@ abstract class OAuth */ protected $state; + /** + * @var array + */ + protected $scopes; + /** * OAuth constructor. * @@ -31,13 +36,17 @@ abstract class OAuth * @param string $appSecret * @param string $callback * @param array $state + * @param array $scopes */ - public function __construct(string $appId, string $appSecret, string $callback, $state = []) + public function __construct(string $appId, string $appSecret, string $callback, $state = [], $scopes = []) { $this->appID = $appId; $this->appSecret = $appSecret; $this->callback = $callback; $this->state = $state; + foreach($scopes as $scope) { + $this->addScope($scope); + } } /** @@ -78,14 +87,34 @@ abstract class OAuth */ abstract public function getUserName(string $accessToken):string; + /** + * @param $scope + * + * @return $this + */ + protected function addScope(string $scope):OAuth{ + // Add a scope to the scopes array if it isn't already present + if (!in_array($scope, $this->scopes)){ + $this->scopes[] = $scope; + } + return $this; + } + + /** + * @return array + */ + protected function getScopes():array{ + return $this->scopes; + } + + // The parseState function was designed specifically for Amazon OAuth Adapter to override. // The response from Amazon is html encoded and hence it needs to be html_decoded before // json_decoding - /** * @param $state * - * @return json + * @return string */ public function parseState(string $state) { diff --git a/src/Auth/OAuth/Amazon.php b/src/Auth/OAuth/Amazon.php index 71bb8aaee6..64c04fdc90 100644 --- a/src/Auth/OAuth/Amazon.php +++ b/src/Auth/OAuth/Amazon.php @@ -15,6 +15,13 @@ class Amazon extends OAuth */ protected $user = []; + /** + * @var array + */ + protected $scopes = [ + "profile" + ]; + /** * @return string */ @@ -39,12 +46,13 @@ class Amazon extends OAuth */ public function getLoginURL(): string { - return 'https://www.amazon.com/ap/oa?' . - 'client_id='.urlencode($this->appID). - '&redirect_uri='.urlencode($this->callback). - '&response_type=code'. - '&state='.urlencode(json_encode($this->state)). - '&scope=profile'; + 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 + ]); } /** @@ -59,11 +67,13 @@ class Amazon extends OAuth 'POST', 'https://api.amazon.com/auth/o2/token', $headers, - 'code=' . urlencode($code) . - '&client_id=' . urlencode($this->appID) . - '&client_secret=' . urlencode($this->appSecret). - '&redirect_uri='.urlencode($this->callback). - '&grant_type=authorization_code' + http_build_query([ + 'code' => $code, + 'client_id' => $this->appID , + 'client_secret' => $this->appSecret, + 'redirect_uri' => $this->callback , + 'grant_type' => 'authorization_code' + ]) ); $accessToken = json_decode($accessToken, true); diff --git a/src/Auth/OAuth/Apple.php b/src/Auth/OAuth/Apple.php index fbe4b65b1a..3a5de8ebdc 100644 --- a/src/Auth/OAuth/Apple.php +++ b/src/Auth/OAuth/Apple.php @@ -14,6 +14,14 @@ class Apple extends OAuth */ protected $user = []; + /** + * @var array + */ + protected $scopes = [ + "name", + "email" + ]; + /** * @return string */ @@ -27,13 +35,14 @@ class Apple extends OAuth */ public function getLoginURL(): string { - return 'https://appleid.apple.com/auth/authorize?'. - 'client_id='.urlencode($this->appID). - '&redirect_uri='.urlencode($this->callback). - '&state='.urlencode(json_encode($this->state)). - '&response_type=code'. - '&response_mode=form_post'. - '&scope=name+email'; + 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()) + ]); } /** @@ -48,16 +57,15 @@ class Apple extends OAuth 'POST', 'https://appleid.apple.com/auth/token', $headers, - 'code='.urlencode($code). - '&client_id='.urlencode($this->appID). - '&client_secret='.urlencode($this->appSecret). - '&redirect_uri='.urlencode($this->callback). - '&grant_type=authorization_code' + http_build_query([ + 'code' => $code, + 'client_id' => $this->appID, + 'client_secret' => $this->appSecret, + 'redirect_uri' => $this->callback, + 'grant_type' => 'authorization_code' + ]) ); - var_dump($accessToken); - exit(); - $accessToken = json_decode($accessToken, true); if (isset($accessToken['access_token'])) { diff --git a/src/Auth/OAuth/Bitbucket.php b/src/Auth/OAuth/Bitbucket.php index 902c0a4238..9e2a86be69 100644 --- a/src/Auth/OAuth/Bitbucket.php +++ b/src/Auth/OAuth/Bitbucket.php @@ -14,6 +14,11 @@ class Bitbucket extends OAuth */ protected $user = []; + /** + * @var array + */ + protected $scopes = []; + /** * @return string */ @@ -27,10 +32,12 @@ class Bitbucket extends OAuth */ public function getLoginURL(): string { - return 'https://bitbucket.org/site/oauth2/authorize?' . - 'client_id=' . urlencode($this->appID). - '&state=' . urlencode(json_encode($this->state)). - '&response_type=code'; + return 'https://bitbucket.org/site/oauth2/authorize?'.http_build_query([ + 'response_type' => 'code', + 'client_id' => $this->appID, + 'scope' => implode(' ', $this->getScopes()), + 'state' => json_encode($this->state), + ]); } /** @@ -42,15 +49,17 @@ class Bitbucket extends OAuth { // Required as per Bitbucket Spec. $headers[] = 'Content-Type: application/x-www-form-urlencoded'; - + $accessToken = $this->request( 'POST', 'https://bitbucket.org/site/oauth2/access_token', $headers, - 'code=' . urlencode($code) . - '&client_id=' . urlencode($this->appID) . - '&client_secret=' . urlencode($this->appSecret). - '&grant_type=authorization_code' + http_build_query([ + 'code' => $code, + 'client_id' => $this->appID, + 'client_secret' => $this->appSecret, + 'grant_type' => 'authorization_code' + ]) ); $accessToken = json_decode($accessToken, true); diff --git a/src/Auth/OAuth/Discord.php b/src/Auth/OAuth/Discord.php index b23653e992..54cf5546b6 100644 --- a/src/Auth/OAuth/Discord.php +++ b/src/Auth/OAuth/Discord.php @@ -20,7 +20,7 @@ class Discord extends OAuth protected $user = []; - protected $scope = [ + protected $scopes = [ 'identify', 'email' ]; @@ -42,7 +42,7 @@ class Discord extends OAuth http_build_query([ 'response_type' => 'code', 'client_id' => $this->appID, - 'scope' => implode(' ', $this->scope), + 'scope' => implode(' ', $this->getScopes()), 'redirect_uri' => $this->callback ]); diff --git a/src/Auth/OAuth/Dropbox.php b/src/Auth/OAuth/Dropbox.php index a4a6335f36..db74215274 100644 --- a/src/Auth/OAuth/Dropbox.php +++ b/src/Auth/OAuth/Dropbox.php @@ -14,6 +14,11 @@ class Dropbox extends OAuth */ protected $user = []; + /** + * @var array + */ + protected $scopes = []; + /** * @return string */ @@ -27,11 +32,12 @@ class Dropbox extends OAuth */ public function getLoginURL(): string { - return 'https://www.dropbox.com/oauth2/authorize?'. - 'client_id='.urlencode($this->appID). - '&redirect_uri='.urlencode($this->callback). - '&state='.urlencode(json_encode($this->state)). - '&response_type=code'; + 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' + ]); } /** @@ -46,11 +52,13 @@ class Dropbox extends OAuth 'POST', 'https://api.dropboxapi.com/oauth2/token', $headers, - 'code='.urlencode($code). - '&client_id='.urlencode($this->appID). - '&client_secret='.urlencode($this->appSecret). - '&redirect_uri='.urlencode($this->callback). - '&grant_type=authorization_code' + http_build_query([ + 'code' => $code, + 'client_id' => $this->appID, + 'client_secret' => $this->appSecret, + 'redirect_uri' => $this->callback, + 'grant_type' => 'authorization_code' + ]) ); $accessToken = json_decode($accessToken, true); diff --git a/src/Auth/OAuth/Facebook.php b/src/Auth/OAuth/Facebook.php index ed50748bac..c3c348e493 100644 --- a/src/Auth/OAuth/Facebook.php +++ b/src/Auth/OAuth/Facebook.php @@ -16,6 +16,13 @@ class Facebook extends OAuth */ protected $user = []; + /** + * @var array + */ + protected $scopes = [ + 'email' + ]; + /** * @return string */ @@ -29,7 +36,12 @@ class Facebook extends OAuth */ public function getLoginURL():string { - return 'https://www.facebook.com/'.$this->version.'/dialog/oauth?client_id='.urlencode($this->appID).'&redirect_uri='.urlencode($this->callback).'&scope=email&state='.urlencode(json_encode($this->state)); + 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) + ]); } /** @@ -41,19 +53,20 @@ class Facebook extends OAuth { $accessToken = $this->request( 'GET', - 'https://graph.facebook.com/'.$this->version.'/oauth/access_token?'. - 'client_id='.urlencode($this->appID). - '&redirect_uri='.urlencode($this->callback). - '&client_secret='.urlencode($this->appSecret). - '&code='.urlencode($code) + '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 + ]) ); - $accessToken = json_decode($accessToken, true); // + $accessToken = json_decode($accessToken, true); if (isset($accessToken['access_token'])) { return $accessToken['access_token']; } - + return ''; } diff --git a/src/Auth/OAuth/GitHub.php b/src/Auth/OAuth/GitHub.php index 405f2f9f78..e0e056930d 100644 --- a/src/Auth/OAuth/GitHub.php +++ b/src/Auth/OAuth/GitHub.php @@ -11,6 +11,13 @@ class Github extends OAuth */ protected $user = []; + /** + * @var array + */ + protected $scopes = [ + 'user:email' + ]; + /** * @return string */ @@ -24,7 +31,13 @@ class Github extends OAuth */ public function getLoginURL():string { - return 'https://github.com/login/oauth/authorize?client_id='.urlencode($this->appID).'&redirect_uri='.urlencode($this->callback).'&scope=user:email&state='.urlencode(json_encode($this->state)); + 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) + ]); + } /** @@ -38,10 +51,12 @@ class Github extends OAuth 'POST', 'https://github.com/login/oauth/access_token', [], - 'client_id='.urlencode($this->appID). - '&redirect_uri='.urlencode($this->callback). - '&client_secret='.urlencode($this->appSecret). - '&code='.urlencode($code) + http_build_query([ + 'client_id' => $this->appID, + 'redirect_uri' => $this->callback, + 'client_secret' => $this->appSecret, + 'code' => $code + ]) ); $output = []; diff --git a/src/Auth/OAuth/Gitlab.php b/src/Auth/OAuth/Gitlab.php index fbc6df60fa..d74e97a766 100644 --- a/src/Auth/OAuth/Gitlab.php +++ b/src/Auth/OAuth/Gitlab.php @@ -14,6 +14,13 @@ class Gitlab extends OAuth */ protected $user = []; + /** + * @var array + */ + protected $scopes = [ + 'read_user' + ]; + /** * @return string */ @@ -27,12 +34,13 @@ class Gitlab extends OAuth */ public function getLoginURL(): string { - return 'https://gitlab.com/oauth/authorize?'. - 'client_id='.urlencode($this->appID). - '&redirect_uri='.urlencode($this->callback). - '&scope=read_user'. - '&state='.urlencode(json_encode($this->state)). - '&response_type=code'; + return 'https://gitlab.com/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' + ]); } /** @@ -44,12 +52,13 @@ class Gitlab extends OAuth { $accessToken = $this->request( 'POST', - 'https://gitlab.com/oauth/token?'. - 'code='.urlencode($code). - '&client_id='.urlencode($this->appID). - '&client_secret='.urlencode($this->appSecret). - '&redirect_uri='.urlencode($this->callback). - '&grant_type=authorization_code' + 'https://gitlab.com/oauth/token?'.http_build_query([ + 'code' => $code, + 'client_id' => $this->appID, + 'client_secret' => $this->appSecret, + 'redirect_uri' => $this->callback, + 'grant_type' => 'authorization_code' + ]) ); $accessToken = json_decode($accessToken, true); diff --git a/src/Auth/OAuth/Google.php b/src/Auth/OAuth/Google.php index 42f4357bd7..cad8c537d8 100644 --- a/src/Auth/OAuth/Google.php +++ b/src/Auth/OAuth/Google.php @@ -14,6 +14,15 @@ class Google extends OAuth * @var string */ protected $version = 'v4'; + + /** + * @var array + */ + protected $scopes = [ + 'https://www.googleapis.com/auth/userinfo.email', + 'https://www.googleapis.com/auth/userinfo.profile' + ]; + /** * @var array */ @@ -32,12 +41,13 @@ class Google extends OAuth */ public function getLoginURL(): string { - return 'https://accounts.google.com/o/oauth2/v2/auth?'. - 'client_id='.urlencode($this->appID). - '&redirect_uri='.urlencode($this->callback). - '&scope=https://www.googleapis.com/auth/userinfo.email+https://www.googleapis.com/auth/userinfo.profile'. - '&state='.urlencode(json_encode($this->state)). - '&response_type=code'; + 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' + ]); } /** @@ -49,13 +59,14 @@ class Google extends OAuth { $accessToken = $this->request( 'POST', - 'https://www.googleapis.com/oauth2/'.$this->version.'/token?'. - 'code='.urlencode($code). - '&client_id='.urlencode($this->appID). - '&client_secret='.urlencode($this->appSecret). - '&redirect_uri='.urlencode($this->callback). - '&scope='. - '&grant_type=authorization_code' + 'https://www.googleapis.com/oauth2/'.$this->version.'/token?'.http_build_query([ + 'code' => $code, + 'client_id' => $this->appID, + 'client_secret' => $this->appSecret, + 'redirect_uri' => $this->callback, + 'scope' => null, + 'grant_type' => 'authorization_code' + ]) ); $accessToken = json_decode($accessToken, true); diff --git a/src/Auth/OAuth/LinkedIn.php b/src/Auth/OAuth/LinkedIn.php index 101e1f09c5..efe6b6bc86 100644 --- a/src/Auth/OAuth/LinkedIn.php +++ b/src/Auth/OAuth/LinkedIn.php @@ -14,7 +14,7 @@ class LinkedIn extends OAuth /** * @var array */ - protected $scope = [ + protected $scopes = [ 'r_basicprofile', 'r_emailaddress', ]; @@ -49,7 +49,7 @@ class LinkedIn extends OAuth 'response_type' => 'code', 'client_id' => $this->appID, 'redirect_uri' => $this->callback, - 'scope' => implode(' ', $this->scope), + 'scope' => implode(' ', $this->getScopes()), 'state' => json_encode($this->state), ]); } diff --git a/src/Auth/OAuth/Microsoft.php b/src/Auth/OAuth/Microsoft.php index 6bbf0bad83..c2c99a38d7 100644 --- a/src/Auth/OAuth/Microsoft.php +++ b/src/Auth/OAuth/Microsoft.php @@ -14,6 +14,14 @@ class Microsoft extends OAuth */ protected $user = []; + /** + * @var array + */ + protected $scopes = [ + 'offline_access', + 'user.read' + ]; + /** * @return string */ @@ -27,13 +35,14 @@ class Microsoft extends OAuth */ public function getLoginURL(): string { - return 'https://login.microsoftonline.com/common/oauth2/v2.0/authorize?'. - 'client_id='.urlencode($this->appID). - '&redirect_uri='.urlencode($this->callback). - '&state='.urlencode(json_encode($this->state)). - '&scope=offline_access+user.read'. - '&response_type=code'. - '&response_mode=query'; + return 'https://login.microsoftonline.com/common/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' + ]); } /** @@ -49,12 +58,14 @@ class Microsoft extends OAuth 'POST', 'https://login.microsoftonline.com/common/oauth2/v2.0/token', $headers, - 'code='.urlencode($code). - '&client_id='.urlencode($this->appID). - '&client_secret='.urlencode($this->appSecret). - '&redirect_uri='.urlencode($this->callback). - '&scope=offline_access+user.read'. - '&grant_type=authorization_code' + http_build_query([ + 'code' => $code, + 'client_id' => $this->appID, + 'client_secret' => $this->appSecret, + 'redirect_uri' => $this->callback, + 'scope' => implode(' ', $this->getScopes()), + 'grant_type' => 'authorization_code' + ]) ); $accessToken = json_decode($accessToken, true); diff --git a/src/Auth/OAuth/Mock.php b/src/Auth/OAuth/Mock.php index 004836e0e9..4c99ee6404 100644 --- a/src/Auth/OAuth/Mock.php +++ b/src/Auth/OAuth/Mock.php @@ -11,6 +11,13 @@ class Mock extends OAuth */ protected $version = 'v1'; + /** + * @var array + */ + protected $scopes = [ + 'email' + ]; + /** * @var array */ @@ -29,7 +36,12 @@ class Mock extends OAuth */ public function getLoginURL():string { - return 'http://localhost/'.$this->version.'/oauth?client_id='.urlencode($this->appID).'&redirect_uri='.urlencode($this->callback).'&scope=email&state='.urlencode(json_encode($this->state)); + return 'http://localhost/'.$this->version.'/oauth?'. http_build_query([ + 'client_id' => $this->appID, + 'redirect_uri' => $this->callback, + 'scope' => implode(' ', $this->getScopes()), + 'state' => json_encode($this->state) + ]); } /** @@ -42,10 +54,12 @@ class Mock extends OAuth $accessToken = $this->request( 'GET', 'http://localhost/'.$this->version.'/oauth/token?'. - 'client_id='.urlencode($this->appID). - '&redirect_uri='.urlencode($this->callback). - '&client_secret='.urlencode($this->appSecret). - '&code='.urlencode($code) + http_build_query([ + 'client_id' => $this->appID, + 'redirect_uri' => $this->callback, + 'client_secret' => $this->appSecret, + 'code' => $code + ]) ); $accessToken = json_decode($accessToken, true); // diff --git a/src/Auth/OAuth/Slack.php b/src/Auth/OAuth/Slack.php index 120dd4233d..3458e743b6 100644 --- a/src/Auth/OAuth/Slack.php +++ b/src/Auth/OAuth/Slack.php @@ -11,6 +11,16 @@ class Slack extends OAuth */ protected $user = []; + /** + * @var array + */ + protected $scopes = [ + 'identity.avatar', + 'identity.basic', + 'identity.email', + 'identity.team' + ]; + /** * @return string */ @@ -25,11 +35,12 @@ class Slack extends OAuth 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'. - '?client_id='.urlencode($this->appID). - '&scope=identity.avatar+identity.basic+identity.email+identity.team'. - '&redirect_uri='.urlencode($this->callback). - '&state='.urlencode(json_encode($this->state)); + 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) + ]); } /** @@ -42,11 +53,12 @@ class Slack extends OAuth // https://api.slack.com/docs/oauth#step_3_-_exchanging_a_verification_code_for_an_access_token $accessToken = $this->request( 'GET', - 'https://slack.com/api/oauth.access'. - '?client_id='.urlencode($this->appID). - '&client_secret='.urlencode($this->appSecret). - '&code='.urlencode($code). - '&redirect_uri='.urlencode($this->callback) + 'https://slack.com/api/oauth.access?'.http_build_query([ + 'client_id' => $this->appID, + 'client_secret' => $this->appSecret, + 'code' => $code, + 'redirect_uri' => $this->callback + ]) ); $accessToken = json_decode($accessToken, true); // @@ -118,7 +130,7 @@ class Slack extends OAuth // https://api.slack.com/methods/users.identity $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); diff --git a/src/Auth/OAuth/Spotify.php b/src/Auth/OAuth/Spotify.php index 84cd9d0151..92c366026f 100644 --- a/src/Auth/OAuth/Spotify.php +++ b/src/Auth/OAuth/Spotify.php @@ -23,7 +23,7 @@ class Spotify extends OAuth /** * @var array */ - protected $scope = [ + protected $scopes = [ 'user-read-email', ]; @@ -49,7 +49,7 @@ class Spotify extends OAuth http_build_query([ 'response_type' => 'code', 'client_id' => $this->appID, - 'scope' => implode(' ', $this->scope), + 'scope' => implode(' ', $this->getScopes()), 'redirect_uri' => $this->callback, 'state' => json_encode($this->state) ]); diff --git a/src/Auth/OAuth/Twitch.php b/src/Auth/OAuth/Twitch.php index b9455bd58a..e5ecb5b142 100644 --- a/src/Auth/OAuth/Twitch.php +++ b/src/Auth/OAuth/Twitch.php @@ -23,7 +23,7 @@ class Twitch extends OAuth /** * @var array */ - protected $scope = [ + protected $scopes = [ 'user:read:email', ]; @@ -49,7 +49,7 @@ class Twitch extends OAuth http_build_query([ 'response_type' => 'code', 'client_id' => $this->appID, - 'scope' => implode(' ', $this->scope), + 'scope' => implode(' ', $this->getScopes()), 'redirect_uri' => $this->callback, 'force_verify' => true, 'state' => json_encode($this->state) diff --git a/src/Auth/OAuth/Twitter.php b/src/Auth/OAuth/Twitter.php new file mode 100644 index 0000000000..e69de29bb2 diff --git a/src/Auth/OAuth/Vk.php b/src/Auth/OAuth/Vk.php index ad860aff84..1878fbd348 100644 --- a/src/Auth/OAuth/Vk.php +++ b/src/Auth/OAuth/Vk.php @@ -17,6 +17,14 @@ class Vk extends OAuth */ protected $user = []; + /** + * @var array + */ + protected $scopes = [ + 'openid', + 'email' + ]; + /** * @var string */ @@ -36,13 +44,14 @@ class Vk extends OAuth */ public function getLoginURL(): string { - return 'https://oauth.vk.com/authorize?' . - 'client_id='.urlencode($this->appID). - '&redirect_uri='.urlencode($this->callback). - '&response_type=code'. - '&state='.urlencode(json_encode($this->state)). - '&v='.urlencode($this->version). - '&scope=openid+email'; + return 'https://oauth.vk.com/authorize?' . http_build_query([ + 'client_id' => $this->appID, + 'redirect_uri' => $this->callback, + 'response_type' => 'code', + 'state' => json_encode($this->state), + 'v' => $this->version, + 'scope' => implode(' ', $this->getScopes()) + ]); } /** @@ -57,10 +66,12 @@ class Vk extends OAuth 'POST', 'https://oauth.vk.com/access_token?', $headers, - 'code=' . urlencode($code) . - '&client_id=' . urlencode($this->appID) . - '&client_secret=' . urlencode($this->appSecret). - '&redirect_uri='.urlencode($this->callback) + http_build_query([ + 'code' => $code, + 'client_id' => $this->appID, + 'client_secret' => $this->appSecret, + 'redirect_uri' => $this->callback + ]) ); $accessToken = json_decode($accessToken, true); @@ -136,10 +147,11 @@ class Vk extends OAuth if (empty($this->user['name'])) { $user = $this->request( 'GET', - 'https://api.vk.com/method/users.get?'. - 'v='.urlencode($this->version). - '&fields=id,name,email,first_name,last_name'. - '&access_token='.urlencode($accessToken) + 'https://api.vk.com/method/users.get?'. http_build_query([ + 'v' => $this->version, + 'fields' => 'id,name,email,first_name,last_name', + 'access_token' => $accessToken + ]) ); $user = json_decode($user, true); diff --git a/src/Auth/OAuth/Yahoo.php b/src/Auth/OAuth/Yahoo.php index c14e4c6650..84aa596684 100644 --- a/src/Auth/OAuth/Yahoo.php +++ b/src/Auth/OAuth/Yahoo.php @@ -23,7 +23,7 @@ class Yahoo extends OAuth /** * @var array */ - protected $scope = [ + protected $scopes = [ 'sdct-r', 'sdpp-w', ]; @@ -61,7 +61,7 @@ class Yahoo extends OAuth http_build_query([ 'response_type' => 'code', 'client_id' => $this->appID, - 'scope' => implode(' ', $this->scope), + 'scope' => implode(' ', $this->getScopes()), 'redirect_uri' => $this->callback, 'state' => json_encode($this->state) ]);