Переглянути джерело

Merge pull request #1985 from nextcloud/fix/user-agent-text

Fix user agent for text app
Marino Faggiana 3 роки тому
батько
коміт
d3e900fd09

+ 4 - 0
Nextcloud.xcodeproj/project.pbxproj

@@ -31,6 +31,7 @@
 		AF2D7C7E2742559100ADF566 /* NCShareUserCell.swift in Sources */ = {isa = PBXBuildFile; fileRef = AF2D7C7D2742559100ADF566 /* NCShareUserCell.swift */; };
 		AF36077127BFA4E8001A243D /* ParallelWorker.swift in Sources */ = {isa = PBXBuildFile; fileRef = AF36077027BFA4E8001A243D /* ParallelWorker.swift */; };
 		AF36077627BFB019001A243D /* ParallelWorkerTest.swift in Sources */ = {isa = PBXBuildFile; fileRef = AF36077527BFB019001A243D /* ParallelWorkerTest.swift */; };
+		AF3F909A28213BEA0048A93E /* UserAgentTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = AF3F909928213BEA0048A93E /* UserAgentTests.swift */; };
 		AF3FDCC22796ECC300710F60 /* NCTrash+CollectionView.swift in Sources */ = {isa = PBXBuildFile; fileRef = AF3FDCC12796ECC300710F60 /* NCTrash+CollectionView.swift */; };
 		AF3FDCC32796F3FB00710F60 /* NCTrashListCell.swift in Sources */ = {isa = PBXBuildFile; fileRef = F78ACD4821903F850088454D /* NCTrashListCell.swift */; };
 		AF4BF614275629E20081CEEF /* NCManageDatabase+Account.swift in Sources */ = {isa = PBXBuildFile; fileRef = AF4BF613275629E20081CEEF /* NCManageDatabase+Account.swift */; };
@@ -502,6 +503,7 @@
 		AF2D7C7D2742559100ADF566 /* NCShareUserCell.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = NCShareUserCell.swift; sourceTree = "<group>"; };
 		AF36077027BFA4E8001A243D /* ParallelWorker.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ParallelWorker.swift; sourceTree = "<group>"; };
 		AF36077527BFB019001A243D /* ParallelWorkerTest.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ParallelWorkerTest.swift; sourceTree = "<group>"; };
+		AF3F909928213BEA0048A93E /* UserAgentTests.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = UserAgentTests.swift; sourceTree = "<group>"; };
 		AF3FDCC12796ECC300710F60 /* NCTrash+CollectionView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = "NCTrash+CollectionView.swift"; sourceTree = "<group>"; };
 		AF4BF613275629E20081CEEF /* NCManageDatabase+Account.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = "NCManageDatabase+Account.swift"; sourceTree = "<group>"; };
 		AF4BF61827562A4B0081CEEF /* NCManageDatabase+Metadata.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = "NCManageDatabase+Metadata.swift"; sourceTree = "<group>"; };
@@ -1071,6 +1073,7 @@
 				AF8ED2022757822700B8DBC4 /* NCGlobalTests.swift */,
 				AF36077527BFB019001A243D /* ParallelWorkerTest.swift */,
 				AF70C14C27F3484D00E13DF2 /* SharePermissionTest.swift */,
+				AF3F909928213BEA0048A93E /* UserAgentTests.swift */,
 				AF8ED1FB2757821000B8DBC4 /* NextcloudTests.swift */,
 			);
 			path = NextcloudTests;
