VUE3 CSP issue at "new Function" - vuejs3

I am using vue 3.1.5 and vue cli 4.5.0 for special application like chrome extension and get the following error
"Refused to evaluate a string as JavaScript because 'unsafe-eval' is not an allowed source of script in the following Content Security Policy directive: "script-src chrome://resources 'self'".
in runtime-core.esm-bundler.js
function compileToFunction(source, options = {}) {
...
// compile
const { code } = baseCompile(source, options);
// evaluate function
const msg = new Function(return ${code})();
...
}
Is there any way to build vue3 application compatible to CSP?
I have tried these options
config.resolve.alias.set('vue$', 'vue/dist/vue.esm.js');
configureWebpack: { devtool: inline-source-map }
configureWebpack: { devtool: false }
Are there any other options or I have missed something?
Regards,
Pavel

Yes, Vue uses new Function for runtime compilation of templates.
If you do not wish to allow 'unsafe-eval' in the CSP, you have to pre-compile tempaltes into render functions.

Related

Storybook + Vue3 - Error when trying to use custom directives

When trying to use custom directives with Vue3 and storybook, I get this error:
I don't understand the issue and have no idea where to even start to look. I'm still very new to Vue and storybook.
I created a small test directive just to make sure it wasn't something to do with a more complicated one:
app.directive('red-bg', {
beforeMount: (element, binding) => {
element.style.backgroundColor = "red";
}
});
and applied it:
<div class="wmr-select relative" ref="selectRef" v-red-bg>
It works in the normal app part of the the project (as you can see with the red bg):
But in story book I get the error in the first image.
I haven't been able to find any kind of answer for this.
Hoping someone will swoop in and save me.
Thanks.
Since Storybook is using another file to initialize your app, you need to define the directive in both file.
This is explained in the configuring storybook section of the doc.
In my case, I had defined the directive in my main.js file, but I also had to define it in the preview.js file, of the .storybook folder.
As a reference, here is was my .storybook/preview.js looks like:
import { app } from "#storybook/vue3";
/* all the other import needed for my project **/
import store from "#/store";
/** ... */
export const parameters = {
/** Some parameters specifics to the plugins of storybook. **/
/** For example, when using themes. **/
};
/** App specific initialization, ex defining locale */
const i18n = createI18n({
locale: "en",
fallbackLocale: "en",
messages: myLocaleMessageLoader()
});
/** registering directives */
app.directive("my-custom-directive", myCustomDirectiveHandler);
app
.use(i18n)
.use(store)
/** all the other `.use` that my app need.*/
Please note the usage of storybook own app in the import.
After adding the directive in the .storybook/preview.js I was successfully able to use it in my stories.

Using GTM w/ Next.js can't get past CSP

I have custom CSP headers in next.config.js that are loaded into the head of the page in ./layouts.
const defaultCSP = {
"script-src": [
"'self'",
"'unsafe-eval'",
"'unsafe-inline'",
`'nonce-${nonce}'`,
"tagmanager.google.com/",
"googletagmanager.com",
],
"script-src-elem": [
"'self'",
`'nonce-${nonce}'`,
"tagmanager.google.com/",
"googletagmanager.com",
],
};
Trying to use react-gtm-module-nonce like so in _app.tsx
useEffect(() => {
TagManager.initialize({
gtmId: GTM_CONTAINER_ID,
auth: GTM_AUTH,
preview: GTM_PREVIEW,
nonce: NONCE,
});
}, []);
but when the app is loaded I see the following error
Refused to execute inline script because it violates the following Content Security Policy directive: "script-src-elem 'self' 'nonce-SOME_NONCE_VALUE' tagmanager.google.com/ googletagmanager.com Either the 'unsafe-inline' keyword, a hash ('sha256-r7NoIbKRzEIuATQ9EL7eN52m5xWoVwuBBTdGzzqnMbY='), or a nonce ('nonce-...') is required to enable inline execution.
It seems like I have the necessary items to run GTM but can't get past CSP. Any clues as to what's happening here? I've tried adding 'unsafe-inline' to script-src-elem but then it shows that it will be ignored if there's a nonce.

