Facebook Login not working on phone Angular Satellizer - javascript

Problem
I'm working on angular and have implemented facebook login through Satellizer. It works well on desktop, but when accessed on mobile, it sometimes work, and sometimes don't. The login pop-up is never closed when it is not working, and it opens the home page in login pop-up, while the main screen which requested login is still waiting for the pop-up to close. Any suggestion what might be wrong here?
Sample Code
This is how I'm authenticating from facebook
var commonConfig = {
popupOptions: {
location: 'no',
toolbar: 'yes',
width: window.screen.width,
height: window.screen.height
}
};
var permissions = ["public_profile","email"];
$authProvider.facebook(angular.extend({}, commonConfig, {
clientId: FacebookAppId,
url: ApiUrl+'api/v1/facebook/auth',
scope:permissions,
scopeDelimiter:','
}));
This code is called when "connect using facebook" is pressed
$scope.loginSocial = function () {
$scope.disableSubmitBtn = true;
$scope.showSpinner = true;
$auth.authenticate('facebook')
.then(function (result) {
result = angular.fromJson(result.data.code)
return AuthServerProvider.loginFb(result.facebookCode);
},function (error) {
$scope.status = 'facebook-error';
$scope.disableSubmitBtn = false;
$scope.showSpinner = false;
})
.then(function(){
$scope.disableSubmitBtn = true;
$scope.showSpinner = true;
})
This code works perfectly on desktop web browsers, but when accessed through phone browsers "$auth.authenticate('facebook')" fails most of the time.

We were facing similar problem with implementing Satellizer. It turned out that the problem was with handling the redirectUri within angular ui.router.
if you go back to the library documentation you will notice this qoute:
To avoid potential 404 errors, create server routes for each redirectUri > URL that return 200 OK. Or alternatively, you may render a custom template with a loading spinner. For the moment, a popup will not stay long > enough to see that custom template, due to 20ms interval polling, but in > the future I may add support for overriding this polling interval value.
In the above code you have mentioned, you didn't assign the redirectUri, so it will be defaulted to '/'. If you already have this route handled in a different way it might sometimes get caught by angular routes and being redirected before Satellizer can fetch it. In order to solve this just assign a redirectUri and handle it through angular routes.
For further details please read this post.

Related

How can I close certificate authentication pop-up

Recently in our application we have added the Certification authentication and when ever we access the application the authentication pop-up is displayed and we have to select the correct authentication and click on the Ok button. I tried looking for solutions to use in protractor, but no luck. I have attached the SS of my window. When I use the below code I am getting only 1 windowhandler.
I would appreciate your help as my scripts failing due to this issue.
flow = protractor.promise.controlFlow();
flow.execute(function () {
browser.ignoreSynchronization = true;
browser.get('https://test.xyz.net/').then(function () {
browser.driver.getAllWindowHandles().then(function (handles) {
console.log (handles.length);
})
})
browser.ignoreSynchronization = false;
});

How to determine if google auth2.signIn() window was closed by the user?

Im implementing auth using this and am currently showing a loading icon in React when a user clicks the button to sign in and the auth2 account selection/login window shows.
However if a user closes the window, there doesnt seem to be any event fired i.e the signIn() function which returns a promise never resolves, I would have thought google would return an error for this promise if the window is closed. As a result there is no way for me to stop showing the loader icon and reshow the login menu.
I was wondering if anyone had a solution for this?
I try to modifiy my code that call Google OAuth 2.0 window.
You only have to add extra AJAX method that cover what is Google OAuth error result.
gapi.auth2.getAuthInstance().signIn()
Change it to this one,
gapi.auth2.getAuthInstance().signIn().then(function(response){
//If Google OAuth 2 works fine
console.log(response);
}, function(error){
//If Google OAuth 2 occured error
console.log(error);
if(error.error === 'popup_closed_by_user'){
alert('Oh Dude, Why you close authentication user window...!');
}
});
That's it...
For more detail about Google OAuth 2.0 information, you can visit this link.
https://developers.google.com/api-client-library/javascript/samples/samples#authorizing-and-making-authorized-requests
Sample code on JavaScript:
https://github.com/google/google-api-javascript-client/blob/master/samples/authSample.html
Although the API provides a mechanism for detecting when the user clicks the Deny button, there is not a built-in way for detecting that the user abruptly closed the popup window (or exited their web browser, shut down their computer, and so on). The Deny condition is provided in case you want to re-prompt the user with reduced scopes (e.g. you requested "email" but only need profile and will let the user proceed without giving you their email).
If the response from the sign-in callback contains the error, access_denied, it indicates the user clicked the deny button:
function onSignInCallback(authResult) {
if (authResult['error'] && authResult['error'] == 'access_denied') {
// User explicitly denied this application's requested scopes
}
}
You should be able to implement sign-in without detecting whether the window was closed; this is demonstrated in virtually all of the Google+ sample apps. In short, you should avoid using a spinner as you're doing and instead should hide authenticated UI until the user has successfully signed in.
It's not recommended you do this, but to implement detection of the pop-up closing, you could do something like override the global window.open call, then detect in window.unload or poll whether the window was closed without the user authenticating:
var lastOpenedWindow = undefined;
window.open = function (open) {
return function (url, name, features) {
// set name if missing here
name = name || "default_window_name";
lastOpenedWindow = open.call(window, url, name, features);
return lastOpenedWindow;
};
}(window.open);
var intervalHandle = undefined;
function detectClose() {
intervalHandle = setInterval(function(){
if (lastOpenedWindow && lastOpenedWindow.closed) {
// TODO: check user was !authenticated
console.log("Why did the window close without auth?");
window.clearInterval(intervalHandle);
}
}, 500);
}
Note that as I've implemented it, this mechanism is unreliable and subject to race conditions.

How to get access token from node-webkit for a desktop app without hosting page?

I'm trying to create a desktop app with node-webkit. A part of this app require the use of facebook to get/post some content to any profile (facebook user) that use my desktop app on my personal computer.
Regarding facebook api documentation (https://developers.facebook.com/docs/facebook-login/manually-build-a-login-flow/v2.0) , I have to manually implement the login flow and use the following URI as the redirect URI: https://www.facebook.com/connect/login_success.html
Currently, in my node-webkit app, via a child window (a popup), a user can login to facebook and authorize my desktop app to interact with it's profile.
Here is a part of the code:
var url = "https://www.facebook.com/dialog/oauth?client_id=myclientID&redirect_uri=https://www.facebook.com/connect/login_success.html&response_type=token&scope=publish_actions";
loginWindow = window.open(url, 'Login facebook', 'location=yes,toolbar=yes,menubar=yes,directories=yes,status=yes,resizable=yes,scrollbars=yes,height=480,width=640', false);
After that, the user is redirected to the following URI and as mentioned in the doc, the access token appear correctly:
https://www.facebook.com/connect/login_success.html#access_token=theBigTokenString&expires_in=3864.
But it appears only for few seconds and after that the url is replaced by https://www.facebook.com/connect/blank.html#_=_ (with a security warning message).
I've read some post that propose to add eventListener like hashchange to the opened window in order to capture the access token. But after some redirect within the child window, I'm no longer available to interact with it via javascript.
So finally, I can't get the access token that the child window has retrieved and make visible for few seconds.
Is anyone can help me to get this user access token with node-webkit?
I really don't want to use a server (for hosting a web page) between my desktop app and facebook.
Thanks in advance for help.
With the help of an other question (here) I found a solution to my problem.
I post the code that I use now and I Hope it will help someone else:
var url = "https://www.facebook.com/dialog/oauth?&client_id=myBigClientID&redirect_uri=https://www.facebook.com/connect/login_success.html&response_type=token&scope=publish_actions";
function Response() {
this.access_token = null;
this.expires_in = null;
};
var response = new Response();
//function called every 500ms to check if token is in url
window.hashUpdate = function() {
if(window.loginWindow.closed){
window.clearInterval(intervalId);
start(); //just a callback that I'm using to start another part of my application (after I caught the token)
}
else {
var url = window.loginWindow.document.URL;
var tabUrl = url.split("#"); //first split to separate the domain part and the parameter part
var paramString = tabUrl[1]; //I concerned only by the second part after the '#'
if(paramString != undefined){
var allParam = paramString.split("&");
for (var i = 0; i < allParam.length; i++) {
var oneParamKeyValue = allParam[i].split("=");
response[oneParamKeyValue[0]] = oneParamKeyValue[1]; //store my token in form of key => value
};
//close the window after 1500ms
setTimeout(function(){
window.loginWindow.close();
}, 1500);
}
}
}
//open the url and start the watching process
window.loginWindow = window.open(this.url, 'Login facebook', false);
this.intervalId = window.setInterval("window.hashUpdate()", 500);

Windows Store HTML app with popup window

I'm wrapping a web app in a Windows Store app shell using a x-ms-webview. This works fine, but I have one problem. I use PayPal and since PayPal doesn't allow to be iframed I need to open PayPal in a new browser window.
On regular browsers this isn't a problem. The window open and when the user returns from PayPal I can a callback on "opener" and update the users account.
But when doing this in a Windows Store app the window.open triggers IE to launch. The problem is to return to my app and let it know that the user finished the transaction.
My first idea was just to use a URI activation. This kind of works, but I having trouble knowing if the PayPal page was launch from a regular browser or an app. I also think it is confusing for the user to be taken to another app to make the purchase.
I would prefer to have the window open in my app, but I'm not sure how I would open open a new x-ms-webview as a modal window overlapping existing webview.
What is the best way to communicate from the current web view and the app?
Can I use postMessage to send messages between the app and the x-ms-webview even though the src of the web view is a http hosted site?
Thank you for your help.
I found a solution to this.
First, you will need to use a https url for the embedded site. The reason for this is that the solution include postMessage and invokeScriptAsync.
First, my markup in my app looks something like this to have one webview for the app and one web view for the PayPal popup.
<x-ms-webview id="webview" src="https://myapp"></x-ms-webview>
<div id="paypalContainer">
<div class="paypal-header"><button id="paypalClose" type="reset">Close</button></div>
<div class="paypal-body"><x-ms-webview id="paypalWebView" src="about:blank"></x-ms-webview></div>
</div>
Then, when the web app is ready to use PayPal, I use window.external.notify to send a message to the Windows Store app.
if (window.external && 'notify' in window.external) {
window.external.notify(JSON.stringify({ action: 'paypal' }));
}
The windows store app listens for Script Notify events and displays the paypalWebView.
webview.addEventListener("MSWebViewScriptNotify", scriptNotify);
function scriptNotify(e) {
var data = JSON.parse(e.value);
if (data.action === "paypal") {
var loading = document.getElementById("loading-indicator");
var container = document.getElementById("paypalContainer");
var paypalWebView = document.getElementById("paypalWebView");
var paypalClose = document.getElementById("paypalClose");
if (paypalWebView.src === "about:blank") {
paypalWebView.addEventListener('MSWebViewNavigationCompleted', function (e) {
loading.classList.remove('loading');
var successUrl = '/paypal/success';
if (event.target.src.indexOf(successUrl) !== -1) {
var operation = webview.invokeScriptAsync("updateUser");
operation.oncomplete = function () {
(new Windows.UI.Popups.MessageDialog("Your account is refreshed", "")).showAsync().done();
};
operation.start();
}
});
paypalWebView.addEventListener('MSWebViewNavigationStarting', function (e) {
console.log("Started loading");
loading.classList.add('loading');
});
paypalClose.addEventListener('click', function () {
container.classList.remove("visible");
});
}
paypalWebView.src = "https://myapp/paypal/";
container.classList.add("visible");
}
}
So, basically, when the script notify event fires, I parse the sent json string to an object and check what kind of action it is. If it's the first time I run this I setup some naviation event handlers that check if the web view reach the Success page. If we have, I use incokeScriptAsync to let the web app know that we're done so it can refresh the user account the new payment.
I think you can use a similar solution for authentication and just check your your return URL after authenticating.
Hope this helps!

Facebook Application permission

Hi I have developed a Facebook application in Flash using Action-script 3. The application is working fine. I have developed Facebook login and authentication in JavaScript. The problem is then the user is not sign in to Facebook the application works fine, provide the user login panel and application permission panel and post the desire thing on user wall but if the user is already sign in than the JavaScript wont ask for the Facebook app permission and hence the app wont post on user wall. My JavaScript code is
<script type="text/javascript">
var APP_ID = "xxxxxxxxxxxxxxx";
var REDIRECT_URI = "http://apps.facebook.com/engel-tanimiyorum/";
var PERMS = 'publish_stream , email, user_birthday'; //comma separated list of extended permissions
function init()
{
FB.init({appId:APP_ID, status: true, cookie: true, oauth: true});
FB.getLoginStatus(handleLoginStatus);
}
function handleLoginStatus(response)
{
if (response.authResponse && response.status=="connected")
{
//Show the SWF
$('#ConnectDemo').append('<h1>You need at least Flash Player 9.0 to view this page.</h1>');
swfobject.embedSWF("index.swf",
"ConnectDemo", "803", "516", "9.0", null, null, null, {name:"ConnectDemo"});
}
else
{
var params = window.location.toString().slice(window.location.toString().indexOf('?'));
top.location = 'http://graph.facebook.com/oauth/authorize?client_id='
+APP_ID
+'&scope='+PERMS
+'&redirect_uri=' + REDIRECT_URI
+ params;
}
}
$(init);
</script>
Yours quick response will be highly appreciable
Regards
I don't know if this helps or not. But instead of your
var PERMS = 'publish_stream , email, user_birthday';
I do believe it should be states as an Array and then you would list your permissions.
It works for me, so I think it should look like this:
public var PERMS:Array = ["publish_stream","email","user_birthday"];
Also, not having your variables public might be the problem too.
Also, from what I see, you don't have any buttons, or text input?
If not, you need to create those. Then have a click handler for when there is text in the text input it will activate a click handler that then will go to a submit post handler, which then goes to a get status handler that will show you the new status you have created. I may be saying this all wrong. After all, I am not using Java for my app. But it seems logical to me that that is what you would do.. Try my first suggestions out and get back to me. If you'd rather, email me at Shandan_Spencer#live.com, so I can help you some more.

Categories

Resources