browser_sniffer 1.1.3 → 1.3.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: fd1a593002b74a298902288af9c9ad850599246545788da8ec5282661ace4b72
4
- data.tar.gz: e51a161b66ef5e9f237e498fed82c101ee55dcfd85493a2003743cdbf305be43
3
+ metadata.gz: c1f122e65998d2712691f2b2dfefd9cbbdb7e824ad1a5a39bab483b4274bbac3
4
+ data.tar.gz: 002eb813a2e049806a5e409035aeb8f303c4dff4797e05461993d70e372f5c18
5
5
  SHA512:
6
- metadata.gz: dcce3cb34e52ffe1d43b5ee06f96d7093effce03cef846c709d7addc06555266edcd2f1b0d5b0879d5a5bae17e2f46d78cc64a939bc45e5a229f9575106f9011
7
- data.tar.gz: 4a2b2a8995d1e2b7cc6c9aa61bcbb839f63dae0963cd7513eb2ad88fae1755dc39713c730d8d74b0e51ec7a1257f5e4e87fde5a8bed88c87c9837e69f969c6fc
6
+ metadata.gz: 266ff5af2b669e477e088b0cf2caff845e7bacdbcc2abd7a6c4380921a9343e15604c2c4975260bf53cdccc0002de45b49563aef40e790c4fe46f1abc5e497b0
7
+ data.tar.gz: 9c9620bb162e584acc189d3a6e208d67470a0d16aeefd5b331f9250e5dc1eb444fc1243fef615bf242cde1a5ba4d89c9a124a0984e56119baf4c05831c545225
data/.travis.yml CHANGED
@@ -3,6 +3,10 @@ rvm:
3
3
  - 1.9
4
4
  - 2.0
5
5
  - 2.1
6
+ - 2.4
7
+ - 2.5
8
+ - 2.6
9
+ - truffleruby-19.2.0.1 # like 2.6.2
6
10
  - jruby
7
11
 
8
12
  before_install: gem update bundler
@@ -17,6 +17,8 @@ Gem::Specification.new do |spec|
17
17
 
18
18
  spec.required_ruby_version = ">= 1.9.3"
19
19
 
20
+ spec.metadata['allowed_push_host'] = 'https://rubygems.org'
21
+
20
22
  spec.add_development_dependency "bundler"
21
23
  spec.add_development_dependency "minitest"
22
24
  spec.add_development_dependency "rake"
