/** * Detects the current server's Content-Security-Policy to stop the setup if any directive doesn't meet the application's requirements * * @type {{_FindItopVersionInURI: (function(): string|string), aFlags: {bUnsafeInlineScriptOk: boolean, bUnsafeEvalScriptOk: boolean, bUnsafeInlineStyleOk: boolean}, _TestUnsafeEvalScript: SetupCSPDetection._TestUnsafeEvalScript, _HideContinueButtonIfPolicyNotOk: SetupCSPDetection._HideContinueButtonIfPolicyNotOk, _TestUnsafeInlineStyle: SetupCSPDetection._TestUnsafeInlineStyle, Run: SetupCSPDetection.Run, _TestUnSafeInlineScript: SetupCSPDetection._TestUnSafeInlineScript, _AddErrorAlert: SetupCSPDetection._AddErrorAlert}} * @since 2.7.11 3.0.5 3.1.2 3.2.0 N°7075 */ SetupCSPDetection = { aFlags: { bUnsafeInlineScriptOk: false, bUnsafeEvalScriptOk: false, bUnsafeInlineStyleOk: false, }, Run: function () { this._TestUnSafeInlineScript(); this._TestUnsafeEvalScript(); this._TestUnsafeInlineStyle(); this._HideContinueButtonIfPolicyNotOk(); }, /** * Test if the CSP "unsafe-inline" directive for script-src if enabled, otherwise it forbids the setup to go further * @private */ _TestUnSafeInlineScript: function() { var sBaitElemID = "csp-detection--unsafe-inline-script-bait"; // Add inline script that should add an element in the DOM var sAddedScript = ''; $("body").append(sAddedScript); // Check if element has been added to the DOM if ($("#" + sBaitElemID).length === 1) { this.aFlags.bUnsafeInlineScriptOk = true; } else { this._AddErrorAlert("unsafe-inline", "script"); } }, /** * Test if the CSP "unsafe-eval" directive for script-src if enabled, otherwise it forbids the setup to go further * @private */ _TestUnsafeEvalScript: function() { var sBaitElemID = "csp-detection--unsafe-eval-script-bait"; // Add inline eval script that should add an element in the DOM var sAddedScript = ''; $("body").append(sAddedScript); // Check if element has been added to the DOM if ($("#" + sBaitElemID).length === 1) { this.aFlags.bUnsafeEvalScriptOk = true; } else { this._AddErrorAlert("unsafe-eval", "script"); } }, /** * Test if the CSP "unsafe-inline" directive for style-src if enabled, otherwise it forbids the setup to go further * @private */ _TestUnsafeInlineStyle: function() { var sBaitElemID = "csp-detection--unsafe-inline-style-bait"; // Add inline eval script that should add an element in the DOM $("body").append("
If this is present in the DOM and visible, then unsafe-inline for styles policy must be allowed
"); $("body").append(""); // Check if style has been applied if ($("#" + sBaitElemID).is(":visible") === false) { this.aFlags.bUnsafeInlineStyleOk = true; } else { // Remove bait div to avoid polluting the screen $("#" + sBaitElemID).remove(); this._AddErrorAlert("unsafe-inline", "style"); } }, /** * Hide continue button to prevent setup from going further if any policy is not OK * @private */ _HideContinueButtonIfPolicyNotOk: function() { if (false === this.aFlags.bUnsafeInlineScriptOk || false === this.aFlags.bUnsafeEvalScriptOk || false === this.aFlags.bUnsafeInlineStyleOk) { // Hide next button to prevent user from going forward. // Note that we don't remove it completely to be able to by-pass it. $("#btn_next").addClass("ibo-is-hidden"); } }, /** * Internal helper to add an error alert in case of failure * @param {String} sPolicyOption e.g. "unsafe-inline", "unsafe-eval", ... * @param {String} sResourceType script|style * @private */ _AddErrorAlert: function(sPolicyOption, sResourceType) { var sFilesType = sResourceType === "script" ? "scripts" : "styles"; // Add alert in the DOM $("
Error:Your server Content-Security-Policy header doesn't allow " + sPolicyOption + " " + sFilesType + ". Therefore, the application cannot be installed (see documentation).
") .insertAfter( $("#wiz_form h1:first") ); }, /** * Internal helper to find the iTop version as wiki syntax from the script URI * @returns {string|string} * @private */ _FindItopVersionInURI: function() { // First find script tag for the current file var sScriptURI = $('script[src*="setup/csp-detection.js"]').attr("src"); // Extract parameter value from URI var regex = new RegExp('[\\?&]' + 'itop_version_wiki_syntax' + '=([^&#]*)'); var results = regex.exec(sScriptURI); return results === null ? '' : decodeURIComponent(results[1].replace(/\+/g, ' ')); } }; $(document).ready(function() { SetupCSPDetection.Run(); });