From 47ad9cc6a3850b42448176f50868a10f7e3fc621 Mon Sep 17 00:00:00 2001 From: Andrew Minion Date: Tue, 5 Mar 2024 14:12:36 -0600 Subject: [PATCH 1/8] use correct token endpoint --- src/Clover/Provider.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/Clover/Provider.php b/src/Clover/Provider.php index 548d5b467..9bd1dfa48 100644 --- a/src/Clover/Provider.php +++ b/src/Clover/Provider.php @@ -60,7 +60,7 @@ protected function getTokenUrl() default => 'api.clover.com', }; - return sprintf('https://%s/oauth/token', $domain); + return sprintf('https://%s/oauth/v2/token', $domain); } /** From cb2d108d1f3efb252e62cda11f58e09bb1800480 Mon Sep 17 00:00:00 2001 From: Andrew Minion Date: Tue, 5 Mar 2024 14:12:51 -0600 Subject: [PATCH 2/8] fix code stye --- src/Clover/Provider.php | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/src/Clover/Provider.php b/src/Clover/Provider.php index 9bd1dfa48..5105f4928 100644 --- a/src/Clover/Provider.php +++ b/src/Clover/Provider.php @@ -35,7 +35,7 @@ protected function getApiDomain(): string { return match ($this->getConfig('environment')) { 'sandbox' => 'sandbox.dev.clover.com', - default => 'www.clover.com', + default => 'www.clover.com', }; } @@ -57,7 +57,7 @@ protected function getTokenUrl() { $domain = match ($this->getConfig('environment')) { 'sandbox' => 'apisandbox.dev.clover.com', - default => 'api.clover.com', + default => 'api.clover.com', }; return sprintf('https://%s/oauth/v2/token', $domain); @@ -93,11 +93,11 @@ protected function getUserByToken($token) protected function mapUserToObject(array $user) { return (new User())->setRaw($user)->map([ - 'id' => $user['id'], + 'id' => $user['id'], 'nickname' => $user['name'], - 'name' => $user['name'], - 'email' => $user['email'], - 'avatar' => null, + 'name' => $user['name'], + 'email' => $user['email'], + 'avatar' => null, ]); } } From 0c37db2ea603f57f85e812439a5ccfaddd0035af Mon Sep 17 00:00:00 2001 From: Andrew Minion Date: Tue, 5 Mar 2024 14:13:22 -0600 Subject: [PATCH 3/8] get access token response using JSON instead of form params --- src/Clover/Provider.php | 17 +++++++++++++++++ 1 file changed, 17 insertions(+) diff --git a/src/Clover/Provider.php b/src/Clover/Provider.php index 5105f4928..5f5789853 100644 --- a/src/Clover/Provider.php +++ b/src/Clover/Provider.php @@ -2,6 +2,7 @@ namespace SocialiteProviders\Clover; +use GuzzleHttp\RequestOptions; use SocialiteProviders\Manager\OAuth2\AbstractProvider; use SocialiteProviders\Manager\OAuth2\User; @@ -31,6 +32,22 @@ public static function additionalConfigKeys() ]; } + /** + * Get the access token response for the given code. + * + * @param string $code + * @return array + */ + public function getAccessTokenResponse($code) + { + $response = $this->getHttpClient()->post($this->getTokenUrl(), [ + RequestOptions::HEADERS => $this->getTokenHeaders($code), + RequestOptions::JSON => $this->getTokenFields($code), + ]); + + return json_decode($response->getBody(), true); + } + protected function getApiDomain(): string { return match ($this->getConfig('environment')) { From 309dfc8a8ddd7ade911fd4eae184e9a0d1125ab6 Mon Sep 17 00:00:00 2001 From: Andrew Minion Date: Tue, 5 Mar 2024 14:13:37 -0600 Subject: [PATCH 4/8] =?UTF-8?q?parse=20expiration=20timestamp=20to=20Socia?= =?UTF-8?q?lite=E2=80=99s=20format?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/Clover/Provider.php | 12 ++++++++++++ 1 file changed, 12 insertions(+) diff --git a/src/Clover/Provider.php b/src/Clover/Provider.php index 5f5789853..c71144aa1 100644 --- a/src/Clover/Provider.php +++ b/src/Clover/Provider.php @@ -3,6 +3,7 @@ namespace SocialiteProviders\Clover; use GuzzleHttp\RequestOptions; +use Illuminate\Support\Arr; use SocialiteProviders\Manager\OAuth2\AbstractProvider; use SocialiteProviders\Manager\OAuth2\User; @@ -117,4 +118,15 @@ protected function mapUserToObject(array $user) 'avatar' => null, ]); } + + /** + * Get the expires in from the token response body. + * + * @param array $body + * @return string + */ + protected function parseExpiresIn($body) + { + return (string) (Arr::get($body, 'access_token_expiration') - time()); + } } From c34c3b82cf78e4f4481a84a07da4e52942bc3948 Mon Sep 17 00:00:00 2001 From: Andrew Minion Date: Tue, 5 Mar 2024 14:13:46 -0600 Subject: [PATCH 5/8] update docs --- src/Clover/README.md | 18 ++++++++++++++++-- 1 file changed, 16 insertions(+), 2 deletions(-) diff --git a/src/Clover/README.md b/src/Clover/README.md index 299514d08..e0a258cb3 100644 --- a/src/Clover/README.md +++ b/src/Clover/README.md @@ -52,7 +52,21 @@ The user includes a `token` property that you can use to retrieve the API token Route::get('clover/auth/callback', function () { $user = Socialite::driver('clover')->user(); - // Save this token somewhere for other use. - $token = $user->token; + // Save these tokens somewhere for use with the API. + $token = $user->accessTokenResponseBody; + + // Here’s what it looks like: + // [ + // 'access_token' => 'JWT', + // 'access_token_expiration' => 1709563149, + // 'refresh_token' => 'clvroar-6e49ffe9b5122f137aa39d8f7f930558', + // 'refresh_token_expiration' => 1741097349, + // ] + + // You may also want to store the merchant ID somewhere. + $merchantId = request()->input('merchant_id'); + + // Here’s what it looks like: + // 'ABC123DEF4567' }); ``` From 8dba06f5ced4062a6b44908747de72169135c645 Mon Sep 17 00:00:00 2001 From: Andrew Minion Date: Tue, 5 Mar 2024 14:20:55 -0600 Subject: [PATCH 6/8] add some suggested changes from #1162 --- src/Clover/CloverExtendSocialite.php | 2 +- src/Clover/Provider.php | 18 ++++++------------ src/Clover/README.md | 2 +- src/Clover/composer.json | 14 +++++++++++++- 4 files changed, 21 insertions(+), 15 deletions(-) diff --git a/src/Clover/CloverExtendSocialite.php b/src/Clover/CloverExtendSocialite.php index 32476227e..a740ab060 100644 --- a/src/Clover/CloverExtendSocialite.php +++ b/src/Clover/CloverExtendSocialite.php @@ -6,7 +6,7 @@ class CloverExtendSocialite { - public function handle(SocialiteWasCalled $socialiteWasCalled) + public function handle(SocialiteWasCalled $socialiteWasCalled): void { $socialiteWasCalled->extendSocialite(Provider::IDENTIFIER, Provider::class); } diff --git a/src/Clover/Provider.php b/src/Clover/Provider.php index c71144aa1..f1c7a93bc 100644 --- a/src/Clover/Provider.php +++ b/src/Clover/Provider.php @@ -26,7 +26,7 @@ class Provider extends AbstractProvider */ protected $stateless = true; - public static function additionalConfigKeys() + public static function additionalConfigKeys(): array { return [ 'environment', @@ -37,9 +37,8 @@ public static function additionalConfigKeys() * Get the access token response for the given code. * * @param string $code - * @return array */ - public function getAccessTokenResponse($code) + public function getAccessTokenResponse($code): array { $response = $this->getHttpClient()->post($this->getTokenUrl(), [ RequestOptions::HEADERS => $this->getTokenHeaders($code), @@ -60,7 +59,7 @@ protected function getApiDomain(): string /** * {@inheritdoc} */ - protected function getAuthUrl($state) + protected function getAuthUrl($state): string { return $this->buildAuthUrlFromBase( sprintf('https://%s/oauth/v2/authorize', $this->getApiDomain()), @@ -71,7 +70,7 @@ protected function getAuthUrl($state) /** * {@inheritdoc} */ - protected function getTokenUrl() + protected function getTokenUrl(): string { $domain = match ($this->getConfig('environment')) { 'sandbox' => 'apisandbox.dev.clover.com', @@ -86,16 +85,11 @@ protected function getTokenUrl() */ protected function getUserByToken($token) { - $requestParams = str(request()->fullUrl()) - ->after('?') - ->explode('&') - ->mapWithKeys(fn (string $keyAndValue) => [str($keyAndValue)->before('=')->toString() => str($keyAndValue)->after('=')->toString()]); - $response = $this->getHttpClient()->get(sprintf( 'https://%s/v3/merchants/%s/employees/%s', $this->getApiDomain(), - $requestParams['merchant_id'], - $requestParams['employee_id'], + $this->request->query('merchant_id'), + $this->request->query('employee_id'), ), [ 'headers' => [ 'Authorization' => 'Bearer '.$token, diff --git a/src/Clover/README.md b/src/Clover/README.md index e0a258cb3..34284703b 100644 --- a/src/Clover/README.md +++ b/src/Clover/README.md @@ -31,7 +31,7 @@ Add the event to your `listen[]` array in `app/Providers/EventServiceProvider`. protected $listen = [ \SocialiteProviders\Manager\SocialiteWasCalled::class => [ // ... other providers - 'SocialiteProviders\\Clover\\CloverExtendSocialite@handle', + \SocialiteProviders\Clover\CloverExtendSocialite::class.'@handle', ], ]; ``` diff --git a/src/Clover/composer.json b/src/Clover/composer.json index b64340f4c..ba5746806 100644 --- a/src/Clover/composer.json +++ b/src/Clover/composer.json @@ -2,16 +2,28 @@ "name": "socialiteproviders/clover", "description": "Clover OAuth2 Provider for Laravel Socialite", "license": "MIT", + "keywords": [ + "clover", + "laravel", + "oauth", + "provider", + "socialite" + ], "authors": [ { "name": "macbookandrew", "homepage": "https://andrewrminion.com" } ], + "support": { + "issues": "https://github.com/socialiteproviders/providers/issues", + "source": "https://github.com/socialiteproviders/providers", + "docs": "https://socialiteproviders.com/clover" + }, "require": { "php": "^8.1", "ext-json": "*", - "socialiteproviders/manager": "^4.0" + "socialiteproviders/manager": "^4.4" }, "autoload": { "psr-4": { From e65c35d696fa08c656e343bd24d17c8114177010 Mon Sep 17 00:00:00 2001 From: Andrew Minion Date: Mon, 11 Mar 2024 13:27:23 -0500 Subject: [PATCH 7/8] add Latin America and Europe regions --- src/Clover/Provider.php | 4 +++- src/Clover/README.md | 2 +- 2 files changed, 4 insertions(+), 2 deletions(-) diff --git a/src/Clover/Provider.php b/src/Clover/Provider.php index f1c7a93bc..c70e15ad2 100644 --- a/src/Clover/Provider.php +++ b/src/Clover/Provider.php @@ -52,7 +52,9 @@ protected function getApiDomain(): string { return match ($this->getConfig('environment')) { 'sandbox' => 'sandbox.dev.clover.com', - default => 'www.clover.com', + 'europe' => 'api.eu.clover.com', + 'latin-america' => 'api.la.clover.com', + default => 'api.clover.com', }; } diff --git a/src/Clover/README.md b/src/Clover/README.md index 34284703b..ceab4f49d 100644 --- a/src/Clover/README.md +++ b/src/Clover/README.md @@ -17,7 +17,7 @@ Ensure the app has permission to read employees. 'client_id' => env('CLOVER_CLIENT_ID'), 'client_secret' => env('CLOVER_CLIENT_SECRET'), 'redirect' => env('CLOVER_REDIRECT_URI') - 'environment' => env('CLOVER_ENVIRONMENT', 'production'), + 'environment' => env('CLOVER_ENVIRONMENT', 'production'), // one of the following: 'sandbox', 'production' (for US/Canada), 'europe', or 'latin-america' ], ``` From c91b03ea923e192a6dc9c1ddc6295aeed9006b6a Mon Sep 17 00:00:00 2001 From: Andrew Minion Date: Tue, 12 Mar 2024 09:28:59 -0500 Subject: [PATCH 8/8] add North America region https://github.com/SocialiteProviders/Providers/pull/1172#pullrequestreview-1929882851 --- src/Clover/Provider.php | 4 +++- src/Clover/README.md | 2 +- 2 files changed, 4 insertions(+), 2 deletions(-) diff --git a/src/Clover/Provider.php b/src/Clover/Provider.php index c70e15ad2..a4e363a78 100644 --- a/src/Clover/Provider.php +++ b/src/Clover/Provider.php @@ -53,7 +53,7 @@ protected function getApiDomain(): string return match ($this->getConfig('environment')) { 'sandbox' => 'sandbox.dev.clover.com', 'europe' => 'api.eu.clover.com', - 'latin-america' => 'api.la.clover.com', + 'latin_america' => 'api.la.clover.com', default => 'api.clover.com', }; } @@ -76,6 +76,8 @@ protected function getTokenUrl(): string { $domain = match ($this->getConfig('environment')) { 'sandbox' => 'apisandbox.dev.clover.com', + 'europe' => 'eu.clover.com', + 'latin_america' => 'la.clover.com', default => 'api.clover.com', }; diff --git a/src/Clover/README.md b/src/Clover/README.md index ceab4f49d..03e586584 100644 --- a/src/Clover/README.md +++ b/src/Clover/README.md @@ -17,7 +17,7 @@ Ensure the app has permission to read employees. 'client_id' => env('CLOVER_CLIENT_ID'), 'client_secret' => env('CLOVER_CLIENT_SECRET'), 'redirect' => env('CLOVER_REDIRECT_URI') - 'environment' => env('CLOVER_ENVIRONMENT', 'production'), // one of the following: 'sandbox', 'production' (for US/Canada), 'europe', or 'latin-america' + 'environment' => env('CLOVER_ENVIRONMENT', 'north_america'), // one of the following: 'sandbox', 'north_america' (for US/Canada), 'europe', or 'latin_america' ], ```