diff --git a/readme.md b/readme.md index 5e4cb21..df8cc63 100644 --- a/readme.md +++ b/readme.md @@ -45,8 +45,38 @@ QB_BASE_URL= ### Connect QuickBooks account -Go to `{yourdomain}/quickbooks/connect` to -connect your QuickBooks account with your application. +To connect your application with your QuickBooks company you can use `QuickbooksConnect` helper. +Helper has two methods: +* `getAuthorizationUrl` -> Returns redirect URL and puts `quickbooks_auth` cookie into Laravel cookie queue. +Cookie is valid for 30 minutes. +* `processHook` -> Validates `quickbooks_auth` cookie and sets realm id, access token and refresh token. + +Usage example: + +```php +namespace App\Http\Controllers; + +use LifeOnScreen\LaravelQuickBooks\QuickbooksConnect; +use Cookie; + +class QuickBooksController extends Controller +{ + public function connect() + { + return redirect(QuickbooksConnect::getAuthorizationUrl()) + ->withCookies(Cookie::getQueuedCookies()); + } + + public function refreshTokens() + { + if (QuickbooksConnect::processHook()) { + return 'Tokens successfully refreshed.'; + } + + return 'There were some problems refreshing tokens.'; + } +} +``` ### Sync Eloquent model to QuickBooks diff --git a/src/Controllers/QuickbooksController.php b/src/Controllers/QuickbooksController.php deleted file mode 100644 index 072d74e..0000000 --- a/src/Controllers/QuickbooksController.php +++ /dev/null @@ -1,36 +0,0 @@ -getAuthorizationUrl(); - - header('Location: ' . $url); - } - - /** - * @throws \QuickBooksOnline\API\Exception\SdkException - */ - public function refreshTokens() - { - if ((new QuickbooksConnect())->processHook(Request::get('realmId'), Request::get('code'))) { - return 'Tokens successfully refreshed.'; - } - - return 'There were some problems refreshing tokens.'; - } -} \ No newline at end of file diff --git a/src/LaravelQuickBooksServiceProvider.php b/src/LaravelQuickBooksServiceProvider.php index 8c9208b..c74b052 100644 --- a/src/LaravelQuickBooksServiceProvider.php +++ b/src/LaravelQuickBooksServiceProvider.php @@ -13,9 +13,6 @@ class LaravelQuickBooksServiceProvider extends ServiceProvider */ public function boot() { - $this->loadRoutesFrom(__DIR__ . '/Routes/routes.php'); - $this->loadViewsFrom(__DIR__ . '/path/to/views', 'courier'); - // Publishing is only necessary when using the CLI. if ($this->app->runningInConsole()) { diff --git a/src/QuickBooksEntity.php b/src/QuickBooksEntity.php index b6aee57..d0c103d 100644 --- a/src/QuickBooksEntity.php +++ b/src/QuickBooksEntity.php @@ -30,16 +30,6 @@ abstract class QuickBooksEntity extends Model implements QuickBookable */ protected $quickBooksConnection; - /** - * QuickBooksEntity constructor. - * @param array $attributes - */ - public function __construct(array $attributes = []) - { - $this->quickBooksConnection = App::make(QuickBooksConnection::class); - parent::__construct($attributes); - } - abstract protected function getQuickBooksArray(): array; /** @@ -140,6 +130,7 @@ protected function updateToQuickBooks(array $updateArray): bool */ public function syncToQuickbooks(): bool { + $this->quickBooksConnection = App::make(QuickBooksConnection::class); $syncArray = $this->getQuickBooksArray(); if (empty($this->quickbooks_id)) { return $this->insertToQuickBooks($syncArray); diff --git a/src/QuickBooksResources.php b/src/QuickBooksResources.php index 0a28b35..f9098bd 100644 --- a/src/QuickBooksResources.php +++ b/src/QuickBooksResources.php @@ -2,7 +2,7 @@ namespace LifeOnScreen\LaravelQuickBooks; -use QuickBooksOnline\API\Facades AS QuickBooksFacades; +use QuickBooksOnline\API\Facades as QuickBooksFacades; /** * Class QuickBooksResources diff --git a/src/QuickbooksConnect.php b/src/QuickbooksConnect.php index c86d153..0e59989 100644 --- a/src/QuickbooksConnect.php +++ b/src/QuickbooksConnect.php @@ -2,8 +2,11 @@ namespace LifeOnScreen\LaravelQuickBooks; +use Carbon\Carbon; +use Cookie; use Exception; use QuickBooksOnline\API\DataService\DataService; +use Request; /** * Class Init @@ -11,46 +14,36 @@ */ class QuickbooksConnect { - /** - * @var DataService - */ - private $dataService; /** - * Init constructor. + * @return string * @throws \QuickBooksOnline\API\Exception\SdkException */ - public function __construct() + public static function getAuthorizationUrl(): string { - $this->dataService = DataService::Configure([ - 'auth_mode' => config('quickbooks.data-service.auth-mode'), - 'ClientID' => config('quickbooks.data-service.client-id'), - 'ClientSecret' => config('quickbooks.data-service.client-secret'), - 'RedirectURI' => config('quickbooks.data-service.redirect-uri'), - 'scope' => config('quickbooks.data-service.scope'), - 'baseUrl' => config('quickbooks.data-service.base-url') - ]); - } + $cookieValue = str_random(32); + $validUntil = Carbon::now()->addMinutes(30)->timestamp; + Cookie::queue(Cookie::make('quickbooks_auth', $cookieValue, 30)); + option(['qb-auth' => "{$cookieValue}|{$validUntil}"]); - /** - * @throws \QuickBooksOnline\API\Exception\SdkException - */ - public function getAuthorizationUrl() - { - $OAuth2LoginHelper = $this->dataService->getOAuth2LoginHelper(); - - return $OAuth2LoginHelper->getAuthorizationCodeURL(); + return self::getDataService()->getOAuth2LoginHelper()->getAuthorizationCodeURL(); } /** - * @param $requestCode - * @param $realmID + * Set realm id, access token and refresh token. * @return bool */ - public function processHook(string $realmID, string $requestCode): bool + public static function processHook(): bool { + $realmID = Request::get('realmId'); + $requestCode = Request::get('code'); + if (empty($realmID) || empty($requestCode) || !self::cookieIsValid()) { + return false; + } + try { - $OAuth2LoginHelper = $this->dataService->getOAuth2LoginHelper(); + + $OAuth2LoginHelper = self::getDataService()->getOAuth2LoginHelper(); $accessTokenObj = $OAuth2LoginHelper->exchangeAuthorizationCodeForToken($requestCode, $realmID); $accessTokenValue = $accessTokenObj->getAccessToken(); @@ -58,10 +51,40 @@ public function processHook(string $realmID, string $requestCode): bool option(['qb-realm-id' => $realmID]); option(['qb-access-token' => $accessTokenValue]); option(['qb-refresh-token' => $refreshTokenValue]); + return true; } catch (Exception $e) { return false; } + } + + /** + * Get QuickBooksOnline\API\DataService\DataService object. + * @throws \QuickBooksOnline\API\Exception\SdkException + */ + protected static function getDataService(): DataService + { + return DataService::Configure([ + 'auth_mode' => config('quickbooks.data-service.auth-mode'), + 'ClientID' => config('quickbooks.data-service.client-id'), + 'ClientSecret' => config('quickbooks.data-service.client-secret'), + 'RedirectURI' => config('quickbooks.data-service.redirect-uri'), + 'scope' => config('quickbooks.data-service.scope'), + 'baseUrl' => config('quickbooks.data-service.base-url') + ]); + } + + /** + * Checks if the cookie is valid. + * @return bool + */ + protected static function cookieIsValid(): bool + { + $validCookie = explode('|', option('qb-auth')); + if ($validCookie[0] === Cookie::get('quickbooks_auth') && (int)$validCookie[1] > time()) { + return true; + } + return false; } } \ No newline at end of file diff --git a/src/Routes/routes.php b/src/Routes/routes.php deleted file mode 100644 index 1e665cc..0000000 --- a/src/Routes/routes.php +++ /dev/null @@ -1,11 +0,0 @@ -