Skip to content

Commit

Permalink
Added script to copy CSP from index.html meta to netlify _headers file
Browse files Browse the repository at this point in the history
  • Loading branch information
dsebastien committed Mar 3, 2019
1 parent 9c8ab62 commit c31120c
Show file tree
Hide file tree
Showing 3 changed files with 81 additions and 1 deletion.
75 changes: 75 additions & 0 deletions csp-util.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,75 @@
#!/usr/bin/env node

This comment has been minimized.

Copy link
@janpauldahlke

janpauldahlke Oct 5, 2020

possible Gatsby CSP Solution?

This comment has been minimized.

Copy link
@dsebastien

dsebastien Oct 8, 2020

Author Contributor

Well it does help but does not solve all the CSP issues of Gatsby, unfortunately ;-)

This comment has been minimized.

Copy link
@janpauldahlke

janpauldahlke Nov 2, 2020

Sorry, man it was more a comment for myself to find this again at work.
And this issue is really annoying, since iam hosting on bitbucket. Cheers mate


const fs = require('fs');
const path = require('path');
const htmlparser = require('htmlparser2');
const replaceInFile = require('replace-in-file');

const TARGET_FOLDER = path.join(__dirname, 'public');

const INPUT_FILE = path.join(TARGET_FOLDER, 'index.html');
const OUTPUT_FILE = path.join(TARGET_FOLDER, '_headers');
const TOKEN_TO_REPLACE = '__REPLACE_ME__';

console.log('Copying the CSP for Netlify headers');

const cspContent = getCspContentFrom(INPUT_FILE);

updateNetlifyHeaderFile(cspContent, OUTPUT_FILE);


function getCspContentFrom(inputFile) {
console.log(`Getting the CSP content from ${inputFile}`);
try {
const fileContents = fs.readFileSync(inputFile, {encoding: 'utf-8'});

let found = false;
let retVal = '';

const parser = new htmlparser.Parser({
onopentag: (name, attributes) => {
if (name === "meta") {
if (attributes['http-equiv'] && 'Content-Security-Policy' === attributes['http-equiv']) {
console.log('Found the CSP content:', attributes['content']);
found = true;
retVal = attributes['content'];
}
}
}
}, {decodeEntities: true});

parser.write(fileContents);

if (found === false) {
throw new Error(`Could not find the CSP`);
}

return retVal;

} catch (err) {
console.error('Could not retrieve the CSP content. Did you build first? Is the gatsby-config.js still correct?');
throw err;
}
}

function updateNetlifyHeaderFile(cspText, outputFile) {
console.log(`Updating the CSP in the output file [${outputFile}]`);
const replacementOptions = {
files: outputFile,
from: new RegExp(TOKEN_TO_REPLACE, 'g'),
to: cspText,
};

try {
console.log(`Modifying Netlify's header file`);
const changes = replaceInFile.sync(replacementOptions);
if (changes && changes.length && changes.length > 0) {
console.log(`Modified Netlify's headers file successfully`, changes.join(', '));
} else {
throw new Error(`Failed to find the expected token to replace: ${TOKEN_TO_REPLACE}`);
}
} catch (error) {
console.error(`Failed to modify Netlify's header file`);
throw error;
}
}
3 changes: 3 additions & 0 deletions gatsby-config.js
Original file line number Diff line number Diff line change
Expand Up @@ -155,6 +155,9 @@ module.exports = {
options: {
headers: {
"/*": [
// The CSP is generated by gatsby-plugin-csp and added to the _headers file in public/ before publish.
// That is handled by the build:prod script which executes csp-util.js, which looks for the token below.
"Content-Security-Policy: __REPLACE_ME__",
"Access-Control-Allow-Origin: null",
//"Clear-Site-Data: *" // useful for logout pages: https://developer.mozilla.org/en-US/docs/Web/HTTP/Headers/Clear-Site-Data

Expand Down
4 changes: 3 additions & 1 deletion package.json
Original file line number Diff line number Diff line change
Expand Up @@ -42,10 +42,12 @@
"gatsby-plugin-ts-loader": "0.1.0",
"gatsby-source-filesystem": "2.0.23",
"gatsby-transformer-sharp": "2.1.15",
"htmlparser2": "3.10.1",
"husky": "1.3.1",
"lint-staged": "8.1.5",
"node-sass": "4.11.0",
"prettier": "1.16.4",
"replace-in-file": "3.4.3",
"stylelint": "9.10.1",
"stylelint-config-prettier": "5.0.0",
"stylelint-webpack-plugin": "0.10.5",
Expand All @@ -58,7 +60,7 @@
"scripts": {
"build": "npm run build:dev",
"build:dev": "gatsby develop",
"build:prod": "gatsby build --prefix-paths",
"build:prod": "gatsby build --prefix-paths && node ./csp-util.js",
"check-deps": "npx npm-check",
"clean": "npm run rimraf -- node_modules .tmp .cache public dist",
"clean:install": "yarn install",
Expand Down

0 comments on commit c31120c

Please sign in to comment.