@@ -73,8 +73,8 @@ class BrowserSniffer
73
73
  %r{.*(Shopify POS Next|Shopify POS)\/(?:iOS)\/([\d\.]+) \((iPhone|iPad|iPod)}i
74
74
  ], [[:name, 'Shopify POS'], :version], [
75
75
  # Shopify Mobile for Android
76
- %r{.*(Shopify Mobile)\/Android\/([\d\.]+(?: \(debug(?:|-push)\))?) \(Build (\d+) with API (\d+)}i
77
- ], [[:name, 'Shopify Mobile'], :version, :build, :sdk_version], [
76
+ %r{.*(Shopify Mobile)\/Android\/([\d\.]+)(?: \((debug(?:|-push))\))? \(Build (\d+) with API (\d+)}i
77
+ ], [[:name, 'Shopify Mobile'], :version, :debug_mode, :build, :sdk_version], [
78
78
  # ShopifyFoundation shared library
79
79
  /^(ShopifyFoundation)/i,
80
80
  ], [:name], [
@@ -332,7 +332,7 @@ class BrowserSniffer
332
332
  /(gnu)\s?([\w\.]+)*/i # GNU
333
333
  ], [:name, :version, [:type, :linux]], [
334
334
  /(cros)\s[\w]+\s([\w\.]+\w)/i # Chromium OS
335
- ], [[:name, 'Chromium OS'], :version],[
335
+ ], [[:name, 'Chromium OS'], :version, [:type, :chromium_os]],[
336
336
  # Solaris
337
337
  /(sunos)\s?([\w\.]+\d)*/i # Solaris
338
338
  ], [[:name, 'Solaris'], :version], [
@@ -1,3 +1,3 @@
1
1
  class BrowserSniffer
2
- VERSION = "1.1.3"
2
+ VERSION = "1.3.0"
3
3
  end
@@ -24,6 +24,15 @@ class BrowserSniffer
24
24
  browser == :ie && major_browser_version == 11
25
25
  end
26
26
 
27
+ # This method checks ie 11 mobile or ie11 rendering an older version in compatibility mode, in addition to `ie11?`.
28
+ # The `ie11?` method would return false in both those scenarios.
29
+ def ie11_actual?
30
+ ie11_engine = major_engine_version == 7 && engine_name == 'Trident'
31
+ ie_mobile11 = major_browser_version == 11 && browser_name == 'IEMobile'
32
+
33
+ ie11? || ie11_engine || ie_mobile11
34
+ end
35
+
27
36
  def handheld?
28
37
  form_factor == :handheld
29
38
  end
@@ -153,4 +162,42 @@ class BrowserSniffer
153
162
  end
154
163
  result
155
164
  end
165
+
166
+ def same_site_none_compatible?
167
+ return false unless user_agent
168
+
169
+ webkit_same_site_compatible? && same_site_recognized_browser?
170
+ end
171
+
172
+ def webkit_same_site_compatible?
173
+ return false unless os && os_version && browser
174
+
175
+ !(os == :ios && os_version.match(/^([0-9]|1[12])[\.\_]/)) &&
176
+ !(os == :mac && browser == :safari && os_version.match(/^10[\.\_]14/))
177
+ end
178
+
179
+ def same_site_recognized_browser?
180
+ return false unless major_browser_version
181
+
182
+ !(chromium_based? && major_browser_version >= 51 && major_browser_version <= 66) &&
183
+ !(uc_browser? && !uc_browser_version_at_least?(12, 13, 2))
184
+ end
185
+
186
+ def chromium_based?
187
+ browser_name ? browser_name.downcase.match(/chrom(e|ium)/) : false
188
+ end
189
+
190
+ def uc_browser?
191
+ user_agent ? user_agent.downcase.match(/uc\s?browser/) : false
192
+ end
193
+
194
+ def uc_browser_version_at_least?(major, minor, build)
195
+ return false unless browser_version
196
+ digits = browser_version.split('.').map(&:to_i)
197
+ return false unless digits.count >= 3
198
+
199
+ return digits[0] > major if digits[0] != major
200
+ return digits[1] > minor if digits[1] != minor
201
+ digits[2] >= build
202
+ end
156
203
  end
@@ -454,6 +454,7 @@ class BrowserSnifferTest < Minitest::Test
454
454
  :android? => false,
455
455
  :desktop? => true,
456
456
  :ie11? => false,
457
+ :ie11_actual? => false,
457
458
  :engine => nil,
458
459
  :major_engine_version => nil,
459
460
  :os => :mac,
@@ -467,6 +468,7 @@ class BrowserSnifferTest < Minitest::Test
467
468
  :form_factor => :desktop,
468
469
  :ios? => false,
469
470
  :ie11? => true,
471
+ :ie11_actual? => true,
470
472
  :android? => false,
471
473
  :desktop? => true,
472
474
  :engine => :trident,
@@ -481,6 +483,7 @@ class BrowserSnifferTest < Minitest::Test
481
483
  :form_factor => :desktop,
482
484
  :ios? => false,
483
485
  :ie11? => true,
486
+ :ie11_actual? => true,
484
487
  :android? => false,
485
488
  :desktop? => true,
486
489
  :engine => :trident,
@@ -495,6 +498,7 @@ class BrowserSnifferTest < Minitest::Test
495
498
  :form_factor => :desktop,
496
499
  :ios? => false,
497
500
  :ie11? => true,
501
+ :ie11_actual? => true,
498
502
  :android? => false,
499
503
  :desktop? => true,
500
504
  :engine => :trident,
@@ -509,6 +513,7 @@ class BrowserSnifferTest < Minitest::Test
509
513
  :form_factor => :desktop,
510
514
  :ios? => false,
511
515
  :ie11? => true,
516
+ :ie11_actual? => true,
512
517
  :android? => false,
513
518
  :desktop? => true,
514
519
  :engine => :trident,
@@ -523,6 +528,7 @@ class BrowserSnifferTest < Minitest::Test
523
528
  :form_factor => :desktop,
524
529
  :ios? => false,
525
530
  :ie11? => false,
531
+ :ie11_actual? => false,
526
532
  :android? => false,
527
533
  :desktop? => true,
528
534
  :engine => :webkit,
@@ -544,7 +550,52 @@ class BrowserSnifferTest < Minitest::Test
544
550
  :os_version => nil,
545
551
  :browser => nil,
546
552
  :major_browser_version => nil
547
- }
553
+ },
554
+ :chromiumos_chrome => {
555
+ :user_agent => "Mozilla/5.0 (X11; CrOS x86_64 10066.0.0) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/81.0.4044.122 Safari/537.36",
556
+ :form_factor => :desktop,
557
+ :ios? => false,
558
+ :android? => false,
559
+ :desktop? => true,
560
+ :engine => :webkit,
561
+ :major_engine_version => 537,
562
+ :os => :chromium_os,
563
+ :os_version => '10066.0.0',
564
+ :browser => :chrome,
565
+ :major_browser_version => 81,
566
+ },
567
+ :windows_phone_8_1_ie11 => {
568
+ :user_agent => "Mozilla/5.0 (Mobile; Windows Phone 8.1; Android 4.0; ARM; Trident/7.0; Touch; rv:11.0; IEMobile/11.0; Microsoft; " \
569
+ "Lumia 640 XL) like iPhone OS 7_0_3 Mac OS X AppleWebKit/537 (KHTML, like Gecko) Mobile Safari/537",
570
+ :form_factor => :handheld,
571
+ :ios? => false,
572
+ :ie11? => false,
573
+ :ie11_actual? => true,
574
+ :android? => false,
575
+ :desktop? => false,
576
+ :engine => :webkit,
577
+ :major_engine_version => 53,
578
+ :os => :windows,
579
+ :os_version => "8.1",
580
+ :browser => nil,
581
+ :major_browser_version => 11
582
+ },
583
+ :win10_ie11_in_ie7_compatibility_mode => {
584
+ :user_agent => "Mozilla/4.0 (compatible; MSIE 7.0; Windows NT 10.0; WOW64; Trident/7.0; .NET4.0C; .NET4.0E; .NET CLR 2.0.50727; " \
585
+ ".NET CLR 3.0.30729; .NET CLR 3.5.30729; InfoPath.3; Tablet PC 2.0; Zoom 3.6.0)",
586
+ :form_factor => :desktop,
587
+ :ios? => false,
588
+ :ie11? => false,
589
+ :ie11_actual? => true,
590
+ :android? => false,
591
+ :desktop? => true,
592
+ :engine => :trident,
593
+ :major_engine_version => 7,
594
+ :os => :windows,
595
+ :os_version => "10",
596
+ :browser => :ie,
597
+ :major_browser_version => 7
598
+ },
548
599
  }
549
600
 
550
601
  AGENTS.each do |agent, attributes|
@@ -155,6 +155,7 @@ describe "Shopify agents" do
155
155
  assert_equal ({
156
156
  name: 'Shopify Mobile',
157
157
  version: '5.4.4',
158
+ debug_mode: nil,
158
159
  build: '12005',
159
160
  sdk_version: '25',
160
161
  }), sniffer.browser_info
@@ -174,10 +175,11 @@ describe "Shopify agents" do
174
175
  "MobileMiddlewareSupported Mozilla/5.0 (Linux; Android 9; Android SDK built for x86 Build/PSR1.180720.075; wv) "\
175
176
  "AppleWebKit/537.36 (KHTML, like Gecko) Version/4.0 Chrome/69.0.3497.100 Mobile Safari/537.36"
176
177
  sniffer = BrowserSniffer.new(user_agent)
177
-
178
+
178
179
  assert_equal ({
179
180
  name: 'Shopify Mobile',
180
181
  version: '8.12.0',
182
+ debug_mode: nil,
181
183
  build: '12005',
182
184
  sdk_version: '28',
183
185
  }), sniffer.browser_info
@@ -203,7 +205,8 @@ describe "Shopify agents" do
203
205
 
204
206
  assert_equal ({
205
207
  name: 'Shopify Mobile',
206
- version: '6.2.0 (debug)',
208
+ version: '6.2.0',
209
+ debug_mode: 'debug',
207
210
  build: '1',
208
211
  sdk_version: '25',
209
212
  }), sniffer.browser_info
