loopback-component-satellizer
Version:
A loopback module for satellizer
190 lines (173 loc) • 4.92 kB
text/coffeescript
async = require 'async'
debug = require('debug') 'loopback:satellizer:twitter'
qs = require 'querystring'
request = require 'request'
randomstring = require 'randomstring'
common = require '../common'
module.exports = (server, options) ->
Common = common server, options
Model = server.models[options.model]
credentials = options.credentials
callbackUrl = options.callbackUrl
handleFirstRequest = (callback) ->
request.post
url: 'https://api.twitter.com/oauth/request_token'
oauth:
consumer_key: credentials.public
consumer_secret: credentials.private
, (err, res, body) ->
return callback err if err
callback null, qs.parse body
fetchAccessToken = (oauthToken, oauthVerifier, callback) ->
request.post
url: 'https://api.twitter.com/oauth/access_token'
oauth:
consumer_key: credentials.public
consumer_secret: credentials.private
token: oauthToken
verifier: oauthVerifier
, (err, res, accessToken) ->
if err
debug JSON.stringify err
return callback err
if res.statusCode isnt 200
err = new Error accessToken
err.status = 500
debug JSON.stringify err
return callback err
callback null, qs.parse accessToken
fetchProfile = (accessToken, callback) ->
debug 'fetchProfile'
request.get
url: 'https://api.twitter.com/1.1/users/show.json?screen_name=' + accessToken.screen_name
oauth:
consumer_key: credentials.public
consumer_secret: credentials.private
oauth_token: accessToken.oauth_token
json: true
, (err, res, profile) ->
if err
debug JSON.stringify err
return callback err
if res.statusCode isnt 200
err = new Error JSON.stringify profile
err.status = 500
debug JSON.stringify err
return callback err
callback null, profile
link = (req, profile, callback) ->
debug 'link'
Common.current req, (err, found) ->
if err
debug err
return callback err
if found is null
err = new Error 'not_an_account'
err.status = 409
debug err
return callback err
if found
return link.existing profile, found, callback
#
query =
where: {}
query.where[options.mapping.id] = profile.id
#
Model.findOne query, (err, found) ->
if err
debug err
return callback err
return link.create profile, callback if not found
return link.existing profile, found, callback
link.create = (profile, callback) ->
debug 'link.create', profile.id
tmp =
email: "#{profile.id}@twitter.com"
password: randomstring.generate()
Common.map options.mapping, profile, tmp
Model.create tmp, (err, created) ->
debug err if err
return callback err, created
link.existing = (profile, account, callback) ->
debug 'link.existing'
if account[options.mapping.id] and account[options.mapping.id] != profile.id
err = new Error 'account_conflict'
err.status = 409
debug err
return callback err
Common.map options.mapping, profile, account
account.save (err) ->
debug err if err
return callback err, account
Model.twitter = (req, oauthToken, oauthVerifier, callback) ->
debug "#{oauthToken}, #{oauthVerifier}"
# Initial request for satellizer
return handleFirstRequest callback if not oauthToken or not oauthVerifier
async.waterfall [
(done) ->
fetchAccessToken oauthToken, oauthVerifier, done
(accessToken, done) ->
fetchProfile accessToken, done
(profile, done) ->
link req, profile, done
(account, done) ->
Common.authenticate account, done
], callback
Model['twitter-get'] = Model.twitter
Model.remoteMethod 'twitter-get',
accepts: [
{
arg: 'req'
type: 'object'
http:
source: 'req'
}
{
arg: 'oauth_token'
type: 'string'
http:
source: 'query'
}
{
arg: 'oauth_verifier'
type: 'string'
http:
source: 'query'
}
]
returns:
arg: 'result'
type: 'object'
root: true
http:
verb: 'get'
path: options.uri
Model.remoteMethod 'twitter',
accepts: [
{
arg: 'req'
type: 'object'
http:
source: 'req'
}
{
arg: 'oauth_token'
type: 'string'
http:
source: 'form'
}
{
arg: 'oauth_verifier'
type: 'string'
http:
source: 'form'
}
]
returns:
arg: 'result'
type: 'object'
root: true
http:
verb: 'post'
path: options.uri
return