Skip to content

Commit b26b52d

Browse files
Tyler KingclydesantiagoClyde Dexter Santiagosquatto
authored
Merge 16.0.4 and 16.0.5 (gnikyt#733)
* Fix to webhook stub to adjust 'domain' to 'shopDomain' * Fix high usage of memory during installation (gnikyt#705) Co-authored-by: Clyde Dexter Santiago <clydesantiago@MacBook-Pro-M1.local> * Updated CONTRIBUTORS.txt * bugfix/593 (gnikyt#732) * Fix for issue gnikyt#742 * AuthShopify middleware: moved implode of data sources to own function * AuthShopify middleware: implode of data sources now handles array and nested arrays * SyleCI fix * Ignore data if no HMAC in AuthShopify middleware * Use named routes (gnikyt#730) * Updated CONTRIBUTORS.txt * StyleCI fixes Co-authored-by: Clyde Dexter Santiago <31274021+clydesantiago@users.noreply.github.com> Co-authored-by: Clyde Dexter Santiago <clydesantiago@MacBook-Pro-M1.local> Co-authored-by: Scott Carpenter <scott@payforstay.com>
1 parent 17471ef commit b26b52d

File tree

6 files changed

+122
-66
lines changed

6 files changed

+122
-66
lines changed

CONTRIBUTORS.txt

Lines changed: 27 additions & 26 deletions
Original file line numberDiff line numberDiff line change
@@ -1,36 +1,37 @@
1-
# [...document.getElementsByClassName('contrib-person')].map(n => n.getElementsByClassName('avatar')[0].alt).join('\n');
2-
osiset
3-
darrynten
1+
# [...document.getElementsByClassName('contrib-person')].map(n => n.getElementsByClassName('avatar')[0].alt).sort().join('\n');
2+
Enmaboya
3+
ImgBotApp
4+
Jamesking56
5+
aaronlp
6+
aepnat
47
amosmos
5-
lucasmichot
6-
jedimdan
7-
ilamp
8+
andrewscofield
89
awebartisan
10+
azhar25git
11+
baorv
912
bilfeldt
10-
oanhnn
11-
tuimz
12-
aepnat
13-
seka19
14-
msonowal
15-
mtownsend5512
16-
ncpope
17-
niveshsaharan
13+
bravemaster619
1814
c4l3b
15+
clydesantiago
16+
darrynten
1917
dellow
20-
ericnkatz
21-
savchukoleksii
22-
ImgBotApp
2318
dhritimannath
19+
ericnkatz
2420
florinsith
25-
aaronlp
26-
squatto
27-
bravemaster619
2821
honzah1
29-
azhar25git
22+
ilamp
23+
jedimdan
3024
joelvh
31-
Jamesking56
32-
baorv
33-
Enmaboya
34-
andrewscofield
25+
lucasmichot
26+
mat-dropshipspy
27+
msonowal
28+
mtownsend5512
29+
ncpope
30+
niveshsaharan
31+
oanhnn
32+
osiset
3533
parkourben99
36-
mat-dropshipsp
34+
savchukoleksii
35+
seka19
36+
squatto
37+
tuimz

src/ShopifyApp/Console/stubs/webhook-job.stub

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -48,7 +48,7 @@ class DummyClass implements ShouldQueue
4848
public function handle()
4949
{
5050
// Convert domain
51-
$this->shopDomain = ShopDomain::fromNative($this->domain);
51+
$this->shopDomain = ShopDomain::fromNative($this->shopDomain);
5252

5353
// Do what you wish with the data
5454
// Access domain name as $this->shopDomain->toNative()

src/ShopifyApp/Http/Middleware/AuthShopify.php

Lines changed: 79 additions & 32 deletions
Original file line numberDiff line numberDiff line change
@@ -5,8 +5,6 @@
55
use Closure;
66
use Illuminate\Http\RedirectResponse;
77
use Illuminate\Http\Request;
8-
use Illuminate\Support\Facades\Auth;
9-
use Illuminate\Support\Facades\Log;
108
use Illuminate\Support\Facades\Redirect;
119
use Illuminate\Support\Facades\Session;
1210
use Osiset\ShopifyApp\Contracts\ApiHelper as IApiHelper;
@@ -68,7 +66,7 @@ public function __construct(IApiHelper $apiHelper, ShopSession $shopSession)
6866
public function handle(Request $request, Closure $next)
6967
{
7068
// Grab the domain and check the HMAC (if present)
71-
$domain = $this->getShopDomainFromData($request);
69+
$domain = $this->getShopDomainFromRequest($request);
7270
$hmac = $this->verifyHmac($request);
7371

7472
$checks = [];
@@ -230,6 +228,51 @@ private function getHmac(Request $request): ?array
230228
return null;
231229
}
232230

231+
/**
232+
* Grab the shop, if present, and how it was found.
233+
* Order of precedence is:.
234+
*
235+
* - GET/POST Variable
236+
* - Headers
237+
* - Referer
238+
*
239+
* @param Request $request The request object.
240+
*
241+
* @return ShopDomainValue
242+
*/
243+
private function getShopDomainFromRequest(Request $request): ShopDomainValue
244+
{
245+
// All possible methods
246+
$options = [
247+
// GET/POST
248+
DataSource::INPUT()->toNative() => $request->input('shop'),
249+
// Headers
250+
DataSource::HEADER()->toNative() => $request->header('X-Shop-Domain'),
251+
// Headers: Referer
252+
DataSource::REFERER()->toNative() => function () use ($request): ?string {
253+
$url = parse_url($request->header('referer'), PHP_URL_QUERY);
254+
parse_str($url, $refererQueryParams);
255+
if (! $refererQueryParams || ! isset($refererQueryParams['shop'])) {
256+
return null;
257+
}
258+
259+
return $refererQueryParams['shop'];
260+
},
261+
];
262+
263+
// Loop through each until we find the HMAC
264+
foreach ($options as $method => $value) {
265+
$result = is_callable($value) ? $value() : $value;
266+
if ($result !== null) {
267+
// Found a shop
268+
return ShopDomain::fromNative($result);
269+
}
270+
}
271+
272+
// No shop domain found in any source
273+
return NullShopDomain::fromNative(null);
274+
}
275+
233276
/**
234277
* Grab the data.
235278
*
@@ -247,7 +290,7 @@ private function getData(Request $request, string $source): array
247290
// Verify
248291
$verify = [];
249292
foreach ($request->query() as $key => $value) {
250-
$verify[$key] = is_array($value) ? '["'.implode('", "', $value).'"]' : $value;
293+
$verify[$key] = $this->parseDataSourceValue($value);
251294
}
252295

253296
return $verify;
@@ -274,7 +317,7 @@ private function getData(Request $request, string $source): array
274317

275318
foreach (compact('code', 'locale', 'state', 'id', 'ids') as $key => $value) {
276319
if ($value) {
277-
$verify[$key] = is_array($value) ? '["'.implode('", "', $value).'"]' : $value;
320+
$verify[$key] = $this->parseDataSourceValue($value);
278321
}
279322
}
280323

@@ -288,7 +331,7 @@ private function getData(Request $request, string $source): array
288331
// Verify
289332
$verify = [];
290333
foreach ($refererQueryParams as $key => $value) {
291-
$verify[$key] = is_array($value) ? '["'.implode('", "', $value).'"]' : $value;
334+
$verify[$key] = $this->parseDataSourceValue($value);
292335
}
293336

294337
return $verify;
@@ -298,32 +341,6 @@ private function getData(Request $request, string $source): array
298341
return $options[$source]();
299342
}
300343

301-
/**
302-
* Gets the shop domain from the data.
303-
*
304-
* @param Request $request The request object.
305-
*
306-
* @return ShopDomainValue
307-
*/
308-
private function getShopDomainFromData(Request $request): ShopDomainValue
309-
{
310-
$options = [
311-
DataSource::INPUT()->toNative(),
312-
DataSource::HEADER()->toNative(),
313-
DataSource::REFERER()->toNative(),
314-
];
315-
foreach ($options as $option) {
316-
$result = $this->getData($request, $option);
317-
if (isset($result['shop'])) {
318-
// Found a shop
319-
return ShopDomain::fromNative($result['shop']);
320-
}
321-
}
322-
323-
// No shop domain found in any source
324-
return NullShopDomain::fromNative(null);
325-
}
326-
327344
/**
328345
* Handle bad verification by killing the session and redirecting to auth.
329346
*
@@ -353,4 +370,34 @@ private function handleBadVerification(Request $request, ShopDomainValue $domain
353370
['shop' => $domain->toNative()]
354371
);
355372
}
373+
374+
/**
375+
* Parse the data source value.
376+
* Handle simple key/values, arrays, and nested arrays.
377+
*
378+
* @param mixed $value
379+
*
380+
* @return string
381+
*/
382+
private function parseDataSourceValue($value): string
383+
{
384+
/**
385+
* Format the value.
386+
*
387+
* @param mixed $val
388+
*
389+
* @return string
390+
*/
391+
$formatValue = function ($val): string {
392+
return is_array($val) ? '["'.implode('", "', $val).'"]' : $val;
393+
};
394+
395+
// Nested array
396+
if (is_array($value) && is_array(current($value))) {
397+
return implode(', ', array_map($formatValue, $value));
398+
}
399+
400+
// Array or basic value
401+
return $formatValue($value);
402+
}
356403
}

src/ShopifyApp/Http/Middleware/ITP.php

Lines changed: 11 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -6,12 +6,12 @@
66
use Illuminate\Http\RedirectResponse;
77
use Illuminate\Http\Request;
88
use Illuminate\Http\Response as HttpResponse;
9-
use Illuminate\Support\Arr;
109
use Illuminate\Support\Facades\Redirect;
1110
use Illuminate\Support\Facades\Response;
1211
use Illuminate\Support\Facades\URL;
1312
use Illuminate\Support\Facades\View;
1413
use Illuminate\Support\Str;
14+
use function Osiset\ShopifyApp\getShopifyConfig;
1515

1616
/**
1717
* Ensuring ITP process.
@@ -56,11 +56,19 @@ public function handle(Request $request, Closure $next)
5656
*/
5757
protected function redirect(Request $request): HttpResponse
5858
{
59+
$authUrl = URL::secure(
60+
URL::route(
61+
getShopifyConfig('route_names.itp'),
62+
['shop' => $request->get('shop')],
63+
false
64+
)
65+
);
66+
5967
return Response::make(
6068
View::make(
6169
'shopify-app::auth.fullpage_redirect',
6270
[
63-
'authUrl' => URL::secure('itp').'?'.Arr::query(['shop' => $request->get('shop')]),
71+
'authUrl' => $authUrl,
6472
'shopDomain' => $request->get('shop'),
6573
]
6674
)
@@ -74,6 +82,6 @@ protected function redirect(Request $request): HttpResponse
7482
*/
7583
protected function ask(): RedirectResponse
7684
{
77-
return Redirect::route('itp.ask');
85+
return Redirect::route(getShopifyConfig('route_names.itp.ask'));
7886
}
7987
}

src/ShopifyApp/Storage/Queries/Shop.php

Lines changed: 0 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -42,7 +42,6 @@ public function getByID(ShopIdValue $shopId, array $with = [], bool $withTrashed
4242
}
4343

4444
return $result
45-
->get()
4645
->where('id', $shopId->toNative())
4746
->first();
4847
}
@@ -58,7 +57,6 @@ public function getByDomain(ShopDomainValue $domain, array $with = [], bool $wit
5857
}
5958

6059
return $result
61-
->get()
6260
->where('name', $domain->toNative())
6361
->first();
6462
}

src/ShopifyApp/Traits/ItpController.php

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -3,11 +3,13 @@
33
namespace Osiset\ShopifyApp\Traits;
44

55
use Illuminate\Contracts\View\View as ViewView;
6+
use Illuminate\Http\RedirectResponse;
67
use Illuminate\Http\Request;
78
use Illuminate\Support\Facades\Cookie;
89
use Illuminate\Support\Facades\Redirect;
910
use Illuminate\Support\Facades\URL;
1011
use Illuminate\Support\Facades\View;
12+
use function Osiset\ShopifyApp\getShopifyConfig;
1113

1214
/**
1315
* Responsible for handling ITP issues.
@@ -27,7 +29,7 @@ public function attempt(Request $request)
2729
// Create samesite cookie
2830
Cookie::queue('itp', true, 6000, null, null, true, true, false, 'none');
2931

30-
return Redirect::route('home', [
32+
return Redirect::route(getShopifyConfig('route_names.home'), [
3133
'shop' => $request->query('shop'),
3234
'itp' => true,
3335
]);
@@ -42,7 +44,7 @@ public function attempt(Request $request)
4244
public function ask(): ViewView
4345
{
4446
return View::make('shopify-app::itp.ask', [
45-
'redirect' => URL::route('home'),
47+
'redirect' => URL::route(getShopifyConfig('route_names.home')),
4648
]);
4749
}
4850
}

0 commit comments

Comments
 (0)