mirror of
https://github.com/XcodesOrg/XcodesApp.git
synced 2026-03-25 08:55:46 +00:00
feat: switch login to use xcodesLoginKit
This commit is contained in:
parent
17f3d365b8
commit
84f1838e60
23 changed files with 163 additions and 192 deletions
|
|
@ -3,7 +3,7 @@
|
|||
archiveVersion = 1;
|
||||
classes = {
|
||||
};
|
||||
objectVersion = 54;
|
||||
objectVersion = 60;
|
||||
objects = {
|
||||
|
||||
/* Begin PBXBuildFile section */
|
||||
|
|
@ -60,7 +60,6 @@
|
|||
CA9FF8E025959BAA00E47BAF /* ConnectionVerifier.swift in Sources */ = {isa = PBXBuildFile; fileRef = CA9FF8DF25959BAA00E47BAF /* ConnectionVerifier.swift */; };
|
||||
CA9FF8E625959BB800E47BAF /* AuditTokenHack.m in Sources */ = {isa = PBXBuildFile; fileRef = CA9FF8E525959BB800E47BAF /* AuditTokenHack.m */; };
|
||||
CA9FF9362595B44700E47BAF /* HelperClient.swift in Sources */ = {isa = PBXBuildFile; fileRef = CA9FF9352595B44700E47BAF /* HelperClient.swift */; };
|
||||
CAA1CB2D255A5262003FD669 /* AppleAPI in Frameworks */ = {isa = PBXBuildFile; productRef = CAA1CB2C255A5262003FD669 /* AppleAPI */; };
|
||||
CAA1CB35255A5AD5003FD669 /* SignInCredentialsView.swift in Sources */ = {isa = PBXBuildFile; fileRef = CAA1CB34255A5AD5003FD669 /* SignInCredentialsView.swift */; };
|
||||
CAA1CB45255A5B60003FD669 /* SignIn2FAView.swift in Sources */ = {isa = PBXBuildFile; fileRef = CAA1CB44255A5B60003FD669 /* SignIn2FAView.swift */; };
|
||||
CAA1CB49255A5C97003FD669 /* SignInSMSView.swift in Sources */ = {isa = PBXBuildFile; fileRef = CAA1CB48255A5C97003FD669 /* SignInSMSView.swift */; };
|
||||
|
|
@ -129,6 +128,8 @@
|
|||
E87DD6EB25D053FA00D86808 /* Progress+.swift in Sources */ = {isa = PBXBuildFile; fileRef = E87DD6EA25D053FA00D86808 /* Progress+.swift */; };
|
||||
E89342FA25EDCC17007CF557 /* NotificationManager.swift in Sources */ = {isa = PBXBuildFile; fileRef = E89342F925EDCC17007CF557 /* NotificationManager.swift */; };
|
||||
E8977EA325C11E1500835F80 /* PreferencesView.swift in Sources */ = {isa = PBXBuildFile; fileRef = E8977EA225C11E1500835F80 /* PreferencesView.swift */; };
|
||||
E89CBD382D5FAB950037ED95 /* XcodesLoginKit in Frameworks */ = {isa = PBXBuildFile; productRef = E89CBD372D5FAB950037ED95 /* XcodesLoginKit */; };
|
||||
E89CBD3D2D5FB25A0037ED95 /* AppleAPI in Frameworks */ = {isa = PBXBuildFile; productRef = E89CBD3C2D5FB25A0037ED95 /* AppleAPI */; };
|
||||
E8B20CBF2A2EDEC20057D816 /* SDKs+Xcode.swift in Sources */ = {isa = PBXBuildFile; fileRef = E8B20CBE2A2EDEC20057D816 /* SDKs+Xcode.swift */; };
|
||||
E8C0EB1A291EF43E0081528A /* XcodesKit in Frameworks */ = {isa = PBXBuildFile; productRef = E8C0EB19291EF43E0081528A /* XcodesKit */; };
|
||||
E8C0EB1C291EF9A10081528A /* AppState+Runtimes.swift in Sources */ = {isa = PBXBuildFile; fileRef = E8C0EB1B291EF9A10081528A /* AppState+Runtimes.swift */; };
|
||||
|
|
@ -141,7 +142,6 @@
|
|||
E8E98A9625D863D700EC89A0 /* InstallationStepDetailView.swift in Sources */ = {isa = PBXBuildFile; fileRef = E8E98A9525D863D700EC89A0 /* InstallationStepDetailView.swift */; };
|
||||
E8F44A1E296B4CD7002D6592 /* Path in Frameworks */ = {isa = PBXBuildFile; productRef = E8F44A1D296B4CD7002D6592 /* Path */; };
|
||||
E8FA00542B5B109800769CE0 /* com.xcodesorg.xcodesapp.Helper in Copy Helper */ = {isa = PBXBuildFile; fileRef = CA9FF8AE2595967A00E47BAF /* com.xcodesorg.xcodesapp.Helper */; settings = {ATTRIBUTES = (CodeSignOnCopy, ); }; };
|
||||
E8FD5727291EE4AC001E004C /* AsyncNetworkService in Frameworks */ = {isa = PBXBuildFile; productRef = E8FD5726291EE4AC001E004C /* AsyncNetworkService */; };
|
||||
/* End PBXBuildFile section */
|
||||
|
||||
/* Begin PBXContainerItemProxy section */
|
||||
|
|
@ -229,7 +229,6 @@
|
|||
CA452BAF259FD9770072DFA4 /* ProgressIndicator.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ProgressIndicator.swift; sourceTree = "<group>"; };
|
||||
CA452BBF259FDDFE0072DFA4 /* Stub-version.plist */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.plist.xml; path = "Stub-version.plist"; sourceTree = "<group>"; };
|
||||
CA452BEA25A236500072DFA4 /* Stub-0.0.0.Info.plist */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.plist.xml; path = "Stub-0.0.0.Info.plist"; sourceTree = "<group>"; };
|
||||
CA538A0C255A4F1A00E64DD7 /* AppleAPI */ = {isa = PBXFileReference; lastKnownFileType = folder; name = AppleAPI; path = Xcodes/AppleAPI; sourceTree = "<group>"; };
|
||||
CA5D781D257365D6008EDE9D /* PinCodeTextView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = PinCodeTextView.swift; sourceTree = "<group>"; };
|
||||
CA61A6DF259835580008926E /* Xcode.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = Xcode.swift; sourceTree = "<group>"; };
|
||||
CA735108257BF96D00EA9CF8 /* AttributedText.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = AttributedText.swift; sourceTree = "<group>"; };
|
||||
|
|
@ -358,15 +357,15 @@
|
|||
33027E342CA8C18800CB387C /* LibFido2Swift in Frameworks */,
|
||||
CABFA9E42592F08E00380FEE /* Version in Frameworks */,
|
||||
CABFA9FD2592F13300380FEE /* LegibleError in Frameworks */,
|
||||
E89CBD3D2D5FB25A0037ED95 /* AppleAPI in Frameworks */,
|
||||
E689540325BE8C64000EBCEA /* DockProgress in Frameworks */,
|
||||
CA9FF86D25951C6E00E47BAF /* XCModel in Frameworks */,
|
||||
CABFA9F82592F0F900380FEE /* KeychainAccess in Frameworks */,
|
||||
E83FDC442CBB649100679C6B /* Sparkle in Frameworks */,
|
||||
E862D43B2CC8B26F00BAA376 /* SRP in Frameworks */,
|
||||
CAA858CD25A3D8BC00ACF8C0 /* ErrorHandling in Frameworks */,
|
||||
E89CBD382D5FAB950037ED95 /* XcodesLoginKit in Frameworks */,
|
||||
E8C0EB1A291EF43E0081528A /* XcodesKit in Frameworks */,
|
||||
E8FD5727291EE4AC001E004C /* AsyncNetworkService in Frameworks */,
|
||||
CAA1CB2D255A5262003FD669 /* AppleAPI in Frameworks */,
|
||||
CABFA9EE2592F0CC00380FEE /* SwiftSoup in Frameworks */,
|
||||
E84E4F572B335094003F3959 /* OrderedCollections in Frameworks */,
|
||||
E8F44A1E296B4CD7002D6592 /* Path in Frameworks */,
|
||||
|
|
@ -585,7 +584,6 @@
|
|||
CA8FB61C256E115700469DA5 /* .github */,
|
||||
CA9FF9252595A7EB00E47BAF /* Scripts */,
|
||||
CA9FF8242594F10700E47BAF /* AcknowledgementsGenerator */,
|
||||
CA538A0C255A4F1A00E64DD7 /* AppleAPI */,
|
||||
CAD2E7A02449574E00113D76 /* Xcodes */,
|
||||
CAD2E7B62449575100113D76 /* XcodesTests */,
|
||||
CA9FF8AF2595967A00E47BAF /* com.xcodesorg.xcodesapp.Helper */,
|
||||
|
|
@ -715,7 +713,6 @@
|
|||
);
|
||||
name = Xcodes;
|
||||
packageProductDependencies = (
|
||||
CAA1CB2C255A5262003FD669 /* AppleAPI */,
|
||||
CABFA9E32592F08E00380FEE /* Version */,
|
||||
CABFA9ED2592F0CC00380FEE /* SwiftSoup */,
|
||||
CABFA9F72592F0F900380FEE /* KeychainAccess */,
|
||||
|
|
@ -723,13 +720,14 @@
|
|||
CA9FF86C25951C6E00E47BAF /* XCModel */,
|
||||
CAA858CC25A3D8BC00ACF8C0 /* ErrorHandling */,
|
||||
E689540225BE8C64000EBCEA /* DockProgress */,
|
||||
E8FD5726291EE4AC001E004C /* AsyncNetworkService */,
|
||||
E8C0EB19291EF43E0081528A /* XcodesKit */,
|
||||
E8F44A1D296B4CD7002D6592 /* Path */,
|
||||
E84E4F562B335094003F3959 /* OrderedCollections */,
|
||||
E83FDC432CBB649100679C6B /* Sparkle */,
|
||||
334A932B2CA885A400A5E079 /* LibFido2Swift */,
|
||||
E862D43A2CC8B26F00BAA376 /* SRP */,
|
||||
E89CBD372D5FAB950037ED95 /* XcodesLoginKit */,
|
||||
E89CBD3C2D5FB25A0037ED95 /* AppleAPI */,
|
||||
);
|
||||
productName = XcodesMac;
|
||||
productReference = CAD2E79E2449574E00113D76 /* Xcodes.app */;
|
||||
|
|
@ -814,11 +812,11 @@
|
|||
CAA858CB25A3D8BC00ACF8C0 /* XCRemoteSwiftPackageReference "ErrorHandling" */,
|
||||
CAC28186259EE27200B8AB0B /* XCRemoteSwiftPackageReference "CombineExpectations" */,
|
||||
E689540125BE8C64000EBCEA /* XCRemoteSwiftPackageReference "DockProgress" */,
|
||||
E8FD5725291EE4AC001E004C /* XCRemoteSwiftPackageReference "AsyncHTTPNetworkService" */,
|
||||
E8F44A1C296B4CD7002D6592 /* XCRemoteSwiftPackageReference "Path" */,
|
||||
E84E4F552B335094003F3959 /* XCRemoteSwiftPackageReference "swift-collections" */,
|
||||
E83FDC422CBB649100679C6B /* XCRemoteSwiftPackageReference "Sparkle" */,
|
||||
33027E282CA8BB5800CB387C /* XCRemoteSwiftPackageReference "LibFido2Swift" */,
|
||||
E89CBD362D5FAB950037ED95 /* XCRemoteSwiftPackageReference "XcodesLoginKit" */,
|
||||
E89CBD3B2D5FB25A0037ED95 /* XCLocalSwiftPackageReference "Xcodes/AppleAPI" */,
|
||||
);
|
||||
productRefGroup = CAD2E79F2449574E00113D76 /* Products */;
|
||||
projectDirPath = "";
|
||||
|
|
@ -1487,15 +1485,14 @@
|
|||
};
|
||||
/* End XCConfigurationList section */
|
||||
|
||||
/* Begin XCRemoteSwiftPackageReference section */
|
||||
33027E282CA8BB5800CB387C /* XCRemoteSwiftPackageReference "LibFido2Swift" */ = {
|
||||
isa = XCRemoteSwiftPackageReference;
|
||||
repositoryURL = "https://github.com/kinoroy/LibFido2Swift.git";
|
||||
requirement = {
|
||||
kind = upToNextMinorVersion;
|
||||
minimumVersion = 0.1.0;
|
||||
};
|
||||
/* Begin XCLocalSwiftPackageReference section */
|
||||
E89CBD3B2D5FB25A0037ED95 /* XCLocalSwiftPackageReference "Xcodes/AppleAPI" */ = {
|
||||
isa = XCLocalSwiftPackageReference;
|
||||
relativePath = Xcodes/AppleAPI;
|
||||
};
|
||||
/* End XCLocalSwiftPackageReference section */
|
||||
|
||||
/* Begin XCRemoteSwiftPackageReference section */
|
||||
CA9FF86B25951C6E00E47BAF /* XCRemoteSwiftPackageReference "data" */ = {
|
||||
isa = XCRemoteSwiftPackageReference;
|
||||
repositoryURL = "https://github.com/xcodereleases/data";
|
||||
|
|
@ -1576,6 +1573,14 @@
|
|||
minimumVersion = 1.0.5;
|
||||
};
|
||||
};
|
||||
E89CBD362D5FAB950037ED95 /* XCRemoteSwiftPackageReference "XcodesLoginKit" */ = {
|
||||
isa = XCRemoteSwiftPackageReference;
|
||||
repositoryURL = "https://github.com/XcodesOrg/XcodesLoginKit";
|
||||
requirement = {
|
||||
branch = main;
|
||||
kind = branch;
|
||||
};
|
||||
};
|
||||
E8F44A1C296B4CD7002D6592 /* XCRemoteSwiftPackageReference "Path" */ = {
|
||||
isa = XCRemoteSwiftPackageReference;
|
||||
repositoryURL = "https://github.com/mxcl/Path.swift";
|
||||
|
|
@ -1584,14 +1589,6 @@
|
|||
minimumVersion = 1.0.0;
|
||||
};
|
||||
};
|
||||
E8FD5725291EE4AC001E004C /* XCRemoteSwiftPackageReference "AsyncHTTPNetworkService" */ = {
|
||||
isa = XCRemoteSwiftPackageReference;
|
||||
repositoryURL = "https://github.com/RobotsAndPencils/AsyncHTTPNetworkService";
|
||||
requirement = {
|
||||
branch = main;
|
||||
kind = branch;
|
||||
};
|
||||
};
|
||||
/* End XCRemoteSwiftPackageReference section */
|
||||
|
||||
/* Begin XCSwiftPackageProductDependency section */
|
||||
|
|
@ -1604,10 +1601,6 @@
|
|||
package = CA9FF86B25951C6E00E47BAF /* XCRemoteSwiftPackageReference "data" */;
|
||||
productName = XCModel;
|
||||
};
|
||||
CAA1CB2C255A5262003FD669 /* AppleAPI */ = {
|
||||
isa = XCSwiftPackageProductDependency;
|
||||
productName = AppleAPI;
|
||||
};
|
||||
CAA858CC25A3D8BC00ACF8C0 /* ErrorHandling */ = {
|
||||
isa = XCSwiftPackageProductDependency;
|
||||
package = CAA858CB25A3D8BC00ACF8C0 /* XCRemoteSwiftPackageReference "ErrorHandling" */;
|
||||
|
|
@ -1657,6 +1650,15 @@
|
|||
isa = XCSwiftPackageProductDependency;
|
||||
productName = SRP;
|
||||
};
|
||||
E89CBD372D5FAB950037ED95 /* XcodesLoginKit */ = {
|
||||
isa = XCSwiftPackageProductDependency;
|
||||
package = E89CBD362D5FAB950037ED95 /* XCRemoteSwiftPackageReference "XcodesLoginKit" */;
|
||||
productName = XcodesLoginKit;
|
||||
};
|
||||
E89CBD3C2D5FB25A0037ED95 /* AppleAPI */ = {
|
||||
isa = XCSwiftPackageProductDependency;
|
||||
productName = AppleAPI;
|
||||
};
|
||||
E8C0EB19291EF43E0081528A /* XcodesKit */ = {
|
||||
isa = XCSwiftPackageProductDependency;
|
||||
productName = XcodesKit;
|
||||
|
|
@ -1666,11 +1668,6 @@
|
|||
package = E8F44A1C296B4CD7002D6592 /* XCRemoteSwiftPackageReference "Path" */;
|
||||
productName = Path;
|
||||
};
|
||||
E8FD5726291EE4AC001E004C /* AsyncNetworkService */ = {
|
||||
isa = XCSwiftPackageProductDependency;
|
||||
package = E8FD5725291EE4AC001E004C /* XCRemoteSwiftPackageReference "AsyncHTTPNetworkService" */;
|
||||
productName = AsyncNetworkService;
|
||||
};
|
||||
/* End XCSwiftPackageProductDependency section */
|
||||
};
|
||||
rootObject = CAD2E7962449574E00113D76 /* Project object */;
|
||||
|
|
|
|||
|
|
@ -3,10 +3,10 @@
|
|||
"pins": [
|
||||
{
|
||||
"package": "AsyncNetworkService",
|
||||
"repositoryURL": "https://github.com/RobotsAndPencils/AsyncHTTPNetworkService",
|
||||
"repositoryURL": "https://github.com/XcodesOrg/AsyncHTTPNetworkService",
|
||||
"state": {
|
||||
"branch": "main",
|
||||
"revision": "97770856c4e429f880d4b4dd68cfaf286dc00c30",
|
||||
"revision": "12e225af8b5dc25afcfabfcf582a165b0581ab19",
|
||||
"version": null
|
||||
}
|
||||
},
|
||||
|
|
@ -78,8 +78,8 @@
|
|||
"repositoryURL": "https://github.com/kinoroy/LibFido2Swift.git",
|
||||
"state": {
|
||||
"branch": null,
|
||||
"revision": "b77e5c6451bea69d15615d6578936b11777d9a6c",
|
||||
"version": "0.1.2"
|
||||
"revision": "94d496d6f850dcbb3e8c4a27cd7eeabfad9f14e3",
|
||||
"version": "0.1.4"
|
||||
}
|
||||
},
|
||||
{
|
||||
|
|
@ -144,6 +144,15 @@
|
|||
"revision": "087c91fedc110f9f833b14ef4c32745dabca8913",
|
||||
"version": "1.0.3"
|
||||
}
|
||||
},
|
||||
{
|
||||
"package": "XcodesLoginKit",
|
||||
"repositoryURL": "https://github.com/XcodesOrg/XcodesLoginKit",
|
||||
"state": {
|
||||
"branch": "main",
|
||||
"revision": "3a6f2b82c47aea17c510f0326849734a08a74eae",
|
||||
"version": null
|
||||
}
|
||||
}
|
||||
]
|
||||
},
|
||||
|
|
|
|||
|
|
@ -2,6 +2,7 @@ import Combine
|
|||
import Foundation
|
||||
import Path
|
||||
import AppleAPI
|
||||
import XcodesLoginKit
|
||||
import Version
|
||||
import LegibleError
|
||||
import os.log
|
||||
|
|
|
|||
|
|
@ -1,9 +1,10 @@
|
|||
import Foundation
|
||||
import XcodesKit
|
||||
import AppleAPI
|
||||
import OSLog
|
||||
import Combine
|
||||
import Path
|
||||
import AppleAPI
|
||||
import XcodesLoginKit
|
||||
import Version
|
||||
|
||||
extension AppState {
|
||||
|
|
|
|||
|
|
@ -4,7 +4,7 @@ import Path
|
|||
import Version
|
||||
import SwiftSoup
|
||||
import struct XCModel.Xcode
|
||||
import AppleAPI
|
||||
import XcodesLoginKit
|
||||
import XcodesKit
|
||||
|
||||
extension AppState {
|
||||
|
|
|
|||
|
|
@ -1,5 +1,5 @@
|
|||
import AppKit
|
||||
import AppleAPI
|
||||
import XcodesLoginKit
|
||||
import Combine
|
||||
import Path
|
||||
import LegibleError
|
||||
|
|
@ -9,7 +9,6 @@ import Version
|
|||
import os.log
|
||||
import DockProgress
|
||||
import XcodesKit
|
||||
import LibFido2Swift
|
||||
|
||||
enum PreferenceKey: String {
|
||||
case installPath
|
||||
|
|
@ -31,7 +30,7 @@ enum PreferenceKey: String {
|
|||
}
|
||||
|
||||
class AppState: ObservableObject {
|
||||
private let client = AppleAPI.Client()
|
||||
private let client = XcodesLoginKit.Client()
|
||||
internal let runtimeService = RuntimeService()
|
||||
|
||||
// MARK: - Published Properties
|
||||
|
|
@ -258,50 +257,40 @@ class AppState: ObservableObject {
|
|||
}
|
||||
|
||||
func signInIfNeeded() -> AnyPublisher<Void, Error> {
|
||||
validateSession()
|
||||
.catch { (error) -> AnyPublisher<Void, Error> in
|
||||
guard
|
||||
let username = self.savedUsername,
|
||||
let password = try? Current.keychain.getString(username)
|
||||
else {
|
||||
return Fail(error: error)
|
||||
.eraseToAnyPublisher()
|
||||
}
|
||||
|
||||
return self.signIn(username: username, password: password)
|
||||
.map { _ in Void() }
|
||||
.eraseToAnyPublisher()
|
||||
}
|
||||
.eraseToAnyPublisher()
|
||||
return validateSession()
|
||||
// .catch { (error) -> AnyPublisher<Void, Error> in
|
||||
// guard
|
||||
// let username = self.savedUsername,
|
||||
// let password = try? Current.keychain.getString(username)
|
||||
// else {
|
||||
// return Fail(error: error)
|
||||
// .eraseToAnyPublisher()
|
||||
// }
|
||||
//
|
||||
// return self.signIn(username: username, password: password)
|
||||
// //.map { _ in Void() }
|
||||
// .eraseToAnyPublisher()
|
||||
// }
|
||||
// .eraseToAnyPublisher()
|
||||
}
|
||||
|
||||
func signIn(username: String, password: String) {
|
||||
authError = nil
|
||||
signIn(username: username, password: password)
|
||||
.sink(
|
||||
receiveCompletion: { _ in },
|
||||
receiveValue: { _ in }
|
||||
)
|
||||
.store(in: &cancellables)
|
||||
}
|
||||
|
||||
func signIn(username: String, password: String) -> AnyPublisher<AuthenticationState, Error> {
|
||||
try? Current.keychain.set(password, key: username)
|
||||
Current.defaults.set(username, forKey: "username")
|
||||
|
||||
isProcessingAuthRequest = true
|
||||
return client.srpLogin(accountName: username, password: password)
|
||||
.receive(on: DispatchQueue.main)
|
||||
.handleEvents(
|
||||
receiveOutput: { authenticationState in
|
||||
self.authenticationState = authenticationState
|
||||
},
|
||||
receiveCompletion: { completion in
|
||||
self.handleAuthenticationFlowCompletion(completion)
|
||||
self.isProcessingAuthRequest = false
|
||||
}
|
||||
)
|
||||
.eraseToAnyPublisher()
|
||||
|
||||
Task { @MainActor in
|
||||
do {
|
||||
let authenticationState = try await client.srpLogin(accountName: username, password: password)
|
||||
handleAuthenticationFlowCompletion(authenticationState)
|
||||
isProcessingAuthRequest = false
|
||||
} catch {
|
||||
Logger.appState.error("Error signing in: \(error, privacy: .public)")
|
||||
authError = error
|
||||
self.isProcessingAuthRequest = false
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
func handleTwoFactorOption(_ option: TwoFactorOption, authOptions: AuthOptionsResponse, serviceKey: String, sessionID: String, scnt: String) {
|
||||
|
|
@ -314,21 +303,18 @@ class AppState: ObservableObject {
|
|||
|
||||
func requestSMS(to trustedPhoneNumber: AuthOptionsResponse.TrustedPhoneNumber, authOptions: AuthOptionsResponse, sessionData: AppleSessionData) {
|
||||
isProcessingAuthRequest = true
|
||||
client.requestSMSSecurityCode(to: trustedPhoneNumber, authOptions: authOptions, sessionData: sessionData)
|
||||
.receive(on: DispatchQueue.main)
|
||||
.sink(
|
||||
receiveCompletion: { completion in
|
||||
self.handleAuthenticationFlowCompletion(completion)
|
||||
self.isProcessingAuthRequest = false
|
||||
},
|
||||
receiveValue: { authenticationState in
|
||||
self.authenticationState = authenticationState
|
||||
if case let AuthenticationState.waitingForSecondFactor(option, authOptions, sessionData) = authenticationState {
|
||||
self.handleTwoFactorOption(option, authOptions: authOptions, serviceKey: sessionData.serviceKey, sessionID: sessionData.sessionID, scnt: sessionData.scnt)
|
||||
}
|
||||
}
|
||||
)
|
||||
.store(in: &cancellables)
|
||||
Task {
|
||||
do {
|
||||
let authenticationState = try await client.requestSMSSecurityCode(to: trustedPhoneNumber, authOptions: authOptions, sessionData: sessionData)
|
||||
self.handleAuthenticationFlowCompletion(authenticationState)
|
||||
self.isProcessingAuthRequest = false
|
||||
|
||||
} catch {
|
||||
Logger.appState.error("Error requesting SMS: \(error, privacy: .public)")
|
||||
authError = error
|
||||
self.isProcessingAuthRequest = false
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
func choosePhoneNumberForSMS(authOptions: AuthOptionsResponse, sessionData: AppleSessionData) {
|
||||
|
|
@ -341,101 +327,67 @@ class AppState: ObservableObject {
|
|||
|
||||
func submitSecurityCode(_ code: SecurityCode, sessionData: AppleSessionData) {
|
||||
isProcessingAuthRequest = true
|
||||
client.submitSecurityCode(code, sessionData: sessionData)
|
||||
.receive(on: DispatchQueue.main)
|
||||
.sink(
|
||||
receiveCompletion: { completion in
|
||||
self.handleAuthenticationFlowCompletion(completion)
|
||||
self.isProcessingAuthRequest = false
|
||||
},
|
||||
receiveValue: { authenticationState in
|
||||
self.authenticationState = authenticationState
|
||||
}
|
||||
)
|
||||
.store(in: &cancellables)
|
||||
}
|
||||
|
||||
var fido2: FIDO2?
|
||||
|
||||
func createAndSubmitSecurityKeyAssertationWithPinCode(_ pinCode: String, sessionData: AppleSessionData, authOptions: AuthOptionsResponse) {
|
||||
self.presentedSheet = .securityKeyTouchToConfirm
|
||||
|
||||
guard let fsaChallenge = authOptions.fsaChallenge else {
|
||||
// This shouldn't happen
|
||||
// we shouldn't have called this method without setting the fsaChallenge
|
||||
// so this is an assertionFailure
|
||||
assertionFailure()
|
||||
self.authError = "Something went wrong. Please file a bug report"
|
||||
return
|
||||
}
|
||||
|
||||
// The challenge is encoded in Base64URL encoding
|
||||
let challengeUrl = fsaChallenge.challenge
|
||||
let challenge = FIDO2.base64urlToBase64(base64url: challengeUrl)
|
||||
let origin = "https://idmsa.apple.com"
|
||||
let rpId = "apple.com"
|
||||
// Allowed creds is sent as a comma separated string
|
||||
let validCreds = fsaChallenge.allowedCredentials.split(separator: ",").map(String.init)
|
||||
|
||||
Task {
|
||||
do {
|
||||
let fido2 = FIDO2()
|
||||
self.fido2 = fido2
|
||||
let response = try fido2.respondToChallenge(args: ChallengeArgs(rpId: rpId, validCredentials: validCreds, devPin: pinCode, challenge: challenge, origin: origin))
|
||||
|
||||
Task { @MainActor in
|
||||
self.isProcessingAuthRequest = true
|
||||
}
|
||||
|
||||
let respData = try JSONEncoder().encode(response)
|
||||
client.submitChallenge(response: respData, sessionData: AppleSessionData(serviceKey: sessionData.serviceKey, sessionID: sessionData.sessionID, scnt: sessionData.scnt))
|
||||
.receive(on: DispatchQueue.main)
|
||||
.handleEvents(
|
||||
receiveOutput: { authenticationState in
|
||||
self.authenticationState = authenticationState
|
||||
},
|
||||
receiveCompletion: { completion in
|
||||
self.handleAuthenticationFlowCompletion(completion)
|
||||
self.isProcessingAuthRequest = false
|
||||
}
|
||||
).sink(
|
||||
receiveCompletion: { _ in },
|
||||
receiveValue: { _ in }
|
||||
).store(in: &cancellables)
|
||||
} catch FIDO2Error.canceledByUser {
|
||||
// User cancelled the auth flow
|
||||
// we don't have to show an error
|
||||
// because the sheet will already be dismissed
|
||||
let authenticationState = try await client.submitSecurityCode(code, sessionData: sessionData)
|
||||
self.handleAuthenticationFlowCompletion(authenticationState)
|
||||
self.isProcessingAuthRequest = false
|
||||
} catch {
|
||||
Logger.appState.error("ERROR SUBMITTING SECURITYCODE: \(error, privacy: .public)")
|
||||
authError = error
|
||||
self.isProcessingAuthRequest = false
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
func createAndSubmitSecurityKeyAssertationWithPinCode(_ pinCode: String, sessionData: AppleSessionData, authOptions: AuthOptionsResponse) {
|
||||
isProcessingAuthRequest = true
|
||||
self.presentedSheet = .securityKeyTouchToConfirm
|
||||
|
||||
Task {
|
||||
do {
|
||||
let authenticationState = try await client.submitSecurityKeyPinCode(pinCode, sessionData: sessionData, authOptions: authOptions)
|
||||
self.handleAuthenticationFlowCompletion(authenticationState)
|
||||
self.isProcessingAuthRequest = false
|
||||
|
||||
} catch {
|
||||
print("ERROR Requesting SMS: \(error)")
|
||||
authError = error
|
||||
self.isProcessingAuthRequest = false
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
func cancelSecurityKeyAssertationRequest() {
|
||||
self.fido2?.cancel()
|
||||
self.client.cancelSecurityKeyAssertationRequest()
|
||||
}
|
||||
|
||||
private func handleAuthenticationFlowCompletion(_ completion: Subscribers.Completion<Error>) {
|
||||
switch completion {
|
||||
case let .failure(error):
|
||||
// remove saved username and any stored keychain password if authentication fails so it doesn't try again.
|
||||
clearLoginCredentials()
|
||||
Logger.appState.error("Authentication error: \(error.legibleDescription)")
|
||||
self.authError = error
|
||||
case .finished:
|
||||
switch self.authenticationState {
|
||||
case .authenticated, .unauthenticated, .notAppleDeveloper:
|
||||
self.presentedSheet = nil
|
||||
case let .waitingForSecondFactor(option, authOptions, sessionData):
|
||||
self.handleTwoFactorOption(option, authOptions: authOptions, serviceKey: sessionData.serviceKey, sessionID: sessionData.sessionID, scnt: sessionData.scnt)
|
||||
}
|
||||
|
||||
private func handleAuthenticationFlowCompletion(_ authenticationState: AuthenticationState) {
|
||||
self.authenticationState = authenticationState
|
||||
|
||||
switch authenticationState {
|
||||
case .unauthenticated:
|
||||
authError = AuthenticationError.notAuthorized
|
||||
case let .waitingForSecondFactor(twoFactorOption, authOptionsResponse, appleSessionData):
|
||||
self.presentedSheet = .twoFactor(.init(
|
||||
option: twoFactorOption,
|
||||
authOptions: authOptionsResponse,
|
||||
sessionData: AppleSessionData(serviceKey: appleSessionData.serviceKey, sessionID: appleSessionData.sessionID, scnt: appleSessionData.scnt)
|
||||
))
|
||||
case .authenticated(let appleSession):
|
||||
Logger.appState.info("SUCCESSFULLY LOGGED IN - WELCOME: \(appleSession.user.fullName ?? "")")
|
||||
self.presentedSheet = nil
|
||||
break
|
||||
case .notAppleDeveloper:
|
||||
authError = AuthenticationError.notDeveloperAppleId
|
||||
}
|
||||
}
|
||||
|
||||
func signOut() {
|
||||
clearLoginCredentials()
|
||||
AppleAPI.Current.network.session.configuration.httpCookieStorage?.removeCookies(since: .distantPast)
|
||||
// TODO FIX ME
|
||||
//client.signout()
|
||||
authenticationState = .unauthenticated
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -2,6 +2,7 @@ import Combine
|
|||
import Foundation
|
||||
import Path
|
||||
import AppleAPI
|
||||
import XcodesLoginKit
|
||||
import KeychainAccess
|
||||
import XcodesKit
|
||||
/**
|
||||
|
|
|
|||
|
|
@ -1,5 +1,5 @@
|
|||
import Foundation
|
||||
import AppleAPI
|
||||
import XcodesLoginKit
|
||||
|
||||
enum XcodesSheet: Identifiable {
|
||||
case signIn
|
||||
|
|
|
|||
|
|
@ -117,7 +117,7 @@ struct MainWindow: View {
|
|||
|
||||
@ViewBuilder
|
||||
private func signInView() -> some View {
|
||||
if appState.authenticationState == .authenticated {
|
||||
if case .authenticated(_) = appState.authenticationState {
|
||||
VStack {
|
||||
SignedInView()
|
||||
.padding(32)
|
||||
|
|
|
|||
|
|
@ -1,4 +1,4 @@
|
|||
import AppleAPI
|
||||
import XcodesLoginKit
|
||||
import SwiftUI
|
||||
import Path
|
||||
|
||||
|
|
|
|||
|
|
@ -1,4 +1,4 @@
|
|||
import AppleAPI
|
||||
import XcodesLoginKit
|
||||
import SwiftUI
|
||||
|
||||
struct DownloadPreferencePane: View {
|
||||
|
|
|
|||
|
|
@ -1,4 +1,4 @@
|
|||
import AppleAPI
|
||||
import XcodesLoginKit
|
||||
import Path
|
||||
import SwiftUI
|
||||
|
||||
|
|
|
|||
|
|
@ -1,4 +1,4 @@
|
|||
import AppleAPI
|
||||
import XcodesLoginKit
|
||||
import SwiftUI
|
||||
|
||||
struct GeneralPreferencePane: View {
|
||||
|
|
@ -7,7 +7,7 @@ struct GeneralPreferencePane: View {
|
|||
var body: some View {
|
||||
VStack(alignment: .leading) {
|
||||
GroupBox(label: Text("AppleID")) {
|
||||
if appState.authenticationState == .authenticated {
|
||||
if case .authenticated(_) = appState.authenticationState {
|
||||
SignedInView()
|
||||
} else {
|
||||
Button("SignIn", action: { self.appState.presentedSheet = .signIn })
|
||||
|
|
|
|||
|
|
@ -1,4 +1,4 @@
|
|||
import AppleAPI
|
||||
import XcodesLoginKit
|
||||
import Sparkle
|
||||
import SwiftUI
|
||||
|
||||
|
|
|
|||
|
|
@ -1,5 +1,5 @@
|
|||
import SwiftUI
|
||||
import AppleAPI
|
||||
import XcodesLoginKit
|
||||
|
||||
struct SignIn2FAView: View {
|
||||
@EnvironmentObject var appState: AppState
|
||||
|
|
|
|||
|
|
@ -1,4 +1,4 @@
|
|||
import AppleAPI
|
||||
import XcodesLoginKit
|
||||
import SwiftUI
|
||||
|
||||
struct SignInPhoneListView: View {
|
||||
|
|
|
|||
|
|
@ -1,5 +1,5 @@
|
|||
import SwiftUI
|
||||
import AppleAPI
|
||||
import XcodesLoginKit
|
||||
|
||||
struct SignInSMSView: View {
|
||||
@EnvironmentObject var appState: AppState
|
||||
|
|
|
|||
|
|
@ -7,7 +7,7 @@
|
|||
//
|
||||
|
||||
import SwiftUI
|
||||
import AppleAPI
|
||||
import XcodesLoginKit
|
||||
|
||||
struct SignInSecurityKeyPinView: View {
|
||||
@EnvironmentObject var appState: AppState
|
||||
|
|
|
|||
|
|
@ -7,7 +7,7 @@
|
|||
//
|
||||
|
||||
import SwiftUI
|
||||
import AppleAPI
|
||||
import XcodesLoginKit
|
||||
|
||||
struct SignInSecurityKeyTouchView: View {
|
||||
@EnvironmentObject var appState: AppState
|
||||
|
|
|
|||
|
|
@ -1,4 +1,4 @@
|
|||
{\rtf1\ansi\ansicpg1252\cocoartf2818
|
||||
{\rtf1\ansi\ansicpg1252\cocoartf2821
|
||||
\cocoatextscaling0\cocoaplatform0{\fonttbl\f0\fnil\fcharset0 .SFNS-Regular;}
|
||||
{\colortbl;\red255\green255\blue255;}
|
||||
{\*\expandedcolortbl;;}
|
||||
|
|
|
|||
|
|
@ -237,6 +237,16 @@
|
|||
}
|
||||
}
|
||||
},
|
||||
"%@ (%@)" : {
|
||||
"localizations" : {
|
||||
"en" : {
|
||||
"stringUnit" : {
|
||||
"state" : "new",
|
||||
"value" : "%1$@ (%2$@)"
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
"%@ %@ %@" : {
|
||||
"localizations" : {
|
||||
"ar" : {
|
||||
|
|
|
|||
|
|
@ -14,7 +14,7 @@ let package = Package(
|
|||
],
|
||||
dependencies: [
|
||||
// Dependencies declare other packages that this package depends on.
|
||||
.package(url: "https://github.com/RobotsAndPencils/AsyncHTTPNetworkService", branch: "main"),
|
||||
.package(url: "https://github.com/XcodesOrg/AsyncHTTPNetworkService", branch: "main"),
|
||||
.package(url: "https://github.com/mxcl/Path.swift", from: "1.0.0"),
|
||||
],
|
||||
targets: [
|
||||
|
|
|
|||
|
|
@ -1,4 +1,4 @@
|
|||
import AppleAPI
|
||||
import XcodesLoginKit
|
||||
import Combine
|
||||
import CombineExpectations
|
||||
import Path
|
||||
|
|
|
|||
Loading…
Reference in a new issue