"use strict";
/*
 * @adonisjs/shield
 *
 * (c) Harminder Virk <virk@adonisjs.com>
 *
 * For the full copyright and license information, please view the LICENSE
 * file that was distributed with this source code.
 */
var __importDefault = (this && this.__importDefault) || function (mod) {
    return (mod && mod.__esModule) ? mod : { "default": mod };
};
Object.defineProperty(exports, "__esModule", { value: true });
exports.cspFactory = void 0;
const helmet_csp_1 = __importDefault(require("helmet-csp"));
const noop_1 = require("./noop");
/**
 * Directives to inspect for the `@nonce` keyword
 */
const nonceDirectives = ['defaultSrc', 'scriptSrc', 'styleSrc'];
/**
 * Reads `nonce` from the ServerResponse and returns appropriate
 * string
 */
function nonceFn(_, response) {
    return `'nonce-${response['nonce']}'`;
}
/**
 * Transform `@nonce` keywords for a given directive
 */
function transformNonceKeywords(directive) {
    /**
     * Transform array values. There should be only one `@nonce` keyword
     */
    if (Array.isArray(directive)) {
        const nonceIndex = directive.indexOf('@nonce');
        if (nonceIndex > -1) {
            directive[nonceIndex] = nonceFn;
        }
    }
    return directive;
}
/**
 * Factory that returns a function to set the `Content-Security-Policy` header based upon
 * the user config
 */
function cspFactory(options) {
    if (!options.enabled) {
        return noop_1.noop;
    }
    if (options.directives) {
        /**
         * Transform directives that may contain the
         * "@nonce" directive.
         */
        nonceDirectives.forEach((directive) => {
            if (options.directives[directive]) {
                options.directives[directive] = transformNonceKeywords(options.directives[directive]);
            }
        });
    }
    const helmetCspMiddleware = (0, helmet_csp_1.default)(options);
    return function csp({ response, view }) {
        /**
         * Helmet csp needs the `nonce` property on the HTTP ServerResponse
         */
        response.response['nonce'] = response.nonce;
        view.share({ cspNonce: response.nonce });
        helmetCspMiddleware(response.request, response.response, () => { });
    };
}
exports.cspFactory = cspFactory;
