public async Task <IActionResult> SendNewSms()
        {
            SmsSession smsSession = _dbContext.smsSessions.Where(s => s.UserId == User.GetId())
                                    .OrderByDescending(s => s.Id)
                                    .Include(s => s.User)
                                    .Take(1)
                                    .FirstOrDefault();

            if (smsSession == null)
            {
                return(BadRequest(new { Messages = new[] { "Resending SMS is only available after registration." } }));
            }
            if (Math.Abs((smsSession.CreatedAt - DateTime.UtcNow).Minutes) < 1)
            {
                return(BadRequest(new { Messages = new[] { "SMS code has already been sent to you. To send a new one, wait a minute from the moment of sending the past." } }));
            }

            // Generate OTP
            long hotpCounter = _dbContext.GetHotpCounter();
            var  hotpCode    = hotp.ComputeHOTP(1 /*hotpCounter*/);

            //HttpStatusCode sendingResult = await _smsSender.SendSmsAsync(user.Phone, hotpCode);
            //if (sendingResult != HttpStatusCode.OK)
            //    return StatusCode(500, new { Message = "Error sending SMS code." });

            SmsSession newSmsSession = new SmsSession()
            {
                UserId = smsSession.User.Id, CodeHotpCounter = 1 /*hotpCode*/, CreatedAt = DateTime.UtcNow
            };

            _dbContext.smsSessions.Add(newSmsSession);
            await _dbContext.SaveChangesAsync();

            return(StatusCode(201, new { Message = "SMS with a verification code has been sent to your number." }));
        }
        public async Task <IActionResult> VerifyPhone([FromBody] SmsCodeModel model)
        {
            SmsSession smsSession = _dbContext.smsSessions.Where(s => s.UserId == User.GetId()).OrderBy(s => s.Id).LastOrDefault();

            if (smsSession == null)
            {
                return(NotFound(new { Messages = new[] { "SMS code was not sent to the phone number." } }));
            }
            if ((DateTime.UtcNow - smsSession.CreatedAt) > TimeSpan.FromMinutes(2))
            {
                return(BadRequest(new { Messages = new[] { "The previously sent code is out of date. Send a request to resend SMS." } }));
            }

            // Verify OTP
            smsSession.Attempts++;
            if (!hotp.VerifyHotp(model.Code, smsSession.CodeHotpCounter))
            {
                if (smsSession.Attempts >= 5)
                {
                    return(BadRequest(new { Messages = new[] { "The number of incorrect attempts to enter SMS code is exceeded. Send a request to resend SMS." } }));
                }

                await _dbContext.SaveChangesAsync();

                return(BadRequest(new { Messages = new[] { "Incorrect SMS code entered." } }));
            }

            smsSession.Checked = true;
            await _dbContext.SaveChangesAsync();

            return(Ok(new { AuthToken = IssueToken(TypeToken.Аuthorization, User.GetId()) }));
        }
        public Task <IActionResult> Registration([FromBody] RegistrModel model)
        {
            // Checking user existence
            User user = _dbContext.users.Where(u => u.Phone == model.Phone).FirstOrDefault();

            if (user == null)
            {
                return(BadRequest(new { Messages = new[] { "Incorrect phone or card number." } }));
            }

            // Verify PAN
            Card card = _dbContext.cards.Where(c => c.PAN == model.PAN).FirstOrDefault();

            if (!CheckCardNumber(model.PAN) || card == null || card.UserId != user.Id)
            {
                return(BadRequest(new { Messages = new[] { "Incorrect phone or card number." } }));
            }

            // Check if SMS was sent recently to this user
            SmsSession smsSession = _dbContext.smsSessions.Where(s => s.UserId == user.Id)
                                    .OrderByDescending(s => s.Id)
                                    .Include(s => s.User)
                                    .Take(1)
                                    .FirstOrDefault();

            if (smsSession != null)
            {
                if (Math.Abs((smsSession.CreatedAt - DateTime.UtcNow).Minutes) < 1)
                {
                    return(BadRequest(new { Messages = new[] { "SMS code has already been sent to you. To send a new one, wait a minute from the moment of sending the past." } }));
                }
            }

            // Generate OTP
            long   hotpCounter = _dbContext.GetHotpCounter();
            string hotpCode    = hotp.ComputeHOTP(1 /*hotpCounter*/);

            //Send SMS
            //HttpStatusCode sendingResult = await _smsSender.SendSmsAsync(model.Phone, hotpCode);
            //if (sendingResult != HttpStatusCode.OK)
            //    return StatusCode(500, new { Message = "Error sending SMS code." });

            // Save SmsSession
            smsSession = new SmsSession()
            {
                UserId = user.Id, CodeHotpCounter = 1 /*hotpCounter*/, CreatedAt = DateTime.UtcNow
            };
            _dbContext.smsSessions.Add(smsSession);
            //await _dbContext.SaveChangesAsync();

            return(Created("", new
            {
                Message = "An SMS with a verification code has been sent to your number.",
                SessionToken = IssueToken(TypeToken.Session, user.Id)
            }));
        }