Skip to content

Conversation

ravishanigarapu
Copy link
Member

@ravishanigarapu ravishanigarapu commented May 22, 2025

πŸ“‹ Description

JIRA ID: AMM-1456

Please provide a summary of the change and the motivation behind it. Include relevant context and details.


βœ… Type of Change

  • 🐞 Bug fix (non-breaking change which resolves an issue)
  • ✨ New feature (non-breaking change which adds functionality)
  • πŸ”₯ Breaking change (fix or feature that would cause existing functionality to not work as expected)
  • πŸ›  Refactor (change that is neither a fix nor a new feature)
  • βš™οΈ Config change (configuration file or build script updates)
  • πŸ“š Documentation (updates to docs or readme)
  • πŸ§ͺ Tests (adding new or updating existing tests)
  • 🎨 UI/UX (changes that affect the user interface)
  • πŸš€ Performance (improves performance)
  • 🧹 Chore (miscellaneous changes that don't modify src or test files)

ℹ️ Additional Information

Please describe how the changes were tested, and include any relevant screenshots, logs, or other information that provides additional context.

Summary by CodeRabbit

  • New Features

    • Added centralized utilities for creating HTTP requests with consistent headers, including authorization and user agent information.
    • Introduced thread-safe user agent context management for improved request handling.
    • Enabled custom overriding of HTTP Authorization headers in incoming requests.
  • Bug Fixes

    • Improved cookie handling to prevent potential errors when cookies are missing.
  • Refactor

    • Simplified and standardized HTTP request construction for retrieving campaign roles.
    • Streamlined JWT validation and authorization logic for better maintainability.

Copy link

coderabbitai bot commented May 22, 2025

Warning

Rate limit exceeded

@ravishanigarapu has exceeded the limit for the number of commits or files that can be reviewed per hour. Please wait 1 minutes and 23 seconds before requesting another review.

βŒ› How to resolve this issue?

After the wait time has elapsed, a review can be triggered using the @coderabbitai review command as a PR comment. Alternatively, push new commits to this PR.

We recommend that you space out your commits to avoid hitting the rate limit.

🚦 How do rate limits work?

CodeRabbit enforces hourly rate limits for each developer per organization.

Our paid plans have higher rate limits than the trial, open-source and free plans. In all cases, we re-allow further reviews after a brief timeout.

Please see our FAQ for further information.

πŸ“₯ Commits

Reviewing files that changed from the base of the PR and between 91153d7 and 30f7b62.

πŸ“’ Files selected for processing (2)
  • src/main/java/com/iemr/admin/utils/RestTemplateUtil.java (1 hunks)
  • src/main/java/com/iemr/admin/utils/http/HTTPRequestInterceptor.java (1 hunks)

Walkthrough

These changes introduce utility classes for centralized HTTP request construction and user agent management, refactor JWT token extraction to be static and safer, and update a filter to use a new request wrapper for Authorization headers. Manual header and cookie handling is replaced with reusable utilities, improving consistency and encapsulation.

Changes

File(s) Change Summary
src/main/java/com/iemr/admin/service/employeemaster/EmployeeMasterServiceImpl.java Refactored the getCTICampaignRoles method to use RestTemplateUtil.createRequestEntity for HTTP request construction, removing manual JWT and header handling.
src/main/java/com/iemr/admin/utils/CookieUtil.java Changed getJwtTokenFromCookie to a static method and added a null check for cookies to prevent exceptions.
src/main/java/com/iemr/admin/utils/JwtUserIdValidationFilter.java Modified JWT validation to use AuthorizationHeaderRequestWrapper and improved handling of requests without valid tokens, including user agent context management and consolidated logging.
src/main/java/com/iemr/admin/utils/RestTemplateUtil.java Added new utility class RestTemplateUtil with a static method to create HTTP request entities, handling headers and JWT token extraction from cookies or request context.
src/main/java/com/iemr/admin/utils/UserAgentContext.java Added new utility class UserAgentContext for thread-local user agent storage, with static methods to set, get, and clear the user agent string.
src/main/java/com/iemr/admin/utils/http/AuthorizationHeaderRequestWrapper.java Added new class AuthorizationHeaderRequestWrapper to override or inject the "Authorization" header in an HTTP request, including header name and value management.

Sequence Diagram(s)

sequenceDiagram
    participant Client
    participant Filter as JwtUserIdValidationFilter
    participant RequestWrapper as AuthorizationHeaderRequestWrapper
    participant UserAgentCtx as UserAgentContext
    participant Service as EmployeeMasterServiceImpl
    participant RestUtil as RestTemplateUtil

    Client->>Filter: Send HTTP request (with/without JWT)
    Filter->>Filter: Check JWT in cookie/header
    alt JWT found
        Filter->>RequestWrapper: Wrap request with Authorization header
        RequestWrapper->>Service: Pass wrapped request
    else No JWT, but mobile client and Authorization present
        Filter->>UserAgentCtx: Set user agent context
        UserAgentCtx->>Service: Pass request with user agent context
        Service->>UserAgentCtx: Clear user agent context
    else No valid JWT or Authorization
        Filter->>Client: Respond 401 Unauthorized
    end
    Service->>RestUtil: Create HTTP request entity (headers, JWT, user agent)
    RestUtil->>Service: Return HttpEntity
    Service->>...: Continue processing
Loading

Suggested reviewers

  • helenKaryamsetty

Poem

In the warren of code, a rabbit did see
New wrappers and headers, as neat as can be.
JWTs now fetched with a static delight,
User agents tucked in for each thread’s night.
With utilities handy and filters anew,
This patch hops alongβ€”secure, tidy, and true!
πŸ‡βœ¨

✨ Finishing Touches
  • πŸ“ Generate Docstrings

Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❀️ Share
πŸͺ§ Tips

Chat

There are 3 ways to chat with CodeRabbit:

  • Review comments: Directly reply to a review comment made by CodeRabbit. Example:
    • I pushed a fix in commit <commit_id>, please review it.
    • Explain this complex logic.
    • Open a follow-up GitHub issue for this discussion.
  • Files and specific lines of code (under the "Files changed" tab): Tag @coderabbitai in a new review comment at the desired location with your query. Examples:
    • @coderabbitai explain this code block.
    • @coderabbitai modularize this function.
  • PR comments: Tag @coderabbitai in a new PR comment to ask questions about the PR branch. For the best results, please provide a very specific query, as very limited context is provided in this mode. Examples:
    • @coderabbitai gather interesting stats about this repository and render them as a table. Additionally, render a pie chart showing the language distribution in the codebase.
    • @coderabbitai read src/utils.ts and explain its main purpose.
    • @coderabbitai read the files in the src/scheduler package and generate a class diagram using mermaid and a README in the markdown format.
    • @coderabbitai help me debug CodeRabbit configuration file.

Support

Need help? Create a ticket on our support page for assistance with any issues or questions.

Note: Be mindful of the bot's finite context window. It's strongly recommended to break down tasks such as reading entire modules into smaller chunks. For a focused discussion, use review comments to chat about specific files and their changes, instead of using the PR comments.

CodeRabbit Commands (Invoked using PR comments)

  • @coderabbitai pause to pause the reviews on a PR.
  • @coderabbitai resume to resume the paused reviews.
  • @coderabbitai review to trigger an incremental review. This is useful when automatic reviews are disabled for the repository.
  • @coderabbitai full review to do a full review from scratch and review all the files again.
  • @coderabbitai summary to regenerate the summary of the PR.
  • @coderabbitai generate docstrings to generate docstrings for this PR.
  • @coderabbitai generate sequence diagram to generate a sequence diagram of the changes in this PR.
  • @coderabbitai resolve resolve all the CodeRabbit review comments.
  • @coderabbitai configuration to show the current CodeRabbit configuration for the repository.
  • @coderabbitai help to get help.

Other keywords and placeholders

  • Add @coderabbitai ignore anywhere in the PR description to prevent this PR from being reviewed.
  • Add @coderabbitai summary to generate the high-level summary at a specific location in the PR description.
  • Add @coderabbitai anywhere in the PR title to generate the title automatically.

CodeRabbit Configuration File (.coderabbit.yaml)

  • You can programmatically configure CodeRabbit by adding a .coderabbit.yaml file to the root of your repository.
  • Please see the configuration documentation for more information.
  • If your editor has YAML language server enabled, you can add the path at the top of this file to enable auto-completion and validation: # yaml-language-server: $schema=https://coderabbit.ai/integrations/schema.v2.json

Documentation and Community

  • Visit our Documentation for detailed information on how to use CodeRabbit.
  • Join our Discord Community to get help, request features, and share feedback.
  • Follow us on X/Twitter for updates and announcements.

Copy link

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 5

🧹 Nitpick comments (6)
src/main/java/com/iemr/admin/utils/UserAgentContext.java (1)

3-18: Well-designed thread-local implementation for User-Agent context

This is a clean implementation of the thread-local pattern for storing User-Agent information. The class provides simple methods for setting, getting, and clearing the context, and properly uses ThreadLocal.remove() to prevent memory leaks.

However, consider adding documentation to emphasize that users of this class must ensure clear() is called after processing, ideally in a try-finally block, to prevent memory leaks with thread pools:

 public class UserAgentContext {
 	private static final ThreadLocal<String> userAgentHolder = new ThreadLocal<>();
 
+    /**
+     * Store the user agent for the current thread
+     * @param userAgent The user agent string to store
+     */
     public static void setUserAgent(String userAgent) {
         userAgentHolder.set(userAgent);
     }
 
+    /**
+     * Get the user agent for the current thread
+     * @return The stored user agent string or null if not set
+     */
     public static String getUserAgent() {
         return userAgentHolder.get();
     }
 
+    /**
+     * Clear the user agent from the current thread.
+     * This must be called after processing is complete to prevent memory leaks,
+     * especially in application server environments with thread pools.
+     */
     public static void clear() {
         userAgentHolder.remove();
     }
 }
src/main/java/com/iemr/admin/utils/http/AuthorizationHeaderRequestWrapper.java (3)

10-16: Follow Java naming conventions for member variables

The member variable Authorization should follow Java's camelCase naming convention for variables.

- private final String Authorization;
+ private final String authorization;

Remember to update references to this variable in your methods as well.


18-24: Consider adding null check for authorization value

The method currently returns the Authorization field even if it's null. Consider adding a null check to avoid returning null values.

@Override
public String getHeader(String name) {
    if ("Authorization".equalsIgnoreCase(name)) {
-        return Authorization;
+        return Authorization != null ? Authorization : "";
    }
    return super.getHeader(name);
}

1-42: Add JavaDoc documentation to improve code maintainability

Consider adding JavaDoc comments to describe the purpose of this class and its methods. This would help other developers understand how and when to use this wrapper class.

package com.iemr.admin.utils.http;

import java.util.Collections;
import java.util.Enumeration;
import java.util.List;

import jakarta.servlet.http.HttpServletRequest;
import jakarta.servlet.http.HttpServletRequestWrapper;

+/**
+ * A wrapper for HttpServletRequest that overrides the Authorization header with a custom value.
+ * This is useful when you need to modify the Authorization header before passing the request along
+ * the filter chain.
+ */
public class AuthorizationHeaderRequestWrapper extends HttpServletRequestWrapper{
    private final String Authorization;

+    /**
+     * Constructs a request wrapper that will override the Authorization header
+     * with the provided value.
+     *
+     * @param request The original HttpServletRequest
+     * @param authHeaderValue The value to use for the Authorization header
+     */
    public AuthorizationHeaderRequestWrapper(HttpServletRequest request, String authHeaderValue) {
        super(request);
        this.Authorization = authHeaderValue;
    }
src/main/java/com/iemr/admin/utils/RestTemplateUtil.java (2)

16-23: Extract request attribute retrieval logic to improve readability

Consider extracting the logic to get the request attributes into a separate method to improve code readability and maintainability.

- ServletRequestAttributes servletRequestAttributes = ((ServletRequestAttributes) RequestContextHolder.getRequestAttributes());
- if (servletRequestAttributes == null) {
+ HttpServletRequest request = getRequestFromContext();
+ if (request == null) {
    MultiValueMap<String, String> headers = new LinkedMultiValueMap<>();
    headers.add(HttpHeaders.CONTENT_TYPE, MediaType.APPLICATION_JSON_VALUE + ";charset=utf-8");
    headers.add(HttpHeaders.AUTHORIZATION, authorization);
    return new HttpEntity<>(body, headers);
}
- HttpServletRequest requestHeader = servletRequestAttributes.getRequest();

Then add a private method:

private static HttpServletRequest getRequestFromContext() {
    ServletRequestAttributes servletRequestAttributes = 
        (ServletRequestAttributes) RequestContextHolder.getRequestAttributes();
    return servletRequestAttributes != null ? servletRequestAttributes.getRequest() : null;
}

13-41: Add JavaDoc documentation for the utility class and method

Consider adding JavaDoc comments to describe the purpose of this utility class and its method to improve code maintainability.

package com.iemr.admin.utils;

import org.springframework.http.HttpEntity;
import org.springframework.http.HttpHeaders;
import org.springframework.http.MediaType;
import org.springframework.util.LinkedMultiValueMap;
import org.springframework.util.MultiValueMap;
import org.springframework.web.context.request.RequestContextHolder;
import org.springframework.web.context.request.ServletRequestAttributes;

import jakarta.servlet.http.HttpServletRequest;

+/**
+ * Utility class for creating HTTP request entities with consistent headers.
+ */
public class RestTemplateUtil {
+    /**
+     * Creates an HttpEntity with the provided body and authorization,
+     * including additional headers from the current request context if available.
+     *
+     * @param body The request body object
+     * @param authorization The authorization header value
+     * @return An HttpEntity with appropriate headers set
+     */
    public static HttpEntity<Object> createRequestEntity(Object body, String authorization) {
πŸ“œ Review details

Configuration used: CodeRabbit UI
Review profile: CHILL
Plan: Pro

πŸ“₯ Commits

Reviewing files that changed from the base of the PR and between 357f765 and 91153d7.

πŸ“’ Files selected for processing (6)
  • src/main/java/com/iemr/admin/service/employeemaster/EmployeeMasterServiceImpl.java (2 hunks)
  • src/main/java/com/iemr/admin/utils/CookieUtil.java (1 hunks)
  • src/main/java/com/iemr/admin/utils/JwtUserIdValidationFilter.java (2 hunks)
  • src/main/java/com/iemr/admin/utils/RestTemplateUtil.java (1 hunks)
  • src/main/java/com/iemr/admin/utils/UserAgentContext.java (1 hunks)
  • src/main/java/com/iemr/admin/utils/http/AuthorizationHeaderRequestWrapper.java (1 hunks)
🧰 Additional context used
🧬 Code Graph Analysis (3)
src/main/java/com/iemr/admin/utils/JwtUserIdValidationFilter.java (2)
src/main/java/com/iemr/admin/utils/http/AuthorizationHeaderRequestWrapper.java (1)
  • AuthorizationHeaderRequestWrapper (10-42)
src/main/java/com/iemr/admin/utils/UserAgentContext.java (1)
  • UserAgentContext (3-18)
src/main/java/com/iemr/admin/utils/RestTemplateUtil.java (1)
src/main/java/com/iemr/admin/utils/UserAgentContext.java (1)
  • UserAgentContext (3-18)
src/main/java/com/iemr/admin/service/employeemaster/EmployeeMasterServiceImpl.java (1)
src/main/java/com/iemr/admin/utils/RestTemplateUtil.java (1)
  • RestTemplateUtil (13-42)
⏰ Context from checks skipped due to timeout of 90000ms (1)
  • GitHub Check: Analyze (java)
πŸ”‡ Additional comments (5)
src/main/java/com/iemr/admin/utils/CookieUtil.java (1)

26-35: Good improvement with null safety and static method conversion

The method has been appropriately converted to static and includes explicit null checking for cookies, which prevents potential NullPointerException that could occur when calling Arrays.stream on a null array. This is a robust defensive programming practice.

src/main/java/com/iemr/admin/utils/JwtUserIdValidationFilter.java (3)

77-79: Improved security by clearing Authorization header with request wrapper

Using AuthorizationHeaderRequestWrapper to set an empty Authorization header helps prevent potential security issues where both JWT token and Authorization header authentication might conflict or be misused.


82-89: Consistent handling for JWT token from header

This change applies the same pattern as for cookie-based JWT tokens, providing consistency in how authentication is handled regardless of where the token comes from.


90-101: Good implementation of User-Agent context management for mobile clients

The implementation correctly sets and clears the UserAgentContext in a thread-safe manner using a try-finally block. This ensures that the thread-local context is always cleared, even if an exception occurs during filter chain processing.

src/main/java/com/iemr/admin/utils/http/AuthorizationHeaderRequestWrapper.java (1)

34-41: LGTM - Header names handling is correct

The implementation correctly adds the "Authorization" header name if it's not already present in the list of header names.

Comment on lines +104 to +105
logger.warn("No valid authentication token found");
response.sendError(HttpServletResponse.SC_UNAUTHORIZED, "Unauthorized: Invalid or missing token");
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

⚠️ Potential issue

Duplicate error message

There's a duplicate error message at lines 104-105 and 107-108. One of these blocks should be removed to avoid redundant logging and response.

-			logger.warn("No valid authentication token found");
-			response.sendError(HttpServletResponse.SC_UNAUTHORIZED, "Unauthorized: Invalid or missing token");

Committable suggestion skipped: line range outside the PR's diff.

πŸ€– Prompt for AI Agents
In src/main/java/com/iemr/admin/utils/JwtUserIdValidationFilter.java around
lines 104 to 105, there is a duplicate error message block that repeats again at
lines 107 to 108. Remove one of these duplicate blocks to avoid redundant
logging and sending the same error response twice, ensuring only a single
warning log and error response is sent for invalid or missing authentication
tokens.

Comment on lines +467 to +470
HttpEntity<Object> request = RestTemplateUtil.createRequestEntity(campaignName, authToken);
String url = configProperties.getPropertyByName("common-url") + configProperties.getPropertyByName("create-feedback");
HttpEntity<Object> request1 = new HttpEntity<Object>(campaignName, headers);
ResponseEntity<String> responseStr = restTemplate.exchange(url, HttpMethod.POST, request1, String.class);

ResponseEntity<String> responseStr = restTemplate.exchange(url, HttpMethod.POST, request, String.class);
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

πŸ’‘ Verification agent

🧩 Analysis chain

Good refactoring using centralized HTTP request entity creation

The refactoring simplifies the code by leveraging the new RestTemplateUtil.createRequestEntity method, which centralizes HTTP request construction and improves consistency by ensuring all necessary headers are included. This change removes duplicate code and makes the implementation more maintainable.

However, the URL being used appears to be for creating feedback but is used in a method for getting CTI campaign roles. Verify that this is the correct endpoint:


🏁 Script executed:

#!/bin/bash
# Verify the URL endpoint being used
echo "Method: getCTICampaignRoles"
echo "URL being used: ${configProperties.getPropertyByName('common-url')} + ${configProperties.getPropertyByName('create-feedback')}"
echo "Is this correct for retrieving campaign roles?"

Length of output: 383


🏁 Script executed:

#!/bin/bash
# Show context around the getCTICampaignRoles method
rg -n -B3 -A10 "getCTICampaignRoles" --color=never src/main/java

# Search for the 'create-feedback' key in all .properties files
rg -n "create-feedback" -g "*.properties"

# Search for any 'campaign' keys (to find the roles endpoint) in all .properties files
rg -n "campaign" -g "*.properties"

Length of output: 4265


Fix endpoint property key in getCTICampaignRoles

The code is using the undefined "create-feedback" property for fetching campaign roles. Use the "campaign-roles-url" key defined in application.properties instead.

  • File: src/main/java/com/iemr/admin/service/employeemaster/EmployeeMasterServiceImpl.java, line 468
- String url = configProperties.getPropertyByName("common-url")  + configProperties.getPropertyByName("create-feedback");
+ String url = configProperties.getPropertyByName("common-url")  + configProperties.getPropertyByName("campaign-roles-url");
πŸ“ Committable suggestion

‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.

Suggested change
HttpEntity<Object> request = RestTemplateUtil.createRequestEntity(campaignName, authToken);
String url = configProperties.getPropertyByName("common-url") + configProperties.getPropertyByName("create-feedback");
HttpEntity<Object> request1 = new HttpEntity<Object>(campaignName, headers);
ResponseEntity<String> responseStr = restTemplate.exchange(url, HttpMethod.POST, request1, String.class);
ResponseEntity<String> responseStr = restTemplate.exchange(url, HttpMethod.POST, request, String.class);
HttpEntity<Object> request = RestTemplateUtil.createRequestEntity(campaignName, authToken);
String url = configProperties.getPropertyByName("common-url") + configProperties.getPropertyByName("campaign-roles-url");
ResponseEntity<String> responseStr = restTemplate.exchange(url, HttpMethod.POST, request, String.class);
πŸ€– Prompt for AI Agents
In
src/main/java/com/iemr/admin/service/employeemaster/EmployeeMasterServiceImpl.java
around lines 467 to 470, the URL for the REST call incorrectly uses the
"create-feedback" property key, which is meant for feedback creation, not for
fetching CTI campaign roles. Replace the property key "create-feedback" with the
correct "campaign-roles-url" key from application.properties to ensure the
endpoint matches the method's purpose.

Comment on lines 1 to 42
package com.iemr.admin.utils;

import org.springframework.http.HttpEntity;
import org.springframework.http.HttpHeaders;
import org.springframework.http.MediaType;
import org.springframework.util.LinkedMultiValueMap;
import org.springframework.util.MultiValueMap;
import org.springframework.web.context.request.RequestContextHolder;
import org.springframework.web.context.request.ServletRequestAttributes;

import jakarta.servlet.http.HttpServletRequest;

public class RestTemplateUtil {
public static HttpEntity<Object> createRequestEntity(Object body, String authorization) {

ServletRequestAttributes servletRequestAttributes = ((ServletRequestAttributes) RequestContextHolder.getRequestAttributes());
if (servletRequestAttributes == null) {
MultiValueMap<String, String> headers = new LinkedMultiValueMap<>();
headers.add(HttpHeaders.CONTENT_TYPE, MediaType.APPLICATION_JSON_VALUE + ";charset=utf-8");
headers.add(HttpHeaders.AUTHORIZATION, authorization);
return new HttpEntity<>(body, headers);
}
HttpServletRequest requestHeader = servletRequestAttributes.getRequest();
String jwtTokenFromCookie = null;
try {
jwtTokenFromCookie = CookieUtil.getJwtTokenFromCookie(requestHeader);

} catch (Exception e) {
e.printStackTrace();
}

MultiValueMap<String, String> headers = new LinkedMultiValueMap<>();
headers.add(HttpHeaders.CONTENT_TYPE, MediaType.APPLICATION_JSON_VALUE + ";charset=utf-8");
headers.add(HttpHeaders.USER_AGENT, UserAgentContext.getUserAgent());
headers.add(HttpHeaders.AUTHORIZATION, authorization);
headers.add("JwtToken",requestHeader.getHeader("JwtToken"));
headers.add(HttpHeaders.COOKIE, "Jwttoken=" + jwtTokenFromCookie);

return new HttpEntity<>(body, headers);
}

}
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

πŸ’‘ Verification agent

🧩 Analysis chain

Verify JWT token naming consistency

I notice inconsistent naming of the JWT token:

  1. The method refers to "Jwttoken" in the cookie header
  2. The header is named "JwtToken"

Ensure this naming is consistent with other parts of the application.


🏁 Script executed:

#!/bin/bash
# Check for other occurrences of JWT token naming in the codebase
echo "Searching for JWT token references in the codebase..."
rg -i "jwt(token|token)" --type java

Length of output: 2642


🏁 Script executed:

#!/bin/bash
# Display CookieUtil.java to inspect token naming
sed -n '1,200p' src/main/java/com/iemr/admin/utils/CookieUtil.java

Length of output: 1082


Unify JWT token naming across headers and cookies

The codebase currently mixes two variantsβ€”Jwttoken and JwtTokenβ€”when reading from or writing to cookies and headers. This can lead to hard-to-trace bugs. Standardize on a single name (e.g. "JwtToken") by:

  • Defining a constant, e.g.
    public static final String JWT_TOKEN_KEY = "JwtToken";
    in a shared class (JwtConstants or similar).
  • Replacing all literal occurrences:
    • In CookieUtil.getJwtTokenFromCookie(...): filter on JWT_TOKEN_KEY instead of "Jwttoken".
    • In RestTemplateUtil.createRequestEntity(...):
      • Change headers.add("JwtToken", ...) and
        headers.add(HttpHeaders.COOKIE, "Jwttoken=" + ...)
        to use JWT_TOKEN_KEY for both header name and cookie name.
    • In JwtUserIdValidationFilter.java:
      • Use JWT_TOKEN_KEY when calling request.getHeader(...).
      • Match the same constant when iterating cookies.

This will ensure a single source of truth and avoid mismatches.

πŸ€– Prompt for AI Agents
In src/main/java/com/iemr/admin/utils/RestTemplateUtil.java lines 1 to 42, the
JWT token naming is inconsistent between "Jwttoken" and "JwtToken" in headers
and cookies. To fix this, define a constant JWT_TOKEN_KEY (e.g., "JwtToken") in
a shared class and replace all literal occurrences in this file and related
classes like CookieUtil and JwtUserIdValidationFilter to use this constant for
both header and cookie names, ensuring consistent naming across the codebase.

Comment on lines 32 to 38
MultiValueMap<String, String> headers = new LinkedMultiValueMap<>();
headers.add(HttpHeaders.CONTENT_TYPE, MediaType.APPLICATION_JSON_VALUE + ";charset=utf-8");
headers.add(HttpHeaders.USER_AGENT, UserAgentContext.getUserAgent());
headers.add(HttpHeaders.AUTHORIZATION, authorization);
headers.add("JwtToken",requestHeader.getHeader("JwtToken"));
headers.add(HttpHeaders.COOKIE, "Jwttoken=" + jwtTokenFromCookie);

Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

πŸ› οΈ Refactor suggestion

Add null checks before adding headers

The code doesn't check if values like UserAgentContext.getUserAgent() or requestHeader.getHeader("JwtToken") are null before adding them to headers. This could lead to unexpected behavior.

MultiValueMap<String, String> headers = new LinkedMultiValueMap<>();
headers.add(HttpHeaders.CONTENT_TYPE, MediaType.APPLICATION_JSON_VALUE + ";charset=utf-8");
- headers.add(HttpHeaders.USER_AGENT, UserAgentContext.getUserAgent());
+ String userAgent = UserAgentContext.getUserAgent();
+ if (userAgent != null) {
+     headers.add(HttpHeaders.USER_AGENT, userAgent);
+ }
headers.add(HttpHeaders.AUTHORIZATION, authorization);
- headers.add("JwtToken", requestHeader.getHeader("JwtToken"));
+ String jwtToken = requestHeader.getHeader("JwtToken");
+ if (jwtToken != null) {
+     headers.add("JwtToken", jwtToken);
+ }
- headers.add(HttpHeaders.COOKIE, "Jwttoken=" + jwtTokenFromCookie);
+ if (jwtTokenFromCookie != null) {
+     headers.add(HttpHeaders.COOKIE, "Jwttoken=" + jwtTokenFromCookie);
+ }
πŸ“ Committable suggestion

‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.

Suggested change
MultiValueMap<String, String> headers = new LinkedMultiValueMap<>();
headers.add(HttpHeaders.CONTENT_TYPE, MediaType.APPLICATION_JSON_VALUE + ";charset=utf-8");
headers.add(HttpHeaders.USER_AGENT, UserAgentContext.getUserAgent());
headers.add(HttpHeaders.AUTHORIZATION, authorization);
headers.add("JwtToken",requestHeader.getHeader("JwtToken"));
headers.add(HttpHeaders.COOKIE, "Jwttoken=" + jwtTokenFromCookie);
MultiValueMap<String, String> headers = new LinkedMultiValueMap<>();
headers.add(HttpHeaders.CONTENT_TYPE, MediaType.APPLICATION_JSON_VALUE + ";charset=utf-8");
String userAgent = UserAgentContext.getUserAgent();
if (userAgent != null) {
headers.add(HttpHeaders.USER_AGENT, userAgent);
}
headers.add(HttpHeaders.AUTHORIZATION, authorization);
String jwtToken = requestHeader.getHeader("JwtToken");
if (jwtToken != null) {
headers.add("JwtToken", jwtToken);
}
if (jwtTokenFromCookie != null) {
headers.add(HttpHeaders.COOKIE, "Jwttoken=" + jwtTokenFromCookie);
}
πŸ€– Prompt for AI Agents
In src/main/java/com/iemr/admin/utils/RestTemplateUtil.java around lines 32 to
38, add null checks before adding headers such as
UserAgentContext.getUserAgent() and requestHeader.getHeader("JwtToken") to the
MultiValueMap. Only add these headers if their values are not null to prevent
potential null values causing unexpected behavior in the headers.

Copy link

@ravishanigarapu ravishanigarapu merged commit fd2c377 into PSMRI:develop May 22, 2025
7 checks passed
This was referenced May 25, 2025
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

2 participants