I'm trying to get geolocation inside a webview in a Chrome Packaged App, in order to run my application properly. I've tried several ways to get the permission in manifest.json and injecting scripts, but it doesn't work and doesn't show any error message.
Could someone give me a light or a solution to get permission and show my geolocation?
Some features that usually require permissions in a normal web page are also available in a webview. However, instead of the normal popup "the website xyz.com wants to know your physical location - allow / deny", the app that contains the webview needs to explicitly authorize it. Here is how it works:
No need to change the web page inside the webview;
In the app, you listen for permissionrequest events on the <webview> element:
webview.addEventListener('permissionrequest', function(e) {
if ( e.permission === 'geolocation' ) {
e.request.allow();
} else {
console.log('Denied permission '+e.permission+' requested by webview');
e.request.deny();
}
});
One thing to note is that the request doesn't need to be handled immediately. You can do whatever you need to do before allowing or denying, as long as you call preventDefault in the permissionrequest event and keep the event object from being garbage collected. This is useful if you need to do any async operation, like going to a storage to check if the URL requesting a permission should be allowed or not.
For example:
webview.addEventListener('permissionrequest', function(e) {
if ( e.permission === 'geolocation' ) {
// Calling e.preventDefault() is necessary to delay the response.
// If the default is not prevented then the default action is to
// deny the permission request.
e.preventDefault();
setTimeout(function() { decidePermission(e); }, 0);
}
});
var decidePermission = function(e) {
if (e.url == 'http://www.google.com') {
e.request.allow();
}
// Calling e.request.deny() explicitly is not absolutely necessary because
// the request object is managed by the Javascript garbage collector.
// Once collected, the request will automatically be denied.
// If you wish to deny immediately call e.request.deny();
}
Also note that your app needs to also request the respective permission:
"permissions": ["geolocation"],
The webview sample has more code for other permissions, like pointerLock and media capture.
A bit more detail:
The response does not need to be made immediately as long as you preventDefault(). The default action is to deny the permission request.
webview.addEventListener('permissionrequest', function(e) {
if ( e.permission === 'geolocation' ) {
// Calling e.preventDefault() is necessary to delay the response.
// If the default is not prevented then the default action is to
// deny the permission request.
e.preventDefault();
setTimeout(function() { decidePermission(e); }, 0);
}
});
var decidePermission = function(e) {
if (e.url == 'http://www.google.com') {
e.request.allow();
}
// Calling e.request.deny() explicitly is not absolutely necessary because
// the request object is managed by the Javascript garbage collector.
// Once collected, the request will automatically be denied.
// If you wish to deny immediately call e.request.deny();
}
Related
I'm using gapi.analytics for Embed API and I'm verifying the authentication using the below code in gapi.analytics.ready function.
if (gapi.analytics.auth.isAuthorized()) {
onAuthorize();
} else {
gapi.analytics.auth.on('success', onAuthorize);
}
but gapi.analytics.auth.isAuthorized() is always returning false on page load.
How I can fix this?
You can do it this way:
gapi.analytics.auth.on('needsAuthorization', function() {
console.log('User is not Authorized!');
});
When invoking the gapi.analytics.auth.authorize method, an initial check is made to see if the user is currently signed in. If the user is not signed in, this event is fired to indicate that further authorization is required.
I'm having an issue displaying the content in the page after the Worklight http request has been executed.
The weird thing is that when I go to another page and I come back, the content gets displayed. It's like if it needs to be refreshed or something. I can see the console.log() data was received, but page was not refreshed.
This is my code:
$stateProvider.state('accounts', {
url: "/accounts",
templateUrl: 'views/accounts.html',
controller: function($scope, $ionicScrollDelegate, $rootScope){
var req = new WLResourceRequest("/adapters/JavaMQ/bankmq/getAccounts/"+$rootScope.globalReqUserId, WLResourceRequest.GET);
req.send().then(function(resp){
var x2js = new X2JS();
resp.responseText = x2js.xml_str2json(resp.responseText); //to JSON
$scope.reqUserId = resp.responseText['ASI_Message']['Riyad_Bank_Header']['Requestor_User_ID'];
$scope.accountsList = resp.responseText['ASI_Message']['Repeating_Group_Section']['Repeating_Group'];
console.log($rootScope);
})
}
});
UPDATE:
I noticed that I also keep getting the following when I moved the project to Windows (Never happened in my mac)
Deviceready has not fired after 5 seconds
Channel not fired: onCordovaInfoReady
Channel not fired: onCordovaConnectionReady
I don't really know Worklight but the documentation indicate that the send().then() handles both the onSuccess and onFailure.
Maybe the then() is expecting 2 parameters like this:
var request = WLResourceRequest(url, method, timeout);
request.send(content).then(
function(response) {
// success flow
},
function(error) {
// fail flow
}
);
If that doesn't work, can you put a breakpoint at the start of var x2js = new X2JS(); and tell us what happens?
I've tried this:
browser.wait(function () {
return browser.executeScript('return document.readyState==="complete" &&' +
' jQuery !== undefined && jQuery.active==0;').then(function (text) {
return text === true;
});
}, 30000);
If jQuery.active==0 then page is completely loaded. This should work for sites with JQuery and non angular pages.
However, I have many problems of instability to test for non angular sites.
How to fix this?
By default protractor waits until the page is loaded completely. If you are facing any error then it is because protractor is waiting for the default time to be completed, that you have specified in your conf.js file to wait until page loads. Change the value to wait a for longer time if you think your app is slow -
// How long to wait for a page to load.
getPageTimeout: 10000, //Increase this time to whatever you think is better
You can also increase the defaultTimeoutInterval to make protractor wait a little longer before the test fails -
jasmineNodeOpts: {
// Default time to wait in ms before a test fails.
defaultTimeoutInterval: 30000
},
If you want to wait for any particular element, then you can do so by using wait() function. Probably waiting for last element to load is the best way to test it. Here's how -
var EC = protractor.ExpectedConditions;
var lastElement = element(LOCATOR_OF_LAST_ELEMENT);
browser.wait(EC.visibilityOf(lastElement), 10000).then(function(){ //Alternatively change the visibilityOf to presenceOf to check for the element's presence only
//Perform operation on the last element
});
Hope it helps.
I use ExpectedConditions to wait for, and verify page loads. I walk through it a bit on my site, and example code on GitHub. Here's the gist...
Base Page: (gets extended by all page objects)
// wait for & verify correct page is loaded
this.at = function() {
var that = this;
return browser.wait(function() {
// call the page's pageLoaded method
return that.pageLoaded();
}, 5000);
};
// navigate to a page
this.to = function() {
browser.get(this.url, 5000);
// wait and verify we're on the expected page
return this.at();
};
...
Page Object:
var QsHomePage = function() {
this.url = 'http://qualityshepherd.com';
// pageLoaded uses Expected Conditions `and()`, that allows us to use
// any number of functions to wait for, and test we're on a given page
this.pageLoaded = this.and(
this.hasText($('h1.site-title'), 'Quality Shepherd')
...
};
QsHomePage.prototype = basePage; // extend basePage
module.exports = new QsHomePage();
The page object may contain a url (if direct access is possible), and a pageLoaded property that returns the ExepectedCondition function that we use to prove the page is loaded (and the right page).
Usage:
describe('Quality Shepherd blog', function() {
beforeEach(function() {
// go to page
qsHomePage.to();
});
it('home link should navigate home', function() {
qsHomePage.homeLink.click();
// wait and verify we're on expected page
expect(qsHomePage.at()).toBe(true);
});
});
Calling at() calls the ExpectedCondidion (which can be be an and() or an or(), etc...).
Hope this helps...
I am trying to implement user authentication in my sails app.. But I am encountering a problem in different controllers that their action are being called twice.. I have checked from my browser and the request is only being sent once.. Here is an example..
// api/controllers/AuthController.js
...
logout: function (req, res) {
console.log("Loggin out");
req.logOut();
res.json({message: 'Logged out succesfully'});
},
...
Following is my config/routes.js file. (using get for many action just for sake of ease for testing api..)
module.exports.routes = {
// By default, your root route (aka home page) points to a view
// located at `views/home/index.ejs`
//
// (This would also work if you had a file at: `/views/home.ejs`)
'/': {
view: 'home/index'
},
// testing the api
'get /users/check' : 'UserController.test',
'get /login' : 'AuthController.process',
'get /logout' : 'AuthController.logout',
'get /signup': 'UserController.add',
'get /verify/username/:username?' : 'UserController.checkUsername',
'get /verify/email/:email?' : 'UserController.checkEmail',
// add friend
'get /:user?/addfriend': 'FriendController.addFriend',
// accept request
'get /:user?/friendrequest/:request?/accept': 'FriendController.acceptRequest',
};
I have applied the isAuthenticated policy on this action.. which is like
module.exports = function(req, res, next) {
if(req.isAuthenticated()) {
console.log("Valid User");
return next();
}
else {
console.log("User not logged in");
return res.json({error: "Please login"});
}
};
No whenever I call <myhost>/logout I get the following json back..
{
"error": "Please login"
}
and here is the output on the server..
Valid User
Loggin out
User not logged in
This means that my controller's action is being called twice.. and this is not the problem with only this controller. The UserController.add action has the same problem. I seem to be doing every thing fine but I don't know where this problem is coming from. Can any one suggest how can I debug it . Or what could be the root of the problem. As far as I have check..
Browser is not sending the request twice.
The Controller's action is being called twice and so are the middleware assosiated with it.
Oh i have the same Problem a few weeks ago.
Sails also call the middleware on static files (like your styles.css). Console.log the req-object than you see what your browser requested.
There a two Ways to handle this Problem:
1.) Try to set skipAssets: true in your route (see: http://beta.sailsjs.org/#/documentation/concepts/Routes/RouteTargetSyntax.html)
2.) In your policy add an if-condition to skip assets (like ".js", ".css" and so on).
I'm working in a mini-app, which will have 3 pages, and i want all the interaction to happen inside a profile-tab.So, using javascript, i want to show/hide a few divs, which i'll populate using the FBJS ajax object.
My problem is, i'm not getting the user session in the ajax calls.As documentation is extremely confusing, i've ended up not knowing if this is possible at all.Any ideas?
You can get the user's id if you require login from your ajax request on a profile tab. For instance:
var ajax = new Ajax();
ajax.responseType = Ajax.RAW;
ajax.ondone = function(data) {
console.log('done');
console.log(data);
}
ajax.onerror = function(data) {
console.log('error');
console.log(data);
}
ajax.requireLogin = true;
ajax.post('http://DOMAIN/add_story', {story: story});
The requireLogin = true part will cause an authorization window to popup. If they agree, you can get the user ID in your AJAX handler using the PHP SDK, like:
$facebook->getUser();