Skip to content

Commit f11c5a8

Browse files
Merge pull request #18 from MinistryPlatform-Community/fix/xmldom-critical-via-docxtemplater-image
fix(deps): replace abandoned docxtemplater-image-module-free with docxtemplater-image
2 parents facacd0 + a9b3b05 commit f11c5a8

11 files changed

Lines changed: 33 additions & 145 deletions

File tree

.claude/TODO/2026-04-17-commands-audit-deps-stale-key-deps.md

Lines changed: 0 additions & 45 deletions
This file was deleted.

.claude/TODO/2026-05-21-xmldom-critical-vulnerability.md

Lines changed: 0 additions & 64 deletions
This file was deleted.

.claude/TODO/INDEX.md

Lines changed: 7 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,7 @@ last_updated: 2026-05-21
88
<!-- 2026-04-18: closed 3 utils TODOs (imb-fallback-silent, tool-params-missing-test, tool-params-parseint-nan) — see commit fix(utils): log barcode fallbacks, guard tool-params NaN, add tool-params tests -->
99
<!-- 2026-04-18: closed 5 low TODOs (contexts-session-context-misnamed, dto-constants-batchsize-duplication, dto-constants-mailerid-not-validated, testing-claude-md-readme-counts-drift, verify-auth-oauth-flow) — see commit chore: rename contexts hook, dedupe BATCH_SIZE, validate mailerId, refresh docs -->
1010
<!-- 2026-05-21: opened 1 critical TODO (xmldom-critical-vulnerability) — see install-testing feedback; address before next ship -->
11+
<!-- 2026-05-21: closed 1 critical TODO (xmldom-critical-vulnerability) — replaced docxtemplater-image-module-free with maintained docxtemplater-image (uses @xmldom/xmldom@^0.9.7) -->
1112

1213

1314
# TODO Index
@@ -19,16 +20,14 @@ All open TODOs dropped during the context-engineering review (2026-04-17) and an
1920
- **medium**: doc drift, missing test, refactor with real cost
2021
- **low**: nits, minor doc fixes, stylistic improvements
2122

22-
Total: **4 open TODOs**.
23+
Total: **3 open TODOs**.
2324

2425
---
2526

2627
## By severity
2728

28-
### Critical (1)
29-
| Area | Tags | Title | File |
30-
|---|---|---|---|
31-
| components | security | Critical xmldom vulnerability via docxtemplater-image-module-free | [](2026-05-21-xmldom-critical-vulnerability.md) |
29+
### Critical (0)
30+
_none open_
3231

3332
### High
3433
_none open_
@@ -47,8 +46,8 @@ _none open_
4746

4847
## By tag
4948

50-
### security (1)
51-
- xmldom-critical-vulnerability — critical
49+
### security (0)
50+
_none open_
5251

5352
### bug (2)
5453
_see severity sections above; tag appears on items involving a functional defect_
@@ -74,7 +73,7 @@ _none open_
7473

7574
| Area | Count |
7675
|---|---|
77-
| components | 4 |
76+
| components | 3 |
7877
| auth | 0 |
7978
| mp-provider | 0 |
8079
| services | 0 |

.claude/commands/audit-deps.md

Lines changed: 9 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -46,9 +46,13 @@ If the user requests, execute the recommended action plan:
4646
- Report final status
4747

4848
## Key Dependencies to Always Check
49-
- next / next-auth (framework security)
49+
- next / eslint-config-next (framework security)
5050
- react / react-dom (core framework)
51-
- jsonwebtoken / bcryptjs (auth/crypto)
52-
- drizzle-orm / drizzle-kit (database)
53-
- Any AWS SDK packages
54-
- Any packages with known historical vulnerabilities
51+
- better-auth (auth/session)
52+
- zod (validation — v4 API differs from v3)
53+
- @grapesjs/react / grapesjs / grapesjs-mjml / mjml (template editor)
54+
- docx / docxtemplater / docxtemplater-image-module-free / pizzip (Word merge)
55+
- openai (LLM client, if used by tools)
56+
- @react-pdf/renderer (PDF output)
57+
- vitest / @vitest/coverage-v8 / @vitejs/plugin-react (test runner)
58+
- typescript (toolchain)