@@ -2437,6 +2440,7 @@
 			buildActionMask = 2147483647;
 			files = (
 				AF70C14D27F3484D00E13DF2 /* SharePermissionTest.swift in Sources */,
+				AF3F909A28213BEA0048A93E /* UserAgentTests.swift in Sources */,
 				AF36077627BFB019001A243D /* ParallelWorkerTest.swift in Sources */,
 				AF8ED1FC2757821000B8DBC4 /* NextcloudTests.swift in Sources */,
 				AF8ED2032757822700B8DBC4 /* NCGlobalTests.swift in Sources */,

+ 64 - 0
NextcloudTests/UserAgentTests.swift

@@ -0,0 +1,64 @@
+//
+//  UserAgentTests.swift
+//  Nextcloud
+//
+//  Created by Henrik Storch on 03.05.22.
+//  Copyright © 2022 Henrik Storch. All rights reserved.
+//
+//  Author Henrik Storch <henrik.storch@nextcloud.com>
+//
+//  This program is free software: you can redistribute it and/or modify
+//  it under the terms of the GNU General Public License as published by
+//  the Free Software Foundation, either version 3 of the License, or
+//  (at your option) any later version.
+//
+//  This program is distributed in the hope that it will be useful,
+//  but WITHOUT ANY WARRANTY; without even the implied warranty of
+//  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+//  GNU General Public License for more details.
+//
+//  You should have received a copy of the GNU General Public License
+//  along with this program.  If not, see <http://www.gnu.org/licenses/>.
+//
+
+@testable import Nextcloud
+import XCTest
+
+class UserAgentTests: XCTestCase {
+    // https://github.com/nextcloud/server/blob/fc826e98115b510313ddacbf6fef4ce8d041e373/lib/public/IRequest.php#L83
+    let ncServerUARegex = "^Mozilla\\/5\\.0 \\(iOS\\) (ownCloud|Nextcloud)\\-iOS.*$"
+
+    // https://github.com/ProseMirror/prosemirror-view/blob/427d278aaaacde422ed1f2b8c84bb53337162775/src/browser.js#L18-L22
+    let proseMirrorWebKitUARegex = "\\bAppleWebKit\\/(\\d+)"
+    let proseMirroriOSUARegex = "Mobile\\/\\w+"
+
+    func testDefaultUserAgent() throws {
+        let userAgent: String = CCUtility.getUserAgent()
+        let match = try matches(for: ncServerUARegex, in: userAgent).first
+        XCTAssertNotNil(match)
+    }
+
+    func testTextUserAgent() throws {
+        let userAgent: String = NCUtility.shared.getCustomUserAgentNCText()
+        let match = try matches(for: ncServerUARegex, in: userAgent).first
+        XCTAssertNotNil(match)
+
+        let iOSMatch = try matches(for: proseMirroriOSUARegex, in: userAgent).first
+        XCTAssertNotNil(iOSMatch)
+
+        // https://github.com/ProseMirror/prosemirror-view/blob/8f246f320801f8e3cac92c97f71ac91e3e327f2f/src/input.js#L521-L522
+        let webKitMatch = try matches(for: proseMirrorWebKitUARegex, in: userAgent).first
+        XCTAssertNotNil(webKitMatch)
+        XCTAssertEqual(webKitMatch!.numberOfRanges, 2)
+        let versionRange = webKitMatch!.range(at: 1)
+        let versionString = userAgent[Range(versionRange, in: userAgent)!]
+        let webkitVersion = Int(versionString) ?? 0
+        XCTAssertGreaterThanOrEqual(webkitVersion, 604)
+    }
+
+    func matches(for regex: String, in text: String) throws -> [NSTextCheckingResult] {
+        let range = NSRange(location: 0, length: text.utf16.count)
+        let regex = try NSRegularExpression(pattern: regex)
+        return regex.matches(in: text, range: range)
+    }
+}

+ 7 - 2
iOSClient/Main/Create cloud/NCCreateFormUploadDocuments.swift

@@ -328,7 +328,9 @@ import XLForm
 
             if self.editorId == NCGlobal.shared.editorOnlyoffice {
                 customUserAgent = NCUtility.shared.getCustomUserAgentOnlyOffice()
-            }
+            } else if editorId == NCGlobal.shared.editorText {
+                customUserAgent = NCUtility.shared.getCustomUserAgentNCText()
+            } // else: use default
 
             NCCommunication.shared.NCTextCreateFile(fileNamePath: fileNamePath, editorId: editorId, creatorId: creatorId, templateId: templateIdentifier, customUserAgent: customUserAgent) { account, url, errorCode, errorMessage in
 
@@ -396,7 +398,10 @@ import XLForm
             var customUserAgent: String?
             if self.editorId == NCGlobal.shared.editorOnlyoffice {
                 customUserAgent = NCUtility.shared.getCustomUserAgentOnlyOffice()
-            }
+            } else if editorId == NCGlobal.shared.editorText {
+                customUserAgent = NCUtility.shared.getCustomUserAgentNCText()
+            } // else: use default
+
             NCCommunication.shared.NCTextGetListOfTemplates(customUserAgent: customUserAgent) { account, templates, errorCode, _ in
 
                 self.indicator.stopAnimating()

+ 13 - 0
iOSClient/Utility/NCUtility.swift

@@ -305,6 +305,19 @@ class NCUtility: NSObject {
         return true
     }
 
+    @objc func getCustomUserAgentNCText() -> String {
+        let userAgent: String = CCUtility.getUserAgent()
+        if UIDevice.current.userInterfaceIdiom == .phone {
+            // NOTE: Hardcoded (May 2022)
+            // Tested for iPhone SE (1st), iOS 12; iPhone Pro Max, iOS 15.4
+            // 605.1.15 = WebKit build version
+            // 15E148 = frozen iOS build number according to: https://chromestatus.com/feature/4558585463832576
+            return userAgent + " " + "AppleWebKit/605.1.15 Mobile/15E148"
+        } else {
+            return userAgent
+        }
+    }
+
     @objc func getCustomUserAgentOnlyOffice() -> String {
 
         let appVersion = Bundle.main.object(forInfoDictionaryKey: "CFBundleShortVersionString")!

+ 2 - 0
iOSClient/Viewer/NCViewer.swift

@@ -152,6 +152,8 @@ class NCViewer: NSObject {
 
                         if editor == NCGlobal.shared.editorOnlyoffice {
                             customUserAgent = NCUtility.shared.getCustomUserAgentOnlyOffice()
+                        } else {
+                            customUserAgent = NCUtility.shared.getCustomUserAgentNCText()
                         }
 
                         NCUtility.shared.startActivityIndicator(backgroundView: viewController.view, blurEffect: true)

+ 3 - 3
iOSClient/Viewer/NCViewerNextcloudText/NCViewerNextcloudText.swift

@@ -72,9 +72,9 @@ class NCViewerNextcloudText: UIViewController, WKNavigationDelegate, WKScriptMes
 
         if editor == NCGlobal.shared.editorOnlyoffice {
             webView.customUserAgent = NCUtility.shared.getCustomUserAgentOnlyOffice()
-        } else {
-            webView.customUserAgent = CCUtility.getUserAgent()
-        }
+        } else if editor == NCGlobal.shared.editorText {
+            webView.customUserAgent = NCUtility.shared.getCustomUserAgentNCText()
+        } // else: use default
 
         webView.load(request)
     }