No callback when calling yam.platform.login - yammer

When using Yammer SDK and using yam.platform.login method, I don't get any callback when authentication fails or when the user closes dialog window. Is this a bug or something you have seen in your Yammer integration tasks?
My code
yam.platform.getLoginStatus(function (response) {
if (response.authResponse) {
}
else {
yam.platform.login(function (response) {
if (response.authResponse) {
console.dir(response);
}
else {
### CODE NEVER EXECUTED IF LOGIN FAILS OR USER CLOSE POPUP###
}
});
}
});

Make sure to add your web application url to "Javascript Origins" of your registered yammer app.
Make sure you added your web app url to "Trusted Sites" and other Yammer urls.

We get this problem (no callback on yam.platform.login) when the user is currently logged into a network other than the home network (network where app is registered). If your users use multiple networks, you may need to add your app to the global app register.
An alternative (hacky) way is to 'try' the approach below. This worked for us as it only needed to happen once (to get the auth token).
yam.getLoginStatus(function(resp){
if (resp.authResponse) {
//success
} else {
// not logged in
var yamLoginSuccess=0;
try {
yam.platform.login( function (response) { //prompt login
console.log('no response here if user in another network');
if (response.authResponse) {
//success
yamLoginSuccess=1;
}
});
}
catch(err) {
// does not throw an error so this bit is not helpful
}
finally{
if(yamLoginSuccess===0){
alert('Need to be logged into the home yammer first :-/ /n '
+ 'Redirecting now, hit back to come back');
window.location='https://www.yammer.com/YOURNETWORK/';
}
}
}
});

Related

YouTube Data API: add a subscription

