Просмотр исходного кода

feat: EK-744: 会员注册成功后,增加发送短信功能.

kevinElken 10 месяцев назад
Родитель
Сommit
fda7fa2b85

+ 43 - 0
common/components/EknotifierSmsDriver.php

@@ -0,0 +1,43 @@
+<?php
+namespace common\components;
+
+use common\helpers\LoggerTool;
+use common\models\SmsRecord;
+use ElkenGit\EknotifierPHP\EknotifierSms;
+
+class EknotifierSmsDriver implements SmsDriverInterface
+{
+    /**
+     * Send SMS via Eknotifier.
+     *
+     * @param string $mobile
+     * @param string $message
+     * @param string $userId
+     * @param string $countryId
+     * @param string $classify
+     * @return bool
+     * @throws \Exception
+     */
+    public function send(string $mobile, string $message, string $userId, string $countryId, string $classify = ''): bool
+    {
+        $eknotifierUrl = \Yii::$app->params['sms']['url'];
+        $applicationCode = \Yii::$app->params['sms']['url'];
+        $applicationPassword = \Yii::$app->params['sms']['url'];
+
+        $eknotifierSms = new EknotifierSms($eknotifierUrl, $applicationCode, $applicationPassword);
+        $response = $eknotifierSms->sendSMS($mobile, $message, $userId);
+
+        LoggerTool::debug(json_encode(['eknotifierSms', $eknotifierUrl, $applicationCode, $applicationPassword, $mobile, $message, $userId, $eknotifierSms, $response]));
+
+        $record = new SmsRecord();
+        $record->USER_ID = $userId;
+        $record->CLASSIFY = $classify;
+        $record->COUNTRY_ID = $countryId;
+        $record->MOBILE = $mobile;
+        $record->CONTENT = $message;
+        $record->RESULT = '';
+        $record->save();
+
+        return true;
+    }
+}

+ 17 - 0
common/components/SmsDriverInterface.php

@@ -0,0 +1,17 @@
+<?php
+namespace common\components;
+
+interface SmsDriverInterface
+{
+    /**
+     * Send the SMS.
+     *
+     * @param string $mobile
+     * @param string $message
+     * @param string $userId
+     * @param string $countryId
+     * @param string $classify
+     * @return bool
+     */
+    public function send(string $mobile, string $message, string $userId, string $countryId, string $classify): bool;
+}

+ 7 - 0
common/config/params.php

@@ -434,4 +434,11 @@ return [
     'allowPlatform' => $mainConfig['allowPlatform'],
     // cdn地址
     'cdnPath' => $mainConfig['cdnPath'],
+    // sms
+    'sms' => [
+        'driver' => 'eknotifier',
+        'url' => 'https://notificationuat.elken.com',
+        'code' => 'EVO_202303',
+        'password' => 'J0N2O51nQz@w',
+    ],
 ];

+ 25 - 0
common/helpers/Sms.php

@@ -0,0 +1,25 @@
+<?php
+namespace common\helpers;
+
+use common\components\EknotifierSmsDriver;
+
+class Sms
+{
+    const welcomePack = 'welcomePack';
+
+    /**
+     * Send the SMS.
+     *
+     * @param string $mobile
+     * @param string $message
+     * @param string $userId
+     * @param string $countryId
+     * @param string $classify
+     * @return bool
+     * @throws \Exception
+     */
+    public function sendSMS(string $mobile, string $message, string $userId, string $countryId, string $classify): bool
+    {
+        return (new EknotifierSmsDriver)->send($mobile, $message, $userId, $countryId, $classify);
+    }
+}

+ 58 - 0
common/models/SmsRecord.php

@@ -0,0 +1,58 @@
+<?php
+
+namespace common\models;
+
+use Yii;
+
+/**
+ * This is the model class for table "{{%SMS_RECORD}}".
+ *
+ * @property string ID
+ * @property string USER_ID 用户ID
+ * @property string CLASSIFY 类型
+ * @property string CONTENT 内容
+ * @property string COUNTRY_ID 国家ID
+ * @property string MOBILE 号码
+ * @property int RESULT 状态
+ * @property string RESPONSE 回调
+ * @property string CREATED_AT 时间
+ */
+class SmsRecord extends \common\components\ActiveRecord
+{
+    /**
+     * {@inheritdoc}
+     */
+    public static function tableName()
+    {
+        return '{{%SMS_RECORD}}';
+    }
+
+    /**
+     * {@inheritdoc}
+     */
+    public function rules()
+    {
+        return [
+            [['ID'], 'string', 'max' => 32],
+            [['ID'], 'unique'],
+        ];
+    }
+
+    /**
+     * {@inheritdoc}
+     */
+    public function attributeLabels()
+    {
+        return [
+            'ID' => 'ID',
+            'USER_ID' => '用户ID',
+            'CLASSIFY' => '类型',
+            'COUNTRY_ID' => '国家ID',
+            'MOBILE' => '号码',
+            'CONTENT' => '内容',
+            'RESULT' => '状态',
+            'RESPONSE' => '回调',
+            'CREATED_AT' => '创建时间',
+        ];
+    }
+}

