public async Task <IActionResult> ForgotPasswordAsync([FromBody] ForgotPasswordDTO ForgotPasswordDTO)
        {
            Guard.Against.NullItem(ForgotPasswordDTO);

            ApplicationUser applicationUser = await _userManager.FindByNameAsync(ForgotPasswordDTO.UserName);

            if (applicationUser == null)
            {
                return(NotFound(new { message = "No user found with such email, provide a valid email" }));
            }

            IList <UserLoginInfo> externalUserList = await _userManager.GetLoginsAsync(applicationUser);

            if (externalUserList.Count > 0)
            {
                return(StatusCode(401, new { message = "External users not authorized to change password, change password with the login-provider" }));
            }

            await _userManager.RemovePasswordAsync(applicationUser);

            IdentityResult changePasswordResult = await _userManager.AddPasswordAsync(applicationUser, ForgotPasswordDTO.NewPassword);

            if (!changePasswordResult.Succeeded)
            {
                return(BadRequest(new { message = changePasswordResult.GetIdentityResultErrorMessage() }));
            }

            return(Ok(new { message = "Password changed successfully" }));
        }
        public async Task <IActionResult> AddAdminAsync([FromBody] RegisterUserModelDTO RegisterModelDTO)
        {
            Guard.Against.NullItem(RegisterModelDTO);

            //Check for duplicate user-names and e-mail
            ApplicationUser foundUser = await _userManager.Users.Where(x => x.Email == RegisterModelDTO.UserEmail || x.UserName == RegisterModelDTO.UserName).FirstOrDefaultAsync();

            //Throw HTTP 409 Conflict then
            if (foundUser != null)
            {
                return(StatusCode(409, new { message = $"The username / email is already taken and is conflicting with other records, please give an unique username / email." }));
            }

            ApplicationUser applicationUser = new ApplicationUser
            {
                UserName       = RegisterModelDTO.UserName,
                Email          = RegisterModelDTO.UserEmail,
                FirstName      = RegisterModelDTO.FirstName,
                LastName       = RegisterModelDTO.LastName,
                PhoneNumber    = RegisterModelDTO.PhoneNumber,
                EmailConfirmed = false
            };

            //Create the admin now
            IdentityResult createResult = await _userManager.CreateAsync(applicationUser, RegisterModelDTO.Password);

            if (!createResult.Succeeded)
            {
                return(BadRequest(new { message = createResult.GetIdentityResultErrorMessage() }));
            }

            //Add admin to role
            await _userManager.AddToRoleAsync(applicationUser, UserType.Admin.ToString());

            //Generate JWT now
            string token = await _tokenManager.GenerateJWTAsync(applicationUser);

            EmailModel emailModel = new EmailModel
            {
                EmailTo = RegisterModelDTO.UserEmail,
                Body    = $"<html><body><a href='{_configSettings.URL.VerifyEmailURL}/{token}'>Click here to verify Email</a></body></html>",
                Subject = "Verify your Email"
            };

            //Send verify email to admin now
            await _emailManager.SendEmailAsync(emailModel);

            //Return HTTP 201 now
            return(StatusCode(201, new { message = $"Successfully added admin {RegisterModelDTO.UserName}." }));
        }
        public async Task <IActionResult> ChangePasswordAsync(string token, [FromBody] ChangePasswordDTO ChangePasswordModel)
        {
            Guard.Against.NullString(token);
            Guard.Against.NullItem <ChangePasswordDTO>(ChangePasswordModel);

            //Decode the token
            JwtSecurityToken decodedToken = _tokenProviderService.DecodeJWTAsync(token);

            if (decodedToken == null)
            {
                return(BadRequest(new { message = "Invalid token, please resend the change password request again to continue!" }));
            }

            string email = decodedToken.Claims.First(claims => claims.Type == "sub").Value;

            ApplicationUser applicationUser = await _userManager.FindByEmailAsync(email);

            if (applicationUser == null)
            {
                return(NotFound(new { message = "No user found for this email." }));
            }

            //Checking if the user can change password
            IList <UserLoginInfo> userLogins = await _userManager.GetLoginsAsync(applicationUser);

            if (userLogins.Count > 0)
            {
                return(StatusCode(401, new { message = "External accounts not authorized to change password in Visneto, please change password with your login-provider." }));
            }

            IdentityResult changePasswordResult = await _userManager.ChangePasswordAsync(applicationUser, ChangePasswordModel.OldPassword, ChangePasswordModel.NewPassword);

            if (!changePasswordResult.Succeeded)
            {
                return(BadRequest(new { message = changePasswordResult.GetIdentityResultErrorMessage() }));
            }

            return(Ok(new
            {
                message = "Password Changed Successfully!!",
                email
            }));
        }
        public async Task <IActionResult> RegisterAsync([FromBody] RegisterUserModelDTO RegisterUserModelDTO)
        {
            Guard.Against.NullItem(RegisterUserModelDTO);

            //Check for duplicate user-names and e-mail
            ApplicationUser foundUser = await _userManager.Users.Where(x => x.Email == RegisterUserModelDTO.UserEmail || x.UserName == RegisterUserModelDTO.UserName).FirstOrDefaultAsync();

            //Throw HTTP 409 Conflict then
            if (foundUser != null)
            {
                return(StatusCode(409, new { message = $"The username / email is already taken and is conflicting with other records, please give an unique username / email." }));
            }

            ApplicationUser applicationUser = new ApplicationUser
            {
                UserName       = RegisterUserModelDTO.UserName,
                Email          = RegisterUserModelDTO.UserEmail,
                FirstName      = RegisterUserModelDTO.FirstName,
                LastName       = RegisterUserModelDTO.LastName,
                PhoneNumber    = RegisterUserModelDTO.PhoneNumber,
                EmailConfirmed = false
            };

            IdentityResult createResult = await _userManager.CreateAsync(applicationUser, RegisterUserModelDTO.Password);

            //User creation failed because of some constraints
            if (!createResult.Succeeded)
            {
                return(BadRequest(new { message = createResult.GetIdentityResultErrorMessage() }));
            }

            await _signInManager.SignInAsync(applicationUser, false);

            await _userManager.AddToRoleAsync(applicationUser, UserType.User.ToString());

            //Generate JWT now
            string jwtToken = await _tokenManager.GenerateJWTAsync(applicationUser);

            //Send verify email now
            EmailModel emailModel = new EmailModel
            {
                EmailTo = RegisterUserModelDTO.UserEmail,
                Body    = $"<html><body><a href='{_configSettings.URL.VerifyEmailURL}/{jwtToken}'>Click here to verify Email</a><br></body></html>",
                Subject = "Verify your Email"
            };
            await _emailManager.SendEmailAsync(emailModel);

            ReferralCode referralCode = GenerateReferralCode(applicationUser.UserName, applicationUser.Id);
            await _referralCodeService.AddReferralCode(referralCode);

            //Send Referral code mail now
            emailModel.Body    = $"<html><body><fieldset><legend> Referral code for User - {applicationUser.UserName} </legend> {referralCode.RefCode} </fieldset></body></html>";
            emailModel.Subject = $"Visneto Referral Code for new user - {applicationUser.UserName}";
            await _emailManager.SendEmailAsync(emailModel);

            //Return HTTP 201 Created for new user
            return(StatusCode(201, new
            {
                role = UserType.User.ToString(),
                access_token = jwtToken,
                expires = 3600,
                email = string.Empty,
                user_name = RegisterUserModelDTO.UserName
            }));
        }
        public async Task <IActionResult> ExternalLoginAsync([FromBody] OAuthDTO AuthDTO)
        {
            Guard.Against.NullItem <OAuthDTO>(AuthDTO);

            JObject responseBody = new JObject();

            ApplicationUser applicationUserRegistered = await _userManager.FindByEmailAsync(AuthDTO.Email);

            ApplicationUser applicationExternalUser = await _userManager.FindByLoginAsync("Google", AuthDTO.ProviderKey);

            //user registered with same email id of Visneto registration
            if (applicationUserRegistered != null && applicationExternalUser == null)
            {
                return(StatusCode(401, new { message = "Already registered with Visneto. Cannot use Google SignIn credentials to login. Please use Visneto credentials to login." }));
            }


            //User is already registered with Visneto and Google
            if (applicationUserRegistered != null && applicationExternalUser != null)
            {
                string access_token = await _tokenManager.GenerateJWTAsync(applicationUserRegistered);

                IList <string> externalLoginUserRolesList = await _userManager.GetRolesAsync(applicationUserRegistered);

                if (externalLoginUserRolesList.Count > 0)
                {
                    responseBody.Add("role", JToken.FromObject(externalLoginUserRolesList[0]));
                }

                else
                {
                    return(StatusCode(401, new { message = $"Unauthorized, no roles for the user specified." }));
                }

                responseBody.Add("access_token", JToken.FromObject(access_token));
                responseBody.Add("expires", JToken.FromObject(3600));
                responseBody.Add("user_name", JToken.FromObject(applicationExternalUser.FirstName));
                responseBody.Add("provider", JToken.FromObject("Google"));
                return(Ok(responseBody));
            }

            //User is not registered with Visneto but Google
            ApplicationUser user = new ApplicationUser
            {
                UserName       = AuthDTO.Email,
                Email          = AuthDTO.Email,
                FirstName      = AuthDTO.DisplayName,
                EmailConfirmed = true
            };

            IdentityResult createUser = await _userManager.CreateAsync(user);

            if (!createUser.Succeeded)
            {
                return(BadRequest(new { message = createUser.GetIdentityResultErrorMessage() }));
            }

            user.ProfileImage = new ProfileImage
            {
                ProfileImageID  = Guid.NewGuid(),
                ProfileImageUrl = AuthDTO.ImageUrl,
                ContainerName   = String.Empty,
                ResourceName    = String.Empty
            };

            await _userManager.AddToRoleAsync(user, UserType.User.ToString());

            await _userManager.AddLoginAsync(user, new UserLoginInfo("Google", AuthDTO.ProviderKey, AuthDTO.DisplayName));

            string token = await _tokenManager.GenerateJWTAsync(user);

            //Generation of referral code
            ReferralCode referralCode = GenerateReferralCode(user.UserName, user.Id);
            await _referralCodeService.AddReferralCode(referralCode);

            //Send Referral code mail now
            EmailModel emailModel = new EmailModel
            {
                EmailTo = user.Email,
                Body    = $"<html><body><fieldset><legend> Referral code for User - {user.UserName} </legend> {referralCode.RefCode} </fieldset></body></html>",
                Subject = $"Visneto Referral Code for new user - {user.UserName}"
            };

            await _emailManager.SendEmailAsync(emailModel);

            responseBody.Add("access_token", JToken.FromObject(token));
            responseBody.Add("expires", JToken.FromObject(3600));
            responseBody.Add("user_name", JToken.FromObject(user.Email));
            responseBody.Add("provider", JToken.FromObject("Google"));
            responseBody.Add("role", JToken.FromObject(UserType.User.ToString()));
            return(StatusCode(201, responseBody));
        }