Skip to content

Instantly share code, notes, and snippets.

@vivekgidmare
Created May 5, 2015 11:44
Show Gist options
  • Save vivekgidmare/8f2bcdbf6f7f02696363 to your computer and use it in GitHub Desktop.
Save vivekgidmare/8f2bcdbf6f7f02696363 to your computer and use it in GitHub Desktop.
Twitter auth
var exports = exports || this;
exports.Twitter = (function(global) {
var K = function() {
},
isAndroid = Ti.Platform.osname === "android",
jsOAuth = require('/twitter/jsOAuth-1.3.1');
// var utility = require("/utility");
var APP = require('utility');
// APP.Ui.showLoader('Loading...');
// APP.Ui.hideLoader();
/**
* Twitter constructor function
*
* var client = Twitter({
* consumerKey: "INSERT YOUR KEY HERE",
* consumerSecret: "INSERT YOUR SECRET HERE"
* });
*
* Can be used with or without `new` keyword.
*
* @constructor
* @requires jsOAuth: http://github.com/bytespider/jsOAuth
* @param options {Object} Configuration object
* @param options.consumerKey {String} Application consumer key
* @param options.consumerSecret {String} Application consumer secret
* @param options.accessTokenKey {String} (optional) The user's access token key
* @param options.accessTokenSecret {String} (optional) The user's access token secret
* @param [options.windowTitle="Twitter Authorization"] {String} (optional) The title to display in the authentication window
*/
var Twitter = function(options) {
var self;
if (this instanceof Twitter) {
self = this;
} else {
self = new K();
}
if (!options) {
options = {};
}
self.windowTitle = options.windowTitle || "Twitter Authorization";
self.consumerKey = options.consumerKey;
self.consumerSecret = options.consumerSecret;
self.authorizeUrl = "https://api.twitter.com/oauth/authorize";
self.accessTokenKey = options.accessTokenKey;
self.accessTokenSecret = options.accessTokenSecret;
self.authorized = false;
self.listeners = {};
if (self.accessTokenKey && self.accessTokenSecret) {
self.authorized = true;
}
options.requestTokenUrl = options.requestTokenUrl || "https://api.twitter.com/oauth/request_token";
self.oauthClient = jsOAuth.OAuth(options);
return self;
};
K.prototype = Twitter.prototype;
function createAuthWindow() {
var self = this,
oauth = this.oauthClient,
// webViewWindow = Ti.UI.createWindow({title: this.windowTitle}),
webViewWindow = Ti.UI.createWindow({
top : (OS_IOS) ? 20 : 30,
navBarHidden : true,
backgroundColor : '#7000',
orientationModes : [Titanium.UI.PORTRAIT]
}),
webView = Ti.UI.createWebView({
top : (OS_IOS) ? 10 : 20,
bottom : 5,
borderColor : 'white',
left : 5,
right : 5,
borderRadius : 5,
borderWidth : 3
}),
loadingOverlay = Ti.UI.createView({
backgroundColor : 'white',
top : (OS_IOS) ? 10 : 20,
opacity : (OS_IOS) ? 0.7 : 0.3,
left : 5,
right : 5,
zIndex : 1
}),
actInd = Titanium.UI.createActivityIndicator({
message : 'Loading...',
left : 30,
color : 'white'
}),
closeButton = Ti.UI.createButton({
backgroundImage : "/images/fb_twitter_close.png",
width : (OS_IOS) ? 30 : 40,
height : (OS_IOS) ? 30 : 40,
top : 0,
left : -3,
zIndex : 2
}),
backButton = Ti.UI.createButton({
title : "Back",
top : 20
});
this.webView = webView;
webViewWindow.leftNavButton = closeButton;
webViewWindow.add(loadingOverlay);
webViewWindow.open({
// modal : true
});
webViewWindow.add(webView);
webViewWindow.add(closeButton);
closeButton.addEventListener('click', function(e) {
webViewWindow.close();
APP.Ui.hideLoader();
self.fireEvent('cancel', {
success : false,
error : "The user cancelled.",
result : null
});
});
backButton.addEventListener('click', function(e) {
webView.goBack();
APP.Ui.hideLoader();
});
webView.addEventListener('beforeload', function(e) {
if (!isAndroid) {
webViewWindow.add(loadingOverlay);
}
actInd.show();
});
var webViewFirstLoad = true;
webView.addEventListener('load', function(event) {
// If we're not on the Twitter authorize page
if (event.url.indexOf(self.authorizeUrl) === -1) {
webViewWindow.remove(loadingOverlay);
actInd.hide();
// Required for Android
// Switch out close button for back button
if (webViewWindow.leftNavButton !== backButton) {
webViewWindow.leftNavButton = backButton;
}
} else {
// Switch out back button for close button
if (webViewWindow.leftNavButton !== closeButton) {
webViewWindow.leftNavButton = closeButton;
}
// Grab the PIN code out of the DOM
//Sort out android with version > 4.4.2
if (isAndroid && Ti.Platform.version >= '4.4.2') {
//Need to setup a collection method.
webViewWindow.remove(loadingOverlay);
actInd.hide();
if (!webViewFirstLoad) {
var promptView = Ti.UI.createView({
width : '90%',
height : '25%',
layout : "vertical",
backgroundColor : '#80000000',
bottom : "20%"
}),
pinField = Ti.UI.createTextField({
width : "70%",
font : {
fontSize : '20dp'
},
height : 40,
backgroundColor:'white',
color:'black',
hintText : 'Please Enter PIN'
}),
pinButton = Ti.UI.createButton({
width : "50%",
height :40,
top:10,
backgroundColor:'#4099FF',
color:'white',
title : "Authorize"
});
promptView.add(pinField);
promptView.add(pinButton);
webViewWindow.add(promptView);
pinButton.addEventListener('click', function() {
if (!pinField.value) {
alert('Please enter above PIN.');
} else {
var pin = pinField.value;
Ti.API.info('Pin :' + pin);
if (!isAndroid) {// on iOS we can close the modal window right away
mainWindow.close();
}
oauth.accessTokenUrl = "https://api.twitter.com/oauth/access_token?oauth_verifier=" + pin;
oauth.fetchAccessToken(function(data) {
var returnedParams = oauth.parseTokenRequest(data.text);
self.fireEvent('login', {
success : true,
error : false,
accessTokenKey : returnedParams.oauth_token,
accessTokenSecret : returnedParams.oauth_token_secret
});
if (isAndroid) {// we have to wait until now to close the modal window on Android: http://developer.appcelerator.com/question/91261/android-probelm-with-httpclient
webViewWindow.close();
}
}, function(data) {
self.fireEvent('login', {
success : false,
error : "Failure to fetch access token, please try again.",
result : data
});
});
}
});
} else {
webViewFirstLoad = false;
}
} else {
var pin = event.source.evalJS("document.getElementById('oauth_pin').getElementsByTagName('code')[0].innerText");
Ti.API.info('Pin :' + pin);
if (!pin) {
// We're here when:
// - "No thanks" button clicked
// - Bad username/password
webViewWindow.remove(loadingOverlay);
actInd.hide();
} else {
// if (!isAndroid) {// on iOS we can close the modal window right away
// webViewWindow.close();
// }
oauth.accessTokenUrl = "https://api.twitter.com/oauth/access_token?oauth_verifier=" + pin;
oauth.fetchAccessToken(function(data) {
var returnedParams = oauth.parseTokenRequest(data.text);
//Added by vivek
//Save oauth token and oauth token secret for parse use
Ti.App.Properties.setString("twitter_oauthToken", returnedParams.oauth_token);
Ti.App.Properties.setString("twitter_oauthTokenSecret", returnedParams.oauth_token_secret);
self.accessTokenKey = returnedParams.oauth_token;
self.accessTokenSecret = returnedParams.oauth_token_secret;
self.fireEvent('login', {
success : true,
error : false,
accessTokenKey : returnedParams.oauth_token,
accessTokenSecret : returnedParams.oauth_token_secret
});
Ti.API.info('Twitter Web Closed');
webViewWindow.close();
// utility.showIndicator("Authenticating...");
APP.Ui.showLoader('Loading...');
if (isAndroid) {// we have to wait until now to close the modal window on Android: http://developer.appcelerator.com/question/91261/android-probelm-with-httpclient
webViewWindow.close();
}
}, function(data) {
self.fireEvent('login', {
success : false,
error : "Failure to fetch access token, please try again.",
result : data
});
});
}
}
}
});
}
/*
* Requests the user to authorize via Twitter through a modal WebView.
*/
Twitter.prototype.authorize = function() {
var self = this;
if (this.authorized) {
// TODO: verify access tokens are still valid?
// We're putting this fireEvent call inside setTimeout to allow
// a user to add an event listener below the call to authorize.
// Not totally sure if the timeout should be greater than 1. It
// seems to do the trick on iOS/Android.
setTimeout(function() {
self.fireEvent('login', {
success : true,
error : false,
accessTokenKey : self.accessTokenKey,
accessTokenSecret : self.accessTokenSecret
});
}, 1);
} else {
createAuthWindow.call(this);
this.oauthClient.fetchRequestToken(function(requestParams) {
var authorizeUrl = self.authorizeUrl + requestParams;
self.webView.url = authorizeUrl;
}, function(data) {
self.fireEvent('login', {
success : false,
error : "Failure to fetch access token, please try again.",
result : data
});
});
}
};
Twitter.prototype.deauthorize = function(callback) {
Ti.API.info('this.authorized :' + (this.authorized));
if (this.authorized) {
self.accessTokenKey = "";
self.accessTokenSecret = "";
Ti.App.Properties.setString("twitter_oauthToken", "");
Ti.App.Properties.setString("twitter_oauthTokenSecret", "");
// execute the callback function
if ( typeof (callback) == 'function') {
callback(!authorized);
}
} else {
// execute the callback function
if ( typeof (callback) == 'function') {
callback(!authorized);
}
}
return !this.authorized;
};
/*
* Make an authenticated Twitter API request.
*
* @param {String} path the Twitter API path without leading forward slash. For example: `1/statuses/home_timeline.json`
* @param {Object} params the parameters to send along with the API call
* @param {String} [httpVerb="GET"] the HTTP verb to use
* @param {Function} callback
*/
Twitter.prototype.request = function(path, params, httpVerb, callback) {
var self = this,
oauth = this.oauthClient,
url = "https://api.twitter.com/" + path;
oauth.request({
method : httpVerb,
url : url,
data : params,
success : function(data) {
callback.call(self, {
success : true,
error : false,
result : data
});
},
failure : function(data) {
callback.call(self, {
success : false,
error : "Request failed",
result : data
});
}
});
};
/*
* Add an event listener
*/
Twitter.prototype.addEventListener = function(eventName, callback) {
this.listeners = this.listeners || {};
this.listeners[eventName] = this.listeners[eventName] || [];
this.listeners[eventName].push(callback);
};
/*
* Fire an event
*/
Twitter.prototype.fireEvent = function(eventName, data) {
var eventListeners = this.listeners[eventName] || [];
for (var i = 0; i < eventListeners.length; i++) {
eventListeners[i].call(this, data);
}
};
return Twitter;
})(this);
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment