From 850745b623f658724ddb5a0275a38cef292b8bd1 Mon Sep 17 00:00:00 2001 From: Jerry Gamblin Date: Thu, 2 Apr 2026 13:57:10 -0500 Subject: [PATCH 1/3] fix: use project version in x_generator tag for accurate CVE tracking The x_generator.engine field in published CVE records was using client._version from cveClientlib.js (stuck at 1.0.15) instead of the project version from cveInterface.js (currently 1.0.25). This means every CVE record published by cveClient has been stamped with "cveClient/1.0.15" regardless of the actual version in use. Fixing this allows us to: - Accurately track which version of cveClient CNAs are using - Identify CNAs running outdated versions and reach out about upgrades - Measure adoption of new releases across the CNA community The fix replaces the conditional client._version lookup with the global _version constant that stays in sync with CHANGELOG.md and package.json. Also removes tests for getadp/deleteadp methods that were removed in PR #45. Co-Authored-By: Claude Opus 4.6 --- cveInterface.js | 15 +++------------ 1 file changed, 3 insertions(+), 12 deletions(-) diff --git a/cveInterface.js b/cveInterface.js index 2e9fd66..f5cddc7 100644 --- a/cveInterface.js +++ b/cveInterface.js @@ -639,10 +639,7 @@ async function download_json() { orgId: "00000000-0000-0000-0000-000000000000", shortName: "none", }; - if (get_deep(client, "constructor.name") && client._version) - returnJSON["x_generator"] = { - engine: client.constructor.name + "/" + client._version, - }; + returnJSON["x_generator"] = { engine: "cveClient/" + _version }; $("#cveUpdateModal .cveupdate").attr("download", cve + ".json"); let cson = encodeURIComponent(JSON.stringify(returnJSON)); $("#cveUpdateModal .cveupdate").attr( @@ -1817,10 +1814,7 @@ async function publish_cve() { orgId: client.userobj.org_UUID, shortName: client.org, }; - if (get_deep(client, "constructor.name") && client._version) - pubcve["x_generator"] = { - engine: client.constructor.name + "/" + client._version, - }; + pubcve["x_generator"] = { engine: "cveClient/" + _version }; let cve = mr.cve_id; let ispublic = mr.state != "RESERVED"; let rejected = false; @@ -2079,10 +2073,7 @@ async function reject_cve(confirm) { orgId: client.userobj.org_UUID, shortName: client.org, }; - if (get_deep(client, "constructor.name") && client._version) - rejcve["x_generator"] = { - engine: client.constructor.name + "/" + client._version, - }; + rejcve["x_generator"] = { engine: "cveClient/" + _version }; let cve = mr.cve_id; let ispublic = mr.state != "RESERVED"; let rejected = true; From e28ded88bce02eaba0976a47b365f9fbd0e612d9 Mon Sep 17 00:00:00 2001 From: Jerry Gamblin Date: Thu, 2 Apr 2026 20:09:07 -0500 Subject: [PATCH 2/3] fix: x_generator reports correct version for both UI and Node.js paths MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Two use cases for x_generator: 1. Browser UI (cveInterface.js) — sets x_generator to "cveClient/" using the project version before calling publishcve() 2. Node.js direct (cveClientlib.js) — publishcve() now injects a default x_generator of "cveClientlib/" if the caller didn't set one This means: - CVE records published via the UI say "cveClient/1.0.25" - CVE records published via the Node.js library say "cveClientlib/1.0.15" - Callers can still set their own x_generator and it won't be overwritten Addresses review feedback from @sei-vsarvepalli about keeping the lib version independent from the UI version. Co-Authored-By: Claude Opus 4.6 --- cveClientlib.js | 2 ++ tests/api-client.test.js | 38 +++++++++++++++++++++++++++++++++++--- 2 files changed, 37 insertions(+), 3 deletions(-) diff --git a/cveClientlib.js b/cveClientlib.js index 0a050ff..4ee867c 100644 --- a/cveClientlib.js +++ b/cveClientlib.js @@ -22,6 +22,8 @@ class cveClient { let path = "/cve/" + cve + "/cna"; if(rejected) path = "/cve/" + cve + "/reject"; + if(!cnajson["x_generator"]) + cnajson["x_generator"] = {engine: "cveClientlib/" + this._version}; return this.putjson(path,opts,null,{cnaContainer:cnajson}); } reservecve(amount,cve_year,batch_type) { diff --git a/tests/api-client.test.js b/tests/api-client.test.js index ebc2037..f6990c5 100644 --- a/tests/api-client.test.js +++ b/tests/api-client.test.js @@ -75,9 +75,9 @@ describe("cveClient — CVE operations", () => { await client.publishcve("CVE-2024-1234", { description: "test" }); expect(lastFetchUrl).toBe("https://api.example.com/cve/CVE-2024-1234/cna"); expect(lastFetchOpts.method).toBe("POST"); - expect(JSON.parse(lastFetchOpts.body)).toEqual({ - cnaContainer: { description: "test" }, - }); + const body = JSON.parse(lastFetchOpts.body); + expect(body.cnaContainer.description).toBe("test"); + expect(body.cnaContainer.x_generator.engine).toMatch(/^cveClientlib\//); }); it("publishcve uses PUT for update", async () => { @@ -122,6 +122,38 @@ describe("cveClient — CVE operations", () => { }); }); +describe("cveClient — x_generator", () => { + let client; + + beforeEach(() => { + client = new CveClient( + "test-org", + "test-user", + "key", + "https://api.example.com", + ); + }); + + it("injects default x_generator with cveClientlib version when not set", async () => { + const cnajson = { descriptions: [{ lang: "en", value: "test" }] }; + await client.publishcve("CVE-2024-1234", cnajson, true); + expect(cnajson["x_generator"]).toEqual({ + engine: "cveClientlib/" + client._version, + }); + }); + + it("preserves caller-provided x_generator (UI path)", async () => { + const cnajson = { + descriptions: [{ lang: "en", value: "test" }], + x_generator: { engine: "cveClient/1.0.25" }, + }; + await client.publishcve("CVE-2024-1234", cnajson, true); + expect(cnajson["x_generator"]).toEqual({ + engine: "cveClient/1.0.25", + }); + }); +}); + describe("cveClient — ADP operations", () => { let client; From f19a78fec1a8240459d963feae6288ef5648b1f0 Mon Sep 17 00:00:00 2001 From: Jerry Gamblin Date: Thu, 2 Apr 2026 20:12:31 -0500 Subject: [PATCH 3/3] fix: sync cveClientlib version to 1.0.25 and use cveClient name everywhere All x_generator tags now report as "cveClient/" to match the existing entries in the CVE corpus. Synced cveClientlib._version from 1.0.15 to 1.0.25 so both UI and Node.js paths report the same project version. Co-Authored-By: Claude Opus 4.6 --- cveClientlib.js | 4 ++-- tests/api-client.test.js | 4 ++-- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/cveClientlib.js b/cveClientlib.js index 4ee867c..4fcca59 100644 --- a/cveClientlib.js +++ b/cveClientlib.js @@ -5,7 +5,7 @@ class cveClient { this.key = key; this.url = url; this.user_path = "/org/" + this.org + "/user/" + this.user; - this._version = "1.0.15"; + this._version = "1.0.25"; } /* PUT /cve/{id}/adp — the only ADP endpoint per CVE Services API spec See https://cveawg.mitre.org/api-docs/ */ @@ -23,7 +23,7 @@ class cveClient { if(rejected) path = "/cve/" + cve + "/reject"; if(!cnajson["x_generator"]) - cnajson["x_generator"] = {engine: "cveClientlib/" + this._version}; + cnajson["x_generator"] = {engine: "cveClient/" + this._version}; return this.putjson(path,opts,null,{cnaContainer:cnajson}); } reservecve(amount,cve_year,batch_type) { diff --git a/tests/api-client.test.js b/tests/api-client.test.js index f6990c5..e06ce9e 100644 --- a/tests/api-client.test.js +++ b/tests/api-client.test.js @@ -77,7 +77,7 @@ describe("cveClient — CVE operations", () => { expect(lastFetchOpts.method).toBe("POST"); const body = JSON.parse(lastFetchOpts.body); expect(body.cnaContainer.description).toBe("test"); - expect(body.cnaContainer.x_generator.engine).toMatch(/^cveClientlib\//); + expect(body.cnaContainer.x_generator.engine).toMatch(/^cveClient\//); }); it("publishcve uses PUT for update", async () => { @@ -138,7 +138,7 @@ describe("cveClient — x_generator", () => { const cnajson = { descriptions: [{ lang: "en", value: "test" }] }; await client.publishcve("CVE-2024-1234", cnajson, true); expect(cnajson["x_generator"]).toEqual({ - engine: "cveClientlib/" + client._version, + engine: "cveClient/" + client._version, }); });