public virtual async Task <AuthEventEnum> VerifyPasswordAsync(string password) { if (CurrentChallenge != AuthChallengeEnum.Password) { return(AuthEventEnum.Alert_VerifyCalledButNoChallengeFound); } if (!CheckPasswordFormat(password)) { return(AuthEventEnum.Alert_PasswordFormatRequirementsFailed); } try { switch (CurrentAuthProcess) { case AuthProcessEnum.SigningIn: if (IsSignedIn) { return(AuthEventEnum.Alert_AlreadySignedIn); } // When using Cognito, we must have already verified login to create the CognitoUser // before we can collect password and attempt to sign in. if (!IsLoginVerified) { return(AuthEventEnum.Alert_LoginMustBeSuppliedFirst); } // This step may throw an exception in the AWS StartWithSrpAuthAsync call. // AWS exceptions for sign in are a bit hard to figure out in some cases. // Depending on the UserPool setup, AWS may request an auth code. This would be // detected and handled in the NextChallenge() call. authFlowResponse = await CognitoUser.StartWithSrpAuthAsync( new InitiateSrpAuthRequest() { Password = password } ).ConfigureAwait(false); this.password = password; IsPasswordVerified = true; AuthChallengeList.Remove(AuthChallengeEnum.Password); return(await NextChallenge()); case AuthProcessEnum.SigningUp: if (IsSignedIn) { return(AuthEventEnum.Alert_AlreadySignedIn); } // We don't expect this step to throw an exception this.password = password; IsPasswordVerified = true; AuthChallengeList.Remove(AuthChallengeEnum.Password); return(await NextChallenge()); case AuthProcessEnum.UpdatingPassword: if (!IsSignedIn) { return(AuthEventEnum.Alert_NeedToBeSignedIn); } // We don't expect this step to throw an exception this.password = password; IsPasswordVerified = true; AuthChallengeList.Remove(AuthChallengeEnum.Password); return(await NextChallenge()); default: return(AuthEventEnum.Alert_InternalProcessError); } } catch (InvalidPasswordException) { return(AuthEventEnum.Alert_PasswordFormatRequirementsFailed); } catch (TooManyRequestsException) { return(AuthEventEnum.Alert_TooManyAttempts); } catch (TooManyFailedAttemptsException) { return(AuthEventEnum.Alert_TooManyAttempts); } catch (NotAuthorizedException) { return(AuthEventEnum.Alert_NotAuthorized); } catch (UserNotFoundException) { return(AuthEventEnum.Alert_UserNotFound); } catch (UserNotConfirmedException) { return(AuthEventEnum.Alert_NotConfirmed); } catch (Exception e) { Debug.WriteLine($"VerifyPassword() threw an exception {e}"); CognitoUser = null; return(AuthEventEnum.Alert_Unknown); } }
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); } }
public virtual async Task <AuthEventEnum> VerifyLoginAsync(string login) { if (CurrentChallenge != AuthChallengeEnum.Login) { return(AuthEventEnum.Alert_VerifyCalledButNoChallengeFound); } if (!CheckLoginFormat(login)) { return(AuthEventEnum.Alert_LoginFormatRequirementsFailed); } try { switch (CurrentAuthProcess) { case AuthProcessEnum.SigningIn: if (IsSignedIn) { return(AuthEventEnum.Alert_AlreadySignedIn); } // We don't expect this to ever throw an exception as the AWS operation is local CognitoUser = new CognitoUser(login, clientId, userPool, providerClient); this.login = login; IsLoginVerified = true; AuthChallengeList.Remove(AuthChallengeEnum.Login); return(await NextChallenge()); case AuthProcessEnum.SigningUp: if (IsSignedIn) { return(AuthEventEnum.Alert_AlreadySignedIn); } // We don't expect this to ever throw an exception this.login = login; IsLoginVerified = true; AuthChallengeList.Remove(AuthChallengeEnum.Login); return(await NextChallenge()); case AuthProcessEnum.ResettingPassword: if (IsSignedIn) { return(AuthEventEnum.Alert_InvalidOperationWhenSignedIn); } // This step may throw an exception if the call to ForgotPasswordAsync fails. CognitoUser = new CognitoUser(login, clientId, userPool, providerClient); this.login = login; IsLoginVerified = true; AuthChallengeList.Remove(AuthChallengeEnum.Login); 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($"VerifyLogin() threw an exception {e}"); CognitoUser = null; return(AuthEventEnum.Alert_Unknown); } }