Skip to content

Commit

Permalink
feat: apply cspNonce when client reordering (#1836)
Browse files Browse the repository at this point in the history
* feat: apply cspNonce when client reordering
  • Loading branch information
vwong committed Jul 30, 2022
1 parent 63161ab commit ec57ebd
Show file tree
Hide file tree
Showing 12 changed files with 212 additions and 7 deletions.
5 changes: 5 additions & 0 deletions .changeset/silver-apricots-tell.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
---
"marko": patch
---

Avoid inline styles when using tight Content Security Policy
34 changes: 27 additions & 7 deletions packages/marko/src/core-tags/core/await/reorderer-renderer.js
Original file line number Diff line number Diff line change
@@ -1,5 +1,8 @@
"use strict";

var escapeDoubleQuotes =
require("../../../runtime/html/helpers/escape-quotes").___escapeDoubleQuotes;

module.exports = function (input, out) {
// We cannot call beginSync() when using renderSync(). In this case we will
// ignore the await-reorderer tag.
Expand Down Expand Up @@ -54,13 +57,30 @@ module.exports = function (input, out) {
global._afRuntime = true;
}

asyncOut.write(
'<div id="af' +
awaitInfo.id +
'" style="display:none">' +
result.toString() +
"</div>"
);
if (global.cspNonce) {
asyncOut.write(
'<style nonce="' +
escapeDoubleQuotes(global.cspNonce) +
'">' +
"#af" +
awaitInfo.id +
"{display:none;}" +
"</style>" +
'<div id="af' +
awaitInfo.id +
'">' +
result.toString() +
"</div>"
);
} else {
asyncOut.write(
'<div id="af' +
awaitInfo.id +
'" style="display:none">' +
result.toString() +
"</div>"
);
}

asyncOut.script(
"$af(" +
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,24 @@
[
{
"event": "await:begin",
"arg": {
"name": "data.outer",
"clientReorder": false
}
},
{
"event": "await:beforeRender",
"arg": {
"name": "data.outer",
"clientReorder": false
}
},
{
"event": "await:finish",
"arg": {
"name": "data.outer",
"clientReorder": false,
"finished": true
}
}
]
Original file line number Diff line number Diff line change
@@ -0,0 +1,27 @@
[
{
"event": "await:begin",
"arg": {
"name": "input.outer",
"clientReorder": true,
"id": 0
}
},
{
"event": "await:beforeRender",
"arg": {
"name": "input.outer",
"clientReorder": true,
"id": 0
}
},
{
"event": "await:finish",
"arg": {
"name": "input.outer",
"clientReorder": true,
"id": 0,
"finished": true
}
}
]
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
<noscript id="afph0"></noscript><!--FLUSH--><style nonce="xyz">#af0{display:none;}</style><div id="af0"><div class="foo"><h1>Foo</h1> Hello World</div></div><script nonce="xyz">function $af(d,a,e,l,g,h,k,b,f,c){c=$af;if(a&&!c[a])(c[a+="$"]||(c[a]=[])).push(d);else{e=document;l=e.getElementById("af"+d);g=e.getElementById("afph"+d);h=e.createDocumentFragment();k=l.childNodes;b=0;for(f=k.length;b<f;b++)h.appendChild(k.item(0));g&&g.parentNode.replaceChild(h,g);c[d]=1;if(a=c[d+"$"])for(b=0,f=a.length;b<f;b++)c(a[b])}};$af(0)</script>
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
<await(data.outer) client-reorder>
<@then|outer|>
<div class="foo">
<h1>Foo</h1> Hello World
</div>
</@then>
</await>
<await-reorderer/>
Original file line number Diff line number Diff line change
@@ -0,0 +1,29 @@
var extend = require("raptor-util/extend");
var expect = require("chai").expect;
const { callbackProvider } = require("../../../__util__/async-helpers");

exports.templateData = {
outer: callbackProvider(1, {}),
$global: {
cspNonce: "xyz"
}
};

exports.checkEvents = function (events, snapshot, out) {
events = events.map(function (eventInfo) {
var arg = extend({}, eventInfo.arg);
expect(arg.out != null).to.equal(true);

delete arg.out; // Not serializable
delete arg.asyncValue; // Not serializable

return {
event: eventInfo.event,
arg: arg
};
});

snapshot(events, out.isVDOM ? "-events-vdom.json" : "-events.json");
};

exports.skip_vdom = "client-reorder/placeholders are not supported in vdom";
Original file line number Diff line number Diff line change
@@ -0,0 +1,24 @@
[
{
"event": "await:begin",
"arg": {
"name": "data.outer",
"clientReorder": false
}
},
{
"event": "await:beforeRender",
"arg": {
"name": "data.outer",
"clientReorder": false
}
},
{
"event": "await:finish",
"arg": {
"name": "data.outer",
"clientReorder": false,
"finished": true
}
}
]
Original file line number Diff line number Diff line change
@@ -0,0 +1,30 @@
[
{
"event": "await:begin",
"arg": {
"name": "input.outer",
"clientReorder": true,
"dataProvider": {},
"id": 0
}
},
{
"event": "await:beforeRender",
"arg": {
"name": "input.outer",
"clientReorder": true,
"dataProvider": {},
"id": 0
}
},
{
"event": "await:finish",
"arg": {
"name": "input.outer",
"clientReorder": true,
"dataProvider": {},
"id": 0,
"finished": true
}
}
]
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
<noscript id="afph0"></noscript><style nonce="xyz">#af0{display:none;}</style><div id="af0"><div class="foo"><h1>Foo</h1> Hello World</div></div><script nonce="xyz">function $af(d,a,e,l,g,h,k,b,f,c){c=$af;if(a&&!c[a])(c[a+="$"]||(c[a]=[])).push(d);else{e=document;l=e.getElementById("af"+d);g=e.getElementById("afph"+d);h=e.createDocumentFragment();k=l.childNodes;b=0;for(f=k.length;b<f;b++)h.appendChild(k.item(0));g&&g.parentNode.replaceChild(h,g);c[d]=1;if(a=c[d+"$"])for(b=0,f=a.length;b<f;b++)c(a[b])}};$af(0)</script>
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
<await(data.outer) client-reorder>
<@then|outer|>
<div class="foo">
<h1>Foo</h1> Hello World
</div>
</@then>
</await>
<await-reorderer/>
Original file line number Diff line number Diff line change
@@ -0,0 +1,28 @@
var extend = require("raptor-util/extend");
var expect = require("chai").expect;

exports.templateData = {
outer: Promise.resolve(),
$global: {
cspNonce: "xyz"
}
};

exports.checkEvents = function (events, snapshot, out) {
events = events.map(function (eventInfo) {
var arg = extend({}, eventInfo.arg);
expect(arg.out != null).to.equal(true);

delete arg.out; // Not serializable
delete arg.asyncValue; // Not serializable

return {
event: eventInfo.event,
arg: arg
};
});

snapshot(events, out.isVDOM ? "-events-vdom.json" : "-events.json");
};

exports.skip_vdom = "client-reorder/placeholders are not supported in vdom";

0 comments on commit ec57ebd

Please sign in to comment.