@@ -406,6 +409,77 @@ describe "Shopify agents" do
406
409
  }), sniffer.os_info
407
410
  end
408
411
 
412
+ it "Shopify POS via webview can be sniffed" do
413
+ user_agent = "Mozilla/5.0 (iPhone; CPU iPhone OS 12_0 like Mac OS X) "\
414
+ "AppleWebKit/ 604.1.21 (KHTML, like Gecko) Version/ 12.0 Mobile/17A6278a Safari/602.1.26 "\
415
+ "MobileMiddlewareSupported com.jadedpixel.pos Shopify POS/5.43.1 (iPad; iOS 13.1; Scale/2.00)"
416
+ sniffer = BrowserSniffer.new(user_agent)
417
+
418
+ assert_equal ({
419
+ name: 'Shopify POS',
420
+ version: '5.43.1',
421
+ }), sniffer.browser_info
422
+
423
+ assert_equal ({
424
+ type: :tablet,
425
+ scale: '2.00',
426
+ }), sniffer.device_info
427
+
428
+ assert_equal ({
429
+ type: :ios,
430
+ version: '13.1',
431
+ name: 'iOS',
432
+ }), sniffer.os_info
433
+ end
434
+
435
+ it "Shopify POS with modern user agent via webview can be sniffed" do
436
+ user_agent = "Mozilla/5.0 (iPhone; CPU iPhone OS 12_0 like Mac OS X) "\
437
+ "AppleWebKit/ 604.1.21 (KHTML, like Gecko) Version/ 12.0 Mobile/17A6278a "\
438
+ "Safari/602.1.26 MobileMiddlewareSupported Shopify POS/iOS/3.12.1 "\
439
+ "(iPad4,7/com.jadedpixel.pos/10.3.1) - Build 1"
440
+ sniffer = BrowserSniffer.new(user_agent)
441
+
442
+ assert_equal ({
443
+ name: 'Shopify POS',
444
+ version: '3.12.1',
445
+ }), sniffer.browser_info
446
+
447
+ assert_equal ({
448
+ type: :tablet,
449
+ model: '4,7',
450
+ }), sniffer.device_info
451
+
452
+ assert_equal ({
453
+ type: :ios,
454
+ name: 'iOS',
455
+ version: '10.3.1',
456
+ }), sniffer.os_info
457
+ end
458
+
459
+ it "Shopify POS Next with modern user agent via webview can be sniffed" do
460
+ user_agent = "Mozilla/5.0 (iPhone; CPU iPhone OS 12_0 like Mac OS X) "\
461
+ "AppleWebKit/ 604.1.21 (KHTML, like Gecko) Version/ 12.0 Mobile/17A6278a "\
462
+ "Safari/602.1.26 MobileMiddlewareSupported Shopify POS Next/iOS/3.12.1 "\
463
+ "(iPad4,7/com.jadedpixel.pos/10.3.1) - Build 1"
464
+ sniffer = BrowserSniffer.new(user_agent)
465
+
466
+ assert_equal ({
467
+ name: 'Shopify POS',
468
+ version: '3.12.1',
469
+ }), sniffer.browser_info
470
+
471
+ assert_equal ({
472
+ type: :tablet,
473
+ model: '4,7',
474
+ }), sniffer.device_info
475
+
476
+ assert_equal ({
477
+ type: :ios,
478
+ name: 'iOS',
479
+ version: '10.3.1',
480
+ }), sniffer.os_info
481
+ end
482
+
409
483
  it "Shopify POS with okhttp user agent can be parsed" do
410
484
  user_agent = "okhttp/3.6.0"