.claude/references/components/address-labels.md

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -59,7 +59,7 @@ Tool route: `src/app/(web)/tools/addresslabels/page.tsx` → `address-labels.tsx
5959
- **POSTNET**: Legacy 5/9/11-digit tall/short bar barcode (no Mailer ID needed).
6060
- **Skip reasons** (`SkipReason` in `src/lib/dto/address-label.dto.ts:15`): `no_address`, `no_postal_code`, `opted_out` (`Bulk_Mail_Opt_Out=true`), `no_barcode` (only when `includeMissingBarcodes=false`), `no_household` (household mode only — contact lacks `Household_ID` so dedup cannot be guaranteed).
6161
- **Pre-encoded bar states**: `preEncodeBarcodes()` encodes once on the server into `LabelData.barStates` so the PDF/Word renderers are pure layout (see `../utils/barcodes.md`).
62-
- **Mail-merge tab**: uploads a `.docx` with `{Name}`, `{AddressLine1}`, `{AddressLine2}`, `{City}`, `{State}`, `{PostalCode}`, `{%Barcode}` tokens plus `{#addresses}…{/addresses}` loop and `{#isNotLast}<pagebreak>{/isNotLast}` conditional — barcodes become BMP images via `docxtemplater-image-module-free`.
62+
- **Mail-merge tab**: uploads a `.docx` with `{Name}`, `{AddressLine1}`, `{AddressLine2}`, `{City}`, `{State}`, `{PostalCode}`, `{%Barcode}` tokens plus `{#addresses}…{/addresses}` loop and `{#isNotLast}<pagebreak>{/isNotLast}` conditional — barcodes become BMP images via `docxtemplater-image`.
6363
- **LocalStorage persistence**: last-used `LabelConfig` stored under key `address-labels-config` (`src/app/(web)/tools/addresslabels/address-labels.tsx:15`).
6464

6565
## API / Interface
@@ -177,7 +177,7 @@ const SERVICE_TYPES = [{id:'040',…}, {id:'300',…}, {id:'044',…}, {id:'700'
177177
### mergeTemplate (.docx mail merge)
178178
- Rejects `templateBase64` if `Math.ceil(length * 0.75) > 5 * 1024 * 1024`.
179179
- `preEncodeBarcodes()` then builds `addresses[]` rows with `{ Name, AddressLine1, AddressLine2, City, State, PostalCode, Barcode: 'barcode_N', isNotLast }` plus a `Map<string,Buffer>` of BMP barcodes keyed by `barcode_N`.
180-
- `Docxtemplater` with `docxtemplater-image-module-free``getImage` resolves key strings to buffers; `getSize` returns `[200, 25]` for the `Barcode` tag.
180+
- `Docxtemplater` with `docxtemplater-image``getImage` resolves key strings to buffers; `getSize` returns `[200, 25]` for the `Barcode` tag.
181181
- Render errors containing "tag" are wrapped as `Template error: …`.
182182

183183
### Mail merge tab upload flow

package-lock.json

Lines changed: 10 additions & 16 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

package.json

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -47,7 +47,7 @@
4747
"cmdk": "^1.1.1",
4848
"docx": "^9.6.1",
4949
"docxtemplater": "^3.68.5",
50-
"docxtemplater-image-module-free": "^1.1.1",
50+
"docxtemplater-image": "^0.1.2",
5151
"dotenv": "^17.3.1",
5252
"grapesjs": "^0.22.14",
5353
"grapesjs-mjml": "^1.0.8",

src/components/address-labels/actions.test.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -72,7 +72,7 @@ vi.mock('pizzip', () => ({
7272
default: class {},
7373
}));
7474

75-
vi.mock('docxtemplater-image-module-free', () => ({
75+
vi.mock('docxtemplater-image', () => ({
7676
default: class {},
7777
}));
7878

src/components/address-labels/actions.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -23,7 +23,7 @@ import { preEncodeBarcodes } from '@/lib/barcode-helpers';
2323
import { validateMailerId } from '@/lib/validation';
2424
import Docxtemplater from 'docxtemplater';
2525
import PizZip from 'pizzip';
26-
import ImageModule from 'docxtemplater-image-module-free';
26+
import ImageModule from 'docxtemplater-image';
2727
import { imbBarcodeToBmp, postnetBarcodeToBmp } from '@/lib/barcode-image';
2828

2929
async function getSession() {

src/components/address-labels/sample-template.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -88,7 +88,7 @@ export async function generateSampleTemplate(): Promise<string> {
8888
],
8989
}),
9090

91-
// Barcode image placeholder (% prefix for docxtemplater-image-module-free)
91+
// Barcode image placeholder (% prefix for docxtemplater-image)
9292
new Paragraph({
9393
spacing: { after: 200 },
9494
children: [new TextRun({ text: '{%Barcode}', size: 22, font: 'Arial' })],

0 commit comments

Comments
 (0)