Esempio n. 1
0
        public virtual async Task <AuthEventEnum> VerifyNewPasswordAsync(string newPassword)
        {
            if (CurrentChallenge != AuthChallengeEnum.NewPassword)
            {
                return(AuthEventEnum.Alert_VerifyCalledButNoChallengeFound);
            }

            if (!CheckNewPasswordFormat(newPassword))
            {
                return(AuthEventEnum.Alert_PasswordFormatRequirementsFailed);
            }

            try
            {
                switch (CurrentAuthProcess)
                {
                case AuthProcessEnum.SigningUp:
                    authFlowResponse = await CognitoUser.RespondToNewPasswordRequiredAsync(
                        new RespondToNewPasswordRequiredRequest()
                    {
                        SessionID   = authFlowResponse.SessionID,
                        NewPassword = newPassword
                    }
                        ).ConfigureAwait(false);

                    this.newPassword = newPassword;
                    AuthChallengeList.Remove(AuthChallengeEnum.NewPassword);
                    return(await NextChallenge());

                case AuthProcessEnum.ResettingPassword:
                    this.newPassword = newPassword;
                    CognitoUser user = new CognitoUser(login, clientId, userPool, providerClient);
                    await user.ForgotPasswordAsync().ConfigureAwait(false);

                    AuthChallengeList.Remove(AuthChallengeEnum.NewPassword);
                    AuthChallengeList.Add(AuthChallengeEnum.Code);
                    return(await NextChallenge());

                case AuthProcessEnum.UpdatingPassword:
                    this.newPassword = newPassword;
                    AuthChallengeList.Remove(AuthChallengeEnum.NewPassword);
                    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);
            }
        }
Esempio n. 2
0
        public virtual async Task <AuthEventEnum> VerifyEmailAsync(string email)
        {
            if (CurrentChallenge != AuthChallengeEnum.Email)
            {
                return(AuthEventEnum.Alert_VerifyCalledButNoChallengeFound);
            }

            if (!CheckEmailFormat(email))
            {
                return(AuthEventEnum.Alert_EmailFormatRequirementsFailed);
            }

            await Init();

            try
            {
                switch (CurrentAuthProcess)
                {
                case AuthProcessEnum.SigningUp:
                    IsEmailVerified = true;
                    this.email      = email;
                    AuthChallengeList.Remove(AuthChallengeEnum.Email);
                    return(await NextChallenge());

                default:
                    return(AuthEventEnum.Alert_InternalProcessError);
                }
            }
            catch (Exception e)
            {
                Debug.WriteLine($"UpdateEmail() threw an exception {e}");
                return(AuthEventEnum.Alert_Unknown);
            }
        }
Esempio n. 3
0
        public virtual async Task <AuthEventEnum> VerifyLoginAsync(string login)
        {
            if (CurrentChallenge != AuthChallengeEnum.Login)
            {
                return(AuthEventEnum.Alert_VerifyCalledButNoChallengeFound);
            }

            if (!CheckLoginFormat(login))
            {
                return(AuthEventEnum.Alert_LoginFormatRequirementsFailed);
            }

            await Init();

            try
            {
                switch (CurrentAuthProcess)
                {
                case AuthProcessEnum.SigningIn:
                    if (IsSignedIn)
                    {
                        return(AuthEventEnum.Alert_AlreadySignedIn);
                    }
                    this.login      = login;
                    IsLoginVerified = true;
                    AuthChallengeList.Remove(AuthChallengeEnum.Login);
                    return(await NextChallenge());

                case AuthProcessEnum.SigningUp:
                    if (IsSignedIn)
                    {
                        return(AuthEventEnum.Alert_AlreadySignedIn);
                    }
                    this.login      = login;
                    IsLoginVerified = true;
                    AuthChallengeList.Remove(AuthChallengeEnum.Login);
                    return(await NextChallenge());

                case AuthProcessEnum.ResettingPassword:
                    if (IsSignedIn)
                    {
                        return(AuthEventEnum.Alert_InvalidOperationWhenSignedIn);
                    }
                    this.login      = login;
                    IsLoginVerified = true;
                    AuthChallengeList.Remove(AuthChallengeEnum.Login);
                    return(await NextChallenge());

                default:
                    return(AuthEventEnum.Alert_InternalProcessError);
                }
            }
            catch (Exception e)
            {
                Debug.WriteLine($"VerifyLogin() threw an exception {e}");
                return(AuthEventEnum.Alert_Unknown);
            }
        }
