5
5
use Closure ;
6
6
use Illuminate \Http \RedirectResponse ;
7
7
use Illuminate \Http \Request ;
8
- use Illuminate \Support \Facades \Auth ;
9
- use Illuminate \Support \Facades \Log ;
10
8
use Illuminate \Support \Facades \Redirect ;
11
9
use Illuminate \Support \Facades \Session ;
12
10
use Osiset \ShopifyApp \Contracts \ApiHelper as IApiHelper ;
@@ -68,7 +66,7 @@ public function __construct(IApiHelper $apiHelper, ShopSession $shopSession)
68
66
public function handle (Request $ request , Closure $ next )
69
67
{
70
68
// Grab the domain and check the HMAC (if present)
71
- $ domain = $ this ->getShopDomainFromData ($ request );
69
+ $ domain = $ this ->getShopDomainFromRequest ($ request );
72
70
$ hmac = $ this ->verifyHmac ($ request );
73
71
74
72
$ checks = [];
@@ -230,6 +228,51 @@ private function getHmac(Request $request): ?array
230
228
return null ;
231
229
}
232
230
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
+
233
276
/**
234
277
* Grab the data.
235
278
*
@@ -247,7 +290,7 @@ private function getData(Request $request, string $source): array
247
290
// Verify
248
291
$ verify = [];
249
292
foreach ($ request ->query () as $ key => $ value ) {
250
- $ verify [$ key ] = is_array ( $ value ) ? ' [" ' . implode ( ' ", " ' , $ value ). ' "] ' : $ value ;
293
+ $ verify [$ key ] = $ this -> parseDataSourceValue ( $ value );
251
294
}
252
295
253
296
return $ verify ;
@@ -274,7 +317,7 @@ private function getData(Request $request, string $source): array
274
317
275
318
foreach (compact ('code ' , 'locale ' , 'state ' , 'id ' , 'ids ' ) as $ key => $ value ) {
276
319
if ($ value ) {
277
- $ verify [$ key ] = is_array ( $ value ) ? ' [" ' . implode ( ' ", " ' , $ value ). ' "] ' : $ value ;
320
+ $ verify [$ key ] = $ this -> parseDataSourceValue ( $ value );
278
321
}
279
322
}
280
323
@@ -288,7 +331,7 @@ private function getData(Request $request, string $source): array
288
331
// Verify
289
332
$ verify = [];
290
333
foreach ($ refererQueryParams as $ key => $ value ) {
291
- $ verify [$ key ] = is_array ( $ value ) ? ' [" ' . implode ( ' ", " ' , $ value ). ' "] ' : $ value ;
334
+ $ verify [$ key ] = $ this -> parseDataSourceValue ( $ value );
292
335
}
293
336
294
337
return $ verify ;
@@ -298,32 +341,6 @@ private function getData(Request $request, string $source): array
298
341
return $ options [$ source ]();
299
342
}
300
343
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
-
327
344
/**
328
345
* Handle bad verification by killing the session and redirecting to auth.
329
346
*
@@ -353,4 +370,34 @@ private function handleBadVerification(Request $request, ShopDomainValue $domain
353
370
['shop ' => $ domain ->toNative ()]
354
371
);
355
372
}
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
+ }
356
403
}
0 commit comments