I'm using YouTube's V3 Data API to add a subscription to a channel. This occurs on a Wordpress installation.
I added Google APIs (for oauth) on Wordpress theme functions:
wp_enqueue_script( 'googleapi', 'https://apis.google.com/js/client.js?onload=googleApiClientReady', array(), '1.0.0', true );
I added in the same way the oauth javascript file, which is the first one here: https://developers.google.com/youtube/v3/code_samples/javascript.
Following this guide(https://developers.google.com/youtube/v3/docs/subscriptions/insert (Apps Script)), I extended the OAuth js with the addSubscription method.
Google Client API seems to be loaded and working as it calls correctly googleApiClientReady on the oauth javascript.
So, this is how the subscription is being inserted:
OAUTH JAVASCRIPT
... ... ...
// After the API loads
function handleAPILoaded() {
addSubscription();
}
function addSubscription() {
// Replace this channel ID with the channel ID you want to subscribe to
var channelId = 'this is filled with the channel ID';
var resource = {
snippet: {
resourceId: {
kind: 'youtube#channel',
channelId: channelId
}
}
};
try {
var response = YouTube.Subscriptions.insert(resource, 'snippet');
jQuery('#success').show();
} catch (e) {
if(e.message.match('subscriptionDuplicate')) {
jQuery('#success').show();
} else {
jQuery('#fail').show();
alert("Please send us a mail () with the following: ERROR: " + e.message);
}
}
So, the first error comes with
YouTube.Subscriptions.insert(resource, 'snippet')
It says YouTube is not defined. I replaced it with:
gapi.client.youtube.subscriptions.insert(resource, 'snippet');
And that error went away. When checking response, as the subscription isn't completed, this is what I get
{"wc":1,"hg":{"Ph":null,"hg":{"path":"/youtube/v3/subscriptions","method":"POST","params":{},"headers":{},"body":"snippet","root":"https://www.googleapis.com"},"wc":"auto"}}
So, I would like to know what's happening on that POST request and what's the solution to this.
I can post the full OAuth file, but it's just as in the example, plus that addSubscription method at the end.
Okay, I got it working, the problem was on the POST request. Here is the full method working:
// Subscribes the authorized user to the channel specified
function addSubscription(channelSub) {
var resource = {
part: 'id,snippet',
snippet: {
resourceId: {
kind: 'youtube#channel',
channelId: channelSub
}
}
};
var request = gapi.client.youtube.subscriptions.insert(resource);
request.execute(function (response) {
var result = response.result;
if (result) {
// alert("Subscription completed");
}
} else {
// alert("Subscripion failed");
// ...
}
});
}
Also make sure to load Google Apps API (in fact without it the authorize/login button won't work) and jQuery.
Any chance you can post everything that made this work...all the JS entire auth.js save for your private keys, im working on this exact problem.

Meteor-Validate multi OAuth account in 'onCreateUser'

I am trying to login to single user with multi OAuth (facebook, google) login service. Here is what I try.
In Client:
'click #signInByFacebook': function (e) {
e.preventDefault();
Meteor.loginWithFacebook({requestPermissions: ['public_profile', 'email', 'user_about_me', 'user_photos']}, function (err, res) {
if (err) {
showError($('.alert'), err, 'login');
return;
}
showSuccess($('.alert'), 'login');
Session.set('notAdmin', !Roles.userIsInRole(Meteor.user(), ["admin"]));
Router.go('/');
});
},
'click #signInByGoogle': function (e) {
e.preventDefault();
Meteor.loginWithGoogle({requestPermissions: ['profile', 'email', 'openid']}, function (err, res) {
if (err) {
showError($('.alert'), err, 'login');
return;
}
showSuccess($('.alert'), 'login');
Session.set('notAdmin', !Roles.userIsInRole(Meteor.user(), ["admin"]));
Router.go('/');
});
}
In Server:
Accounts.onCreateUser(function (options, user) {
if (options.profile) {
user.profile = options.profile;
}
var sameuser = Meteor.users.findOne({$or: [{'emails.address': getEmail(user)}, {'services.facebook.email': getEmail(user)}, {'services.google.email': getEmail(user)}]});
console.log(sameuser);
if (sameuser) {
if (user.services.facebook) {
console.log("facebook");
Meteor.users.update({_id: sameuser._id}, {$set: {'services.facebook': user.services.facebook}});
}
if (user.services.google) {
console.log("google");
Meteor.users.update({_id: sameuser._id}, {$set: {'services.google': user.services.google}});
}
return;
}
console.log('register success');
return user;
});
This code will check if any user logined with facebook/google has the
same email or not with current sign in. If they are the same, just
update information to old account. If not, create new user.
This works great, but there is a problem with the 'return ;' in server code. I dont know what should I return to stop create user and auto login to the user that has same email. Anybody can help this issue ? Thank you.
The only way to stop creation of the new user is to throw an exception, but that will also prevent logging in as the existing user.
However, your general approach is insecure. Consider a user who has a Google account with a strong password and a Facebook account with a weak one. When he uses the Google account to authenticate with your app, he doesn't (and shouldn't) expect that someone who gains access to his Facebook account will be able access your app as him.
A better approach is to require that the user be logged into both services simultaneously before merging the services. The good news is that this also means that you don't need to worry about logging in after preventing the creation of the new user, because the user will already be logged in. Something like this might work:
Accounts.onCreateUser(function (options, user) {
if (options.profile) {
user.profile = options.profile;
}
var currentUser = Meteor.user();
console.log(currentUser);
if (currentUser) {
if (user.services.facebook) {
console.log("facebook");
Meteor.users.update({_id: currentUser._id}, {$set: {'services.facebook': user.services.facebook}});
}
if (user.services.google) {
console.log("google");
Meteor.users.update({_id: currentUser._id}, {$set: {'services.google': user.services.google}});
}
throw new Meteor.Error(Accounts.LoginCancelledError.numericError, "Service added to existing user (or something similar)");;
}
console.log('register success');
return user;
});
There are still a couple loose ends. First, I think Meteor expects OAuth credentials to be "pinned" to the user that they are associated with, so you probably need to repin the credentials you are copying.
Second, the above approach bypasses the validateLoginAttempt() callbacks. If you, or any package you are using, has registered any such callbacks, they won't be called when logging in using the second service, so they won't be able to prevent any such logins that they might consider invalid.
You can address both of these issues and skip the onCreateUser() callback as well, by just adding my brettle:accounts-add-service package to your app.

User Sessions Parse.com Cloud Code Hosting

My login form currently posts to itself on /
The post request is then picked up as follows...
app.post('/', userController.doLogin);
Then the controller is a follows..
exports.doLogin= function(req, res) {
Parse.User.logIn(req.body.username, req.body.password, {
success: function(user) {
console.log('login success');
res.render('loginSuccess');
},
error: function(user, error) {
console.log('login failed');
res.render('loginFailed');
}
});
}
This works correctly for a correct / incorrect login.
However, once logged in, the session is not stored no cookies are created / local storage etc..
Therefore when I test for login on one of my other routes it always displays as no-session, i am checking with the following code..
if(Parse.User.current()){
console.log('logged in and redirected');
res.redirect('/member/home');
}else{
console.log('not logged in, redirected to home/login page');
res.redirect('/');
}
Which always goes too home / again.
I read here https://parse.com/docs/hosting_guide#webapp-users that...
You just need to call Parse.User.logIn() in Cloud Code, and this middleware will automatically manage the user session for you.
Which would suggest it does the session for me?
Any help would be super useful! many thanks in advance!
Ok so after a lot of digging I have worked it out. First you need to add the module by doing the following..
var parseExpressCookieSession = require('parse-express-cookie-session');
Second you need to setup your own variables like this
app.use(express.cookieParser('YOUR_SIGNING_SECRET'));
app.use(parseExpressCookieSession({ cookie: { maxAge: 3600000 } }));
Third, you must do send the login/session all over HTTPS.
Boom, working - easy peasy when you know how.

How to use Passport-Facebook login without redirection?

I'm building a phonegap application which will have nodejs at the server side. I wanted to implement login using passport-facebook strategy but their callbacks specify two routes, /successcallback and /failurecallback. Having a single page application, this makes it very confusing to have users redirected to so and so page.
I don't want to serve static files (index.html, login.html) from the server but rather have them on the client and ask the client to make ajax calls. So far, I'm able to make /auth/facebook call as an AJAX request but I can't receive any response on the same request because the login strategy requires the user to be redirected. I'd rather want to send a user_id or name back to the user on successful login or show him the login form (which is also on the www directory in phonegap) on failure. But the redirection and CORS errors are preventing me from doing this. Is there any way I can implement this? I've looked for this since a few weeks now, but no success. I'd really appreciate your help!
PS: I'd rather avoid having to send all html and static content from the node server.
EDIT: Adding login code for better understanding:
app.get('/userpage', utility.isLoggedIn, function(req, res)
{
res.send('User:'+req.user);
});
app.get('/', utility.isLoggedIn, function(req, res)
{
res.redirect('/userpage');
});
app.get('/auth/facebook', passport.authenticate('facebook'));
app.get('/auth/facebook/callback',passport.authenticate('facebook',
{
successRedirect : '/',
failureRedirect : '/login'
}));
app.get('/logout', function(req, res)
{
req.logout();
res.redirect('/login');
});
utility.isLoggedIn:
function isLoggedIn(req, res, next)
{
if (req.isAuthenticated())
return next();
res.redirect('/login');
}
You can't do that with facebook oAuth, but Facebook provides another login solution where you can code your client app to request a token, that you can later validate on the server with passport-facebook-token.
This way you can use the advantages of passport for persistent sessions, without that annoying redirection.
Instead of using the standard redirections offered by passport, you can define your own function which will be executed instead of the redirection. Here's an example of what that code would look like
passport.authenticate('login', function(err, user, info) {
if (err) { return next(err); }
if (!user) { return res.json({ status:"failed", "error": "Invalid credentials" }); }
// req / res held in closure
req.logIn(user, function(err) {
if (err) { return next(err); }
return res.json({ "status":"success"});
})
})(req, res, next);

handling http 302 redirect in nyroModal

I'm using nyroModal v2 in an ASP.NET MVC3 application. The application forces users to authenticate and the auth cookie has max. lifetime of two hours. When the auth cookie expires all requestes are redirected to a login page (using http status code 302).
When a user opens a link in a modal "window" (using jQuery plugin nyroModal) and the auth cookie is expired nyroModal shows "an error has occoured". I managed to add a callback function to handle all errors
$(this).nyroModal({
callbacks: {
error: function (nm) {
alert("some error");
}
});
but I don't see a way to decide what kind of error (http status code) has happened. Is there an error object in nyroModal?
What I want to achieve is: close the modal window and redirect the browser window to the login page.
Thanks in advance!
Thomas
$(window).ajaxComplete(function(ev, xmlhr, options){
try {
var json = $.parseJSON(xmlhr.responseText);
}
catch(e) {
console.log('Session OK');
return;
}
if ($.isPlainObject(json) && json.SESSION == 'EXPIRED') {
console.log('Session Expired');
return;
}
console.log('Session OK');
});

Resources