Skip to content
New issue

Have a question about this project? # for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “#”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? # to your account

refactor: Remove liquid templates #353

Open
wants to merge 3 commits into
base: main
Choose a base branch
from

Conversation

abovedave
Copy link
Collaborator

I noticed when working on #352 that the Liquid decency is outdated and flagged in a security issue. This PR refactors the preview site templates to use a simpler approach as we're not using any of the features Liquid provides.

@giamir
Copy link
Contributor

giamir commented Oct 1, 2024

Thanks @abovedave for the PR. I am all up for simplifying but consider that we have recently introduced liquid templates for mocking Core's layout in new Free Refills services. I don't see our usage of liquid going away any time soon.

Perhaps there is another webpack loader we can use instead of removing the liquid templates all together?
Where can I read more about the vulnerabilities of that loader?

Thank you

@abovedave
Copy link
Collaborator Author

Ah I see! I could just swap out the new Function() with the actual Liquid package and skip the unmaintained loader if we really want it? It just seemed uncessary to use liquid just for a simple layout-view setup.

This was the error:

# npm audit report

liquidjs  <10.0.0
Severity: moderate
liquidjs may leak properties of a prototype - https://github.com/advisories/GHSA-45rm-2893-5f49
No fix available
node_modules/liquidjs
  liquidjs-loader  *
  Depends on vulnerable versions of liquidjs
  node_modules/liquidjs-loader

@giamir
Copy link
Contributor

giamir commented Oct 1, 2024

It just seemed uncessary to use liquid just for a simple layout-view set

@abovedave I would like to talk to Dan before removing Liquid all together from this repo. If the new Function() approach can buy us some time and fix the vulnerability I would prefer it. Thanks 🙏

Copy link

netlify bot commented Oct 1, 2024

Deploy Preview for stacks-editor ready!

Name Link
🔨 Latest commit 68c162c
🔍 Latest deploy log https://app.netlify.com/sites/stacks-editor/deploys/66fbe8db3a4930000889de51
😎 Deploy Preview https://deploy-preview-353--stacks-editor.netlify.app
📱 Preview on mobile
Toggle QR Code...

QR Code

Use your smartphone camera to open QR code link.

To edit notification comments on pull requests, go to your Netlify site configuration.

@b-kelly
Copy link
Collaborator

b-kelly commented Oct 3, 2024

I haven't reviewed this PR yet (expect a review later today), but I'm 100% ok with dropping liquid in this repo. The reason I introduced it was because I wanted a simple shared layout for the docs and liquid syntax was already used in Stacks's docs. The use of liquid in this repo is probably overkill, but it worked ok and stayed out of the way. If it is causing issues now, then let's ditch it.

Copy link
Collaborator

@b-kelly b-kelly left a comment

Choose a reason for hiding this comment

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

Other than the use of new Function, this change looks good to me. See my previous comment on OK'ing dropping liquid syntax entirely from this repo.

I'll pull this PR down today and find a good alternative to the new Function call.

@@ -3,6 +3,8 @@ const common = require("./webpack.common.js");
const HtmlWebpackPlugin = require("html-webpack-plugin");
const fs = require("fs");

const htmlLayout = fs.readFileSync("./site/layout.html");
Copy link
Collaborator

Choose a reason for hiding this comment

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

optional: Move this into the exported function (after line 8) so it only runs when invoked.

In this circumstance it changes basically nothing, but its generally good form to avoid side effects on import when possible.

@@ -67,7 +67,6 @@
"husky": "^9.0.11",
"jest": "^29.7.0",
"jest-environment-jsdom": "^29.7.0",
"liquidjs-loader": "^1.0.1",
Copy link
Collaborator

Choose a reason for hiding this comment

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

🎉

@@ -127,11 +127,7 @@
<label id="a11y-editor-label" class="v-visible-sr">
Stacks-Editor demo implementation
</label>
{% block content %}
Copy link
Collaborator

Choose a reason for hiding this comment

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

I'll miss having this default example for reference, but... not so much that I'd block this change from going in.

lgtm

);

