From f105360339af703e2caab8d1df5760972cbc8873 Mon Sep 17 00:00:00 2001 From: Chris Minett <1084019+chrisminett@users.noreply.github.com> Date: Tue, 17 Jun 2025 11:11:37 +0100 Subject: [PATCH 1/4] Tag for v5.2.0 --- CHANGELOG.md | 2 ++ src/Client.php | 2 +- 2 files changed, 3 insertions(+), 1 deletion(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index a0c9ec0..1b2cf46 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -5,6 +5,8 @@ The format is based on [Keep a Changelog](http://keepachangelog.com/) and this project adheres to [Semantic Versioning](http://semver.org/). ## [Unreleased] + +## [5.2.0] - 2025-06-25 ### Added - Support for API token authentication. Username and password can still be used as a fallback. diff --git a/src/Client.php b/src/Client.php index 1ec8620..828fc6b 100644 --- a/src/Client.php +++ b/src/Client.php @@ -59,7 +59,7 @@ */ class Client implements \Psr\Log\LoggerAwareInterface { - public const VERSION = '5.1'; + public const VERSION = '5.2'; /** * @var string From a6d252a0351c75b9c666b0aecdaaab4789579c7d Mon Sep 17 00:00:00 2001 From: Chris Minett <1084019+chrisminett@users.noreply.github.com> Date: Sun, 20 Jul 2025 08:16:22 +0100 Subject: [PATCH 2/4] Revert token auth config options --- CHANGELOG.md | 6 ++- README.md | 3 +- phpunit.xml.dist | 3 +- src/Client.php | 52 +++++++++----------------- tests/ClientTest.php | 80 ++++++++++------------------------------ tests/FunctionalTest.php | 3 +- 6 files changed, 47 insertions(+), 100 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 1b2cf46..c4eb54a 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -5,11 +5,13 @@ The format is based on [Keep a Changelog](http://keepachangelog.com/) and this project adheres to [Semantic Versioning](http://semver.org/). ## [Unreleased] +### Changed +- Revert support for token auth, added in v5.2.0. ## [5.2.0] - 2025-06-25 ### Added -- Support for API token authentication. Username and password can still be used - as a fallback. +- ~~Support for API token authentication. Username and password can still be used + as a fallback.~~ Reverted in v5.2.1. ### Changed - Deprecate `getConfig()` method. Packages can maintain their config internally. diff --git a/README.md b/README.md index f8d47c4..1f40d73 100644 --- a/README.md +++ b/README.md @@ -36,7 +36,8 @@ $ composer require maxemail/api-php ```php // Instantiate Client: $config = [ - 'token' => 'apitoken', + 'username' => 'api@user.com', + 'password' => 'apipass' ]; $api = new \Maxemail\Api\Client($config); diff --git a/phpunit.xml.dist b/phpunit.xml.dist index 8a738f1..e6230c1 100644 --- a/phpunit.xml.dist +++ b/phpunit.xml.dist @@ -12,7 +12,8 @@ - + + diff --git a/src/Client.php b/src/Client.php index 828fc6b..af61459 100644 --- a/src/Client.php +++ b/src/Client.php @@ -66,11 +66,6 @@ class Client implements \Psr\Log\LoggerAwareInterface */ private $uri = 'https://mxm.xtremepush.com/'; - /** - * @var string - */ - private $token; - /** * @var string */ @@ -113,9 +108,8 @@ class Client implements \Psr\Log\LoggerAwareInterface /** * @param array $config { - * @var string $token Required, or username & password - * @var string $username Required, if no token - * @var string $password Required, if no token + * @var string $username Required + * @var string $password Required * @var string $uri Optional. Default https://mxm.xtremepush.com/ * @var string $user @deprecated See username * @var string $pass @deprecated See password @@ -124,25 +118,20 @@ class Client implements \Psr\Log\LoggerAwareInterface */ public function __construct(array $config) { - // Must have API token - if (!isset($config['token'])) { - // Support deprecated key names from v3 - if (!isset($config['username']) && isset($config['user'])) { - $config['username'] = $config['user']; - } - if (!isset($config['password']) && isset($config['pass'])) { - $config['password'] = $config['pass']; - } + // Support deprecated key names from v3 + if (!isset($config['username']) && isset($config['user'])) { + $config['username'] = $config['user']; + } + if (!isset($config['password']) && isset($config['pass'])) { + $config['password'] = $config['pass']; + } - // Must have user/pass - if (!isset($config['username']) || !isset($config['password'])) { - throw new Exception\InvalidArgumentException('API config requires token OR username & password'); - } - $this->username = $config['username']; - $this->password = $config['password']; - } else { - $this->token = $config['token']; + // Must have user/pass + if (!isset($config['username']) || !isset($config['password'])) { + throw new Exception\InvalidArgumentException('API config requires username & password'); } + $this->username = $config['username']; + $this->password = $config['password']; if (isset($config['uri'])) { $parsed = parse_url($config['uri']); @@ -186,6 +175,10 @@ private function getClient(): GuzzleClientInterface $clientConfig = [ 'base_uri' => $this->uri . 'api/json/', + 'auth' => [ + $this->username, + $this->password, + ], 'headers' => [ 'User-Agent' => 'MxmApiClient/' . self::VERSION . ' PHP/' . PHP_VERSION, 'Content-Type' => 'application/x-www-form-urlencoded', @@ -194,15 +187,6 @@ private function getClient(): GuzzleClientInterface 'handler' => $stack, ]; - if (isset($this->token)) { - $clientConfig['headers']['Authorization'] = 'Bearer ' . $this->token; - } else { - $clientConfig['auth'] = [ - $this->username, - $this->password, - ]; - } - if (!isset($this->httpClientFactory)) { $this->httpClient = new GuzzleClient($clientConfig); } else { diff --git a/tests/ClientTest.php b/tests/ClientTest.php index 370a511..f00982b 100644 --- a/tests/ClientTest.php +++ b/tests/ClientTest.php @@ -19,7 +19,8 @@ class ClientTest extends TestCase { private $testConfig = [ 'uri' => 'https://maxemail.example.com/', - 'token' => 'apitoken', + 'username' => 'api@user.com', + 'password' => 'apipass', ]; public function testConfigValid() @@ -30,11 +31,16 @@ public function testConfigValid() $expectedUri = $this->testConfig['uri'] . 'api/json/'; static::assertSame($expectedUri, $actual['base_uri']); + $expectedAuth = [ + $this->testConfig['username'], + $this->testConfig['password'], + ]; + static::assertSame($expectedAuth, $actual['auth']); + $expectedHeaders = [ 'User-Agent' => 'MxmApiClient/' . Client::VERSION . ' PHP/' . PHP_VERSION, 'Content-Type' => 'application/x-www-form-urlencoded', 'Accept' => 'application/json', - 'Authorization' => 'Bearer ' . $this->testConfig['token'], ]; static::assertSame($expectedHeaders, $actual['headers']); @@ -75,7 +81,8 @@ public function testConfigSupportDeprecatedUserPass() public function testConfigDefaultHost() { $config = [ - 'token' => 'apitoken', + 'username' => 'api@user.com', + 'password' => 'apipass', ]; $api = new Client($config); @@ -97,7 +104,8 @@ public function testConfigStripsUriPath() { $config = [ 'uri' => 'https://maxemail.example.com/some/extra/path', - 'token' => 'apitoken', + 'username' => 'api@user.com', + 'password' => 'apipass', ]; $api = new Client($config); @@ -122,7 +130,8 @@ public function testConfigInvalidUri() $config = [ 'uri' => '//', - 'token' => 'apitoken', + 'username' => 'api@user.com', + 'password' => 'apipass', ]; new Client($config); @@ -135,49 +144,17 @@ public function testConfigMissingUriProtocol() $config = [ 'uri' => 'maxemail.example.com', - 'token' => 'apitoken', - ]; - - new Client($config); - } - - public function testConfigLegacyAuthentication(): void - { - $config = [ 'username' => 'api@user.com', 'password' => 'apipass', ]; - $api = new Client($config); - - $factory = function (array $actual) use ($config): GuzzleClient { - $expectedAuth = [ - $config['username'], - $config['password'], - ]; - static::assertSame($expectedAuth, $actual['auth']); - - return $this->createMock(GuzzleClient::class); - }; - - $api->setHttpClientFactory($factory); - - // Get a service, to trigger the HTTP Client factory - $api->folder; - } - - public function testConfigMissingToken(): void - { - $this->expectException(Exception\InvalidArgumentException::class); - $this->expectExceptionMessage('API config requires token OR username & password'); - - new Client([]); + new Client($config); } public function testConfigMissingUsername(): void { $this->expectException(Exception\InvalidArgumentException::class); - $this->expectExceptionMessage('API config requires token OR username & password'); + $this->expectExceptionMessage('API config requires username & password'); $config = [ 'password' => 'apipass', @@ -189,7 +166,7 @@ public function testConfigMissingUsername(): void public function testConfigMissingPassword(): void { $this->expectException(Exception\InvalidArgumentException::class); - $this->expectExceptionMessage('API config requires token OR username & password'); + $this->expectExceptionMessage('API config requires username & password'); $config = [ 'username' => 'api@user.com', @@ -198,30 +175,11 @@ public function testConfigMissingPassword(): void new Client($config); } - public function testGetConfigWithToken(): void + public function testGetConfig(): void { $api = new Client($this->testConfig); - $expected = [ - 'uri' => $this->testConfig['uri'], - 'username' => null, - 'password' => null, - ]; - - static::assertSame($expected, $api->getConfig()); - } - - public function testGetConfigWithLegacyAuthentication(): void - { - $config = [ - 'uri' => 'https://maxemail.example.com/', - 'username' => 'api@user.com', - 'password' => 'apipass', - ]; - - $api = new Client($config); - - static::assertSame($config, $api->getConfig()); + static::assertSame($this->testConfig, $api->getConfig()); } public function testSetGetLogger() diff --git a/tests/FunctionalTest.php b/tests/FunctionalTest.php index 21567bd..5df4ca7 100644 --- a/tests/FunctionalTest.php +++ b/tests/FunctionalTest.php @@ -30,7 +30,8 @@ protected function setUp(): void $config = [ 'uri' => getenv('FUNC_API_URI'), - 'token' => getenv('FUNC_API_TOKEN'), + 'username' => getenv('FUNC_API_USERNAME'), + 'password' => getenv('FUNC_API_PASSWORD'), ]; $this->client = new Client($config); } From 042ecb741c56e8b8a95fa57961b316e687189225 Mon Sep 17 00:00:00 2001 From: Chris Minett <1084019+chrisminett@users.noreply.github.com> Date: Sun, 20 Jul 2025 08:16:51 +0100 Subject: [PATCH 3/4] Label username and password for client ID and secret --- CHANGELOG.md | 1 + README.md | 4 ++-- phpunit.xml.dist | 4 ++-- src/Client.php | 4 ++-- tests/ClientTest.php | 24 ++++++++++++------------ 5 files changed, 19 insertions(+), 18 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index c4eb54a..7d7a67d 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -7,6 +7,7 @@ and this project adheres to [Semantic Versioning](http://semver.org/). ## [Unreleased] ### Changed - Revert support for token auth, added in v5.2.0. +- Label username and password for clientId and clientSecret. No param changes. ## [5.2.0] - 2025-06-25 ### Added diff --git a/README.md b/README.md index 1f40d73..335a696 100644 --- a/README.md +++ b/README.md @@ -36,8 +36,8 @@ $ composer require maxemail/api-php ```php // Instantiate Client: $config = [ - 'username' => 'api@user.com', - 'password' => 'apipass' + 'username' => 'client ID', + 'password' => 'client secret' ]; $api = new \Maxemail\Api\Client($config); diff --git a/phpunit.xml.dist b/phpunit.xml.dist index e6230c1..0d42423 100644 --- a/phpunit.xml.dist +++ b/phpunit.xml.dist @@ -12,8 +12,8 @@ - - + + diff --git a/src/Client.php b/src/Client.php index af61459..780776f 100644 --- a/src/Client.php +++ b/src/Client.php @@ -108,8 +108,8 @@ class Client implements \Psr\Log\LoggerAwareInterface /** * @param array $config { - * @var string $username Required - * @var string $password Required + * @var string $username Required; API client ID + * @var string $password Required; API client secret * @var string $uri Optional. Default https://mxm.xtremepush.com/ * @var string $user @deprecated See username * @var string $pass @deprecated See password diff --git a/tests/ClientTest.php b/tests/ClientTest.php index f00982b..ce9346a 100644 --- a/tests/ClientTest.php +++ b/tests/ClientTest.php @@ -19,8 +19,8 @@ class ClientTest extends TestCase { private $testConfig = [ 'uri' => 'https://maxemail.example.com/', - 'username' => 'api@user.com', - 'password' => 'apipass', + 'username' => 'clientId', + 'password' => 'clientSecret', ]; public function testConfigValid() @@ -81,8 +81,8 @@ public function testConfigSupportDeprecatedUserPass() public function testConfigDefaultHost() { $config = [ - 'username' => 'api@user.com', - 'password' => 'apipass', + 'username' => 'clientId', + 'password' => 'clientSecret', ]; $api = new Client($config); @@ -104,8 +104,8 @@ public function testConfigStripsUriPath() { $config = [ 'uri' => 'https://maxemail.example.com/some/extra/path', - 'username' => 'api@user.com', - 'password' => 'apipass', + 'username' => 'clientId', + 'password' => 'clientSecret', ]; $api = new Client($config); @@ -130,8 +130,8 @@ public function testConfigInvalidUri() $config = [ 'uri' => '//', - 'username' => 'api@user.com', - 'password' => 'apipass', + 'username' => 'clientId', + 'password' => 'clientSecret', ]; new Client($config); @@ -144,8 +144,8 @@ public function testConfigMissingUriProtocol() $config = [ 'uri' => 'maxemail.example.com', - 'username' => 'api@user.com', - 'password' => 'apipass', + 'username' => 'clientId', + 'password' => 'clientSecret', ]; new Client($config); @@ -157,7 +157,7 @@ public function testConfigMissingUsername(): void $this->expectExceptionMessage('API config requires username & password'); $config = [ - 'password' => 'apipass', + 'password' => 'clientSecret', ]; new Client($config); @@ -169,7 +169,7 @@ public function testConfigMissingPassword(): void $this->expectExceptionMessage('API config requires username & password'); $config = [ - 'username' => 'api@user.com', + 'username' => 'clientId', ]; new Client($config); From 0f8256a605071b0c9cc47e4d8f2406f67abb0e88 Mon Sep 17 00:00:00 2001 From: Chris Minett <1084019+chrisminett@users.noreply.github.com> Date: Sun, 20 Jul 2025 08:34:23 +0100 Subject: [PATCH 4/4] Tag for v5.2.1 --- CHANGELOG.md | 2 ++ 1 file changed, 2 insertions(+) diff --git a/CHANGELOG.md b/CHANGELOG.md index 7d7a67d..90e6af1 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -5,6 +5,8 @@ The format is based on [Keep a Changelog](http://keepachangelog.com/) and this project adheres to [Semantic Versioning](http://semver.org/). ## [Unreleased] + +## [5.2.1] - 2025-07-20 ### Changed - Revert support for token auth, added in v5.2.0. - Label username and password for clientId and clientSecret. No param changes.