411
485
  sniffer = BrowserSniffer.new(user_agent)
@@ -486,7 +560,8 @@ describe "Shopify agents" do
486
560
 
487
561
  assert_equal ({
488
562
  name: 'Shopify Mobile',
489
- version: '6.0.0 (debug)',
563
+ version: '6.0.0',
564
+ debug_mode: 'debug',
490
565
  build: '1',
491
566
  sdk_version: '25',
492
567
  }), sniffer.browser_info
@@ -509,7 +584,8 @@ describe "Shopify agents" do
509
584
 
510
585
  assert_equal ({
511
586
  name: 'Shopify Mobile',
512
- version: '6.0.0 (debug-push)',
587
+ version: '6.0.0',
588
+ debug_mode: 'debug-push',
513
589
  build: '1',
514
590
  sdk_version: '25',
515
591
  }), sniffer.browser_info
@@ -603,4 +679,37 @@ describe "Shopify agents" do
603
679
  name: 'iOS',
604
680
  }), sniffer.os_info
605
681
  end
682
+
683
+ INCOMPATIBLE_USER_AGENTS = [
684
+ "Mozilla/5.0 (iPhone; CPU iPhone OS 12_0 like Mac OS X) AppleWebKit/605.1.15 (KHTML, like Gecko)"\
685
+ " GSA/87.0.279142407 Mobile/15E148 Safari/605.1",
686
+ "Mozilla/5.0 (Macintosh; Intel Mac OS X 10_14_6) AppleWebKit/605.1.15 (KHTML, like Gecko)"\
687
+ " Version/12.1.2 Safari/605.1.15",
688
+ "Mozilla/5.0 (Linux; U; Android 7.0; en-US; SM-G935F Build/NRD90M) AppleWebKit/534.30 (KHTML, like Gecko) "\
689
+ "Version/4.0 UCBrowser/11.3.8.976 U3/0.8.0 Mobile Safari/534.30",
690
+ ]
691
+
692
+ INCOMPATIBLE_USER_AGENTS.each do |user_agent|
693
+ it "user agent #{user_agent} is correctly marked as incompatible" do
694
+ sniffer = BrowserSniffer.new(user_agent)
695
+
696
+ refute sniffer.same_site_none_compatible?
697
+ end
698
+ end
699
+
700
+ COMPATIBLE_USER_AGENTS = [
701
+ "Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_2) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/79.0.3945.117"\
702
+ " Safari/537.36",
703
+ "Mozilla/5.0 (Macintosh; Intel Mac OS X 10.15; rv:72.0) Gecko/20100101 Firefox/72.0",
704
+ "Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_2) AppleWebKit/605.1.15 (KHTML, like Gecko) Version/13.0.4"\
705
+ " Safari/605.1.15",
706
+ ]
707
+
708
+ COMPATIBLE_USER_AGENTS.each do |user_agent|
709
+ it "user agent #{user_agent} is correctly marked as compatible" do
710
+ sniffer = BrowserSniffer.new(user_agent)
711
+
712
+ assert sniffer.same_site_none_compatible?
713
+ end
714
+ end
606
715
  end
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: browser_sniffer
3
3
  version: !ruby/object:Gem::Version
4
- version: 1.1.3
4
+ version: 1.3.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - Shopify
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2019-05-06 00:00:00.000000000 Z
11
+ date: 2021-10-21 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: bundler
@@ -79,7 +79,8 @@ homepage: https://github.com/Shopify/browser_sniffer
79
79
  licenses:
80
80
  - GPLv2
81
81
  - MIT
82
- metadata: {}
82
+ metadata:
83
+ allowed_push_host: https://rubygems.org
83
84
  post_install_message:
84
85
  rdoc_options: []
85
86
  require_paths:
@@ -95,8 +96,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
95
96
  - !ruby/object:Gem::Version
96
97
  version: '0'
97
98
  requirements: []
98
- rubyforge_project:
99
- rubygems_version: 2.7.6
99
+ rubygems_version: 3.2.20
100
100
  signing_key:
101
101
  specification_version: 4
102
102
  summary: Parses user agent strings and boils it all down to a few simple classifications.