diff --git a/Config/CommonConfiguration.swift b/Config/CommonConfiguration.swift index 5937b46590..6f9a7f555b 100644 --- a/Config/CommonConfiguration.swift +++ b/Config/CommonConfiguration.swift @@ -17,6 +17,10 @@ import Foundation import MatrixSDK +#if !os(OSX) +import DeviceKit +#endif + /// CommonConfiguration is the central point to setup settings for MatrixSDK, MatrixKit and common configurations for all targets. class CommonConfiguration: NSObject, Configurable { @@ -66,8 +70,13 @@ class CommonConfiguration: NSObject, Configurable { // Disable identicon use sdkOptions.disableIdenticonUseForUserAvatar = true + // Set up user agent + if let userAgent = makeASCIIUserAgent() { + sdkOptions.httpAdditionalHeaders = ["User-Agent": userAgent] + } + // Pass httpAdditionalHeaders to the SDK - sdkOptions.httpAdditionalHeaders = BuildSettings.httpAdditionalHeaders + sdkOptions.httpAdditionalHeaders = (sdkOptions.httpAdditionalHeaders ?? [:]).merging(BuildSettings.httpAdditionalHeaders, uniquingKeysWith: { _, value in value }) // Disable key backup on common sdkOptions.enableKeyBackupWhenStartingMXCrypto = false @@ -82,6 +91,59 @@ class CommonConfiguration: NSObject, Configurable { MXKeyProvider.sharedInstance().delegate = EncryptionKeyManager.shared } + private func makeASCIIUserAgent() -> String? { + guard var userAgent = makeUserAgent() else { + return nil + } + if !userAgent.canBeConverted(to: .ascii) { + let mutableUserAgent = NSMutableString(string: userAgent) + if CFStringTransform(mutableUserAgent, nil, "Any-Latin; Latin-ASCII; [:^ASCII:] Remove" as CFString, false) { + userAgent = mutableUserAgent as String + } + } + return userAgent + } + + private func makeUserAgent() -> String? { + let appInfo = AppInfo.current + let clientName = appInfo.displayName + let clientVersion = appInfo.appVersion?.bundleShortVersion ?? "unknown" + + #if os(iOS) + return String( + format: "%@/%@ (%@; iOS %@; Scale/%0.2f)", + clientName, + clientVersion, + Device.current.safeDescription, + UIDevice.current.systemVersion, + UIScreen.main.scale) + #elseif os(tvOS) + return String( + format: "%@/%@ (%@; tvOS %@; Scale/%0.2f)", + clientName, + clientVersion, + Device.current.safeDescription, + UIDevice.current.systemVersion, + UIScreen.main.scale) + #elseif os(watchOS) + return String( + format: "%@/%@ (%@; watchOS %@; Scale/%0.2f)", + clientName, + clientVersion, + Device.current.safeDescription, + WKInterfaceDevice.current.systemVersion, + WKInterfaceDevice.currentDevice.screenScale) + #elseif os(OSX) + return String( + format: "%@/%@ (Mac; Mac OS X %@)", + clientName, + clientVersion, + NSProcessInfo.processInfo.operatingSystemVersionString) + #else + return nil + #endif + } + // MARK: - Per matrix session settings diff --git a/Riot.xcworkspace/xcshareddata/swiftpm/Package.resolved b/Riot.xcworkspace/xcshareddata/swiftpm/Package.resolved index 3d248ff515..7b45c9e98f 100644 --- a/Riot.xcworkspace/xcshareddata/swiftpm/Package.resolved +++ b/Riot.xcworkspace/xcshareddata/swiftpm/Package.resolved @@ -1,5 +1,14 @@ { "pins" : [ + { + "identity" : "devicekit", + "kind" : "remoteSourceControl", + "location" : "https://github.com/devicekit/DeviceKit", + "state" : { + "revision" : "20e0991f3975916ab0f6d58db84d8bc64f883537", + "version" : "4.7.0" + } + }, { "identity" : "maplibre-gl-native-distribution", "kind" : "remoteSourceControl", diff --git a/Riot/Assets/third_party_licenses.html b/Riot/Assets/third_party_licenses.html index a9365018fe..ebd5e6b119 100644 --- a/Riot/Assets/third_party_licenses.html +++ b/Riot/Assets/third_party_licenses.html @@ -1908,6 +1908,32 @@ CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.

