Determine device names with device_detector
Replace the hand-rolled user-agent regexes with the device_detector gem. Its UA database recognises many more clients (and, e.g., GNOME Web when its UA carries the Epiphany token). WebKit "Safari" user agents on Linux (WebKitGTK, which GNOME Web sends) are labelled "WebKit on Linux", since Safari never runs on Linux. Part of #254
This commit is contained in:
4 files changed
+32
-19
No files matched your search
@@ -43,6 +43,7 @@ gem 'flipper-ui'
|
||||
gem 'gpgme', '~> 2.0.24'
|
||||
gem 'zbase32', '~> 0.1.1'
|
||||
gem 'kramdown'
|
||||
gem 'device_detector'
|
||||
|
||||
# HTTP requests
|
||||
gem 'faraday'
|
||||
|
||||
@@ -136,6 +136,7 @@ GEM
|
||||
database_cleaner-core (~> 2.0.0)
|
||||
database_cleaner-core (2.0.1)
|
||||
date (3.5.1)
|
||||
device_detector (1.1.3)
|
||||
devise (5.0.4)
|
||||
bcrypt (~> 3.0)
|
||||
orm_adapter (~> 0.1)
|
||||
@@ -543,6 +544,7 @@ DEPENDENCIES
|
||||
capybara
|
||||
cssbundling-rails
|
||||
database_cleaner
|
||||
device_detector
|
||||
devise (~> 5.0)
|
||||
devise_ldap_authenticatable
|
||||
discourse_api
|
||||
|
||||
@@ -47,25 +47,17 @@ class RemoteStorageAuthorization < ApplicationRecord
|
||||
def device_name
|
||||
return nil if user_agent.blank?
|
||||
|
||||
browser =
|
||||
case user_agent
|
||||
when /Firefox/ then "Firefox"
|
||||
when /Edg\// then "Edge"
|
||||
when /Chrome/ then "Chrome"
|
||||
when /Safari/ then "Safari"
|
||||
else "Unknown browser"
|
||||
end
|
||||
client = DeviceDetector.new(user_agent)
|
||||
name = client.name.presence
|
||||
os = client.os_name.presence
|
||||
os = "Linux" if os == "GNU/Linux"
|
||||
os = "macOS" if os == "Mac"
|
||||
|
||||
os =
|
||||
case user_agent
|
||||
when /Android/ then "Android"
|
||||
when /iPhone|iPad|iPod/ then "iOS"
|
||||
when /Mac OS X/ then "macOS"
|
||||
when /Windows/ then "Windows"
|
||||
when /Linux/ then "Linux"
|
||||
end
|
||||
# Safari never runs on Linux. A WebKit "Safari" user agent on Linux is a
|
||||
# WebKitGTK browser (e.g. GNOME Web), which sends a Safari-compatible UA.
|
||||
name = "WebKit" if name == "Safari" && os == "Linux"
|
||||
|
||||
os ? "#{browser} on #{os}" : browser
|
||||
[name, os].compact.join(" on ").presence
|
||||
end
|
||||
|
||||
def delete_token_from_redis
|
||||
|
||||
@@ -344,10 +344,28 @@ RSpec.describe RemoteStorageAuthorization, type: :model do
|
||||
expect(auth_with_user_agent(ua).device_name).to eq("Chrome on macOS")
|
||||
end
|
||||
|
||||
it "recognizes Safari on iOS" do
|
||||
it "recognizes Mobile Safari on iOS" do
|
||||
ua = "Mozilla/5.0 (iPhone; CPU iPhone OS 17_1 like Mac OS X) " \
|
||||
"AppleWebKit/605.1.15 (KHTML, like Gecko) Version/17.1 Mobile/15E148 Safari/604.1"
|
||||
expect(auth_with_user_agent(ua).device_name).to eq("Safari on iOS")
|
||||
expect(auth_with_user_agent(ua).device_name).to eq("Mobile Safari on iOS")
|
||||
end
|
||||
|
||||
it "recognizes GNOME Web on Linux (Epiphany's Safari-like user agent)" do
|
||||
ua = "Mozilla/5.0 (X11; Linux x86_64) AppleWebKit/605.1.15 (KHTML, like Gecko) " \
|
||||
"Version/16.0 Safari/605.1.15 Epiphany/45.0"
|
||||
expect(auth_with_user_agent(ua).device_name).to eq("GNOME Web on Linux")
|
||||
end
|
||||
|
||||
it "treats a WebKit Safari user agent on Linux as WebKit (WebKitGTK)" do
|
||||
ua = "Mozilla/5.0 (X11; Linux x86_64) AppleWebKit/605.1.15 (KHTML, like Gecko) " \
|
||||
"Version/60.5 Safari/605.1.15"
|
||||
expect(auth_with_user_agent(ua).device_name).to eq("WebKit on Linux")
|
||||
end
|
||||
|
||||
it "keeps Safari on macOS as Safari" do
|
||||
ua = "Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_7) AppleWebKit/605.1.15 " \
|
||||
"(KHTML, like Gecko) Version/17.1 Safari/605.1.15"
|
||||
expect(auth_with_user_agent(ua).device_name).to eq("Safari on macOS")
|
||||
end
|
||||
|
||||
it "falls back to the browser when the OS is unknown" do
|
||||
|
||||
Reference in new issue
Block a user