/**
 * Проставляем заголовок для CSP
 */

const crypto = require('crypto');
const _ = require('lodash');
const frameAncestors = require('../config/csp_frame_ancestors');

const genNonce = () => crypto.randomBytes(16).toString('base64');

module.exports = function(req, res, next) {
    const config = req.config;

    // не добавляем заголовки для не html запросов
    if (req.accepts(['html']) !== 'html') {
        next();

        return;
    }

    const csp = _.clone(config.csp.rules);

    if (config.csp.extra) {
        Object.keys(config.csp.extra).forEach(key => {
            csp[key] = csp[key] ? `${csp[key]} ${config.csp.extra[key]}` : config.csp.extra[key];
        });
    }

    const nonce = config.app.isDev ? config.app.devNonce : genNonce();

    req.nonce = nonce;
    req.context.nonce = nonce;

    csp['style-src'] += ` 'nonce-${nonce}'`;
    csp['script-src'] += ` 'nonce-${nonce}'`;

    if (csp['frame-ancestors']) {
        req.config.frameAncestors = csp['frame-ancestors'].split(' ');
    } else {
        csp['frame-ancestors'] = frameAncestors.join(' ');
        req.config.frameAncestors = frameAncestors;
    }

    const reportQueryOptions = {
        from: 'portal',
        version: config.app.version,
        yandex_login: decodeURIComponent(_.get(req, 'cookies.yandex_login', '')),
        yandexuid: _.get(req, 'cookies.yandexuid', ''),
    };

    const reportQuery = Object.keys(reportQueryOptions)
        .map(key => `${key}=${encodeURIComponent(reportQueryOptions[key])}`)
        .join('&');

    csp['report-uri'] = `${config.csp.report}?${reportQuery}`;

    const headerValue = Object.keys(csp)
        .map(key => `${key} ${csp[key]}`)
        .join('; ');

    res.setHeader('Content-Security-Policy', headerValue);
    next();
};
