public virtual async Task <AuthEventEnum> VerifyNewEmailAsync(string newEmail) { if (CurrentChallenge != AuthChallengeEnum.NewEmail) { return(AuthEventEnum.Alert_VerifyCalledButNoChallengeFound); } if (!CheckEmailFormat(newEmail)) { return(AuthEventEnum.Alert_EmailFormatRequirementsFailed); } try { switch (CurrentAuthProcess) { case AuthProcessEnum.UpdatingEmail: if (!IsSignedIn) { return(AuthEventEnum.Alert_NeedToBeSignedIn); } // Get the current values on the server. // This step may throw an exception in RefreshUserDetailsAsync. There seems to be // no way to recover from this other than retry or abandon the process. Let the // calling class figure out what is right for their usecase. AuthEventEnum refreshUserDetailsResult = await RefreshUserDetailsAsync().ConfigureAwait(false); if (refreshUserDetailsResult != AuthEventEnum.Alert_RefreshUserDetailsDone) { return(AuthEventEnum.Alert_CantRetrieveUserDetails); } // make sure the values are different if (this.email.Equals(newEmail)) //todo - check { return(AuthEventEnum.Alert_EmailAddressIsTheSame); } // Update the user email on the server // This may throw an exception in the UpdateAttributesAsync call. var attributes = new Dictionary <string, string>() { { "email", newEmail } }; // Cognito sends a auth code when the Email attribute is changed await CognitoUser.UpdateAttributesAsync(attributes).ConfigureAwait(false); AuthChallengeList.Remove(AuthChallengeEnum.NewEmail); IsEmailVerified = true; return(await NextChallenge()); default: return(AuthEventEnum.Alert_InternalProcessError); } } catch (TooManyRequestsException) { return(AuthEventEnum.Alert_TooManyAttempts); } catch (TooManyFailedAttemptsException) { return(AuthEventEnum.Alert_TooManyAttempts); } catch (Exception e) { Debug.WriteLine($"UpdateEmail() threw an exception {e}"); return(AuthEventEnum.Alert_Unknown); } }