GWT: A way to cancel PlaceChangeEvent? - gwt

I'm using Activity/Place in my GWT project, if current user is not logged in, when he navigates to some Place, the user will be redirect to login page, if the user has logged in, then he will be taken to that Place. How to implement this logic efficiently?
I tried to hook PlaceChangeRequestEvent:
eventBus.addHandler(PlaceChangeRequestEvent.TYPE,new PlaceChangeRequestEvent.Handler() {
#Override
public void onPlaceChangeRequest(PlaceChangeRequestEvent event) {
Place newPlace = event.getNewPlace();
if (newPlace instanceof MyProtectedPlace && userNotLoggedIn()) {
event.goTo(new LoginPlace());
}
}
});
Unfortunately it does not work since the ongoing request for MyProtectedPlace is not cancelled.
Yes I could check this when user are about to navigation away from current place, but this will not be efficient as the check logic will scattered throughout the program.
Thanks.

You can do it a little bit differently I think. Let's say that you want a place called SecuredPlace to be accessible only after login. You have a corresponding SecuredActivity.
What you can do is, when you start your SecuredActivity, you check if your user is logged in. If not you do placeController.goTo(new LoginPlace ()).
If the user is logged in then you continue. As the start is called by the framework there is no way to skip this step which in my opinion makes it secured enough.
But you should implement your security on network calls to your backend not on places. Every time you call the backend, you check that user is authenticated and has the right credentials. If not you can intercept the callback, check that it is a 403 error and then redirect automatically to your login page. Because if your backend calls are not secured, securing your places is useless.

Related

Meteor keep track of user sign ins

I would like to keep track of the amount of times that a user has logged into the application to either:
Remind them on their first visit to complete their profile
If profile is not complete, every X amount of visits remind user to complete
I'm not sure if the proper way to do this would be adding a key value to the users collection, or tie login to a new collection which counts up one each time a login occurs.
Is there a built in method to keep track of login successes?
Yup. You can even keep track of login failures.
From http://docs.meteor.com/#/full/accounts_onlogin:
Accounts.onLogin(function() {
// track successful login here. You can just use Meteor.user() to find out which user.
});
Accounts.onLoginFailure(function() {
// track failed login here.
});
There is even a "validate login attempt" method where you could potentially screen your users:
Accounts.validateLoginAttempt(func):
Accounts.validateLoginAttempt(function(loginInfo) {
// loginInfo.user returns a valid user object, if logged in successfully. Maybe tie this one to a collection, and do some checks etc.
// you can even use loginInfo.connection to see where the user has connected from (e.g. IP address.. perhaps)
return true; // return false if you want to 'bounce' this user.
});
Note: These can be done server-side only.

How to redirect the user to a custom page when user click "Connect to QuickBooks" button?

So Intuit charges for each active connections to QuickBooks. Therefore, I want to restrict the QuickBooks functionality in my application to premium users only.
Ideally when any user clicks the "Connect to QuickBooks" button and my RequestOAuthToken http handler is called, I want to check if the user is allowed to use QuickBooks. If that is the case, then the normal OAuth flow continue. If the user is NOT allowed, then I want to redirect the user to the upgrade page of my app.
Given that the "Connect to QuickBooks" button opens a new window (at least on desktop, I haven't tried on phone/tablets), the window should get closed, and the main window (my app) should redirect the user to the right page. And actually this is exactly what happens if the normal OAuth flow completes.
Now, I have tried a few different approaches but I couldn't get it working.
1) In my RequestOAuthToken, return a HTTP redirect to the plan page
2) In my RequestOAuthToken, return an html page with javascript logic to redirect to page
3) In my RequestOAuthToken, return HTTP redirect to a page with javascript logic to redirect to page
4) I haven't tried that one but could I somehow intercept the javascript click handler on the Intuit button. I'm not sure if that is an accepted practice.
Here is the piece a javascript I grabbed from the .Net sample:
try
{
var parentlocation = window.parent.opener.location.hostname;
var currentlocation = window.location.hostname;
if (parentlocation != currentlocation)
{
window.location = plansUrl;
}
else
{
window.opener.location.href = window.opener.location.href;
window.close();
}
}
catch (e)
{
window.location = plansUrl;
}
Help me out please.
I don't think you'll be able to do exactly what you're asking, but you can probably come close by taking a different approach.
Rather than trying to redirect them after they click the button, why not try to redirect them before they click it? e.g. when they try to get to the page that has the "Connect to QuickBooks" button it, check if they are a premium user there, and redirect them if they are not.
I don't think you'll be able to redirect them after they click the button because once they click that button, they get kicked over to Intuit's website and it's beyond your control at that point.
Clement, Keith has provided the answer we would want you to pursue. You may not alter the behavior of the Connect To QuickBooks button. It must be used as described in our documentation. Providing a link to a page that shows the Connect To QuickBooks buttons for your premium users and an upgrade message to non-premium users is the way to go.
I highly recommend that you visit http://docs.developer.intuit.com/0025_Intuit_Anywhere/0010_Getting_Started/0040_Publishing_Your_App and review all of the documentation there. If you develop with our guidelines and requirements in mind it will speed up the review process.
Tony Purmal
Developer Relations Engineer
Intuit Partner Platform

