From 04d789ea107bc85dda58b3c21820cf772e75d8ac Mon Sep 17 00:00:00 2001 From: Chris Barth Date: Sun, 6 Sep 2026 08:34:25 -0500 Subject: [PATCH 01/10] docs: add AGENTS.md and CLAUDE.md Add AGENTS.md as the single place describing how to work in this repository: layout, the build/test/lint commands, and the constraints that are easy to violate without noticing. Three of those are worth calling out because they are not visible from the code alone. The fixtures under test/static and test/validators are byte-sensitive, since canonicalization and digests depend on exact bytes, so formatting them silently invalidates signatures. The supported Node floor comes from `engines` plus the CI matrix, and because npm treats a package's `engines` as advisory rather than binding, tooling has to be run on the oldest supported version to know whether it works there. Anything re-exported from src/index.ts is semver-bound public API, while devDependency and CI changes are not. CLAUDE.md only points at AGENTS.md, via an @-import so the content is actually loaded, so that guidance lives in one file rather than drifting between two. Seeded from the AGENTS.md drafted on the `deps` branch. Co-Authored-By: Claude Opus 5 --- AGENTS.md | 77 +++++++++++++++++++++++++++++++++++++++++++++++++++++++ CLAUDE.md | 7 +++++ 2 files changed, 84 insertions(+) create mode 100644 AGENTS.md create mode 100644 CLAUDE.md diff --git a/AGENTS.md b/AGENTS.md new file mode 100644 index 00000000..12b33777 --- /dev/null +++ b/AGENTS.md @@ -0,0 +1,77 @@ +# AGENTS.md + +## What this is + +`xml-crypto` implements XML digital signatures for Node.js. It is published to npm and +depended on by security-sensitive projects such as `node-saml`, so a bug here can become +an authentication bypass downstream. Treat every change as security-relevant. + +## Layout + +- `src/` — TypeScript source; the only code that ships. +- `src/index.ts` — the public barrel. Anything re-exported here is public API. +- `src/signed-xml.ts` — the core signing and verification logic. +- `test/*.spec.ts` — Mocha specs. +- `test/static/`, `test/validators/` — fixtures. See the warning below. +- `lib/` — build output. Generated; never edit. + +## Commands + +- `npm run build` — compile `src/` to `lib/`. +- `npm test` — `nyc mocha` over `test/*.spec.ts`. +- `npm run lint` — ESLint plus `prettier --check`. +- `npm run lint:fix` — ESLint `--fix` plus `prettier --write`; rewrites files. + +Run `npm run build && npm test && npm run lint` before calling work done. + +## Hard constraints + +### Fixtures are byte-sensitive + +`test/static/` and `test/validators/` contain XML signature fixtures. Canonicalization +and digests depend on the exact bytes, so reformatting whitespace silently invalidates +signatures and the failure can look unrelated. `.prettierignore` excludes both +directories — keep it that way, and never run a formatter over them. + +### The supported Node floor is real + +`engines` in `package.json` is the contract, and the matrix in +`.github/workflows/ci.yml` runs the suite on every supported version, oldest included. +Read both rather than assuming; they change. Development tooling has to install and run +on the _oldest_ entry, not just the newest. + +A package's declared `engines` is advisory — npm only warns — so it predicts neither +direction reliably. Some tools declaring a newer Node still run fine on the floor; +others crash on a feature they never declared. Verify by actually running on the oldest +supported version. + +### The public API is semver-bound + +Changing or removing anything re-exported from `src/index.ts`, or altering types in +`src/types.ts`, is breaking for consumers. Changes confined to `devDependencies`, +tests, CI, or tooling are not. + +## Security posture + +- Verification must fail closed. Never make a check more permissive to get a test green. +- Preserve constant-time comparison where it is used (HMAC verification). +- Be careful with XPath. Expressions can originate from the document under inspection; + do not broaden what a reference is able to select. +- Prefer an explicit error over silently accepting a malformed document. + +## Style + +- Strict TypeScript (`strict: true`), CommonJS, target ES2020. +- Two lint rules bite often: `deprecation/deprecation` is an error, so calling a + deprecated API fails lint even when it works; `@typescript-eslint/no-non-null-assertion` + is an error, so no `!` assertions. +- Prettier owns formatting (`printWidth: 100`). Don't hand-format. +- Prettier 3 does not auto-load plugins. A plugin in `devDependencies` does nothing + unless it is also listed under `plugins` in `.prettierrc.json`. + +## Conventions + +- Keep changes minimal and focused; match the surrounding style. +- Work in `src/` and `test/` unless asked otherwise. +- Never edit `node_modules/` or `lib/`. +- Add a test for any behaviour change. The suite is the safety net for a security library. diff --git a/CLAUDE.md b/CLAUDE.md new file mode 100644 index 00000000..512a4e74 --- /dev/null +++ b/CLAUDE.md @@ -0,0 +1,7 @@ +# CLAUDE.md + +The instructions for working in this repository live in @AGENTS.md. Read that file and +follow it. + +This file exists only to point there, so that guidance stays in one place for every +tool. Add new rules to `AGENTS.md`, not here. From c2ee01cf81050f037ae9cb67740411ee8821c9ad Mon Sep 17 00:00:00 2001 From: Chris Barth Date: Sun, 6 Sep 2026 08:43:10 -0500 Subject: [PATCH 02/10] docs: describe test scope and the no-footguns API stance in AGENTS.md Add two sections capturing decisions that are visible in the code but nowhere written down. Tests: the suite exists to pin down attack vectors and spec/interop behavior, not to cover the code. Internal implementation details are explicitly out of scope, since tests that restate the code catch nothing and make refactoring expensive. Points at the self-reference prevention specs as the model for the first kind and the SAML/WS-Fed/Java fixtures for the second. API design: prefer removing footguns over adding convenience, because a default that makes a security decision on the caller's behalf hands them the consequence without the choice. This is already how the library behaves; the section just names the pattern and cites the existing examples: signatureAlgorithm and digestAlgorithm throw rather than default, getCertFromKeyInfo defaults to SignedXml.noop rather than trusting a certificate the document supplied, and HMAC stays off until enableHMAC() is called. Requiring a decision only works if the options are written down, so it also asks for them to be documented in README. Drops the "add a test for any behavior change" bullet from Conventions, which the Tests section now states more precisely. Co-Authored-By: Claude Opus 5 --- AGENTS.md | 47 ++++++++++++++++++++++++++++++++++++++--------- 1 file changed, 38 insertions(+), 9 deletions(-) diff --git a/AGENTS.md b/AGENTS.md index 12b33777..2e6644c5 100644 --- a/AGENTS.md +++ b/AGENTS.md @@ -40,11 +40,6 @@ directories — keep it that way, and never run a formatter over them. Read both rather than assuming; they change. Development tooling has to install and run on the _oldest_ entry, not just the newest. -A package's declared `engines` is advisory — npm only warns — so it predicts neither -direction reliably. Some tools declaring a newer Node still run fine on the floor; -others crash on a feature they never declared. Verify by actually running on the oldest -supported version. - ### The public API is semver-bound Changing or removing anything re-exported from `src/index.ts`, or altering types in @@ -59,6 +54,43 @@ tests, CI, or tooling are not. do not broaden what a reference is able to select. - Prefer an explicit error over silently accepting a malformed document. +## API design + +Prefer removing footguns over adding convenience. A default that makes a security +decision on the caller's behalf is a footgun: the caller lives with the consequence +without ever having made the choice. + +- Don't add a default for anything security-relevant. Throw instead: the errors + `signatureAlgorithm is required` and `digestAlgorithm is required` exist so that + nobody silently inherits SHA-1. +- Where guessing at an extension point would be dangerous, ship an inert default rather + than a working one. `getCertFromKeyInfo` defaults to `SignedXml.noop`, not to "trust + the certificate embedded in the document" — that default would let an attacker supply + the key that verifies their own signature. +- Keep dangerous-but-legitimate features off until asked for. HMAC is supported, but the + caller has to call `enableHMAC()`. +- A choice is only real if it is documented. When you require the implementer to decide, + list the sensible options and their trade-offs in `README.md` so they can choose + knowingly. + +## Tests + +The suite is not here to cover the code. It is here to pin down the things a signature +library has to get right, which is a much smaller set: + +- **Attack vectors** — the ways a crafted document could get a bad signature accepted. + `describe("Signature self-reference prevention")` in + `test/signature-object-tests.spec.ts` is the model: it asserts that a `Reference` + cannot point at `SignedInfo` or at the `Signature` itself. +- **Spec compliance and interoperability** — canonicalization, digests and transforms + behaving as the specs require, and documents produced by other implementations still + verifying. That is what the SAML, WS-Fed and Java validator fixtures are for. + +Don't test internal implementation details. A test that pins a private method or simply +restates the code catches nothing, and it makes future refactoring expensive. Add a test +when a change alters what the library accepts or rejects; skip it when the change is +internal and the observable behavior is the same. + ## Style - Strict TypeScript (`strict: true`), CommonJS, target ES2020. @@ -66,12 +98,9 @@ tests, CI, or tooling are not. deprecated API fails lint even when it works; `@typescript-eslint/no-non-null-assertion` is an error, so no `!` assertions. - Prettier owns formatting (`printWidth: 100`). Don't hand-format. -- Prettier 3 does not auto-load plugins. A plugin in `devDependencies` does nothing - unless it is also listed under `plugins` in `.prettierrc.json`. ## Conventions -- Keep changes minimal and focused; match the surrounding style. +- Keep changes minimal and focused; use modern semantic coding practices. - Work in `src/` and `test/` unless asked otherwise. - Never edit `node_modules/` or `lib/`. -- Add a test for any behaviour change. The suite is the safety net for a security library. From 29fa30ea03f8b9487d400a1a50c172bf07cdcb0a Mon Sep 17 00:00:00 2001 From: Chris Barth Date: Sun, 6 Sep 2026 08:47:08 -0500 Subject: [PATCH 03/10] docs: add a commenting standard to AGENTS.md MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Agents habitually narrate what code does, which duplicates something the code already says and goes stale as soon as the line beneath it changes. Write the rule down: code describes itself, and comments cover only what it cannot say — why, not what or how. Uses the constant-time comparison in src/signature-algorithms.ts as the model, since its comments are the good kind: two lines giving the reason the comparison must be constant-time and the issue it came from, and one flagging that timingSafeEqual throws on a length mismatch, which the call site does not reveal. Also carves out JSDoc on exported API, which documents the contract for consumers rather than narrating the implementation, so the rule does not get over-applied to it. Co-Authored-By: Claude Opus 5 --- AGENTS.md | 32 ++++++++++++++++++++++++++++++++ 1 file changed, 32 insertions(+) diff --git a/AGENTS.md b/AGENTS.md index 2e6644c5..16626033 100644 --- a/AGENTS.md +++ b/AGENTS.md @@ -99,6 +99,38 @@ internal and the observable behavior is the same. is an error, so no `!` assertions. - Prettier owns formatting (`printWidth: 100`). Don't hand-format. +## Comments + +Code describes itself. Name things well and keep functions small enough that the _what_ +and the _how_ are readable from the code, then don't restate them in prose that goes +stale the first time someone edits the line below it. + +Comment only what the code cannot say: _why_ something is done, what would break if it +were done the obvious way, and which non-obvious constraint is being satisfied. +Exceptions, gotchas, threat-model reasoning, spec quirks, and a link to the issue that +prompted the code are all worth writing down. + +The constant-time comparison in `src/signature-algorithms.ts` is the model: + +``` +// Use constant-time comparison to prevent timing attacks (CWE-208) +// See: https://github.com/node-saml/xml-crypto/issues/522 + +// timingSafeEqual throws if buffer lengths don't match +``` + +None of that repeats the code. The first two lines say why the comparison has to be +constant-time and where the requirement came from; the third flags behavior of +`timingSafeEqual` that the call site doesn't reveal. + +A comment reading "loop over the references" above a loop over references, or one +restating a field's name as a sentence, earns nothing and costs a review every time the +code beneath it changes. Delete those rather than update them. + +JSDoc on exported API is a separate thing and is welcome: it documents the contract for +consumers and surfaces in their editor. Keep it about the contract — parameters, return +values, what throws, what is deprecated — not about the implementation. + ## Conventions - Keep changes minimal and focused; use modern semantic coding practices. From 5d4cf11917af5867863f4d0e96c05f7a7272cf5d Mon Sep 17 00:00:00 2001 From: Chris Barth Date: Sun, 6 Sep 2026 09:05:18 -0500 Subject: [PATCH 04/10] Lint --- AGENTS.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/AGENTS.md b/AGENTS.md index 16626033..b538bf48 100644 --- a/AGENTS.md +++ b/AGENTS.md @@ -112,7 +112,7 @@ prompted the code are all worth writing down. The constant-time comparison in `src/signature-algorithms.ts` is the model: -``` +```javascript // Use constant-time comparison to prevent timing attacks (CWE-208) // See: https://github.com/node-saml/xml-crypto/issues/522 From 91995157382984c62a11ddafdf40d800bf3e8ca0 Mon Sep 17 00:00:00 2001 From: Chris Barth Date: Sun, 6 Sep 2026 09:24:38 -0500 Subject: [PATCH 05/10] Remove directions that won't age well --- AGENTS.md | 15 +-------------- 1 file changed, 1 insertion(+), 14 deletions(-) diff --git a/AGENTS.md b/AGENTS.md index b538bf48..20f06364 100644 --- a/AGENTS.md +++ b/AGENTS.md @@ -107,22 +107,9 @@ stale the first time someone edits the line below it. Comment only what the code cannot say: _why_ something is done, what would break if it were done the obvious way, and which non-obvious constraint is being satisfied. -Exceptions, gotchas, threat-model reasoning, spec quirks, and a link to the issue that +Exceptions, gotchas, threat-model reasoning, spec quirks, and a link to the issue or spec that prompted the code are all worth writing down. -The constant-time comparison in `src/signature-algorithms.ts` is the model: - -```javascript -// Use constant-time comparison to prevent timing attacks (CWE-208) -// See: https://github.com/node-saml/xml-crypto/issues/522 - -// timingSafeEqual throws if buffer lengths don't match -``` - -None of that repeats the code. The first two lines say why the comparison has to be -constant-time and where the requirement came from; the third flags behavior of -`timingSafeEqual` that the call site doesn't reveal. - A comment reading "loop over the references" above a loop over references, or one restating a field's name as a sentence, earns nothing and costs a review every time the code beneath it changes. Delete those rather than update them. From d95422e553964ac69116a757bcd79f17617ca32c Mon Sep 17 00:00:00 2001 From: Chris Barth Date: Sun, 6 Sep 2026 23:01:24 -0500 Subject: [PATCH 06/10] docs: make the Tests section concrete and location-independent Drop the pointers to a specific describe block and spec file. They were the clearest illustration available, but a test that gets renamed or moved turns the guidance into a dead reference, and the point stands without them. Replace them by stating the shape of a test outright, since that is what an agent needs in order to decide whether to write one at all. A test feeds the library XML plus a configuration a JavaScript caller could actually pass, then asserts the library does not return improper data (spec compliance, interoperability, best practice) and does not report something as secure or trusted when it is not (the attack-vector case). The configuration point is the one most easily missed: the types only protect TypeScript users, so anything reachable from plain JavaScript is reachable in production regardless of what tsc would have said. Tests should therefore be written against what JavaScript allows, casting past the type error where that is the whole point. Notes to use `as` rather than `!`, since no-non-null-assertion is an error and applies to test files too. Co-Authored-By: Claude Opus 5 --- AGENTS.md | 42 +++++++++++++++++++++++++++--------------- 1 file changed, 27 insertions(+), 15 deletions(-) diff --git a/AGENTS.md b/AGENTS.md index 20f06364..fa5b69b6 100644 --- a/AGENTS.md +++ b/AGENTS.md @@ -75,21 +75,33 @@ without ever having made the choice. ## Tests -The suite is not here to cover the code. It is here to pin down the things a signature -library has to get right, which is a much smaller set: - -- **Attack vectors** — the ways a crafted document could get a bad signature accepted. - `describe("Signature self-reference prevention")` in - `test/signature-object-tests.spec.ts` is the model: it asserts that a `Reference` - cannot point at `SignedInfo` or at the `Signature` itself. -- **Spec compliance and interoperability** — canonicalization, digests and transforms - behaving as the specs require, and documents produced by other implementations still - verifying. That is what the SAML, WS-Fed and Java validator fixtures are for. - -Don't test internal implementation details. A test that pins a private method or simply -restates the code catches nothing, and it makes future refactoring expensive. Add a test -when a change alters what the library accepts or rejects; skip it when the change is -internal and the observable behavior is the same. +The suite is not here to cover the code. It exists to catch two specific failures, and a +test that is not chasing one of them probably should not exist. + +Every test has the same shape. Give the library: + +- **XML** — a document crafted to exercise the case. +- **A configuration a JavaScript caller could actually pass.** The types only protect + TypeScript users. If a configuration is reachable from plain JavaScript then it is + reachable in production, whether or not `tsc` would have rejected it, so write the test + for what JavaScript allows rather than for what the types permit. When the point of the + test is that a JavaScript caller can reach that state, casting away the type error is + correct; use `as`, since `!` assertions fail lint. + +Then assert that the library does neither of these: + +1. **Returns improper data.** Output that violates the specs, fails to interoperate with + documents other implementations produce, or ignores an established best practice. +2. **Claims something is secure or trusted when it is not.** Reports a signature as + valid, or data as trustworthy, when the document does not justify it. This is the + attack-vector case, and the worse of the two, because the caller has no way to detect + the lie. + +Nothing else is likely to earn a test. Don't pin internal implementation details: a test +asserting how a private method behaves, or one that restates the code, catches nothing +and makes refactoring expensive. Add a test when a change alters what the library +accepts, rejects, or emits; skip it when the change is internal and the observable +behavior is identical. ## Style From 73645110269457855526f160375e78dfa8df21d1 Mon Sep 17 00:00:00 2001 From: Chris Barth Date: Sun, 6 Sep 2026 23:41:18 -0500 Subject: [PATCH 07/10] docs: refine commenting standard with linking and JSDoc rules Expands on the existing commenting standard to provide more specific guidance. Clarifies that comments should explicitly link to issues or specs, and emphasizes keeping comments concise and "DRY" by citing rather than quoting. Also defines the appropriate use of `/** */` JSDoc blocks, reserving them for exported API contracts and discouraging their use on internal code to avoid implying non-existent contracts. --- AGENTS.md | 12 ++++++++---- 1 file changed, 8 insertions(+), 4 deletions(-) diff --git a/AGENTS.md b/AGENTS.md index fa5b69b6..655cb099 100644 --- a/AGENTS.md +++ b/AGENTS.md @@ -118,9 +118,12 @@ and the _how_ are readable from the code, then don't restate them in prose that stale the first time someone edits the line below it. Comment only what the code cannot say: _why_ something is done, what would break if it -were done the obvious way, and which non-obvious constraint is being satisfied. -Exceptions, gotchas, threat-model reasoning, spec quirks, and a link to the issue or spec that -prompted the code are all worth writing down. +were done the obvious way, and which non-obvious constraint is being satisfied. Link the +issue or spec that prompted the code. + +If a comment is needed at all, keep it DRY. The `it()` name plus a spec link is often the +whole comment. Cite, don't quote: prefer a section number and a URL over the sentence they +contain. Keep it to a line or two. A comment reading "loop over the references" above a loop over references, or one restating a field's name as a sentence, earns nothing and costs a review every time the @@ -128,7 +131,8 @@ code beneath it changes. Delete those rather than update them. JSDoc on exported API is a separate thing and is welcome: it documents the contract for consumers and surfaces in their editor. Keep it about the contract — parameters, return -values, what throws, what is deprecated — not about the implementation. +values, what throws, what is deprecated — not about the implementation. Reserve the `/** */` +form for that; on internal code and tests it advertises a contract that isn't there. ## Conventions From 6e552fbcfac9b8620c95e063ce0819901da4d506 Mon Sep 17 00:00:00 2001 From: Chris Barth Date: Sun, 6 Sep 2026 23:47:05 -0500 Subject: [PATCH 08/10] docs: add guidance for bug fix testing Clarifies the process for validating bug fixes by requiring observation of the test failure for the reported reason. Stresses that a regression test is only meaningful if its failure is confirmed, and that branches reproducing a bug should remain red until the fix is proven. --- AGENTS.md | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/AGENTS.md b/AGENTS.md index 655cb099..b1c127db 100644 --- a/AGENTS.md +++ b/AGENTS.md @@ -103,6 +103,11 @@ and makes refactoring expensive. Add a test when a change alters what the librar accepts, rejects, or emits; skip it when the change is internal and the observable behavior is identical. +For a bug fix, watch the test fail first. A regression test nobody observed failing — for +the reported reason, not an unrelated one — proves nothing about the fix. A branch that +only reproduces a bug is legitimately red; say so rather than skipping the test to get +green. + ## Style - Strict TypeScript (`strict: true`), CommonJS, target ES2020. From aefc9451cbe7d346160fb81a3f8a8f2692f8dc24 Mon Sep 17 00:00:00 2001 From: Chris Barth Date: Wed, 9 Sep 2026 11:46:56 -0500 Subject: [PATCH 09/10] Improve testing section --- AGENTS.md | 55 ++++++++++-------------- src/types.ts | 3 +- test/canonicalization-unit-tests.spec.ts | 4 +- 3 files changed, 26 insertions(+), 36 deletions(-) diff --git a/AGENTS.md b/AGENTS.md index b1c127db..74626208 100644 --- a/AGENTS.md +++ b/AGENTS.md @@ -75,38 +75,25 @@ without ever having made the choice. ## Tests -The suite is not here to cover the code. It exists to catch two specific failures, and a -test that is not chasing one of them probably should not exist. - -Every test has the same shape. Give the library: - -- **XML** — a document crafted to exercise the case. -- **A configuration a JavaScript caller could actually pass.** The types only protect - TypeScript users. If a configuration is reachable from plain JavaScript then it is - reachable in production, whether or not `tsc` would have rejected it, so write the test - for what JavaScript allows rather than for what the types permit. When the point of the - test is that a JavaScript caller can reach that state, casting away the type error is - correct; use `as`, since `!` assertions fail lint. - -Then assert that the library does neither of these: - -1. **Returns improper data.** Output that violates the specs, fails to interoperate with - documents other implementations produce, or ignores an established best practice. -2. **Claims something is secure or trusted when it is not.** Reports a signature as - valid, or data as trustworthy, when the document does not justify it. This is the - attack-vector case, and the worse of the two, because the caller has no way to detect - the lie. - -Nothing else is likely to earn a test. Don't pin internal implementation details: a test -asserting how a private method behaves, or one that restates the code, catches nothing -and makes refactoring expensive. Add a test when a change alters what the library -accepts, rejects, or emits; skip it when the change is internal and the observable -behavior is identical. - -For a bug fix, watch the test fail first. A regression test nobody observed failing — for -the reported reason, not an unrelated one — proves nothing about the fix. A branch that -only reproduces a bug is legitimately red; say so rather than skipping the test to get -green. +Tests should protect observable behavior rather than implementation details. Favor tests +that establish what the library accepts, rejects, emits, or considers trustworthy. +Security regressions are especially important: a test should ensure that malformed or +adversarial XML cannot cause the library to report untrusted data as valid. + +- Test at a public boundary for the behavior being changed. +- Where possible, start with XML and a configuration a JavaScript caller could actually + provide, then exercise the public API. +- Test an algorithm or utility directly only when it has an independently defined + observable contract, such as canonicalization or exported encoding utilities. Assert its + externally meaningful input/output behavior rather than its private implementation. +- Do not unit-test private methods merely to increase coverage or mirror their + implementation. Good public-boundary tests naturally exercise meaningful code paths. + Uncovered code indicates either inadequately tested public behavior or code that may be + unnecessary; determine which rather than adding private-method tests to raise coverage. +- Add a test when a change alters what the library accepts, rejects, emits, or considers + trustworthy. +- For a bug fix, observe the regression test failing for the reported reason before + applying the fix. ## Style @@ -144,3 +131,7 @@ form for that; on internal code and tests it advertises a contract that isn't th - Keep changes minimal and focused; use modern semantic coding practices. - Work in `src/` and `test/` unless asked otherwise. - Never edit `node_modules/` or `lib/`. +- Before changing behavior, read the relevant implementation, tests, and public API. Do + not infer behavior from names or issue descriptions when the repository can answer the + question. Keep the change scoped to the requested problem; do not combine bug fixes with + unrelated refactoring or cleanup. diff --git a/src/types.ts b/src/types.ts index 89c0b304..08c4300f 100644 --- a/src/types.ts +++ b/src/types.ts @@ -18,8 +18,7 @@ export type CanonicalizationAlgorithmType = | string; export type CanonicalizationOrTransformAlgorithmType = - | CanonicalizationAlgorithmType - | "http://www.w3.org/2000/09/xmldsig#enveloped-signature"; + CanonicalizationAlgorithmType | "http://www.w3.org/2000/09/xmldsig#enveloped-signature"; export type HashAlgorithmType = | "http://www.w3.org/2000/09/xmldsig#sha1" diff --git a/test/canonicalization-unit-tests.spec.ts b/test/canonicalization-unit-tests.spec.ts index 4bce8a6f..6a997656 100644 --- a/test/canonicalization-unit-tests.spec.ts +++ b/test/canonicalization-unit-tests.spec.ts @@ -319,7 +319,7 @@ describe("Canonicalization unit tests", function () { ); }); - it("SignedInfo canonization", function () { + (it("SignedInfo canonization", function () { compare( 'http://stockservice.contoso.com/wse/samples/2003/06/StockQuoteRequestuuid:6250c037-bcde-40ab-82b3-3a08efc86cdchttp://schemas.xmlsoap.org/ws/2004/03/addressing/role/anonymoushttp://localhost:8889/2008-09-01T17:44:21Z2008-09-01T17:49:21ZMIIBxDCCAW6gAwIBAgIQxUSXFzWJYYtOZnmmuOMKkjANBgkqhkiG9w0BAQQFADAWMRQwEgYDVQQDEwtSb290IEFnZW5jeTAeFw0wMzA3MDgxODQ3NTlaFw0zOTEyMzEyMzU5NTlaMB8xHTAbBgNVBAMTFFdTRTJRdWlja1N0YXJ0Q2xpZW50MIGfMA0GCSqGSIb3DQEBAQUAA4GNADCBiQKBgQC+L6aB9x928noY4+0QBsXnxkQE4quJl7c3PUPdVu7k9A02hRG481XIfWhrDY5i7OEB7KGW7qFJotLLeMec/UkKUwCgv3VvJrs2nE9xO3SSWIdNzADukYh+Cxt+FUU6tUkDeqg7dqwivOXhuOTRyOI3HqbWTbumaLdc8jufz2LhaQIDAQABo0swSTBHBgNVHQEEQDA+gBAS5AktBh0dTwCNYSHcFmRjoRgwFjEUMBIGA1UEAxMLUm9vdCBBZ2VuY3mCEAY3bACqAGSKEc+41KpcNfQwDQYJKoZIhvcNAQEEBQADQQAfIbnMPVYkNNfX1tG1F+qfLhHwJdfDUZuPyRPucWF5qkh6sSdWVBY5sT/txBnVJGziyO8DPYdu2fPMER8ajJfl+465BlJx5xOfHsIFezQt0MS1vZQ=jEe8rnaaqBWZQe+xHBQXriVG99o=W45ginYdBVqOqEaqPI2piZMPReA=m2VlWz/ZDTWL7FREHK+wpKhvjJM=Qws229qmAzSTZ4OKmAUWgl0PWWo=iEazGnkPY5caCWVZOHyR87CZ1h0=Fkm7AbwiJCiOzY8ldfuA9pTW1G+EtE+UX4Cv7SoMIqeUdfWRDVHZpJAQyf7aoQnlpJNV/3k9L1PT6rJbfV478CkULJENPLm1m0fmDeLzhIHDEANuzp/AirC60tMD5jCARb4B4Nr/6bTmoyDQsTY8VLRiiINng7Mpweg1FZvd8a0=FABRIKAM', "//*[local-name(.)='SignedInfo']", @@ -395,7 +395,7 @@ describe("Canonicalization unit tests", function () { "//*[local-name(.)='Body']", '\n \n \n \n \n \n \n \n \n \n \n \n \n ererer\n dfdf\n \n \n \n \n \n \n \n \n \n erer\n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n ', ); - }); + })); it("Multiple Canonicalization with namespace definition outside of signed element", function () { const doc = new xmldom.DOMParser().parseFromString( From 1d299d23822547cb21b8e279deffa071350e6d4d Mon Sep 17 00:00:00 2001 From: Chris Barth Date: Wed, 9 Sep 2026 12:01:22 -0500 Subject: [PATCH 10/10] Improve test focus --- AGENTS.md | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/AGENTS.md b/AGENTS.md index 74626208..d027164f 100644 --- a/AGENTS.md +++ b/AGENTS.md @@ -87,9 +87,9 @@ adversarial XML cannot cause the library to report untrusted data as valid. observable contract, such as canonicalization or exported encoding utilities. Assert its externally meaningful input/output behavior rather than its private implementation. - Do not unit-test private methods merely to increase coverage or mirror their - implementation. Good public-boundary tests naturally exercise meaningful code paths. - Uncovered code indicates either inadequately tested public behavior or code that may be - unnecessary; determine which rather than adding private-method tests to raise coverage. + implementation. Uncovered code indicates either inadequately tested public behavior or + code that may be unnecessary; determine which rather than adding private-method tests + merely to increase coverage. - Add a test when a change alters what the library accepts, rejects, emits, or considers trustworthy. - For a bug fix, observe the regression test failing for the reported reason before