Skip to content

Commit 6855261

Browse files
add nonce
1 parent d7d760d commit 6855261

File tree

3 files changed

+64
-0
lines changed

3 files changed

+64
-0
lines changed

src/oc-client.js

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -38,6 +38,7 @@ export function createOc(oc) {
3838
let renderedComponents = oc.renderedComponents;
3939
let dataRenderedAttribute = "data-rendered";
4040
let dataRenderingAttribute = "data-rendering";
41+
let nonce = ocConf.nonce;
4142
let logError = (msg) => console.log(msg);
4243
let logInfo = (msg) => ocConf.debug && console.log(msg);
4344
let handleFetchResponse = (response) => {
@@ -124,6 +125,9 @@ export function createOc(oc) {
124125
for (let attribute of Array.from(script.attributes)) {
125126
newScript.setAttribute(attribute.name, attribute.value);
126127
}
128+
if (nonce) {
129+
newScript.setAttribute("nonce", nonce);
130+
}
127131
script.parentNode?.replaceChild(newScript, script);
128132
}
129133
};
@@ -140,6 +144,9 @@ export function createOc(oc) {
140144
oc.addStylesToHead = (styles) => {
141145
let style = $document.createElement("style");
142146
style.textContent = styles;
147+
if (nonce) {
148+
style.setAttribute("nonce", nonce);
149+
}
143150
$document.head.appendChild(style);
144151
};
145152

tests/addStylesToHead.spec.js

Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -18,4 +18,22 @@ test.describe("oc-client : addStylesToHead", () => {
1818
});
1919
expect(style).toEqual("body: {background: red;}");
2020
});
21+
22+
test("should set nonce on style tag when cspNonce is provided", async ({
23+
page,
24+
}) => {
25+
const result = await page.evaluate(() => {
26+
oc.conf.cspNonce = "test-style-nonce";
27+
oc.addStylesToHead("body { color: black; }");
28+
const styles = document.head.querySelectorAll("style");
29+
const last = styles[styles.length - 1];
30+
return {
31+
nonce: last.getAttribute("nonce"),
32+
content: last.textContent,
33+
};
34+
});
35+
36+
expect(result.nonce).toBe("test-style-nonce");
37+
expect(result.content).toBe("body { color: black; }");
38+
});
2139
});

tests/security.spec.js

Lines changed: 39 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -301,4 +301,43 @@ test.describe("oc-client : security and script handling", () => {
301301
}
302302
}
303303
});
304+
305+
test("should set nonce on re-animated script when cspNonce is provided", async ({
306+
page,
307+
}) => {
308+
const result = await page.evaluate(() => {
309+
return new Promise((resolve) => {
310+
oc.conf.cspNonce = "test-script-nonce";
311+
const component = document.createElement("oc-component");
312+
component.setAttribute("href", "//oc-registry.com/nonce-test/");
313+
document.body.appendChild(component);
314+
315+
// Stub renderByHref to return HTML with a script that records its nonce
316+
const originalRenderByHref = oc.renderByHref;
317+
oc.renderByHref = (opts, cb) => {
318+
cb(null, {
319+
html: '<div>Content<script>window.nonceFromCurrentScript = document.currentScript && document.currentScript.getAttribute("nonce");</script></div>',
320+
version: "1.0.0",
321+
name: "nonce-test",
322+
key: "nonce-key",
323+
});
324+
};
325+
326+
oc.renderNestedComponent(component, () => {
327+
const script = component.querySelector("script");
328+
const data = {
329+
attrNonce: script?.getAttribute("nonce"),
330+
currentScriptNonce: window.nonceFromCurrentScript,
331+
};
332+
// cleanup
333+
oc.renderByHref = originalRenderByHref;
334+
component.remove();
335+
resolve(data);
336+
});
337+
});
338+
});
339+
340+
expect(result.attrNonce).toBe("test-script-nonce");
341+
expect(result.currentScriptNonce).toBe("test-script-nonce");
342+
});
304343
});

0 commit comments

Comments
 (0)