public async Task <ActionResult <UserBindingDto> > RefreshToken([FromBody] UserRefreshTokenDto dto,
                                                                        CancellationToken token = default)
        {
            var principal = GetPrincipalFromExpiredToken(dto.ExpiredToken);

            var valid = Guid.TryParse(principal.FindFirstValue(ClaimTypes.NameIdentifier), out var userId);

            if (!valid)
            {
                return(NotFound("Token is not valid."));
            }

            var durationToCheck = DateTimeOffset.Now.AddDays(-jwtOptions.RefreshTokenDurationInDays);
            var device          = await Context.Devices
                                  .Where(x => x.RefreshToken == dto.RefreshToken && x.User.Id == userId)
                                  .Where(x => x.UpdatedAt > durationToCheck)
                                  .SingleOrDefaultAsync(token);

            if (device
                == null)
            {
                return(NotFound("Device not found."));
            }

            var user = await userManager.FindByIdAsync(userId.ToString());

            var accessTokenExpiration = DateTimeOffset.UtcNow.AddMinutes(jwtOptions.DurationInMinutes);

            var claims = await GenerateClaims(user);

            var jwt = GenerateJwt(claims, accessTokenExpiration);

            device.RefreshToken = Guid.NewGuid();
            await Context.SaveChangesAsync(token);

            var result = new UserBindingDto(jwt, accessTokenExpiration, device.RefreshToken);

            return(Ok(result));
        }
        public async Task <ActionResult <UserBindingDto> > LoginUser([FromBody] UserLoginDto userLogin,
                                                                     CancellationToken token = default)
        {
            var user = await userManager.FindByNameAsync(userLogin.UserName)
                       ?? await userManager.FindByEmailAsync(userLogin.UserName);

            if (user == null || !await userManager.CheckPasswordAsync(user, userLogin.Password))
            {
                return(NotFound("User not found or wrong password"));
            }

            var device =
                await Context.Devices.FirstOrDefaultAsync(e => e.Name == userLogin.DeviceName && e.User == user, token);

            if (device == null)
            {
                device = new Device {
                    User = user, Name = userLogin.DeviceName
                };
                Context.Devices.Add(device);
            }

            var accessTokenExpiration = DateTimeOffset.UtcNow.AddMinutes(jwtOptions.DurationInMinutes);

            var claims = await GenerateClaims(user);

            var jwt = GenerateJwt(claims, accessTokenExpiration);

            var refreshToken = Guid.NewGuid();

            device.RefreshToken = refreshToken;

            await Context.SaveChangesAsync(token);

            var dto = new UserBindingDto(jwt, accessTokenExpiration, refreshToken);

            return(Ok(dto));
        }