PrintJs - Cors issue on android chrome browser - printjs

Trying to load an external pdf url for print using PrintJS,
getting SecurityError: Blocked a frame with origin "URL" from accessing a cross-origin frame.
Same application is working fine in Chrome browser on windows.

Same issue from me, code is working fine on Safari (MacBook) but fails on Chrome (Android).
const handlePrintLabel = () => {
setValue('isFull', true);
trigger().then((result) => {
if (result) {
axiosInstance.current.post(`/api/.../request...`, {
headers: {
'Content-Type': 'application/json',
'Accept': 'application/text'
}
}).then((response) => {
printJS({printable: response.data, type: 'pdf', base64: true})
}).catch((error) => {
if (error instanceof AxiosError) {
throw Error(`Nieznany błąd: ${error.message}`)
} else {
throw error
}
})
}
}).finally(() => setValue('isFull', false))
}
Error:
init.js:26 Uncaught DOMException: Blocked a frame with origin "https://XXX.team" from accessing a cross-origin frame.
at performPrint (https://XXX.unibe.team/static/js/18.chunk.js:1324:43)
at iframeElement.onload (https://XXX.team/static/js/18.chunk.js:1278:19)

Related

The first API call after login is unauthorized until page reload (Laravel Sanctum & VueJS)

I am trying to resolve this 401 issue for some time. After logging in and obtaining the token I am setting it as a header, but keep getting 401 exception on first load of the page. The error goes away after refresh. It seems that the token is not written to store or localStorage the first time around. Here's my code for login (I set the token to state.token in the mutation):
retrieveToken(context, credentials) {
return new Promise((resolve, reject) => {
axios.post('api/login', {
email: credentials.email,
password: credentials.password,
})
.then(response => {
const token = response.data.access_token
localStorage.setItem('access_token', token)
context.commit('RETRIEVE_TOKEN', token)
resolve(response)
console.log(response.data)
})
.catch(error => {
console.log(error)
reject(error)
})
})
},
And that's how I set it to header (setting it from localStorage doesn't solve the issue):
const authorizedApiClient = axios.create({
baseURL: process.env.VUE_APP_PRODUCTION_URL,
headers: {
Accept: 'application/json',
'Authorization': `Bearer ${store.getters.token}`
}
})
This behavior baffles me. Is there any theory or suggestions on how to debug?
I guess when the axios client is created the token is not yet retrieved from api. Try setting the header before each request using an interceptor:
const authorizedApiClient = axios.create({
baseURL: process.env.VUE_APP_PRODUCTION_URL,
headers: {
Accept: 'application/json'
}
})
authorizedApiClient.interceptors.request.use((config) => {
if (store.getters.token){ // or get it from localStorage
config.headers["Authorization"] = "Bearer " + store.getters.token
}
return config
})

Bearer Authorization is not working on android, but it does fine in iOS

After trying to use the app on an android device and simulator, the result is the same, I'm getting a 401 (unauthenticated). The problem seems to be weird, as the homescreen does fetch the objects properly, but on another view, same thing, 401 (only on android).
The axios call I'm doing is the following:
async getSubject(){
const token = await AsyncStorage.getItem('access');
const access = 'Bearer ' + token;
axios.get(`http://example.com/api/auth/subject/${this.props.navigation.getParam('id')}`, {
headers: {
'Authorization': access,
}
})
.then(res => {
this.setState({ subject: res.data.subject })
this.setState({ loading: false });
this.setState({ refreshing: false })
})
}
My backend is laravel, I'm using passport. But still, not sure why it only works fine on iOS and not in android.
Why is this happening?

react-native-image-picker upload image fetch network error

I use react-native-image-picker to upload image to a server. I use the following code:
sendPhoto = async () =>{
const fileToUpload = {
type:'image/jpg',
uri: 'file://'+this.state.photo.path,
name:'uploadimage.jpg'
}
console.log(fileToUpload);
let data = new FormData();
data.append('file_attachment', { type:'image/jpg', uri: this.state.photo.path, name:'uploadimage.jpg'})
fetch (settings.ajaxurl+'sickFishUpload',{
method: 'POST',
body: data,
headers: {
'Content-Type': 'multipart/form-data; ',
},
})
.then( (response) => response.json())
.then((res) => {
console.log(res);
//console.log(res);
})
.catch(function(error) {
console.log('There has been a problem with your fetch operation: ' + error.message);
// ADD THIS THROW error
throw error;
})
}
Unfortunatelly It cannot communicate with the server. I got this message: There has been a problem with your fetch operation: TypeError: Network request failed.
If I erase this json from the data:
{ type:'image/jpg', uri: this.state.photo.path, name:'uploadimage.jpg'}
it can communicate with the server.
I set the AndroidManifest.xml with
<uses-permission android:name="android.permission.CAMERA"/>
<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE"/>
<uses-permission android:name="android.permission.READ_EXTERNAL_STORAGE" />
and the application tag with
android:requestLegacyExternalStorage="true"
I'm totally stucked. Do you have any idea what is wrong? Of course I 've found this question in a previous post, but It is more than a years old and my solution is worked with the previous version of react-native. So I don't know how to upgrade my code...
Every suggestion is very welcome.
thx
Adam

Angular2 post request despite a XMLHttRequest error

I send a request to a remote API. It takes a little time for API to proceed on its side.
After this little waiting time, i can see in network tab a HTTP 200. In the response, I got the proper intended information. Everything on the API side works fine.
BIT on the console, I can see I encountered a XMLHttpRequest Error.
Why, especially if I have a XMLHttpRequest Error, the POST is completed with 200? Shouldn't it be "blocked" by Angular2?
The unintended result is: my file is correctly uploaded and handled by the API, but in Angular2, it triggers the ERROR part of my call.
If I use https://resttesttest.com/ for example, it seems to encounter the same error but it doesn't finalize the POST:
Oh no! Javascript returned an
HTTP 0 error. One common reason this might happen is that you
requested a cross-domain resource from a server that did not include
the appropriate CORS headers in the response.
Angular 2 Code for this call
this.http
.post(this.documentUploadAPIUrl, formData, options)
.subscribe(
res => {
this.responseData = res.json();
console.log(this.responseData);
console.log('Uploaded a blob or file!');
},
error => {
console.log('Upload failed! Error:', error);
}
);
try to set withCredential attribute of xmlHttpRequest to true, this will send credentials managed by the browser, in angular 2 you can do like this
import { RequestOptions } from '#angular/http';
this.http
.post(this.documentUploadAPIUrl, formData, this.post_options)
.subscribe(
res => {
this.responseData = res.json();
console.log(this.responseData);
console.log('Uploaded a blob or file!');
},
error => {
console.log('Upload failed! Error:', error);
}
);
post_options() {
return new RequestOptions({ method: 'post', withCredentials : true });
}

Ember Simple Auth on Firefox: authentication throws Error

I am extending Ember Simple Auth's base authentication class to allow authentication with Google. So far, it works on Safari 8 and Chrome 41 (both on Yosemite) with no errors. However, on Firefox 35, it throws an Error that does not occur on the other browsers. Here is my Google authenticator class:
App.GoogleAuthenticator = SimpleAuth.Authenticators.Base.extend({
// constants for Google API
GAPI_CLIENT_ID: 'the client id',
GAPI_SCOPE: ['email'],
GAPI_TOKEN_VERIFICATION_ENDPOINT: 'https://www.googleapis.com/oauth2/v2/tokeninfo',
// method for scheduleing a single token refresh
// time in milliseconds
scheduleSingleTokenRefresh: function(time) {
var self = this;
return new Ember.RSVP.Promise(function(resolve, reject) {
Ember.run.later(self, function() {
gapi.auth.authorize({
client_id: self.GAPI_CLIENT_ID,
scope: self.GAPI_SCOPE,
immediate: true
}, function(data) {
if (data && !data.error) {
resolve(data);
} else {
reject((data || {}).error);
}
});
}, time);
});
},
// WIP: recursive method that reschedules another token refresh after the previous scheduled one was fulfilled
// usage: scheduleTokenRefreshes(time until token should refresh for the first time, time between subsequent refreshes)
// usage: scheduleTokenRefreshes(time between refreshes)
scheduleTokenRefreshes: function(time1, time2) {
var self = this;
// if there is a time2, schedule a single refresh, wait for it to be fulfilled, then call myself to schedule again
if (!Ember.isEmpty(time2)) {
self.scheduleSingleTokenRefresh(time1)
.then(function() {
self.scheduleTokenRefreshes(time2);
});
// if there isn't a time2, simply schedule a single refresh, then call myself to schedule again
} else {
self.scheduleSingleTokenRefresh(time1)
.then(function() {
self.scheduleTokenRefreshes(time1);
});
}
},
// method that restores the session on reload
restore: function(data) {
var self = this;
return new Ember.RSVP.Promise(function(resolve, reject) {
console.log(data);
if (Ember.isEmpty(data.access_token)) {
reject();
return;
}
// schedule a refresh 15 minutes before it expires or immediately if it expires in < 15
var timeNow = Math.floor(Date.now() / 1000);
var expiresAt = +data.expires_at;
var timeDifference = expiresAt - timeNow;
var schedulingDelay = Math.floor(timeDifference - 15 * 60);
schedulingDelay = schedulingDelay < 0 ? 0 : schedulingDelay;
self.scheduleTokenRefreshes(schedulingDelay * 1000, 45 * 60);
resolve(data);
});
},
// method that authenticates
authenticate: function() {
var self = this;
return new Ember.RSVP.Promise(function(resolve, reject) {
gapi.auth.authorize({
client_id: self.GAPI_CLIENT_ID,
scope: self.GAPI_SCOPE
}, function(data) {
if (data && !data.error) {
// schedule a refresh in 45 minutes
var schedulingDelay = 45 * 60;
self.scheduleTokenRefreshes(schedulingDelay * 1000);
resolve(data);
} else {
reject((data || {}).error);
}
});
});
},
// method that logs the user out and revokes the token
invalidate: function(data) {
var self = this;
return new Ember.RSVP.Promise(function(resolve, reject) {
// send a GET request to revoke the token
Ember.$.ajax({
type: 'GET',
url: 'https://accounts.google.com/o/oauth2/revoke?token=' + self.get('session.access_token'),
contentType: 'application/json',
dataType: 'jsonp'
})
.done(function(successData) {
resolve(successData);
})
.fail(function(error) {
reject(error);
});
});
}
});
When the popup window closes after a successful login on Google's end, this error appears on Firefox's console:
Error: Assertion Failed: Error: Permission denied to access property 'toJSON' ember.js:13749
"__exports__.default<.persist#http://127.0.0.1/~jonchan/test/bower_components/ember-simple-auth/simple-auth.js:1524:1
__exports__.default<.updateStore#http://127.0.0.1/~jonchan/test/bower_components/ember-simple-auth/simple-auth.js:1195:11
__exports__.default<.setup#http://127.0.0.1/~jonchan/test/bower_components/ember-simple-auth/simple-auth.js:1149:9
__exports__.default<.authenticate/</<#http://127.0.0.1/~jonchan/test/bower_components/ember-simple-auth/simple-auth.js:1066:13
tryCatch#http://127.0.0.1/~jonchan/test/bower_components/ember/ember.js:47982:16
invokeCallback#http://127.0.0.1/~jonchan/test/bower_components/ember/ember.js:47994:17
publish#http://127.0.0.1/~jonchan/test/bower_components/ember/ember.js:47965:11
#http://127.0.0.1/~jonchan/test/bower_components/ember/ember.js:29462:9
Queue.prototype.invoke#http://127.0.0.1/~jonchan/test/bower_components/ember/ember.js:848:11
Queue.prototype.flush#http://127.0.0.1/~jonchan/test/bower_components/ember/ember.js:913:13
DeferredActionQueues.prototype.flush#http://127.0.0.1/~jonchan/test/bower_components/ember/ember.js:718:13
Backburner.prototype.end#http://127.0.0.1/~jonchan/test/bower_components/ember/ember.js:143:11
createAutorun/backburner._autorun<#http://127.0.0.1/~jonchan/test/bower_components/ember/ember.js:546:9
" ember.js:29488
Here is the version information:
DEBUG: Ember : 1.9.1
DEBUG: Ember Data : 1.0.0-beta.14.1
DEBUG: Handlebars : 2.0.0
DEBUG: jQuery : 2.1.3
DEBUG: Ember Simple Auth : 0.7.2
The most confounding thing is that this only appears on Firefox. Is it a bug in Ember Simple Auth or Ember? How do I fix it?
I do not know about only Firefox throwing an error (I've had a similar error with Chrome 40), but there is a bug in ember-simple-auth 0.7.2 with Ember 1.9 that prohibits sending an actual error response in the authenticate method in the authenticator.
If you return reject() in the rejection function of authenticate it will not throw an additional error. This will however not propagate the errorstatus or message, so I consider this a bug.
A work-around was proposed on github about this issue by setting Ember.onerror=Ember.K temporarily so additional errors will not be propagated, although it will propagate the original authenticate rejection with the error-status.
The issue in the github repo only mentions problems with testing this, but I've had this problem in normal code.
see: https://github.com/simplabs/ember-simple-auth/issues/407
Turns out the error was on the resolve part of the authenticate method. Here is what fixed it:
App.GoogleAuthenticator = SimpleAuth.Authenticators.Base.extend({
authenticate: function() {
return new Ember.RSVP.Promise(function(resolve, reject) {
gapi.auth.authorize({
client_id: 'the client id',
scope: ['the scopes'],
}, function(data) {
if (data && !data.error) {
resolve({
access_token: data.access_token // !! passing the entire 'data' object caused the error somehow
});
} else {
reject((data || {}).error);
}
});
});
},
// ...
});
I'm still not quite sure why this caused the error. Perhaps the Google API's response (in its entirety) is somehow incompatible with Ember Simple Auth.

Resources