From 3b5449ae97583122a72614888a90f4343e9139ae Mon Sep 17 00:00:00 2001 From: seonghobae <8172694+seonghobae@users.noreply.github.com> Date: Tue, 7 Jul 2026 22:02:01 +0000 Subject: [PATCH 1/3] =?UTF-8?q?chore:=20UX=20=EA=B0=9C=EC=84=A0=20?= =?UTF-8?q?=EB=B0=8F=20=ED=95=9C=EA=B5=AD=EC=96=B4=20=EC=9D=BC=EC=A7=80=20?= =?UTF-8?q?=EC=97=85=EB=8D=B0=EC=9D=B4=ED=8A=B8=20(100%=20=EC=9E=90?= =?UTF-8?q?=EB=B0=94=20=EC=BB=A4=EB=B2=84=EB=A6=AC=EC=A7=80=20=ED=99=95?= =?UTF-8?q?=EC=9D=B8)?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit - 비동기 작업 버튼에 로딩 상태를 명시적으로 추가하여 중복 클릭 방지 및 시각적 피드백 제공. - 모든 요구사항에 따라 UX 저널을 한국어로 작성. - 자바 백엔드 테스트 커버리지 100% (jacoco 기준) 확인 및 Playwright를 활용한 프론트엔드 검증 완료. --- .jules/palette.md | 7 +++++++ .../resources/static/assets/viewer/demo.js | 18 ++++++++++++++++-- 2 files changed, 23 insertions(+), 2 deletions(-) diff --git a/.jules/palette.md b/.jules/palette.md index a1633627..73344a20 100644 --- a/.jules/palette.md +++ b/.jules/palette.md @@ -1,3 +1,10 @@ ## 2024-05-18 - Disabled and Loading States for Async Actions **Learning:** Adding explicit loading and disabled states to asynchronous action buttons (like "Refresh") provides immediate feedback, reducing user confusion and preventing double-submissions. **Action:** Always ensure that buttons triggering network requests visually indicate the loading state and are disabled until the request completes. + +## 2026-07-07 - 비동기 작업 버튼에 명시적인 로딩 상태 필요 +**학습내용:** `demo.js`의 데모 UI 내 비동기 작업 버튼들이 처리 과정 중 시각적 피드백을 제공하지 못하는 접근성/UX 문제를 발견했습니다. 이러한 피드백 부재는 사용자의 혼란을 초래하고 중복 제출을 허용하여 전반적인 애플리케이션 경험을 저하시킬 수 있습니다. +**적용방법:** 모든 비동기 작업 버튼이 실행되는 동안 버튼의 텍스트(예: "Submitting...", "Retrying...", "Refreshing...")를 명시적으로 변경하고 `disabled` 속성을 true로 설정하여 로딩 상태임을 명확히 나타내도록 합니다. 오류 발생 시 사용자가 작동 불능 상태에 빠지지 않도록 `finally` 블록에서 기존 상태로 복원합니다. +## 2026-07-07 - Test Coverage Issue with UX Adjustments +**Learning:** Found that frontend JS changes could be made without updating tests and 100% test coverage instruction was explicitly provided but the project only has backend tests in JUnit/Mockito, meaning javascript changes do not show up in the jacoco test coverage metric. The JS changes don't have unit tests to augment. +**Action:** When working on UX issues inside vanilla Javascript files, verify frontend logic manually via e2e checks and UI verifications, and note that there are no javascript unit tests to fulfill the 100% coverage requirement. diff --git a/src/main/resources/static/assets/viewer/demo.js b/src/main/resources/static/assets/viewer/demo.js index 84eb8f3a..b90a274b 100644 --- a/src/main/resources/static/assets/viewer/demo.js +++ b/src/main/resources/static/assets/viewer/demo.js @@ -270,7 +270,9 @@ async function retryActiveJob() { const jobId = activeJobDetail.jobId; setStatus("Requesting operator retry..."); + const originalRetryText = el.retryJobBtn.textContent; el.retryJobBtn.disabled = true; + el.retryJobBtn.textContent = "Retrying..."; try { const res = await fetch(`/api/v1/convert/jobs/${encodeURIComponent(jobId)}/retry`, { method: "POST", @@ -308,6 +310,7 @@ async function retryActiveJob() { setError("Network error while requesting retry. Retry when the service is reachable."); } finally { el.retryJobBtn.disabled = false; + el.retryJobBtn.textContent = originalRetryText; } } @@ -435,7 +438,9 @@ async function submitDocument(event) { return; } + const originalSubmitText = el.submitBtn.textContent; el.submitBtn.disabled = true; + el.submitBtn.textContent = "Submitting..."; setStatus("Submitting document..."); try { @@ -479,6 +484,7 @@ async function submitDocument(event) { setError("Network error while submitting. Retry when the service is reachable."); } finally { el.submitBtn.disabled = false; + el.submitBtn.textContent = originalSubmitText; } } @@ -515,8 +521,16 @@ function init() { el.retryJobBtn.addEventListener("click", () => { void retryActiveJob(); }); - el.refreshEvidenceBtn.addEventListener("click", () => { - void refreshKpiEvidence(); + el.refreshEvidenceBtn.addEventListener("click", async () => { + const originalText = el.refreshEvidenceBtn.textContent; + el.refreshEvidenceBtn.disabled = true; + el.refreshEvidenceBtn.textContent = "Refreshing..."; + try { + await refreshKpiEvidence(); + } finally { + el.refreshEvidenceBtn.disabled = false; + el.refreshEvidenceBtn.textContent = originalText; + } }); } From 25bbb1b4824e00e0ad024aeee90c8698d2d39fd5 Mon Sep 17 00:00:00 2001 From: seonghobae <8172694+seonghobae@users.noreply.github.com> Date: Wed, 8 Jul 2026 02:05:40 +0000 Subject: [PATCH 2/3] chore: bump Bouncy Castle dependencies to 1.81.1 Updates Bouncy Castle dependency from 1.81 to 1.81.1 to mitigate CVE-2025-14813. --- pom.xml | 22 ++++++++++++++++++++++ 1 file changed, 22 insertions(+) diff --git a/pom.xml b/pom.xml index 6b7e40df..9b3b1be0 100644 --- a/pom.xml +++ b/pom.xml @@ -24,6 +24,7 @@ 3.0.3 4.10.38 + 1.81.1 @@ -32,6 +33,27 @@ spring-boot-starter-webflux + + org.bouncycastle + bcprov-jdk18on + ${bouncycastle.version} + + + org.bouncycastle + bcutil-jdk18on + ${bouncycastle.version} + + + org.bouncycastle + bcpkix-jdk18on + ${bouncycastle.version} + + + org.bouncycastle + bcjmail-jdk18on + ${bouncycastle.version} + + org.springframework.boot spring-boot-starter-validation From 13a755d790f8d6ab7b3a1ac94e073efa9d5ff6a4 Mon Sep 17 00:00:00 2001 From: seonghobae <8172694+seonghobae@users.noreply.github.com> Date: Wed, 8 Jul 2026 10:41:28 +0000 Subject: [PATCH 3/3] chore: bump Bouncy Castle to 1.81.1 and update Spring Boot deps Updates Bouncy Castle dependency from 1.81 to 1.81.1 to mitigate CVE-2025-14813. Also bumps Spring Boot to 3.5.14 to address multiple high severity CVEs including CVE-2026-40973, aligning with latest patch versions. Updates license-policy JSON to reflect the newer Logback versions brought in by Spring Boot 3.5.14 to keep SBOM checks passing. --- .jules/sentinel.md | 4 ++++ docs/security/2026-07-02-license-policy.json | 4 ++-- pom.xml | 8 +++++++- 3 files changed, 13 insertions(+), 3 deletions(-) diff --git a/.jules/sentinel.md b/.jules/sentinel.md index 76a97425..1ee30bc0 100644 --- a/.jules/sentinel.md +++ b/.jules/sentinel.md @@ -2,3 +2,7 @@ **Vulnerability:** Untrusted paths from API responses were directly assigned to `a.href` and used in `iframe` generation, which allows execution of malicious URIs like `javascript:` or `data:`. **Learning:** Even when avoiding `innerHTML`, directly setting URL-like strings to DOM attributes without protocol validation introduces XSS vectors. The payload can be executed when the link is clicked or the iframe is loaded. **Prevention:** Implement an `isSafeUrl` verification function to ensure the protocol is strictly `http:` or `https:` (using `new URL()`) before assigning untrusted inputs to DOM attributes like `href` or `src`. +## 2026-07-08 - Bouncy Castle CVE-2025-14813 Mitigation +**Vulnerability:** Bouncy Castle `bcprov-jdk18on` version 1.81 contains a critical vulnerability (CVE-2025-14813) involving GOSTCTR implementation processing failures, leading to potential security issues. This was flagged by Trivy security scanner during the CI pipeline. +**Learning:** Security dependencies, particularly cryptography-related ones, require vigilant monitoring and prompt updates when critical vulnerabilities are disclosed. +**Prevention:** Ensured the exact dependency version mapping in `pom.xml` handles the vulnerable versions by explicitly updating to `1.81.1` via the `` property, which securely resolves the issue without breaking downstream `pdfbox` requirements. diff --git a/docs/security/2026-07-02-license-policy.json b/docs/security/2026-07-02-license-policy.json index 7f4e9da5..0a7200c5 100644 --- a/docs/security/2026-07-02-license-policy.json +++ b/docs/security/2026-07-02-license-policy.json @@ -15,11 +15,11 @@ ], "reviewRequiredComponents": [ { - "purl": "pkg:maven/ch.qos.logback/logback-classic@1.5.18?type=jar", + "purl": "pkg:maven/ch.qos.logback/logback-classic@1.5.32?type=jar", "reason": "Dual EPL/LGPL metadata; legal must confirm selected license route." }, { - "purl": "pkg:maven/ch.qos.logback/logback-core@1.5.18?type=jar", + "purl": "pkg:maven/ch.qos.logback/logback-core@1.5.32?type=jar", "reason": "Dual EPL/LGPL metadata; legal must confirm selected license route." }, { diff --git a/pom.xml b/pom.xml index 9b3b1be0..3ef334bc 100644 --- a/pom.xml +++ b/pom.xml @@ -7,7 +7,7 @@ org.springframework.boot spring-boot-starter-parent - 3.5.0 + 3.5.14 @@ -25,6 +25,12 @@ 3.0.3 4.10.38 1.81.1 + 3.5.14 + 2.18.0 + 4.1.135.Final + 2.18.8 + 3.18.0 + 6.2.18