Redirect after user has logged in

I'm pretty new to Angular, and right now I'm just trying to get all my routes set up and working as I'd like.
Setup:
When a user navigates to certain pages (/settings for this example) the app should check if there is a user already logged in. If there is continue as usual. Otherwise the user should go to the login page (/login).
What I'd like:
After the user has successfully logged in they should go to the page they were originally trying to get to (/settings)
My question:
Is there an "Angular way" to remember where the user was trying to go to?
Relevant code:
app.js
.when('/settings', {
templateUrl: '/views/auth/settings.html',
controller: 'SettingsCtrl',
resolve: {
currentUser: function($q, $location, Auth) {
var deferred = $q.defer();
var noUser = function() {
//remember where the user was trying to go
$location.path("/login")
};
Auth.checkLogin(function() {
if (Auth.currentUser()) {
deferred.resolve(Auth.currentUser());
} else {
deferred.reject(noUser());
}
});
return deferred.promise;
}
}
})
login.js
$scope.submit = function() {
if(!$scope.logInForm.$invalid) {
Auth.login($scope.login, $scope.password, $scope.remember_me)
//go to the page the user was trying to get to
}
};
Much thanks to John Lindquist for the video which got me this far.
First off, you do not want to redirect the user to a login page.
An ideal flow in a single page web app is as follows:
A user visits a web site. The web site replies with the static assets for the
angular app at the specific route (e.g. /profile/edit).
The controller (for the given route) makes a call to an API using $http, $route, or other mechanism (e.g. to pre-fill the Edit Profile form with details from the logged in user's account via a GET to /api/v1/users/profile)
If/while the client receives a 401 from the API, show a modal to
login, and replay the API call.
The API call succeeds (in this case, the user can view a pre-filled Edit Profile form for their account.)
How can you do #3? The answer is $http Response Interceptors.
For purposes of global error handling, authentication or any kind of
synchronous or asynchronous preprocessing of received responses, it is
desirable to be able to intercept responses for http requests before
they are handed over to the application code that initiated these
requests. The response interceptors leverage the promise apis to
fulfil this need for both synchronous and asynchronous preprocessing.
http://docs.angularjs.org/api/ng.$http
Now that we know what the ideal user experience should be, how do we do it?
There is an example here: http://witoldsz.github.com/angular-http-auth/
The example is based on this article:
http://www.espeo.pl/2012/02/26/authentication-in-angularjs-application
Good luck and happy Angularing!

App deauthorization: Is there any triggered event by which I can update fbsr cookie without reloading page?

My first post here ! :)
Situation:
User authorized the app and while using it, in the next tab he is removing app from settings page (app deauthorization).
Why:
I want authorize every function call through existing fbsr cookie where its existence is a proof of user login status.
Other solutions:
I can do it using signed request passed in every Canvas POST but I don't want to mix it :)
Before every each call I can refresh login status by FB.getLoginStatus() method
... check every user_id from sr with database entries (what anyway must be done), it's ok but not straight ;)
Just check me/permissions every time you want to verify your user...
FB.api('/me/permissions', function(response) {
var ra = response['data'][0];
pPublishStream = (ra['publish_stream'] == 1);
pCreateEvent = (ra['create_event'] == 1);
if (pPublishStream && pCreateEvent) {
// yay!!!
}
});
Edit: In retrospect, my answer above solves the issues you mentioned but also catches the case where the user removes individual permissions for the app. So maybe it's not exactly what you wanted.

Extend auth token without refreshing the page