return new HtmlWebpackPlugin({
templateContent: new Function(
Copy link
Collaborator

Choose a reason for hiding this comment

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

The use of new Function here is a large code smell to me. I'll pull down the PR here shortly and see if I can't whip up an alternative approach.

Copy link
Collaborator

@b-kelly b-kelly left a comment

Choose a reason for hiding this comment

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

I added a few comments with suggested changes. I'd push directly to the branch, but doing so to a fork is a pain in the rear. The change comments are prefixed with _loader-update_. The gist of the changes are as follows:

  1. readd html-loader, since it handles recompiling on file change for us (which templateContent does not, along with a host of other potentially useful utilities (such as preprocessing, see next point)
  2. add a preprocessor entry to wrap the files with our layout (inspired by the Templating section in the loader docs)

<textarea id="content" name="content" class="d-none"></textarea>
<div id="example-1"></div>
{% endblock %}
${content}
Copy link
Collaborator

Choose a reason for hiding this comment

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

loader-update: I changed this to use lodash templating syntax, which is what html-webpack-template uses by default. The syntax doesn't actually matter, but it'll at least be internally consistent if we decide to use any of the other supported templating features later.

Suggested change
${content}
<%=content%>

Comment on lines +40 to +53
...fs.readdirSync("./site/views").map((f) => {
const htmlView = fs.readFileSync(
`./site/views/${f}`,
"utf8"
);

return new HtmlWebpackPlugin({
templateContent: new Function(
["content"],
`return \`${htmlLayout}\`;`
)(htmlView),
filename: f,
});
}),
Copy link
Collaborator

Choose a reason for hiding this comment

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

loader-update: Revert this change

Suggested change
...fs.readdirSync("./site/views").map((f) => {
const htmlView = fs.readFileSync(
`./site/views/${f}`,
"utf8"
);
return new HtmlWebpackPlugin({
templateContent: new Function(
["content"],
`return \`${htmlLayout}\`;`
)(htmlView),
filename: f,
});
}),
...fs.readdirSync("./site/views").map(
(f) =>
new HtmlWebpackPlugin({
template: "./site/views/" + f,
filename: f,
})
),

@@ -17,22 +19,6 @@ module.exports = (env, argv) => {
},
mode: emulateProdServer ? "production" : "development",
devtool: emulateProdServer ? false : "inline-source-map",
module: {
Copy link
Collaborator

Choose a reason for hiding this comment

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

loader-update: Partially revert this change, modifying html-loader to do the work for us (GitHub doesn't allow suggestions on deleted lines, so you'll have to fix this manually)

            module: {
                rules: [
                    {
                        test: /\.html$/,
                        use: [
                            {
                                loader: "html-loader",
                                options: {
                                    // wrap the content of the html file in the layout.html file
                                    preprocessor: (content) =>
                                        htmlLayout.replace(
                                            "<%=content%>",
                                            content
                                        ),
                                },
                            },
                        ],
                    },
                ],
            },

@@ -3,6 +3,8 @@ const common = require("./webpack.common.js");
const HtmlWebpackPlugin = require("html-webpack-plugin");
const fs = require("fs");

const htmlLayout = fs.readFileSync("./site/layout.html");
Copy link
Collaborator

Choose a reason for hiding this comment

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

loader-update: Set the "utf-8" flag so the file is read as a string (instead of Buffer)

Suggested change
const htmlLayout = fs.readFileSync("./site/layout.html");
const htmlLayout = fs.readFileSync("./site/layout.html", "utf-8");

@giamir
Copy link
Contributor

giamir commented Oct 4, 2024

@b-kelly If we are going to keep a templating language of sort, I would prefer to stay consistent with what we use in Stacks docs. We have just started to use liquid also for some free refills mock layout stuff (see WIP). Perhaps it is just a matter of swapping the existing loader with one that does not have vulnerabilities. I haven't looked in details but maybe this one could be an option.

@b-kelly
Copy link
Collaborator

b-kelly commented Oct 4, 2024

@giamir I'm ok with adding back in a special loader or templating language, but I think it's overkill for our use case. 100% of the code that does the "templating" in this case is just a single line:

htmlLayout.replace("<%=content%>", content)

So... we really don't need a full blown templating solution for this. Imo, we can revisit in the future if we ever need a more full-featured solution.

# for free to join this conversation on GitHub. Already have an account? # to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

3 participants