From d4b5ff53da0824c3845ebba5b8ca6a45f673f13b Mon Sep 17 00:00:00 2001 From: DurgaPrasad-54 Date: Mon, 19 Jan 2026 16:22:25 +0530 Subject: [PATCH 01/13] Add documentation badge --- README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/README.md b/README.md index 5b8cca9c..b9176dec 100644 --- a/README.md +++ b/README.md @@ -1,6 +1,6 @@ # AMRIT - Mobile Medical Unit (MMU) Service -[![License: GPL v3](https://img.shields.io/badge/License-GPLv3-blue.svg)](https://www.gnu.org/licenses/gpl-3.0) ![branch parameter](https://github.com/PSMRI/MMU-API/actions/workflows/sast-and-package.yml/badge.svg) +[![License: GPL v3](https://img.shields.io/badge/License-GPLv3-blue.svg)](https://www.gnu.org/licenses/gpl-3.0) [![DeepWiki](https://img.shields.io/badge/DeepWiki-PSMRI%2FMMU--API-blue)](https://deepwiki.com/PSMRI/MMU-API) The AMRIT Mobile Medical Unit (MMU) service provides essential medical assistance to individuals without requiring them to be admitted to a hospital. This service operates through a mobile unit equipped with a laboratory for conducting medical tests and the capability to dispense medicines. The MMU employs an internet-connected device to collect and transmit medical data to the AMRIT application. It supports various medical standards and incorporates a feature that allows data capture and synchronization even when an internet connection is unavailable. From 576031c32886c75d67d2c0bfab9e2a4eb5432f9c Mon Sep 17 00:00:00 2001 From: DurgaPrasad-54 Date: Thu, 5 Feb 2026 20:29:38 +0530 Subject: [PATCH 02/13] chore(swagger): automate swagger sync to amrit-docs --- .github/workflows/swagger-json.yml | 100 ++++++++++++++++++ pom.xml | 5 + .../utils/mapper/SwaggerSecurityConfig.java | 21 ++++ .../resources/application-swagger.properties | 57 ++++++++++ 4 files changed, 183 insertions(+) create mode 100644 .github/workflows/swagger-json.yml create mode 100644 src/main/java/com/iemr/mmu/utils/mapper/SwaggerSecurityConfig.java create mode 100644 src/main/resources/application-swagger.properties diff --git a/.github/workflows/swagger-json.yml b/.github/workflows/swagger-json.yml new file mode 100644 index 00000000..171ca206 --- /dev/null +++ b/.github/workflows/swagger-json.yml @@ -0,0 +1,100 @@ +name: Sync Swagger to AMRIT-Docs + +on: + push: + branches: [ main ] + workflow_dispatch: + +jobs: + swagger-sync: + runs-on: ubuntu-latest + timeout-minutes: 20 + + steps: + - name: Checkout API repo (full history) + uses: actions/checkout@v4 + with: + fetch-depth: 0 + + - name: Set up Java 17 + uses: actions/setup-java@v4 + with: + distribution: temurin + java-version: 17 + cache: maven + + - name: Build API (skip tests) + run: mvn -B clean package -DskipTests + + - name: Install jq + run: sudo apt-get update && sudo apt-get install -y jq + + - name: Run API in swagger profile + run: | + nohup mvn spring-boot:run \ + -Dspring-boot.run.profiles=swagger \ + -Dspring-boot.run.arguments=--server.port=9090 \ + > app.log 2>&1 & + echo $! > api_pid.txt + + - name: Wait for API & fetch Swagger + run: | + for i in {1..40}; do + CODE=$(curl --connect-timeout 2 --max-time 5 -s -o swagger_raw.json -w "%{http_code}" http://localhost:9090/v3/api-docs || true) + + if [ "$CODE" = "200" ]; then + jq . swagger_raw.json > mmu-api.json || { + echo "Swagger JSON invalid" + cat swagger_raw.json + exit 1 + } + + if [ "$(jq '.paths | length' mmu-api.json)" -eq 0 ]; then + echo "Swagger paths empty – failing" + exit 1 + fi + + echo "Swagger generated successfully" + exit 0 + fi + + echo "Waiting for API... ($i)" + sleep 4 + done + + echo "Swagger not generated" + cat app.log || true + exit 1 + + - name: Stop API + if: always() + run: | + if [ -f api_pid.txt ]; then + kill -9 $(cat api_pid.txt) || true + fi + + - name: Checkout AMRIT-Docs + uses: actions/checkout@v4 + with: + repository: PSMRI/AMRIT-Docs + token: ${{ secrets.DOCS_REPO_TOKEN }} + path: amrit-docs + fetch-depth: 0 + + - name: Copy Swagger JSON + run: | + mkdir -p amrit-docs/docs/swagger + cp mmu-api.json amrit-docs/docs/swagger/mmu-api.json + + - name: Create Pull Request + uses: peter-evans/create-pull-request@v6 + with: + token: ${{ secrets.DOCS_REPO_TOKEN }} + path: amrit-docs + branch: auto/swagger-update-${{ github.run_id }}-${{ github.run_attempt }} + base: main + commit-message: "chore(docs): auto-update MMU-API swagger" + title: "chore(docs): auto-update MMU-API swagger" + body: | + This PR automatically updates MMU-API Swagger JSON + from the latest main branch build. diff --git a/pom.xml b/pom.xml index a15dfc50..6dfc6675 100644 --- a/pom.xml +++ b/pom.xml @@ -290,6 +290,11 @@ 0.12.6 runtime + + com.h2database + h2 + runtime + ${artifactId}-${version} diff --git a/src/main/java/com/iemr/mmu/utils/mapper/SwaggerSecurityConfig.java b/src/main/java/com/iemr/mmu/utils/mapper/SwaggerSecurityConfig.java new file mode 100644 index 00000000..4a470d1c --- /dev/null +++ b/src/main/java/com/iemr/mmu/utils/mapper/SwaggerSecurityConfig.java @@ -0,0 +1,21 @@ +package com.iemr.mmu.utils.mapper; + +import org.springframework.context.annotation.Configuration; +import org.springframework.context.annotation.Profile; +import org.springframework.security.config.annotation.web.builders.HttpSecurity; +import org.springframework.security.config.annotation.web.configuration.EnableWebSecurity; +import org.springframework.security.web.SecurityFilterChain; +import org.springframework.context.annotation.Bean; + +@Configuration +@Profile("swagger") +@EnableWebSecurity +public class SwaggerSecurityConfig { + @Bean + public SecurityFilterChain securityFilterChain(HttpSecurity http) throws Exception { + http + .csrf().disable() + .authorizeRequests().anyRequest().permitAll(); + return http.build(); + } +} diff --git a/src/main/resources/application-swagger.properties b/src/main/resources/application-swagger.properties new file mode 100644 index 00000000..2aa0915a --- /dev/null +++ b/src/main/resources/application-swagger.properties @@ -0,0 +1,57 @@ +dataSyncDownloadUrl=http://localhost:8080/data/sync/download +benGenUrlCentral=http://localhost:8080/ben/gen/central +benImportUrlLocal=http://localhost:8080/ben/import/local +dataSyncTransactionDownloadUrl=http://localhost:8080/data/sync/transaction/download +dataSyncProcessedFlagUpdate=http://localhost:8080/data/sync/processed/flag/update +registrationUrl=http://localhost:8080/registration +registrarQuickSearchByPhoneNoUrl=http://localhost:8080/registrar/quicksearch/phone +beneficiaryEditUrl=http://localhost:8080/beneficiary/edit +registrarAdvanceSearchUrl=http://localhost:8080/registrar/advance/search +serverIP=127.0.0.1 +serverDomain=localhost +serverUserName=admin +serverPassword=admin +getServerCredentialURL=http://localhost:8080/server/credential +localFolderToSync=/tmp/local +serverFolder=/tmp/server +TMReferredWL=1 +BATCH_SIZE=100 +dataSyncUploadUrl=http://localhost:8080/data/sync/upload +getBenImageFromIdentity=http://localhost:8080/identity/ben/image +specialistSign=1 +tmCentralServer=http://localhost:8080/tm/centralserver +mmucentralserver=http://localhost:8080/mmu/centralserver +fileBasePath=/tmp +carestreamOrderCreateURL=http://localhost:8080/carestream/order/create +registrarQuickSearchByIdUrl=http://localhost:8080/registrar/quicksearch/byid +oncoWL=1 +radioWL=1 +labWL=1 +pharmaWL=1 +snomedCTPageSize=100 +tmReferCheckValue=1 +tcSpecialistSlotCancel=http://localhost:8080/tc/specialist/slot/cancel + +tcSpecialistSlotBook=http://localhost:8080/tc/specialist/slot/book +docWL=1 +spring.datasource.url=jdbc:h2:mem:swaggerdb +spring.datasource.driver-class-name=org.h2.Driver +spring.jpa.database-platform=org.hibernate.dialect.H2Dialect +spring.jpa.hibernate.ddl-auto=create-drop + +# Disable Redis if not needed for docs (optional) +spring.redis.host=${REDIS_HOST:localhost} +spring.redis.port=${REDIS_PORT:6379} + +# Add or update Hibernate DDL auto for H2 in-memory DB +spring.jpa.hibernate.ddl-auto=create-drop +spring.jpa.show-sql=true + +# CORS for Swagger UI +cors.allowed-origins=${CORS_ALLOWED_ORIGINS:http://localhost:9090,http://localhost:8080} +# Logging +logging.level.root=INFO + +# Use environment variable for JWT secret +jwt.secret=${JWT_SECRET_KEY:default-swagger-secret-change-me} +nurseWL=1 \ No newline at end of file From 370f2e55b424cdc3d72f86938e06a2a8f76e55ca Mon Sep 17 00:00:00 2001 From: DurgaPrasad-54 Date: Thu, 5 Feb 2026 20:41:58 +0530 Subject: [PATCH 03/13] chore(swagger): automate swagger sync to amrit-docs --- src/main/resources/application-swagger.properties | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) diff --git a/src/main/resources/application-swagger.properties b/src/main/resources/application-swagger.properties index 2aa0915a..9f2d2b53 100644 --- a/src/main/resources/application-swagger.properties +++ b/src/main/resources/application-swagger.properties @@ -9,8 +9,8 @@ beneficiaryEditUrl=http://localhost:8080/beneficiary/edit registrarAdvanceSearchUrl=http://localhost:8080/registrar/advance/search serverIP=127.0.0.1 serverDomain=localhost -serverUserName=admin -serverPassword=admin +serverUserName=${SERVER_USERNAME:admin} +serverPassword=${SERVER_PASSWORD:admin} getServerCredentialURL=http://localhost:8080/server/credential localFolderToSync=/tmp/local serverFolder=/tmp/server @@ -37,7 +37,6 @@ docWL=1 spring.datasource.url=jdbc:h2:mem:swaggerdb spring.datasource.driver-class-name=org.h2.Driver spring.jpa.database-platform=org.hibernate.dialect.H2Dialect -spring.jpa.hibernate.ddl-auto=create-drop # Disable Redis if not needed for docs (optional) spring.redis.host=${REDIS_HOST:localhost} From 3f7f33b68defb73787f14e92eec9915f26edc84e Mon Sep 17 00:00:00 2001 From: DurgaPrasad-54 Date: Thu, 5 Feb 2026 20:48:00 +0530 Subject: [PATCH 04/13] chore(swagger): automate swagger sync to amrit-docs --- src/main/resources/application-swagger.properties | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/main/resources/application-swagger.properties b/src/main/resources/application-swagger.properties index 9f2d2b53..4c35e387 100644 --- a/src/main/resources/application-swagger.properties +++ b/src/main/resources/application-swagger.properties @@ -52,5 +52,5 @@ cors.allowed-origins=${CORS_ALLOWED_ORIGINS:http://localhost:9090,http://localho logging.level.root=INFO # Use environment variable for JWT secret -jwt.secret=${JWT_SECRET_KEY:default-swagger-secret-change-me} +jwt.secret=${JWT_SECRET_KEY:JWT_SECRET_KEY} nurseWL=1 \ No newline at end of file From 32d3ca8ba105062cef9e69e74bd17e24376a5284 Mon Sep 17 00:00:00 2001 From: DurgaPrasad-54 Date: Thu, 5 Feb 2026 21:09:09 +0530 Subject: [PATCH 05/13] chore(swagger): automate swagger sync to amrit-docs --- .../com/iemr/mmu/utils/mapper/SwaggerSecurityConfig.java | 5 +++-- src/main/resources/application-swagger.properties | 2 +- 2 files changed, 4 insertions(+), 3 deletions(-) diff --git a/src/main/java/com/iemr/mmu/utils/mapper/SwaggerSecurityConfig.java b/src/main/java/com/iemr/mmu/utils/mapper/SwaggerSecurityConfig.java index 4a470d1c..5a0474be 100644 --- a/src/main/java/com/iemr/mmu/utils/mapper/SwaggerSecurityConfig.java +++ b/src/main/java/com/iemr/mmu/utils/mapper/SwaggerSecurityConfig.java @@ -13,9 +13,10 @@ public class SwaggerSecurityConfig { @Bean public SecurityFilterChain securityFilterChain(HttpSecurity http) throws Exception { + // CSRF is disabled only for the swagger profile to allow anonymous access to API docs and endpoints during testing. This is not used in production. http - .csrf().disable() - .authorizeRequests().anyRequest().permitAll(); + .csrf(csrf -> csrf.disable()) + .authorizeHttpRequests(auth -> auth.anyRequest().permitAll()); return http.build(); } } diff --git a/src/main/resources/application-swagger.properties b/src/main/resources/application-swagger.properties index 4c35e387..814887e0 100644 --- a/src/main/resources/application-swagger.properties +++ b/src/main/resources/application-swagger.properties @@ -52,5 +52,5 @@ cors.allowed-origins=${CORS_ALLOWED_ORIGINS:http://localhost:9090,http://localho logging.level.root=INFO # Use environment variable for JWT secret -jwt.secret=${JWT_SECRET_KEY:JWT_SECRET_KEY} +jwt.secret=${JWT_SECRET_KEY:JWT_SECRET} nurseWL=1 \ No newline at end of file From 10c076c4ee4b3df3d612c50e576cca31d65a72e6 Mon Sep 17 00:00:00 2001 From: DurgaPrasad-54 Date: Fri, 6 Feb 2026 08:54:54 +0530 Subject: [PATCH 06/13] chore(swagger): automate swagger sync to amrit-docs --- src/main/java/com/iemr/mmu/utils/mapper/SecurityConfig.java | 5 ++++- src/main/resources/application-swagger.properties | 2 +- 2 files changed, 5 insertions(+), 2 deletions(-) diff --git a/src/main/java/com/iemr/mmu/utils/mapper/SecurityConfig.java b/src/main/java/com/iemr/mmu/utils/mapper/SecurityConfig.java index 3fe096d2..ac915dba 100644 --- a/src/main/java/com/iemr/mmu/utils/mapper/SecurityConfig.java +++ b/src/main/java/com/iemr/mmu/utils/mapper/SecurityConfig.java @@ -39,7 +39,10 @@ public SecurityFilterChain securityFilterChain(HttpSecurity http) throws Excepti .csrf(csrf -> csrf.disable()) .sessionManagement(session -> session.sessionCreationPolicy(SessionCreationPolicy.STATELESS)) .authorizeHttpRequests(auth -> auth - .requestMatchers("/user/**").permitAll() + .requestMatchers( + "/user/**", + "/v3/api-docs/**" + ).permitAll() .anyRequest().authenticated() ) .exceptionHandling(ex -> ex diff --git a/src/main/resources/application-swagger.properties b/src/main/resources/application-swagger.properties index 814887e0..06bd0ead 100644 --- a/src/main/resources/application-swagger.properties +++ b/src/main/resources/application-swagger.properties @@ -52,5 +52,5 @@ cors.allowed-origins=${CORS_ALLOWED_ORIGINS:http://localhost:9090,http://localho logging.level.root=INFO # Use environment variable for JWT secret -jwt.secret=${JWT_SECRET_KEY:JWT_SECRET} +jwt.secret=${JWT_SECRET_KEY:#{T(java.util.UUID).randomUUID().toString()}} nurseWL=1 \ No newline at end of file From 5a29cbc711fa58929446d88be5f7f3e7bdc28a5b Mon Sep 17 00:00:00 2001 From: DurgaPrasad-54 Date: Fri, 6 Feb 2026 08:59:35 +0530 Subject: [PATCH 07/13] chore(swagger): automate swagger sync to amrit-docs --- .../utils/mapper/SwaggerSecurityConfig.java | 22 ------------------- 1 file changed, 22 deletions(-) delete mode 100644 src/main/java/com/iemr/mmu/utils/mapper/SwaggerSecurityConfig.java diff --git a/src/main/java/com/iemr/mmu/utils/mapper/SwaggerSecurityConfig.java b/src/main/java/com/iemr/mmu/utils/mapper/SwaggerSecurityConfig.java deleted file mode 100644 index 5a0474be..00000000 --- a/src/main/java/com/iemr/mmu/utils/mapper/SwaggerSecurityConfig.java +++ /dev/null @@ -1,22 +0,0 @@ -package com.iemr.mmu.utils.mapper; - -import org.springframework.context.annotation.Configuration; -import org.springframework.context.annotation.Profile; -import org.springframework.security.config.annotation.web.builders.HttpSecurity; -import org.springframework.security.config.annotation.web.configuration.EnableWebSecurity; -import org.springframework.security.web.SecurityFilterChain; -import org.springframework.context.annotation.Bean; - -@Configuration -@Profile("swagger") -@EnableWebSecurity -public class SwaggerSecurityConfig { - @Bean - public SecurityFilterChain securityFilterChain(HttpSecurity http) throws Exception { - // CSRF is disabled only for the swagger profile to allow anonymous access to API docs and endpoints during testing. This is not used in production. - http - .csrf(csrf -> csrf.disable()) - .authorizeHttpRequests(auth -> auth.anyRequest().permitAll()); - return http.build(); - } -} From 311e59e16a27310ba3463dfd4cdd0ad13c0ff98e Mon Sep 17 00:00:00 2001 From: DurgaPrasad-54 Date: Fri, 6 Feb 2026 10:10:51 +0530 Subject: [PATCH 08/13] chore(swagger): automate swagger sync to amrit-docs --- src/main/java/com/iemr/mmu/utils/mapper/SecurityConfig.java | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/main/java/com/iemr/mmu/utils/mapper/SecurityConfig.java b/src/main/java/com/iemr/mmu/utils/mapper/SecurityConfig.java index ac915dba..4a15afb3 100644 --- a/src/main/java/com/iemr/mmu/utils/mapper/SecurityConfig.java +++ b/src/main/java/com/iemr/mmu/utils/mapper/SecurityConfig.java @@ -40,8 +40,8 @@ public SecurityFilterChain securityFilterChain(HttpSecurity http) throws Excepti .sessionManagement(session -> session.sessionCreationPolicy(SessionCreationPolicy.STATELESS)) .authorizeHttpRequests(auth -> auth .requestMatchers( - "/user/**", - "/v3/api-docs/**" + "/user/**", + "/v3/**" ).permitAll() .anyRequest().authenticated() ) From 0503339447b6f5e681eca02423f9d836b13c8dc5 Mon Sep 17 00:00:00 2001 From: DurgaPrasad-54 Date: Fri, 6 Feb 2026 10:32:49 +0530 Subject: [PATCH 09/13] chore(swagger): automate swagger sync to amrit-docs --- .../iemr/mmu/utils/mapper/SecurityConfig.java | 8 +++---- .../utils/mapper/SwaggerSecurityConfig.java | 22 +++++++++++++++++++ .../resources/application-swagger.properties | 1 + 3 files changed, 26 insertions(+), 5 deletions(-) create mode 100644 src/main/java/com/iemr/mmu/utils/mapper/SwaggerSecurityConfig.java diff --git a/src/main/java/com/iemr/mmu/utils/mapper/SecurityConfig.java b/src/main/java/com/iemr/mmu/utils/mapper/SecurityConfig.java index 4a15afb3..fa328938 100644 --- a/src/main/java/com/iemr/mmu/utils/mapper/SecurityConfig.java +++ b/src/main/java/com/iemr/mmu/utils/mapper/SecurityConfig.java @@ -12,11 +12,12 @@ import com.iemr.mmu.utils.exception.CustomAuthenticationEntryPoint; import com.iemr.mmu.utils.exception.CustomAccessDeniedHandler; - +import org.springframework.context.annotation.Profile; @Configuration @EnableMethodSecurity @EnableWebSecurity +@Profile("!swagger") public class SecurityConfig { private final RoleAuthenticationFilter roleAuthenticationFilter; private final CustomAuthenticationEntryPoint customAuthenticationEntryPoint; @@ -39,10 +40,7 @@ public SecurityFilterChain securityFilterChain(HttpSecurity http) throws Excepti .csrf(csrf -> csrf.disable()) .sessionManagement(session -> session.sessionCreationPolicy(SessionCreationPolicy.STATELESS)) .authorizeHttpRequests(auth -> auth - .requestMatchers( - "/user/**", - "/v3/**" - ).permitAll() + .requestMatchers("/user/**").permitAll() .anyRequest().authenticated() ) .exceptionHandling(ex -> ex diff --git a/src/main/java/com/iemr/mmu/utils/mapper/SwaggerSecurityConfig.java b/src/main/java/com/iemr/mmu/utils/mapper/SwaggerSecurityConfig.java new file mode 100644 index 00000000..504c4de4 --- /dev/null +++ b/src/main/java/com/iemr/mmu/utils/mapper/SwaggerSecurityConfig.java @@ -0,0 +1,22 @@ +package com.iemr.mmu.utils.mapper; + +import org.springframework.context.annotation.Bean; +import org.springframework.context.annotation.Configuration; +import org.springframework.context.annotation.Profile; +import org.springframework.security.config.annotation.web.builders.HttpSecurity; +import org.springframework.security.web.SecurityFilterChain; + +@Configuration +@Profile("swagger") +public class SwaggerSecurityConfig { + + @Bean + public SecurityFilterChain swaggerSecurityFilterChain(HttpSecurity http) throws Exception { + System.out.println(">>> SwaggerSecurityConfig is ACTIVE <<<"); + http + .csrf(csrf -> csrf.disable()) + .securityMatcher("/v3/api-docs/**") + .authorizeHttpRequests(auth -> auth.anyRequest().permitAll()); + return http.build(); + } +} diff --git a/src/main/resources/application-swagger.properties b/src/main/resources/application-swagger.properties index 06bd0ead..3af439e0 100644 --- a/src/main/resources/application-swagger.properties +++ b/src/main/resources/application-swagger.properties @@ -1,3 +1,4 @@ +spring.jpa.hibernate.ddl-auto=create dataSyncDownloadUrl=http://localhost:8080/data/sync/download benGenUrlCentral=http://localhost:8080/ben/gen/central benImportUrlLocal=http://localhost:8080/ben/import/local From 3c21ab6a56be00cc9a60b5e730cbe38a537fb910 Mon Sep 17 00:00:00 2001 From: DurgaPrasad-54 Date: Fri, 6 Feb 2026 10:48:24 +0530 Subject: [PATCH 10/13] fix(security): restrict Swagger to swagger profile for CI sync --- src/main/java/com/iemr/mmu/utils/mapper/SecurityConfig.java | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) diff --git a/src/main/java/com/iemr/mmu/utils/mapper/SecurityConfig.java b/src/main/java/com/iemr/mmu/utils/mapper/SecurityConfig.java index fa328938..665c357b 100644 --- a/src/main/java/com/iemr/mmu/utils/mapper/SecurityConfig.java +++ b/src/main/java/com/iemr/mmu/utils/mapper/SecurityConfig.java @@ -33,9 +33,8 @@ public SecurityConfig(RoleAuthenticationFilter roleAuthenticationFilter, @Bean public SecurityFilterChain securityFilterChain(HttpSecurity http) throws Exception { - CookieCsrfTokenRepository csrfTokenRepository = new CookieCsrfTokenRepository(); - csrfTokenRepository.setCookieHttpOnly(true); - csrfTokenRepository.setCookiePath("/"); + // CSRF is disabled because this API is stateless and uses JWT tokens in Authorization headers. + // Disabling CSRF is safe for REST APIs that do not use cookies for authentication. http .csrf(csrf -> csrf.disable()) .sessionManagement(session -> session.sessionCreationPolicy(SessionCreationPolicy.STATELESS)) From f40ed90434998fe15dd79f6aaba9ba7e122bc195 Mon Sep 17 00:00:00 2001 From: DurgaPrasad-54 Date: Fri, 6 Feb 2026 10:54:25 +0530 Subject: [PATCH 11/13] chore(security,swagger): scope swagger sync to swagger profile - Move Swagger access to swagger profile for CI automation - Remove public exposure of /v3/api-docs from default security config - Clean up CSRF config for stateless JWT API --- src/main/java/com/iemr/mmu/utils/mapper/SecurityConfig.java | 5 +++-- .../com/iemr/mmu/utils/mapper/SwaggerSecurityConfig.java | 3 ++- 2 files changed, 5 insertions(+), 3 deletions(-) diff --git a/src/main/java/com/iemr/mmu/utils/mapper/SecurityConfig.java b/src/main/java/com/iemr/mmu/utils/mapper/SecurityConfig.java index 665c357b..fa328938 100644 --- a/src/main/java/com/iemr/mmu/utils/mapper/SecurityConfig.java +++ b/src/main/java/com/iemr/mmu/utils/mapper/SecurityConfig.java @@ -33,8 +33,9 @@ public SecurityConfig(RoleAuthenticationFilter roleAuthenticationFilter, @Bean public SecurityFilterChain securityFilterChain(HttpSecurity http) throws Exception { - // CSRF is disabled because this API is stateless and uses JWT tokens in Authorization headers. - // Disabling CSRF is safe for REST APIs that do not use cookies for authentication. + CookieCsrfTokenRepository csrfTokenRepository = new CookieCsrfTokenRepository(); + csrfTokenRepository.setCookieHttpOnly(true); + csrfTokenRepository.setCookiePath("/"); http .csrf(csrf -> csrf.disable()) .sessionManagement(session -> session.sessionCreationPolicy(SessionCreationPolicy.STATELESS)) diff --git a/src/main/java/com/iemr/mmu/utils/mapper/SwaggerSecurityConfig.java b/src/main/java/com/iemr/mmu/utils/mapper/SwaggerSecurityConfig.java index 504c4de4..efeb33e6 100644 --- a/src/main/java/com/iemr/mmu/utils/mapper/SwaggerSecurityConfig.java +++ b/src/main/java/com/iemr/mmu/utils/mapper/SwaggerSecurityConfig.java @@ -13,8 +13,9 @@ public class SwaggerSecurityConfig { @Bean public SecurityFilterChain swaggerSecurityFilterChain(HttpSecurity http) throws Exception { System.out.println(">>> SwaggerSecurityConfig is ACTIVE <<<"); + // CSRF is disabled here because these endpoints are only used for API documentation/testing. + // No authentication or state-changing operations are exposed, so disabling CSRF is safe. http - .csrf(csrf -> csrf.disable()) .securityMatcher("/v3/api-docs/**") .authorizeHttpRequests(auth -> auth.anyRequest().permitAll()); return http.build(); From 7c37554c07bd4aa05bdaf82350ecaea27f2ca7e1 Mon Sep 17 00:00:00 2001 From: DurgaPrasad-54 Date: Wed, 11 Feb 2026 08:23:42 +0530 Subject: [PATCH 12/13] chore(swagger): update swagger workflow and security config --- .github/workflows/swagger-json.yml | 27 ++++++++++++------- .../utils/mapper/SwaggerSecurityConfig.java | 10 +++++-- 2 files changed, 25 insertions(+), 12 deletions(-) diff --git a/.github/workflows/swagger-json.yml b/.github/workflows/swagger-json.yml index 171ca206..991d404f 100644 --- a/.github/workflows/swagger-json.yml +++ b/.github/workflows/swagger-json.yml @@ -11,10 +11,8 @@ jobs: timeout-minutes: 20 steps: - - name: Checkout API repo (full history) + - name: Checkout API repo uses: actions/checkout@v4 - with: - fetch-depth: 0 - name: Set up Java 17 uses: actions/setup-java@v4 @@ -25,15 +23,15 @@ jobs: - name: Build API (skip tests) run: mvn -B clean package -DskipTests - + - name: Install jq run: sudo apt-get update && sudo apt-get install -y jq - name: Run API in swagger profile run: | - nohup mvn spring-boot:run \ - -Dspring-boot.run.profiles=swagger \ - -Dspring-boot.run.arguments=--server.port=9090 \ + nohup java -jar target/mmu-api-*.war \ + --spring.profiles.active=swagger \ + --server.port=9090 \ > app.log 2>&1 & echo $! > api_pid.txt @@ -69,9 +67,17 @@ jobs: - name: Stop API if: always() run: | + # Graceful shutdown of the process group + sleep 5 + # Force kill the process group if still running if [ -f api_pid.txt ]; then - kill -9 $(cat api_pid.txt) || true - fi + PID=$(cat api_pid.txt) + kill -TERM -- -"$PID" 2>/dev/null || true + sleep 2 + kill -9 -- -"$PID" 2>/dev/null || true + fi + # Fallback: kill any remaining java process on port 9090 + fuser -k 9090/tcp 2>/dev/null || true - name: Checkout AMRIT-Docs uses: actions/checkout@v4 @@ -87,7 +93,7 @@ jobs: cp mmu-api.json amrit-docs/docs/swagger/mmu-api.json - name: Create Pull Request - uses: peter-evans/create-pull-request@v6 + uses: peter-evans/create-pull-request@v8 with: token: ${{ secrets.DOCS_REPO_TOKEN }} path: amrit-docs @@ -95,6 +101,7 @@ jobs: base: main commit-message: "chore(docs): auto-update MMU-API swagger" title: "chore(docs): auto-update MMU-API swagger" + delete-branch: true body: | This PR automatically updates MMU-API Swagger JSON from the latest main branch build. diff --git a/src/main/java/com/iemr/mmu/utils/mapper/SwaggerSecurityConfig.java b/src/main/java/com/iemr/mmu/utils/mapper/SwaggerSecurityConfig.java index efeb33e6..66940cfc 100644 --- a/src/main/java/com/iemr/mmu/utils/mapper/SwaggerSecurityConfig.java +++ b/src/main/java/com/iemr/mmu/utils/mapper/SwaggerSecurityConfig.java @@ -4,20 +4,26 @@ import org.springframework.context.annotation.Configuration; import org.springframework.context.annotation.Profile; import org.springframework.security.config.annotation.web.builders.HttpSecurity; +import org.springframework.security.config.annotation.web.configuration.EnableWebSecurity; import org.springframework.security.web.SecurityFilterChain; +import org.springframework.core.annotation.Order; @Configuration +@EnableWebSecurity @Profile("swagger") public class SwaggerSecurityConfig { @Bean + @Order(1) public SecurityFilterChain swaggerSecurityFilterChain(HttpSecurity http) throws Exception { System.out.println(">>> SwaggerSecurityConfig is ACTIVE <<<"); // CSRF is disabled here because these endpoints are only used for API documentation/testing. // No authentication or state-changing operations are exposed, so disabling CSRF is safe. http - .securityMatcher("/v3/api-docs/**") - .authorizeHttpRequests(auth -> auth.anyRequest().permitAll()); + .authorizeHttpRequests(auth -> auth + .requestMatchers("/swagger-ui/**", "/v3/api-docs/**", "/swagger-ui.html").permitAll() + .anyRequest().authenticated() + ); return http.build(); } } From 3334922a2046694c83b77242fdfa0d7d1433ba4a Mon Sep 17 00:00:00 2001 From: DurgaPrasad-54 Date: Wed, 11 Feb 2026 08:31:13 +0530 Subject: [PATCH 13/13] fix(swagger): update the swagger workflow stop api issue --- .github/workflows/swagger-json.yml | 12 +++++++----- 1 file changed, 7 insertions(+), 5 deletions(-) diff --git a/.github/workflows/swagger-json.yml b/.github/workflows/swagger-json.yml index 991d404f..92b26bc5 100644 --- a/.github/workflows/swagger-json.yml +++ b/.github/workflows/swagger-json.yml @@ -11,8 +11,10 @@ jobs: timeout-minutes: 20 steps: - - name: Checkout API repo + - name: Checkout API repo (full history) uses: actions/checkout@v4 + with: + fetch-depth: 0 - name: Set up Java 17 uses: actions/setup-java@v4 @@ -23,15 +25,15 @@ jobs: - name: Build API (skip tests) run: mvn -B clean package -DskipTests - + - name: Install jq run: sudo apt-get update && sudo apt-get install -y jq - name: Run API in swagger profile run: | - nohup java -jar target/mmu-api-*.war \ - --spring.profiles.active=swagger \ - --server.port=9090 \ + nohup mvn spring-boot:run \ + -Dspring-boot.run.profiles=swagger \ + -Dspring-boot.run.arguments=--server.port=9090 \ > app.log 2>&1 & echo $! > api_pid.txt