diff --git a/swift-sdk/Internal/AuthManager.swift b/swift-sdk/Internal/AuthManager.swift index 94b22abe3..8a3dadf53 100644 --- a/swift-sdk/Internal/AuthManager.swift +++ b/swift-sdk/Internal/AuthManager.swift @@ -53,6 +53,12 @@ class AuthManager: IterableAuthManagerProtocol { } } + func setNewToken(_ newToken: String) { + ITBInfo() + + onAuthTokenReceived(retrievedAuthToken: newToken) + } + func logoutUser() { ITBInfo() @@ -86,7 +92,7 @@ class AuthManager: IterableAuthManagerProtocol { queueAuthTokenExpirationRefresh(authToken) } - private func onAuthTokenReceived(retrievedAuthToken: String?, onSuccess: AuthTokenRetrievalHandler?) { + private func onAuthTokenReceived(retrievedAuthToken: String?, onSuccess: AuthTokenRetrievalHandler? = nil) { pendingAuth = false authToken = retrievedAuthToken diff --git a/swift-sdk/Internal/InternalIterableAPI.swift b/swift-sdk/Internal/InternalIterableAPI.swift index e7be40904..3ed5d4261 100644 --- a/swift-sdk/Internal/InternalIterableAPI.swift +++ b/swift-sdk/Internal/InternalIterableAPI.swift @@ -95,7 +95,7 @@ final class InternalIterableAPI: NSObject, PushTrackerProtocol, AuthProvider { deviceAttributes.removeValue(forKey: name) } - func setEmail(_ email: String?) { + func setEmail(_ email: String?, authToken: String? = nil) { ITBInfo() if _email == email { @@ -109,10 +109,10 @@ final class InternalIterableAPI: NSObject, PushTrackerProtocol, AuthProvider { storeIdentifierData() - onLogin() + onLogin(authToken) } - func setUserId(_ userId: String?) { + func setUserId(_ userId: String?, authToken: String? = nil) { ITBInfo() if _userId == userId { @@ -126,7 +126,7 @@ final class InternalIterableAPI: NSObject, PushTrackerProtocol, AuthProvider { storeIdentifierData() - onLogin() + onLogin(authToken) } func logoutUser() { @@ -200,10 +200,13 @@ final class InternalIterableAPI: NSObject, PushTrackerProtocol, AuthProvider { withToken token: String? = nil, onSuccess: OnSuccessHandler? = nil, onFailure: OnFailureHandler? = nil) -> Pending { - requestHandler.updateEmail(newEmail, onSuccess: nil, onFailure: nil).onSuccess { json in + requestHandler.updateEmail(newEmail, + onSuccess: nil, + onFailure: nil).onSuccess { json in if self.email != nil { - self.setEmail(newEmail) + self.setEmail(newEmail, authToken: token) } + onSuccess?(json) }.onError { error in onFailure?(error.reason, error.data) @@ -475,10 +478,13 @@ final class InternalIterableAPI: NSObject, PushTrackerProtocol, AuthProvider { localStorage.userId = _userId } - private func onLogin() { + private func onLogin(_ authToken: String? = nil) { ITBInfo() - if isEitherUserIdOrEmailSet() && config.authDelegate != nil { + if let authToken = authToken { + self.authManager.setNewToken(authToken) + completeUserLogin() + } else if isEitherUserIdOrEmailSet() && config.authDelegate != nil { requestNewAuthToken() } else { completeUserLogin() diff --git a/swift-sdk/IterableAPI.swift b/swift-sdk/IterableAPI.swift index 7d955b952..5d7e317df 100644 --- a/swift-sdk/IterableAPI.swift +++ b/swift-sdk/IterableAPI.swift @@ -309,7 +309,7 @@ public final class IterableAPI: NSObject { /// /// - Parameters: /// - newEmail: The new email of this user - /// - token: The new authentication token for this user + /// - token: The new authentication token for this user, if left out, the SDK will not update the token in any way /// - onSuccess: `OnSuccessHandler` to invoke if update is successful /// - onFailure: `OnFailureHandler` to invoke if update fails /// @@ -321,7 +321,7 @@ public final class IterableAPI: NSObject { withToken token: String, onSuccess: OnSuccessHandler?, onFailure: OnFailureHandler?) { - internalImplementation?.updateEmail(newEmail, onSuccess: onSuccess, onFailure: onFailure) + internalImplementation?.updateEmail(newEmail, withToken: token, onSuccess: onSuccess, onFailure: onFailure) } /// Tracks what's in the shopping cart (or equivalent) at this point in time diff --git a/swift-sdk/IterableAuthManagerProtocol.swift b/swift-sdk/IterableAuthManagerProtocol.swift index 800723733..7b3eeb5ba 100644 --- a/swift-sdk/IterableAuthManagerProtocol.swift +++ b/swift-sdk/IterableAuthManagerProtocol.swift @@ -8,5 +8,6 @@ import Foundation func getAuthToken() -> String? func resetFailedAuthCount() func requestNewAuthToken(hasFailedPriorAuth: Bool, onSuccess: ((String?) -> Void)?) + func setNewToken(_ newToken: String) func logoutUser() } diff --git a/tests/unit-tests/AuthTests.swift b/tests/unit-tests/AuthTests.swift index baef1c521..3a3849ee4 100644 --- a/tests/unit-tests/AuthTests.swift +++ b/tests/unit-tests/AuthTests.swift @@ -90,7 +90,7 @@ class AuthTests: XCTestCase { XCTAssertNil(internalAPI.auth.authToken) } - func testNewEmailWithTokenChange() { + func testNewEmailAndThenChangeToken() { var internalAPI: InternalIterableAPI? let originalEmail = "first@example.com" @@ -128,7 +128,7 @@ class AuthTests: XCTestCase { XCTAssertEqual(API.auth.authToken, newToken) } - func testNewUserIdWithTokenChange() { + func testNewUserIdAndThenChangeToken() { var internalAPI: InternalIterableAPI? let originalUserId = "firstUserId" @@ -166,8 +166,8 @@ class AuthTests: XCTestCase { XCTAssertEqual(API.auth.authToken, newToken) } - func testUpdateEmailWithToken() { - let condition1 = expectation(description: "update email with auth token") + func testUpdateEmailAndThenChangeToken() { + let condition1 = expectation(description: "update email and then change auth token") var internalAPI: InternalIterableAPI? @@ -211,6 +211,50 @@ class AuthTests: XCTestCase { wait(for: [condition1], timeout: testExpectationTimeout) } + func testUpdateEmailWithTokenParam() { + let condition1 = expectation(description: #function) + + var internalAPI: InternalIterableAPI? + + let originalEmail = "rtbo" + let originalToken = "hngk" + + let updatedEmail = "2" + let updatedToken = "564g" + + let authDelegate = DefaultAuthDelegate { + return originalToken + } + + let config = IterableConfig() + config.authDelegate = authDelegate + + internalAPI = InternalIterableAPI.initializeForTesting(config: config) + + guard let API = internalAPI else { + XCTFail() + return + } + + API.setEmail(originalEmail) + + XCTAssertEqual(API.email, originalEmail) + XCTAssertNil(API.userId) + XCTAssertEqual(API.auth.authToken, originalToken) + + API.updateEmail(updatedEmail, withToken: updatedToken) { data in + XCTAssertEqual(API.email, updatedEmail) + XCTAssertNil(API.userId) + XCTAssertEqual(API.auth.authToken, updatedToken) + + condition1.fulfill() + } onFailure: { reason, data in + XCTFail() + } + + wait(for: [condition1], timeout: testExpectationTimeout) + } + func testLogoutUser() { let authDelegate = createStockAuthDelegate()