diff --git a/mobile/android/app/src/main/kotlin/app/alextran/immich/core/HttpClientManager.kt b/mobile/android/app/src/main/kotlin/app/alextran/immich/core/HttpClientManager.kt index cefdf4fbd2..73f7a09183 100644 --- a/mobile/android/app/src/main/kotlin/app/alextran/immich/core/HttpClientManager.kt +++ b/mobile/android/app/src/main/kotlin/app/alextran/immich/core/HttpClientManager.kt @@ -53,7 +53,7 @@ import javax.net.ssl.TrustManagerFactory import javax.net.ssl.X509KeyManager import javax.net.ssl.X509TrustManager -const val USER_AGENT = "Immich_Android_${BuildConfig.VERSION_NAME}" +const val USER_AGENT = "immich-android/${BuildConfig.VERSION_NAME}" private const val CERT_ALIAS = "client_cert" private const val PREFS_NAME = "immich.ssl" private const val PREFS_CERT_ALIAS = "immich.client_cert" diff --git a/mobile/ios/Runner/Core/URLSessionManager.swift b/mobile/ios/Runner/Core/URLSessionManager.swift index 9eb93f9ff9..e9d65d3113 100644 --- a/mobile/ios/Runner/Core/URLSessionManager.swift +++ b/mobile/ios/Runner/Core/URLSessionManager.swift @@ -36,7 +36,7 @@ extension UserDefaults { /// Old sessions are kept alive by Dart's FFI retain until all isolates release them. class URLSessionManager: NSObject { static let shared = URLSessionManager() - + private(set) var session: URLSession let delegate: URLSessionManagerDelegate private static let cacheDir: URL = { @@ -53,7 +53,7 @@ class URLSessionManager: NSObject { ) static let userAgent: String = { let version = Bundle.main.object(forInfoDictionaryKey: "CFBundleShortVersionString") as? String ?? "unknown" - return "Immich_iOS_\(version)" + return "immich-ios/\(version)" }() static let cookieStorage = HTTPCookieStorage.sharedCookieStorage(forGroupContainerIdentifier: APP_GROUP) private static var serverUrls: [String] = [] diff --git a/mobile/lib/utils/user_agent.dart b/mobile/lib/utils/user_agent.dart index 232bcaec38..f08793e3a1 100644 --- a/mobile/lib/utils/user_agent.dart +++ b/mobile/lib/utils/user_agent.dart @@ -1,15 +1,16 @@ import 'dart:io' show Platform; + import 'package:package_info_plus/package_info_plus.dart'; Future getUserAgentString() async { final packageInfo = await PackageInfo.fromPlatform(); String platform; if (Platform.isAndroid) { - platform = 'Android'; + platform = 'android'; } else if (Platform.isIOS) { - platform = 'iOS'; + platform = 'ios'; } else { - platform = 'Unknown'; + platform = 'unknown'; } - return 'Immich_${platform}_${packageInfo.version}'; + return 'immich-$platform/${packageInfo.version}'; } diff --git a/server/src/utils/request.spec.ts b/server/src/utils/request.spec.ts new file mode 100644 index 0000000000..f65d19f86f --- /dev/null +++ b/server/src/utils/request.spec.ts @@ -0,0 +1,29 @@ +import { getAppVersionFromUA } from 'src/utils/request'; + +describe(getAppVersionFromUA.name, () => { + it('should get the app version for android', () => { + expect(getAppVersionFromUA('immich-android/1.123.4')).toEqual('1.123.4'); + }); + + it('should get the app version for ios', () => { + expect(getAppVersionFromUA('immich-ios/1.123.4')).toEqual('1.123.4'); + }); + + it('should get the app version for unknown', () => { + expect(getAppVersionFromUA('immich-unknown/1.123.4')).toEqual('1.123.4'); + }); + + describe('legacy format', () => { + it('should get the app version from the old android format', () => { + expect(getAppVersionFromUA('Immich_Android_1.123.4')).toEqual('1.123.4'); + }); + + it('should get the app version from the old ios format', () => { + expect(getAppVersionFromUA('Immich_iOS_1.123.4')).toEqual('1.123.4'); + }); + + it('should get the app version from the old unknown format', () => { + expect(getAppVersionFromUA('Immich_Unknown_1.123.4')).toEqual('1.123.4'); + }); + }); +}); diff --git a/server/src/utils/request.ts b/server/src/utils/request.ts index c64c980520..4cd8decf45 100644 --- a/server/src/utils/request.ts +++ b/server/src/utils/request.ts @@ -7,8 +7,11 @@ export const fromChecksum = (checksum: string): Buffer => { export const fromMaybeArray = (param: T | T[]) => (Array.isArray(param) ? param[0] : param); -const getAppVersionFromUA = (ua: string) => - ua.match(/^Immich_(?:Android|iOS)_(?.+)$/)?.groups?.appVersion ?? null; +export const getAppVersionFromUA = (ua: string) => + ua.match(/^immich-(?:android|ios|unknown)\/(?.+)$/)?.groups?.appVersion ?? + // legacy format + ua.match(/^Immich_(?:Android|iOS|Unknown)_(?.+)$/)?.groups?.appVersion ?? + null; export const getUserAgentDetails = (headers: IncomingHttpHeaders) => { const userAgent = UAParser(headers['user-agent']);