From bb9001f8b01930eeda6392b561f2d42ae3c183d4 Mon Sep 17 00:00:00 2001 From: Tony Li Date: Wed, 25 Jun 2025 12:35:20 +1200 Subject: [PATCH 1/2] Call invalid token handler when receiving 'reauthentication_required' errors --- Sources/CoreAPI/WordPressComRestApi.swift | 6 +++-- ...omRestApiFailReauthenticationRequired.json | 4 +++ .../WordPressComRestApiTests.swift | 25 +++++++++++++++++++ WordPressKit.xcodeproj/project.pbxproj | 4 +++ 4 files changed, 37 insertions(+), 2 deletions(-) create mode 100644 Tests/CoreAPITests/Stubs/JSON/WordPressComRestApiFailReauthenticationRequired.json diff --git a/Sources/CoreAPI/WordPressComRestApi.swift b/Sources/CoreAPI/WordPressComRestApi.swift index 92d09222..26055e7d 100644 --- a/Sources/CoreAPI/WordPressComRestApi.swift +++ b/Sources/CoreAPI/WordPressComRestApi.swift @@ -30,6 +30,7 @@ public typealias WordPressComRestApiError = WordPressComRestApiErrorCode case preconditionFailure case malformedURL case invalidQuery + case reauthorizationRequired } public struct WordPressComRestApiEndpointError: Error { @@ -536,11 +537,12 @@ extension WordPressComRestApi { "authorization_required": .authorizationRequired, "upload_error": .uploadFailed, "unauthorized": .authorizationRequired, - "invalid_query": .invalidQuery + "invalid_query": .invalidQuery, + "reauthorization_required": .reauthorizationRequired, ] let mappedError = errorsMap[errorCode] ?? .unknown - if mappedError == .invalidToken { + if mappedError == .invalidToken || mappedError == .reauthorizationRequired { // Call `invalidTokenHandler in the main thread since it's typically used by the apps to present an authentication UI. DispatchQueue.main.async { self.invalidTokenHandler?() diff --git a/Tests/CoreAPITests/Stubs/JSON/WordPressComRestApiFailReauthenticationRequired.json b/Tests/CoreAPITests/Stubs/JSON/WordPressComRestApiFailReauthenticationRequired.json new file mode 100644 index 00000000..63be1a7c --- /dev/null +++ b/Tests/CoreAPITests/Stubs/JSON/WordPressComRestApiFailReauthenticationRequired.json @@ -0,0 +1,4 @@ +{ + "message": "A fresh access token must be used to query information about the current user.", + "error": "reauthorization_required" +} diff --git a/Tests/CoreAPITests/WordPressComRestApiTests.swift b/Tests/CoreAPITests/WordPressComRestApiTests.swift index 83cca189..a52784d1 100644 --- a/Tests/CoreAPITests/WordPressComRestApiTests.swift +++ b/Tests/CoreAPITests/WordPressComRestApiTests.swift @@ -189,6 +189,31 @@ class WordPressComRestApiTests: XCTestCase { self.waitForExpectations(timeout: 2, handler: nil) } + func testInvalidTokenFailedCallWithReauthenticationRequiredError() throws { + let stubPath = try XCTUnwrap( + OHPathForFileInBundle("WordPressComRestApiFailReauthenticationRequired.json", Bundle.coreAPITestsBundle) + ) + stub(condition: isRestAPIRequest()) { _ in + return fixture(filePath: stubPath, status: 401, headers: ["Content-Type" as NSObject: "application/json" as AnyObject]) + } + + let expect = self.expectation(description: "One callback should be invoked") + let handlerCalled = self.expectation(description: "Handler should be called") + let api = WordPressComRestApi(oAuthToken: "fakeToken") + api.setInvalidTokenHandler { + handlerCalled.fulfill() + } + api.GET(wordPressMediaRoutePath, parameters: nil, success: { (_: AnyObject, _: HTTPURLResponse?) in + expect.fulfill() + XCTFail("This call should fail") + }, failure: { (error, _) in + expect.fulfill() + XCTAssert(error.domain == "WordPressKit.WordPressComRestApiError", "The error should a WordPressComRestApiError") + XCTAssert(error.code == Int(WordPressComRestApiErrorCode.reauthorizationRequired.rawValue), "The error code should be invalid token") + }) + self.wait(for: [expect, handlerCalled], timeout: 2) + } + func testInvalidJSONReceivedFailedCall() throws { let stubPath = try XCTUnwrap( OHPathForFileInBundle("WordPressComRestApiFailInvalidJSON.json", Bundle.coreAPITestsBundle) diff --git a/WordPressKit.xcodeproj/project.pbxproj b/WordPressKit.xcodeproj/project.pbxproj index c6177f16..e028239c 100644 --- a/WordPressKit.xcodeproj/project.pbxproj +++ b/WordPressKit.xcodeproj/project.pbxproj @@ -224,6 +224,7 @@ 4A3239642B73132B00EFD2A8 /* SelfHostedPluginManagementClientTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = 4A3239632B73132B00EFD2A8 /* SelfHostedPluginManagementClientTests.swift */; }; 4A3239662B7314E200EFD2A8 /* self-hosted-plugins-get.json in Resources */ = {isa = PBXBuildFile; fileRef = 4A3239652B7314E200EFD2A8 /* self-hosted-plugins-get.json */; }; 4A3239682B74319400EFD2A8 /* self-hosted-plugins-install.json in Resources */ = {isa = PBXBuildFile; fileRef = 4A3239672B74319400EFD2A8 /* self-hosted-plugins-install.json */; }; + 4A399CD52E0B7A9D0014E6AE /* WordPressComRestApiFailReauthenticationRequired.json in Resources */ = {isa = PBXBuildFile; fileRef = 4A399CD42E0B7A9D0014E6AE /* WordPressComRestApiFailReauthenticationRequired.json */; }; 4A40F6552B2A5A1A0015DA77 /* WordPressAPIErrorTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = 4A40F6542B2A5A1A0015DA77 /* WordPressAPIErrorTests.swift */; }; 4A57A6812B549144008D0660 /* WordPressComRestApiTests+Error.swift in Sources */ = {isa = PBXBuildFile; fileRef = 4A57A6802B549144008D0660 /* WordPressComRestApiTests+Error.swift */; }; 4A68E3CD29404181004AC3DC /* RemoteBlog.swift in Sources */ = {isa = PBXBuildFile; fileRef = 4A68E3CC29404181004AC3DC /* RemoteBlog.swift */; }; @@ -1005,6 +1006,7 @@ 4A3239632B73132B00EFD2A8 /* SelfHostedPluginManagementClientTests.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = SelfHostedPluginManagementClientTests.swift; sourceTree = ""; }; 4A3239652B7314E200EFD2A8 /* self-hosted-plugins-get.json */ = {isa = PBXFileReference; lastKnownFileType = text.json; path = "self-hosted-plugins-get.json"; sourceTree = ""; }; 4A3239672B74319400EFD2A8 /* self-hosted-plugins-install.json */ = {isa = PBXFileReference; lastKnownFileType = text.json; path = "self-hosted-plugins-install.json"; sourceTree = ""; }; + 4A399CD42E0B7A9D0014E6AE /* WordPressComRestApiFailReauthenticationRequired.json */ = {isa = PBXFileReference; lastKnownFileType = text.json; path = WordPressComRestApiFailReauthenticationRequired.json; sourceTree = ""; }; 4A40F6542B2A5A1A0015DA77 /* WordPressAPIErrorTests.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = WordPressAPIErrorTests.swift; sourceTree = ""; }; 4A57A6802B549144008D0660 /* WordPressComRestApiTests+Error.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = "WordPressComRestApiTests+Error.swift"; sourceTree = ""; }; 4A68E3CC29404181004AC3DC /* RemoteBlog.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = RemoteBlog.swift; sourceTree = ""; }; @@ -1743,6 +1745,7 @@ 74B335DF1F06F6290053A184 /* WordPressComRestApiFailInvalidInput.json */, 74B335DD1F06F5A50053A184 /* WordPressComRestApiFailInvalidJSON.json */, 74B335E11F06F6730053A184 /* WordPressComRestApiFailRequestInvalidToken.json */, + 4A399CD42E0B7A9D0014E6AE /* WordPressComRestApiFailReauthenticationRequired.json */, 93F50A3B1F226C0100B5BEBA /* WordPressComRestApiFailThrottled.json */, 74B335E71F06F7200053A184 /* WordPressComRestApiFailUnauthorized.json */, 74B335E51F06F6E90053A184 /* WordPressComRestApiMedia.json */, @@ -3139,6 +3142,7 @@ FFE247AF20C891E6002DF3A2 /* WordPressComOAuthWrongPasswordFail.json in Resources */, 0CE311C52DCBB970003AADB3 /* site-subscriber-stats-response.json in Resources */, F194E1252417EE7E00874408 /* atomic-get-auth-cookie-success.json in Resources */, + 4A399CD52E0B7A9D0014E6AE /* WordPressComRestApiFailReauthenticationRequired.json in Resources */, 731BA83A21DED358000FDFCD /* site-creation-success.json in Resources */, FEFFD99726C158F400F34231 /* share-app-content-success.json in Resources */, 465F88B7263B455300F4C950 /* get_wp_v2_themes_twentytwentyone-no-colors.json in Resources */, From 9a049a232a63833c39807e7fcee17c0c9be5a6ae Mon Sep 17 00:00:00 2001 From: Tony Li Date: Wed, 25 Jun 2025 15:26:36 +1200 Subject: [PATCH 2/2] Update the xcframework link --- Package.swift | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/Package.swift b/Package.swift index 80b5bbb8..14da2427 100644 --- a/Package.swift +++ b/Package.swift @@ -11,8 +11,8 @@ let package = Package( targets: [ .binaryTarget( name: "WordPressKit", - url: "https://github.com/user-attachments/files/20825728/WordPressKit.zip", - checksum: "097a2e55e4ec66b4d8c37bc49181df33c4b62ea9d130fac4de057a0867b68a69" + url: "https://github.com/user-attachments/files/20895757/WordPressKit.zip", + checksum: "b08eaf182f0399303aadccb1a6dad6cad294a9c8d123d920889b15950c85e08f" ), ] )