Skip to content

Commit c7f60bd

Browse files
@W-19461882: [M1][MSDK13.1] Enable Flexible Server Matching for QR Code Login (iOS) (Refactor Methods From AuthCoordinatorFrontdoorBridgeLoginOverride To FrontdoorBridgeUrlAppLoginHostMatch To Enable AI-Assisted Test Development)
1 parent c8a643f commit c7f60bd

4 files changed

Lines changed: 124 additions & 43 deletions

File tree

libs/SalesforceSDKCore/SalesforceSDKCore.xcodeproj/project.pbxproj

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -415,6 +415,7 @@
415415
CED452ED1D808DEE009266EB /* SFNativeRestRequestListener.h in Headers */ = {isa = PBXBuildFile; fileRef = CED452E91D808DEE009266EB /* SFNativeRestRequestListener.h */; };
416416
CED452EF1D808E0A009266EB /* SFNativeRestRequestListener.m in Sources */ = {isa = PBXBuildFile; fileRef = CED452EA1D808DEE009266EB /* SFNativeRestRequestListener.m */; };
417417
CED452F01D808E0F009266EB /* SalesforceRestAPITests.m in Sources */ = {isa = PBXBuildFile; fileRef = CED452E81D808DEE009266EB /* SalesforceRestAPITests.m */; };
418+
D36056492E6A4F1B00E3366B /* FrontdoorBridgeUrlAppLoginHostMatch.swift in Sources */ = {isa = PBXBuildFile; fileRef = D36056482E6A4F1B00E3366B /* FrontdoorBridgeUrlAppLoginHostMatch.swift */; };
418419
D3B1519F2E1DA6EB00914EF1 /* AuthCoordinatorFrontdoorBridgeLoginOverride.swift in Sources */ = {isa = PBXBuildFile; fileRef = D3B1519E2E1DA6EB00914EF1 /* AuthCoordinatorFrontdoorBridgeLoginOverride.swift */; };
419420
D3D675DB2D39EF01008E468E /* ChatGenerationsRequestBody.swift in Sources */ = {isa = PBXBuildFile; fileRef = D3D675CF2D39EF01008E468E /* ChatGenerationsRequestBody.swift */; };
420421
D3D675DC2D39EF01008E468E /* EmbeddingsRequestBody.swift in Sources */ = {isa = PBXBuildFile; fileRef = D3D675D12D39EF01008E468E /* EmbeddingsRequestBody.swift */; };
@@ -956,6 +957,7 @@
956957
CED452E81D808DEE009266EB /* SalesforceRestAPITests.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; name = SalesforceRestAPITests.m; path = SalesforceSDKCoreTests/SalesforceRestAPITests.m; sourceTree = SOURCE_ROOT; };
957958
CED452E91D808DEE009266EB /* SFNativeRestRequestListener.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = SFNativeRestRequestListener.h; path = SalesforceSDKCoreTests/SFNativeRestRequestListener.h; sourceTree = SOURCE_ROOT; };
958959
CED452EA1D808DEE009266EB /* SFNativeRestRequestListener.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; name = SFNativeRestRequestListener.m; path = SalesforceSDKCoreTests/SFNativeRestRequestListener.m; sourceTree = SOURCE_ROOT; };
960+
D36056482E6A4F1B00E3366B /* FrontdoorBridgeUrlAppLoginHostMatch.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = FrontdoorBridgeUrlAppLoginHostMatch.swift; sourceTree = "<group>"; };
959961
D3B1519E2E1DA6EB00914EF1 /* AuthCoordinatorFrontdoorBridgeLoginOverride.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = AuthCoordinatorFrontdoorBridgeLoginOverride.swift; sourceTree = "<group>"; };
960962
D3D675CF2D39EF01008E468E /* ChatGenerationsRequestBody.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ChatGenerationsRequestBody.swift; sourceTree = "<group>"; };
961963
D3D675D02D39EF01008E468E /* ChatGenerationsResponseBody.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ChatGenerationsResponseBody.swift; sourceTree = "<group>"; };
@@ -1213,6 +1215,7 @@
12131215
4F96FCC71BFD32130022F021 /* SFOAuthCoordinator.m */,
12141216
4F96FCC51BFD32130022F021 /* SFOAuthCoordinator+Internal.h */,
12151217
D3B1519E2E1DA6EB00914EF1 /* AuthCoordinatorFrontdoorBridgeLoginOverride.swift */,
1218+
D36056482E6A4F1B00E3366B /* FrontdoorBridgeUrlAppLoginHostMatch.swift */,
12161219
4F96FCC91BFD32130022F021 /* SFOAuthCredentials.h */,
12171220
4F96FCCA1BFD32130022F021 /* SFOAuthCredentials.m */,
12181221
4F96FCC81BFD32130022F021 /* SFOAuthCredentials+Internal.h */,
@@ -2297,6 +2300,7 @@
22972300
B7348BF0235F7CDB00E3BBE3 /* SFSDKIDPAuthHelper.m in Sources */,
22982301
CE4CE3441C0E5252009F6029 /* SFOAuthCoordinator.m in Sources */,
22992302
B7895D1A2345304800765D85 /* SFSDKCompositeResponse.m in Sources */,
2303+
D36056492E6A4F1B00E3366B /* FrontdoorBridgeUrlAppLoginHostMatch.swift in Sources */,
23002304
B7FB26E11F78096300FB25A2 /* SFSDKSPLoginResponseHandler.m in Sources */,
23012305
B70135641F87F63900995171 /* SFSDKAuthErrorManager.m in Sources */,
23022306
69D03E262D2C6D0B004381EC /* SFLoginViewController+QrCodeLogin.swift in Sources */,

libs/SalesforceSDKCore/SalesforceSDKCore/Classes/Login/LoginHost/SFSDKLoginHostStorage.h

Lines changed: 11 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -32,11 +32,21 @@ NS_ASSUME_NONNULL_BEGIN
3232

3333
@class SFSDKLoginHost;
3434

35+
@protocol SFSDKLoginHostStore <NSObject>
36+
37+
@required
38+
- (SFSDKLoginHost *)loginHostAtIndex:(NSUInteger)index;
39+
40+
@required
41+
- (NSUInteger)numberOfLoginHosts;
42+
43+
@end
44+
3545
/**
3646
* This class manages the list of login hosts as well its persistence.
3747
* Currently this list is persisted in the user defaults.
3848
*/
39-
@interface SFSDKLoginHostStorage : NSObject
49+
@interface SFSDKLoginHostStorage : NSObject<SFSDKLoginHostStore>
4050

4151
/**
4252
* Returns the shared instance of this class.

libs/SalesforceSDKCore/SalesforceSDKCore/Classes/OAuth/AuthCoordinatorFrontdoorBridgeLoginOverride.swift

Lines changed: 8 additions & 42 deletions
Original file line numberDiff line numberDiff line change
@@ -73,7 +73,13 @@ public class AuthCoordinatorFrontdoorBridgeLoginOverride: NSObject {
7373
self.matchesConsumerKey = frontdoorBridgeUrlClientId == appConsumerKey
7474

7575
// Check if the front door URL host matches the app's selected login host
76-
var appLoginHost = appLoginHostForFrontdoorBridgeUrl(frontdoorBridgeUrl)
76+
var frontdoorBridgeUrlAppLoginHostMatch = FrontdoorBridgeUrlAppLoginHostMatch(
77+
frontdoorBridgeUrl: frontdoorBridgeUrl,
78+
loginHostStore: loginHostStore,
79+
addingAndSwitchingLoginHostsAllowed: addingAndSwitchingLoginHostsAllowed,
80+
selectedAppLoginHost: UserAccountManager.shared.loginHost
81+
)
82+
var appLoginHost = frontdoorBridgeUrlAppLoginHostMatch.appLoginHostMatch
7783
if (appLoginHost == nil && addingAndSwitchingLoginHostsAllowed) {
7884
appLoginHost = frontdoorBridgeUrl.host()
7985
}
@@ -93,47 +99,7 @@ public class AuthCoordinatorFrontdoorBridgeLoginOverride: NSObject {
9399
!SFManagedPreferences.shared().onlyShowAuthorizedHosts && SFManagedPreferences.shared().loginHosts.count == 0
94100
}
95101

96-
private var loginHostStorage: SFSDKLoginHostStorage {
102+
private var loginHostStore: SFSDKLoginHostStore {
97103
SFSDKLoginHostStorage.sharedInstance()
98104
}
99-
100-
private func appLoginHostForFrontdoorBridgeUrl(_ frontdoorBridgeUrl: URL) -> String? {
101-
guard let frontdoorBridgeUrlHost = frontdoorBridgeUrl.host() else {
102-
return nil
103-
}
104-
105-
let frontdoorBridgeUrlIsMyDomain = frontdoorBridgeUrlHost.contains(".my.")
106-
107-
var eligibleAppLoginHosts : [String] = []
108-
if (addingAndSwitchingLoginHostsAllowed) {
109-
for i in 0..<loginHostStorage.numberOfLoginHosts() {
110-
eligibleAppLoginHosts.append(loginHostStorage.loginHost(at: i).host)
111-
}
112-
}
113-
else {
114-
eligibleAppLoginHosts = [UserAccountManager.shared.loginHost]
115-
}
116-
117-
if (frontdoorBridgeUrlIsMyDomain) {
118-
guard let startIndex = frontdoorBridgeUrlHost.range(of: ".my.")?.upperBound else { return nil }
119-
let frontdoorBridgeUrlMyDomainSuffix = frontdoorBridgeUrlHost.suffix(from: startIndex)
120-
121-
for eligibleAppLoginHost in eligibleAppLoginHosts {
122-
if (eligibleAppLoginHost.hasSuffix(frontdoorBridgeUrlMyDomainSuffix)) {
123-
return eligibleAppLoginHost
124-
}
125-
}
126-
}
127-
128-
else {
129-
130-
for eligibleAppLoginHost in eligibleAppLoginHosts {
131-
if (frontdoorBridgeUrlHost == eligibleAppLoginHost) {
132-
return eligibleAppLoginHost
133-
}
134-
}
135-
}
136-
137-
return nil
138-
}
139105
}
Lines changed: 101 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,101 @@
1+
/*
2+
Copyright (c) 2025-present, salesforce.com, inc. All rights reserved.
3+
4+
Redistribution and use of this software in source and binary forms, with or without modification,
5+
are permitted provided that the following conditions are met:
6+
* Redistributions of source code must retain the above copyright notice, this list of conditions
7+
and the following disclaimer.
8+
* Redistributions in binary form must reproduce the above copyright notice, this list of
9+
conditions and the following disclaimer in the documentation and/or other materials provided
10+
with the distribution.
11+
* Neither the name of salesforce.com, inc. nor the names of its contributors may be used to
12+
endorse or promote products derived from this software without specific prior written
13+
permission of salesforce.com, inc.
14+
15+
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR
16+
IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND
17+
FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR
18+
CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
19+
DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
20+
DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
21+
WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY
22+
WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
23+
*/
24+
25+
26+
import Foundation
27+
28+
public struct FrontdoorBridgeUrlAppLoginHostMatch {
29+
30+
let frontdoorBridgeUrl: URL
31+
let loginHostStore: SFSDKLoginHostStore
32+
let addingAndSwitchingLoginHostsAllowed: Bool
33+
let selectedAppLoginHost: String
34+
35+
internal lazy var appLoginHostMatch: String? = {
36+
return appLoginHostForFrontdoorBridgeUrl(
37+
frontdoorBridgeUrl,
38+
loginHostStore: loginHostStore,
39+
addingAndSwitchingLoginHostsAllowed: addingAndSwitchingLoginHostsAllowed,
40+
selectedAppLoginHost: selectedAppLoginHost)
41+
}()
42+
43+
private func appLoginHostForFrontdoorBridgeUrl(
44+
_ frontdoorBridgeUrl: URL,
45+
loginHostStore: SFSDKLoginHostStore,
46+
addingAndSwitchingLoginHostsAllowed: Bool,
47+
selectedAppLoginHost: String
48+
) -> String?
49+
{
50+
guard let frontdoorBridgeUrlHost = frontdoorBridgeUrl.host() else {
51+
return nil
52+
}
53+
54+
let frontdoorBridgeUrlIsMyDomain = frontdoorBridgeUrlHost.contains(".my.")
55+
56+
let eligibleAppLoginHosts = eligibleAppLoginHostsForFrontdoorBridgeUrl(
57+
loginHostStore: loginHostStore,
58+
addingAndSwitchingLoginHostsAllowed: addingAndSwitchingLoginHostsAllowed,
59+
selectedAppLoginHost: selectedAppLoginHost
60+
)
61+
62+
if (frontdoorBridgeUrlIsMyDomain) {
63+
guard let startIndex = frontdoorBridgeUrlHost.range(of: ".my.")?.upperBound else { return nil }
64+
let frontdoorBridgeUrlMyDomainSuffix = frontdoorBridgeUrlHost.suffix(from: startIndex)
65+
66+
for eligibleAppLoginHost in eligibleAppLoginHosts {
67+
if (eligibleAppLoginHost.hasSuffix(frontdoorBridgeUrlMyDomainSuffix)) {
68+
return eligibleAppLoginHost
69+
}
70+
}
71+
}
72+
73+
else {
74+
for eligibleAppLoginHost in eligibleAppLoginHosts {
75+
if (frontdoorBridgeUrlHost == eligibleAppLoginHost) {
76+
return eligibleAppLoginHost
77+
}
78+
}
79+
}
80+
81+
return nil
82+
}
83+
84+
private func eligibleAppLoginHostsForFrontdoorBridgeUrl(
85+
loginHostStore: SFSDKLoginHostStore,
86+
addingAndSwitchingLoginHostsAllowed: Bool,
87+
selectedAppLoginHost: String
88+
) -> [String] {
89+
var results : [String] = []
90+
if (addingAndSwitchingLoginHostsAllowed) {
91+
for i in 0..<loginHostStore.numberOfLoginHosts() {
92+
results.append(loginHostStore.loginHost(at: i).host)
93+
}
94+
}
95+
else {
96+
results = [selectedAppLoginHost]
97+
}
98+
99+
return results
100+
}
101+
}

0 commit comments

Comments
 (0)