"Process is not defined"-error with Polymer and Redux

When I try to use Redux with Polymer (lit Element) I got this error:
"Process is not defined ad redux.js".
How to solve this error?
I found a hack solution from Polymer's PWA Starter kits.
Add this lines to your index.html:
<script>
// HACK(keanulee): The Redux package assumes `process` exists - mock it here before
// the module is loaded.
window.process = {
env: {
NODE_ENV: 'production'
}
};
</script>
Works like a charm.

"moment is undefined" when launching angular app in node-webkit

I want to launch my angular application which works in general, but when I get to use moment I got the error that "moment" is undefined.
I am using "angular-moment" from here
var app = angular.module("MyApp",
[
"ngRoute",
"ui.bootstrap",
"angularMoment",
'angular-jwt',
'angular-storage'
]);
My package.json looks like this
{
"name": "myapp",
"main": "index.html",
"toolbar":"true",
"dependencies": {
"moment": "*"
}
}
I am trying to use it with
app.config(function (moment) {
moment().format();
});
which says that moment ist undefined.
How do I have to modify my package.json to get node-webkit find moment? Or Angular-Moment?
Thanks in advance.
Make sure you have both moment and angular-moment loading in your HTML file.
Follow the instructions on the angular-moment github page. I don't think moment().format(); is valid because moment should not be a function..
Also try including "node-remote": "<local>" in your package.json file.
I encountered the same problem, I use this code snippet to solve it. You should replace vendor.js with your own files suce as angular, moment.
<script>
//hide global object
try {
window.globalTmp = global;
global = undefined;
} catch (e) {}
</script>
<script src="vendor.js"></script>
<script>
//recover global object
try {
global = window.globalTmp;
window.globalTmp = undefined;
} catch (e) {}
</script>
moment is undefined because it's added to global other than window. global is an object of node-webkit.If you type global in console, you will find global.moment in output.
I found this snippet in moment's source code which can support my explain.
var moment,
VERSION = '2.8.4',
// the global-scope this is NOT the global object in Node.js
globalScope = typeof global !== 'undefined' ? global : this,

Translating views with HotTowel (Durandal framework) + VS2012

I develop an ASP.NET MVC solution with Durandal and Breeze. I need to translate frontend to french and dutch. How to proceed with Durandal/knockout?
In a classic ASP.NET MVC solution we have the opportunity to have the views rendered server side (thanks to razor).
Thanks for your help.
To expand on Rob's answer of trying the i18n.js plugin for require.js, here's the steps I followed (I'm working off the Durandal starter template in Visual Studio).
Download the i18n.js plugin and put it in the App folder.
Create an App/nls folder, which is where you will put the require.js resource bundles, e.g. App/nls/welcomeBundle.js.
define({
"root": {
"displayName": "Welcome to the Durandal Starter Project!"
},
"fr-fr": true
});
You'll see I added a line to tell require.js that there's a French version available. This will be created in App/nls/fr-fr/welcomeBundle.js, which I kinda did below (changed the to le :D)
define({
"displayName": "Welcome to le Durandal Starter Project!"
});
require.js needs to be configured initially with the locale (can't be done dynamically). So in the main.js file, I declare the below getLocale() function, which I use to configure the locale for require.js:
function getLocale() {
var locale = 'en-us';
if (localStorage) {
var storedLocale = localStorage.getItem('locale');
locale = storedLocale || locale;
}
return locale;
}
requirejs.config({
paths: {
'text': 'durandal/amd/text'
},
locale: getLocale()
});
In the welcome.js module I then load the bundle and use it for the displayName property:
define(function(require) {
var bundle = require('i18n!nls/welcomeBundle');
return {
displayName: bundle.displayName,
...
}
});
I then set the locale to French and reload the page via JavaScript:
localStorage.setItem('locale', 'fr-fr');
location.reload();
Hope that helps :)
Edit: 2013-04-04: I updated the above to initialize the locale in the main.js file and not in the shell.js module, as for some reason the locale wasn't being used correctly when loading the bundle in the shell module. Figure that it should be configured as soon as possible anyway.

Resources