Skip to content

Conversation

SauravBizbRolly
Copy link

@SauravBizbRolly SauravBizbRolly commented Jun 19, 2025

πŸ“‹ Description

JIRA ID:

3.3.0 release

βœ… 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

    • Introduced beneficiary consent management via new REST endpoints for sending, validating, and resending OTPs.
    • Added support for sending push notifications through Firebase Cloud Messaging.
    • Added configuration options for Firebase integration, including credential management for CI/CD environments.
    • Implemented secure OTP generation, caching, and SMS delivery for beneficiary consent.
    • Added user token management for notification services with JWT-based user identification.
  • Bug Fixes

    • Improved OTP handling logic and logging for beneficiary consent workflows.
  • Chores

    • Updated project dependencies to include Firebase Admin SDK.
  • Documentation

    • Enhanced configuration documentation with new Firebase-related properties.

SauravBizbRolly and others added 22 commits March 10, 2025 16:27
# Conflicts:
#	pom.xml
#	src/main/environment/common_ci.properties
#	src/main/environment/common_dev.properties
#	src/main/environment/common_test.properties
#	src/main/environment/common_uat.properties
#	src/main/java/com/iemr/common/controller/grievance/GrievanceController.java
#	src/main/java/com/iemr/common/data/grievance/GrievanceCallRequest.java
#	src/main/java/com/iemr/common/data/grievance/GrievanceDetails.java
#	src/main/java/com/iemr/common/repository/callhandling/IEMRCalltypeRepositoryImplCustom.java
#	src/main/java/com/iemr/common/repository/grievance/GrievanceDataRepo.java
#	src/main/java/com/iemr/common/service/grievance/GrievanceDataSyncImpl.java
#	src/main/java/com/iemr/common/service/grievance/GrievanceHandlingService.java
#	src/main/java/com/iemr/common/service/grievance/GrievanceHandlingServiceImpl.java
#	src/main/java/com/iemr/common/utils/http/HTTPRequestInterceptor.java
Copy link
Contributor

coderabbitai bot commented Jun 19, 2025

Important

Review skipped

Auto reviews are disabled on base/target branches other than the default branch.

Please check the settings in the CodeRabbit UI or the .coderabbit.yaml file in this repository. To trigger a single review, invoke the @coderabbitai review command.

You can disable this status message by setting the reviews.review_status to false in the CodeRabbit configuration file.

"""

Walkthrough

This update introduces Firebase Cloud Messaging integration and a new beneficiary consent flow. It adds dependencies and configuration for Firebase, implements OTP handling logic for beneficiary consent via new controllers and services, and updates data models. Several new classes and endpoints are added, with some minor adjustments to existing logging and model fields.

Changes

File(s) Change Summary
pom.xml Added Firebase Admin SDK dependency.
src/main/environment/common_ci.properties Added Firebase configuration properties.
src/main/java/com/iemr/common/CommonApplication.java Added unused Firebase-related imports.
src/main/java/com/iemr/common/config/firebase/FirebaseMessagingConfig.java New configuration class for FirebaseMessaging bean.
src/main/java/com/iemr/common/controller/beneficiaryConsent/BeneficiaryConsentController.java New REST controller for beneficiary consent OTP flow.
src/main/java/com/iemr/common/controller/firebaseNotification/FirebaseNotificationController.java New REST controller for sending Firebase notifications.
src/main/java/com/iemr/common/controller/otp/OTPGateway.java Enhanced logging and relaxed success check for OTP responses.
src/main/java/com/iemr/common/data/beneficiaryConsent/BeneficiaryConsentRequest.java New data class for beneficiary consent requests.
src/main/java/com/iemr/common/dto/identity/CommonIdentityDTO.java Added (duplicate) isConsent Boolean field, one initialized to false.
src/main/java/com/iemr/common/model/beneficiary/BeneficiaryModel.java Added (duplicate) isConsent Boolean field, both initialized to false.
src/main/java/com/iemr/common/model/notification/NotificationMessage.java New data class for notification messages.
src/main/java/com/iemr/common/service/beneficiary/RegisterBenificiaryServiceImpl.java Removed unused import, uncommented logger, added redundant isConsent set.
src/main/java/com/iemr/common/service/beneficiaryOTPHandler/BeneficiaryOTPHandler.java New interface for beneficiary OTP handling.
src/main/java/com/iemr/common/service/beneficiaryOTPHandler/BeneficiaryOTPHandlerImpl.java New service class implementing OTP logic for beneficiary consent.
src/main/java/com/iemr/common/service/firebaseNotification/FirebaseNotificationService.java New service for sending notifications via Firebase.
src/main/java/com/iemr/common/service/notification/NotificationService.java Added blank line at end of interface.
src/main/java/com/iemr/common/utils/JwtUserIdValidationFilter.java Added blank line after logging in filter method.
src/main/java/com/iemr/common/data/userToken/UserTokenData.java New JPA entity for user tokens.
src/main/java/com/iemr/common/model/notification/UserToken.java New data class for user tokens.
src/main/java/com/iemr/common/repo/userToken/UserTokenRepo.java New JPA repository interface for user tokens.

Sequence Diagram(s)

sequenceDiagram
    participant Client
    participant BeneficiaryConsentController
    participant BeneficiaryOTPHandler
    participant SMS Gateway

    Client->>BeneficiaryConsentController: POST /sendConsent (beneficiary data)
    BeneficiaryConsentController->>BeneficiaryOTPHandler: sendOTP(request)
    BeneficiaryOTPHandler->>SMS Gateway: Send OTP SMS
    SMS Gateway-->>BeneficiaryOTPHandler: SMS sent response
    BeneficiaryOTPHandler-->>BeneficiaryConsentController: OTP send result
    BeneficiaryConsentController-->>Client: Success/Error response

    Client->>BeneficiaryConsentController: POST /validateConsent (mobile, OTP)
    BeneficiaryConsentController->>BeneficiaryOTPHandler: validateOTP(request)
    BeneficiaryOTPHandler-->>BeneficiaryConsentController: Validation result
    BeneficiaryConsentController-->>Client: Success/Error response
Loading
sequenceDiagram
    participant Client
    participant FirebaseNotificationController
    participant FirebaseNotificationService
    participant FirebaseMessaging (SDK)

    Client->>FirebaseNotificationController: POST /firebaseNotification/sendNotification (NotificationMessage)
    FirebaseNotificationController->>FirebaseNotificationService: sendNotification(notificationMessage)
    FirebaseNotificationService->>FirebaseMessaging: Send notification
    FirebaseMessaging-->>FirebaseNotificationService: Response
    FirebaseNotificationService-->>FirebaseNotificationController: Result string
    FirebaseNotificationController-->>Client: Response
Loading

Possibly related PRs

  • PSMRI/Common-API#170: Both PRs modify CommonIdentityDTO and BeneficiaryModel by adding the isConsent Boolean field for tracking beneficiary consent.
  • PSMRI/Common-API#183: Both PRs add Firebase Admin SDK, Firebase configuration, and introduce the same notification controller, service, and data model.

Suggested labels

enhancement

Suggested reviewers

  • ravishanigarapu
  • vanitha1822

Poem

A rabbit hopped through fields of code,
Bringing Firebase to lighten the load.
Consent and OTPs now dance in spring,
Notifications flutter on digital wing.
With beans and tokens, all set anewβ€”
The meadow of features just grew and grew!
πŸ‡βœ¨
"""


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.

@Operation(summary = "Resend Consent")
@RequestMapping(value = "/resendConsent", method = RequestMethod.POST, consumes = MediaType.APPLICATION_JSON, produces = MediaType.APPLICATION_JSON, headers = "Authorization")
public String resendConsent(@Param(value = "{\"mobNo\":\"String\"}") @RequestBody String requestOBJ) {
logger.info(requestOBJ.toString());

Check notice

Code scanning / SonarCloud

Logging should not be vulnerable to injection attacks Low

Change this code to not log user-controlled data. See more on SonarQube Cloud
@Operation(summary = "Send OTP")
@RequestMapping(value = "/sendOTP", method = RequestMethod.POST, consumes = MediaType.APPLICATION_JSON, produces = MediaType.APPLICATION_JSON, headers = "Authorization")
public String sendOTP(@Param(value = "{\"mobNo\":\"String\"}") @RequestBody String requestOBJ) {
logger.info(requestOBJ.toString());

Check notice

Code scanning / SonarCloud

Logging should not be vulnerable to injection attacks Low

Change this code to not log user-controlled data. See more on SonarQube Cloud
@Operation(summary = "Resend OTP")
@RequestMapping(value = "/resendOTP", method = RequestMethod.POST, consumes = MediaType.APPLICATION_JSON, produces = MediaType.APPLICATION_JSON, headers = "Authorization")
public String resendOTP(@Param(value = "{\"mobNo\":\"String\"}") @RequestBody String requestOBJ) {
logger.info(requestOBJ.toString());

Check notice

Code scanning / SonarCloud

Logging should not be vulnerable to injection attacks Low

Change this code to not log user-controlled data. See more on SonarQube Cloud
Copy link
Contributor

@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: 17

🧹 Nitpick comments (11)
src/main/environment/common_ci.properties (1)

43-49: Align environment variable naming

The property firebase.enabled is populated from @env.FIREBASE_ENABLE@. For consistency and clarity, consider renaming the environment variable to FIREBASE_ENABLED to match the property key format.

src/main/java/com/iemr/common/CommonApplication.java (1)

24-27: Remove unused imports.

The Firebase-related imports, ClassPathResource, and IOException are not used in this class. Consider removing them to keep the code clean.

-import com.google.auth.oauth2.GoogleCredentials;
-import com.google.firebase.FirebaseApp;
-import com.google.firebase.FirebaseOptions;
-import com.google.firebase.messaging.FirebaseMessaging;
 import org.springframework.boot.SpringApplication;
 import org.springframework.boot.autoconfigure.SpringBootApplication;
 import org.springframework.boot.builder.SpringApplicationBuilder;
 import org.springframework.boot.web.servlet.support.SpringBootServletInitializer;
 import org.springframework.context.annotation.Bean;
-import org.springframework.core.io.ClassPathResource;
 import org.springframework.data.redis.connection.RedisConnectionFactory;
 import com.iemr.common.data.users.User;
 import com.iemr.common.utils.IEMRApplBeans;

-import java.io.IOException;

Also applies to: 33-33, 44-44

src/main/java/com/iemr/common/data/beneficiaryConsent/BeneficiaryConsentRequest.java (1)

7-10: Consider adding validation annotations for data integrity.

The request fields lack validation constraints which could lead to invalid data being processed. Consider adding appropriate validation annotations.

+import javax.validation.constraints.NotBlank;
+import javax.validation.constraints.Pattern;
+
 @Data
 public class BeneficiaryConsentRequest {
+    @NotBlank(message = "Mobile number is required")
+    @Pattern(regexp = "^[0-9]{10}$", message = "Mobile number must be 10 digits")
     private String mobNo;
+    @NotBlank(message = "OTP is required")
     private String otp;
+    @NotBlank(message = "Username is required")
     private String userName;
+    @NotBlank(message = "Designation is required")
     private String designation;
src/main/java/com/iemr/common/service/beneficiaryOTPHandler/BeneficiaryOTPHandler.java (2)

4-4: Remove unused import.

The OTPRequestParsor import is not used in this interface and should be removed.

-import com.iemr.common.data.otp.OTPRequestParsor;

8-12: Consider standardizing return types for consistency.

The interface has inconsistent return types (String vs JSONObject). Consider using a consistent response wrapper or standardizing on a single return type for better API consistency.

src/main/java/com/iemr/common/controller/firebaseNotification/FirebaseNotificationController.java (1)

13-13: Remove unused logger field.

The logger field is declared but never used in the controller. Either use it for logging or remove it to reduce clutter.

-    final Logger logger = LoggerFactory.getLogger(this.getClass().getName());
src/main/java/com/iemr/common/config/firebase/FirebaseMessagingConfig.java (3)

30-32: Consider logging configuration status instead of throwing exception.

Throwing an exception when Firebase is disabled might not be the best approach if the application should continue to function without Firebase. Consider logging the status and returning a no-op implementation instead.

 if (!firebaseEnabled) {
+    logger.info("Firebase is disabled, skipping Firebase messaging configuration");
-    throw new IllegalStateException("Firebase is disabled");
+    return null; // or return a no-op implementation
 }

43-45: Improve error message specificity.

The error message could be more helpful by indicating what configuration is expected.

-throw new IllegalStateException("No Firebase credentials provided");
+throw new IllegalStateException("No Firebase credentials provided. Please configure either 'firebase.credential-file' or 'firebase.credential-base64' property");

51-53: Add logging for Firebase app initialization.

Consider adding logging to track Firebase app initialization status for better debugging and monitoring.

+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
 @Configuration
 public class FirebaseMessagingConfig {
+    private static final Logger logger = LoggerFactory.getLogger(FirebaseMessagingConfig.class);
+
     // ... existing code ...
     
     FirebaseApp firebaseApp = FirebaseApp.getApps().isEmpty()
-            ? FirebaseApp.initializeApp(options)
+            ? FirebaseApp.initializeApp(options, "common-api")
             : FirebaseApp.getInstance();
+    
+    logger.info("Firebase app initialized: {}", firebaseApp.getName());
src/main/java/com/iemr/common/service/firebaseNotification/FirebaseNotificationService.java (1)

15-15: Remove unused logger or add proper logging.

The logger is declared but never used. Either utilize it for error logging or remove it.

-    final Logger logger = LoggerFactory.getLogger(this.getClass().getName());
src/main/java/com/iemr/common/controller/beneficiaryConsent/BeneficiaryConsentController.java (1)

6-6: Remove unused import.

The OTPHandler import is not used in this class and should be removed.

-import com.iemr.common.service.otp.OTPHandler;
πŸ“œ Review details

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

πŸ“₯ Commits

Reviewing files that changed from the base of the PR and between 13d1abb and cafa96e.

πŸ“’ Files selected for processing (17)
  • pom.xml (1 hunks)
  • src/main/environment/common_ci.properties (1 hunks)
  • src/main/java/com/iemr/common/CommonApplication.java (3 hunks)
  • src/main/java/com/iemr/common/config/firebase/FirebaseMessagingConfig.java (1 hunks)
  • src/main/java/com/iemr/common/controller/beneficiaryConsent/BeneficiaryConsentController.java (1 hunks)
  • src/main/java/com/iemr/common/controller/firebaseNotification/FirebaseNotificationController.java (1 hunks)
  • src/main/java/com/iemr/common/controller/otp/OTPGateway.java (2 hunks)
  • src/main/java/com/iemr/common/data/beneficiaryConsent/BeneficiaryConsentRequest.java (1 hunks)
  • src/main/java/com/iemr/common/dto/identity/CommonIdentityDTO.java (1 hunks)
  • src/main/java/com/iemr/common/model/beneficiary/BeneficiaryModel.java (2 hunks)
  • src/main/java/com/iemr/common/model/notification/NotificationMessage.java (1 hunks)
  • src/main/java/com/iemr/common/service/beneficiary/RegisterBenificiaryServiceImpl.java (2 hunks)
  • src/main/java/com/iemr/common/service/beneficiaryOTPHandler/BeneficiaryOTPHandler.java (1 hunks)
  • src/main/java/com/iemr/common/service/beneficiaryOTPHandler/BeneficiaryOTPHandlerImpl.java (1 hunks)
  • src/main/java/com/iemr/common/service/firebaseNotification/FirebaseNotificationService.java (1 hunks)
  • src/main/java/com/iemr/common/service/notification/NotificationService.java (1 hunks)
  • src/main/java/com/iemr/common/utils/JwtUserIdValidationFilter.java (1 hunks)
⏰ Context from checks skipped due to timeout of 90000ms (4)
  • GitHub Check: style-check / checkstyle
  • GitHub Check: Package-test
  • GitHub Check: Analyze (java)
  • GitHub Check: Build
πŸ”‡ Additional comments (8)
src/main/java/com/iemr/common/service/notification/NotificationService.java (1)

58-58: No-op change, blank line added

The added blank line at the end of the interface declaration has no functional impact.

src/main/java/com/iemr/common/utils/JwtUserIdValidationFilter.java (1)

62-62: No-op change, blank line added

A blank line was inserted after the logging statement. This is purely cosmetic and does not alter any logic.

pom.xml (1)

114-119: Add Firebase Admin SDK dependency

The Firebase Admin SDK (firebase-admin:9.4.3) is correctly added to support FCM integration. Ensure this version is compatible with Spring Boot 3.2.2 and monitor for newer stable releases to keep dependencies up-to-date.

src/main/java/com/iemr/common/model/notification/NotificationMessage.java (1)

1-15: New DTO for Firebase notifications

The NotificationMessage class cleanly encapsulates the notification payload using Lombok’s @Data. All required fields are present and appropriately typed.

src/main/java/com/iemr/common/controller/otp/OTPGateway.java (2)

56-56: Good logging additions for debugging OTP flows.

The request logging will help trace OTP operations during troubleshooting.

Also applies to: 103-103


64-65: ```shell
#!/bin/bash

Locate OTPGateway methods and inspect return values and conditions

1. Find all occurrences of sendOTP and show context

echo "=== sendOTP references ==="
rg -n 'sendOTP' src
for file in $(rg -l 'sendOTP' src); do
echo -e "\n--- Context in $file ---"
rg -n -C5 'sendOTP' "$file"
done

2. Find all occurrences of resendOTP and show context

echo -e "\n=== resendOTP references ==="
rg -n 'resendOTP' src
for file in $(rg -l 'resendOTP' src); do
echo -e "\n--- Context in $file ---"
rg -n -C5 'resendOTP' "$file"
done

3. Show previous exact match check

echo -e "\n=== Previous equalsIgnoreCase usage in OTPGateway.java ==="
rg -n -C3 'equalsIgnoreCase' src/main/java/com/iemr/common/controller/otp/OTPGateway.java

4. Show new contains("otp") check

echo -e "\n=== New contains("otp") usage in OTPGateway.java ==="
rg -n -C3 'contains("otp")' src/main/java/com/iemr/common/controller/otp/OTPGateway.java


</details>
<details>
<summary>src/main/java/com/iemr/common/service/beneficiary/RegisterBenificiaryServiceImpl.java (1)</summary>

`167-167`: **Good addition of debug logging.**

The logging will help trace beneficiary registration operations.

</details>
<details>
<summary>src/main/java/com/iemr/common/service/beneficiaryOTPHandler/BeneficiaryOTPHandlerImpl.java (1)</summary>

`132-133`: **Approve secure OTP generation implementation.**

The use of `SecureRandom.getInstanceStrong()` and 6-digit OTP generation provides good security practices for OTP generation.

</details>

</blockquote></details>

</details>

<!-- This is an auto-generated comment by CodeRabbit for review status -->

Comment on lines +172 to +175
identityDTO.setIsConsent(beneficiaryModel.getIsConsent());
identityDTO.setFaceEmbedding(beneficiaryModel.getFaceEmbedding());
identityDTO.setEmergencyRegistration(beneficiaryModel.isEmergencyRegistration());
identityDTO.setIsConsent(beneficiaryModel.getIsConsent());
Copy link
Contributor

Choose a reason for hiding this comment

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

⚠️ Potential issue

Remove duplicate assignment.

The isConsent field is being set twice consecutively from the same source, which is redundant.

 identityDTO.setIsConsent(beneficiaryModel.getIsConsent());
 identityDTO.setFaceEmbedding(beneficiaryModel.getFaceEmbedding());
 identityDTO.setEmergencyRegistration(beneficiaryModel.isEmergencyRegistration());
-identityDTO.setIsConsent(beneficiaryModel.getIsConsent());
πŸ“ 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
identityDTO.setIsConsent(beneficiaryModel.getIsConsent());
identityDTO.setFaceEmbedding(beneficiaryModel.getFaceEmbedding());
identityDTO.setEmergencyRegistration(beneficiaryModel.isEmergencyRegistration());
identityDTO.setIsConsent(beneficiaryModel.getIsConsent());
identityDTO.setIsConsent(beneficiaryModel.getIsConsent());
identityDTO.setFaceEmbedding(beneficiaryModel.getFaceEmbedding());
identityDTO.setEmergencyRegistration(beneficiaryModel.isEmergencyRegistration());
πŸ€– Prompt for AI Agents
In
src/main/java/com/iemr/common/service/beneficiary/RegisterBenificiaryServiceImpl.java
around lines 172 to 175, there is a duplicate assignment of the isConsent field
on identityDTO from beneficiaryModel. Remove the redundant second call to
identityDTO.setIsConsent to avoid unnecessary repetition.

Comment on lines +80 to +81
@Expose
private Boolean isConsent=false;
Copy link
Contributor

Choose a reason for hiding this comment

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

⚠️ Potential issue

Fix duplicate field declaration.

Two isConsent fields are declared with identical names, types, and initialization values. This will cause compilation issues or unexpected behavior.

 @Expose
 private List<BenPhoneMapModel> parentBenPhoneMaps;
-@Expose
-private Boolean isConsent=false;


 @Expose
 private String beneficiaryID;
 @Expose
 private Short titleId;
 @Expose
 private String titleName;
 @Expose
 private TitleModel m_title;
 @Expose
 private String firstName;
 @Expose
 private Boolean isConsent=false;

Also applies to: 94-95

πŸ€– Prompt for AI Agents
In src/main/java/com/iemr/common/model/beneficiary/BeneficiaryModel.java at
lines 80-81 and 94-95, there are duplicate declarations of the field isConsent
with the same name, type, and initialization. Remove one of the duplicate
declarations in each case to ensure only a single isConsent field exists,
preventing compilation errors and unexpected behavior.

private Integer beneficiaryRegId;
private Integer communityId;
private String community;
private Boolean isConsent=false;
Copy link
Contributor

Choose a reason for hiding this comment

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

⚠️ Potential issue

Fix duplicate field declaration.

Two isConsent fields are declared - one initialized to false and one uninitialized. This will cause compilation issues or unexpected behavior.

 private String community;
-private Boolean isConsent=false;

 private Timestamp dob;
 private Integer ageAtMarriage;
 private Integer educationId;
 private String education;
 private Boolean emergencyRegistration = false;
-private Boolean isConsent;
+private Boolean isConsent = false;

Also applies to: 64-64

πŸ€– Prompt for AI Agents
In src/main/java/com/iemr/common/dto/identity/CommonIdentityDTO.java at lines 57
and 64, there are duplicate declarations of the field isConsent, one initialized
to false and one uninitialized. Remove one of these declarations to eliminate
the duplicate field error and ensure only a single isConsent field exists in the
class.

@Data
public class BeneficiaryConsentRequest {
private String mobNo;
private int otp;
Copy link
Contributor

Choose a reason for hiding this comment

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

⚠️ Potential issue

Change OTP field type to String to preserve leading zeros.

Using int for OTP can cause issues if the OTP starts with zero, as leading zeros will be lost. OTPs should be treated as strings to preserve their exact format.

-    private int otp;
+    private String otp;
πŸ“ 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
private int otp;
- private int otp;
+ private String otp;
πŸ€– Prompt for AI Agents
In
src/main/java/com/iemr/common/data/beneficiaryConsent/BeneficiaryConsentRequest.java
at line 8, change the type of the otp field from int to String to ensure leading
zeros are preserved and the OTP format remains accurate.

Comment on lines +8 to +12
public String sendOTP(BeneficiaryConsentRequest obj) throws Exception;

public JSONObject validateOTP(BeneficiaryConsentRequest obj) throws Exception;

public String resendOTP(BeneficiaryConsentRequest obj) throws Exception;
Copy link
Contributor

Choose a reason for hiding this comment

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

πŸ› οΈ Refactor suggestion

Replace generic Exception with specific exception types.

Using generic Exception makes it difficult for clients to handle specific error scenarios. Consider using specific exception types or creating custom exceptions for different failure modes.

-    public String sendOTP(BeneficiaryConsentRequest obj) throws Exception;
+    public String sendOTP(BeneficiaryConsentRequest obj) throws OTPGenerationException, SMSDeliveryException;

-    public JSONObject validateOTP(BeneficiaryConsentRequest obj) throws Exception;
+    public JSONObject validateOTP(BeneficiaryConsentRequest obj) throws OTPValidationException;

-    public String resendOTP(BeneficiaryConsentRequest obj) throws Exception;
+    public String resendOTP(BeneficiaryConsentRequest obj) throws OTPGenerationException, SMSDeliveryException;
πŸ“ 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
public String sendOTP(BeneficiaryConsentRequest obj) throws Exception;
public JSONObject validateOTP(BeneficiaryConsentRequest obj) throws Exception;
public String resendOTP(BeneficiaryConsentRequest obj) throws Exception;
public String sendOTP(BeneficiaryConsentRequest obj) throws OTPGenerationException, SMSDeliveryException;
public JSONObject validateOTP(BeneficiaryConsentRequest obj) throws OTPValidationException;
public String resendOTP(BeneficiaryConsentRequest obj) throws OTPGenerationException, SMSDeliveryException;
πŸ€– Prompt for AI Agents
In
src/main/java/com/iemr/common/service/beneficiaryOTPHandler/BeneficiaryOTPHandler.java
around lines 8 to 12, replace the generic Exception in the method signatures of
sendOTP, validateOTP, and resendOTP with more specific exception types relevant
to the possible failure scenarios. Identify the specific exceptions these
methods can throw or define custom exceptions to clearly communicate error
conditions, and update the method signatures accordingly to improve error
handling clarity.

import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;

public class BeneficiaryConsentController {
Copy link
Contributor

Choose a reason for hiding this comment

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

⚠️ Potential issue

Add missing @RestController annotation.

The class is missing the @RestController annotation, which is required for Spring to recognize it as a REST controller and handle HTTP requests properly.

+@RestController
 public class BeneficiaryConsentController {
πŸ“ 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
public class BeneficiaryConsentController {
@RestController
public class BeneficiaryConsentController {
πŸ€– Prompt for AI Agents
In
src/main/java/com/iemr/common/controller/beneficiaryConsent/BeneficiaryConsentController.java
at line 20, the class lacks the @RestController annotation. Add the
@RestController annotation above the class declaration to ensure Spring
recognizes this class as a REST controller and properly handles HTTP requests.

Comment on lines 38 to 41
if (success.contains("otp"))
response.setResponse(success);
else
response.setError(500, "failure");
Copy link
Contributor

Choose a reason for hiding this comment

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

⚠️ Potential issue

Fix success condition logic mismatch.

The success condition checks for "otp" in the response, but the service method returns "success". This will cause all successful OTP sends to be treated as failures.

-            if (success.contains("otp"))
+            if (success.equals("success"))
                 response.setResponse(success);
             else
                 response.setError(500, "failure");
πŸ“ 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
if (success.contains("otp"))
response.setResponse(success);
else
response.setError(500, "failure");
if (success.equals("success"))
response.setResponse(success);
else
response.setError(500, "failure");
πŸ€– Prompt for AI Agents
In
src/main/java/com/iemr/common/controller/beneficiaryConsent/BeneficiaryConsentController.java
around lines 38 to 41, the condition incorrectly checks if the success string
contains "otp" instead of "success". Update the condition to check if the
success string contains "success" to correctly identify successful OTP sends and
avoid treating them as failures.

Comment on lines 80 to 82
OTPRequestParsor obj = InputMapper.gson().fromJson(requestOBJ, OTPRequestParsor.class);

String success = beneficiaryOTPHandler.resendOTP(obj);
Copy link
Contributor

Choose a reason for hiding this comment

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

⚠️ Potential issue

Fix parameter type inconsistency in resendConsent method.

Similar to validateConsent, this method uses OTPRequestParsor but the service method resendOTP expects BeneficiaryConsentRequest.

-            OTPRequestParsor obj = InputMapper.gson().fromJson(requestOBJ, OTPRequestParsor.class);
+            BeneficiaryConsentRequest obj = InputMapper.gson().fromJson(requestOBJ, BeneficiaryConsentRequest.class);
πŸ“ 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
OTPRequestParsor obj = InputMapper.gson().fromJson(requestOBJ, OTPRequestParsor.class);
String success = beneficiaryOTPHandler.resendOTP(obj);
BeneficiaryConsentRequest obj = InputMapper.gson().fromJson(requestOBJ, BeneficiaryConsentRequest.class);
String success = beneficiaryOTPHandler.resendOTP(obj);
πŸ€– Prompt for AI Agents
In
src/main/java/com/iemr/common/controller/beneficiaryConsent/BeneficiaryConsentController.java
around lines 80 to 82, the resendConsent method incorrectly parses the input
JSON into an OTPRequestParsor object, but the resendOTP service method expects a
BeneficiaryConsentRequest object. To fix this, change the parsing to convert the
requestOBJ JSON into a BeneficiaryConsentRequest instance before passing it to
resendOTP, ensuring the parameter types are consistent.

Comment on lines +85 to +88
if (success.contains("otp"))
response.setResponse(success);
else
response.setError(500, "failure");
Copy link
Contributor

Choose a reason for hiding this comment

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

⚠️ Potential issue

Fix success condition logic in resendConsent method.

Same issue as in sendConsent - the success condition logic is incorrect.

-            if (success.contains("otp"))
+            if (success.equals("success"))
                 response.setResponse(success);
             else
                 response.setError(500, "failure");
πŸ“ 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
if (success.contains("otp"))
response.setResponse(success);
else
response.setError(500, "failure");
if (success.equals("success"))
response.setResponse(success);
else
response.setError(500, "failure");
πŸ€– Prompt for AI Agents
In
src/main/java/com/iemr/common/controller/beneficiaryConsent/BeneficiaryConsentController.java
around lines 85 to 88, the success condition logic in the resendConsent method
is incorrect as it only checks if the success string contains "otp". Update the
condition to correctly reflect the success criteria used in the sendConsent
method, ensuring that the response is set to success only when the operation
truly succeeds; otherwise, set the error response appropriately.

Comment on lines 57 to 59
OTPRequestParsor obj = InputMapper.gson().fromJson(requestOBJ, OTPRequestParsor.class);

JSONObject responseOBJ = beneficiaryOTPHandler.validateOTP(obj);
Copy link
Contributor

Choose a reason for hiding this comment

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

⚠️ Potential issue

Fix parameter type inconsistency causing method signature mismatch.

The validateConsent method uses OTPRequestParsor but the service method validateOTP expects BeneficiaryConsentRequest. This will cause a compilation error or runtime issues.

-            OTPRequestParsor obj = InputMapper.gson().fromJson(requestOBJ, OTPRequestParsor.class);
+            BeneficiaryConsentRequest obj = InputMapper.gson().fromJson(requestOBJ, BeneficiaryConsentRequest.class);
πŸ“ 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
OTPRequestParsor obj = InputMapper.gson().fromJson(requestOBJ, OTPRequestParsor.class);
JSONObject responseOBJ = beneficiaryOTPHandler.validateOTP(obj);
BeneficiaryConsentRequest obj = InputMapper.gson().fromJson(requestOBJ, BeneficiaryConsentRequest.class);
JSONObject responseOBJ = beneficiaryOTPHandler.validateOTP(obj);
πŸ€– Prompt for AI Agents
In
src/main/java/com/iemr/common/controller/beneficiaryConsent/BeneficiaryConsentController.java
around lines 57 to 59, the parameter type passed to the validateOTP method is
OTPRequestParsor, but validateOTP expects a BeneficiaryConsentRequest object.
Change the parameter type to BeneficiaryConsentRequest by parsing the requestOBJ
into BeneficiaryConsentRequest instead of OTPRequestParsor before calling
validateOTP to fix the method signature mismatch.

Copy link
Contributor

@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: 6

♻️ Duplicate comments (6)
src/main/java/com/iemr/common/controller/firebaseNotification/FirebaseNotificationController.java (2)

44-47: Add error handling and input validation.

The sendNotification endpoint still lacks proper error handling and input validation as previously identified. This could lead to runtime exceptions and poor user experience.


44-47: Add input validation and proper error handling.

The endpoint lacks essential input validation and error handling, which could lead to runtime exceptions and poor user experience.

src/main/java/com/iemr/common/service/firebaseNotification/FirebaseNotificationService.java (4)

74-74: Use the autowired FirebaseMessaging instance instead of getInstance().

The code still uses FirebaseMessaging.getInstance() instead of the autowired firebaseMessaging field, which bypasses dependency injection.

-String response = FirebaseMessaging.getInstance().send(message);
+String response = firebaseMessaging.send(message);

66-81: Improve error handling and add input validation.

The sendNotification method still lacks proper input validation and error logging as previously identified. The generic error message doesn't help with debugging.


74-74: Use the autowired FirebaseMessaging instance instead of getInstance().

The code bypasses dependency injection by using FirebaseMessaging.getInstance() instead of the autowired firebaseMessaging field.


66-81: Add comprehensive input validation and improve error handling.

The method lacks essential input validation and provides insufficient error details for debugging.

🧹 Nitpick comments (3)
src/main/java/com/iemr/common/service/firebaseNotification/FirebaseNotificationService.java (2)

89-89: Replace mixed language comments with English.

Comments contain Hindi text mixed with English, which affects code readability and maintainability in an international development environment.

-            // User token exist karta hai => update karna hai
+            // User token exists => update it
-            // User token nahi mila => naya insert karna hai
+            // User token not found => insert new one
-                .map(UserTokenData::getToken)  // mil gaya to token nikalo
-                .orElse(null); // nah
+                .map(UserTokenData::getToken)  // if found, extract token
+                .orElse(null); // if not found, return null

Also applies to: 94-94, 109-111


89-89: Use consistent language in code comments.

The Hindi comments reduce code readability for international development teams. Consider using English consistently throughout the codebase.

-            // User token exist karta hai => update karna hai
+            // User token exists => update it
-            // User token nahi mila => naya insert karna hai
+            // User token not found => insert new record

Also applies to: 94-94

src/main/java/com/iemr/common/controller/firebaseNotification/FirebaseNotificationController.java (1)

54-58: Improve response consistency and add logging.

While this endpoint properly handles exceptions with IEMRException, consider returning ResponseEntity<String> for consistency with HTTP status codes and add logging for better observability.

 @RequestMapping(value = "getToken",method = RequestMethod.GET,headers = "Authorization")
-public String  getUserToken() throws IEMRException {
+public ResponseEntity<String> getUserToken() throws IEMRException {
+    try {
+        String token = firebaseNotificationService.getUserToken();
+        if (token != null) {
+            logger.info("Token retrieved successfully");
+            return ResponseEntity.ok(token);
+        } else {
+            logger.warn("No token found for user");
+            return ResponseEntity.notFound().build();
+        }
+    } catch (IEMRException e) {
+        logger.error("Error retrieving user token: ", e);
+        throw e; // Re-throw to maintain existing behavior
+    }
-    return  firebaseNotificationService.getUserToken();
 }
πŸ“œ Review details

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

πŸ“₯ Commits

Reviewing files that changed from the base of the PR and between cafa96e and 465795f.

πŸ“’ Files selected for processing (6)
  • src/main/java/com/iemr/common/controller/firebaseNotification/FirebaseNotificationController.java (1 hunks)
  • src/main/java/com/iemr/common/data/userToken/UserTokenData.java (1 hunks)
  • src/main/java/com/iemr/common/model/notification/NotificationMessage.java (1 hunks)
  • src/main/java/com/iemr/common/model/notification/UserToken.java (1 hunks)
  • src/main/java/com/iemr/common/repo/userToken/UserTokenRepo.java (1 hunks)
  • src/main/java/com/iemr/common/service/firebaseNotification/FirebaseNotificationService.java (1 hunks)
βœ… Files skipped from review due to trivial changes (3)
  • src/main/java/com/iemr/common/model/notification/UserToken.java
  • src/main/java/com/iemr/common/repo/userToken/UserTokenRepo.java
  • src/main/java/com/iemr/common/data/userToken/UserTokenData.java
🚧 Files skipped from review as they are similar to previous changes (1)
  • src/main/java/com/iemr/common/model/notification/NotificationMessage.java
⏰ Context from checks skipped due to timeout of 90000ms (4)
  • GitHub Check: style-check / checkstyle
  • GitHub Check: Analyze (java)
  • GitHub Check: Package-test
  • GitHub Check: Build
πŸ”‡ Additional comments (1)
src/main/java/com/iemr/common/service/firebaseNotification/FirebaseNotificationService.java (1)

105-112: ```shell
#!/bin/bash

Locate and inspect the UserTokenData entity to verify the type of its ID field

1. Find the file

file=$(find . -type f -name "UserTokenData.java" | head -n1)
echo "Found file: $file"

2. If found, print the class declaration and its field definitions (first 200 lines)

if [[ -n "$file" ]]; then
echo "----- Begin UserTokenData.java -----"
sed -n '1,200p' "$file"
echo "----- End UserTokenData.java -----"
else
echo "UserTokenData.java not found in repository."
fi


</details>

</blockquote></details>

</details>

<!-- This is an auto-generated comment by CodeRabbit for review status -->

Comment on lines +49 to +52
@RequestMapping(value = "updateToken",method = RequestMethod.POST)
public String updateToken(@RequestBody UserToken userToken){
return firebaseNotificationService.updateToken(userToken);
}
Copy link
Contributor

Choose a reason for hiding this comment

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

πŸ› οΈ Refactor suggestion

Add error handling and input validation for updateToken endpoint.

Similar to the sendNotification endpoint, this method lacks error handling and input validation. Consider returning proper HTTP status codes and handling potential exceptions.

 @RequestMapping(value = "updateToken",method = RequestMethod.POST)
-public String  updateToken(@RequestBody UserToken userToken){
+public ResponseEntity<String> updateToken(@Valid @RequestBody UserToken userToken){
+    try {
+        if (userToken == null || userToken.getUserId() == null || userToken.getToken() == null) {
+            return ResponseEntity.badRequest().body("User ID and token are required");
+        }
+        String result = firebaseNotificationService.updateToken(userToken);
+        return ResponseEntity.ok(result);
+    } catch (Exception e) {
+        logger.error("Error updating token: ", e);
+        return ResponseEntity.internalServerError().body("Failed to update token");
+    }
-    return firebaseNotificationService.updateToken(userToken);
 }
πŸ“ 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
@RequestMapping(value = "updateToken",method = RequestMethod.POST)
public String updateToken(@RequestBody UserToken userToken){
return firebaseNotificationService.updateToken(userToken);
}
@RequestMapping(value = "updateToken", method = RequestMethod.POST)
public ResponseEntity<String> updateToken(@Valid @RequestBody UserToken userToken) {
try {
if (userToken == null || userToken.getUserId() == null || userToken.getToken() == null) {
return ResponseEntity.badRequest().body("User ID and token are required");
}
String result = firebaseNotificationService.updateToken(userToken);
return ResponseEntity.ok(result);
} catch (Exception e) {
logger.error("Error updating token: ", e);
return ResponseEntity.internalServerError().body("Failed to update token");
}
}
πŸ€– Prompt for AI Agents
In
src/main/java/com/iemr/common/controller/firebaseNotification/FirebaseNotificationController.java
around lines 49 to 52, the updateToken method lacks error handling and input
validation. Add validation to check the userToken input for null or invalid
fields before processing. Wrap the service call in a try-catch block to handle
exceptions and return appropriate HTTP status codes, such as 400 for bad input
and 500 for server errors, using ResponseEntity to provide meaningful responses.

πŸ› οΈ Refactor suggestion

Add input validation and error handling for consistency.

Similar to the sendNotificationByToken method, this endpoint lacks input validation and error handling. Consider applying the same improvements for consistency.

 @RequestMapping(value = "updateToken",method = RequestMethod.POST)
-public String  updateToken(@RequestBody UserToken userToken){
+public ResponseEntity<String> updateToken(@Valid @RequestBody UserToken userToken){
+    try {
+        if (userToken == null) {
+            return ResponseEntity.badRequest().body("User token is required");
+        }
         String result = firebaseNotificationService.updateToken(userToken);
-        return firebaseNotificationService.updateToken(userToken);
+        return ResponseEntity.ok(result);
+    } catch (Exception e) {
+        logger.error("Error updating token: ", e);
+        return ResponseEntity.internalServerError().body("Failed to update token");
+    }
 }

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

πŸ€– Prompt for AI Agents
In
src/main/java/com/iemr/common/controller/firebaseNotification/FirebaseNotificationController.java
around lines 49 to 52, the updateToken method lacks input validation and error
handling. Add validation to check if the userToken object and its required
fields are not null or empty before proceeding. Wrap the service call in a
try-catch block to handle potential exceptions and return appropriate error
responses or messages for consistency with the sendNotificationByToken method.

Comment on lines +54 to +58
@RequestMapping(value = "getToken",method = RequestMethod.GET,headers = "Authorization")
public String getUserToken() throws IEMRException {

return firebaseNotificationService.getUserToken();
}
Copy link
Contributor

Choose a reason for hiding this comment

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

πŸ› οΈ Refactor suggestion

Improve error handling for getUserToken endpoint.

The getUserToken method throws IEMRException but doesn't handle it properly at the controller level. Consider wrapping in try-catch and returning appropriate HTTP responses.

 @RequestMapping(value = "getToken",method = RequestMethod.GET,headers = "Authorization")
-public String  getUserToken() throws IEMRException {
-
-    return  firebaseNotificationService.getUserToken();
+public ResponseEntity<String> getUserToken() {
+    try {
+        String token = firebaseNotificationService.getUserToken();
+        if (token == null) {
+            return ResponseEntity.notFound().build();
+        }
+        return ResponseEntity.ok(token);
+    } catch (IEMRException e) {
+        logger.error("Error retrieving user token: ", e);
+        return ResponseEntity.internalServerError().body("Failed to retrieve token");
+    }
 }
πŸ€– Prompt for AI Agents
In
src/main/java/com/iemr/common/controller/firebaseNotification/FirebaseNotificationController.java
around lines 54 to 58, the getUserToken method declares throwing IEMRException
but does not handle it within the controller. Modify the method to wrap the call
to firebaseNotificationService.getUserToken() in a try-catch block, catch
IEMRException, and return an appropriate HTTP response (e.g., ResponseEntity
with error status and message) instead of letting the exception propagate.

Comment on lines 105 to 112
public String getUserToken() throws IEMRException {
HttpServletRequest requestHeader = ((ServletRequestAttributes) RequestContextHolder.getRequestAttributes())
.getRequest();
String jwtTokenFromCookie = cookieUtil.getJwtTokenFromCookie(requestHeader);
return userTokenRepo.findById(Integer.parseInt(jwtUtil.extractUserId(jwtTokenFromCookie))) // because your userId is Long in DB
.map(UserTokenData::getToken) // mil gaya to token nikalo
.orElse(null); // nah
}
Copy link
Contributor

Choose a reason for hiding this comment

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

πŸ› οΈ Refactor suggestion

Improve error handling and add null checks in getUserToken method.

The method lacks proper error handling for potential JWT parsing failures and database access issues.

 public String getUserToken() throws IEMRException {
-    HttpServletRequest requestHeader = ((ServletRequestAttributes) RequestContextHolder.getRequestAttributes())
-            .getRequest();
-    String jwtTokenFromCookie = cookieUtil.getJwtTokenFromCookie(requestHeader);
-    return userTokenRepo.findById(Integer.parseInt(jwtUtil.extractUserId(jwtTokenFromCookie)))
-            .map(UserTokenData::getToken)
-            .orElse(null);
+    try {
+        ServletRequestAttributes attributes = (ServletRequestAttributes) RequestContextHolder.getRequestAttributes();
+        if (attributes == null) {
+            throw new IEMRException("No request context available");
+        }
+        
+        HttpServletRequest requestHeader = attributes.getRequest();
+        String jwtTokenFromCookie = cookieUtil.getJwtTokenFromCookie(requestHeader);
+        
+        if (jwtTokenFromCookie == null) {
+            throw new IEMRException("JWT token not found in cookie");
+        }
+        
+        String userIdStr = jwtUtil.extractUserId(jwtTokenFromCookie);
+        if (userIdStr == null) {
+            throw new IEMRException("User ID not found in JWT token");
+        }
+        
+        Integer userId = Integer.parseInt(userIdStr);
+        return userTokenRepo.findById(userId)
+                .map(UserTokenData::getToken)
+                .orElse(null);
+    } catch (NumberFormatException e) {
+        logger.error("Invalid user ID format in JWT token", e);
+        throw new IEMRException("Invalid user ID format");
+    } catch (Exception e) {
+        logger.error("Error retrieving user token", e);
+        throw new IEMRException("Failed to retrieve user token");
+    }
 }
πŸ“ 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
public String getUserToken() throws IEMRException {
HttpServletRequest requestHeader = ((ServletRequestAttributes) RequestContextHolder.getRequestAttributes())
.getRequest();
String jwtTokenFromCookie = cookieUtil.getJwtTokenFromCookie(requestHeader);
return userTokenRepo.findById(Integer.parseInt(jwtUtil.extractUserId(jwtTokenFromCookie))) // because your userId is Long in DB
.map(UserTokenData::getToken) // mil gaya to token nikalo
.orElse(null); // nah
}
public String getUserToken() throws IEMRException {
try {
ServletRequestAttributes attributes = (ServletRequestAttributes) RequestContextHolder.getRequestAttributes();
if (attributes == null) {
throw new IEMRException("No request context available");
}
HttpServletRequest requestHeader = attributes.getRequest();
String jwtTokenFromCookie = cookieUtil.getJwtTokenFromCookie(requestHeader);
if (jwtTokenFromCookie == null) {
throw new IEMRException("JWT token not found in cookie");
}
String userIdStr = jwtUtil.extractUserId(jwtTokenFromCookie);
if (userIdStr == null) {
throw new IEMRException("User ID not found in JWT token");
}
Integer userId = Integer.parseInt(userIdStr);
return userTokenRepo.findById(userId)
.map(UserTokenData::getToken)
.orElse(null);
} catch (NumberFormatException e) {
logger.error("Invalid user ID format in JWT token", e);
throw new IEMRException("Invalid user ID format");
} catch (Exception e) {
logger.error("Error retrieving user token", e);
throw new IEMRException("Failed to retrieve user token");
}
}
πŸ€– Prompt for AI Agents
In
src/main/java/com/iemr/common/service/firebaseNotification/FirebaseNotificationService.java
around lines 105 to 112, the getUserToken method lacks error handling for JWT
parsing and database access. Add try-catch blocks to handle exceptions from
jwtUtil.extractUserId and userTokenRepo.findById calls. Also, include null
checks for the JWT token extracted from the cookie before parsing and handle
cases where the user ID or token is not found, returning null or throwing a
custom exception as appropriate.

Comment on lines 83 to 103
public String updateToken(UserToken userToken) {
Optional<UserTokenData> existingTokenData = userTokenRepo.findById(userToken.getUserId());

UserTokenData userTokenData;

if (existingTokenData.isPresent()) {
// User token exist karta hai => update karna hai
userTokenData = existingTokenData.get();
userTokenData.setToken(userToken.getToken());
userTokenData.setUpdatedAt(new Timestamp(System.currentTimeMillis()));
} else {
// User token nahi mila => naya insert karna hai
userTokenData = new UserTokenData();
userTokenData.setUserId(userToken.getUserId());
userTokenData.setToken(userToken.getToken());
userTokenData.setUpdatedAt(new Timestamp(System.currentTimeMillis()));
}

userTokenRepo.save(userTokenData);
return "Save Successfully";
}
Copy link
Contributor

Choose a reason for hiding this comment

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

πŸ› οΈ Refactor suggestion

Add input validation and improve error handling in updateToken method.

The updateToken method lacks input validation and proper error handling, which could lead to runtime exceptions.

 public String updateToken(UserToken userToken) {
+    if (userToken == null) {
+        logger.error("UserToken is null");
+        return "Error: User token data is required";
+    }
+    
+    if (userToken.getUserId() == null || userToken.getToken() == null || userToken.getToken().trim().isEmpty()) {
+        logger.error("Invalid user token data - userId or token is missing");
+        return "Error: User ID and token are required";
+    }
+    
+    try {
         Optional<UserTokenData> existingTokenData = userTokenRepo.findById(userToken.getUserId());
         // ... rest of the method
         userTokenRepo.save(userTokenData);
+        logger.info("Token updated successfully for user: {}", userToken.getUserId());
         return "Save Successfully";
+    } catch (Exception e) {
+        logger.error("Error updating token for user: {}", userToken.getUserId(), e);
+        return "Error updating token: " + e.getMessage();
+    }
 }
πŸ“ 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
public String updateToken(UserToken userToken) {
Optional<UserTokenData> existingTokenData = userTokenRepo.findById(userToken.getUserId());
UserTokenData userTokenData;
if (existingTokenData.isPresent()) {
// User token exist karta hai => update karna hai
userTokenData = existingTokenData.get();
userTokenData.setToken(userToken.getToken());
userTokenData.setUpdatedAt(new Timestamp(System.currentTimeMillis()));
} else {
// User token nahi mila => naya insert karna hai
userTokenData = new UserTokenData();
userTokenData.setUserId(userToken.getUserId());
userTokenData.setToken(userToken.getToken());
userTokenData.setUpdatedAt(new Timestamp(System.currentTimeMillis()));
}
userTokenRepo.save(userTokenData);
return "Save Successfully";
}
public String updateToken(UserToken userToken) {
if (userToken == null) {
logger.error("UserToken is null");
return "Error: User token data is required";
}
if (userToken.getUserId() == null
|| userToken.getToken() == null
|| userToken.getToken().trim().isEmpty()) {
logger.error("Invalid user token data - userId or token is missing");
return "Error: User ID and token are required";
}
try {
Optional<UserTokenData> existingTokenData = userTokenRepo.findById(userToken.getUserId());
UserTokenData userTokenData;
if (existingTokenData.isPresent()) {
// User token exist karta hai => update karna hai
userTokenData = existingTokenData.get();
userTokenData.setToken(userToken.getToken());
userTokenData.setUpdatedAt(new Timestamp(System.currentTimeMillis()));
} else {
// User token nahi mila => naya insert karna hai
userTokenData = new UserTokenData();
userTokenData.setUserId(userToken.getUserId());
userTokenData.setToken(userToken.getToken());
userTokenData.setUpdatedAt(new Timestamp(System.currentTimeMillis()));
}
userTokenRepo.save(userTokenData);
logger.info("Token updated successfully for user: {}", userToken.getUserId());
return "Save Successfully";
} catch (Exception e) {
logger.error("Error updating token for user: {}", userToken.getUserId(), e);
return "Error updating token: " + e.getMessage();
}
}
πŸ€– Prompt for AI Agents
In
src/main/java/com/iemr/common/service/firebaseNotification/FirebaseNotificationService.java
between lines 83 and 103, the updateToken method lacks input validation and
error handling. Add checks to validate that the userToken and its userId and
token fields are not null or empty before proceeding. Wrap the database
operations in a try-catch block to handle potential exceptions, and return
meaningful error messages or throw custom exceptions as appropriate to improve
robustness.

πŸ› οΈ Refactor suggestion

Add input validation and error handling for database operations.

The method lacks input validation and proper error handling for database operations, which could lead to runtime exceptions.

 public String updateToken(UserToken userToken) {
+    if (userToken == null || userToken.getUserId() == null || userToken.getToken() == null) {
+        logger.error("Invalid user token data provided");
+        return "Error: Invalid user token data";
+    }
+    
+    try {
         Optional<UserTokenData> existingTokenData = userTokenRepo.findById(userToken.getUserId());
         // ... rest of the logic
         userTokenRepo.save(userTokenData);
-        return "Save Successfully";
+        logger.info("Token updated successfully for user: {}", userToken.getUserId());
+        return "Token saved successfully";
+    } catch (Exception e) {
+        logger.error("Error saving user token for user: {}", userToken.getUserId(), e);
+        return "Error saving token";
+    }
 }
πŸ“ 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
public String updateToken(UserToken userToken) {
Optional<UserTokenData> existingTokenData = userTokenRepo.findById(userToken.getUserId());
UserTokenData userTokenData;
if (existingTokenData.isPresent()) {
// User token exist karta hai => update karna hai
userTokenData = existingTokenData.get();
userTokenData.setToken(userToken.getToken());
userTokenData.setUpdatedAt(new Timestamp(System.currentTimeMillis()));
} else {
// User token nahi mila => naya insert karna hai
userTokenData = new UserTokenData();
userTokenData.setUserId(userToken.getUserId());
userTokenData.setToken(userToken.getToken());
userTokenData.setUpdatedAt(new Timestamp(System.currentTimeMillis()));
}
userTokenRepo.save(userTokenData);
return "Save Successfully";
}
public String updateToken(UserToken userToken) {
if (userToken == null || userToken.getUserId() == null || userToken.getToken() == null) {
logger.error("Invalid user token data provided");
return "Error: Invalid user token data";
}
try {
Optional<UserTokenData> existingTokenData = userTokenRepo.findById(userToken.getUserId());
UserTokenData userTokenData;
if (existingTokenData.isPresent()) {
// User token exist karta hai => update karna hai
userTokenData = existingTokenData.get();
userTokenData.setToken(userToken.getToken());
userTokenData.setUpdatedAt(new Timestamp(System.currentTimeMillis()));
} else {
// User token nahi mila => naya insert karna hai
userTokenData = new UserTokenData();
userTokenData.setUserId(userToken.getUserId());
userTokenData.setToken(userToken.getToken());
userTokenData.setUpdatedAt(new Timestamp(System.currentTimeMillis()));
}
userTokenRepo.save(userTokenData);
logger.info("Token updated successfully for user: {}", userToken.getUserId());
return "Token saved successfully";
} catch (Exception e) {
logger.error("Error saving user token for user: {}", userToken.getUserId(), e);
return "Error saving token";
}
}
πŸ€– Prompt for AI Agents
In
src/main/java/com/iemr/common/service/firebaseNotification/FirebaseNotificationService.java
around lines 83 to 103, the updateToken method lacks input validation and error
handling for database operations. Add validation to check if the userToken
parameter and its fields (userId and token) are not null or empty before
proceeding. Wrap the database operations in a try-catch block to handle
potential exceptions, and return appropriate error messages or throw custom
exceptions if validation fails or database errors occur.

@drtechie drtechie changed the base branch from develop to enhancement June 19, 2025 12:31
@drtechie drtechie changed the base branch from enhancement to 3.3.0 June 19, 2025 12:32
start-sms-scheduler=true
cron-scheduler-sms=0 0/1 * * * ? *

# Firebase Configuration
Copy link
Member

Choose a reason for hiding this comment

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

Please add similar variables to the _docker file

Copy link
Member

Choose a reason for hiding this comment

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

Copy link
Author

Choose a reason for hiding this comment

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

I have added firebase configuration in _ docker file

cors.allowed-origins=${CORS_ALLOWED_ORIGINS}

# Firebase Configuration
firebase.enabled=@env.FIREBASE_ENABLE@
Copy link
Member

Choose a reason for hiding this comment

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

this is not right. Use ${}

@drtechie
Copy link
Member

@SauravBizbRolly please look into the security hotspot?

@SauravBizbRolly
Copy link
Author

@drtechie
The security hotspot has been resolved.

Copy link

Quality Gate Failed Quality Gate failed

Failed conditions
4.4% Duplication on New Code (required ≀ 3%)
B Security Rating on New Code (required β‰₯ A)

See analysis details on SonarQube Cloud

Catch issues before they fail your Quality Gate with our IDE extension SonarQube for IDE

@drtechie drtechie merged commit 66c3702 into PSMRI:3.3.0 Jun 23, 2025
1 of 2 checks passed
@coderabbitai coderabbitai bot mentioned this pull request Jun 23, 2025
10 tasks
This was referenced Jul 3, 2025
Merged
@coderabbitai coderabbitai bot mentioned this pull request Aug 28, 2025
10 tasks
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.

3 participants