Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Include browser version in parsed user agent (PSG-761) #6788

Merged
merged 7 commits into from
Oct 4, 2022
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions Riot/Assets/en.lproj/Vector.strings
Original file line number Diff line number Diff line change
Expand Up @@ -2408,6 +2408,7 @@ To enable access, tap Settings> Location and select Always";
"user_session_details_device_ip_address" = "IP address";
"user_session_details_device_ip_location" = "IP location";
"user_session_details_device_model" = "Model";
"user_session_details_device_browser" = "Browser";
"user_session_details_device_os" = "Operating System";
"user_session_details_application_name" = "Name";
"user_session_details_application_version" = "Version";
Expand Down
4 changes: 4 additions & 0 deletions Riot/Generated/Strings.swift
Original file line number Diff line number Diff line change
Expand Up @@ -8495,6 +8495,10 @@ public class VectorL10n: NSObject {
public static var userSessionDetailsApplicationVersion: String {
return VectorL10n.tr("Vector", "user_session_details_application_version")
}
/// Browser
public static var userSessionDetailsDeviceBrowser: String {
return VectorL10n.tr("Vector", "user_session_details_device_browser")
}
/// IP address
public static var userSessionDetailsDeviceIpAddress: String {
return VectorL10n.tr("Vector", "user_session_details_device_ip_address")
Expand Down
48 changes: 34 additions & 14 deletions RiotSwiftUI/Modules/UserSessions/Common/UserAgentParser.swift
Original file line number Diff line number Diff line change
Expand Up @@ -125,18 +125,28 @@ enum UserAgentParser {
// Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_7) AppleWebKit/537.36 (KHTML, like Gecko) ElementNightly/2022091301 Chrome/104.0.5112.102 Electron/20.1.1 Safari/537.36
private static func parseDesktop(_ userAgent: String) -> UserAgent {
var deviceOS: String?
let browserName = browserName(for: userAgent)
let browserInfo = browserInfo(for: userAgent)

if let deviceInfo = findFirstDeviceInfo(in: userAgent) {
let deviceInfoComponents = deviceInfo.components(separatedBy: "; ")
deviceOS = deviceInfoComponents[safe: 1]?.hasPrefix("Android") == true ? deviceInfoComponents[safe: 1] : deviceInfoComponents.first
if deviceInfoComponents[safe: 1]?.hasPrefix("Android") == true {
deviceOS = deviceInfoComponents[safe: 1]
} else if deviceInfoComponents.first == "Macintosh" {
var osFull = deviceInfoComponents[safe: 1]
osFull = osFull?.replacingOccurrences(of: "Intel ", with: "")
osFull = osFull?.replacingOccurrences(of: "Mac OS X", with: "macOS")
osFull = osFull?.replacingOccurrences(of: "_", with: ".")
deviceOS = osFull
} else {
deviceOS = deviceInfoComponents.first
}
}

return UserAgent(deviceType: .desktop,
deviceModel: browserName,
deviceModel: nil,
deviceOS: deviceOS,
clientName: nil,
clientVersion: nil)
clientName: browserInfo.name,
clientVersion: browserInfo.version)
}

// Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_7) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/105.0.0.0 Safari/537.36
Expand Down Expand Up @@ -164,20 +174,30 @@ enum UserAgentParser {
return nil
}

private static func browserName(for userAgent: String) -> String? {
private static func browserInfo(for userAgent: String) -> (name: String?, version: String?) {
let components = userAgent.components(separatedBy: " ")
if components.last?.hasPrefix("Firefox") == true {
return "Firefox"
} else if components.last?.hasPrefix("Safari") == true
&& components[safe:components.count - 2]?.hasPrefix("Mobile") == true {
let version = components.last?.components(separatedBy: "/").last
return ("Firefox", version)
} else if components.last?.hasPrefix("Safari") == true,
components[safe: components.count - 2]?.hasPrefix("Mobile") == true {
// mobile browser
let possibleBrowserName = components[safe:components.count - 3]?.components(separatedBy: "/").first
return possibleBrowserName == "Version" ? "Safari" : possibleBrowserName
} else if components.last?.hasPrefix("Safari") == true && components[safe:components.count - 2]?.hasPrefix("Version") == true {
return "Safari"
let possibleBrowserComponents = components[safe: components.count - 3]
if possibleBrowserComponents?.hasPrefix("Version") == true {
let version = possibleBrowserComponents?.components(separatedBy: "/").last
return ("Safari", version)
} else {
let components = possibleBrowserComponents?.components(separatedBy: "/")
return (components?.first, components?.last)
}
} else if components.last?.hasPrefix("Safari") == true, components[safe: components.count - 2]?.hasPrefix("Version") == true {
let version = components[safe: components.count - 2]?.components(separatedBy: "/").last
return ("Safari", version)
} else {
// regular browser
return components[safe:components.count - 2]?.components(separatedBy: "/").first
let browserComponent = components[safe: components.count - 2]
let components = browserComponent?.components(separatedBy: "/")
return (components?.first, components?[safe: 1])
}
}
}
Expand Down
7 changes: 5 additions & 2 deletions RiotSwiftUI/Modules/UserSessions/Common/UserSessionInfo.swift
Original file line number Diff line number Diff line change
Expand Up @@ -58,8 +58,11 @@ struct UserSessionInfo: Identifiable {
/// Last seen IP location
let lastSeenIPLocation: String?

/// Device name
let deviceName: String?
/// Client name
let clientName: String?

/// Client version
let clientVersion: String?

/// True to indicate that session has been used under `inactiveSessionDurationTreshold` value
let isActive: Bool
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -150,7 +150,8 @@ struct UserSessionCardViewPreview: View {
deviceModel: nil,
deviceOS: "iOS 15.5",
lastSeenIPLocation: nil,
deviceName: "My iPhone",
clientName: "Element",
clientVersion: "1.0.0",
isActive: true,
isCurrent: isCurrent)
viewData = UserSessionCardViewData(session: session)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -53,7 +53,8 @@ enum MockUserSessionDetailsScreenState: MockScreenState, CaseIterable {
deviceModel: nil,
deviceOS: "iOS 15.5",
lastSeenIPLocation: nil,
deviceName: "My iPhone",
clientName: "Element",
clientVersion: "1.0.0",
isActive: true,
isCurrent: true)
case .sessionSectionOnly:
Expand All @@ -69,7 +70,8 @@ enum MockUserSessionDetailsScreenState: MockScreenState, CaseIterable {
deviceModel: nil,
deviceOS: "Android 4.0",
lastSeenIPLocation: nil,
deviceName: "My Phone",
clientName: "Element",
clientVersion: "1.0.0",
isActive: true,
isCurrent: false)
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -113,7 +113,8 @@ class UserSessionDetailsViewModelTests: XCTestCase {
deviceModel: String? = nil,
deviceOS: String? = nil,
lastSeenIPLocation: String? = nil,
deviceName: String? = nil,
clientName: String? = nil,
clientVersion: String? = nil,
isActive: Bool = true,
isCurrent: Bool = true) -> UserSessionInfo {
UserSessionInfo(id: id,
Expand All @@ -128,7 +129,8 @@ class UserSessionDetailsViewModelTests: XCTestCase {
deviceModel: deviceModel,
deviceOS: deviceOS,
lastSeenIPLocation: lastSeenIPLocation,
deviceName: deviceName,
clientName: clientName,
clientVersion: clientVersion,
isActive: isActive,
isCurrent: isCurrent)
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -93,6 +93,12 @@ class UserSessionDetailsViewModel: UserSessionDetailsViewModelType, UserSessionD
deviceSectionItems.append(.init(title: VectorL10n.userSessionDetailsDeviceModel,
value: model))
}
if session.deviceType == .web,
let clientName = session.clientName,
let clientVersion = session.clientVersion {
deviceSectionItems.append(.init(title: VectorL10n.userSessionDetailsDeviceBrowser,
value: "\(clientName) \(clientVersion)"))
}
if let deviceOS = session.deviceOS {
deviceSectionItems.append(.init(title: VectorL10n.userSessionDetailsDeviceOs,
value: deviceOS))
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -53,7 +53,8 @@ enum MockUserSessionOverviewScreenState: MockScreenState, CaseIterable {
deviceModel: nil,
deviceOS: "iOS 15.5",
lastSeenIPLocation: nil,
deviceName: "My iPhone",
clientName: "Element",
clientVersion: "1.0.0",
isActive: true,
isCurrent: true)
case .otherSession:
Expand All @@ -69,7 +70,8 @@ enum MockUserSessionOverviewScreenState: MockScreenState, CaseIterable {
deviceModel: nil,
deviceOS: "macOS 12.5.1",
lastSeenIPLocation: nil,
deviceName: "My Mac",
clientName: "Electron",
clientVersion: "20.1.1",
isActive: false,
isCurrent: false)
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -52,13 +52,14 @@ class UserSessionOverviewViewModelTests: XCTestCase {
isVerified: false,
lastSeenIP: "10.0.0.10",
lastSeenTimestamp: Date().timeIntervalSince1970 - 100,
applicationName: "Element",
applicationName: "Element iOS",
applicationVersion: "1.9.7",
applicationURL: nil,
deviceModel: "iPhone XS",
deviceOS: "iOS 15.5",
lastSeenIPLocation: nil,
deviceName: "Mobile",
clientName: "Element",
clientVersion: "1.9.7",
isActive: true,
isCurrent: true)
}
Expand Down
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
//
//
// Copyright 2022 New Vector Ltd
//
// Licensed under the Apache License, Version 2.0 (the "License");
Expand Down Expand Up @@ -44,7 +44,7 @@ class UserSessionsDataProvider: UserSessionsDataProviderProtocol {
session.crypto.device(withDeviceId: deviceId, ofUser: userId)
}

func accountData(for eventType: String) -> [AnyHashable : Any]? {
func accountData(for eventType: String) -> [AnyHashable: Any]? {
session.accountData.accountData(forEventType: eventType)
}
}
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
//
//
// Copyright 2022 New Vector Ltd
//
// Licensed under the Apache License, Version 2.0 (the "License");
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -143,7 +143,8 @@ extension UserSessionInfo {
deviceModel: userAgent?.deviceModel,
deviceOS: userAgent?.deviceOS,
lastSeenIPLocation: nil,
deviceName: userAgent?.clientName,
clientName: userAgent?.clientName,
clientVersion: userAgent?.clientVersion,
isActive: isActive,
isCurrent: isCurrent)
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -89,7 +89,8 @@ class MockUserSessionsOverviewService: UserSessionsOverviewServiceProtocol {
deviceModel: nil,
deviceOS: "iOS 15.5",
lastSeenIPLocation: nil,
deviceName: "My iPhone",
clientName: "Element",
clientVersion: "1.0.0",
isActive: true,
isCurrent: true)
}
Expand All @@ -107,7 +108,8 @@ class MockUserSessionsOverviewService: UserSessionsOverviewServiceProtocol {
deviceModel: nil,
deviceOS: "macOS 12.5.1",
lastSeenIPLocation: nil,
deviceName: "My Mac",
clientName: "Electron",
clientVersion: "20.0.0",
isActive: active,
isCurrent: false),
UserSessionInfo(id: "2 verified: \(verified) active: \(active)",
Expand All @@ -122,7 +124,8 @@ class MockUserSessionsOverviewService: UserSessionsOverviewServiceProtocol {
deviceModel: nil,
deviceOS: "Windows 10",
lastSeenIPLocation: nil,
deviceName: "My Windows",
clientName: "Firefox",
clientVersion: "39.0",
isActive: active,
isCurrent: false),
UserSessionInfo(id: "3 verified: \(verified) active: \(active)",
Expand All @@ -137,7 +140,8 @@ class MockUserSessionsOverviewService: UserSessionsOverviewServiceProtocol {
deviceModel: nil,
deviceOS: "Android 4.0",
lastSeenIPLocation: nil,
deviceName: "My Phone",
clientName: "Element",
clientVersion: "1.0.0",
isActive: active,
isCurrent: false)]
}
Expand Down
54 changes: 28 additions & 26 deletions RiotTests/UserAgentParserTests.swift
Original file line number Diff line number Diff line change
Expand Up @@ -121,15 +121,15 @@ class UserAgentParserTests: XCTestCase {

let expected = [
UserAgent(deviceType: .desktop,
deviceModel: "Electron",
deviceOS: "Macintosh",
clientName: nil,
clientVersion: nil),
deviceModel: nil,
deviceOS: "macOS 10.15.7",
clientName: "Electron",
clientVersion: "20.1.1"),
UserAgent(deviceType: .desktop,
deviceModel: "Electron",
deviceModel: nil,
deviceOS: "Windows NT 10.0",
clientName: nil,
clientVersion: nil)
clientName: "Electron",
clientVersion: "20.1.1")
]

XCTAssertEqual(userAgents, expected)
Expand All @@ -147,30 +147,30 @@ class UserAgentParserTests: XCTestCase {

let expected = [
UserAgent(deviceType: .web,
deviceModel: "Chrome",
deviceOS: "Macintosh",
clientName: nil,
clientVersion: nil),
deviceModel: nil,
deviceOS: "macOS 10.15.7",
clientName: "Chrome",
clientVersion: "104.0.5112.102"),
UserAgent(deviceType: .web,
deviceModel: "Chrome",
deviceModel: nil,
deviceOS: "Windows NT 10.0",
clientName: nil,
clientVersion: nil),
clientName: "Chrome",
clientVersion: "104.0.5112.102"),
UserAgent(deviceType: .web,
deviceModel: "Firefox",
deviceOS: "Macintosh",
clientName: nil,
clientVersion: nil),
deviceModel: nil,
deviceOS: "macOS 10.10",
clientName: "Firefox",
clientVersion: "39.0"),
UserAgent(deviceType: .web,
deviceModel: "Safari",
deviceOS: "Macintosh",
clientName: nil,
clientVersion: nil),
deviceModel: nil,
deviceOS: "macOS 10.10.2",
clientName: "Safari",
clientVersion: "8.0.3"),
UserAgent(deviceType: .web,
deviceModel: "Chrome",
deviceModel: nil,
deviceOS: "Android 9",
clientName: nil,
clientVersion: nil)
clientName: "Chrome",
clientVersion: "69.0.3497.100")
]

XCTAssertEqual(userAgents, expected)
Expand All @@ -181,14 +181,16 @@ class UserAgentParserTests: XCTestCase {
"Element (iPhone X; OS 15.2; 3.00)",
"Element/1.9.9; iOS",
"Element/1.9.7 Android",
"Element/1.9.9; iOS "
"some random string",
"Element/1.9.9; iOS ",
]
let userAgents = uaStrings.map { UserAgentParser.parse($0) }

let expected = [
.unknown,
.unknown,
.unknown,
.unknown,
UserAgent(deviceType: .mobile,
deviceModel: nil,
deviceOS: nil,
Expand Down
1 change: 1 addition & 0 deletions changelog.d/pr-6788.change
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
User session details: Include browser version for web sessions (PSG-761).