djipco / webmidi

Tame the Web MIDI API. Send and receive MIDI messages with ease. Control instruments with user-friendly functions (playNote, sendPitchBend, etc.). React to MIDI input with simple event listeners (noteon, pitchbend, controlchange, etc.).
Apache License 2.0
1.53k stars 115 forks source link

EvalError, 'unsafe-eval' when trying to move from webmidi 2.5 to 3.0 #277

Closed djipco closed 2 years ago

djipco commented 2 years ago

Discussed in https://github.com/djipco/webmidi/discussions/276

Originally posted by **robertmassman** June 30, 2022 webmidi.esm.min.js.87 Uncaught (in promise) EvalError: 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 'self'". (node:44479) UnhandledPromiseRejectionWarning: Error: ERR_FAILED (-2) loading 'file:///Users/.../.../.../index.html' at rejectAndCleanup (node:electron/js2c/browser_init:161:7647) at EventEmitter.stopLoadingListener (node:electron/js2c/browser_init:161:8022) at EventEmitter.emit (node:events:390:28) (Use `Electron --trace-warnings ...` to show where the warning was created) (node:44479) UnhandledPromiseRejectionWarning: Unhandled promise rejection. This error originated either by throwing inside of an async function without a catch block, or by rejecting a promise which was not handled with .catch(). To terminate the node process on unhandled promise rejection, use the CLI flag `--unhandled-rejections=strict` (see https://nodejs.org/api/cli.html#cli_unhandled_rejections_mode). (rejection id: 1) webmidi 2.5 works but when I moved to 3.0 the above message is coming up. Any thoughts on how to resolve the EvalError? ![Screen Shot 2022-06-30 at 6 04 22 AM](https://user-images.githubusercontent.com/12559691/176651801-6ac444af-206d-48ae-bd04-f7fb5f950e5a.png)
djipco commented 2 years ago

The error comes from this bit of code that detects whether the current environment is Node.js or not:

/**
 * Indicates whether the execution environment is Node.js (`true`) or not (`false`)
 * @type {boolean}
 */
static get isNode() {
  return new Function("try { return this === global; } catch(e) { return false; }")();
}

This code does not use eval() per se but something that is functionally equivalent. It seems that Electron does not like eval() at all. I tried adding usafe-eval to script-src in the Content-Security-Policy and it did solve the problem (but still threw a warning in the console):

<meta
  http-equiv="Content-Security-Policy"
  content="default-src 'self'; script-src 'self' 'unsafe-eval'; style-src 'self' 'unsafe-inline'"
>

This is the solution I can offer for now.

Obviously, we need a better solution than that. Oddly, it turns out to be difficult to properly detect the environment the code is running in. I guess I will have to find another way...

djipco commented 2 years ago

Release v3.0.21 fixes this problem. It is available now on NPM.