From 9498ee6bfeeec5b87eb86775dbb23f7ee4924030 Mon Sep 17 00:00:00 2001 From: Tilman Vatteroth Date: Thu, 17 Jun 2021 21:07:04 +0200 Subject: [PATCH 1/5] Remove cdn support Signed-off-by: Tilman Vatteroth --- app.js | 1 - docs/content/configuration.md | 1 - lib/config/default.js | 1 - lib/config/environment.js | 1 - lib/config/hackmdEnvironment.js | 1 - lib/config/oldDefault.js | 1 - lib/csp.js | 7 ----- public/views/hedgedoc/footer.ejs | 23 -------------- public/views/hedgedoc/head.ejs | 10 ------ public/views/index/footer.ejs | 11 ------- public/views/index/head.ejs | 10 ------ public/views/pretty.ejs | 28 ----------------- public/views/shared/polyfill.ejs | 7 ----- public/views/slide.ejs | 29 ------------------ test/csp.js | 16 ---------- webpack.common.js | 52 -------------------------------- 16 files changed, 199 deletions(-) delete mode 100644 public/views/shared/polyfill.ejs diff --git a/app.js b/app.js index 45e70c8b5..878c85729 100644 --- a/app.js +++ b/app.js @@ -191,7 +191,6 @@ app.engine('ejs', ejs.renderFile) // set view engine app.set('view engine', 'ejs') // set generally available variables for all views -app.locals.useCDN = config.useCDN app.locals.serverURL = config.serverURL app.locals.sourceURL = config.sourceURL app.locals.allowAnonymous = config.allowAnonymous diff --git a/docs/content/configuration.md b/docs/content/configuration.md index c6e3fc3eb..a19c749df 100644 --- a/docs/content/configuration.md +++ b/docs/content/configuration.md @@ -98,7 +98,6 @@ these are rarely used for various reasons. | config file | environment | **default** and example value | description | | --------------- | -------------------- | ----------------------------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------ | | `allowGravatar` | `CMD_ALLOW_GRAVATAR` | **`true`** or `false` | set to `false` to disable [Libravatar](https://www.libravatar.org/) as profile picture source on your instance. Libravatar is a federated open-source alternative to Gravatar. | -| `useCDN` | `CMD_USECDN` | **`false`** or `true` | set to use CDN resources or not (default is `false`) | ## Users and Privileges diff --git a/lib/config/default.js b/lib/config/default.js index c1f3f9733..f98adf37b 100644 --- a/lib/config/default.js +++ b/lib/config/default.js @@ -29,7 +29,6 @@ module.exports = { }, cookiePolicy: 'lax', protocolUseSSL: false, - useCDN: false, allowAnonymous: true, allowAnonymousEdits: false, allowFreeURL: false, diff --git a/lib/config/environment.js b/lib/config/environment.js index 1a43a88f9..e9b711ff0 100644 --- a/lib/config/environment.js +++ b/lib/config/environment.js @@ -27,7 +27,6 @@ module.exports = { cookiePolicy: process.env.CMD_COOKIE_POLICY, protocolUseSSL: toBooleanConfig(process.env.CMD_PROTOCOL_USESSL), allowOrigin: toArrayConfig(process.env.CMD_ALLOW_ORIGIN), - useCDN: toBooleanConfig(process.env.CMD_USECDN), allowAnonymous: toBooleanConfig(process.env.CMD_ALLOW_ANONYMOUS), allowAnonymousEdits: toBooleanConfig(process.env.CMD_ALLOW_ANONYMOUS_EDITS), allowFreeURL: toBooleanConfig(process.env.CMD_ALLOW_FREEURL), diff --git a/lib/config/hackmdEnvironment.js b/lib/config/hackmdEnvironment.js index 76e413612..c40ffc961 100644 --- a/lib/config/hackmdEnvironment.js +++ b/lib/config/hackmdEnvironment.js @@ -20,7 +20,6 @@ module.exports = { }, protocolUseSSL: toBooleanConfig(process.env.HMD_PROTOCOL_USESSL), allowOrigin: toArrayConfig(process.env.HMD_ALLOW_ORIGIN), - useCDN: toBooleanConfig(process.env.HMD_USECDN), allowAnonymous: toBooleanConfig(process.env.HMD_ALLOW_ANONYMOUS), allowAnonymousEdits: toBooleanConfig(process.env.HMD_ALLOW_ANONYMOUS_EDITS), allowFreeURL: toBooleanConfig(process.env.HMD_ALLOW_FREEURL), diff --git a/lib/config/oldDefault.js b/lib/config/oldDefault.js index 738ad9f7d..c9af50988 100644 --- a/lib/config/oldDefault.js +++ b/lib/config/oldDefault.js @@ -6,7 +6,6 @@ module.exports = { alloworigin: undefined, usessl: undefined, protocolusessl: undefined, - usecdn: undefined, allowanonymous: undefined, allowanonymousedits: undefined, allowfreeurl: undefined, diff --git a/lib/csp.js b/lib/csp.js index 74404413c..76426d526 100644 --- a/lib/csp.js +++ b/lib/csp.js @@ -15,12 +15,6 @@ const defaultDirectives = { connectSrc: ['*'] } -const cdnDirectives = { - scriptSrc: ['https://cdnjs.cloudflare.com', 'https://cdn.mathjax.org'], - styleSrc: ['https://cdnjs.cloudflare.com', 'https://fonts.googleapis.com'], - fontSrc: ['https://cdnjs.cloudflare.com', 'https://fonts.gstatic.com'] -} - const disqusDirectives = { scriptSrc: ['https://disqus.com', 'https://*.disqus.com', 'https://*.disquscdn.com'], styleSrc: ['https://*.disquscdn.com'], @@ -39,7 +33,6 @@ CspStrategy.computeDirectives = function () { const directives = {} mergeDirectives(directives, config.csp.directives) mergeDirectivesIf(config.csp.addDefaults, directives, defaultDirectives) - mergeDirectivesIf(config.useCDN, directives, cdnDirectives) mergeDirectivesIf(config.csp.addDisqus, directives, disqusDirectives) mergeDirectivesIf(config.csp.addGoogleAnalytics, directives, googleAnalyticsDirectives) mergeDirectivesIf(config.dropbox.appKey, directives, dropboxDirectives) diff --git a/public/views/hedgedoc/footer.ejs b/public/views/hedgedoc/footer.ejs index 86572091e..c3927db77 100644 --- a/public/views/hedgedoc/footer.ejs +++ b/public/views/hedgedoc/footer.ejs @@ -1,28 +1,5 @@ -<% if(useCDN) { %> - - - - - - - - - - - - - - - - - - - -<%- include('../build/index-scripts') %> -<% } else { %> <%- include('../build/index-pack-scripts') %> -<% } %> diff --git a/public/views/hedgedoc/head.ejs b/public/views/hedgedoc/head.ejs index 419d5dcc7..c2321fccf 100644 --- a/public/views/hedgedoc/head.ejs +++ b/public/views/hedgedoc/head.ejs @@ -15,15 +15,5 @@ <% } %> <%= title %> -<% if(useCDN) { %> - - - - - -<%- include('../build/index-header') %> -<%- include('../shared/polyfill') %> -<% } else { %> <%- include('../build/index-pack-header') %> -<% } %> diff --git a/public/views/index/footer.ejs b/public/views/index/footer.ejs index c9532f6d9..c6469cc0b 100644 --- a/public/views/index/footer.ejs +++ b/public/views/index/footer.ejs @@ -1,12 +1 @@ -<% if(useCDN) { %> - - - - - - - -<%- include('../build/cover-scripts') %> -<% } else { %> <%- include('../build/cover-pack-scripts') %> -<% } %> diff --git a/public/views/index/head.ejs b/public/views/index/head.ejs index a6e79e35c..a6751bbf4 100644 --- a/public/views/index/head.ejs +++ b/public/views/index/head.ejs @@ -16,14 +16,4 @@ HedgeDoc - <%= __('Collaborative markdown notes') %> -<% if(useCDN) { %> - - - - - -<%- include('../build/cover-header') %> -<%- include('../shared/polyfill') %> -<% } else { %> <%- include('../build/cover-pack-header') %> -<% } %> diff --git a/public/views/pretty.ejs b/public/views/pretty.ejs index fc222cb8c..97274ba15 100644 --- a/public/views/pretty.ejs +++ b/public/views/pretty.ejs @@ -25,17 +25,8 @@ <%= title %> <%- include('includes/favicon.ejs') %> - <% if(useCDN) { %> - - - - - <%- include('build/pretty-header') %> - <%- include('shared/polyfill') %> - <% } else { %> <%- include('build/pretty-pack-header') %> - <% } %> @@ -80,27 +71,8 @@ -<% if(useCDN) { %> - - - - - - - - - - - - - - - -<%- include('build/pretty-scripts') %> -<% } else { %> <%- include('build/pretty-pack-scripts') %> -<% } %> <%- include('shared/ga') %> diff --git a/public/views/shared/polyfill.ejs b/public/views/shared/polyfill.ejs deleted file mode 100644 index 82b2f0253..000000000 --- a/public/views/shared/polyfill.ejs +++ /dev/null @@ -1,7 +0,0 @@ - - - diff --git a/public/views/slide.ejs b/public/views/slide.ejs index e08ca0579..5837737ce 100644 --- a/public/views/slide.ejs +++ b/public/views/slide.ejs @@ -14,19 +14,9 @@ <%= title %> <%- include('includes/favicon.ejs') %> - - <% if(useCDN) { %> - - - - - <%- include('build/slide-header') %> - <%- include('shared/polyfill') %> - <% } else { %> <%- include('build/slide-pack-header') %> - <% } %> <% if(typeof theme !== 'undefined' && theme) { %> @@ -87,29 +77,10 @@ - <% if(useCDN) { %> - - - - - - - - - - - - - - - - <%- include('build/slide-scripts') %> - <% } else { %> <%- include('build/slide-pack-scripts') %> - <% } %> diff --git a/test/csp.js b/test/csp.js index 154120221..02184662c 100644 --- a/test/csp.js +++ b/test/csp.js @@ -27,7 +27,6 @@ describe('Content security policies', function () { upgradeInsecureRequests: 'auto', reportURI: undefined }, - useCDN: true, dropbox: { appKey: undefined } @@ -44,21 +43,6 @@ describe('Content security policies', function () { csp = mock.reRequire('../lib/csp') }) - // beginnging Tests - it('Disable CDN', function () { - const testconfig = defaultConfig - testconfig.useCDN = false - mock('../lib/config', testconfig) - csp = mock.reRequire('../lib/csp') - - assert(!csp.computeDirectives().scriptSrc.includes('https://cdnjs.cloudflare.com')) - assert(!csp.computeDirectives().scriptSrc.includes('https://cdn.mathjax.org')) - assert(!csp.computeDirectives().styleSrc.includes('https://cdnjs.cloudflare.com')) - assert(!csp.computeDirectives().styleSrc.includes('https://fonts.googleapis.com')) - assert(!csp.computeDirectives().fontSrc.includes('https://cdnjs.cloudflare.com')) - assert(!csp.computeDirectives().fontSrc.includes('https://fonts.gstatic.com')) - }) - it('Disable Google Analytics', function () { const testconfig = defaultConfig testconfig.csp.addGoogleAnalytics = false diff --git a/webpack.common.js b/webpack.common.js index 48b5bf147..70175c39e 100644 --- a/webpack.common.js +++ b/webpack.common.js @@ -22,13 +22,6 @@ module.exports = { 'moment': 'moment', CodeMirror: 'codemirror/lib/codemirror.js' }), - new HtmlWebpackPlugin({ - template: 'public/views/includes/header.ejs', - chunks: ['font', 'index-styles', 'index'], - filename: path.join(__dirname, 'public/views/build/index-header.ejs'), - inject: false, - chunksSortMode: 'manual' - }), new HtmlWebpackPlugin({ template: 'public/views/includes/header.ejs', chunks: ['font-pack', 'index-styles-pack', 'index-styles', 'index'], @@ -36,12 +29,6 @@ module.exports = { inject: false, chunksSortMode: 'manual' }), - new HtmlWebpackPlugin({ - template: 'public/views/includes/scripts.ejs', - chunks: ['index'], - filename: path.join(__dirname, 'public/views/build/index-scripts.ejs'), - inject: false - }), new HtmlWebpackPlugin({ template: 'public/views/includes/scripts.ejs', chunks: ['common', 'index-pack'], @@ -49,13 +36,6 @@ module.exports = { inject: false, chunksSortMode: 'manual' }), - new HtmlWebpackPlugin({ - template: 'public/views/includes/header.ejs', - chunks: ['font', 'cover'], - filename: path.join(__dirname, 'public/views/build/cover-header.ejs'), - inject: false, - chunksSortMode: 'manual' - }), new HtmlWebpackPlugin({ template: 'public/views/includes/header.ejs', chunks: ['font-pack', 'cover-styles-pack', 'cover'], @@ -63,12 +43,6 @@ module.exports = { inject: false, chunksSortMode: 'manual' }), - new HtmlWebpackPlugin({ - template: 'public/views/includes/scripts.ejs', - chunks: ['cover'], - filename: path.join(__dirname, 'public/views/build/cover-scripts.ejs'), - inject: false - }), new HtmlWebpackPlugin({ template: 'public/views/includes/scripts.ejs', chunks: ['common', 'cover-pack'], @@ -76,13 +50,6 @@ module.exports = { inject: false, chunksSortMode: 'manual' }), - new HtmlWebpackPlugin({ - template: 'public/views/includes/header.ejs', - chunks: ['font', 'pretty-styles', 'pretty'], - filename: path.join(__dirname, 'public/views/build/pretty-header.ejs'), - inject: false, - chunksSortMode: 'manual' - }), new HtmlWebpackPlugin({ template: 'public/views/includes/header.ejs', chunks: ['font-pack', 'pretty-styles-pack', 'pretty-styles', 'pretty'], @@ -90,12 +57,6 @@ module.exports = { inject: false, chunksSortMode: 'manual' }), - new HtmlWebpackPlugin({ - template: 'public/views/includes/scripts.ejs', - chunks: ['pretty'], - filename: path.join(__dirname, 'public/views/build/pretty-scripts.ejs'), - inject: false - }), new HtmlWebpackPlugin({ template: 'public/views/includes/scripts.ejs', chunks: ['common', 'pretty-pack'], @@ -103,13 +64,6 @@ module.exports = { inject: false, chunksSortMode: 'manual' }), - new HtmlWebpackPlugin({ - template: 'public/views/includes/header.ejs', - chunks: ['font', 'slide-styles', 'slide'], - filename: path.join(__dirname, 'public/views/build/slide-header.ejs'), - inject: false, - chunksSortMode: 'manual' - }), new HtmlWebpackPlugin({ template: 'public/views/includes/header.ejs', chunks: ['font-pack', 'slide-styles-pack', 'slide-styles', 'slide'], @@ -117,12 +71,6 @@ module.exports = { inject: false, chunksSortMode: 'manual' }), - new HtmlWebpackPlugin({ - template: 'public/views/includes/scripts.ejs', - chunks: ['slide'], - filename: path.join(__dirname, 'public/views/build/slide-scripts.ejs'), - inject: false - }), new HtmlWebpackPlugin({ template: 'public/views/includes/scripts.ejs', chunks: ['slide-pack'], From 3b0060187294e9d4b64892c735c9ca68d31f6804 Mon Sep 17 00:00:00 2001 From: David Mehren Date: Mon, 21 Jun 2021 20:14:29 +0200 Subject: [PATCH 2/5] Inline CSS & JS into HTML export template Previously, the HTML export template `html.hbs` included CDN links for the HTML and CSS resources. This commit enables Webpack to create a new `htmlexport.html` at build-time, which includes all resources inline. That template is then used as before by the frontend to be populated with the rendered note content. The tradeoff is that each exported .html file is about 5.6 MB in size, as we need to inline all fonts (icons & emojis). Signed-off-by: David Mehren --- public/js/extra.js | 25 ++++++++++------------- public/js/htmlExport.js | 21 ++++++++++++++++++- public/views/{html.hbs => htmlexport.ejs} | 21 ++----------------- webpack.htmlexport.js | 20 +++++++++++++++--- webpack.prod.js | 3 +++ 5 files changed, 53 insertions(+), 37 deletions(-) rename public/views/{html.hbs => htmlexport.ejs} (71%) diff --git a/public/js/extra.js b/public/js/extra.js index 6e3b0ed0e..c72007b6f 100644 --- a/public/js/extra.js +++ b/public/js/extra.js @@ -681,21 +681,18 @@ export function exportToHTML (view) { const tocAffix = $('#ui-toc-affix').clone() tocAffix.find('*').removeClass('active').find("a[href^='#'][smoothhashscroll]").removeAttr('smoothhashscroll') // generate html via template - $.get(`${serverurl}/build/html.min.css`, css => { - $.get(`${serverurl}/views/html.hbs`, template => { - let html = template.replace('{{{url}}}', serverurl) - html = html.replace('{{title}}', title) - html = html.replace('{{{css}}}', css) - html = html.replace('{{{html}}}', src[0].outerHTML) - html = html.replace('{{{ui-toc}}}', toc.html()) - html = html.replace('{{{ui-toc-affix}}}', tocAffix.html()) - html = html.replace('{{{lang}}}', (md && md.meta && md.meta.lang) ? `lang="${md.meta.lang}"` : '') - html = html.replace('{{{dir}}}', (md && md.meta && md.meta.dir) ? `dir="${md.meta.dir}"` : '') - const blob = new Blob([html], { - type: 'text/html;charset=utf-8' - }) - saveAs(blob, filename, true) + $.get(`${serverurl}/build/htmlexport.html`, template => { + let html = template.replace('{{{url}}}', serverurl) + html = html.replace('{{title}}', title) + html = html.replace('{{{html}}}', src[0].outerHTML) + html = html.replace('{{{ui-toc}}}', toc.html()) + html = html.replace('{{{ui-toc-affix}}}', tocAffix.html()) + html = html.replace('{{{lang}}}', (md && md.meta && md.meta.lang) ? `lang="${md.meta.lang}"` : '') + html = html.replace('{{{dir}}}', (md && md.meta && md.meta.dir) ? `dir="${md.meta.dir}"` : '') + const blob = new Blob([html], { + type: 'text/html;charset=utf-8' }) + saveAs(blob, filename, true) }) } diff --git a/public/js/htmlExport.js b/public/js/htmlExport.js index 1a873aca0..676e2b1bc 100644 --- a/public/js/htmlExport.js +++ b/public/js/htmlExport.js @@ -1,6 +1,25 @@ +require('bootstrap/dist/css/bootstrap.min.css') +require('fork-awesome/css/fork-awesome.min.css') +require('ionicons/css/ionicons.min.css') +require('prismjs/prism') +require('prismjs/themes/prism.css') +require('prismjs/components/prism-wiki') +require('prismjs/components/prism-haskell') +require('prismjs/components/prism-go') +require('prismjs/components/prism-typescript') +require('prismjs/components/prism-jsx') +require('prismjs/components/prism-makefile') +require('prismjs/components/prism-gherkin') +require('highlight.js/styles/github-gist.css') +require('emojify.js/dist/css/basic/emojify.min.css') require('../css/github-extract.css') require('../css/markdown.css') require('../css/extra.css') require('../css/slide-preview.css') -require('../css/google-font.css') +require('../css/font.css') require('../css/site.css') +const $ = require('jquery') +window.jQuery = $ +window.$ = $ +require('bootstrap') +require('gist-embed/gist-embed.min') diff --git a/public/views/html.hbs b/public/views/htmlexport.ejs similarity index 71% rename from public/views/html.hbs rename to public/views/htmlexport.ejs index 7e8268ba3..ee83d8505 100644 --- a/public/views/html.hbs +++ b/public/views/htmlexport.ejs @@ -19,22 +19,7 @@ - - - - - - - - - - + <% _.forEach(htmlWebpackPlugin.files.css, function(cssFile) { %><% }); %> @@ -52,9 +37,7 @@ - - - + <% _.forEach(htmlWebpackPlugin.files.js, function(jsFile) { %><% }); %>