Discovering a more efficient method to accomplish this without relying on accounts-facebook or Facebook's own SDK. Instead, leveraging Meteor's accounts and accounts-ui for convenience.
Client-Side Event Handler:
Template.header.events({
'click #loginFB': function(e) {
e.preventDefault();
OAuth.redirect('facebook', "/oauthlink");
//or
var url = 'https://www.facebook.com/dialog/oauth?client_id=' +client_id+'&response_type=token&redirect_uri='+redirect;
window.location = url;
}
});
Utilizing Iron Router to handle the OAuth result:
this.route('oauthLink', {
path: '/oauthlink',
action: function() {
OAuth.callback('facebook', function(err, result) {
Meteor.call('fblogin', result, function(error, result) {
Meteor.loginWithToken(result.token, function(err) {
if(err) {
Meteor._debug("Error logging in with token: " + err);
}
})
});
});
}
});
Alternatively, omitting oauth.io:
this.route('oauthLink', {
path: '/oauthlink',
action: function() {
var str = window.location.hash;
str = str.split('&');
var accessToken = str[0];
var expiresIn = str[1];
accessToken = accessToken.split('=');
expiresIn = expiresIn.split('=');
var result = {
access_token : accessToken[1],
expires_in : expiresIn[1]
};
Meteor.call('fblogin', result, function(error, result) {
console.log(result)
Meteor.loginWithToken(result.token, function(err) {
if(err) {
Meteor._debug("Error logging in with token: " + err);
}
})
});
}
});
Though unsure about the correct use of 'Action' (as I'm new to iron-router), it functions as intended.
Server-Side Implementation:
Meteor.methods({
fblogin: function(response) {
var identity = Meteor.call('$getIdentity', response.access_token);
var serviceData = {
accessToken: response.access_token,
expiresAt: (+new Date) + (1000 * response.expires_in)
};
var whitelisted = ['id', 'email', 'name', 'first_name',
'last_name', 'link', 'username', 'gender', 'locale', 'age_range'];
var fields = _.pick(identity, whitelisted);
_.extend(serviceData, fields);
var stuff = {
serviceName : 'facebook',
serviceData: serviceData,
options: {profile: {name: identity.name}}
};
var userData = Accounts.updateOrCreateUserFromExternalService(stuff.serviceName, stuff.serviceData, stuff.options);
var x = DDP._CurrentInvocation.get();
var token = Accounts._generateStampedLoginToken();
Accounts._insertLoginToken(userData.userId, token);
Accounts._setLoginToken(userData.userId, x.connection, Accounts._hashLoginToken(token.token))
x.setUserId(userData.userId)
return {
id: userData.userId,
token: token.token,
tokenExpires: Accounts._tokenExpiration(token.when)
};
},
$getIdentity: function(accessToken) {
try {
return HTTP.get("https://graph.facebook.com/me", {
params: {access_token: accessToken}}).data;
} catch (err) {
throw _.extend(new Error("Failed to fetch identity from Facebook. " + err.message),
{response: err.response});
}
}
});
Enhancing functionality inherited from accounts-facebook package while introducing modifications tailored to specific requirements.
Additionally, copying the `$getIdentity` function directly from there.
'var stuff' encapsulates Facebook data alongside meteor account data, seamlessly integrating into Accounts.updateorcreateuserfromexternalservice, thereby streamlining the process.
The 'fblogin()' function yields userData, obtained through Accounts.updateorcreate...., consequently acquiring the essential token utilized for login via Metoer.loginWithToken.
Executing operations sans the need to launch additional windows or tabs as would be the case with accounts-facebook has resolved primary concerns, yielding equivalent functionality.
Eliminating the necessity to ascertain user existence before generating passwords, simplifying the entire procedure.
Potential expansion across alternative OAuth APIs devoid of dependency on oauth.io is entirely feasible. Personal laziness was the only deterrent in exploring further possibilities.