/// <inheritdoc/> public async Task <AuthResponse> RefreshTokenAsync(RefreshTokenRequest request) { var validatedToken = GetPrincipalFromToken(request.Token); if (validatedToken == null) { return(new AuthResponse { Errors = new List <string> { "Invalid token!" } }); } var expiryDateUnix = long.Parse(validatedToken.Claims.Single(x => x.Type == JwtRegisteredClaimNames.Exp).Value); var expiryDateTimeUtc = UnixTimeStampToDateTime(expiryDateUnix); if (expiryDateTimeUtc > DateTime.UtcNow) { return(new AuthResponse { Success = false, Errors = new List <string> { "Access token has not expired yet!" } }); } var storedRefreshToken = await _refreshTokenRepository.GetByRefreshTokenValueAsync(request.RefreshToken); if (storedRefreshToken == null) { return(new AuthResponse { Errors = new List <string> { "Refresh token does not exist!" } }); } if (DateTime.UtcNow > storedRefreshToken.ExpiryDate) { return(new AuthResponse { Errors = new List <string> { "Refresh token has expired, user needs to re-login." }, Success = false }); } if (storedRefreshToken.IsRevoked) { return(new AuthResponse { Errors = new List <string> { "Refresh token has been revoked!" }, Success = false }); } if (storedRefreshToken.IsUsed) { return(new AuthResponse { Errors = new List <string> { "Refresh token has been used." }, Success = false }); } var jti = validatedToken.Claims.Single(x => x.Type == JwtRegisteredClaimNames.Jti).Value; if (storedRefreshToken.JwtId != jti) { return(new AuthResponse { Errors = new List <string> { "This refresh token does not match the saved token!" }, Success = false }); } storedRefreshToken.IsUsed = true; await _refreshTokenRepository.UpdateAsync(storedRefreshToken.Id, storedRefreshToken); var dbUser = (await _userRepository.GetByIdAsync(storedRefreshToken.UserId)).FirstOrDefault(); return(await GenerateAuthResultForUserAsync(dbUser)); }