<commit_before>var http = require('http');
var https = require('https');
var path = require('path');
var express = require('express');
var helmet = require('helmet');
var bodyParser = require('body-parser')

var config = require('./config.server.js');

var buildDir = 'dist';

var app = express();

// var whitelistedCSPDomains = [
//   'https://app.tidepool.org',
//   'https://dev-app.tidepool.org',
//   'https://stg-app.tidepool.org',
//   'https://int-app.tidepool.org',
// ];

// if (process.env.CSP_DEBUG_HOST) {
//   whitelistedCSPDomains.push(process.env.CSP_DEBUG_HOST);
// }

var uuidv4 = require('uuid/v4')

app.use(function (req, res, next) {
  res.locals.nonce = uuidv4()
  next()
})

app.use(helmet());
app.use(helmet.contentSecurityPolicy({
  directives: {
    defaultSrc: ["'none'"],
    baseUri: ["'none'"],
    // scriptSrc: whitelistedCSPDomains,
    scriptSrc: [
      function (req, res) {
        return "'nonce-" + res.locals.nonce + "'"  // 'nonce-614d9122-d5b0-4760-aecf-3a5d17cf0ac9'
      }
    ],
    styleSrc: ["'self'", "'unsafe-inline'"],
    imgSrc: ["'self'", 'data:'],
    fontSrc: ["'self'", 'data:'],
    // styleSrc: whitelistedCSPDomains.concat(["'unsafe-inline'"]),
    // imgSrc: whitelistedCSPDomains.concat(['data:']),
    // fontSrc: whitelistedCSPDomains.concat(['data:']),
    reportUri: '/event/csp-report/violation',
    objectSrc: ['blob:'],
    workerSrc: ['blob:'],
    connectSrc: [].concat([
      process.env.API_HOST,
      'https://api.github.com/repos/tidepool-org/chrome-uploader/releases',
    ]),
  },
  reportOnly: false,
}));

app.use(bodyParser.json({
  type: ['json', 'application/csp-report']
}))

var staticDir = path.join(__dirname, buildDir);
app.use(express.static(staticDir));


//So that we can use react-router and browser history
app.get('*', function (request, response){
  response.sendFile(staticDir + '/index.html');
});

app.post('/event/csp-report/violation', function (req, res) {
  if (req.body) {
    console.log('CSP Violation: ', req.body);
  } else {
    console.log('CSP Violation: No data received!');
  }
  res.status(204).end()
})

// If no ports specified, just start on default HTTP port
if (!(config.httpPort || config.httpsPort)) {
  config.httpPort = 3000;
}

if (config.httpPort) {
  app.server = http.createServer(app).listen(config.httpPort, function() {
    console.log('Connect server started on port', config.httpPort);
    console.log('Serving static directory "' + staticDir + '/"');
  });
}

if (config.httpsPort) {
  https.createServer(config.httpsConfig, app).listen(config.httpsPort, function() {
    console.log('Connect server started on HTTPS port', config.httpsPort);<commit_msg>Set csp script-src to use nonces<commit_after>var http = require('http');
var https = require('https');
var fs = require('fs');
var path = require('path');
var express = require('express');
var helmet = require('helmet');
var bodyParser = require('body-parser');
var crypto = require('crypto');

var config = require('./config.server.js');

var buildDir = 'dist';

var app = express();

var nonceMiddleware = function (req, res, next) {
  // Cache static html file to avoid reading it from the filesystem on each request
  if (!global.html) {
    console.log('Caching static HTML');
    global.html = fs.readFileSync(staticDir + '/index.html', 'utf8');
  }

  // Set a unique nonce for each request
  res.locals.nonce = crypto.randomBytes(16).toString('base64');
  res.locals.htmlWithNonces = global.html.replace(/<(script)/g, '<$1 nonce="' + res.locals.nonce + '"');
  next();
}

app.use(helmet());
app.use(nonceMiddleware, helmet.contentSecurityPolicy({
  directives: {
    defaultSrc: ["'none'"],
    baseUri: ["'none'"],
    scriptSrc: [
      "'self'",
      "'strict-dynamic'",
      function (req, res) {
        return "'nonce-" + res.locals.nonce + "'";
      },
    ],
    styleSrc: ["'self'", "'unsafe-inline'"],
    imgSrc: ["'self'", 'data:'],
    fontSrc: ["'self'", 'data:'],
    reportUri: '/event/csp-report/violation',
    objectSrc: ['blob:'],
    workerSrc: ["'self'", 'blob:'],
    connectSrc: [].concat([
      process.env.API_HOST,
      'https://api.github.com/repos/tidepool-org/chrome-uploader/releases',
    ]),
  },
  reportOnly: false,
}));

app.use(bodyParser.json({
  type: ['json', 'application/csp-report']
}))

var staticDir = path.join(__dirname, buildDir);
app.use(express.static(staticDir));

//So that we can use react-router and browser history
app.get('*', function (req, res){
  res.send(res.locals.htmlWithNonces);
});

app.post('/event/csp-report/violation', function (req, res) {
  if (req.body) {
    console.log('CSP Violation: ', req.body);
  } else {
    console.log('CSP Violation: No data received!');
  }
  res.status(204).end();
})

// If no ports specified, just start on default HTTP port
if (!(config.httpPort || config.httpsPort)) {
  config.httpPort = 3000;
}

if (config.httpPort) {
  app.server = http.createServer(app).listen(config.httpPort, function() {
    console.log('Connect server started on port', config.httpPort);
    console.log('Serving static directory "' + staticDir + '/"');
  });
}

if (config.httpsPort) {
  https.createServer(config.httpsConfig, app).listen(config.httpsPort, function() {
    console.log('Connect server started on HTTPS port', config.httpsPort);
{'fraction_non_alphanumeric': 0.19099437148217635, 'fraction_numerical': 0.007879924953095686, 'mean_word_length': 3.8908256880733947, 'pattern_counts': {'":': 0, '<': 5, '<?xml version=': 0, '>': 3, 'https://': 6, 'lorem ipsum': 0, 'www.': 0, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 0, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '3331066', 'n_tokens_mistral': 1843, 'n_tokens_neox': 1815, 'n_words': 373}