loopback-component-satellizer
Version:
A loopback module for satellizer
230 lines (222 loc) • 5.88 kB
JavaScript
var async, common, debug, qs, randomstring, request;
async = require('async');
debug = require('debug')('loopback:satellizer:twitter');
qs = require('querystring');
request = require('request');
randomstring = require('randomstring');
common = require('../common');
module.exports = function(server, options) {
var Common, Model, callbackUrl, credentials, fetchAccessToken, fetchProfile, handleFirstRequest, link;
Common = common(server, options);
Model = server.models[options.model];
credentials = options.credentials;
callbackUrl = options.callbackUrl;
handleFirstRequest = function(callback) {
return request.post({
url: 'https://api.twitter.com/oauth/request_token',
oauth: {
consumer_key: credentials["public"],
consumer_secret: credentials["private"]
}
}, function(err, res, body) {
if (err) {
return callback(err);
}
return callback(null, qs.parse(body));
});
};
fetchAccessToken = function(oauthToken, oauthVerifier, callback) {
return request.post({
url: 'https://api.twitter.com/oauth/access_token',
oauth: {
consumer_key: credentials["public"],
consumer_secret: credentials["private"],
token: oauthToken,
verifier: oauthVerifier
}
}, function(err, res, accessToken) {
if (err) {
debug(JSON.stringify(err));
return callback(err);
}
if (res.statusCode !== 200) {
err = new Error(accessToken);
err.status = 500;
debug(JSON.stringify(err));
return callback(err);
}
return callback(null, qs.parse(accessToken));
});
};
fetchProfile = function(accessToken, callback) {
debug('fetchProfile');
return 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
}, function(err, res, profile) {
if (err) {
debug(JSON.stringify(err));
return callback(err);
}
if (res.statusCode !== 200) {
err = new Error(JSON.stringify(profile));
err.status = 500;
debug(JSON.stringify(err));
return callback(err);
}
return callback(null, profile);
});
};
link = function(req, profile, callback) {
debug('link');
return Common.current(req, function(err, found) {
var query;
if (err) {
debug(err);
return callback(err);
}
if (found === 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;
return Model.findOne(query, function(err, found) {
if (err) {
debug(err);
return callback(err);
}
if (!found) {
return link.create(profile, callback);
}
return link.existing(profile, found, callback);
});
});
};
link.create = function(profile, callback) {
var tmp;
debug('link.create', profile.id);
tmp = {
email: profile.id + "@twitter.com",
password: randomstring.generate()
};
Common.map(options.mapping, profile, tmp);
return Model.create(tmp, function(err, created) {
if (err) {
debug(err);
}
return callback(err, created);
});
};
link.existing = function(profile, account, callback) {
var err;
debug('link.existing');
if (account[options.mapping.id] && 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);
return account.save(function(err) {
if (err) {
debug(err);
}
return callback(err, account);
});
};
Model.twitter = function(req, oauthToken, oauthVerifier, callback) {
debug(oauthToken + ", " + oauthVerifier);
if (!oauthToken || !oauthVerifier) {
return handleFirstRequest(callback);
}
return async.waterfall([
function(done) {
return fetchAccessToken(oauthToken, oauthVerifier, done);
}, function(accessToken, done) {
return fetchProfile(accessToken, done);
}, function(profile, done) {
return link(req, profile, done);
}, function(account, done) {
return 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
}
});
};