Skip to content

Commit 3a33ce8

Browse files
authored
Merge pull request #7866 from woocommerce/issue/7864-app-in-wrong-state-link-wrong-blog-id
[Universal Links] Do not enter undetermined state if the user does not have access to the passed blog Id
2 parents 240c31a + 59b0d71 commit 3a33ce8

File tree

2 files changed

+51
-11
lines changed

2 files changed

+51
-11
lines changed

WooCommerce/Classes/Authentication/Epilogue/SwitchStoreUseCase.swift

Lines changed: 35 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,6 @@
11
import UIKit
22
import Yosemite
3+
import protocol Storage.StorageManagerType
34

45
protocol SwitchStoreUseCaseProtocol {
56
func switchStore(with storeID: Int64, onCompletion: @escaping (Bool) -> Void)
@@ -10,9 +11,19 @@ protocol SwitchStoreUseCaseProtocol {
1011
final class SwitchStoreUseCase: SwitchStoreUseCaseProtocol {
1112

1213
private let stores: StoresManager
14+
private let storageManager: StorageManagerType
1315

14-
init(stores: StoresManager) {
16+
private lazy var resultsController: ResultsController<StorageSite> = {
17+
return ResultsController(storageManager: storageManager, sortedBy: [])
18+
}()
19+
20+
private var wooCommerceSites: [Site] {
21+
resultsController.fetchedObjects.filter { $0.isWooCommerceActive == true }
22+
}
23+
24+
init(stores: StoresManager, storageManager: StorageManagerType = ServiceLocator.storageManager) {
1525
self.stores = stores
26+
self.storageManager = storageManager
1627
}
1728

1829
/// The async version of `switchStore` that wraps the completion block version.
@@ -28,6 +39,25 @@ final class SwitchStoreUseCase: SwitchStoreUseCaseProtocol {
2839
}
2940
}
3041

42+
/// Switches the to store with the given id if it was previously synced and stored.
43+
/// This is done to check whether the user has access to that store, avoiding undetermined states if we log out
44+
/// from the current one and try to switch to a store they don't have access to.
45+
///
46+
/// - Parameter storeID: target store ID.
47+
/// - Returns: a boolean that indicates whether the site was changed.
48+
///
49+
func switchToStoreIfSiteIsStored(with storeID: Int64, onCompletion: @escaping (Bool) -> Void) {
50+
refreshStoredSites()
51+
52+
let siteWasStored = wooCommerceSites.first(where: { $0.siteID == storeID }) != nil
53+
54+
guard siteWasStored else {
55+
return onCompletion(false)
56+
}
57+
58+
switchStore(with: storeID, onCompletion: onCompletion)
59+
}
60+
3161
/// A static method which allows easily to switch store. The boolean argument in `onCompletion` indicates that the site was changed.
3262
/// When `onCompletion` is called, the selected site ID is updated while `Site` might still not be available if the site does not exist in storage yet
3363
/// (e.g. a newly connected site).
@@ -111,4 +141,8 @@ final class SwitchStoreUseCase: SwitchStoreUseCaseProtocol {
111141

112142
AppDelegate.shared.authenticatorWasDismissed()
113143
}
144+
145+
private func refreshStoredSites() {
146+
try? resultsController.performFetch()
147+
}
114148
}

WooCommerce/Classes/ViewRelated/MainTabBarController.swift

Lines changed: 16 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -337,9 +337,10 @@ extension MainTabBarController {
337337
}
338338
let siteID = Int64(note.meta.identifier(forKey: .site) ?? Int.min)
339339

340-
switchToStore(with: siteID, onCompletion: {
341-
presentNotificationDetails(for: note)
342-
340+
switchToStore(with: siteID, onCompletion: { siteChanged in
341+
if siteChanged {
342+
presentNotificationDetails(for: note)
343+
}
343344
})
344345
}
345346
ServiceLocator.stores.dispatch(action)
@@ -368,14 +369,16 @@ extension MainTabBarController {
368369
"already_read": note.read ])
369370
}
370371

371-
private static func switchToStore(with siteID: Int64, onCompletion: @escaping () -> Void) {
372-
SwitchStoreUseCase(stores: ServiceLocator.stores).switchStore(with: siteID) { siteChanged in
373-
if siteChanged {
374-
let presenter = SwitchStoreNoticePresenter(siteID: siteID)
375-
presenter.presentStoreSwitchedNoticeWhenSiteIsAvailable(configuration: .switchingStores)
372+
private static func switchToStore(with siteID: Int64, onCompletion: @escaping (Bool) -> Void) {
373+
SwitchStoreUseCase(stores: ServiceLocator.stores).switchToStoreIfSiteIsStored(with: siteID) { siteChanged in
374+
guard siteChanged else {
375+
return onCompletion(false)
376376
}
377377

378-
onCompletion()
378+
let presenter = SwitchStoreNoticePresenter(siteID: siteID)
379+
presenter.presentStoreSwitchedNoticeWhenSiteIsAvailable(configuration: .switchingStores)
380+
381+
onCompletion(true)
379382
}
380383
}
381384

@@ -392,8 +395,11 @@ extension MainTabBarController {
392395
}
393396

394397
static func navigateToOrderDetails(with orderID: Int64, siteID: Int64) {
395-
switchToStore(with: siteID, onCompletion: {
398+
switchToStore(with: siteID, onCompletion: { siteChanged in
396399
switchToOrdersTab {
400+
guard siteChanged else {
401+
return
402+
}
397403
// We give some time to the orders tab transition to finish, otherwise it might prevent the second navigation from happening
398404
DispatchQueue.main.asyncAfter(deadline: .now() + 0.3) {
399405
presentDetails(for: orderID, siteID: siteID)

0 commit comments

Comments
 (0)