public async Task <IActionResult> RefreshTokenAsync([FromBody] DTO.RefreshTokenInput refreshToken)
        {
            var token = await AuthManager.RefreshTokenAsync(refreshToken);

            return(Ok(new DTO.SuccessResponse <DTO.TokenOutput>()
            {
                Success = true,
                Content = token
            }));
        }
        public async Task <DTO.TokenOutput> RefreshTokenAsync(DTO.RefreshTokenInput refreshToken)
        {
            var validatedToken = GetClaimsPrincipalFromToken(refreshToken.Token);

            if (validatedToken == null)
            {
                throw new UnautherizedException("Invalid token.");
            }

            var expirationDateUnix =
                long.Parse(validatedToken.Claims.Single(x => x.Type == JwtRegisteredClaimNames.Exp).Value);
            var expirationDateTimeUtc =
                new DateTime(1970, 1, 1, 0, 0, 0, DateTimeKind.Utc).AddSeconds(expirationDateUnix);

            if (expirationDateTimeUtc > DateTime.UtcNow)
            {
                throw new UnautherizedException("This token is still valid.");
            }

            var storedRefreshToken = Context.RefreshTokens.SingleOrDefault(rt => rt.Token == refreshToken.RefreshToken);

            if (storedRefreshToken == null)
            {
                throw new UnautherizedException("This token does not exist.");
            }

            var jti    = validatedToken.Claims.Single(x => x.Type == JwtRegisteredClaimNames.Jti).Value;
            var errors = new List <string>();

            if (DateTime.UtcNow > storedRefreshToken.ExpirationDate)
            {
                errors.Add("This refresh token has expired.");
            }

            if (storedRefreshToken.Invalidated)
            {
                errors.Add("This refresh token has been invalidated.");
            }

            if (storedRefreshToken.Used)
            {
                errors.Add("This refresh token has been used.");
            }

            if (storedRefreshToken.JwtId != jti)
            {
                errors.Add("This refresh token does not match this jwt token.");
            }

            if (errors.Count != 0)
            {
                throw new UnautherizedException(errors);
            }

            storedRefreshToken.Used = true;
            Context.RefreshTokens.Update(storedRefreshToken);
            await Context.SaveChangesAsync();

            var user = await UserManager.FindByIdAsync(validatedToken.Claims.Single(x => x.Type == "id").Value);

            return(await GenerateAuthenticationTokenAsync(user));
        }