public async Task <bool> IsUserNameAvailable([FromQuery] string userName)
        {
            if (string.IsNullOrEmpty(userName))
            {
                return(false);
            }

            if (!userName.Contains("@"))
            {
                try
                {
                    var formatedPhoneNumber = PhoneNumberHelpers.GetFormatedPhoneNumber(userName);
                    userName = formatedPhoneNumber;
                }
                catch (Exception)
                {
                }
            }

            return((await _accountService.FindByUserNameAsync(userName)) == null);
        }
Example #2
0
        public async Task ResetPasswordByPhoneNumber(PhoneNumberResetPassword model)
        {
            string formatedPhoneNumber = PhoneNumberHelpers.GetFormatedPhoneNumber(model.PhoneNumber);
            var    account             = await CheckExsitByPhoneNumberAsync(formatedPhoneNumber);

            if (account == null)
            {
                throw new CustomException(Errors.ACCOUNT_NOT_FOUND, Errors.ACCOUNT_NOT_FOUND_MSG);
            }

            var verification = account.VerificationCodes.FirstOrDefault(t => t.SetPhoneNumber == formatedPhoneNumber && t.Purpose == VerificationPurpose.Password && t.Checked);

            if (verification == null)
            {
                throw new CustomException(Errors.PIN_NOT_VERIFY, Errors.PIN_NOT_VERIFY_MSG);
            }

            account.Password      = _pwdHasher.HashPassword(account, model.NewPassword);
            account.SecurityStamp = GenerateSecurityStamp();
            account.ModifiedAt    = DateTime.Now;

            await _context.SaveChangesAsync();
        }
        public async Task RequestResetPassword([FromQuery] string phoneNumber)
        {
            if (string.IsNullOrEmpty(phoneNumber))
            {
                throw new CustomException(Errors.INVALID_PHONE_NUMBER, Errors.INVALID_PHONE_NUMBER_MSG);
            }

            phoneNumber = PhoneNumberHelpers.GetFormatedPhoneNumber(phoneNumber);
            var account = await _accountService.CheckExsitByPhoneNumberAsync(phoneNumber);

            if (account == null)
            {
                throw new CustomException(Errors.ACCOUNT_NOT_FOUND, Errors.ACCOUNT_NOT_FOUND_MSG);
            }

            var verification = account.VerificationCodes.FirstOrDefault(t => t.SetPhoneNumber == phoneNumber && t.Purpose == VerificationPurpose.Password && !t.Checked);

            if (verification == null)
            {
                verification = new VerificationCode
                {
                    Account        = account,
                    ExpiredAt      = DateTime.Now.AddDays(1),
                    Purpose        = VerificationPurpose.Password,
                    SetPhoneNumber = phoneNumber,
                    VerifyCode     = CommonFunctions.GenerateVerificationCode(true)
                };

                await _verificationService.CreateAsync(verification);
            }

            string smsContent = $"Verification code at JobHop: {verification.VerifyCode}";

            //send SMS using eSMS.vn
            await _esmsService.SendSMS(account.PhoneNumber, smsContent, 4);
        }
        /// <summary>
        /// Get verification for phone number that is not expired
        /// </summary>
        /// <param name="phoneNumber"></param>
        /// <returns></returns>
        public async Task <VerificationCode> GetVerificationCodeFromPhoneNumberAsync(string phoneNumber, VerificationPurpose purpose)
        {
            string formatedPhoneNumber = PhoneNumberHelpers.GetFormatedPhoneNumber(phoneNumber);

            return(await _context.VerificationCodes.FirstOrDefaultAsync(a => a.SetPhoneNumber == formatedPhoneNumber && a.Purpose == purpose && !a.Checked));
        }
Example #5
0
        private async Task GenerateToken(HttpContext context)
        {
            var username = context.Request.Form["username"].ToString();
            var password = context.Request.Form["password"].ToString();

            var _accountService  = (IAccountService)context.RequestServices.GetService(typeof(IAccountService));
            var _verifyService   = (IVerificationService)context.RequestServices.GetService(typeof(IVerificationService));
            var _rawRabbitClient = (IBusClient)context.RequestServices.GetService(typeof(IBusClient));

            //if username is not an email
            if (username != null && !username.Contains("@"))
            {
                //try to format username as internationlazition phone number
                try
                {
                    //try to format with expectation that user filled country code
                    username = PhoneNumberHelpers.GetFormatedPhoneNumber(username);
                }
                catch (NumberParseException)
                {
                    //the username user provide is not an email or valid phone number
                    context.Response.ContentType = "application/json";
                    context.Response.StatusCode  = 400;
                    await context.Response.WriteAsync(JsonConvert.SerializeObject(new
                    {
                        Code    = Errors.INCORRECT_LOGIN,
                        Custom  = Errors.INVALID_PHONE_NUMBER,
                        Message = Errors.INCORRECT_LOGIN_MSG
                    }, Formatting.Indented));

                    return;
                }
            }

            var identity = await _accountService.CheckAsync(username, password);

            //response if account null or inactive
            if (identity == null || identity.Status == UserStatus.InActive || (identity.AccountType == AccountType.Jobseeker && username.Contains("@")))
            {
                context.Response.ContentType = "application/json";
                context.Response.StatusCode  = 400;
                var code    = Errors.INCORRECT_LOGIN;
                var message = Errors.INCORRECT_LOGIN_MSG;
                if (identity != null && identity.Status == UserStatus.InActive)
                {
                    code    = Errors.ACCOUNT_INACTIVE;
                    message = Errors.ACCOUNT_INACTIVE_MSG;
                }

                await context.Response.WriteAsync(JsonConvert.SerializeObject(new
                {
                    Code    = code,
                    Message = message
                }, Formatting.Indented));

                return;
            }

            if (identity.AccountType == AccountType.Jobseeker && !identity.PhoneNumberVerified)
            {
                context.Response.ContentType = "application/json";
                context.Response.StatusCode  = 400;

                //1 account has only 1 verification => get first
                var verification = (await _verifyService.GetVerificationsOfAccount(identity.Id)).FirstOrDefault();

                //account is locked because exceeded limit of retried or resend times
                if (verification.Retry >= VerificationService.MAX_RETRY || verification.Resend > VerificationService.MAX_RESEND)
                {
                    await context.Response.WriteAsync(JsonConvert.SerializeObject(new
                    {
                        Code    = Errors.VERIFICATION_LOCKED,
                        Message = Errors.VERIFICATION_LOCKED_MSG
                    }, Formatting.Indented));
                }
                else //wait for verification
                {
                    await context.Response.WriteAsync(JsonConvert.SerializeObject(new
                    {
                        Code    = Errors.WAIT_FOR_VERIFICATION,
                        Message = Errors.WAIT_FOR_VERIFICATION_MSG
                    }, Formatting.Indented));
                }
                return;
            }

            //add banana reward for first login in day
            if (identity.AccountType == AccountType.Jobseeker)
            {
                var tracker = await _accountService.AddTracker(new LoginTracker { Account = identity, LoginAt = DateTime.Now });

                if (tracker != null)
                {
                    await _rawRabbitClient.PublishAsync(new AccountLoggedIn { AccountId = identity.Id, LoginAt = tracker.LoginAt });
                }
            }

            var permissions = await _accountService.GetPermissionsOfAccountAsync(identity.Id);

            var now = DateTime.Now;

            var encodedJwt = TokenProviderMiddleware.GenerateAccessToken(_options, now, identity.UserName, identity.Id.ToString(), permissions.ToArray());

            var response = new SignInResponseModel
            {
                AccessToken = encodedJwt,
                Expires     = now.AddSeconds((int)_options.Expiration.TotalSeconds),
                Account     = identity.ToViewModel()
            };

            // Serialize and return the response
            context.Response.ContentType = "application/json";
            await context.Response.WriteAsync(JsonConvert.SerializeObject(response, new JsonSerializerSettings
            {
                Formatting = Formatting.Indented
            }));
        }
        public async Task <AccountViewModel> FacebookRegister([FromBody] FacebookRegisterModel model)
        {
            if (model == null || !ModelState.IsValid)
            {
                throw new CustomException(Errors.INVALID_REQUEST, Errors.INVALID_REQUEST_MSG);
            }

            try
            {
                //standardize phone number
                var formatedPhoneNumber = PhoneNumberHelpers.GetFormatedPhoneNumber(model.PhoneNumber);
                model.PhoneNumber = formatedPhoneNumber;
            }
            catch (NumberParseException)
            {
                throw new CustomException(Errors.INVALID_PHONE_NUMBER, Errors.INVALID_PHONE_NUMBER_MSG);
            }

            var verifyResult = await this.VerifyFacebookAccessToken(model.AccessToken);

            if (verifyResult.IsValid)
            {
                var existAccount = await _accountService.FindByExternalProviderAsync("facebook", verifyResult.FacebookId);

                if (existAccount != null)
                {
                    throw new CustomException(Errors.EXTERNAL_LOGIN_EXIST, Errors.EXTERNAL_LOGIN_EXIST_MSG);
                }

                var account = new Account
                {
                    UserName       = model.PhoneNumber,
                    PhoneNumber    = model.PhoneNumber,
                    AccountType    = JobHop.Common.Enums.AccountType.Jobseeker,
                    ExternalLogins = new List <ExternalProvider>()
                    {
                        new ExternalProvider
                        {
                            Provider    = "Facebook",
                            ProviderKey = verifyResult.FacebookId
                        }
                    },
                    AccountPermissions = new List <Models.AccountPermission>()
                    {
                        new Models.AccountPermission
                        {
                            PermissionId = PermissionsList.JOBSEEKER_PERMISSION
                        }
                    }
                };

                account = await _accountService.CreateAsync(account, null, true);


                //publish a jobseeker account is created message to rabbit mq bus
                await _rawRabbitBus.PublishAsync(new JobseekerAccountCreated
                {
                    Id          = account.Id,
                    PhoneNumber = account.PhoneNumber,
                    Avatar      = model.Avatar,
                    FirstName   = model.FirstName,
                    LastName    = model.LastName,
                    Status      = account.Status
                });

                string smsContent = $"Verification code at JobHop: {account.VerificationCodes.First().VerifyCode}";

                //send SMS using Twillio
                //var message = await MessageResource.CreateAsync(to: new Twilio.Types.PhoneNumber(account.PhoneNumber), from: new Twilio.Types.PhoneNumber(_twilioOptions.FromNumber), body: smsContent);

                //send SMS using eSMS.vn
                var response = await _esmsService.SendSMS(account.PhoneNumber, smsContent, 4);

                var viewModel = account.ToViewModel();

                return(viewModel);
            }
            else
            {
                throw new CustomException(Errors.INVALID_REQUEST, Errors.INVALID_REQUEST_MSG);
            }
        }