Last active
June 10, 2019 17:30
-
-
Save faceyspacey/9cdaee9b041fbe55868ad686a13ef3a4 to your computer and use it in GitHub Desktop.
meteor-accounts-twitter-auth
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
const Twit = Meteor.npmRequire('twit'); | |
Accounts.registerLoginHandler('twitter', function(params) { | |
const data = params.twitter; | |
// If this isn't twitter login then we don't care about it. No need to proceed. | |
if (!data) { | |
return undefined; | |
} | |
let {authToken, authTokenSecret} = data; | |
const fields = ['id', 'email', 'screen_name', 'name', 'location', 'verified', 'lang', 'description', 'utc_offset', 'time_zone', 'followers_count', 'profile_image_url', 'profile_image_url_https', 'profile_background_url', 'profile_background_url_https']; | |
// Get our user's identifying information. This also checks if the accessToken | |
// is valid. If not it will error out. | |
const identity = getIdentity(authToken, authTokenSecret, fields); | |
// Search for an existing user with that facebook id | |
const existingUser = Meteor.users.findOne({ 'services.twitter.id': identity.id }); | |
let userId; | |
if (existingUser) { | |
userId = existingUser._id; | |
// Update our data to be in line with the latest from Twitter | |
const prefixedData = {}; | |
_.each(fields, (val, key) => { | |
prefixedData[`services.twitter.${key}`] = val; | |
}); | |
let modifier = {$set: prefixedData}; | |
if(identity.email) { //email is only supplied by Twitter API if your app has received approval to retreive emails | |
modifier.$addToSet = { emails: { address: identity.email, verified: true } }; | |
} | |
Meteor.users.update(userId, modifier); | |
} else { | |
// Create our user | |
let doc = { | |
services: { | |
twitter: identity | |
}, | |
profile: { name: identity.name }, | |
} | |
if(identity.email) { | |
doc.emails = [{ | |
address: identity.email, | |
verified: true | |
}]; | |
} | |
if(Accounts._onCreateUserHook) { | |
doc = Accounts._onCreateUserHook(params, doc); | |
} | |
userId = Meteor.users.insert(doc); | |
} | |
return { userId: userId }; | |
}); | |
const getIdentity = (authToken, authTokenSecret, fields) => { | |
let twitter = new Twit({ | |
consumer_key: Meteor.settings.twitter.consumerKey, | |
consumer_secret: Meteor.settings.twitter.secret, | |
access_token: authToken, | |
access_token_secret: authTokenSecret, | |
timeout_ms: 30*1000, //optional HTTP request timeout to apply to all requests. | |
}); | |
try { | |
let getSync = Meteor.wrapAsync(twitter.get.bind(twitter)); | |
let res = getSync('account/verify_credentials', {include_email: true, skip_status: true}); | |
return fields.reduce((identity, field) => { | |
identity[field] = res[field]; | |
return identity; | |
}, {authToken, authTokenSecret}); | |
} catch (err) { | |
throw new Error("Failed to fetch identity from Twitter. " + err.message); | |
} | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment