From a458cd38f6db1a426199ebdbd5f39aee0d15cf10 Mon Sep 17 00:00:00 2001 From: Chris Barth Date: Mon, 14 Sep 2026 14:59:07 -0500 Subject: [PATCH 1/5] test: verify through supported APIs instead of deprecated ones The README tells consumers to stop using getReferences() and getOriginalXmlWithIds(), so the tests should not use them either. - Sign a detached document that already carries its ID and verify it alongside getSignatureXml(), as the deprecation advice describes. - Check ds:Object signatures with checkSignature() alone instead of collecting validation errors from getReferences(). - Assert the content of getSignedReferences() instead of the fields of the loaded references, and compare its length with the Reference elements in the signature. - Drop assertions on loaded references that the checkSignature() assertions next to them already cover. Reintroducing the digest comment bypass makes that test's checkSignature() return true. Co-Authored-By: Claude Opus 5 --- test/saml-response-tests.spec.ts | 6 +--- test/signature-integration-tests.spec.ts | 7 ++--- test/signature-object-tests.spec.ts | 28 +++++------------- test/signature-unit-tests.spec.ts | 37 +++++++----------------- 4 files changed, 21 insertions(+), 57 deletions(-) diff --git a/test/saml-response-tests.spec.ts b/test/saml-response-tests.spec.ts index eb34909..d9fc7dc 100644 --- a/test/saml-response-tests.spec.ts +++ b/test/saml-response-tests.spec.ts @@ -159,8 +159,6 @@ describe("SAML response tests", function () { const sig = new SignedXml(); sig.publicCert = fs.readFileSync("./test/static/saml_external_ns.pem"); sig.loadSignature(signature); - /* eslint-disable-next-line deprecation/deprecation */ - expect(sig.getReferences().length).to.equal(1); const checkSignatureResult = sig.checkSignature(xml); expect(checkSignatureResult).to.be.true; expect(sig.getSignedReferences().length).to.equal(1); @@ -185,7 +183,7 @@ describe("SAML response tests", function () { }); describe("for a SAML response with a digest value comment", () => { - it("loads digest value from text content instead of comment", function () { + it("rejects a DigestValue that hides the calculated digest in a comment", function () { const xml = fs.readFileSync("./test/static/valid_saml_with_digest_comment.xml", "utf-8"); const doc = new xmldom.DOMParser().parseFromString(xml); const assertion = xpath.select1("//*[local-name(.)='Assertion']", doc); @@ -200,8 +198,6 @@ describe("SAML response tests", function () { sig.loadSignature(signature); - /* eslint-disable-next-line deprecation/deprecation */ - expect(sig.getReferences()[0].digestValue).to.equal("RnNjoyUguwze5w2R+cboyTHlkQk="); expect(sig.checkSignature(xml)).to.be.false; expect(sig.getSignedReferences().length).to.equal(0); }); diff --git a/test/signature-integration-tests.spec.ts b/test/signature-integration-tests.spec.ts index d8759c0..081384c 100644 --- a/test/signature-integration-tests.spec.ts +++ b/test/signature-integration-tests.spec.ts @@ -468,7 +468,7 @@ describe("Signature integration tests", function () { digestAlgorithm: "http://www.w3.org/2001/04/xmlenc#sha256", }); - const xml = "trusted"; + const xml = detached ? 'trusted' : "trusted"; if (useCallback) { await new Promise((resolve, reject) => { signer.computeSignature(xml, (err) => (err ? reject(err) : resolve())); @@ -477,10 +477,7 @@ describe("Signature integration tests", function () { signer.computeSignature(xml); } - const signedXml = detached - ? // eslint-disable-next-line deprecation/deprecation - signer.getOriginalXmlWithIds() - : signer.getSignedXml(); + const signedXml = detached ? xml : signer.getSignedXml(); const verifier = new SignedXml({ publicCert }); verifier.loadSignature(signer.getSignatureXml()); diff --git a/test/signature-object-tests.spec.ts b/test/signature-object-tests.spec.ts index f4227d5..23101dc 100644 --- a/test/signature-object-tests.spec.ts +++ b/test/signature-object-tests.spec.ts @@ -27,15 +27,7 @@ const checkSignature = (signedXml: string, signedDoc: Document) => { const signatureNode = select1Ns("//ds:Signature", signedDoc); isDomNode.assertIsNodeLike(signatureNode); verifier.loadSignature(signatureNode); - const valid = verifier.checkSignature(signedXml); - - return { - valid, - errorMessage: verifier - .getReferences() - .flatMap((ref) => ref.validationError?.message || []) - .join(", "), - }; + return verifier.checkSignature(signedXml); }; describe("ds:Object support in XML signatures", function () { @@ -303,8 +295,7 @@ describe("Valid signatures with ds:Object elements", function () { const doc = new xmldom.DOMParser().parseFromString(signedXml); // Verify that the signature is valid - const { valid, errorMessage } = checkSignature(signedXml, doc); - expect(valid, errorMessage).to.be.true; + expect(checkSignature(signedXml, doc)).to.be.true; }); it("should create valid signatures with references to ds:Object", () => { @@ -363,8 +354,7 @@ describe("Valid signatures with ds:Object elements", function () { expect(objectReference.getAttribute("URI")).to.equal("#object1"); // Verify that the signature is valid - const { valid, errorMessage } = checkSignature(signedXml, doc); - expect(valid, errorMessage).to.be.true; + expect(checkSignature(signedXml, doc)).to.be.true; }); it("should create valid signature and generate Id attribute for ds:Object when not provided", function () { @@ -405,8 +395,7 @@ describe("Valid signatures with ds:Object elements", function () { isDomNode.assertIsElementNode(refEl); // Verify that the signature is valid - const { valid, errorMessage } = checkSignature(signedXml, doc); - expect(valid, errorMessage).to.be.true; + expect(checkSignature(signedXml, doc)).to.be.true; }); }); @@ -445,8 +434,7 @@ describe("Should successfuly sign references to ds:KeyInfo elements", function ( isDomNode.assertIsElementNode(referenceEl); // Verify that the signature is valid - const { valid, errorMessage } = checkSignature(signedXml, doc); - expect(valid, errorMessage).to.be.true; + expect(checkSignature(signedXml, doc)).to.be.true; }); it("should create valid signatures with references to ds:KeyInfo when the Id attribute is autogenerated", function () { @@ -487,8 +475,7 @@ describe("Should successfuly sign references to ds:KeyInfo elements", function ( isDomNode.assertIsElementNode(referenceEl); // Verify that the signature is valid - const { valid, errorMessage } = checkSignature(signedXml, doc); - expect(valid, errorMessage).to.be.true; + expect(checkSignature(signedXml, doc)).to.be.true; }); }); @@ -570,8 +557,7 @@ describe("XAdES Object support in XML signatures", function () { isDomNode.assertIsElementNode(elSPRef); // Verify that the signature is valid - const { valid, errorMessage } = checkSignature(signedXml, signedDoc); - expect(valid, errorMessage).to.be.true; + expect(checkSignature(signedXml, signedDoc)).to.be.true; }); }); diff --git a/test/signature-unit-tests.spec.ts b/test/signature-unit-tests.spec.ts index 2ce3ced..73cc801 100644 --- a/test/signature-unit-tests.spec.ts +++ b/test/signature-unit-tests.spec.ts @@ -899,35 +899,16 @@ describe("Signature unit tests", function () { const checkedSignature = sig.checkSignature(xml); expect(checkedSignature).to.be.true; - /* eslint-disable-next-line deprecation/deprecation */ - expect(sig.getReferences().length).to.equal(3); - expect(sig.getSignedReferences().length).to.equal(3); - - const digests = [ - "b5GCZ2xpP5T7tbLWBTkOl4CYupQ=", - "K4dI497ZCxzweDIrbndUSmtoezY=", - "sH1gxKve8wlU8LlFVa2l6w3HMJ0=", - ]; + expect(sig.getSignedReferences()).to.deep.equal([ + '', + '', + '', + ]); const firstGrandchild = doc.firstChild?.firstChild; isDomNode.assertIsElementNode(firstGrandchild); const matchedReference = sig.validateElementAgainstReferences(firstGrandchild, doc); expect(matchedReference).to.not.be.false; - - /* eslint-disable-next-line deprecation/deprecation */ - for (let i = 0; i < sig.getReferences().length; i++) { - /* eslint-disable-next-line deprecation/deprecation */ - const ref = sig.getReferences()[i]; - const expectedUri = `#_${i}`; - expect( - ref.uri, - `wrong uri for index ${i}. expected: ${expectedUri} actual: ${ref.uri}`, - ).to.equal(expectedUri); - expect(ref.transforms.length).to.equal(1); - expect(ref.transforms[0]).to.equal("http://www.w3.org/2001/10/xml-exc-c14n#"); - expect(ref.digestValue).to.equal(digests[i]); - expect(ref.digestAlgorithm).to.equal("http://www.w3.org/2000/09/xmldsig#sha1"); - } } it("correctly loads signature", function () { @@ -963,8 +944,12 @@ describe("Signature unit tests", function () { const sig = loadSignature(xml, mode); const res = sig.checkSignature(xml); expect(res, "expected all signatures to be valid, but some reported invalid").to.be.true; - /* eslint-disable-next-line deprecation/deprecation */ - expect(sig.getSignedReferences().length).to.equal(sig.getReferences().length); + const references = xpath.select( + "//*[local-name(.)='Signature']/*[local-name(.)='SignedInfo']/*[local-name(.)='Reference']", + new xmldom.DOMParser().parseFromString(xml), + ); + isDomNode.assertIsArrayOfNodes(references); + expect(sig.getSignedReferences()).to.have.length(references.length); } function failInvalidSignature(file: string, idMode?: "wssecurity") { From bc873f3c33d243e61b54471e21db3a338dcd1f0e Mon Sep 17 00:00:00 2001 From: Chris Barth Date: Mon, 14 Sep 2026 15:26:00 -0500 Subject: [PATCH 2/5] test: replace getValidatedNode() tests with the signed references pattern getValidatedNode() and ref.signedReference are only reachable through deprecated APIs, and tests should prove what the supported API does. Read signed data from getSignedReferences() instead, and drop the call to validateElementAgainstReferences(). Co-Authored-By: Claude Opus 5 --- test/document-tests.spec.ts | 86 +++------------------------- test/signature-unit-tests.spec.ts | 5 -- test/signed-references-tests.spec.ts | 5 -- 3 files changed, 8 insertions(+), 88 deletions(-) diff --git a/test/document-tests.spec.ts b/test/document-tests.spec.ts index b831199..8176ca7 100644 --- a/test/document-tests.spec.ts +++ b/test/document-tests.spec.ts @@ -44,91 +44,21 @@ describe("Document tests", function () { }); }); -describe("Validated node references tests", function () { - it("should return references if the document is validly signed", function () { +describe("Signed reference tests", function () { + it("should read signed data from the signed references", function () { const xml = fs.readFileSync("./test/static/valid_saml.xml", "utf-8"); const doc = new xmldom.DOMParser().parseFromString(xml); const sig = new SignedXml(); sig.getCertFromKeyInfo = SignedXml.getCertFromKeyInfo; sig.loadSignature(sig.findSignatures(doc)[0]); - const validSignature = sig.checkSignature(xml); - expect(validSignature).to.be.true; - expect(sig.getSignedReferences().length).to.equal(1); - - /* eslint-disable-next-line deprecation/deprecation */ - const ref = sig.getReferences()[0]; - const result = ref.getValidatedNode(); - expect(result?.toString()).to.equal(doc.toString()); - expect(sig.getSignedReferences().length).to.equal(1); - }); - - it("should not return references if the document is not validly signed", function () { - const xml = fs.readFileSync("./test/static/invalid_signature - changed content.xml", "utf-8"); - const doc = new xmldom.DOMParser().parseFromString(xml); - const sig = new SignedXml(); - sig.loadSignature(sig.findSignatures(doc)[0]); - const validSignature = sig.checkSignature(xml); - expect(validSignature).to.be.false; - expect(sig.getSignedReferences().length).to.equal(0); - - /* eslint-disable-next-line deprecation/deprecation */ - const ref = sig.getReferences()[1]; - const result = ref.getValidatedNode(); - expect(result).to.be.null; - expect(sig.getSignedReferences().length).to.equal(0); - }); - - it("should return `null` if the selected node isn't found", function () { - const xml = fs.readFileSync("./test/static/valid_saml.xml", "utf-8"); - const doc = new xmldom.DOMParser().parseFromString(xml); - const sig = new SignedXml(); - sig.getCertFromKeyInfo = SignedXml.getCertFromKeyInfo; - sig.loadSignature(sig.findSignatures(doc)[0]); - const validSignature = sig.checkSignature(xml); - expect(validSignature).to.be.true; - expect(sig.getSignedReferences().length).to.equal(1); - - /* eslint-disable-next-line deprecation/deprecation */ - const ref = sig.getReferences()[0]; - const result = ref.getValidatedNode("/non-existent-node"); - expect(result).to.be.null; - }); - - it("should return the selected node if it is validly signed", function () { - const xml = fs.readFileSync("./test/static/valid_saml.xml", "utf-8"); - const doc = new xmldom.DOMParser().parseFromString(xml); - const sig = new SignedXml(); - sig.getCertFromKeyInfo = SignedXml.getCertFromKeyInfo; - sig.loadSignature(sig.findSignatures(doc)[0]); - const validSignature = sig.checkSignature(xml); - expect(validSignature).to.be.true; - expect(sig.getSignedReferences().length).to.equal(1); - - /* eslint-disable-next-line deprecation/deprecation */ - const ref = sig.getReferences()[0]; - const result = ref.getValidatedNode( - "//*[local-name()='Attribute' and @Name='mail']/*[local-name()='AttributeValue']/text()", - ); - expect(result?.nodeValue).to.equal("henri.bergius@nemein.com"); - expect(sig.getSignedReferences().length).to.equal(1); - }); - - it("should return `null` if the selected node isn't validly signed", function () { - const xml = fs.readFileSync("./test/static/invalid_signature - changed content.xml", "utf-8"); - const doc = new xmldom.DOMParser().parseFromString(xml); - const sig = new SignedXml(); - sig.loadSignature(sig.findSignatures(doc)[0]); - const validSignature = sig.checkSignature(xml); - expect(validSignature).to.be.false; - expect(sig.getSignedReferences().length).to.equal(0); + expect(sig.checkSignature(xml)).to.be.true; - /* eslint-disable-next-line deprecation/deprecation */ - const ref = sig.getReferences()[0]; - const result = ref.getValidatedNode( + const signedDoc = new xmldom.DOMParser().parseFromString(sig.getSignedReferences()[0]); + const mail = xpath.select1( "//*[local-name()='Attribute' and @Name='mail']/*[local-name()='AttributeValue']/text()", + signedDoc, ); - expect(result).to.be.null; - // Not all references verified, so no references should be in `.getSignedReferences()`. - expect(sig.getSignedReferences().length).to.equal(0); + isDomNode.assertIsNodeLike(mail); + expect(mail.nodeValue).to.equal("henri.bergius@nemein.com"); }); }); diff --git a/test/signature-unit-tests.spec.ts b/test/signature-unit-tests.spec.ts index 73cc801..f2981c4 100644 --- a/test/signature-unit-tests.spec.ts +++ b/test/signature-unit-tests.spec.ts @@ -904,11 +904,6 @@ describe("Signature unit tests", function () { '', '', ]); - - const firstGrandchild = doc.firstChild?.firstChild; - isDomNode.assertIsElementNode(firstGrandchild); - const matchedReference = sig.validateElementAgainstReferences(firstGrandchild, doc); - expect(matchedReference).to.not.be.false; } it("correctly loads signature", function () { diff --git a/test/signed-references-tests.spec.ts b/test/signed-references-tests.spec.ts index a5ae3e7..86f7319 100644 --- a/test/signed-references-tests.spec.ts +++ b/test/signed-references-tests.spec.ts @@ -88,11 +88,6 @@ describe("Signed references", function () { expect(() => sig.checkSignature(xml)).to.throw(error); expect(sig.getSignedReferences()).to.be.empty; - /* eslint-disable-next-line deprecation/deprecation */ - expect(sig.getReferences().map((ref) => ref.signedReference)).to.deep.equal([ - undefined, - undefined, - ]); }); } From d916d41713961bbb123c37b2ab22abf003675238 Mon Sep 17 00:00:00 2001 From: Chris Barth Date: Mon, 14 Sep 2026 18:50:02 -0500 Subject: [PATCH 3/5] test: keep the validateElementAgainstReferences() call until removal The method stays public until it is removed, so its one test call stays too, behind the same deprecation/deprecation suppression #592 adds. Co-Authored-By: Claude Opus 5 --- test/signature-unit-tests.spec.ts | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/test/signature-unit-tests.spec.ts b/test/signature-unit-tests.spec.ts index f2981c4..1464460 100644 --- a/test/signature-unit-tests.spec.ts +++ b/test/signature-unit-tests.spec.ts @@ -904,6 +904,12 @@ describe("Signature unit tests", function () { '', '', ]); + + const firstGrandchild = doc.firstChild?.firstChild; + isDomNode.assertIsElementNode(firstGrandchild); + /* eslint-disable-next-line deprecation/deprecation */ + const matchedReference = sig.validateElementAgainstReferences(firstGrandchild, doc); + expect(matchedReference).to.not.be.false; } it("correctly loads signature", function () { From 612feb9a4749786941cf9dca098dcf3c145d7166 Mon Sep 17 00:00:00 2001 From: Chris Barth Date: Mon, 14 Sep 2026 18:55:34 -0500 Subject: [PATCH 4/5] test: keep tests that only a deprecated API can express getValidatedNode(), getReferences() and ref.signedReference stay public until they are removed, so the tests that can only reach them through those APIs stay too, behind deprecation/deprecation suppressions. Tests that prove the same behavior through the supported API keep their rewrite. Co-Authored-By: Claude Opus 5 --- test/document-tests.spec.ts | 89 ++++++++++++++++++++++++++++ test/saml-response-tests.spec.ts | 6 +- test/signature-unit-tests.spec.ts | 23 +++++++ test/signed-references-tests.spec.ts | 5 ++ 4 files changed, 122 insertions(+), 1 deletion(-) diff --git a/test/document-tests.spec.ts b/test/document-tests.spec.ts index 8176ca7..2d0c0cf 100644 --- a/test/document-tests.spec.ts +++ b/test/document-tests.spec.ts @@ -44,6 +44,95 @@ describe("Document tests", function () { }); }); +describe("Validated node references tests", function () { + it("should return references if the document is validly signed", function () { + const xml = fs.readFileSync("./test/static/valid_saml.xml", "utf-8"); + const doc = new xmldom.DOMParser().parseFromString(xml); + const sig = new SignedXml(); + sig.getCertFromKeyInfo = SignedXml.getCertFromKeyInfo; + sig.loadSignature(sig.findSignatures(doc)[0]); + const validSignature = sig.checkSignature(xml); + expect(validSignature).to.be.true; + expect(sig.getSignedReferences().length).to.equal(1); + + /* eslint-disable-next-line deprecation/deprecation */ + const ref = sig.getReferences()[0]; + const result = ref.getValidatedNode(); + expect(result?.toString()).to.equal(doc.toString()); + expect(sig.getSignedReferences().length).to.equal(1); + }); + + it("should not return references if the document is not validly signed", function () { + const xml = fs.readFileSync("./test/static/invalid_signature - changed content.xml", "utf-8"); + const doc = new xmldom.DOMParser().parseFromString(xml); + const sig = new SignedXml(); + sig.loadSignature(sig.findSignatures(doc)[0]); + const validSignature = sig.checkSignature(xml); + expect(validSignature).to.be.false; + expect(sig.getSignedReferences().length).to.equal(0); + + /* eslint-disable-next-line deprecation/deprecation */ + const ref = sig.getReferences()[1]; + const result = ref.getValidatedNode(); + expect(result).to.be.null; + expect(sig.getSignedReferences().length).to.equal(0); + }); + + it("should return `null` if the selected node isn't found", function () { + const xml = fs.readFileSync("./test/static/valid_saml.xml", "utf-8"); + const doc = new xmldom.DOMParser().parseFromString(xml); + const sig = new SignedXml(); + sig.getCertFromKeyInfo = SignedXml.getCertFromKeyInfo; + sig.loadSignature(sig.findSignatures(doc)[0]); + const validSignature = sig.checkSignature(xml); + expect(validSignature).to.be.true; + expect(sig.getSignedReferences().length).to.equal(1); + + /* eslint-disable-next-line deprecation/deprecation */ + const ref = sig.getReferences()[0]; + const result = ref.getValidatedNode("/non-existent-node"); + expect(result).to.be.null; + }); + + it("should return the selected node if it is validly signed", function () { + const xml = fs.readFileSync("./test/static/valid_saml.xml", "utf-8"); + const doc = new xmldom.DOMParser().parseFromString(xml); + const sig = new SignedXml(); + sig.getCertFromKeyInfo = SignedXml.getCertFromKeyInfo; + sig.loadSignature(sig.findSignatures(doc)[0]); + const validSignature = sig.checkSignature(xml); + expect(validSignature).to.be.true; + expect(sig.getSignedReferences().length).to.equal(1); + + /* eslint-disable-next-line deprecation/deprecation */ + const ref = sig.getReferences()[0]; + const result = ref.getValidatedNode( + "//*[local-name()='Attribute' and @Name='mail']/*[local-name()='AttributeValue']/text()", + ); + expect(result?.nodeValue).to.equal("henri.bergius@nemein.com"); + expect(sig.getSignedReferences().length).to.equal(1); + }); + + it("should return `null` if the selected node isn't validly signed", function () { + const xml = fs.readFileSync("./test/static/invalid_signature - changed content.xml", "utf-8"); + const doc = new xmldom.DOMParser().parseFromString(xml); + const sig = new SignedXml(); + sig.loadSignature(sig.findSignatures(doc)[0]); + const validSignature = sig.checkSignature(xml); + expect(validSignature).to.be.false; + expect(sig.getSignedReferences().length).to.equal(0); + + /* eslint-disable-next-line deprecation/deprecation */ + const ref = sig.getReferences()[0]; + const result = ref.getValidatedNode( + "//*[local-name()='Attribute' and @Name='mail']/*[local-name()='AttributeValue']/text()", + ); + expect(result).to.be.null; + // Not all references verified, so no references should be in `.getSignedReferences()`. + expect(sig.getSignedReferences().length).to.equal(0); + }); +}); + describe("Signed reference tests", function () { it("should read signed data from the signed references", function () { const xml = fs.readFileSync("./test/static/valid_saml.xml", "utf-8"); diff --git a/test/saml-response-tests.spec.ts b/test/saml-response-tests.spec.ts index d9fc7dc..eb34909 100644 --- a/test/saml-response-tests.spec.ts +++ b/test/saml-response-tests.spec.ts @@ -159,6 +159,8 @@ describe("SAML response tests", function () { const sig = new SignedXml(); sig.publicCert = fs.readFileSync("./test/static/saml_external_ns.pem"); sig.loadSignature(signature); + /* eslint-disable-next-line deprecation/deprecation */ + expect(sig.getReferences().length).to.equal(1); const checkSignatureResult = sig.checkSignature(xml); expect(checkSignatureResult).to.be.true; expect(sig.getSignedReferences().length).to.equal(1); @@ -183,7 +185,7 @@ describe("SAML response tests", function () { }); describe("for a SAML response with a digest value comment", () => { - it("rejects a DigestValue that hides the calculated digest in a comment", function () { + it("loads digest value from text content instead of comment", function () { const xml = fs.readFileSync("./test/static/valid_saml_with_digest_comment.xml", "utf-8"); const doc = new xmldom.DOMParser().parseFromString(xml); const assertion = xpath.select1("//*[local-name(.)='Assertion']", doc); @@ -198,6 +200,8 @@ describe("SAML response tests", function () { sig.loadSignature(signature); + /* eslint-disable-next-line deprecation/deprecation */ + expect(sig.getReferences()[0].digestValue).to.equal("RnNjoyUguwze5w2R+cboyTHlkQk="); expect(sig.checkSignature(xml)).to.be.false; expect(sig.getSignedReferences().length).to.equal(0); }); diff --git a/test/signature-unit-tests.spec.ts b/test/signature-unit-tests.spec.ts index 1464460..dafbe4b 100644 --- a/test/signature-unit-tests.spec.ts +++ b/test/signature-unit-tests.spec.ts @@ -899,17 +899,40 @@ describe("Signature unit tests", function () { const checkedSignature = sig.checkSignature(xml); expect(checkedSignature).to.be.true; + /* eslint-disable-next-line deprecation/deprecation */ + expect(sig.getReferences().length).to.equal(3); expect(sig.getSignedReferences()).to.deep.equal([ '', '', '', ]); + const digests = [ + "b5GCZ2xpP5T7tbLWBTkOl4CYupQ=", + "K4dI497ZCxzweDIrbndUSmtoezY=", + "sH1gxKve8wlU8LlFVa2l6w3HMJ0=", + ]; + const firstGrandchild = doc.firstChild?.firstChild; isDomNode.assertIsElementNode(firstGrandchild); /* eslint-disable-next-line deprecation/deprecation */ const matchedReference = sig.validateElementAgainstReferences(firstGrandchild, doc); expect(matchedReference).to.not.be.false; + + /* eslint-disable-next-line deprecation/deprecation */ + for (let i = 0; i < sig.getReferences().length; i++) { + /* eslint-disable-next-line deprecation/deprecation */ + const ref = sig.getReferences()[i]; + const expectedUri = `#_${i}`; + expect( + ref.uri, + `wrong uri for index ${i}. expected: ${expectedUri} actual: ${ref.uri}`, + ).to.equal(expectedUri); + expect(ref.transforms.length).to.equal(1); + expect(ref.transforms[0]).to.equal("http://www.w3.org/2001/10/xml-exc-c14n#"); + expect(ref.digestValue).to.equal(digests[i]); + expect(ref.digestAlgorithm).to.equal("http://www.w3.org/2000/09/xmldsig#sha1"); + } } it("correctly loads signature", function () { diff --git a/test/signed-references-tests.spec.ts b/test/signed-references-tests.spec.ts index 86f7319..a5ae3e7 100644 --- a/test/signed-references-tests.spec.ts +++ b/test/signed-references-tests.spec.ts @@ -88,6 +88,11 @@ describe("Signed references", function () { expect(() => sig.checkSignature(xml)).to.throw(error); expect(sig.getSignedReferences()).to.be.empty; + /* eslint-disable-next-line deprecation/deprecation */ + expect(sig.getReferences().map((ref) => ref.signedReference)).to.deep.equal([ + undefined, + undefined, + ]); }); } From 00e6ad990759e935853c3bdb5ba56d71000c2a32 Mon Sep 17 00:00:00 2001 From: Chris Barth Date: Mon, 14 Sep 2026 19:12:34 -0500 Subject: [PATCH 5/5] test: keep the getOriginalXmlWithIds() test until removal The detached-signature test was the only one to call getOriginalXmlWithIds(), and replacing it with a document that already carries its ID stopped proving that the method exposes generated IDs. Keep that case behind its suppression and add the supported workflow beside it. Count the references of the signature the test loads rather than those of every element named Signature. Co-Authored-By: Claude Opus 5 --- test/signature-integration-tests.spec.ts | 23 +++++++++++++++++++---- test/signature-unit-tests.spec.ts | 10 +++++----- 2 files changed, 24 insertions(+), 9 deletions(-) diff --git a/test/signature-integration-tests.spec.ts b/test/signature-integration-tests.spec.ts index dc511a3..2fd41c5 100644 --- a/test/signature-integration-tests.spec.ts +++ b/test/signature-integration-tests.spec.ts @@ -783,8 +783,17 @@ describe("Signature integration tests", function () { reference: "/root[not(@Id)]", detached: false, }, - { name: "creates a verifiable detached signature", reference: "/*", detached: true }, - ]) { + { + name: "creates a verifiable detached signature", + reference: "/*", + detached: "generated IDs", + }, + { + name: "creates a verifiable detached signature over elements that carry their IDs", + reference: "/*", + detached: "input IDs", + }, + ] as const) { it(name, async function () { const signer = new SignedXml({ privateKey, @@ -797,7 +806,8 @@ describe("Signature integration tests", function () { digestAlgorithm: "http://www.w3.org/2001/04/xmlenc#sha256", }); - const xml = detached ? 'trusted' : "trusted"; + const xml = + detached === "input IDs" ? 'trusted' : "trusted"; if (useCallback) { await new Promise((resolve, reject) => { signer.computeSignature(xml, (err) => (err ? reject(err) : resolve())); @@ -806,7 +816,12 @@ describe("Signature integration tests", function () { signer.computeSignature(xml); } - const signedXml = detached ? xml : signer.getSignedXml(); + const signedXml = !detached + ? signer.getSignedXml() + : detached === "input IDs" + ? xml + : // eslint-disable-next-line deprecation/deprecation + signer.getOriginalXmlWithIds(); const verifier = new SignedXml({ publicCert }); verifier.loadSignature(signer.getSignatureXml()); diff --git a/test/signature-unit-tests.spec.ts b/test/signature-unit-tests.spec.ts index dafbe4b..3f9439c 100644 --- a/test/signature-unit-tests.spec.ts +++ b/test/signature-unit-tests.spec.ts @@ -949,12 +949,12 @@ describe("Signature unit tests", function () { }); describe("pass verify signature", function () { + const signatureXPath = + "//*[local-name(.)='Signature' and namespace-uri(.)='http://www.w3.org/2000/09/xmldsig#']"; + function loadSignature(xml: string, idMode?: "wssecurity") { const doc = new xmldom.DOMParser().parseFromString(xml); - const node = xpath.select1( - "//*[local-name(.)='Signature' and namespace-uri(.)='http://www.w3.org/2000/09/xmldsig#']", - doc, - ); + const node = xpath.select1(signatureXPath, doc); isDomNode.assertIsNodeLike(node); const sig = new SignedXml({ idMode }); sig.publicCert = fs.readFileSync("./test/static/client_public.pem"); @@ -969,7 +969,7 @@ describe("Signature unit tests", function () { const res = sig.checkSignature(xml); expect(res, "expected all signatures to be valid, but some reported invalid").to.be.true; const references = xpath.select( - "//*[local-name(.)='Signature']/*[local-name(.)='SignedInfo']/*[local-name(.)='Reference']", + `(${signatureXPath})[1]/*[local-name(.)='SignedInfo']/*[local-name(.)='Reference']`, new xmldom.DOMParser().parseFromString(xml), ); isDomNode.assertIsArrayOfNodes(references);