+ 2 - 1
composer.json

@@ -29,7 +29,8 @@
         "monolog/monolog": "*",
         "tecnickcom/tcpdf": "^6.4",
         "ext-curl": "*",
-        "smladeoye/yii2-paystack": "^1.0"
+        "smladeoye/yii2-paystack": "^1.0",
+        "elkengit/eknotifier-php": "dev-master"
     },
     "require-dev": {
         "yiisoft/yii2-debug": "~2.0.0",

+ 4 - 0
vendor/elkengit/eknotifier-php/.gitignore

@@ -0,0 +1,4 @@
+composer.lock
+/storage/
+/vendor/
+/.idea/

+ 27 - 0
vendor/elkengit/eknotifier-php/composer.json

@@ -0,0 +1,27 @@
+{
+    "name": "elkengit/eknotifier-php",
+    "description": "EKNotifier Integration Package",
+    "type": "library",
+    "require": {
+        "php": ">=7.1.3",
+        "ext-json": "*",
+        "guzzlehttp/guzzle": "^6.3",
+        "illuminate/cache": "^5.8|6.*|7.*|8.*",
+        "illuminate/filesystem": "^5.8|6.*|7.*|8.*"
+    },
+    "autoload": {
+        "psr-4": {
+            "ElkenGit\\EknotifierPHP\\": "src"
+        },
+        "files": [
+            "src/helpers.php"
+        ]
+    },
+    "extra":{
+        "laravel":{
+            "providers":[
+                "ElkenGit\\EknotifierPHP\\EknotifierPhpServiceProvider"
+            ]
+        }
+    }
+}

+ 76 - 0
vendor/elkengit/eknotifier-php/readme.md

@@ -0,0 +1,76 @@
+# EKNotifier Integration PHP SDK
+
+This package is created as an easy wrapper for EKNotifier Service. It can be used in Laravel
+project or any PHP projects utilizing composer.
+
+## Todo
+- [x] SMS Integration
+- [x] Email Integration
+- [x] Push Notification Integration
+
+## Installation
+Include the repository as a VCS repository and require the version as `dev-master`
+```
+"repositories": [
+        {
+            "type": "vcs",
+            "url": "https://github.com/ElkenGit/eknotifier-php"
+        }
+    ],
+    "require": {
+        ...
+        "elkengit/eknotifier-php": "dev-master"
+    }
+```
+Then run `composer update`.
+
+#### Note : Extra step for laravel user's only!!  
+Run `php artisan vendor:publish --provider="ElkenGit\EknotifierPHP\EknotifierPhpServiceProvider"`  
+This will create a `eknotifier.php` file under your config directory, fill it up.
+
+## Usage
+
+SMS
+```php
+<?php
+
+use ElkenGit\EknotifierPHP\EknotifierSms;
+
+// Instantiate without Laravel
+$sms = new EknotifierSms(EKNOTIFIER_URL, APPLICATION_CODE, APPLICATION_PASSWORD);
+
+// Instantiate with Laravel -- Must have config/eknotifier.php config filled
+$sms = new EknotifierSms;
+
+$phoneNumber = '0123456789'; // String, REQUIRED
+$text = 'TEST SMS TEXT'; // String, REQUIRED
+$userId = 1; // Integer, OPTIONAL (will be set to 0 if it's not given)
+
+// Send the sms.
+$sms->sendSMS($phoneNumber, $text, $userId); // Returns boolean
+````
+
+EMAIL
+```php
+<?php
+
+use ElkenGit\EknotifierPHP\EknotifierEmail;
+
+// Instantiate without Laravel
+$email = new EknotifierEmail(EKNOTIFIER_URL, APPLICATION_CODE, APPLICATION_PASSWORD);
+
+// Instantiate with Laravel -- Must have config/eknotifier.php config filled
+$email = new EknotifierEmail;
+
+// An array of recipients
+$emailsRecipients = [
+    ['email' => 'user@email.com', 'user_id' => 1],
+    ['email' => 'guest@email.com', 'user_id' => null],
+]; 
+
+$subject = 'EMAIL SUBJECT'; // String, REQUIRED
+$text = 'TEST EMAIL TEXT'; // String, REQUIRED
+
+// Send the email.
+$email->sendEmail($emailsRecipients, $subject, $text); // Returns boolean
+````

+ 147 - 0
vendor/elkengit/eknotifier-php/src/EknotifierCommon.php

@@ -0,0 +1,147 @@
+<?php
+namespace ElkenGit\EknotifierPHP;
+
+use GuzzleHttp\Client;
+use GuzzleHttp\Psr7\Response;
+use GuzzleHttp\Exception\BadResponseException;
+use Illuminate\Support\Facades\Log;
+use Psr\Http\Message\ResponseInterface;
+
+/**
+ * Class EKNotifierCommon provide an easy to use integration with the EKNotifier service.
+ */
+class EknotifierCommon
+{
+    /**
+     * Application credentials.
+     *
+     * @var string|null
+     */
+    public $applicationCode, $applicationPassword, $notifierUrl;
+
+    /**
+     * Guzzle client.
+     *
+     * @var Client
+     */
+    private $httpClient;
+
+    /**
+     * Instantiate EknotifierCommon Class.
+     *
+     * @param string|null $url
+     * @param string|null $applicationCode
+     * @param string|null $applicationPassword
+     * @throws \Exception
+     */
+    public function __construct(string $url = null, string $applicationCode = null, string $applicationPassword = null)
+    {
+        $this->httpClient = new Client();
+
+        if (function_exists('config')) {
+            $this->notifierUrl = config('eknotifier.url');
+
+            $this->applicationCode = config('eknotifier.app_code');
+
+            $this->applicationPassword = config('eknotifier.app_password');
+        } elseif (!$url || !$applicationCode || !$applicationPassword) {
+            throw new \Exception('Url, Application Code, or Application Password is missing');
+        } else {
+            $this->notifierUrl = $url;
+
+            $this->applicationCode = $applicationCode;
+
+            $this->applicationPassword = $applicationPassword;
+        }
+    }
+
+    /**
+     * Get the EKNotifier JWT Token.
+     *
+     * @return string|null
+     * @throws \GuzzleHttp\Exception\GuzzleException
+     * @throws \Exception
+     */
+    public function getAuthToken(): ?string
+    {
+        if (!cache('eknotifier_token')) {
+            $this->login();
+        }
+
+        return cache('eknotifier_token');
+    }
+
+    /**
+     * Login to the EKNotifier Service and cache the key.
+     *
+     * @return bool
+     * @throws \GuzzleHttp\Exception\GuzzleException
+     * @throws \Exception
+     */
+    public function login(): bool
+    {
+        if (cache('eknotifier_token')) {
+            return true;
+        }
+
+        $response = $this->postAPI('application/login', [
+            'code' => $this->applicationCode,
+            'password' => $this->applicationPassword
+        ]);
+
+
+        if ($response->getStatusCode() === 200) {
+            $result = json_decode(trim($response->getBody()), true);
+
+            cache(['eknotifier_token' => $result['access_token']], 1800);
+
+            return true;
+        }
+
+        return false;
+    }
+
+    /**
+     * Call EKNotifier POST API.
+     *
+     * @param string $path
+     * @param array $request
+     * @param string|null $token
+     * @return ResponseInterface
+     * @throws \GuzzleHttp\Exception\GuzzleException
+     */
+    protected function postAPI(string $path, array $request, string $token = null): ResponseInterface
+    {
+        $url = $this->notifierUrl . '/api/v1/' . $path;
+
+        $params = ['json' => $request];
+
+        if ($token) {
+            $params['headers'] = ['Authorization' => 'Bearer ' . $token];
+        }
+
+        try {
+            return $this->httpClient->request('POST', $url, $params);
+        } catch (\Exception $exception) {
+            if ($exception instanceof BadResponseException) {
+                if (class_exists(\Illuminate\Log\Logger::class)) {
+                    Log::critical('EKNOTIFIER ERROR' . $exception->getResponse()->getBody()->getContents());
+                }
+
+                return new Response(
+                    $exception->getResponse()->getStatusCode(),
+                    $exception->getResponse()->getHeaders(),
+                    $exception->getResponse()->getBody()->getContents(),
+                    $exception->getResponse()->getProtocolVersion(),
+                    $exception->getResponse()->getReasonPhrase()
+                );
+            }
+
+            if (class_exists(\Illuminate\Log\Logger::class)) {
+                Log::critical('EKNOTIFIER ERROR' . $exception->getMessage());
+            }
+
+            return new Response(500, [], $exception->getMessage());
+        }
+    }
+}

+ 58 - 0
vendor/elkengit/eknotifier-php/src/EknotifierEmail.php

@@ -0,0 +1,58 @@
+<?php
+namespace ElkenGit\EknotifierPHP;
+
+use Carbon\Carbon;
+
+/**
+ * Class EmailNotifier to provide Email Notifier integration for EKNotifier Service.
+ */
+class EknotifierEmail extends EknotifierCommon
+{
+    /**
+     * Instantiate EknotifierEmail Class.
+     *
+     * @param string|null $url
+     * @param string|null $applicationCode
+     * @param string|null $applicationPassword
+     * @throws \Exception
+     */
+    public function __construct(string $url = null, string $applicationCode = null, string $applicationPassword = null)
+    {
+        parent::__construct($url, $applicationCode, $applicationPassword);
+    }
+
+    /**
+     * Send email to the eknotifier service.
+     *
+     * @param array $emails
+     * @param string $subject
+     * @param string $text
+     * @param int $userId
+     * @return bool
+     * @throws \GuzzleHttp\Exception\GuzzleException
+     */
+    public function sendEmail(array $emails, string $subject, string $text): bool
+    {
+        $token = $this->getAuthToken();
+
+        $request = [
+            'name' => $this->applicationCode . ' EMAIL ' . (count($emails) > 1 ? '[multiple]' : $emails[0]['email']),
+            'send_at' => Carbon::now()->format('Y-m-d H:i:s'),
+            'recipients' => []
+        ];
+
+        foreach ($emails as $recipient) {
+            $request['recipients'][] = [
+                'application_user_id' => $recipient['user_id'] ?? 0,
+                'delivery_destination' => $recipient['email'],
+                'delivery_type' => 'EMAIL',
+                'subject' => $subject,
+                'body' => $text
+            ];
+        }
+
+        $response = $this->postAPI('notification/send', $request, $token);
+
+        return $response->getStatusCode() === 200;
+    }
+}

+ 21 - 0
vendor/elkengit/eknotifier-php/src/EknotifierPhpServiceProvider.php

@@ -0,0 +1,21 @@
+<?php
+namespace ElkenGit\EknotifierPHP;
+
+use Illuminate\Support\ServiceProvider;
+
+class EknotifierPhpServiceProvider extends ServiceProvider
+{
+    /**
+     * Bootstrap the application services.
+     *
+     * @return void
+     */
+    public function boot()
+    {
+        if ($this->app->runningInConsole()) {
+            $this->publishes([
+                __DIR__.'/config/eknotifier.php' => $this->app->configPath('/eknotifier.php'),
+            ], 'config');
+        }
+    }
+}

+ 55 - 0
vendor/elkengit/eknotifier-php/src/EknotifierPush.php

@@ -0,0 +1,55 @@
+<?php
+namespace ElkenGit\EknotifierPHP;
+
+use Carbon\Carbon;
+
+/**
+ * Class EknotifierPush to provide Push Notifier integration for EKNotifier Service.
+ */
+class EknotifierPush extends EknotifierCommon
+{
+    /**
+     * Instantiate EknotifierPush Class.
+     *
+     * @param string|null $url
+     * @param string|null $applicationCode
+     * @param string|null $applicationPassword
+     * @throws \Exception
+     */
+    public function __construct(string $url = null, string $applicationCode = null, string $applicationPassword = null)
+    {
+        parent::__construct($url, $applicationCode, $applicationPassword);
+    }
+
+    /**
+     * Send a push notification.
+     *
+     * @param string $deviceToken
+     * @param array $payload
+     * @param int $userId
+     * @return bool
+     * @throws \GuzzleHttp\Exception\GuzzleException
+     */
+    public function sendPush(string $deviceToken, array $payload, int $userId = 0): bool
+    {
+        $token = $this->getAuthToken();
+
+        $request = [
+            'name' => $this->applicationCode . ' PUSH ' . $deviceToken,
+            'send_at' => Carbon::now()->format('Y-m-d H:i:s'),
+            'recipients' => [
+                [
+                    'application_user_id' => $userId,
+                    'delivery_destination' => $deviceToken,
+                    'delivery_type' => 'PUSH',
+                    'body' => 'Push Notification',
+                    'payload' => $payload
+                ]
+            ]
+        ];
+
+        $response = $this->postAPI('notification/send', $request, $token);
+
+        return $response->getStatusCode() === 200;
+    }
+}

+ 52 - 0
vendor/elkengit/eknotifier-php/src/EknotifierSms.php

@@ -0,0 +1,52 @@
+<?php
+namespace ElkenGit\EknotifierPHP;
+
+use Carbon\Carbon;
+
+/**
+ * Class SmsNotifier to provide SMS Notifier integration for EKNotifier Service.
+ */
+class EknotifierSms extends EknotifierCommon
+{
+    /**
+     * Instantiate EknotifierSms Class.
+     *
+     * @param string|null $url
+     * @param string|null $applicationCode
+     * @param string|null $applicationPassword
+     * @throws \Exception
+     */
+    public function __construct(string $url = null, string $applicationCode = null, string $applicationPassword = null)
+    {
+        parent::__construct($url, $applicationCode, $applicationPassword);
+    }
+
+    /**
+     * Send an SMS.
+     *
+     * @param string $phoneNumber
+     * @param string $text
+     * @param int $userId
+     * @return bool
+     * @throws \GuzzleHttp\Exception\GuzzleException
+     */
+    public function sendSMS(string $phoneNumber, string $text, int $userId = 0): bool
+    {
+        $token = $this->getAuthToken();
+
+        $request = [
+            'name' => $this->applicationCode . ' SMS ' . $phoneNumber,
+            'send_at' => Carbon::now()->format('Y-m-d H:i:s'),
+            'recipients' => [
+                [
+                    'application_user_id' => $userId,
+                    'delivery_destination' => $phoneNumber,
+                    'delivery_type' => 'SMS',
+                    'body' => $text
+                ]
+            ]
+        ];
+
+        return $this->postAPI('notification/send', $request, $token);
+    }
+}

+ 19 - 0
vendor/elkengit/eknotifier-php/src/config/eknotifier.php

@@ -0,0 +1,19 @@
+<?php
+
+return [
+
+    /*
+    |--------------------------------------------------------------------------
+    | EK Notifier Integration Config
+    |--------------------------------------------------------------------------    |
+    */
+
+    // EK Notifier URL
+    'url' => env('EKNOTIFIER_URL'),
+
+    // EK Notifier Application Code
+    'app_code' => env('EKNOTIFIER_APPLICATION_CODE'),
+
+    // EK Notifier Application Password
+    'app_password' => env('EKNOTIFIER_APPLICATION_PASSWORD'),
+];

+ 44 - 0
vendor/elkengit/eknotifier-php/src/helpers.php

@@ -0,0 +1,44 @@
+<?php
+
+if (!function_exists('cache'))
+{
+    /**
+     * Create cache instance or set cache.
+     *
+     * @return bool|\Illuminate\Cache\Repository|mixed
+     * @throws Exception
+     */
+    function cache()
+    {
+        $fileStore = new \Illuminate\Cache\FileStore(
+            new \Illuminate\Filesystem\Filesystem(),
+            realpath(__DIR__) . '/../storage/cache'
+        );
+
+        $cache = new \Illuminate\Cache\Repository($fileStore);
+
+        $arguments = func_get_args();
+
+        if (empty($arguments)) {
+            return $cache;
+        }
+
+        if (is_string($arguments[0])) {
+            return $cache->get(...$arguments);
+        }
+
+        if (! is_array($arguments[0])) {
+            throw new Exception(
+                'When setting a value in the cache, you must pass an array of key / value pairs.'
+            );
+        }
+
+        if (! isset($arguments[1])) {
+            throw new Exception(
+                'You must specify an expiration time when setting a value in the cache.'
+            );
+        }
+
+        return $cache->put(key($arguments[0]), reset($arguments[0]), $arguments[1]);
+    }
+}

+ 3 - 0
vendor/elkengit/one-auth-php-sdk/.gitignore

@@ -0,0 +1,3 @@
+/vendor
+/.idea
+/.vscode

+ 60 - 0
vendor/elkengit/one-auth-php-sdk/README.md

@@ -0,0 +1,60 @@
+# One Auth PHP SDK
+
+
+## How to Install the Package?
+
+- Add the following lines into `repositories` and `require` attributes.
+```
+{
+    "repositories": [
+        ...
+        {
+            "type": "vcs",
+            "url": "https://github.com/ElkenGit/One-Auth-PHP-SDK"
+        }
+    ]
+    
+    ...
+    
+    "require": {
+        ...
+        "elkengit/one-auth-php-sdk": "dev-master"
+    }
+}
+```
+
+- Run `composer update`
+
+## How to Install the Package's Config File?
+
+- Execute the following command line
+```
+php artisan vendor:publish --provider="ElkenGit\OneAuthSDK\OneAuthSdkServiceProvider"
+```
+
+- Check your `config` folder, `one_auth.php` has been created. We highly recommend you to delete the file and re-run 
+the command above just in case there is any new changes in the config file. 
+- Look into the `one_auth.php` and add get the `ENV` keys and configure in your `.env` file. Following are the available 
+keys that should setup in your `.env` file. 
+```
+##ONE AUTH SETTINGS-------------------------------------------------------------------------------------
+ONE_AUTH_BASE_URL=
+ONE_AUTH_CLIENT_ID=
+ONE_AUTH_CLIENT_SECRET=
+ONE_AUTH_CLIENT_PLATFORM=
+```
+
+## How to Start Using the "one_auth" Driver?
+
+- Go to `config/auth.php`, look for `guards` array. Following example is we change the driver for `auth:api` 
+to start using `one_auth` driver. 
+```
+...
+
+'api' => [
+    'driver' => 'one_auth',
+    'provider' => 'users',
+]
+
+...
+```

+ 23 - 0
vendor/elkengit/one-auth-php-sdk/composer.json

@@ -0,0 +1,23 @@
+{
+    "name": "elkengit/one-auth-php-sdk",
+    "description": "The oauth 2.0 PHP SDK for Elken One Auth.",
+    "type": "library",
+    "require": {
+        "php": ">=7.4",
+        "ext-json": "*",
+        "guzzlehttp/guzzle": "^6.3"
+    },
+    "autoload": {
+        "psr-4": {
+            "ElkenGit\\OneAuthSDK\\": "src"
+        },
+        "files": []
+    },
+    "extra":{
+        "laravel":{
+            "providers":[
+                "ElkenGit\\OneAuthSDK\\OneAuthSdkServiceProvider"
+            ]
+        }
+    }
+}

+ 334 - 0
vendor/elkengit/one-auth-php-sdk/src/Client.php

@@ -0,0 +1,334 @@
+<?php
+
+namespace ElkenGit\OneAuthSDK;
+
+use Exception;
+use GuzzleHttp\Exception\GuzzleException;
+use Psr\Http\Message\ResponseInterface;
+
+class Client
+{
+    public ?string $bearerToken;
+
+    /**
+     * @param string|null $bearerToken
+     */
+    public function __construct(
+        ?string $bearerToken = null
+    )
+    {
+        $this->setBearerToken($bearerToken);
+    }
+
+    /**
+     * @return string|null
+     */
+    public function getBearerToken(): ?string
+    {
+        return $this->bearerToken ?? null;
+    }
+
+    /**
+     * @param string|null $value
+     * @return void
+     */
+    public function setBearerToken(
+        ?string $value
+    ): void
+    {
+        $this->bearerToken = $value;
+    }
+
+    /**
+     * @return bool
+     * @throws GuzzleException
+     */
+    public function verifyAccessToken(): bool
+    {
+        try {
+            $response = $this->makeOneAuthHttpRequest(
+                'GET',
+                config('one_auth.url_paths.auth.verify_access_token')
+            );
+
+            if ($response->getStatusCode() == 200) {
+                return true;
+            }
+        } catch (Exception $e) {
+            //
+        }
+
+        return false;
+    }
+
+    /**
+     * @param string $clientId
+     * @param string $clientSecret
+     * @return array|null
+     * @throws GuzzleException
+     */
+    public function loginUsingClient(
+        string $clientId,
+        string $clientSecret
+    ): ?array
+    {
+        try {
+            $response = $this->makeOneAuthHttpRequest(
+                'POST',
+                config('one_auth.url_paths.auth.logout'),
+                [
+                    'grant_type' => 'client_credentials',
+                    'client_id' => $clientId,
+                    'client_secret' => $clientSecret
+                ]
+            );
+
+            if ($response->getStatusCode() == 200) {
+                return json_decode(
+                    $response->getBody(),
+                    true
+                );
+            } else {
+                return null;
+            }
+        } catch (Exception $e) {
+            return null;
+        }
+    }
+
+    /**
+     * @param string $userUuid
+     * @param string $password
+     * @return array|null
+     * @throws GuzzleException
+     */
+    public function login(
+        string $userUuid,
+        string $password
+    ): ?array
+    {
+        try {
+            $response = $this->makeOneAuthHttpRequest(
+                'POST',
+                config('one_auth.url_paths.auth.login'),
+                [
+                    'user_uuid' => $userUuid,
+                    'password' => $password
+                ]
+            );
+
+            if ($response->getStatusCode() == 200) {
+                return json_decode(
+                    $response->getBody(),
+                    true
+                );
+            } else {
+                return null;
+            }
+        } catch (Exception $e) {
+            return null;
+        }
+    }
+
+    /**
+     * @param string $userUuid
+     * @param string $loginAsUserUuid
+     * @return array|null
+     * @throws GuzzleException
+     */
+    public function loginAs(
+        string $userUuid,
+        string $loginAsUserUuid
+    ): ?array
+    {
+        try {
+            $response = $this->makeOneAuthHttpRequest(
+                'POST',
+                config('one_auth.url_paths.auth.login_as'),
+                [
+                    'user_uuid' => $userUuid,
+                    'login_as_user_uuid' => $loginAsUserUuid
+                ]
+            );
+
+            if ($response->getStatusCode() == 200) {
+                return json_decode(
+                    $response->getBody(),
+                    true
+                );
+            } else {
+                return null;
+            }
+        } catch (Exception $e) {
+            return null;
+        }
+    }
+
+    /**
+     * @param bool $revokeAllToken
+     * @return bool
+     * @throws GuzzleException
+     */
+    public function logout(
+        bool $revokeAllToken = false
+    ): bool
+    {
+        try {
+            $response = $this->makeOneAuthHttpRequest(
+                'POST',
+                config('one_auth.url_paths.auth.logout'),
+                [
+                    'revoke_all' => $revokeAllToken
+                ]
+            );
+
+            if ($response->getStatusCode() == 200) {
+                return true;
+            }
+        } catch (Exception $e) {
+            //
+        }
+
+        return false;
+    }
+
+    /**
+     * @param string $name
+     * @param string $email
+     * @param string $password
+     * @param string $appName
+     * @param int $appUserId
+     * @param string|null $appMemberId
+     * @param bool $isActive
+     * @return bool
+     * @throws GuzzleException
+     */
+    public function createUser(
+        string $name,
+        string $email,
+        string $password,
+        string $appName,
+        int $appUserId,
+        ?string $appMemberId,
+        bool $isActive = true
+    ): bool
+    {
+        try {
+            $response = $this->makeOneAuthHttpRequest(
+                'POST',
+                config('one_auth.url_paths.users.create'),
+                [
+                    'name' => $name,
+                    'email' => $email,
+                    'password' => $password,
+                    'app_name' => $appName,
+                    'app_user_id' => $appUserId,
+                    'app_member_id' => $appMemberId,
+                    'is_active' => $isActive
+                ]
+            );
+
+            if ($response->getStatusCode() == 200) {
+                return true;
+            }
+        } catch (Exception $e) {
+            //
+        }
+
+        return false;
+    }
+
+    /**
+     * @param string $userUuid
+     * @return array|null
+     * @throws GuzzleException
+     */
+    public function showUser(
+        string $userUuid
+    ): ?array
+    {
+        try {
+            $response = $this->makeOneAuthHttpRequest(
+                'GET',
+                sprintf(
+                    config('one_auth.url_paths.users.show'),
+                    $userUuid
+                )
+            );
+
+            if ($response->getStatusCode() == 200) {
+                return json_decode(
+                    $response->getBody(),
+                    true
+                );
+            } else {
+                return null;
+            }
+        } catch (Exception $e) {
+            return null;
+        }
+    }
+
+    /**
+     * @return array|null
+     * @throws GuzzleException
+     */
+    public function getAuthUser(): ?array
+    {
+        try {
+            $response = $this->makeOneAuthHttpRequest(
+                'GET',
+                config('one_auth.url_paths.auth.show_auth_user')
+            );
+
+            return json_decode(
+                $response->getBody(),
+                true
+            );
+        } catch (Exception $e) {
+            //
+        }
+
+        return null;
+    }
+
+    /**
+     * @param string $httpMethod
+     * @param string $urlPath
+     * @param array $formParams
+     * @return ResponseInterface
+     * @throws GuzzleException
+     */
+    private function makeOneAuthHttpRequest(
+        string $httpMethod,
+        string $urlPath,
+        array $formParams = []
+    ): ResponseInterface
+    {
+        $httpClient = new \GuzzleHttp\Client();
+
+        $options = [
+            'headers' => [
+                'Accept' => 'application/json'
+            ]
+        ];
+
+        if (!empty($this->getBearerToken())) {
+            $options['headers']['Authorization'] = $this->getBearerToken();
+        }
+
+        if (!empty($formParams)) {
+            $options['form_params'] = $formParams;
+        }
+
+        return $httpClient->request(
+            $httpMethod,
+            sprintf(
+                '%s%s',
+                config('one_auth.base_url'),
+                $urlPath
+            ),
+            $options
+        );
+    }
+}

+ 123 - 0
vendor/elkengit/one-auth-php-sdk/src/Drivers/Auth/OneAuthGuard.php

@@ -0,0 +1,123 @@
+<?php
+
+namespace ElkenGit\OneAuthSDK\Drivers\Auth;
+
+use ElkenGit\OneAuthSDK\Client;
+use Illuminate\Auth\GuardHelpers;
+use Illuminate\Auth\TokenGuard;
+use Illuminate\Contracts\Auth\Guard;
+use Illuminate\Contracts\Auth\UserProvider;
+use Illuminate\Http\Request;
+
+class OneAuthGuard implements Guard
+{
+    use GuardHelpers;
+
+    protected ?string $token = null;
+
+    public function __construct(
+        UserProvider $userProvider
+    )
+    {
+        $this->provider = $userProvider;
+    }
+
+    /**
+     * Get the currently authenticated user.
+     *
+     * @return \Illuminate\Contracts\Auth\Authenticatable|null
+     */
+    public function user()
+    {
+        if (!is_null($this->user)) {
+            return $this->user;
+        }
+
+        $this->token = $_SERVER['HTTP_AUTHORIZATION'];
+        if (is_null($this->token)) {
+            return null;
+        }
+
+        $oneAuthUser = $this->getUser();
+        if (empty($oneAuthUser)) {
+            return null;
+        }
+
+        $this->user = $this->provider
+            ->retrieveById(
+                $oneAuthUser['app_user_id']
+            );
+
+        return $this->user;
+    }
+
+    /**
+     * Check if token is valid.
+     *
+     * @return bool
+     * @throws \GuzzleHttp\Exception\GuzzleException
+     */
+    public function check()
+    {
+        $oneAuthClient = new Client($this->token);
+
+        return $oneAuthClient->verifyAccessToken();
+    }
+
+    /**
+     * Validate a user's credentials.
+     *
+     * @param array $credentials
+     * @return bool
+     * @throws \GuzzleHttp\Exception\GuzzleException
+     */
+    public function validate(array $credentials = [])
+    {
+        $oneAuthClient = new Client($this->token);
+
+        return $oneAuthClient->verifyAccessToken();
+    }
+
+    /**
+     * @return bool
+     * @throws \GuzzleHttp\Exception\GuzzleException
+     */
+    public function logout(): bool
+    {
+        $oneAuthSdkClient = new Client($this->token);
+
+        $response = $oneAuthSdkClient->logout();
+
+        if ($response) {
+            $this->user = null;
+        }
+
+        return $response;
+    }
+
+    /**
+     * Set the current request instance.
+     *
+     * @param  \Illuminate\Http\Request  $request
+     * @return $this
+     */
+    public function setRequest(Request $request)
+    {
+        $this->request = $request;
+
+        return $this;
+    }
+
+    /**
+     * Custom function, not extended from \Illuminate\Contracts\Auth\Guard
+     *
+     * @return array|null
+     * @throws \GuzzleHttp\Exception\GuzzleException
+     */
+    private function getUser(): ?array
+    {
+        $oneAuthClient = new Client($this->token);
+
+        return $oneAuthClient->getAuthUser();
+    }
+}

+ 31 - 0
vendor/elkengit/one-auth-php-sdk/src/OneAuthSdkServiceProvider.php

@@ -0,0 +1,31 @@
+<?php
+
+namespace ElkenGit\OneAuthSDK;
+
+use ElkenGit\OneAuthSDK\Drivers\Auth\OneAuthGuard;
+use Illuminate\Support\ServiceProvider;
+use Illuminate\Support\Facades\Auth;
+
+class OneAuthSdkServiceProvider extends ServiceProvider
+{
+    /**
+     * Bootstrap the application services.
+     *
+     * @return void
+     */
+    public function boot()
+    {
+        if ($this->app->runningInConsole()) {
+            $this->publishes(
+                [
+                    __DIR__ .'/config/one_auth.php' => $this->app->configPath('/one_auth.php'),
+                ],
+                'config'
+            );
+        }
+
+        Auth::extend('one_auth', function ($app, $name, array $config) {
+            return new OneAuthGuard(Auth::createUserProvider($config['provider']));
+        });
+    }
+}

+ 42 - 0
vendor/elkengit/one-auth-php-sdk/src/config/one_auth.php

@@ -0,0 +1,42 @@
+<?php
+
+return [
+
+    /*
+    |--------------------------------------------------------------------------
+    | One Auth SDK Configuration
+    |--------------------------------------------------------------------------    |
+    */
+
+    'base_url' => env('ONE_AUTH_BASE_URL'),
+
+    'client_id' => env('ONE_AUTH_CLIENT_ID'),
+
+    'client_secret' => env('ONE_AUTH_CLIENT_SECRET'),
+
+    'client_platform' => env('ONE_AUTH_CLIENT_PLATFORM'),
+
+    'url_paths' => [
+        'oauth' => [
+            'token' => '/oauth/token'
+        ],
+
+        'auth' => [
+            'verify_access_token' => '/api/auth/verify-access-token',
+
+            'show_auth_user' => '/api/auth/user',
+
+            'login' => '/api/auth/login',
+
+            'login_as' => '/api/auth/login-as',
+
+            'logout' => '/api/auth/logout'
+        ],
+
+        'users' => [
+            'create' => '/api/users',
+
+            'show' => '/api/users/%s'
+        ]
+    ]
+];