Add Email/Terms/ReCaptcha into the Authentication flow

Replace ReCaptcha navigation delegate with a WKUserContentController.
Move callback property closures onto the MainActor.
Show a loading indicator whilst waiting for the authentication service to start.
Move nextUncompletedStage into FlowResult.
Handle text field actions during authentication.
Remove scroll view tweaks in server selection screen following EMS banner removal.
This commit is contained in:
Doug
2022-05-12 17:40:36 +01:00
committed by Doug
parent 02e5f0bf2e
commit 1b74f87b35
42 changed files with 635 additions and 263 deletions
@@ -144,7 +144,7 @@ class RegistrationWizard {
/// Perform the "m.login.email.identity" or "m.login.msisdn" stage.
///
/// - Parameter threePID the threePID to add to the account. If this is an email, the homeserver will send an email
/// - Parameter threePID: the threePID to add to the account. If this is an email, the homeserver will send an email
/// to validate it. For a msisdn a SMS will be sent.
func addThreePID(threePID: RegisterThreePID) async throws -> RegistrationResult {
state.currentThreePIDData = nil
@@ -168,15 +168,19 @@ class RegistrationWizard {
/// Useful to poll the homeserver when waiting for the email to be validated by the user.
/// Once the email is validated, this method will return successfully.
/// - Parameter delay How long to wait before sending the request.
func checkIfEmailHasBeenValidated(delay: TimeInterval) async throws -> RegistrationResult {
MXLog.failure("The delay on this method is no longer available. Move this to the object handling the polling.")
func checkIfEmailHasBeenValidated() async throws -> RegistrationResult {
guard let parameters = state.currentThreePIDData?.registrationParameters else {
MXLog.error("[RegistrationWizard] checkIfEmailHasBeenValidated: The current 3pid data hasn't been stored in the state.")
throw RegistrationError.missingThreePIDData
}
return try await performRegistrationRequest(parameters: parameters)
do {
return try await performRegistrationRequest(parameters: parameters)
} catch {
// An unauthorized error indicates that the user hasn't tapped the link yet.
guard isUnauthorized(error) else { throw error }
throw RegistrationError.waitingForThreePIDValidation
}
}
// MARK: - Private
@@ -237,8 +241,14 @@ class RegistrationWizard {
state.currentThreePIDData = ThreePIDData(threePID: threePID, registrationResponse: response, registrationParameters: parameters)
// Send the session id for the first time
return try await performRegistrationRequest(parameters: parameters)
do {
// Send the session id for the first time
return try await performRegistrationRequest(parameters: parameters)
} catch {
// An unauthorized error means that it was accepted and is awaiting validation.
guard isUnauthorized(error) else { throw error }
throw RegistrationError.waitingForThreePIDValidation
}
}
private func performRegistrationRequest(parameters: RegistrationParameters, isCreatingAccount: Bool = false) async throws -> RegistrationResult {
@@ -268,7 +278,13 @@ class RegistrationWizard {
/// Checks for a mandatory dummy stage and handles it automatically when possible.
private func handleMandatoryDummyStage(flowResult: FlowResult) async throws -> RegistrationResult {
// If the dummy stage is mandatory, do the dummy stage now
guard flowResult.missingStages.contains(where: { $0.isDummyAndMandatory }) else { return .flowResponse(flowResult) }
guard flowResult.missingStages.contains(where: { $0.isDummy && $0.isMandatory }) else { return .flowResponse(flowResult) }
return try await dummy()
}
/// Checks whether an error is an `M_UNAUTHORIZED` for handling third party ID responses.
private func isUnauthorized(_ error: Error) -> Bool {
guard let mxError = MXError(nsError: error) else { return false }
return mxError.errcode == kMXErrCodeStringUnauthorized
}
}