Esempio n. 4
0
 public virtual void InternalClearAsync()
 {
     ClearSensitiveFields();
     CognitoUser = null;
     AuthChallengeList.Clear();
     authFlowResponse   = null;
     IsSignedIn         = false;
     CurrentAuthProcess = AuthProcessEnum.None;
 }
Esempio n. 5
0
        public virtual async Task <AuthEventEnum> StartUpdateEmailAsync()
        {
            await Init();

            if (!IsSignedIn)
            {
                return(AuthEventEnum.Alert_NeedToBeSignedIn);
            }

            CurrentAuthProcess = AuthProcessEnum.UpdatingEmail;
            AuthChallengeList.Add(AuthChallengeEnum.NewEmail);
            return(AuthEventEnum.AuthChallenge);
        }
Esempio n. 6
0
        public virtual async Task <AuthEventEnum> VerifyNewPasswordAsync(string newPassword)
        {
            if (CurrentChallenge != AuthChallengeEnum.NewPassword)
            {
                return(AuthEventEnum.Alert_VerifyCalledButNoChallengeFound);
            }

            if (!CheckPasswordFormat(newPassword))
            {
                return(AuthEventEnum.Alert_PasswordFormatRequirementsFailed);
            }

            await Init();

            try
            {
                switch (CurrentAuthProcess)
                {
                case AuthProcessEnum.SigningUp:
                    AuthChallengeList.Remove(AuthChallengeEnum.NewPassword);
                    return(await NextChallenge());

                case AuthProcessEnum.ResettingPassword:
                    this.newPassword = newPassword;
                    await jsModule.InvokeVoidAsync("LzAuth.forgotPassword", login);

                    AuthChallengeList.Remove(AuthChallengeEnum.NewPassword);
                    AuthChallengeList.Add(AuthChallengeEnum.Code);
                    return(await NextChallenge());

                case AuthProcessEnum.UpdatingPassword:
                    this.newPassword = newPassword;
                    await jsModule.InvokeVoidAsync("LzAuth.changePassword", password, newPassword);

                    AuthChallengeList.Remove(AuthChallengeEnum.NewPassword);
                    return(await NextChallenge());

                default:
                    return(AuthEventEnum.Alert_InternalProcessError);
                }
            }
            catch (JSException e)
            {
                return(GetAuthEventEnumForJsError(e));
            }
            catch (Exception e)
            {
                Debug.WriteLine($"VerifyPassword() threw an exception {e}");
                return(AuthEventEnum.Alert_Unknown);
            }
        }
Esempio n. 7
0
        public virtual async Task <AuthEventEnum> StartSignInAsync()
        {
            await Init();

            if (IsSignedIn)
            {
                return(AuthEventEnum.Alert_AlreadySignedIn);
            }

            InternalClearAsync();
            CurrentAuthProcess = AuthProcessEnum.SigningIn;
            AuthChallengeList.Add(AuthChallengeEnum.Login);
            AuthChallengeList.Add(AuthChallengeEnum.Password);
            return(AuthEventEnum.AuthChallenge);
        }
Esempio n. 8
0
        public virtual async Task <AuthEventEnum> StartResetPasswordAsync()
        {
            await Init();

            if (IsSignedIn)
            {
                return(AuthEventEnum.Alert_InvalidOperationWhenSignedIn);
            }

            CurrentAuthProcess = AuthProcessEnum.ResettingPassword;

            AuthChallengeList.Add(AuthChallengeEnum.Login);
            AuthChallengeList.Add(AuthChallengeEnum.NewPassword);
            return(AuthEventEnum.AuthChallenge);
        }
Esempio n. 9
0
        public virtual async Task <AuthEventEnum> VerifyNewPhoneAsync(string newPhone)
        {
            if (CurrentChallenge != AuthChallengeEnum.NewPhone)
            {
                return(AuthEventEnum.Alert_VerifyCalledButNoChallengeFound);
            }

            if (!CheckPhoneFormat(newPhone))
            {
                return(AuthEventEnum.Alert_PhoneFormatRequirementsFailed);
            }

            AuthChallengeList.Remove(AuthChallengeEnum.NewPhone);
            return(await NextChallenge());
        }
Esempio n. 10
0
        public virtual async Task <AuthEventEnum> StartUpdatePasswordAsync()
        {
            await Task.Delay(0);

            if (!IsSignedIn)
            {
                return(AuthEventEnum.Alert_NeedToBeSignedIn);
            }

            CurrentAuthProcess = AuthProcessEnum.UpdatingPassword;

            AuthChallengeList.Add(AuthChallengeEnum.Password);
            AuthChallengeList.Add(AuthChallengeEnum.NewPassword);
            return(AuthEventEnum.AuthChallenge);
        }
Esempio n. 11
0
        public virtual async Task <AuthEventEnum> StartSignUpAsync()
        {
            if (IsSignedIn)
            {
                return(AuthEventEnum.Alert_AlreadySignedIn);
            }

            await ClearAsync(); // calls Init() as well

            CurrentAuthProcess = AuthProcessEnum.SigningUp;

            AuthChallengeList.Add(AuthChallengeEnum.Login);
            AuthChallengeList.Add(AuthChallengeEnum.Password);
            AuthChallengeList.Add(AuthChallengeEnum.Email);
            return(AuthEventEnum.AuthChallenge);
        }
Esempio n. 12
0
        // Cancel the currently executing auth process
        public virtual async Task <AuthEventEnum> CancelAsync()
        {
            await Init();

            switch (CurrentAuthProcess)
            {
            case AuthProcessEnum.None:
            case AuthProcessEnum.SigningIn:
            case AuthProcessEnum.SigningUp:
            case AuthProcessEnum.ResettingPassword:
                InternalClearAsync();
                return(AuthEventEnum.Canceled);

            default:
                ClearSensitiveFields();
                AuthChallengeList.Clear();
                CurrentAuthProcess = AuthProcessEnum.None;
                return(AuthEventEnum.Canceled);
            }
        }
Esempio n. 13
0
        private async Task <AuthEventEnum> NextChallenge(AuthEventEnum lastAuthEventEnum = AuthEventEnum.AuthChallenge)
        {
            await Init();

            try
            {
                if (!HasChallenge)
                {
                    switch (CurrentAuthProcess)
                    {
                    case AuthProcessEnum.None:
                        return(AuthEventEnum.Alert_NothingToDo);

                    case AuthProcessEnum.ResettingPassword:

                        CurrentAuthProcess = AuthProcessEnum.None;
                        ClearSensitiveFields();
                        return(AuthEventEnum.PasswordResetDone);

                    case AuthProcessEnum.SigningUp:

                        if (HasChallenge)
                        {
                            return(AuthEventEnum.AuthChallenge);
                        }

                        if (!IsLoginFormatOk)
                        {
                            AuthChallengeList.Add(AuthChallengeEnum.Login);
                        }
                        else
                        if (!IsPasswordFormatOk)
                        {
                            AuthChallengeList.Add(AuthChallengeEnum.Password);
                        }
                        else
                        if (!IsEmailFormatOk)
                        {
                            AuthChallengeList.Add(AuthChallengeEnum.Email);
                        }

                        if (HasChallenge)
                        {
                            return(AuthEventEnum.AuthChallenge);
                        }

                        if (!IsCodeVerified)
                        {
                            // Request causes AWS to send Auth Code to user by email
                            var attr = new Dictionary <string, string>()
                            {
                                { "email", email }
                            };
                            await jsModule.InvokeVoidAsync("LzAuth.signUp", login, password, attr);

                            if (!AuthChallengeList.Contains(AuthChallengeEnum.Code))
                            {
                                AuthChallengeList.Add(AuthChallengeEnum.Code);
                            }

                            return(AuthEventEnum.AuthChallenge);
                        }

                        CurrentAuthProcess = AuthProcessEnum.None;
                        ClearSensitiveFields();
                        return(AuthEventEnum.SignedUp);

                    case AuthProcessEnum.SigningIn:
                        // await jsModule.InvokeVoidAsync("signIn", login, password);
                        await jsModule.InvokeVoidAsync("LzAuth.signIn", login, password);

                        IsSignedIn         = true;
                        CurrentAuthProcess = AuthProcessEnum.None;
                        ClearSensitiveFields();
                        return(AuthEventEnum.SignedIn);

                    case AuthProcessEnum.UpdatingEmail:
                        if (!IsCodeVerified)
                        {
                            AuthChallengeList.Add(AuthChallengeEnum.Code);
                            return(AuthEventEnum.VerificationCodeSent);
                        }

                        CurrentAuthProcess = AuthProcessEnum.None;
                        ClearSensitiveFields();
                        return(AuthEventEnum.EmailUpdateDone);

                    case AuthProcessEnum.UpdatingPassword:
                        await jsModule.InvokeVoidAsync("LzAuth.changePassword", password, newPassword);

                        CurrentAuthProcess = AuthProcessEnum.None;
                        ClearSensitiveFields();
                        return(AuthEventEnum.PasswordUpdateDone);

                    case AuthProcessEnum.UpdatingPhone:
                        CurrentAuthProcess = AuthProcessEnum.None;
                        ClearSensitiveFields();
                        return(AuthEventEnum.PhoneUpdateDone);
                    }
                }
            }
            catch (JSException ex)
            {
                var msg = ex.Message;
                Debug.WriteLine(ex.Message);
                //return GetAuthEventEnumForJsError(e);
            }
            catch (Exception e)
            {
                string message = e.Message;

                return(AuthEventEnum.Alert_Unknown);
            }

            return(lastAuthEventEnum);
        }
Esempio n. 14
0
        public virtual async Task <AuthEventEnum> VerifyCodeAsync(string code)
        {
            if (CurrentAuthProcess == AuthProcessEnum.None)
            {
                return(AuthEventEnum.Alert_NoActiveAuthProcess);
            }

            if (CurrentChallenge != AuthChallengeEnum.Code)
            {
                return(AuthEventEnum.Alert_VerifyCalledButNoChallengeFound);
            }

            await Init();

            try
            {
                switch (CurrentAuthProcess)
                {
                case AuthProcessEnum.None:
                    return(AuthEventEnum.Alert_InternalProcessError);

                case AuthProcessEnum.ResettingPassword:
                    // todo - call js
                    //await CognitoUser.ConfirmForgotPasswordAsync(code, newPassword).ConfigureAwait(false);
                    await jsModule.InvokeVoidAsync("LzAuth.forgotPasswordSubmit", login, code, newPassword);

                    AuthChallengeList.Remove(AuthChallengeEnum.Code);
                    return(await NextChallenge());

                case AuthProcessEnum.SigningUp:
                    await jsModule.InvokeVoidAsync("LzAuth.confirmSignUp", login, code);

                    IsCodeVerified = true;
                    AuthChallengeList.Remove(AuthChallengeEnum.Code);
                    return(await NextChallenge());

                case AuthProcessEnum.SigningIn:
                    if (authFlowResponse == null)     // authFlowResponse set during VerifyPassword
                    {
                        return(AuthEventEnum.Alert_InternalSignInError);
                    }
                    AuthChallengeList.Remove(AuthChallengeEnum.Code);
                    return(await NextChallenge());

                case AuthProcessEnum.UpdatingEmail:
                    await jsModule.InvokeVoidAsync("LzAuth.verifyCurrentUserAttributeSubmit", "email", code);

                    IsCodeVerified = true;
                    AuthChallengeList.Remove(AuthChallengeEnum.Code);
                    return(await NextChallenge());

                case AuthProcessEnum.UpdatingPhone:
                    return(AuthEventEnum.Alert_InternalProcessError);

                default:
                    return(AuthEventEnum.Alert_InternalProcessError);
                }
            }
            catch (JSException e)
            {
                return(GetAuthEventEnumForJsError(e));
            }
            catch (Exception e)
            {
                return(AuthEventEnum.Alert_Unknown);
            }
        }
Esempio n. 15
0
        public virtual async Task <AuthEventEnum> VerifyNewEmailAsync(string newEmail)
        {
            if (CurrentChallenge != AuthChallengeEnum.NewEmail)
            {
                return(AuthEventEnum.Alert_VerifyCalledButNoChallengeFound);
            }

            if (!CheckEmailFormat(newEmail))
            {
                return(AuthEventEnum.Alert_EmailFormatRequirementsFailed);
            }

            await Init();

            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
                    // Cognito sends a auth code when the Email attribute is changed
                    var attr = new Dictionary <string, string>()
                    {
                        { "email", newEmail }
                    };
                    await jsModule.InvokeVoidAsync("LzAuth.updateUserAttributes", attr);

                    AuthChallengeList.Remove(AuthChallengeEnum.NewEmail);
                    IsEmailVerified = true;
                    return(await NextChallenge());

                default:
                    return(AuthEventEnum.Alert_InternalProcessError);
                }
            }
            catch (JSException e)
            {
                return(GetAuthEventEnumForJsError(e));
            }
            catch (Exception e)
            {
                Debug.WriteLine($"UpdateEmail() threw an exception {e}");
                return(AuthEventEnum.Alert_Unknown);
            }
        }
Esempio n. 16
0
        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);
            }
        }
Esempio n. 17
0
        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);
            }
        }
Esempio n. 18
0
        public virtual async Task <AuthEventEnum> VerifyPasswordAsync(string password)
        {
            if (CurrentChallenge != AuthChallengeEnum.Password)
            {
                return(AuthEventEnum.Alert_VerifyCalledButNoChallengeFound);
            }

            if (!CheckPasswordFormat(password))
            {
                return(AuthEventEnum.Alert_PasswordFormatRequirementsFailed);
            }

            await Init();

            try
            {
                switch (CurrentAuthProcess)
                {
                case AuthProcessEnum.SigningIn:
                    if (IsSignedIn)
                    {
                        return(AuthEventEnum.Alert_AlreadySignedIn);
                    }
                    if (!IsLoginVerified)
                    {
                        return(AuthEventEnum.Alert_LoginMustBeSuppliedFirst);
                    }
                    this.password      = password;
                    IsPasswordVerified = true;
                    AuthChallengeList.Remove(AuthChallengeEnum.Password);
                    return(await NextChallenge());

                case AuthProcessEnum.SigningUp:
                    if (IsSignedIn)
                    {
                        return(AuthEventEnum.Alert_AlreadySignedIn);
                    }
                    this.password      = password;
                    IsPasswordVerified = true;
                    AuthChallengeList.Remove(AuthChallengeEnum.Password);
                    return(await NextChallenge());

                case AuthProcessEnum.UpdatingPassword:
                    if (!IsSignedIn)
                    {
                        return(AuthEventEnum.Alert_NeedToBeSignedIn);
                    }
                    this.password      = password;
                    IsPasswordVerified = true;
                    AuthChallengeList.Remove(AuthChallengeEnum.Password);
                    return(await NextChallenge());

                default:
                    return(AuthEventEnum.Alert_InternalProcessError);
                }
            }
            catch (Exception e)
            {
                Debug.WriteLine($"VerifyPassword() threw an exception {e}");
                return(AuthEventEnum.Alert_Unknown);
            }
        }
Esempio n. 19
0
        public virtual async Task <AuthEventEnum> VerifyCodeAsync(string code)
        {
            if (CurrentAuthProcess == AuthProcessEnum.None)
            {
                return(AuthEventEnum.Alert_NoActiveAuthProcess);
            }

            if (CurrentChallenge != AuthChallengeEnum.Code)
            {
                return(AuthEventEnum.Alert_VerifyCalledButNoChallengeFound);
            }

            try
            {
                switch (CurrentAuthProcess)
                {
                case AuthProcessEnum.None:
                    return(AuthEventEnum.Alert_InternalProcessError);

                case AuthProcessEnum.ResettingPassword:
                    await CognitoUser.ConfirmForgotPasswordAsync(code, newPassword).ConfigureAwait(false);

                    AuthChallengeList.Remove(AuthChallengeEnum.Code);
                    return(await NextChallenge());

                case AuthProcessEnum.SigningUp:
                    var result = await providerClient.ConfirmSignUpAsync(
                        new ConfirmSignUpRequest
                    {
                        ClientId         = clientId,
                        Username         = login,
                        ConfirmationCode = code
                    }).ConfigureAwait(false);

                    IsCodeVerified = true;
                    AuthChallengeList.Remove(AuthChallengeEnum.Code);
                    return(await NextChallenge());

                case AuthProcessEnum.SigningIn:
                    if (authFlowResponse == null)     // authFlowResponse set during VerifyPassword
                    {
                        return(AuthEventEnum.Alert_InternalSignInError);
                    }

                    authFlowResponse = await CognitoUser.RespondToSmsMfaAuthAsync(
                        new RespondToSmsMfaRequest()
                    {
                        SessionID = authFlowResponse.SessionID,
                        MfaCode   = code
                    }
                        ).ConfigureAwait(false);

                    AuthChallengeList.Remove(AuthChallengeEnum.Code);
                    return(await NextChallenge());

                case AuthProcessEnum.UpdatingEmail:
                    await CognitoUser.VerifyAttributeAsync("email", code).ConfigureAwait(false);

                    IsCodeVerified = true;
                    AuthChallengeList.Remove(AuthChallengeEnum.Code);
                    return(await NextChallenge());

                case AuthProcessEnum.UpdatingPhone:
                    return(AuthEventEnum.Alert_InternalProcessError);

                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 (CodeMismatchException) { return(AuthEventEnum.Alert_VerifyFailed); }
            catch (AliasExistsException) { return(AuthEventEnum.Alert_AccountWithThatEmailAlreadyExists); }
            catch (Exception e)
            {
                Debug.WriteLine($"VerifyCode() threw an exception {e}");
                CognitoUser = null;
                return(AuthEventEnum.Alert_Unknown);
            }
        }
Esempio n. 20
0
        private async Task <AuthEventEnum> NextChallenge(AuthEventEnum lastAuthEventEnum = AuthEventEnum.AuthChallenge)
        {
            try
            {
                if (!HasChallenge)
                {
                    switch (CurrentAuthProcess)
                    {
                    case AuthProcessEnum.None:
                        return(AuthEventEnum.Alert_NothingToDo);

                    case AuthProcessEnum.ResettingPassword:

                        CurrentAuthProcess = AuthProcessEnum.None;
                        ClearSensitiveFields();
                        return(AuthEventEnum.PasswordResetDone);

                    case AuthProcessEnum.SigningUp:

                        if (HasChallenge)
                        {
                            return(AuthEventEnum.AuthChallenge);
                        }

                        if (!IsLoginFormatOk)
                        {
                            AuthChallengeList.Add(AuthChallengeEnum.Login);
                        }
                        else
                        if (!IsPasswordFormatOk)
                        {
                            AuthChallengeList.Add(AuthChallengeEnum.Password);
                        }
                        else
                        if (!IsEmailFormatOk)
                        {
                            AuthChallengeList.Add(AuthChallengeEnum.Email);
                        }

                        if (HasChallenge)
                        {
                            return(AuthEventEnum.AuthChallenge);
                        }

                        if (!IsCodeVerified)
                        {
                            // Request Auth Code
                            var signUpRequest = new SignUpRequest()
                            {
                                ClientId = clientId,
                                Password = password,
                                Username = login
                            };

                            signUpRequest.UserAttributes.Add(
                                new AttributeType()
                            {
                                Name  = "email",
                                Value = email
                            });

                            // This call may throw an exception
                            var result = await providerClient.SignUpAsync(signUpRequest).ConfigureAwait(false);

                            if (!AuthChallengeList.Contains(AuthChallengeEnum.Code))
                            {
                                AuthChallengeList.Add(AuthChallengeEnum.Code);
                            }

                            return(AuthEventEnum.AuthChallenge);
                        }

                        CurrentAuthProcess = AuthProcessEnum.None;
                        ClearSensitiveFields();
                        return(AuthEventEnum.SignedUp);

                    case AuthProcessEnum.SigningIn:
                        if (authFlowResponse != null && authFlowResponse.ChallengeName == ChallengeNameType.NEW_PASSWORD_REQUIRED)     // Update Passsword
                        {
                            if (!AuthChallengeList.Contains(AuthChallengeEnum.NewPassword))
                            {
                                AuthChallengeList.Add(AuthChallengeEnum.NewPassword);
                            }
                            authFlowResponse = null;
                            return(AuthEventEnum.AuthChallenge);
                        }

                        // Grab JWT from login to User Pools to extract User Pool Identity
                        //var token = new JwtSecurityToken(jwtEncodedString: CognitoUser.SessionTokens.IdToken);
                        //UpIdentity = token.Claims.First(c => c.Type == "sub").Value; // JWT sub cliam contains User Pool Identity

                        //// Note: creates Identity Pool identity if it doesn't exist
                        Credentials = CognitoUser.GetCognitoAWSCredentials(identityPoolId, regionEndpoint);

                        IsSignedIn         = true;
                        CurrentAuthProcess = AuthProcessEnum.None;
                        ClearSensitiveFields();
                        return(AuthEventEnum.SignedIn);

                    case AuthProcessEnum.UpdatingEmail:
                        if (!IsCodeVerified)
                        {
                            AuthChallengeList.Add(AuthChallengeEnum.Code);
                            return(AuthEventEnum.VerificationCodeSent);
                        }

                        CurrentAuthProcess = AuthProcessEnum.None;
                        ClearSensitiveFields();
                        return(AuthEventEnum.EmailUpdateDone);

                    case AuthProcessEnum.UpdatingPassword:
                        await CognitoUser.ChangePasswordAsync(password, newPassword).ConfigureAwait(false);

                        CurrentAuthProcess = AuthProcessEnum.None;
                        ClearSensitiveFields();
                        return(AuthEventEnum.PasswordUpdateDone);

                    case AuthProcessEnum.UpdatingPhone:
                        CurrentAuthProcess = AuthProcessEnum.None;
                        ClearSensitiveFields();
                        return(AuthEventEnum.PhoneUpdateDone);
                    }
                }
            }
            catch (UsernameExistsException) { return(AuthEventEnum.Alert_LoginAlreadyUsed); }
            catch (InvalidParameterException) { return(AuthEventEnum.Alert_InternalProcessError); }
            catch (InvalidPasswordException) { return(AuthEventEnum.Alert_PasswordFormatRequirementsFailed); }
            catch (TooManyRequestsException) { return(AuthEventEnum.Alert_TooManyAttempts); }
            catch (TooManyFailedAttemptsException) { return(AuthEventEnum.Alert_TooManyAttempts); }
            catch (PasswordResetRequiredException) { return(AuthEventEnum.Alert_PasswordResetRequiredException); }
            catch (Exception e)
            {
                Debug.WriteLine($"SignUp() threw an exception {e}");
                return(AuthEventEnum.Alert_Unknown);
            }

            return(lastAuthEventEnum);
        }