diff --git a/src/modify.js b/src/modify.js index 2d8ee9d..8d80df4 100644 --- a/src/modify.js +++ b/src/modify.js @@ -137,6 +137,11 @@ exports.modifyService = function ( ) { return modifyLock(env, (json) => { const map = getMapFromManifest(json); + const oldUrl = map[serviceName]; + if (oldUrl && json.integrity) { + delete json.integrity[oldUrl]; + } + if (remove) { delete map[serviceName]; delete map[serviceName + "/"]; diff --git a/test/integrity.test.js b/test/integrity.test.js new file mode 100644 index 0000000..60d1fa0 --- /dev/null +++ b/test/integrity.test.js @@ -0,0 +1,116 @@ +const request = require("supertest"); +const { app, setConfig } = require("../src/web-server"); +const { + resetManifest: resetMemoryManifest, +} = require("../src/io-methods/memory"); + +describe(`integrity`, () => { + beforeAll(() => { + setConfig({ + manifestFormat: "importmap", + packagesViaTrailingSlashes: true, + locations: { + prod: "memory://prod", + }, + }); + }); + + beforeEach(() => { + resetMemoryManifest(); + }); + + it(`sets integrity field in import map`, async () => { + const url = "/a.js"; + const integrity = "sha256-example"; + + const response = await request(app) + .patch("/services") + .query({ + skip_url_check: true, + }) + .set("accept", "json") + .send({ + service: "a", + url, + integrity, + }) + .expect(200) + .expect("Content-Type", /json/); + + expect(response.body.integrity).toMatchObject({ + [url]: integrity, + }); + }); + + it(`removes old integrity when patching a service`, async () => { + const url = "/a.js"; + const integrity = "sha256-a"; + + const response = await request(app) + .patch("/services") + .query({ + skip_url_check: true, + }) + .set("accept", "json") + .send({ + service: "a", + url, + integrity, + }) + .expect(200) + .expect("Content-Type", /json/); + + expect(response.body.integrity[url]).not.toBeUndefined(); + + const url2 = "/a2.js"; + const integrity2 = "sha256-a2"; + + const response2 = await request(app) + .patch("/services") + .query({ + skip_url_check: true, + }) + .set("accept", "json") + .send({ + service: "a", + url: url2, + integrity: integrity2, + }) + .expect(200) + .expect("Content-Type", /json/); + + expect(response2.body.integrity[url]).toBeUndefined(); + expect(response2.body.integrity[url2]).not.toBeUndefined(); + }); + + it(`deletes old integrity when deleting a service`, async () => { + const url = "/a.js"; + const integrity = "sha256-example"; + + const response = await request(app) + .patch("/services") + .query({ + skip_url_check: true, + }) + .set("accept", "json") + .send({ + service: "a", + url, + integrity, + }) + .expect(200) + .expect("Content-Type", /json/); + + expect(response.body.integrity).toMatchObject({ + [url]: integrity, + }); + + const response2 = await request(app) + .delete("/services/a") + .set("accept", "json") + .send() + .expect(200) + .expect("Content-Type", /json/); + expect(response2.body.integrity[url]).toBeUndefined(); + }); +});