Class: ShopifyApp::SameSiteCookieMiddleware

Inherits:
Object
  • Object
show all
Defined in:
lib/shopify_app/middleware/same_site_cookie_middleware.rb

Class Method Summary collapse

Instance Method Summary collapse

Constructor Details

#initialize(app) ⇒ SameSiteCookieMiddleware

Returns a new instance of SameSiteCookieMiddleware.



3
4
5
# File 'lib/shopify_app/middleware/same_site_cookie_middleware.rb', line 3

def initialize(app)
  @app = app
end

Class Method Details

.chromium_based?(sniffer) ⇒ Boolean

Returns:

  • (Boolean)


43
44
45
# File 'lib/shopify_app/middleware/same_site_cookie_middleware.rb', line 43

def self.chromium_based?(sniffer)
  sniffer.browser_name.downcase.match?(/chrom(e|ium)/)
end

.drops_unrecognized_same_site_cookies?(sniffer) ⇒ Boolean

Returns:

  • (Boolean)


38
39
40
41
# File 'lib/shopify_app/middleware/same_site_cookie_middleware.rb', line 38

def self.drops_unrecognized_same_site_cookies?(sniffer)
  (chromium_based?(sniffer) && sniffer.major_browser_version >= 51 && sniffer.major_browser_version <= 66) ||
    (uc_browser?(sniffer) && !uc_browser_version_at_least?(sniffer: sniffer, major: 12, minor: 13, build: 2))
end

.same_site_none_incompatible?(user_agent) ⇒ Boolean

Returns:

  • (Boolean)


25
26
27
28
29
30
31
# File 'lib/shopify_app/middleware/same_site_cookie_middleware.rb', line 25

def self.same_site_none_incompatible?(user_agent)
  sniffer = BrowserSniffer.new(user_agent)

  webkit_same_site_bug?(sniffer) || drops_unrecognized_same_site_cookies?(sniffer)
rescue
  true
end

.uc_browser?(sniffer) ⇒ Boolean

Returns:

  • (Boolean)


47
48
49
# File 'lib/shopify_app/middleware/same_site_cookie_middleware.rb', line 47

def self.uc_browser?(sniffer)
  sniffer.user_agent.downcase.match?(/uc\s?browser/)
end

.uc_browser_version_at_least?(sniffer:, major:, minor:, build:) ⇒ Boolean

Returns:

  • (Boolean)


51
52
53
54
55
56
57
58
# File 'lib/shopify_app/middleware/same_site_cookie_middleware.rb', line 51

def self.uc_browser_version_at_least?(sniffer:, major:, minor:, build:)
  digits = sniffer.browser_version.split('.').map(&:to_i)
  return false unless digits.count >= 3

  return digits[0] > major if digits[0] != major
  return digits[1] > minor if digits[1] != minor
  digits[2] >= build
end

.webkit_same_site_bug?(sniffer) ⇒ Boolean

Returns:

  • (Boolean)


33
34
35
36
# File 'lib/shopify_app/middleware/same_site_cookie_middleware.rb', line 33

def self.webkit_same_site_bug?(sniffer)
  (sniffer.os == :ios && sniffer.os_version.match?(/^([0-9]|1[12])[\.\_]/)) ||
    (sniffer.os == :mac && sniffer.browser == :safari && sniffer.os_version.match?(/^10[\.\_]14/))
end

Instance Method Details

#call(env) ⇒ Object



7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
# File 'lib/shopify_app/middleware/same_site_cookie_middleware.rb', line 7

def call(env)
  _status, headers, _body = @app.call(env)
ensure
  user_agent = env['HTTP_USER_AGENT']

  if headers && headers['Set-Cookie'] && !SameSiteCookieMiddleware.same_site_none_incompatible?(user_agent) &&
      ShopifyApp.configuration.enable_same_site_none

    cookies = headers['Set-Cookie'].split("\n").compact

    cookies.each do |cookie|
      unless cookie.include?("; SameSite")
        headers['Set-Cookie'] = headers['Set-Cookie'].gsub("#{cookie}", "#{cookie}; secure; SameSite=None")
      end
    end
  end
end