-
Notifications
You must be signed in to change notification settings - Fork 31
Release 3.6.0 #99
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. Weβll occasionally send you account related emails.
Already on GitHub? Sign in to your account
base: main
Are you sure you want to change the base?
Release 3.6.0 #99
Changes from all commits
3c2135e
23cccac
83f693e
8ae4c09
cdd7b2a
128c8f9
a069382
3fd079a
fcbc3da
5cd719d
2a55c54
110fa59
83d3387
b1a893f
b67332f
bdde896
5315e05
486d412
4e5dab6
cd7f567
f06d077
84b679a
7b123e9
a28294f
093ba26
8820fe2
2aab70e
20eaaed
e04b9e5
bd11453
0addca8
b313e03
adc946d
4e3a304
875e40a
41162a4
27241e1
8fb55ce
45250ea
c824879
7231794
e763f9f
3d22060
226c101
74cd354
f719ba5
bb00223
d52c950
86ed8cb
3ae6436
67a4240
f8e646e
8c48069
5f8dcf2
30d3317
6f5a101
1d45257
0acb505
608773a
5a7c6bf
ad6ff5e
eb98a5a
bffa971
c6ded08
2a04bfb
75d06ca
b421d8b
9c206a4
76db67c
d5b3e20
711128e
091bd75
f76f68c
a52081b
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
| Original file line number | Diff line number | Diff line change | ||||||||||||||||
|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
|
|
@@ -5,7 +5,7 @@ | |||||||||||||||||
| <modelVersion>4.0.0</modelVersion> | ||||||||||||||||||
| <groupId>com.iemr.admin</groupId> | ||||||||||||||||||
| <artifactId>admin-api</artifactId> | ||||||||||||||||||
| <version>3.4.0</version> | ||||||||||||||||||
| <version>3.6.0</version> | ||||||||||||||||||
| <packaging>war</packaging> | ||||||||||||||||||
| <name>Admin-API</name> | ||||||||||||||||||
| <description>Admin Page</description> | ||||||||||||||||||
|
|
@@ -54,6 +54,10 @@ | |||||||||||||||||
| <groupId>org.springframework.boot</groupId> | ||||||||||||||||||
| <artifactId>spring-boot-devtools</artifactId> | ||||||||||||||||||
| </dependency> | ||||||||||||||||||
| <dependency> | ||||||||||||||||||
| <groupId>com.fasterxml.jackson.dataformat</groupId> | ||||||||||||||||||
| <artifactId>jackson-dataformat-xml</artifactId> | ||||||||||||||||||
| </dependency> | ||||||||||||||||||
| <dependency> | ||||||||||||||||||
| <groupId>org.springframework.boot</groupId> | ||||||||||||||||||
| <artifactId>spring-boot-starter</artifactId> | ||||||||||||||||||
|
|
@@ -73,6 +77,11 @@ | |||||||||||||||||
| <groupId>org.springframework.boot</groupId> | ||||||||||||||||||
| <artifactId>spring-boot-starter-data-jpa</artifactId> | ||||||||||||||||||
| </dependency> | ||||||||||||||||||
| <dependency> | ||||||||||||||||||
| <groupId>org.apache.commons</groupId> | ||||||||||||||||||
| <artifactId>commons-compress</artifactId> | ||||||||||||||||||
| <version>1.21</version> | ||||||||||||||||||
| </dependency> | ||||||||||||||||||
|
Comment on lines
+81
to
+84
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. π‘ Verification agent π§© Analysis chaincommons-compress 1.21 is old; likely CVEs. Upgrade or let POI manage transitively. Bump to a current secure version or remove the direct pin. - <groupId>org.apache.commons</groupId>
- <artifactId>commons-compress</artifactId>
- <version>1.21</version>
+ <groupId>org.apache.commons</groupId>
+ <artifactId>commons-compress</artifactId>
+ <version>REPLACE_WITH_SECURE_VERSION</version>To check advisories: π Script executed: #!/bin/bash
rg -n 'commons-compress'
# If feasible in your env:
# mvn -q org.owasp:dependency-check-maven:check -DskipTestsLength of output: 80 π Web query: π‘ Result: Latest release: Apache Commons Compress 1.28.0 β released July 26, 2025. [1][2] Sources: π Web query: π‘ Result: Apache Commons Compress 1.21 is affected by multiple denialβofβservice vulnerabilities (notably CVE-2024-25710 β infinite loop when parsing DUMP files, and CVE-2024-26308 β outβofβmemory during unpacking of malformed Pack200 files). Upgrade to Commons Compress 1.26.0 or later to fix these issues. [1][2][3] Sources:
Upgrade org.apache.commons:commons-compress to 1.28.0 or later - <version>1.21</version>
+ <version>1.28.0</version>π Committable suggestion
Suggested change
π€ Prompt for AI Agents |
||||||||||||||||||
| <dependency> | ||||||||||||||||||
| <groupId>org.springframework.boot</groupId> | ||||||||||||||||||
| <artifactId>spring-boot-starter-web</artifactId> | ||||||||||||||||||
|
|
@@ -181,12 +190,7 @@ | |||||||||||||||||
| <groupId>org.apache.poi</groupId> | ||||||||||||||||||
| <artifactId>poi-ooxml</artifactId> | ||||||||||||||||||
| <version>5.2.3</version> | ||||||||||||||||||
| <exclusions> | ||||||||||||||||||
| <exclusion> | ||||||||||||||||||
| <groupId>org.apache.commons</groupId> | ||||||||||||||||||
| <artifactId>commons-compress</artifactId> | ||||||||||||||||||
| </exclusion> | ||||||||||||||||||
| </exclusions> | ||||||||||||||||||
|
|
||||||||||||||||||
| </dependency> | ||||||||||||||||||
|
|
||||||||||||||||||
| <!-- start newly added dependencies --> | ||||||||||||||||||
|
|
@@ -275,7 +279,7 @@ | |||||||||||||||||
| </dependencies> | ||||||||||||||||||
|
|
||||||||||||||||||
| <build> | ||||||||||||||||||
| <finalName>${artifactId}-${version}</finalName> | ||||||||||||||||||
| <finalName>${project.artifactId}-${project.version}</finalName> | ||||||||||||||||||
| <plugins> | ||||||||||||||||||
| <plugin> | ||||||||||||||||||
| <groupId>org.owasp</groupId> | ||||||||||||||||||
|
|
||||||||||||||||||
| Original file line number | Diff line number | Diff line change | ||
|---|---|---|---|---|
| @@ -0,0 +1,94 @@ | ||||
| package com.iemr.admin.controller.bulkRegistration; | ||||
|
|
||||
| import com.iemr.admin.repo.employeemaster.EmployeeMasterRepoo; | ||||
| import com.iemr.admin.service.bulkRegistration.BulkRegistrationService; | ||||
| import com.iemr.admin.service.bulkRegistration.BulkRegistrationServiceImpl; | ||||
| import com.iemr.admin.service.bulkRegistration.EmployeeXmlService; | ||||
| import com.iemr.admin.service.locationmaster.LocationMasterServiceInter; | ||||
| import io.swagger.v3.oas.annotations.Operation; | ||||
| import jakarta.servlet.http.Cookie; | ||||
| import jakarta.servlet.http.HttpServletRequest; | ||||
| import org.slf4j.Logger; | ||||
| import org.slf4j.LoggerFactory; | ||||
| import org.springframework.beans.factory.annotation.Autowired; | ||||
| import org.springframework.core.io.ClassPathResource; | ||||
| import org.springframework.http.HttpHeaders; | ||||
| import org.springframework.http.MediaType; | ||||
| import org.springframework.http.ResponseEntity; | ||||
| import org.springframework.web.bind.annotation.*; | ||||
|
|
||||
| import java.lang.reflect.Method; | ||||
| import java.util.HashMap; | ||||
| import java.util.Map; | ||||
|
|
||||
| @RestController | ||||
| public class BulkRegistrationController { | ||||
| @Autowired | ||||
| private EmployeeXmlService employeeXmlService; | ||||
| @Autowired | ||||
| BulkRegistrationServiceImpl bulkRegistrationServiceimpl; | ||||
| private Logger logger = LoggerFactory.getLogger(this.getClass().getSimpleName()); | ||||
|
|
||||
|
|
||||
| @Autowired | ||||
| BulkRegistrationService bulkRegistrationService; | ||||
|
|
||||
| @Autowired | ||||
| private EmployeeMasterRepoo employeeMasterRepoo; | ||||
| private Map<String, Object> errorResponse = new HashMap<>(); | ||||
|
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. π οΈ Refactor suggestion Remove unused field. The Apply this diff: - private Map<String, Object> errorResponse = new HashMap<>();π Committable suggestion
Suggested change
π€ Prompt for AI Agents |
||||
| @Autowired | ||||
| private LocationMasterServiceInter locationMasterServiceInter; | ||||
| private Map<String, Object> response = new HashMap<>(); | ||||
|
|
||||
| @PostMapping(value = "/bulkRegistration", headers = "Authorization") | ||||
| public ResponseEntity<Map<String, Object>> registerBulkUser(@RequestBody String m_user, @RequestHeader String authorization, @RequestParam String userName, | ||||
| HttpServletRequest request, @RequestParam Integer serviceProviderID | ||||
| ) { | ||||
|
|
||||
| bulkRegistrationServiceimpl.bulkRegistrationErrors.clear(); | ||||
| logger.info("Bulk registration request received. Request payload is omitted from logs."); | ||||
| try { | ||||
| bulkRegistrationService.registerBulkUser(m_user, authorization,userName,serviceProviderID); | ||||
| response.put("status", "Success"); | ||||
| response.put("statusCode", 200); | ||||
| response.put("totalUser", bulkRegistrationServiceimpl.totalEmployeeListSize); | ||||
| response.put("registeredUser", bulkRegistrationServiceimpl.m_bulkUser.size()); | ||||
| response.put("error", bulkRegistrationServiceimpl.errorLogs.toString()); | ||||
|
|
||||
| bulkRegistrationServiceimpl.m_bulkUser.clear(); | ||||
| bulkRegistrationServiceimpl.m_UserDemographics.clear(); | ||||
| bulkRegistrationServiceimpl.errorLogs.clear(); | ||||
| bulkRegistrationServiceimpl.totalEmployeeListSize=0; | ||||
|
|
||||
| } catch (Exception e) { | ||||
| response.put("message", e.getMessage()); | ||||
| response.put("statusCode", 500); | ||||
|
|
||||
| } | ||||
| return ResponseEntity.ok(response); | ||||
|
|
||||
| } | ||||
|
|
||||
| @GetMapping(value = "/download-error-sheet", headers = "Authorization") | ||||
| public ResponseEntity<byte[]> downloadErrorSheet() { | ||||
| try { | ||||
| byte[] fileContent = bulkRegistrationServiceimpl.insertErrorLog(); | ||||
|
|
||||
| HttpHeaders headers = new HttpHeaders(); | ||||
| headers.add("Content-Disposition", "attachment; filename=error_log.xlsx"); | ||||
|
|
||||
| if(!bulkRegistrationServiceimpl.bulkRegistrationErrors.isEmpty()){ | ||||
| bulkRegistrationServiceimpl.bulkRegistrationErrors.clear(); | ||||
| } | ||||
|
Comment on lines
+75
to
+82
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Potential race condition when clearing errors. The error list is cleared after the file content is generated, which could cause issues if multiple concurrent requests download the error sheet. One request might clear the errors while another is still processing them. Consider refactoring to:
Additionally, validate that errors exist before generating the file: @GetMapping(value = "/download-error-sheet", headers = "Authorization")
public ResponseEntity<byte[]> downloadErrorSheet() {
try {
+ if (bulkRegistrationServiceimpl.bulkRegistrationErrors.isEmpty()) {
+ return ResponseEntity.status(404)
+ .body("No errors to download".getBytes());
+ }
+
byte[] fileContent = bulkRegistrationServiceimpl.insertErrorLog();
HttpHeaders headers = new HttpHeaders();
headers.add("Content-Disposition", "attachment; filename=error_log.xlsx");
- if(!bulkRegistrationServiceimpl.bulkRegistrationErrors.isEmpty()){
- bulkRegistrationServiceimpl.bulkRegistrationErrors.clear();
- }
return ResponseEntity.ok()
.headers(headers)
.contentType(MediaType.APPLICATION_OCTET_STREAM)
.body(fileContent);
|
||||
| return ResponseEntity.ok() | ||||
| .headers(headers) | ||||
| .contentType(MediaType.APPLICATION_OCTET_STREAM) | ||||
| .body(fileContent); | ||||
|
|
||||
| } catch (Exception e) { | ||||
| return ResponseEntity.status(500).body(null); | ||||
| } | ||||
| } | ||||
|
|
||||
|
|
||||
| } | ||||
| Original file line number | Diff line number | Diff line change |
|---|---|---|
|
|
@@ -21,28 +21,34 @@ | |
| */ | ||
| package com.iemr.admin.controller.employeemaster; | ||
|
|
||
| import java.net.URLEncoder; | ||
| import java.nio.charset.StandardCharsets; | ||
| import java.util.Base64; | ||
|
|
||
| import org.slf4j.Logger; | ||
| import org.slf4j.LoggerFactory; | ||
| import org.springframework.beans.factory.annotation.Autowired; | ||
| import org.springframework.context.annotation.PropertySource; | ||
| import org.springframework.http.ContentDisposition; | ||
| import org.springframework.http.HttpHeaders; | ||
| import org.springframework.http.InvalidMediaTypeException; | ||
| import org.springframework.http.MediaType; | ||
| import org.springframework.http.ResponseEntity; | ||
|
|
||
| import org.springframework.web.bind.annotation.GetMapping; | ||
| import org.springframework.web.bind.annotation.PathVariable; | ||
| import org.springframework.web.bind.annotation.PostMapping; | ||
| import org.springframework.web.bind.annotation.RequestBody; | ||
| import org.springframework.web.bind.annotation.RequestMapping; | ||
| import org.springframework.web.bind.annotation.RequestMethod; | ||
| import org.springframework.web.bind.annotation.RestController; | ||
|
|
||
| import com.google.gson.JsonObject; | ||
| import com.iemr.admin.data.employeemaster.EmployeeSignature; | ||
| import com.iemr.admin.service.employeemaster.EmployeeSignatureServiceImpl; | ||
| import com.iemr.admin.utils.mapper.InputMapper; | ||
| import com.iemr.admin.utils.response.OutputResponse; | ||
|
|
||
| import io.swagger.v3.oas.annotations.Operation; | ||
| import jakarta.servlet.http.HttpServletRequest; | ||
|
|
||
|
|
||
| @PropertySource("classpath:application.properties") | ||
|
|
@@ -54,12 +60,10 @@ public class EmployeeSignatureController { | |
| @Autowired | ||
| EmployeeSignatureServiceImpl employeeSignatureServiceImpl; | ||
|
|
||
| private InputMapper inputMapper = new InputMapper(); | ||
|
|
||
| private Logger logger = LoggerFactory.getLogger(this.getClass().getSimpleName()); | ||
|
|
||
| @Operation(summary = "Upload") | ||
| @RequestMapping(value = "/upload", headers = "Authorization", method = { RequestMethod.POST }, produces = { | ||
| @PostMapping(value = "/upload", headers = "Authorization", produces = { | ||
| "application/json" }) | ||
| public String uploadFile(@RequestBody EmployeeSignature emp) { | ||
|
Comment on lines
+66
to
68
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. π‘ Verification agent π§© Analysis chainDrop mapping-level header constraint; declare consumes; return proper HTTP status codes.
Apply this diff to the mapping: -@PostMapping(value = "/upload", headers = "Authorization", produces = {
- "application/json" })
+@PostMapping(
+ value = "/upload",
+ consumes = "application/json",
+ produces = "application/json"
+)Example minimal method refactor (outside the selected range): public ResponseEntity<OutputResponse> uploadFile(@RequestBody EmployeeSignature emp) {
OutputResponse body = new OutputResponse();
try {
if (emp == null || emp.getFileContent() == null) {
body.setError("fileContent is required");
return ResponseEntity.badRequest().body(body);
}
emp.setSignature(Base64.getDecoder().decode(emp.getFileContent()));
Long id = employeeSignatureServiceImpl.uploadSignature(emp);
body.setResponse(id.toString());
return ResponseEntity.status(201).body(body);
} catch (IllegalArgumentException e) { // invalid Base64
body.setError("Invalid fileContent (Base64).");
return ResponseEntity.badRequest().body(body);
} catch (Exception e) {
body.setError("Signature upload failed.");
return ResponseEntity.internalServerError().body(body);
}
}To find other controllers still using the mapping-level header constraint: π Script executed: #!/bin/bash
rg -nP '@(PostMapping|GetMapping|RequestMapping)\([^)]*headers\s*=\s*"Authorization"' -g 'src/main/java/**'Length of output: 70355 Remove mapping-level
π€ Prompt for AI Agents |
||
| OutputResponse response = new OutputResponse(); | ||
|
|
@@ -83,22 +87,27 @@ public String uploadFile(@RequestBody EmployeeSignature emp) { | |
| } | ||
|
|
||
| @Operation(summary = "User id") | ||
| @RequestMapping(value = "/{userID}", headers = "Authorization", method = { RequestMethod.GET }) | ||
| @GetMapping(value = "/{userID}", headers = "Authorization") | ||
| public ResponseEntity<byte[]> fetchFile(@PathVariable("userID") Long userID) throws Exception { | ||
|
Comment on lines
+90
to
91
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. π οΈ Refactor suggestion Remove header constraint from GET mapping; optionally declare produces. Same rationale as POST. Since the response is binary and type varies, omit Apply this diff: -@GetMapping(value = "/{userID}", headers = "Authorization")
+@GetMapping(value = "/{userID}")Additionally, handle βnot found/emptyβ explicitly (outside selected range): EmployeeSignature sig = employeeSignatureServiceImpl.fetchSignature(userID);
if (sig == null || sig.getSignature() == null || sig.getSignature().length == 0) {
return ResponseEntity.notFound().build();
}π€ Prompt for AI Agents |
||
| OutputResponse response = new OutputResponse(); | ||
| logger.debug("File download for userID" + userID); | ||
|
|
||
| try { | ||
|
|
||
| EmployeeSignature userSignID = employeeSignatureServiceImpl.fetchSignature(userID); | ||
| HttpHeaders responseHeaders = new HttpHeaders(); | ||
| responseHeaders.set(HttpHeaders.CONTENT_DISPOSITION, | ||
| "inline; filename=\"" + userSignID.getFileName() + "\""); | ||
| responseHeaders.set("filename", userSignID.getFileName()); | ||
|
|
||
| return ResponseEntity.ok().contentType(MediaType.parseMediaType(userSignID.getFileType())) | ||
| .headers(responseHeaders).body(userSignID.getSignature()); | ||
|
|
||
| ContentDisposition cd = ContentDisposition.attachment() | ||
| .filename(userSignID.getFileName(), StandardCharsets.UTF_8).build(); | ||
| responseHeaders.setContentDisposition(cd); | ||
|
|
||
| MediaType mediaType; | ||
| try { | ||
| mediaType = MediaType.parseMediaType(userSignID.getFileType()); | ||
| } catch (InvalidMediaTypeException | NullPointerException e) { | ||
| mediaType = MediaType.APPLICATION_OCTET_STREAM; | ||
| } | ||
| byte[] fileBytes = userSignID.getSignature(); // MUST be byte[] | ||
| return ResponseEntity.ok().headers(responseHeaders).contentType(mediaType).contentLength(fileBytes.length) | ||
| .body(fileBytes); | ||
| } catch (Exception e) { | ||
| logger.error("Unexpected error:", e); | ||
| logger.error("File download for userID failed with exception " + e.getMessage(), e); | ||
|
|
@@ -117,7 +126,15 @@ public String existFile(@PathVariable("userID") Long userID) throws Exception { | |
| try { | ||
|
|
||
| Boolean userSignID = employeeSignatureServiceImpl.existSignature(userID); | ||
| response.setResponse(userSignID.toString()); | ||
| Boolean signatureActive = employeeSignatureServiceImpl.isSignatureActive(userID); | ||
|
|
||
| // Create JSON response with both fields | ||
| JsonObject responseData = new JsonObject(); | ||
| responseData.addProperty("response", userSignID.toString()); | ||
| responseData.addProperty("signStatus", signatureActive.toString()); | ||
|
|
||
| // Set the response (existing setResponse method will handle it) | ||
| response.setResponse(responseData.toString()); | ||
|
|
||
| } catch (Exception e) { | ||
| logger.error("Unexpected error:", e); | ||
|
|
@@ -128,4 +145,19 @@ public String existFile(@PathVariable("userID") Long userID) throws Exception { | |
| logger.debug("response" + response); | ||
| return response.toString(); | ||
| } | ||
|
|
||
| @Operation(summary = "Active or DeActive user Signature") | ||
| @PostMapping(value = "/activateOrdeActivateSignature", headers = "Authorization", produces = { "application/json" }) | ||
| public String ActivateUser(@RequestBody String activateUser, HttpServletRequest request) { | ||
| OutputResponse response = new OutputResponse(); | ||
| try { | ||
| EmployeeSignature empSignature = employeeSignatureServiceImpl.updateUserSignatureStatus(activateUser); | ||
| boolean active = empSignature.getDeleted() == null ? false : !empSignature.getDeleted(); | ||
| response.setResponse("{\"userID\":" + empSignature.getUserID() + ",\"active\":" + active + "}"); | ||
| } catch (Exception e) { | ||
| logger.error("Active or Deactivate User Signature failed with exception " + e.getMessage(), e); | ||
| response.setError(e); | ||
| } | ||
| return response.toString(); | ||
| } | ||
| } | ||
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,12 @@ | ||
| package com.iemr.admin.data.bulkuser; | ||
|
|
||
| import lombok.Data; | ||
|
|
||
| import java.util.List; | ||
|
|
||
| @Data | ||
| public class BulkRegistrationError { | ||
| String userName; | ||
| Integer rowNumber; | ||
| List<String> error; | ||
| } |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
π οΈ Refactor suggestion | π Major
π§© Analysis chain
Specify explicit version for jackson-dataformat-xml to align with Jackson ecosystem.
The dependency lacks an explicit
<version>tag. Since the project pins Jackson core (2.17.0-rc1) and databind (2.17.0-rc1), add an explicit version to ensure consistency and avoid runtime mismatches.Apply this diff to pin the version:
<dependency> <groupId>com.fasterxml.jackson.dataformat</groupId> <artifactId>jackson-dataformat-xml</artifactId> + <version>2.17.0</version> </dependency>π Web query:
π‘ Result:
Latest stable jackson-dataformat-xml: 2.20.0 (released Aug 28, 2025). [1]
Compatibility: modules should generally match the Jackson 2.x minor version. For use with Jackson 2.17.0-rc1 you should stick to the 2.17.x xml module (e.g., 2.17.2) β mixing 2.20.0 with a 2.17.0-rc1 core is not recommended and may cause incompatibilities. [2][3]
Sources:
Specify explicit version for jackson-dataformat-xml; use stable 2.17.x release instead of RC.
The dependency lacks an explicit
<version>tag, creating compatibility risk. Since the project pins Jackson core to 2.17.0-rc1, use a matching stable 2.17.x release (e.g., 2.17.2) rather than 2.17.0-rc1. Mixing 2.20.0 (the latest stable version) with 2.17.0-rc1 core is not recommended and may cause incompatibilities.Apply this diff instead:
<dependency> <groupId>com.fasterxml.jackson.dataformat</groupId> <artifactId>jackson-dataformat-xml</artifactId> + <version>2.17.2</version> </dependency>π Committable suggestion
π€ Prompt for AI Agents