Skip to content

Instantly share code, notes, and snippets.

@rampicos
Last active January 10, 2019 10:10
Show Gist options
  • Save rampicos/4320296 to your computer and use it in GitHub Desktop.
Save rampicos/4320296 to your computer and use it in GitHub Desktop.
Social.js is the Appcelerator Titanium's Alloy Widget at first it is used to connect with Twitter only, though twitter and linkedin uses OAuth for its authentication I made some changes on Social.js for multi-purpose to connect Twitter and LinkedIn
function hex_sha1(s) {
return binb2hex(core_sha1(str2binb(s), s.length * chrsz));
}
function b64_sha1(s) {
return binb2b64(core_sha1(str2binb(s), s.length * chrsz));
}
function str_sha1(s) {
return binb2str(core_sha1(str2binb(s), s.length * chrsz));
}
function hex_hmac_sha1(key, data) {
return binb2hex(core_hmac_sha1(key, data));
}
function b64_hmac_sha1(key, data) {
return binb2b64(core_hmac_sha1(key, data));
}
function str_hmac_sha1(key, data) {
return binb2str(core_hmac_sha1(key, data));
}
function sha1_vm_test() {
return hex_sha1("abc") == "a9993e364706816aba3e25717850c26c9cd0d89d";
}
function core_sha1(x, len) {
x[len >> 5] |= 128 << 24 - len % 32, x[(len + 64 >> 9 << 4) + 15] = len;
var w = Array(80), a = 1732584193, b = -271733879, c = -1732584194, d = 271733878, e = -1009589776;
for (var i = 0; i < x.length; i += 16) {
var olda = a, oldb = b, oldc = c, oldd = d, olde = e;
for (var j = 0; j < 80; j++) {
j < 16 ? w[j] = x[i + j] : w[j] = rol(w[j - 3] ^ w[j - 8] ^ w[j - 14] ^ w[j - 16], 1);
var t = safe_add(safe_add(rol(a, 5), sha1_ft(j, b, c, d)), safe_add(safe_add(e, w[j]), sha1_kt(j)));
e = d, d = c, c = rol(b, 30), b = a, a = t;
}
a = safe_add(a, olda), b = safe_add(b, oldb), c = safe_add(c, oldc), d = safe_add(d, oldd), e = safe_add(e, olde);
}
return Array(a, b, c, d, e);
}
function sha1_ft(t, b, c, d) {
return t < 20 ? b & c | ~b & d : t < 40 ? b ^ c ^ d : t < 60 ? b & c | b & d | c & d : b ^ c ^ d;
}
function sha1_kt(t) {
return t < 20 ? 1518500249 : t < 40 ? 1859775393 : t < 60 ? -1894007588 : -899497514;
}
function core_hmac_sha1(key, data) {
var bkey = str2binb(key);
bkey.length > 16 && ( bkey = core_sha1(bkey, key.length * chrsz));
var ipad = Array(16), opad = Array(16);
for (var i = 0; i < 16; i++)
ipad[i] = bkey[i] ^ 909522486, opad[i] = bkey[i] ^ 1549556828;
var hash = core_sha1(ipad.concat(str2binb(data)), 512 + data.length * chrsz);
return core_sha1(opad.concat(hash), 672);
}
function safe_add(x, y) {
var lsw = (x & 65535) + (y & 65535), msw = (x >> 16) + (y >> 16) + (lsw >> 16);
return msw << 16 | lsw & 65535;
}
function rol(num, cnt) {
return num << cnt | num >>> 32 - cnt;
}
function str2binb(str) {
var bin = Array(), mask = (1 << chrsz) - 1;
for (var i = 0; i < str.length * chrsz; i += chrsz)
bin[i >> 5] |= (str.charCodeAt(i / chrsz) & mask) << 32 - chrsz - i % 32;
return bin;
}
function binb2str(bin) {
var str = "", mask = (1 << chrsz) - 1;
for (var i = 0; i < bin.length * 32; i += chrsz)
str += String.fromCharCode(bin[i >> 5] >>> 32 - chrsz - i % 32 & mask);
return str;
}
function binb2hex(binarray) {
var hex_tab = hexcase ? "0123456789ABCDEF" : "0123456789abcdef", str = "";
for (var i = 0; i < binarray.length * 4; i++)
str += hex_tab.charAt(binarray[i >> 2] >> (3 - i % 4) * 8 + 4 & 15) + hex_tab.charAt(binarray[i >> 2] >> (3 - i % 4) * 8 & 15);
return str;
}
function binb2b64(binarray) {
var tab = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/", str = "";
for (var i = 0; i < binarray.length * 4; i += 3) {
var triplet = (binarray[i >> 2] >> 8 * (3 - i % 4) & 255) << 16 | (binarray[i + 1 >> 2] >> 8 * (3 - (i + 1) % 4) & 255) << 8 | binarray[i + 2 >> 2] >> 8 * (3 - (i + 2) % 4) & 255;
for (var j = 0; j < 4; j++)
i * 8 + j * 6 > binarray.length * 32 ? str += b64pad : str += tab.charAt(triplet >> 6 * (3 - j) & 63);
}
return str;
}
var hexcase = 0, b64pad = "", chrsz = 8, OAuth;
OAuth == null && ( OAuth = {}), OAuth.setProperties = function(into, from) {
if (into != null && from != null)
for (var key in from)
into[key] = from[key];
return into;
}, OAuth.setProperties(OAuth, {
percentEncode : function(s) {
if (s == null)
return "";
if ( s instanceof Array) {
var e = "";
for (var i = 0; i < s.length; ++s)
e != "" && (e += "&"), e += OAuth.percentEncode(s[i]);
return e;
}
return s = encodeURIComponent(s), s = s.replace(/\!/g, "%21"), s = s.replace(/\*/g, "%2A"), s = s.replace(/\'/g, "%27"), s = s.replace(/\(/g, "%28"), s = s.replace(/\)/g, "%29"), s;
},
decodePercent : function(s) {
return s != null && ( s = s.replace(/\+/g, " ")), decodeURIComponent(s);
},
getParameterList : function(parameters) {
if (parameters == null)
return [];
if ( typeof parameters != "object")
return OAuth.decodeForm(parameters + "");
if ( parameters instanceof Array)
return parameters;
var list = [];
for (var p in parameters)
list.push([p, parameters[p]]);
return list;
},
getParameterMap : function(parameters) {
if (parameters == null)
return {};
if ( typeof parameters != "object")
return OAuth.getParameterMap(OAuth.decodeForm(parameters + ""));
if ( parameters instanceof Array) {
var map = {};
for (var p = 0; p < parameters.length; ++p) {
var key = parameters[p][0];
map[key] === undefined && (map[key] = parameters[p][1]);
}
return map;
}
return parameters;
},
getParameter : function(parameters, name) {
if ( parameters instanceof Array) {
for (var p = 0; p < parameters.length; ++p)
if (parameters[p][0] == name)
return parameters[p][1];
return null;
}
return OAuth.getParameterMap(parameters)[name];
},
formEncode : function(parameters) {
var form = "", list = OAuth.getParameterList(parameters);
for (var p = 0; p < list.length; ++p) {
var value = list[p][1];
value == null && ( value = ""), form != "" && (form += "&"), form += OAuth.percentEncode(list[p][0]) + "=" + OAuth.percentEncode(value);
}
return form;
},
decodeForm : function(form) {
var list = [], nvps = form.split("&");
for (var n = 0; n < nvps.length; ++n) {
var nvp = nvps[n];
if (nvp == "")
continue;
var equals = nvp.indexOf("="), name, value;
equals < 0 ? ( name = OAuth.decodePercent(nvp), value = null) : ( name = OAuth.decodePercent(nvp.substring(0, equals)), value = OAuth.decodePercent(nvp.substring(equals + 1))), list.push([name, value]);
}
return list;
},
setParameter : function(message, name, value) {
var parameters = message.parameters;
if ( parameters instanceof Array) {
for (var p = 0; p < parameters.length; ++p)
parameters[p][0] == name && (value === undefined ? parameters.splice(p, 1) : (parameters[p][1] = value, value = undefined));
value !== undefined && parameters.push([name, value]);
} else
parameters = OAuth.getParameterMap(parameters), parameters[name] = value, message.parameters = parameters;
},
setParameters : function(message, parameters) {
var list = OAuth.getParameterList(parameters);
for (var i = 0; i < list.length; ++i)
OAuth.setParameter(message, list[i][0], list[i][1]);
},
completeRequest : function(message, accessor) {
message.method == null && (message.method = "GET");
var map = OAuth.getParameterMap(message.parameters);
map.oauth_consumer_key == null && OAuth.setParameter(message, "oauth_consumer_key", accessor.consumerKey || ""), map.oauth_token == null && accessor.token != null && OAuth.setParameter(message, "oauth_token", accessor.token), map.oauth_version == null && OAuth.setParameter(message, "oauth_version", "1.0"), map.oauth_timestamp == null && OAuth.setParameter(message, "oauth_timestamp", OAuth.timestamp()), map.oauth_nonce == null && OAuth.setParameter(message, "oauth_nonce", OAuth.nonce(6)), OAuth.SignatureMethod.sign(message, accessor);
},
setTimestampAndNonce : function(message) {
OAuth.setParameter(message, "oauth_timestamp", OAuth.timestamp()), OAuth.setParameter(message, "oauth_nonce", OAuth.nonce(6));
},
addToURL : function(url, parameters) {
newURL = url;
if (parameters != null) {
var toAdd = OAuth.formEncode(parameters);
if (toAdd.length > 0) {
var q = url.indexOf("?");
q < 0 ? newURL += "?" : newURL += "&", newURL += toAdd;
}
}
return newURL;
},
getAuthorizationHeader : function(realm, parameters) {
var header = "OAuth ", list = OAuth.getParameterList(parameters);
for (var p = 0; p < list.length; ++p) {
var parameter = list[p], name = parameter[0];
name.indexOf("oauth_") == 0 && (header += OAuth.percentEncode(name) + "=\"" + OAuth.percentEncode(parameter[1]) + "\"");
if (p != list.length - 1) {
header += ", ";
}
}
return header;
},
correctTimestampFromSrc : function(parameterName) {
parameterName = parameterName || "oauth_timestamp";
var scripts = document.getElementsByTagName("script");
if (scripts == null || !scripts.length)
return;
var src = scripts[scripts.length - 1].src;
if (!src)
return;
var q = src.indexOf("?");
if (q < 0)
return;
parameters = OAuth.getParameterMap(OAuth.decodeForm(src.substring(q + 1)));
var t = parameters[parameterName];
if (t == null)
return;
OAuth.correctTimestamp(t);
},
correctTimestamp : function(timestamp) {
OAuth.timeCorrectionMsec = timestamp * 1000 - (new Date).getTime();
},
timeCorrectionMsec : 0,
timestamp : function() {
var t = (new Date).getTime() + OAuth.timeCorrectionMsec;
return "" + Math.floor(t / 1000);
},
nonce : function(length) {
var chars = OAuth.nonce.CHARS, result = "";
for (var i = 0; i < length; ++i) {
var rnum = Math.floor(Math.random() * chars.length);
result += chars.substring(rnum, rnum + 1);
}
return result;
}
}), OAuth.nonce.CHARS = "0123456789ABCDEFGHIJKLMNOPQRSTUVWXTZabcdefghiklmnopqrstuvwxyz", OAuth.declareClass = function(parent, name, newConstructor) {
var previous = parent[name];
parent[name] = newConstructor;
if (newConstructor != null && previous != null)
for (var key in previous)key != "prototype" && (newConstructor[key] = previous[key]);
return newConstructor;
}, OAuth.declareClass(OAuth, "SignatureMethod", function() {
}), OAuth.setProperties(OAuth.SignatureMethod.prototype, {
sign : function(message) {
var baseString = OAuth.SignatureMethod.getBaseString(message), signature = this.getSignature(baseString);
return OAuth.setParameter(message, "oauth_signature", signature), signature;
},
initialize : function(name, accessor) {
var consumerSecret;
accessor.accessorSecret != null && name.length > 9 && name.substring(name.length - 9) == "-Accessor" ? consumerSecret = accessor.accessorSecret : consumerSecret = accessor.consumerSecret, this.key = OAuth.percentEncode(consumerSecret) + "&" + OAuth.percentEncode(accessor.tokenSecret);
}
}), OAuth.setProperties(OAuth.SignatureMethod, {
sign : function(message, accessor) {
var name = OAuth.getParameterMap(message.parameters).oauth_signature_method;
if (name == null || name == "")
name = "HMAC-SHA1", OAuth.setParameter(message, "oauth_signature_method", name);
OAuth.SignatureMethod.newMethod(name, accessor).sign(message);
},
newMethod : function(name, accessor) {
var impl = OAuth.SignatureMethod.REGISTERED[name];
if (impl != null) {
var method = new impl;
return method.initialize(name, accessor), method;
}
var err = new Error("signature_method_rejected"), acceptable = "";
for (var r in OAuth.SignatureMethod.REGISTERED)acceptable != "" && (acceptable += "&"), acceptable += OAuth.percentEncode(r);
throw err.oauth_acceptable_signature_methods = acceptable, err;
},
REGISTERED : {},
registerMethodClass : function(names, classConstructor) {
for (var n = 0; n < names.length; ++n)
OAuth.SignatureMethod.REGISTERED[names[n]] = classConstructor;
},
makeSubclass : function(getSignatureFunction) {
var superClass = OAuth.SignatureMethod, subClass = function() {
superClass.call(this);
};
return subClass.prototype = new superClass, subClass.prototype.getSignature = getSignatureFunction, subClass.prototype.constructor = subClass, subClass;
},
getBaseString : function(message) {
var URL = message.action, q = URL.indexOf("?"), parameters;
if (q < 0)
parameters = message.parameters;
else {
parameters = OAuth.decodeForm(URL.substring(q + 1));
var toAdd = OAuth.getParameterList(message.parameters);
for (var a = 0; a < toAdd.length; ++a)
parameters.push(toAdd[a]);
}
return OAuth.percentEncode(message.method.toUpperCase()) + "&" + OAuth.percentEncode(OAuth.SignatureMethod.normalizeUrl(URL)) + "&" + OAuth.percentEncode(OAuth.SignatureMethod.normalizeParameters(parameters));
},
normalizeUrl : function(url) {
var uri = OAuth.SignatureMethod.parseUri(url), scheme = uri.protocol.toLowerCase(), authority = uri.authority.toLowerCase(), dropPort = scheme == "http" && uri.port == 80 || scheme == "https" && uri.port == 443;
if (dropPort) {
var index = authority.lastIndexOf(":");
index >= 0 && ( authority = authority.substring(0, index));
}
var path = uri.path;
return path || ( path = "/"), scheme + "://" + authority + path;
},
parseUri : function(str) {
var o = {
key : ["source", "protocol", "authority", "userInfo", "user", "password", "host", "port", "relative", "path", "directory", "file", "query", "anchor"],
parser : {
strict : /^(?:([^:\/?#]+):)?(?:\/\/((?:(([^:@\/]*):?([^:@\/]*))?@)?([^:\/?#]*)(?::(\d*))?))?((((?:[^?#\/]*\/)*)([^?#]*))(?:\?([^#]*))?(?:#(.*))?)/
}
}, m = o.parser.strict.exec(str), uri = {}, i = 14;
while (i--)
uri[o.key[i]] = m[i] || "";
return uri;
},
normalizeParameters : function(parameters) {
if (parameters == null)
return "";
var list = OAuth.getParameterList(parameters), sortable = [];
for (var p = 0; p < list.length; ++p) {
var nvp = list[p];
nvp[0] != "oauth_signature" && sortable.push([OAuth.percentEncode(nvp[0]) + " " + OAuth.percentEncode(nvp[1]), nvp]);
}
sortable.sort(function(a, b) {
return a[0] < b[0] ? -1 : a[0] > b[0] ? 1 : 0;
});
var sorted = [];
for (var s = 0; s < sortable.length; ++s)
sorted.push(sortable[s][1]);
return OAuth.formEncode(sorted);
}
}), OAuth.SignatureMethod.registerMethodClass(["PLAINTEXT", "PLAINTEXT-Accessor"], OAuth.SignatureMethod.makeSubclass(function(baseString) {
return this.key;
})), OAuth.SignatureMethod.registerMethodClass(["HMAC-SHA1", "HMAC-SHA1-Accessor"], OAuth.SignatureMethod.makeSubclass(function(baseString) {
b64pad = "=";
var signature = b64_hmac_sha1(this.key, baseString);
return signature;
}));
try {
OAuth.correctTimestampFromSrc();
} catch (e) {
}
var OAuthAdapter = function(pConsumerSecret, pConsumerKey, pSignatureMethod) {
var fromSite;
function showLoading() {
if (loading)
return;
loading = !0, loadingView.value = 0, estimateID = firstLoad ? "tokenRequest" : "pageLoad", estimates[estimateID] || (estimates[estimateID] = firstLoad ? 2000 : 1000), firstLoad = !1, startTime = (new Date).getTime(), intervalID = setInterval(updateProgress, 30), webView && webView.hide(), loadingView && loadingView.show(), loadingContainer && loadingContainer.show();
}
function updateProgress() {
loadingView && (loadingView.value = ((new Date).getTime() - startTime) / estimates[estimateID]);
}
function authorizeUICallback(e) {
if (e.url.indexOf('linkedin') !== -1) {
fromSite = 'linkedin';
var response = e.source.evalJS("(p = document.getElementsByClassName(\"access-code\")) && p[0].innerHTML");
response ? ( pin = response, destroyAuthorizeUI(e.cb, true), receivePinCallback()) : (loadingView && loadingView.hide(), loadingContainer && loadingContainer.hide(), webView && webView.show()), loading = !1, clearInterval(intervalID), estimates[estimateID] = (new Date).getTime() - startTime, Ti.App.Properties.setString("Social-LoadingEstimates", JSON.stringify(estimates));
} else if (e.url.indexOf('twitter') !== -1) {
// 'Login your twitter account for authorize Shukran application and you will get PIN above.Please enter PIN for complete the authorization.'
fromSite = 'twitter';
Ti.API.info('authorizeUICallback URL ='+e.url);
if((Titanium.Platform.osname == 'android') && Ti.Platform.version >= '4.4.2'){
var promptView = Ti.UI.createView({
width:'90%',
height:'0dp',
layout: "vertical",
backgroundColor:'#52D3FE',
bottom:"15dp"
}),
pinLabel = Ti.UI.createLabel({
top : '5dp',
width: '90%',
font : {
fontSize : '16sp',
fontWeight : 'normal'
},
height: Ti.UI.SIZE,
color :"#FFF",
text : 'Login above and enter the PIN here to authorize'
}),
pinField = Ti.UI.createTextField({
top : '5dp',
color : '#000000',
backgroundColor : "#FFF",
font : {
fontSize : '15sp',
fontWeight : 'normal'
},
keyboardType : Titanium.UI.KEYBOARD_NUMBERS_PUNCTUATION,
height : "35dp",
width : '90%',
hintText : "Enter Pin",
autocorrect:false
}),
pinButton = Ti.UI.createButton({
width: Ti.UI.SIZE,
height: Ti.UI.SIZE,
title: "Authorize"
});
//promptView.add(pinLabel);
promptView.add(pinField);
promptView.add(pinButton);
window.add(promptView);
if(e.url.indexOf('?') !== -1){
promptView.height = 0 ;
}else{
promptView.height = Ti.UI.SIZE ;
}
pinButton.addEventListener('click', function() {
if (!pinField.value) {
alert('No PIN entered');
} else {
pin = pinField.value;
destroyAuthorizeUI(e.cb, true), receivePinCallback();
}
});
}
else{
var response = e.source.evalJS("(p = document.getElementById(\"oauth_pin\")) && p.innerHTML;");
response ? ( pin = response.split("<code>")[1].split("</code>")[0], destroyAuthorizeUI(e.cb, true), receivePinCallback()) : (loadingView && loadingView.hide(), loadingContainer && loadingContainer.hide(), webView && webView.show()), loading = !1, clearInterval(intervalID), estimates[estimateID] = (new Date).getTime() - startTime, Ti.App.Properties.setString("Social-LoadingEstimates", JSON.stringify(estimates));
}
}
}
var consumerSecret = pConsumerSecret, consumerKey = pConsumerKey, signatureMethod = pSignatureMethod, pin = null, requestToken = null, requestTokenSecret = null, accessToken = null, accessTokenSecret = null, accessor = {
consumerSecret : consumerSecret,
tokenSecret : ""
}, window = null, view = null, webView = null, loadingView = null, loadingContainer = null, receivePinCallback = null, accessTokenStore = {};
this.sendTwitterImage = function(options) {
var pUrl = "http://upload.twitter.com/1/statuses/update_with_media.json";
var pTitle = options.title;
var pSuccessMessage = options.onSuccess, pErrorMessage = options.onError;
if (accessToken == null || accessTokenSecret == null) {
Ti.API.debug("The send status cannot be processed as the client doesn't have an access token. Authorize before trying to send.");
return;
}
accessor.tokenSecret = accessTokenSecret;
var message = createMessage(pUrl);
message.parameters.push(["oauth_token", accessToken]);
message.parameters.push(["oauth_timestamp", OAuth.timestamp()]);
message.parameters.push(["oauth_nonce", OAuth.nonce(42)]);
message.parameters.push(["oauth_version", "1.0"]);
OAuth.SignatureMethod.sign(message, accessor);
var parameterMap = OAuth.getParameterMap(message.parameters);
client = Ti.Network.createHTTPClient({
onload : function() {
if (client.status == 200) {
pSuccessMessage && pSuccessMessage(this.responseText);
} else {
pErrorMessage && pErrorMessage(this.responseText);
}
},
onerror : function() {
Ti.API.error("Social.js: FAILED to send a request!");
Ti.API.error(this.responseText);
pErrorMessage && pErrorMessage(this.responseText);
}
});
client.open("POST", pUrl);
header = OAuth.getAuthorizationHeader(pUrl, message.parameters);
client.setRequestHeader("Authorization", header);
if (!Ti.Android) {
client.setRequestHeader("Content-Type", "multipart/form-data");
}
client.send(options.params);
}, this.loadAccessToken = function(pService) {
var token;
if (accessTokenStore[pService])
token = accessTokenStore[pService];
else {
var raw = Ti.App.Properties.getString("Social.js-AccessToken-" + pService, "");
if (!raw)
return;
try {
token = accessTokenStore[pService] = JSON.parse(raw);
} catch (err) {
Ti.API.error("Failed to parse stored access token for " + pService + "!"), Ti.API.error(err);
return;
}
}
token.accessToken && ( accessToken = token.accessToken), token.accessTokenSecret && ( accessTokenSecret = token.accessTokenSecret);
}, this.saveAccessToken = function(pService) {
if (fromSite == "linkedin") {
if (Ti.App.Properties.linkedinButton) {
Ti.App.Properties.linkedinButton.text = (Ti.App.Properties.getString("userLanguage") == 'ar') ? L('disconnect_ar') : "DISCONNECT";
Ti.App.Properties.linkedinButton.backgroundImage = config.getImagePathFromInner('contact_us_bg.png');
}
} else {
if (Ti.App.Properties.twitterButton) {
Ti.App.Properties.twitterButton.image = icons.disconnectButton;
Ti.App.Properties.twitterImage.image = icons.twitterOn;
}
}
accessTokenStore[pService] = {
accessToken : accessToken,
accessTokenSecret : accessTokenSecret
}, Ti.App.Properties.setString("Social.js-AccessToken-" + pService, JSON.stringify(accessTokenStore[pService]));
}, this.clearAccessToken = function(pService) {
if (fromSite == "linkedin") {
if (Ti.App.Properties.linkedinButton) {
Ti.App.Properties.linkedinButton.text = (Ti.App.Properties.getString("userLanguage") == 'ar') ? L('connect_ar') : 'CONNECT';
Ti.App.Properties.linkedinButton.backgroundImage = config.getImagePathFromInner('connect_bg.png');
}
} else {
if (Ti.App.Properties.twitterButton) {
Ti.App.Properties.twitterButton.image = (Ti.App.Properties.getString("userLanguage", "en") == "en") ? icons.connectButton : icons.connectButton_ar;
Ti.App.Properties.twitterImage.image = icons.twitterOff;
}
}
delete accessTokenStore[pService], Ti.App.Properties.setString("Social.js-AccessToken-" + pService, null), accessToken = null, accessTokenSecret = null;
}, this.isAuthorized = function() {
return accessToken != null && accessTokenSecret != null;
};
var createMessage = function(pUrl) {
var message = {
action : pUrl,
method : "POST",
parameters : []
};
return message.parameters.push(["oauth_consumer_key", consumerKey]), message.parameters.push(["oauth_signature_method", signatureMethod]), message;
};
this.getPin = function() {
return pin;
}, this.getRequestToken = function(pUrl, callback) {
accessor.tokenSecret = "";
var message = createMessage(pUrl);
OAuth.setTimestampAndNonce(message), OAuth.SignatureMethod.sign(message, accessor);
var done = !1, client = Ti.Network.createHTTPClient({
onload : function() {
var responseParams = OAuth.getParameterMap(this.responseText);
requestToken = responseParams.oauth_token, requestTokenSecret = responseParams.oauth_token_secret, callback({
success : !0,
token : this.responseText
}), done = !0;
},
onerror : function() {
Ti.API.error("Social.js: FAILED to getRequestToken!"), Ti.API.error(this.responseText), callback({
success : !1
}), done = !0;
}
});
client.open("POST", pUrl), client.send(OAuth.getParameterMap(message.parameters));
};
var destroyAuthorizeUI = function(cb, bool) {
if (window == null)
return;
try {
webView.removeEventListener("load", authorizeUICallback), webView.removeEventListener("beforeload", showLoading), loadingView.hide(), window.close(), loading = null, webView = null, loadingView = null, loading = !1, firstLoad = !0, view = null, window = null;
cb(bool);
} catch (ex) {
Ti.API.debug("Cannot destroy the authorize UI. Ignoring.");
}
Ti.App.Properties.setBool("webviewActive", false);
}, firstLoad = !0, loading = !1, estimates = JSON.parse(Ti.App.Properties.getString("Social-LoadingEstimates", "{}")), estimateID, startTime, intervalID = 0;
this.closeWebView = function(cb) {
destroyAuthorizeUI();
}, this.showLoadingUI = function(cb) {
Ti.App.Properties.setBool("webviewActive", true);
window = Ti.UI.createWindow({
backgroundColor : "transparent",
zIndex : 1000,
windowSoftInputMode : Ti.Android ? Ti.UI.Android.SOFT_INPUT_ADJUST_PAN : null
}), Ti.Android || (window.opacity = 0, window.transform = Ti.UI.create2DMatrix().scale(0)), view = Ti.UI.createView({
top : 10,
right : 10,
bottom : 10,
left : 10,
backgroundColor : "#52D3FE",
border : 10,
borderColor : "#52D3FE",
borderRadius : 10,
borderWidth : 4,
zIndex : -1
});
var closeLabel = Ti.UI.createButton({
font : {
fontSize : 11,
fontWeight : "bold"
},
backgroundColor : "#52D3FE",
borderColor : "#52D3FE",
color : "#fff",
style : 0,
borderRadius : 6,
title : "X",
top : 8,
right : 8,
width : 30,
height : 30
});
closeLabel.addEventListener("click", function() {
destroyAuthorizeUI(cb, false);
}), window.open();
var offset = 0;
Ti.Android && ( offset = "10dp"), loadingContainer = Ti.UI.createView({
top : offset,
right : offset,
bottom : offset,
left : offset,
backgroundColor : "#fff"
}), loadingView = Ti.UI.createProgressBar({
top : 10,
right : 10,
bottom : 10,
left : 10,
min : 0,
max : 1,
value : 0.5,
message : "Loading, please wait.",
backgroundColor : "#fff",
font : {
fontSize : 14,
fontWeight : "bold"
},
style : 0
}), view.add(loadingContainer), loadingContainer.add(loadingView), loadingView.show(), window.add(view), window.add(closeLabel);
if (!Ti.Android) {
var tooBig = Ti.UI.createAnimation({
transform : Ti.UI.create2DMatrix().scale(1.1),
opacity : 1,
duration : 350
}), shrinkBack = Ti.UI.createAnimation({
transform : Ti.UI.create2DMatrix(),
duration : 400
});
tooBig.addEventListener("complete", function() {
window.animate(shrinkBack);
}), window.animate(tooBig);
}
showLoading();
}, this.showAuthorizeUI = function(pUrl, pReceivePinCallback, pCB) {
receivePinCallback = pReceivePinCallback;
var offset = 0;
Ti.Android && ( offset = "10dp"), webView = Ti.UI.createWebView({
url : pUrl,
top : offset,
right : offset,
bottom : offset,
left : offset,
autoDetect : [Ti.UI.AUTODETECT_NONE],
//softKeyboardOnFocus: Titanium.UI.Android.SOFT_KEYBOARD_HIDE_ON_FOCUS,
cb : pCB
}), webView.addEventListener("beforeload", showLoading), webView.addEventListener("load", authorizeUICallback), view.add(webView);
//webView.focus();
if (Ti.Android) {
webView.softKeyboardOnFocus = Titanium.UI.Android.SOFT_KEYBOARD_HIDE_ON_FOCUS;
webView.focus();
}
}, this.getAccessToken = function(pUrl, callback) {
accessor.tokenSecret = requestTokenSecret;
var message = createMessage(pUrl);
message.parameters.push(["oauth_token", requestToken]), message.parameters.push(["oauth_verifier", pin]), OAuth.setTimestampAndNonce(message), OAuth.SignatureMethod.sign(message, accessor);
var parameterMap = OAuth.getParameterMap(message.parameters), client = Ti.Network.createHTTPClient({
onload : function() {
var responseParams = OAuth.getParameterMap(this.responseText);
accessToken = responseParams.oauth_token, accessTokenSecret = responseParams.oauth_token_secret, callback({
success : !0
});
},
onerror : function() {
Ti.API.error("Social.js: FAILED to getAccessToken!"), Ti.API.error(this.responseText), callback({
success : !1
});
}
});
client.open("POST", pUrl), client.send(parameterMap);
}, this.getProfileLinkedin = function(options) {
var pUrl = "http://api.linkedin.com/v1/people/~?format=json";
var pSuccessMessage = options.onSuccess;
var pErrorMessage = options.onError;
accessor.tokenSecret = accessTokenSecret;
var message = createMessage(pUrl);
message.method = 'get';
message.parameters.push(["oauth_nonce", OAuth.nonce(42)]);
message.parameters.push(["oauth_timestamp", OAuth.timestamp()]);
message.parameters.push(["oauth_token", accessToken]);
message.parameters.push(["oauth_version", "1.0"]);
OAuth.SignatureMethod.sign(message, accessor);
var parameterMap = OAuth.getParameterMap(message.parameters);
client = Ti.Network.createHTTPClient({
onload : function() {
if (client.status == 200) {
pSuccessMessage && pSuccessMessage(this.responseText);
} else {
pErrorMessage && pErrorMessage(this.responseText);
}
},
onerror : function() {
Ti.API.error("Social.js: FAILED to send a request!");
Ti.API.error(this.responseText);
pErrorMessage && pErrorMessage(this.responseText);
}
});
client.open("GET", pUrl);
header = OAuth.getAuthorizationHeader("", message.parameters);
client.setRequestHeader("Authorization", header);
client.send();
}, this.shareLinkedin = function(options) {
var pUrl = "http://api.linkedin.com/v1/people/~/shares";
var pSuccessMessage = options.onSuccess;
var pErrorMessage = options.onError;
accessor.tokenSecret = accessTokenSecret;
var message = createMessage(pUrl);
//used to get Oauth sig, do not change
message.parameters.push(["oauth_nonce", OAuth.nonce(42)]);
message.parameters.push(["oauth_timestamp", OAuth.timestamp()]);
message.parameters.push(["oauth_token", accessToken]);
message.parameters.push(["oauth_version", "1.0"]);
OAuth.SignatureMethod.sign(message, accessor);
client = Ti.Network.createHTTPClient({
onload : function() {
if (client.status == 200 || client.status == 201) {
pSuccessMessage && pSuccessMessage(this.responseText);
} else {
pErrorMessage && pErrorMessage(this.responseText);
}
},
onerror : function() {
Ti.API.error("Social.js: FAILED to send a request!");
Ti.API.error(this.responseText);
pErrorMessage && pErrorMessage(this.responseText);
}
});
client.open("POST", pUrl);
header = OAuth.getAuthorizationHeader("", message.parameters);
client.setRequestHeader("Content-Type", "application/json");
client.setRequestHeader("x-li-format", "json");
client.setRequestHeader("Authorization", header);
var payload = JSON.stringify(options.parameters);
client.send(payload);
}, this.send = function(options, callback) {
var pUrl = options.url, pParameters = options.parameters, pTitle = options.title, pSuccessMessage = options.onSuccess, pErrorMessage = options.onError;
if (accessToken == null || accessTokenSecret == null) {
Ti.API.debug("The send status cannot be processed as the client doesn't have an access token. Authorize before trying to send.");
return;
}
accessor.tokenSecret = accessTokenSecret;
var message = createMessage(pUrl);
message.parameters.push(["oauth_token", accessToken]);
for (p in pParameters)
message.parameters.push(pParameters[p]);
OAuth.setTimestampAndNonce(message), OAuth.SignatureMethod.sign(message, accessor);
var parameterMap = OAuth.getParameterMap(message.parameters), client = Ti.Network.createHTTPClient({
onload : function() {
client.status == 200 ? pSuccessMessage && pSuccessMessage(this.responseText) : pErrorMessage && pErrorMessage(this.responseText);
},
onerror : function() {
Ti.API.error("Social.js: FAILED to send a request!"), pErrorMessage && pErrorMessage(this.responseText);
}
});
client.open("POST", pUrl), client.send(parameterMap);
};
}, supportedSites = {
twitter : {
accessToken : "https://api.twitter.com/oauth/access_token",
requestToken : "https://api.twitter.com/oauth/request_token",
authorize : "https://api.twitter.com/oauth/authorize?",
update : "https://api.twitter.com/1.1/statuses/update.json"
},
linkedin : {
accessToken : "https://api.linkedin.com/uas/oauth/accessToken",
requestToken : "https://api.linkedin.com/uas/oauth/requestToken?scope=w_share",
authorize : "https://api.linkedin.com/uas/oauth/authorize?",
update : "http://api.linkedin.com/v1/people/~/shares?format=json"
}
};
exports.create = function(settings) {
var site = (settings.site || "twitter").toLowerCase(), adapter = new OAuthAdapter(settings.consumerSecret, settings.consumerKey, "HMAC-SHA1");
adapter.loadAccessToken(site);
var urls = supportedSites[site];
return urls == null ? (alert("The Social.js module does not support " + site + " yet!"), null) : {
isAuthorized : function() {
return adapter.isAuthorized();
},
deauthorize : function() {
adapter.clearAccessToken(site);
},
closeWin : function() {
adapter.closeWebView();
},
authorize : function(callback) {
if (!adapter.isAuthorized()) {
function receivePin() {
adapter.getAccessToken(urls.accessToken, function(evt) {
evt.success ? (adapter.saveAccessToken(site), callback && callback()) : alert("Did not get access token now!");
});
}
adapter.showLoadingUI(settings.cb), adapter.getRequestToken(urls.requestToken, function(evt) {
evt.success ? adapter.showAuthorizeUI(urls.authorize + evt.token, receivePin, settings.cb) : alert("Did not get access token now!");
});
} else
callback && callback();
},
shareImage : function(options) {
this.authorize(function() {
adapter.sendTwitterImage({
params : {
media : options.image,
status : options.message,
},
title : "Twitter",
onSuccess : options.success,
onError : options.error
});
});
},
share : function(options) {
this.authorize(function() {
adapter.send({
url : urls.update,
parameters : [["status", options.message]],
title : "Twitter",
onSuccess : options.success,
onError : options.error
});
});
},
shareToLinkedin : function(options) {
this.authorize(function() {
adapter.shareLinkedin({
site : 'linkedin',
url : urls.update,
parameters : options.message,
title : "Linkedin",
onSuccess : options.success,
onError : options.error
});
});
},
getProfileLinkedin : function(options) {
this.authorize(function() {
adapter.getProfileLinkedin({
site : 'linkedin',
url : urls.update,
parameters : options.message,
title : "Linkedin",
onSuccess : options.success,
onError : options.error
});
});
}
};
};
@rampicos
Copy link
Author

@sernac
Copy link

sernac commented Jun 13, 2013

Hey Ramkumar,
The code had been working great in my app. However, Twitter recently deprecated the REST API v1 and now I get an error message that I should migrate to API v1.1
Could you please point as to how I should correct this?

Thanks!

@lamotora
Copy link

Help me

@lamotora
Copy link

could not authenticate error 32 twitter

@mattjgarland
Copy link

Same error as Iamotora: {"errors":[{"message":"Could not authenticate you","code":32}]}. The initial token-getting phase seems to work, but authentication on post fails.

Here is the base string generated:

POST&https%3A%2F%2Fapi.twitter.com%2F1.1%2Fstatuses%2Fupdate.json&%3D%26oauth_consumer_key%3DTVm3Gw4noIefIt7SHdgAA%26oauth_nonce%3DiNfErk%26oauth_signature_method%3DHMAC-SHA1%26oauth_timestamp%3D1372878031%26oauth_token%3D803141978-ox0QaRtc9xgDMMZYK0XKAm9zIxEODtTbQMCHKVJF%26status%3DHello%252C%2520world%2521

An online tool tells me that oauth_version is missing, but adding it does no good. After some googling, I also tried to change the content type of the post:

client.setRequestHeader("Content-Type", "application/x-www-form-urlencoded"); (adding at 710)

That didn't work either. Can anyone confirm that the library works with v1.1?

@vyatri
Copy link

vyatri commented Jul 27, 2013

I modified the script. This works on me for my android project. I haven't tested it on ios yet.

please take a look. If it works, please rampicos update the above gist.
https://gist.github.com/vyatri/6094282

hope it's useful

@AppWerft
Copy link

AppWerft commented Sep 4, 2013

@riteshh
Copy link

riteshh commented Dec 15, 2014

Hello all plz help me,

I am using 3.4.0 SDK and i am not able to share image with "shareImage" function.

i write code like...

twitter.shareImage({
message : "Test",
image : (Ti.Filesystem.getFile(Ti.Filesystem.resourcesDirectory, "KS_nav_ui.png")).read(),,
success : function() {
alert('Tweeted!');
},
error : function() {
alert('ERROR Tweeted!');
}
});

Its not working for me. give me solution if possible.
Thanks in advance.

@jeroendk
Copy link

Because of the API update of linkedIn you need to modify the URL on line 724
from: requestToken : "https://api.linkedin.com/uas/oauth/requestToken?scope=rw_nus",
to: requestToken : "https://api.linkedin.com/uas/oauth/requestToken?scope=w_share",

Also adjust the permissions in the linkedin app.

@thepearldream
Copy link

How do I get the user basic profile info to display after authentication ?

@davidcyp
Copy link

@thepearldream just call #getProfileLinkedin

@dineshkoli
Copy link

How to get email id in user profile?

getProfileLinkedin not providing user email. We have already taken the email address permission.

Please provide the solution if possible..
Thanks in advance..

@webexpert4rv
Copy link

Hi,
I am also stuck with get Email from linkedIn. There is permission issue i think. i have to pass 'r_emailaddress' permission but how to use this with oauth i don't understand. Do you have any solution for getting email from linkedIn.

@webexpert4rv
Copy link

I have solve this issue :- you have to change
from: requestToken : "https://api.linkedin.com/uas/oauth/requestToken?scope=w_share",
to: requestToken : "https://api.linkedin.com/uas/oauth/requestToken?scope=r_emailaddress"
after this you got email address as well

@annamf
Copy link

annamf commented Jun 28, 2016

YOUR SOLUTION FOR LINKEDIN HELPED ME A LOT, THANK YOU!!!

Hi,
I want to get the Email from Twitter user's account. I've filled the form to get the email permission. But I can't get it. Any solution? I'm using this js.

The call should be this: https://api.twitter.com/1.1/account/verify_credentials.json?include_email=true
But I can't retrieve the mail with this.

This is my code, but it doesn't work. Titanium says me that they can't found this function:

this.getProfileEmailTwitter = function(options) {

        Ti.API.info("token: " + accessToken + " secret: " + accessTokenSecret);
        var pUrl = "https://api.twitter.com/1.1/account/verify_credentials.json?include_email=true";
        var pSuccessMessage = options.onSuccess;
        var pErrorMessage = options.onError;

        accessor.tokenSecret = accessTokenSecret;
        var message = createMessage(pUrl);

        message.method = 'get';
        message.parameters.push(["oauth_nonce", OAuth.nonce(42)]);
        message.parameters.push(["oauth_timestamp", OAuth.timestamp()]);
        message.parameters.push(["oauth_token", accessToken]);
        message.parameters.push(["oauth_version", "1.0"]);

        OAuth.SignatureMethod.sign(message, accessor);

        var parameterMap = OAuth.getParameterMap(message.parameters);
        Ti.API.info(JSON.stringify(message));

        client = Ti.Network.createHTTPClient({
            onload : function() {
                if (client.status == 200) {
                    pSuccessMessage && pSuccessMessage(this.responseText);
                } else {
                    pErrorMessage && pErrorMessage(this.responseText);
                }
            },
            onerror : function() {
                Ti.API.error("Social.js: FAILED to send a request!");
                Ti.API.error(this.responseText);
                pErrorMessage && pErrorMessage(this.responseText);
            }
        });

        client.open("GET", pUrl);
        header = OAuth.getAuthorizationHeader("", message.parameters);

        client.setRequestHeader("Authorization", header);
        client.send();
    };

@mohitcis
Copy link

mohitcis commented Jul 14, 2016

Hi Ramkumar,
I have used your socialJs module for twitter in titanium. It worked fine for me. I can login successfully with twitter credential. But after login I need user profile information of user like email, username , profile pic etc. Can you please let me know how can I get these information.

Thanks in advance.

@kerobs
Copy link

kerobs commented Aug 24, 2016

Thank you for the solutions.. It works brilliantly in IOS/Android Phone.. but when I try to invoke

var linkedin = social.create({
consumerSecret : 'xxxx',
consumerKey : 'xzxx',
site: 'linkedin'
});

linkedin.getProfileLinkedin({
success : function(data) {
XXxx
},
error : function(error) {
console.log("Error while posting: ", error);
}
})

in WINDOWSPHONE...

linkedin.getProfileLinkedin{()} is undefined... Is there any fix for it.?

@nerdymax
Copy link

Twitter sharing is not working. It says "The Twitter REST API v1 is no longer active. Please migrate to API v1.1. https://dev.twitter.com/docs/api/1.1/overview." How do I fix this?

@SquirrelMobile
Copy link

On linkedin API V1 will be depreciate the 1st March 2019. How to migrate on V2 API ?

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment