Example #1
0
        public static Account CreateRecruiterModelToAccountModel(this CreateRecruiterModel model)
        {
            if (model == null)
            {
                return(null);
            }

            var account = new Account
            {
                AccountType = JobHop.Common.Enums.AccountType.Recruiter,
                Email       = model.Email,
                Status      = UserStatus.Active
            };


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

            return(account);
        }
 public bool IsValidPhoneNumber([FromQuery] string phoneNumber)
 {
     if (string.IsNullOrEmpty(phoneNumber))
     {
         return(false);
     }
     else
     {
         try
         {
             PhoneNumberHelpers.GetFormatedPhoneNumber(phoneNumber);
             return(true);
         }
         catch (NumberParseException)
         {
             return(false);
         }
     }
 }
        public async Task <AccountViewModel> Register([FromBody] RegisterModel model)
        {
            var account = model.RegisterModelToModel();

            if (account == null || !ModelState.IsValid)
            {
                throw new CustomException(Errors.INVALID_REGISTRATION_DATA, Errors.INVALID_REGISTRATION_DATA_MSG);
            }

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

            account.AccountPermissions = new List <Models.AccountPermission>()
            {
                new Models.AccountPermission
                {
                    PermissionId = PermissionsList.JOBSEEKER_PERMISSION
                }
            };

            account = await _accountService.CreateAsync(account, model.Password);

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

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

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

            var viewModel = account.ToViewModel();

            return(viewModel);
        }
        public async Task ResendVerifyCode([FromBody] SendVerificationCodeToPhoneNumberModel model)
        {
            var verification = await _verificationService.GetVerificationCodeFromPhoneNumberAsync(model.PhoneNumber, VerificationPurpose.RegistrationPhoneNumber);

            if (verification == null)
            {
                throw new CustomException(Errors.VERIFICATION_NOT_FOUND, Errors.VERIFICATION_NOT_FOUND_MSG);
            }
            // expired the verification if retried counter or resent counter exceeded limit
            // do not use >= for Resend because of we need increase Resend counter and expired immediatelly the verification
            else if (verification.Retry >= VerificationService.MAX_RETRY || verification.Resend > VerificationService.MAX_RESEND)
            {
                throw new CustomException(Errors.VERIFICATION_LOCKED, Errors.VERIFICATION_LOCKED_MSG);
            }
            else
            {
                if (verification.Resend == VerificationService.MAX_RESEND)
                {
                    await _verificationService.IncreaseResendCounter(verification.Id);

                    throw new CustomException(Errors.VERIFICATION_LOCKED, Errors.VERIFICATION_LOCKED_MSG);
                }
                else
                {
                    string smsContent = $"Verification code at JobHop: {verification.VerifyCode}";

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

                    if (response.IsSuccessStatusCode)
                    {
                        await _verificationService.IncreaseResendCounter(verification.Id);
                    }
                    else
                    {
                        throw new CustomException(response.StatusCode.ToString());
                    }
                }
            }
        }
        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 #6
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 #9
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);
            }
        }