Users want to use my facebook app for many hours without refreshing the browser.
But token expires in 2 hours. Now I ask users to refresh the page but that's annoying.
I don't want to ask offline access permissions because it will scare some users.
The best solution will be somehow "relogin" and get new token without refreshing the page.
Is it possible?
I would subscribe to the expiry trigger (I think this is authResponseChange), then automate another login check. It won't be a perfect solution as it could trigger a pop up (if they have logged out for example) automatically, which a lot of browsers may block. You could instead, when the token expires, check if they will need to complete a pop up, and display a notification on your page somewhere saying 'Facebook needs your attention to continue', then only launch the pop up from their response, which would stop the pop up being blocked.
FB.Event.subscribe('auth.authResponseChange', function(response) {
// do something with response
FB.login(){
// refresh their session - or use JS to display a notification they can
// click to prevent pop up issues
}
});
An algorithm to workout on this
Ask for permission from the user
Save the token
Periodically check for an access token is near to expire or not
If its in verse of expiry, embed some dummy iframe, which redirects to the facebook homepage. - Extend auth token without refreshing the page
This should refresh the token. You might need to generate another token or continue with the same. Whatever be required, can be done without refreshing the page.
Have you thought of using ajax? After two hours you will check, if user is still active. If so, you send axax request to URL, where his session details will be updated. example:
$(document).ready(function(){
setInterval('update_session()', 5500000);
})
update_session(){
$.post({
URL: ..., // script to update session on server
data:{ /* username, password */ },
})
}
and the server-side just takes username and password from post or and runs relogin.
Try acquiring tokens with the offline_access permission.
I presume, guess this is not possible,FB architecture would not allow it. And why is offline_access such a problem!!!!!!...anyway offline_access is the best optimal solution I guess....
Unfortunately I believe this is impossible by design (if you mean for it to happen without user intervention). If the user is still logged in to Facebook you can redirect the top-level page to Facebook and it will bounce you right back with a new code (as it sounds like you are doing already), but that is only possible because of the Facebook cookie that it can check. If you try to do anything from your server, it will be rejected because that cookie will not accompany the request. Same goes for trying to make a call to facebook from javascript -- since your code is running in a different domain, the cookie will not accompany the call and Facebook will reject it. The only way that Facebook can even know who the user is, and that they are still logged in, is to see that cookie. And the only way that can happen is if the browser itself is redirected to the facebook.com domain.
It's worth mentioning also that Facebook has blocked the only logical workaround, i.e. loading the oauth url in an iframe. If you try it you will see that they detect the page is being loaded in an iframe and output a page with a link on it which does a top-level redirect to break out of the frame. So not only does this approach not work, it's clear that Facebook has specifically made it impossible as part of their architecture.
Edit: If what you mean to do is not avoid the refresh altogether but just have it happen automatically when a new token is needed, you can do something like this:
$status=0;
$data=#file_get_contents("https://graph.facebook.com/me?access_token=$token");
foreach ($http_response_header as $rh) if (substr($rh, 0, 4)=='HTTP') list(,$status,)=explode(' ', $rh, 3);
if ($status==200)
{
//token is good, proceed
}
else
{
//token is expired, get new one
$fburl="http://www.facebook.com/dialog/oauth?client_id=APP_ID&redirect_uri=".urlencode('http://apps.facebook.com/yourapp/thispage.php');
echo "<html>\n<body>\n<script>top.location='$fburl';</script>\n</body>\n</html>\n";
exit;
}
This is assuming you have something before this code that will process a signed_request parameter if it is present and assign a value to $token (either explicit code of your own or the appropriate SDK entries). The shown code can then be used anywhere you need to check if $token is still valid before proceeding.
If you get the access_token without specifying any expiry to them they will not expire ..
atleast not till the time user either changes his Fb credentials or de registers your application ..
I presume you are using the iframe signed_request parameter to get your access token. One method of achieving what you require is to use the oAuth 2.0 method of aquiring an access token. This is more prolonged in the first instance; your server and Facebook's have to exchange credentials which can be slow, but it means that you will be given a code that can be exchanged for an access token regularly, meaning your server can maintain the session periodically (probably from an ajax call from the client). You would then pass this new access_token to the client, and use it in your dialog call for your requests (gifts).
Hope that helps.
Spabby
Have a look at https://developers.facebook.com/docs/offline-access-deprecation/#extend_token
basically you extend the token with
https://graph.facebook.com/oauth/access_token?
client_id=APP_ID&
client_secret=APP_SECRET&
grant_type=fb_exchange_token&
fb_exchange_token=EXISTING_ACCESS_TOKEN
that will give you new token with new expiry time (it should be 60d but I'm noticing similar bug like described here https://developers.facebook.com/bugs/347831145255847/?browse=search_4f5b6e51b18170786854060 )