Skip to content
This repository was archived by the owner on Feb 29, 2020. It is now read-only.

Fix Bug 1457233 - Allow AS router message content to include subset of HTML #4162

Merged
merged 7 commits into from
Jun 8, 2018

Conversation

piatra
Copy link
Contributor

@piatra piatra commented May 22, 2018

I've tried including fluent as external modules that resulted in some issues where the build step would complain about the syntax and fail. Alternatively using the compat version requires the regenerator-runtime and in order to build you would have to include this module before fluent, this would result in too many external modules.

Similar problems occur when bundling fluent with AS:

But it works if you get through all of that, although I haven't figured out how to render links yet.

The extra logic involved (LocalizationProvider) is only temporary until projectfluent/fluent.js#202 is fixed.

Copy link
Contributor

@k88hudson k88hudson left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The reason the spread syntax isn't working is that node_modules is excluded in the rule in webpack.config.js. If you change /node_modules/ to /node_modules\/(?!(fluent|fluent-react)\/).*/, it should work. That said, using externals will side-step this problem.

@@ -1,3 +1,4 @@
import "regenerator-runtime/runtime";
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Hm, I see the issue when I tried building this. The syntax that seems to be causing the issue isfor await (const x of iterable), which seems weird to me – we could try to figure this out, however I think the easiest way to deal with this is to use the external (i.e. manually copy node_modules/fluent/fluent.js and node_modules/fluent-react/fluent-react.js). Have you tried that?

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

After some more investigation async iterator support seemed to have landed in acorn 5.4.0 (see https://github.com/acornjs/acorn/releases/tag/5.4.0), so the same bug that is causing our object rest spread bug is also causing this :(

@@ -1,6 +1,8 @@
import {actionCreators as ac, ASRouterActions as ra} from "common/Actions.jsm";
import {OUTGOING_MESSAGE_NAME as AS_GENERAL_OUTGOING_MESSAGE_NAME} from "content-src/lib/init-store";
import {ImpressionsWrapper} from "./components/ImpressionsWrapper/ImpressionsWrapper";
import {LocalizationProvider} from "fluent-react";
import {MessageContext} from "fluent/compat";
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

if you're using fluent/compat you'll need to npm install fluent

@piatra
Copy link
Contributor Author

piatra commented May 25, 2018

I've only whitelisted <b> tags. If any other tag is found, it will be stripped, its text content will be used.

Right now anchors are rendered using ASRouterAnchor but snippets can contain links in arbitrary positions (not just at the end of the message). This requires some changes on the snippets side, anchors will be wrapped in <cta> tags and the URL will be provided separately in the payload like the endpoint demo we currently have.

grafik

Copy link
Contributor

@k88hudson k88hudson left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This works great! Can you maybe add a schema and/or some documentation to content-src/asrouter/schemas that defines the allowed tags?

function convertLinks(links) {
if (links) {
return Object.keys(links).reduce((acc, linkTag) => {
acc[linkTag] = <a href={links[linkTag].url} />;
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Can you whitelist allowed protocols here, so at least javascript: isn't allowed?

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

actually you can use safeURI here for that

@@ -24,6 +24,7 @@ module.exports = Object.assign({}, webpackConfig, {
"react-dom": "commonjs react-dom"
},
plugins: [
new webpack.BannerPlugin(banner)
new webpack.BannerPlugin(banner),
new webpack.DefinePlugin({document: {createElement: () => {}}})
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

looool hax :P Can you add a comment about why this is needed?

<LocalizationProvider messages={generateMessages(this.state.message.content.text)}>
<SimpleSnippet
{...this.state.message}
richText={<RichText text={this.state.message.content} />}
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I would do text={this.state.message.content.text} links={this.state.message.content.links} or just {...this.state.message.content}, passing message.content as text is kind of confusing

@@ -392,14 +392,14 @@
"dev": true
},
"asn1.js": {
"version": "4.9.2",
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

this seems like it might be a lot of changes for just adding a couple of dependencies, what version of npm are you using out of curiosity?

@@ -53,6 +55,45 @@ function shouldSendImpressionOnUpdate(nextProps, prevProps) {
return (nextProps.message.id && (!prevProps.message || prevProps.message.id !== nextProps.message.id));
}

function* generateMessages(content) {
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Any particular reason this is a generator and not an async function?

return null;
}

function RichText(props) {
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Can you add a small comment about what this is for

@piatra
Copy link
Contributor Author

piatra commented Jun 6, 2018

@piatra
Copy link
Contributor Author

piatra commented Jun 7, 2018

Not sure what to do about the package-lock.json diff.

npm --version
5.6.0

Copy link
Contributor

@k88hudson k88hudson left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Great work! I tested with this https://gist.github.com/k88hudson/2d627d17ebd3e622e5b05e060d98b182 and it's working great, plus my XSS attack was blocked 😜

@k88hudson k88hudson assigned piatra and unassigned k88hudson Jun 7, 2018
@piatra piatra merged commit 75050a9 into mozilla:master Jun 8, 2018
Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Labels
Projects
None yet
Development

Successfully merging this pull request may close these issues.

2 participants