public async void SaveRefreshTokenAsync_ShouldSaveRefreshTokenInDatabase()
        {
            var loggerMock      = new Mock <ILogger <AccessTokenService> >();
            var optionsMock     = new Mock <IOptions <AppSettings> >();
            var appSettingsMock = new Mock <AppSettings>();
            var contextMock     = new Mock <IDatabaseContext>();

            optionsMock.Setup(x => x.Value)
            .Returns(appSettingsMock.Object);

            var dbSet = new TestDbSet <RefreshToken>();

            contextMock.Setup(x => x.RefreshTokens)
            .Returns(dbSet);
            contextMock.Setup(x => x.SaveChangesAsync(It.IsAny <CancellationToken>()))
            .Verifiable();

            var service      = new AccessTokenService(loggerMock.Object, contextMock.Object, optionsMock.Object);
            var refreshToken = GetRefreshTokenSample();

            await service.SaveRefreshTokenAsync(refreshToken.UserId.ToString(), refreshToken.Token);

            Assert.Contains(dbSet, x => x.Token == refreshToken.Token && x.UserId == refreshToken.UserId);
            contextMock.Verify(x => x.SaveChangesAsync(It.IsAny <CancellationToken>()));
        }
        public async Task <IActionResult> Refresh([FromBody] RefreshRequestModel refreshRequest)
        {
            var principal         = AccessTokenService.GetPrincipalFromExpiredToken(refreshRequest.Token);
            var userId            = principal.Identity.Name;
            var savedRefreshToken = await AccessTokenService.GetRefreshTokenAsync(userId);

            if (savedRefreshToken != refreshRequest.RefreshToken)
            {
                return(BadRequest("Invalid refresh token"));
            }

            string newJwtToken     = null;
            string newRefreshToken = null;

            try
            {
                newJwtToken     = AccessTokenService.GenerateAccessToken(userId);
                newRefreshToken = AccessTokenService.GenerateRefreshToken();

                await AccessTokenService.DeleteRefreshTokenAsync(userId, refreshRequest.RefreshToken);

                await AccessTokenService.SaveRefreshTokenAsync(userId, newRefreshToken);
            }
            catch (Exception e)
            {
                Logger.LogError(e, e.Message);
                return(StatusCode(500));
            }

            return(Ok(new
            {
                token = newJwtToken,
                refreshToken = newRefreshToken
            }));
        }
        public async Task <IActionResult> Authenticate([FromBody] AuthenticationRequestModel model)
        {
            User   user = null;
            string tokenString;
            string refreshToken;

            try
            {
                user = await UserService.AuthenticateAsync(model.Username, model.Password);

                if (user == null)
                {
                    return(BadRequest(new { message = "Username or password is incorrect" }));
                }

                tokenString  = AccessTokenService.GenerateAccessToken(user.Id.ToString());
                refreshToken = AccessTokenService.GenerateRefreshToken();
                await AccessTokenService.SaveRefreshTokenAsync(user.Id.ToString(), refreshToken);
            }
            catch (ArgumentException e)
            {
                return(BadRequest(e.Message));
            }
            catch
            {
                return(StatusCode(500));
            }

            return(Ok(new
            {
                id = user.Id,
                username = user.Username,
                token = tokenString,
                refreshToken = refreshToken
            }));
        }