Skip to content

Commit b9f14af

Browse files
committed
BIG-27111 Support for retrieving the customer login token
1 parent 37087f7 commit b9f14af

File tree

4 files changed

+69
-1
lines changed

4 files changed

+69
-1
lines changed

composer.json

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -12,7 +12,9 @@
1212
}
1313
],
1414
"require": {
15-
"php": ">=5.3.0"
15+
"php": ">=5.3.0",
16+
"firebase/php-jwt": "~3.0",
17+
"paragonie/random_compat": "~2.0"
1618
},
1719
"require-dev": {
1820
"phpunit/phpunit": "4.5.*",

src/Bigcommerce/Api/Client.php

Lines changed: 31 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,7 @@
33
namespace Bigcommerce\Api;
44

55
use \Exception as Exception;
6+
use Firebase\JWT\JWT;
67

78
/**
89
* Bigcommerce API Client.
@@ -60,6 +61,7 @@ class Client
6061
static private $client_id;
6162
static private $store_hash;
6263
static private $auth_token;
64+
static private $client_secret;
6365
static private $stores_prefix = '/stores/%s/v2';
6466
static private $api_url = 'https://api.bigcommerce.com';
6567
static private $login_url = 'https://login.bigcommerce.com';
@@ -106,6 +108,9 @@ public static function configureOAuth($settings)
106108
self::$client_id = $settings['client_id'];
107109
self::$auth_token = $settings['auth_token'];
108110
self::$store_hash = $settings['store_hash'];
111+
112+
self::$client_secret = isset($settings['client_secret']) ? $settings['client_secret'] : null;
113+
109114
self::$api_path = self::$api_url . sprintf(self::$stores_prefix, self::$store_hash);
110115
self::$connection = false;
111116
}
@@ -413,6 +418,32 @@ public static function getAuthToken($object)
413418
return $connection->post(self::$login_url . '/oauth2/token', $context);
414419
}
415420

421+
public static function getCustomerLoginToken($id, $redirectUrl = '', $requestIp = '')
422+
{
423+
if (empty(self::$client_secret)) {
424+
throw new Exception('Cannot sign customer login tokens without a client secret');
425+
}
426+
427+
$payload = array(
428+
'iss' => self::$client_id,
429+
'iat' => time(),
430+
'jti' => bin2hex(random_bytes(32)),
431+
'operation' => 'customer_login',
432+
'store_hash' => self::$store_hash,
433+
'customer_id' => $id
434+
);
435+
436+
if (!empty($redirectUrl)) {
437+
$payload['redirect_to'] = $redirectUrl;
438+
}
439+
440+
if (!empty($requestIp)) {
441+
$payload['request_ip'] = $requestIp;
442+
}
443+
444+
return JWT::encode($payload, self::$client_secret, 'HS256');
445+
}
446+
416447
/**
417448
* Pings the time endpoint to test the connection to a store.
418449
*

src/Bigcommerce/Api/Resources/Customer.php

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -34,4 +34,9 @@ public function delete()
3434
{
3535
return Client::deleteCustomer($this->id);
3636
}
37+
38+
public function getLoginToken()
39+
{
40+
return Client::getCustomerLoginUrl($this->id);
41+
}
3742
}

test/Unit/Api/ClientTest.php

Lines changed: 30 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -118,6 +118,36 @@ public function testGetLastErrorGetsErrorFromConnection()
118118
$this->assertSame(5, Client::getLastError());
119119
}
120120

121+
public function testGetCustomerLoginTokenReturnsValidLoginToken()
122+
{
123+
Client::configureOAuth(array(
124+
'client_id' => '123',
125+
'auth_token' => 'def',
126+
'store_hash' => 'abc',
127+
'client_secret' => 'zyx'
128+
));
129+
$expectedPayload = array(
130+
'iss' => '123',
131+
'operation' => 'customer_login',
132+
'store_hash' => 'abc',
133+
'customer_id' => 1,
134+
);
135+
$token = Client::getCustomerLoginToken(1);
136+
$actualPayload = (array)\Firebase\JWT\JWT::decode($token, 'zyx', array('HS256'));
137+
$this->assertArraySubset($expectedPayload, $actualPayload);
138+
}
139+
140+
public function testGetCustomerLoginTokenThrowsIfNoClientSecret()
141+
{
142+
Client::configureOAuth(array(
143+
'client_id' => '123',
144+
'auth_token' => 'def',
145+
'store_hash' => 'abc'
146+
));
147+
$this->setExpectedException('\Exception', 'Cannot sign customer login tokens without a client secret');
148+
Client::getCustomerLoginToken(1);
149+
}
150+
121151
public function testGetResourceReturnsSpecifiedType()
122152
{
123153
$this->connection->expects($this->once())

0 commit comments

Comments
 (0)