/// <inheritdoc cref="IUserRepository{T}.RefreshToken"/> /// <exception cref="ArgumentNullException">if email claim is null.</exception> /// <exception cref="SecurityException">if jwt is null or empty</exception> public async Task <IUserActionResult> RefreshToken(string jwt, string refreshToken) { //get the principal var principal = _jwtHandler.GetPrincipalFromExpiredToken(jwt); if (principal == null) { return(_defaultTokenRefreshErrors); } //check if the email in the claim is null, if it is an error occurred. var email = principal.FindFirstValue(ClaimTypes.Email); if (email == null) { throw new NullReferenceException("Email was null"); } //find the user by email and their refresh tokens var user = await FindByEmailIncludingRefreshTokens(email); var storedRefreshToken = user?.RefreshTokens.FirstOrDefault(c => c.Token == refreshToken); //if there is no valid RefreshToken return if (storedRefreshToken == null || storedRefreshToken.IsExpired()) { return(_defaultTokenRefreshErrors); } var newJwt = _jwtHandler.Generate(DefaultJwtHandler.GetDefaultClaims(user.FirstName, user.Email)); var newRefreshToken = _refreshTokenGenerator.Generate(); user.RefreshTokens.Remove(storedRefreshToken); user.RefreshTokens.Add(newRefreshToken); await _userManager.UpdateAsync(user); return(new DefaultUserActionResultBuilder() .Success() .WithJwt(newJwt) .WithRefreshToken(newRefreshToken.Token) .Build()); }