PrintJS getting blocked a frame with origin issue - reactjs

Hi My Main Application url is http:localhost:4000. It internally render iframe app which is http:localhost:4000/contentApp/index.html (with sandbox parameter as sandbox="allow-scripts allow-popups allow-modals allow-forms allowdownloads allow-same-origin") and its in React application.
PrintJS package, using 1.0 version and it makes call to printJS(URL)
//URL, blob:http:localhost:4000/[guid value]
It gets an error at below piece of code within printjs library.
print.js:
try{
iframeElement.focus(); // iframeElement = iframe#printJS { src: blob:http://localhost:4000/a33334343-33434-343434-343434adf', src: '', name: '', sandbox: DOMTockenList(0..)
...
// other browsers
iframeElement.contentWindow.print(); // throw CORS error at here.
} catch(error){ params.onError(error);}
finally {
(o,_function.cleanup)(params);
}
}
above, iframeElement.contentWindow.print() getting an error out with below error CORS:
Uncaught DOMException: Blocked a frame with origin "http://localhost:4000" frame accessing a cross-origin frame.
at performPrint (webpack-internal:///./node_modules/print-js/dist/print.js:898:35)
at HTMLIframeElement.iframeElement.onload (webpack-internal:///./node_modules/print-js/dist/print.js:852:11)
..
When I remove sandbox then it worked. However, I can not remove sandbox as its structure of application.
Is there any way to fix this CORS issue. Like adding some parameter in "iframe sandbox attribute" OR any option at 'printjs' to fix this issue ?
Appreciate for the help.
PrintJS, internally call iframeElement.contentWindow.print(); , I don't have control to do postMessage as its printJS package part. Though, I have control over localhost:4000/contentApp , sandbox attribute.
(Also, it looks like issue created at, "http://localhost:4000" != "BLOB:http://localhost:4000/GUIDvalue" , (which looks weird as, both are pointing to same origin".)

Related

CORS error - Error: Cross origin http://localhost forbidden - in ReactJS/Jest test only

I'm running into a problem where the request I am making to an outside API is working fine in execution, but when runing a Jest/Enzyme test it gives me a CORS error. The function in question is using a JsonRpc implementation from an API, and using fetch from node-fetch. Not sure if there are settings for CORS I can apply somewhere?
I tried many variations of async waits in Jest/Enzyme testing framework but am still running into issues.
test("it should do something", done => {
const component = shallow(<CustomComponent />)
component.instance().customAsyncFunction( result => {
expect(result.length).toEqual(5)
done()
})
// return component.instance().customAsyncFunction().then(data => {
// expect(data.length).toEqual(5)
// })
})
I tried the above and a few other methods (like setTimeout and awaiting it) and get the CORS error.
The results I'm getting are:
console.error
node_modules/jest-environment-jsdom/node_modules/jsdom/lib/jsdom/virtual-console.js:29
Error: Cross origin http://localhost forbidden
at dispatchError (...\node_modules\jest-environment-jsdom\node_modules\jsdom\lib\jsdom\living\xhr-utils.js:65:19)
at Request.client.on.res (...\node_modules\jest-environment-jsdom\node_modules\jsdom\lib\jsdom\living\xmlhttprequest.js:679:38)
at Request.emit (events.js:198:13)
at Request.onRequestResponse (...\node_modules\request\request.js:1066:10)
at ClientRequest.emit (events.js:203:15)
at HTTPParser.parserOnIncomingClient [as onIncoming] (_http_client.js:556:21)
at HTTPParser.parserOnHeadersComplete (_http_common.js:109:17)
at TLSSocket.socketOnData (_http_client.js:442:20) undefined
Any ideas?
Jest allows you to set a setup script file. This file will be required before everything else and gives you a chance to modify the environment in which the tests will run. This way you can unset XMLHttpRequest before axios is loaded and the adapter type evaluated since imports are hoisted.
Link:https://facebook.github.io/jest/docs/configuration.html#setuptestframeworkscriptfile-string
In package.json
{
...,
"jest": {
...,
"setupTestFrameworkScriptFile": "./__tests__/setup.js",
...
},
...
}
__tests__/setup.js
global.XMLHttpRequest = undefined;
The error happens because the external API you call during the tests has a CORS restriction different than Jest's default jsdom one has (http://localhost).
To fix this for Jest v24 - v27 you have to set the appropriate testURL (see the docs) in your Jest config (e.g. jest.config.js):
{
// Other config values here ...
"testURL": "http://localhost:8080"
}
In testURL you have to put the actual URL allowed by CORS at your remote API side.
NB: since v28 the option is organized differentlty that requires different update in Jest config.
Assuming you actually want to call the real API during your tests rather than just mock it, you'll need to make sure the server sends an appropriate "access-control-allow-origin" header (obviously the exact mechanism for doing this depends on your server platform)
1) what you're probably looking for is to instead mock the promise or whatever function is being ran using jest.mock(), then assert that that mock was called (with the correct params)
Jest tests are unit tests that shouldn't really talk to your API
2) most likely something with your env vars while in test mode, process.env.NODE_ENV is set to "test" during jest which might be changing something or maybe one of your own custom config env vars
By settting a testURL option which is a valid URL you want in jest config will resovle this problem.
https://jestjs.io/docs/configuration#testurl-string

Failed To Load Template Issue

Using AngularJS-1.6.5 & Angular-ui-router-1.0.6 && Gulp-3.9.1
I'm having this absolutely annoying issue. I have an angular app that seems to build fine but when I run gulp-connect to run it, I keep getting failed to load template errors in this order:
vendor.js:14803 Error: [$compile:tpload] Failed to load template: app/auth/views/login.tpl.html (HTTP status: undefined undefined)
vendor.js:34081 Transition Rejection($id: 0 type: 6, message: The transition errored, detail: Error: [$compile:tpload] Failed to load template: app/auth/views/login.tpl.html (HTTP status: undefined undefined)
Error: [$compile:tpload] Failed to load template: app/auth/views/login.tpl.html (HTTP status: undefined undefined)
If I run my gulp build process and then use something like httpster to provide the server, the page comes up fine with no error. However, when I add gulp-connect to my build process:
gulp.task("connect",["css", "vendor", "js", "watch", "webWorkers"], function
() {
connect.server({
port: 8888
});
});
I get the errors above.
This was working just a day ago and for whatever reason, even previous versions that worked are no longer working either. I've tried redirecting to another template, verified that all entries are in template cache, tried retrieving a file that was on network instead of the template cache, uninstall/reinstalling gulp-connect and nothing has worked. I'm just completely stumped at this point and need to figure something out soon for the sake of my sanity.
Any thoughts would be greatly appreciated.
Goodness. After a bunch of trial and error, I finally figured out the issue. The issue was actually with an http interceptor that I was configuring with a token that was retrieved from local storage. The token retrieved from local storage was corrupt or invalid in some way (havent figured this issue out yet) and it was silently erroring out without bubbling the error up.
I wrapped the local storage read method in a try catch and now the templates are loading again.
Man I wasted so much time on this, hopefully this helps someone else out.
In my case, it it was a missed return config; statement when I add an interceptor to my app.
app.factory('loadingInterceptor', [
'$rootScope',
function ($rootScope)
{
return {
request: function (config)
{
var loadingEl = $(".loading-element");
if (loadingEl)
{
showLoading(loadingEl, true);
}
// return config;
},
response: function (response)
{
var loadingEl = $(".loading-element");
if (loadingEl) {
showLoading(loadingEl, false);
}
}
};
}
]);
hope this will help someone.
This also got me going for a while. In my case it was adding my view to the anonymousEndpoints config section.
anonymousEndpoints: ['clientapp/modules/login/login.view.html'],
adalProvider.init({
instance: 'https://*.microsoftonline.com/',
tenant: '*.onmicrosoft.com',
clientId: 'Some-long-guid',
anonymousEndpoints: ['clientapp/modules/login/login.view.html'],
extraQueryParameter: 'nux=1',
},$httpProvider);
Hope it helps someone down the road.

nosniff causing img src not to work

I have an Angular 1.5 client, published off of a Node 4,Express 4 server. I do 99% of my manual testing in IE Edge. (The rest is in Mocha, Karma, and before delivery, I hit Firefox.)
We recently added this line to our http server, using helmet:
//Prevent Mime type sniffing/infering
app.use(helmet.noSniff());
PROBLEM: The nosniff option broke all of my thumbnails.
In one of my other Angular modules, which is a controller and view component, I have this line:
...
<img ng-src="/api/thumbnail/{{title}}"/>
...
On my Node/Express server, my /api/thumbnail/:title/ route looks like this:
router.get('/api/thumbnail/:title/',function(req,res){
... get file to read from 'title'
fs.readFile(fileName,function(err,data){
if ( err ) { ... do error handling ... }
else { resp.send(data); }
});
})
Using IE's Network debugger, I noticed that the requests being sent to the server have 'application/octet stream' as the 'Content-Type'. Maybe because I am sending back an 'image/jpeg', so, I asked myself if that's what is causing the nosniff to kill the response?
In my server code, I have a "DEFAULT_THUMBNAIL" which I send back in the event that 'title' produced no viable thumbnail image for me. So, before I do a resp.send(data), I did this:
const mime = require('mime');
...
resp.setHeader('Content-type',mime.lookup(DEFAULT_THUMBNAIL));
And that seemed to fix the nosniff issue.

Google+'s Signin APis [AngularJS]: Refused to display 'X-Frame-Options' to 'SAMEORIGIN'

I've had a look to several similar problems on SO on this problems but I didn't find one which solves mine.
I'm following this tutorial to implement Google+'s Sign-in in my web application: https://blog.codecentric.de/en/2014/06/angularjs-google-sign-integration/
gapi is loaded correctly.
In my controller I have the following code:
gapi.signin.render('signInButton',
{
'callback': $scope.signInCallback, // Function handling the callback.
'clientid': '[MY_CLIENT_ID].apps.googleusercontent.com',
'requestvisibleactions': 'http://schemas.google.com/AddActivity',
'cookiepolicy': 'single_host_origin'
}
);
where
MY_CLIENT_ID is of course replaced by my actual client ID got from Google Dashboard.
I'm working on localhost:85 and "Javascript origin" is set exactly to http://localhost:85/
The error I'm getting is:
Refused to display ... in a frame because it set 'X-Frame-Options' to 'SAMEORIGIN'
NOTE: this error appears only sometimes. I don't understand why (the user interaction doesn't change, though).

AngularDart on Firefox fails with "receiver.webkitCreateShadowRoot is undefined"

I have an AngularDart application that is working fine on Chromium and Chrome with Javascript. But in Firefox and IE, I get the following error:
[14:36:14.648] "NullError: receiver.webkitCreateShadowRoot is undefined
STACKTRACE:
.Element.createShadowRoot$0#http://127.0.0.1:3030/foobarUI/web/foobarui.dart.js:84445
J.createShadowRoot$0$x#http://127.0.0.1:3030/foobarUI/web/foobarui.dart.js:153659
._ComponentFactory.call$6#http://127.0.0.1:3030/foobarUI/web/foobarui.dart.js:11337
.BlockFactory__instantiateDirectives__closure2.call$1#http://127.0.0.1:3030/foobarUI/web/foobarui.dart.js:11097
.Primitives_applyFunction#http://127.0.0.1:3030/foobarUI/web/foobarui.dart.js:5148
._FactoryProvider.get$2#http://127.0.0.1:3030/foobarUI/web/foobarui.dart.js:125034
J.get$2$x#http://127.0.0.1:3030/foobarUI/web/foobarui.dart.js:153716
.DynamicInjector__getInstanceBySymbol_closure.call$0#http://127.0.0.1:3030/foobarUI/web/foobarui.dart.js:124806
._defaultCreationStrategy#http://127.0.0.1:3030/foobarUI/web/foobarui.dart.js:125162
.Binding.creationStrategy$3#http://127.0.0.1:3030/foobarUI/web/foobarui.dart.js:125271
.DynamicInjector._getInstanceBySymbol$2#http://127.0.0.1:3030/foobarUI/web/foobarui.dart.js:124652
.DynamicInjector.get$1#http://127.0.0.1:3030/foobarUI/web/foobarui.dart.js:124694
J.get$1$x#http://127.0.0.1:3030/foobarUI/web/foobarui.dart.js:153713
.BlockFactory__instantiateDirectives_closure3.call$1#http://127.0.0.1:3030/foobarUI/web/foobarui.dart.js:11183
.IterableMixinWorkaround_forEach#http://127.0.0.1:3030/foobarUI/web/foobarui.dart.js:22126
.JSArray.forEach$1#http://127.0.0.1:3030/foobarUI/web/foobarui.dart.js:1995
J.forEach$1$ax#http://127.0.0.1:3030/foobarUI/web/foobarui.dart.js:153707
.BlockFactory._instantiateDirectives$5#http://127.0.0.1:3030/foobarUI/web/foobarui.dart.js:10887
.BlockFactory._dom$_link$4#http://127.0.0.1:3030/foobarUI/web/foobarui.dart.js:10816
.BlockFactory._dom$_link$4#http://127.0.0.1:3030/foobarUI/web/foobarui.dart.js:10818
.BlockFactory._dom$_link$4#http://127.0.0.1:3030/foobarUI/web/foobarui.dart.js:10818
.BlockFactory._dom$_link$4#http://127.0.0.1:3030/foobarUI/web/foobarui.dart.js:10818
.BlockFactory.call$2#http://127.0.0.1:3030/foobarUI/web/foobarui.dart.js:10776
.ngBootstrap_closure0.call$0#http://127.0.0.1:3030/foobarUI/web/foobarui.dart.js:7661
._rootRun#http://127.0.0.1:3030/foobarUI/web/foobarui.dart.js:27183
._ZoneDelegate.run$2#http://127.0.0.1:3030/foobarUI/web/foobarui.dart.js:34652
.NgZone__onRun_closure.call$0#http://127.0.0.1:3030/foobarUI/web/foobarui.dart.js:10306
.NgZone._onRunBase$4#http://127.0.0.1:3030/foobarUI/web/foobarui.dart.js:10162
.NgZone._onRun$4#http://127.0.0.1:3030/foobarUI/web/foobarui.dart.js:10181
$$.BoundClosure$4<.call$4#http://127.0.0.1:3030/foobarUI/web/foobarui.dart.js:424
._ZoneDelegate.run$2#http://127.0.0.1:3030/foobarUI/web/foobarui.dart.js:34652
._CustomizedZone.run$1#http://127.0.0.1:3030/foobarUI/web/foobarui.dart.js:35046
.ngBootstrap#http://127.0.0.1:3030/foobarUI/web/foobarui.dart.js:7485
.main#http://127.0.0.1:3030/foobarUI/web/foobarui.dart.js:130170
._IsolateContext.eval$1#http://127.0.0.1:3030/foobarUI/web/foobarui.dart.js:3635
.startRootIsolate#http://127.0.0.1:3030/foobarUI/web/foobarui.dart.js:3301
#http://127.0.0.1:3030/foobarUI/web/foobarui.dart.js:161315
#http://127.0.0.1:3030/foobarUI/web/foobarui.dart.js:161295
#http://127.0.0.1:3030/foobarUI/web/foobarui.dart.js:161309
#http://127.0.0.1:3030/foobarUI/web/foobarui.dart.js:9
"
Here is my foobarUI/pubspec.yaml:
name: foobarUI
description: A sample web application
dependencies:
angular: 0.9.3
browser: any
json_object: any
petitparser: any
unittest: any
foobar:
path: ../foobarLib
I tried to add the js, shadow_dom and web_ui modules but it made no difference.
I tried to add "useShadowDom = true;" (and false) to the main dart file, no difference.
From the error, it seems obvious that the webkit support for DOM shadow root is missing but why is this module not handling this ?
The same error occurs with angular.dart.tutorial chapter_03 sample. This is clearly an issue with Angular.Dart. Bug filed as: https://code.google.com/p/dart/issues/detail?id=15752
The Dart bug for issue is at: https://code.google.com/p/dart/issues/detail?id=15144
It has been fixed in Dart bug has not been pushed to AngularDart yet. That work is blocked by https://github.com/angular/angular.dart/issues/366.

Resources