/
EnsureShopifySession.php
103 lines (90 loc) · 3.44 KB
/
EnsureShopifySession.php
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
<?php
namespace App\Http\Middleware;
use App\Exceptions\ShopifyBillingException;
use App\Lib\AuthRedirection;
use App\Lib\EnsureBilling;
use App\Lib\TopLevelRedirection;
use Closure;
use Exception;
use Illuminate\Http\Request;
use Illuminate\Support\Facades\Config;
use Shopify\Clients\Graphql;
use Shopify\Context;
use Shopify\Utils;
class EnsureShopifySession
{
public const ACCESS_MODE_ONLINE = 'online';
public const ACCESS_MODE_OFFLINE = 'offline';
public const TEST_GRAPHQL_QUERY = <<<QUERY
{
shop {
name
}
}
QUERY;
/**
* Checks if there is currently an active Shopify session.
*
* @param \Illuminate\Http\Request $request
* @param \Closure $next
* @param string $accessMode
* @return mixed
*/
public function handle(Request $request, Closure $next, string $accessMode = self::ACCESS_MODE_OFFLINE)
{
switch ($accessMode) {
case self::ACCESS_MODE_ONLINE:
$isOnline = true;
break;
case self::ACCESS_MODE_OFFLINE:
$isOnline = false;
break;
default:
throw new Exception(
"Unrecognized access mode '$accessMode', accepted values are 'online' and 'offline'"
);
}
$shop = Utils::sanitizeShopDomain($request->query('shop', ''));
$session = Utils::loadCurrentSession($request->header(), $request->cookie(), $isOnline);
if ($session && $shop && $session->getShop() !== $shop) {
// This request is for a different shop. Go straight to login
return AuthRedirection::redirect($request);
}
if ($session && $session->isValid()) {
if (Config::get('shopify.billing.required')) {
// The request to check billing status serves to validate that the access token is still valid.
try {
list($hasPayment, $confirmationUrl) =
EnsureBilling::check($session, Config::get('shopify.billing'));
$proceed = true;
if (!$hasPayment) {
return TopLevelRedirection::redirect($request, $confirmationUrl);
}
} catch (ShopifyBillingException $e) {
$proceed = false;
}
} else {
// Make a request to ensure the access token is still valid. Otherwise, re-authenticate the user.
$client = new Graphql($session->getShop(), $session->getAccessToken());
$response = $client->query(self::TEST_GRAPHQL_QUERY);
$proceed = $response->getStatusCode() === 200;
}
if ($proceed) {
$request->attributes->set('shopifySession', $session);
return $next($request);
}
}
$bearerPresent = preg_match("/Bearer (.*)/", $request->header('Authorization', ''), $bearerMatches);
if (!$shop) {
if ($session) {
$shop = $session->getShop();
} elseif (Context::$IS_EMBEDDED_APP) {
if ($bearerPresent !== false) {
$payload = Utils::decodeSessionToken($bearerMatches[1]);
$shop = parse_url($payload['dest'], PHP_URL_HOST);
}
}
}
return TopLevelRedirection::redirect($request, "/api/auth?shop=$shop");
}
}