diff --git a/src/MailosaurClient.php b/src/MailosaurClient.php index 06366b7..77e94f5 100644 --- a/src/MailosaurClient.php +++ b/src/MailosaurClient.php @@ -8,6 +8,7 @@ use Mailosaur\Operations\Messages; use Mailosaur\Operations\Servers; use Mailosaur\Operations\Usage; +use Mailosaur\Operations\Devices; class MailosaurClient { @@ -32,6 +33,9 @@ class MailosaurClient /** @var Operations\Usage */ public $usage; + /** @var Operations\Devices */ + public $devices; + public function __construct($apiKey, $baseUri = 'https://mailosaur.com/') { @@ -48,6 +52,8 @@ public function __construct($apiKey, $baseUri = 'https://mailosaur.com/') $this->analysis = new Analysis($this); $this->usage = new Usage($this); + + $this->devices = new Devices($this); } /** @@ -82,4 +88,4 @@ protected function setApiKey($apiKey) $this->apiKey = $apiKey; } -} \ No newline at end of file +} diff --git a/src/Models/Device.php b/src/Models/Device.php new file mode 100644 index 0000000..797f30f --- /dev/null +++ b/src/Models/Device.php @@ -0,0 +1,24 @@ +id = $data->id; + } + + if (property_exists($data, 'name')) { + $this->name = $data->name; + } + } +} diff --git a/src/Models/DeviceCreateOptions.php b/src/Models/DeviceCreateOptions.php new file mode 100644 index 0000000..cc11e51 --- /dev/null +++ b/src/Models/DeviceCreateOptions.php @@ -0,0 +1,35 @@ + $this->name, + 'sharedSecret' => $this->sharedSecret + ); + + return $options; + } + + public function toJsonString() + { + return json_encode($this->__toArray()); + } +} diff --git a/src/Models/DeviceListResult.php b/src/Models/DeviceListResult.php new file mode 100644 index 0000000..81ebdab --- /dev/null +++ b/src/Models/DeviceListResult.php @@ -0,0 +1,21 @@ +items)) { + foreach ($data->items as $item) { + $this->items[] = new Device($item); + } + } + } +} diff --git a/src/Models/OtpResult.php b/src/Models/OtpResult.php new file mode 100644 index 0000000..8c1728f --- /dev/null +++ b/src/Models/OtpResult.php @@ -0,0 +1,24 @@ +code = $data->code; + } + + if (property_exists($data, 'expires')) { + $this->expires = new \DateTime($data->expires); + } + } +} diff --git a/src/Operations/Devices.php b/src/Operations/Devices.php new file mode 100644 index 0000000..0d2b763 --- /dev/null +++ b/src/Operations/Devices.php @@ -0,0 +1,108 @@ +List all devices + * + * @return DeviceListResult + * @throws \Mailosaur\Models\MailosaurException + * @see https://mailosaur.com/docs/api/#operation/Devices_List List all devices + * @example https://mailosaur.com/docs/api/#operation/Devices_List + */ + public function all() + { + $response = $this->request('api/devices'); + + $response = json_decode($response); + + return new DeviceListResult($response); + } + + /** + * Create a device + *

Creates a new virtual security device and returns it.

+ * + * @param $deviceCreateOptions + * + * @return \Mailosaur\Models\Device + * @throws \Mailosaur\Models\MailosaurException + * @see https://mailosaur.com/docs/api/#operation/Devices_Create Create a device + * @example https://mailosaur.com/docs/api/#operation/Devices_Create + */ + public function create(DeviceCreateOptions $deviceCreateOptions) + { + $payload = $deviceCreateOptions->toJsonString(); + + $response = $this->request( + 'api/devices/', + array( + CURLOPT_CUSTOMREQUEST => 'POST', + CURLOPT_POSTFIELDS => $payload, + CURLOPT_HTTPHEADER => array('Content-Type:application/json', 'Content-Length: ' . strlen($payload)) + ) + ); + + $response = json_decode($response); + + return new Device($response); + } + + /** + * Retrieves the current one-time password for a saved device, or given base32-encoded shared secret. + * + * @param string $query Either the unique identifier of the device, or a base32-encoded shared secret. + * + * @return \Mailosaur\Models\OtpResult + * @throws \Mailosaur\Models\MailosaurException + * @see https://mailosaur.com/docs/api/#operation/Devices_Otp Retrieve the current one-time password + * @example https://mailosaur.com/docs/api/#operation/Devices_Otp + */ + public function otp($query) + { + if (str_contains($query, "-")) { + $response = $this->request('api/devices/' . urlencode($query) . '/otp'); + + $response = json_decode($response); + + return new OtpResult($response); + } + + $payload = json_encode(array('sharedSecret' => $query)); + $response = $this->request( + 'api/devices/otp', + array( + CURLOPT_CUSTOMREQUEST => 'POST', + CURLOPT_POSTFIELDS => $payload, + CURLOPT_HTTPHEADER => array('Content-Type:application/json', 'Content-Length: ' . strlen($payload)) + ) + ); + + $response = json_decode($response); + + return new OtpResult($response); + } + + /** + * Delete a device + * + * @param string $id The identifier of the device to be deleted. + * + * @throws \Mailosaur\Models\MailosaurException + * @see https://mailosaur.com/docs/api/#operation/Devices_Delete Delete a device + * @example https://mailosaur.com/docs/api/#operation/Devices_Delete + */ + public function delete($id) + { + $this->request('api/devices/' . urlencode($id), array(CURLOPT_CUSTOMREQUEST => 'DELETE')); + } +} diff --git a/tests/DevicesTests.php b/tests/DevicesTests.php new file mode 100644 index 0000000..e7ca831 --- /dev/null +++ b/tests/DevicesTests.php @@ -0,0 +1,57 @@ +name = $deviceName; + $options->sharedSecret = $sharedSecret; + $createdDevice = self::$client->devices->create($options); + + $this->assertFalse(empty($createdDevice->id)); + $this->assertEquals($deviceName, $createdDevice->name); + + // Retrieve an otp via device ID + $otpResult = self::$client->devices->otp($createdDevice->id); + $this->assertEquals(6, strlen($otpResult->code)); + + $this->assertEquals(1, count(self::$client->devices->all()->items)); + self::$client->devices->delete($createdDevice->id); + $this->assertEquals(0, count(self::$client->devices->all()->items)); + } + + public function testOtpViaSharedSecret() + { + $sharedSecret = "ONSWG4TFOQYTEMY="; + + $otpResult = self::$client->devices->otp($sharedSecret); + $this->assertEquals(6, strlen($otpResult->code)); + } +}