mirror of
https://github.com/XcodesOrg/XcodesApp.git
synced 2026-04-26 14:57:37 +00:00
Merge pull request #129 from RobotsAndPencils/andrew/signInErrorHandling
Show sign in errors inline on sign in view
This commit is contained in:
commit
ffc7223a4d
4 changed files with 30 additions and 8 deletions
|
|
@ -36,6 +36,10 @@ public class Client {
|
||||||
case 401:
|
case 401:
|
||||||
return Fail(error: AuthenticationError.invalidUsernameOrPassword(username: accountName))
|
return Fail(error: AuthenticationError.invalidUsernameOrPassword(username: accountName))
|
||||||
.eraseToAnyPublisher()
|
.eraseToAnyPublisher()
|
||||||
|
case 403:
|
||||||
|
let errorMessage = responseBody.serviceErrors?.first?.description.replacingOccurrences(of: "-20209: ", with: "") ?? ""
|
||||||
|
return Fail(error: AuthenticationError.accountLocked(errorMessage))
|
||||||
|
.eraseToAnyPublisher()
|
||||||
case 409:
|
case 409:
|
||||||
return self.handleTwoStepOrFactor(data: data, response: response, serviceKey: serviceKey)
|
return self.handleTwoStepOrFactor(data: data, response: response, serviceKey: serviceKey)
|
||||||
case 412 where Client.authTypes.contains(responseBody.authType ?? ""):
|
case 412 where Client.authTypes.contains(responseBody.authType ?? ""):
|
||||||
|
|
@ -180,6 +184,7 @@ public enum AuthenticationError: Swift.Error, LocalizedError, Equatable {
|
||||||
case appleIDAndPrivacyAcknowledgementRequired
|
case appleIDAndPrivacyAcknowledgementRequired
|
||||||
case accountUsesTwoStepAuthentication
|
case accountUsesTwoStepAuthentication
|
||||||
case accountUsesUnknownAuthenticationKind(String?)
|
case accountUsesUnknownAuthenticationKind(String?)
|
||||||
|
case accountLocked(String)
|
||||||
case badStatusCode(statusCode: Int, data: Data, response: HTTPURLResponse)
|
case badStatusCode(statusCode: Int, data: Data, response: HTTPURLResponse)
|
||||||
|
|
||||||
public var errorDescription: String? {
|
public var errorDescription: String? {
|
||||||
|
|
@ -203,6 +208,8 @@ public enum AuthenticationError: Swift.Error, LocalizedError, Equatable {
|
||||||
return "Received a response from Apple that indicates this account has two-step authentication enabled. xcodes currently only supports the newer two-factor authentication, though. Please consider upgrading to two-factor authentication, or explain why this isn't an option for you by making a new feature request in the Help menu."
|
return "Received a response from Apple that indicates this account has two-step authentication enabled. xcodes currently only supports the newer two-factor authentication, though. Please consider upgrading to two-factor authentication, or explain why this isn't an option for you by making a new feature request in the Help menu."
|
||||||
case .accountUsesUnknownAuthenticationKind:
|
case .accountUsesUnknownAuthenticationKind:
|
||||||
return "Received a response from Apple that indicates this account has two-step or two-factor authentication enabled, but xcodes is unsure how to handle this response. If you continue to have problems, please submit a bug report in the Help menu."
|
return "Received a response from Apple that indicates this account has two-step or two-factor authentication enabled, but xcodes is unsure how to handle this response. If you continue to have problems, please submit a bug report in the Help menu."
|
||||||
|
case let .accountLocked(message):
|
||||||
|
return message
|
||||||
case let .badStatusCode(statusCode, _, _):
|
case let .badStatusCode(statusCode, _, _):
|
||||||
return "Received an unexpected status code: \(statusCode). If you continue to have problems, please submit a bug report in the Help menu."
|
return "Received an unexpected status code: \(statusCode). If you continue to have problems, please submit a bug report in the Help menu."
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -127,6 +127,7 @@ class AppState: ObservableObject {
|
||||||
}
|
}
|
||||||
|
|
||||||
func signIn(username: String, password: String) {
|
func signIn(username: String, password: String) {
|
||||||
|
authError = nil
|
||||||
signIn(username: username, password: password)
|
signIn(username: username, password: password)
|
||||||
.sink(
|
.sink(
|
||||||
receiveCompletion: { _ in },
|
receiveCompletion: { _ in },
|
||||||
|
|
|
||||||
|
|
@ -133,6 +133,7 @@ struct MainWindow: View {
|
||||||
.padding()
|
.padding()
|
||||||
} else {
|
} else {
|
||||||
SignInCredentialsView()
|
SignInCredentialsView()
|
||||||
|
.frame(width: 400)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -14,30 +14,42 @@ struct SignInCredentialsView: View {
|
||||||
Text("Apple ID:")
|
Text("Apple ID:")
|
||||||
.frame(minWidth: 100, alignment: .trailing)
|
.frame(minWidth: 100, alignment: .trailing)
|
||||||
TextField("example@icloud.com", text: $username)
|
TextField("example@icloud.com", text: $username)
|
||||||
.frame(width: 250)
|
|
||||||
}
|
}
|
||||||
HStack {
|
HStack {
|
||||||
Text("Password:")
|
Text("Password:")
|
||||||
.frame(minWidth: 100, alignment: .trailing)
|
.frame(minWidth: 100, alignment: .trailing)
|
||||||
SecureField("Required", text: $password)
|
SecureField("Required", text: $password)
|
||||||
.frame(width: 250)
|
}
|
||||||
|
if appState.authError != nil {
|
||||||
|
HStack {
|
||||||
|
Text("")
|
||||||
|
.frame(minWidth: 100)
|
||||||
|
Text(appState.authError?.legibleLocalizedDescription ?? "")
|
||||||
|
.fixedSize(horizontal: false, vertical: true)
|
||||||
|
.foregroundColor(.red)
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
HStack {
|
HStack {
|
||||||
Spacer()
|
Spacer()
|
||||||
Button("Cancel") { appState.presentedSheet = nil }
|
Button("Cancel") {
|
||||||
.keyboardShortcut(.cancelAction)
|
appState.authError = nil
|
||||||
ProgressButton(isInProgress: appState.isProcessingAuthRequest,
|
appState.presentedSheet = nil
|
||||||
action: { appState.signIn(username: username, password: password) }) {
|
|
||||||
Text("Next")
|
|
||||||
}
|
}
|
||||||
|
.keyboardShortcut(.cancelAction)
|
||||||
|
ProgressButton(
|
||||||
|
isInProgress: appState.isProcessingAuthRequest,
|
||||||
|
action: { appState.signIn(username: username, password: password) },
|
||||||
|
label: {
|
||||||
|
Text("Next")
|
||||||
|
}
|
||||||
|
)
|
||||||
.disabled(username.isEmpty || password.isEmpty)
|
.disabled(username.isEmpty || password.isEmpty)
|
||||||
.keyboardShortcut(.defaultAction)
|
.keyboardShortcut(.defaultAction)
|
||||||
}
|
}
|
||||||
.frame(height: 25)
|
.frame(height: 25)
|
||||||
}
|
}
|
||||||
.padding()
|
.padding()
|
||||||
.emittingError($appState.authError, recoveryHandler: { _ in })
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -45,5 +57,6 @@ struct SignInCredentialsView_Previews: PreviewProvider {
|
||||||
static var previews: some View {
|
static var previews: some View {
|
||||||
SignInCredentialsView()
|
SignInCredentialsView()
|
||||||
.environmentObject(AppState())
|
.environmentObject(AppState())
|
||||||
|
.previewLayout(.sizeThatFits)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
Loading…
Reference in a new issue