+
  • + DeviceKit (https://github.com/devicekit/DeviceKit) +

    + MIT License +

    + Copyright (c) 2015 Dennis Weissmann +

    + Permission is hereby granted, free of charge, to any person obtaining a copy + of this software and associated documentation files (the "Software"), to deal + in the Software without restriction, including without limitation the rights + to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + copies of the Software, and to permit persons to whom the Software is + furnished to do so, subject to the following conditions: +

    + The above copyright notice and this permission notice shall be included in + all copies or substantial portions of the Software. +

    + THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN + THE SOFTWARE. +

    +
  • diff --git a/Riot/target.yml b/Riot/target.yml index f2a1bb16b5..1d6b61fbba 100644 --- a/Riot/target.yml +++ b/Riot/target.yml @@ -39,6 +39,7 @@ targets: - package: Mapbox - package: OrderedCollections - package: SwiftOGG + - package: DeviceKit configFiles: Debug: Debug.xcconfig diff --git a/RiotNSE/target.yml b/RiotNSE/target.yml index bbf8a6ab32..22b415154f 100644 --- a/RiotNSE/target.yml +++ b/RiotNSE/target.yml @@ -31,6 +31,9 @@ targets: platform: iOS type: app-extension + dependencies: + - package: DeviceKit + configFiles: Debug: Debug.xcconfig Release: Release.xcconfig diff --git a/RiotShareExtension/target.yml b/RiotShareExtension/target.yml index 29dfe514df..a44714f335 100644 --- a/RiotShareExtension/target.yml +++ b/RiotShareExtension/target.yml @@ -31,6 +31,9 @@ targets: platform: iOS type: app-extension + dependencies: + - package: DeviceKit + configFiles: Debug: Debug.xcconfig Release: Release.xcconfig diff --git a/RiotTests/target.yml b/RiotTests/target.yml index 990253346e..cde05e9efe 100644 --- a/RiotTests/target.yml +++ b/RiotTests/target.yml @@ -60,6 +60,8 @@ targets: - path: ../Config/AppConfiguration.swift - path: ../Config/CommonConfiguration.swift - path: ../Riot/Categories/Bundle.swift + - path: ../Riot/Managers/AppInfo/AppInfo.swift + - path: ../Riot/Managers/AppInfo/AppVersion.swift - path: ../Riot/Managers/Settings/RiotSettings.swift - path: ../Riot/Managers/EncryptionKeyManager/EncryptionKeyManager.swift - path: ../Riot/Managers/KeyValueStorage/ diff --git a/SiriIntents/target.yml b/SiriIntents/target.yml index ccce66a4a7..d20501785d 100644 --- a/SiriIntents/target.yml +++ b/SiriIntents/target.yml @@ -33,6 +33,7 @@ targets: dependencies: - sdk: Intents.framework + - package: DeviceKit configFiles: Debug: Debug.xcconfig diff --git a/changelog.d/6742.change b/changelog.d/6742.change new file mode 100644 index 0000000000..38aab166a3 --- /dev/null +++ b/changelog.d/6742.change @@ -0,0 +1 @@ +Include concrete device model in user agent (PSG-754) diff --git a/project.yml b/project.yml index aa33c25d8d..90112cd1be 100644 --- a/project.yml +++ b/project.yml @@ -51,3 +51,6 @@ packages: SwiftOGG: url: https://github.com/vector-im/swift-ogg branch: main + DeviceKit: + url: https://github.com/devicekit/DeviceKit + majorVersion: 4.7.0