Last active
August 29, 2015 14:06
-
-
Save KevinTCoughlin/b51ac04ea6f79e1708ba to your computer and use it in GitHub Desktop.
Tumblr OAuth Client for Windows 8/8.1
This file contains 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
(function () { | |
"use strict"; | |
/** | |
* Tumblr OAuth Client | |
*/ | |
WinJS.Namespace.define('TumblrOAuth', { | |
client: WinJS.Class.define(function (consumerKey, consumerSecret) { | |
this._consumerKey = consumerKey; | |
this._consumerSecret = consumerSecret; | |
var localSettings = Windows.Storage.ApplicationData.current.localSettings; | |
if (!this._accessKey && localSettings.values["accessKey"]) { | |
this._accessKey = localSettings.values["accessKey"]; | |
this._accessSecret = localSettings.values["accessSecret"]; | |
} | |
}, { | |
_consumerKey: null, | |
_consumerSecret: null, | |
_accessKey: null, | |
_accessSecret: null, | |
_loginUrl: "https://www.tumblr.com/oauth/request_token", | |
_authUrl: "https://www.tumblr.com/oauth/authorize?oauth_token=", | |
_accessUrl: "https://www.tumblr.com/oauth/access_token", | |
isLoggedIn: function () { | |
var localSettings = Windows.Storage.ApplicationData.current.localSettings; | |
return localSettings.values["accessKey"]; | |
}, | |
logout: function () { | |
var localSettings = Windows.Storage.ApplicationData.current.localSettings; | |
localSettings.values.remove('accessKey'); | |
localSettings.values.remove('accessSecret'); | |
}, | |
login: function () { | |
var self = this; | |
var loginDetail = {}; | |
var localSettings = Windows.Storage.ApplicationData.current.localSettings; | |
var callback = Windows.Security.Authentication.Web.WebAuthenticationBroker.getCurrentApplicationCallbackUri().absoluteUri; | |
var callback = new Windows.Foundation.Uri(callback.substr(0, callback.length - 1)); | |
loginDetail["oauth_callback"] = callback.absoluteUri; | |
var loginReq = this.getAuthRequest(this._loginUrl, "POST", loginDetail, "text", "oauth_callback"); | |
return loginReq.then(function (r) { | |
var loginResponse = r.split('&'); | |
for (var r in loginResponse) { | |
var parts = loginResponse[r].split('='); | |
switch (parts[0]) { | |
case 'oauth_token': | |
self._accessKey = parts[1]; | |
break; | |
case 'oauth_token_secret': | |
self._accessSecret = parts[1]; | |
} | |
} | |
if (!self._accessKey) { | |
throw r.response; | |
} | |
return true; | |
}) | |
.then(function () { | |
var url = self._authUrl + self._accessKey; | |
return Windows.Security.Authentication.Web.WebAuthenticationBroker.authenticateAsync( | |
Windows.Security.Authentication.Web.WebAuthenticationOptions.none, | |
new Windows.Foundation.Uri(url), callback); | |
}) | |
.then(function (WABResult) { | |
loginDetail.WAB = WABResult; | |
return loginDetail; | |
}) | |
.then(function (details) { | |
var result = details.WAB.responseData; | |
var accessDetail = {}; | |
if (!result || result.length === 0) { | |
return false; | |
} | |
var pieces = new Windows.Foundation.Uri(result).queryParsed; | |
for (var p = 0; p < pieces.size; p++) { | |
var entry = pieces.getAt(p); | |
switch (entry.name) { | |
case "oauth_token": | |
self._accessKey = entry.value; | |
break; | |
case "oauth_verifier": | |
accessDetail.oauth_verifier = entry.value; | |
break; | |
} | |
} | |
return self.getAuthRequest(self._accessUrl, "POST", accessDetail, "text", "oauth_verifier"); | |
}) | |
.then(function (responseData) { | |
if (typeof (responseData) != "string") { | |
responseData = ""; | |
} | |
var pieces = responseData.split('&'); | |
for (var p in pieces) { | |
var part = pieces[p]; | |
var parts = part.split('='); | |
switch (parts[0]) { | |
case 'oauth_token': | |
self._accessKey = parts[1]; | |
localSettings.values["accessKey"] = self._accessKey; | |
break; | |
case 'oauth_token_secret': | |
self._accessSecret = parts[1]; | |
localSettings.values["accessSecret"] = self._accessSecret; | |
break; | |
} | |
} | |
return true; | |
}); | |
}, | |
generateHeader: function (url, method, params, addToHeader) { | |
var epoch = Math.round(new Date().getTime() / 1000); | |
var nonce = Math.random(); | |
var sig = this.generateSignature(url, method, nonce, epoch, params); | |
var sigHeader = "OAuth "; | |
if (addToHeader === "oauth_callback") { | |
sigHeader += (addToHeader + "=\"" + encodeURIComponent(params[addToHeader]) + "\", "); | |
} | |
sigHeader += "oauth_consumer_key=\"" + this._consumerKey + "\", oauth_nonce=\"" + nonce + "\", oauth_signature_method=\"HMAC-SHA1\", oauth_timestamp=\"" + epoch + "\", "; | |
if (this._accessKey) { | |
sigHeader += "oauth_token=\"" + this._accessKey + "\", "; | |
} | |
if (addToHeader == "oauth_verifier") { | |
sigHeader += (addToHeader + "=\"" + encodeURIComponent(params[addToHeader]) + "\", "); | |
} | |
sigHeader += "oauth_version=\"1.0\", oauth_signature=\"" + encodeURIComponent(sig) + "\""; | |
return sigHeader; | |
}, | |
generateSignature: function (url, method, nonce, epoch, params) { | |
var sigParams = { | |
'oauth_consumer_key': this._consumerKey, | |
'oauth_nonce': nonce, | |
'oauth_signature_method': 'HMAC-SHA1', | |
'oauth_timestamp': epoch, | |
'oauth_token': this._accessKey, | |
'oauth_version': '1.0' | |
}; | |
if (!this._accessKey) { | |
delete sigParams.oauth_token; | |
} | |
var sig = []; | |
for (var p in params) { | |
sigParams[p] = params[p]; | |
} | |
var first = true; | |
var keys = Object.keys(sigParams).sort(); | |
for (var k in keys) { | |
var key = keys[k]; | |
if (!first) { | |
sig.push("&"); | |
} | |
first = false; | |
if (typeof (sigParams[key]) === "object") { | |
//TODO: Encode Photo | |
} | |
else { | |
sig.push(encodeURIComponent(key)); | |
sig.push("="); | |
sig.push(encodeURIComponent(sigParams[key])); | |
} | |
} | |
var sigString = method.toUpperCase() + "&" + encodeURIComponent(url) + "&" + encodeURIComponent(sig.join('')); | |
var keyMaterial = Windows.Security.Cryptography.CryptographicBuffer.convertStringToBinary(this._consumerSecret + "&" + (this._accessSecret || ''), Windows.Security.Cryptography.BinaryStringEncoding.utf8); | |
var provider = new Windows.Security.Cryptography.Core.MacAlgorithmProvider.openAlgorithm("HMAC_SHA1"); | |
var key = provider.createKey(keyMaterial); | |
var tbs = Windows.Security.Cryptography.CryptographicBuffer.convertStringToBinary(sigString, Windows.Security.Cryptography.BinaryStringEncoding.Utf8); | |
var signatureBuffer = Windows.Security.Cryptography.Core.CryptographicEngine.sign(key, tbs); | |
var signature = Windows.Security.Cryptography.CryptographicBuffer.encodeToBase64String(signatureBuffer); | |
return signature; | |
}, | |
getApiKeyRequest: function (url, method, params, oauth) { | |
params = params || {}; | |
params["api_key"] = this._consumerKey; | |
if (oauth && this._accessKey) { | |
return this.getAuthRequest(url, method, params); | |
} | |
return this.makeRequest(url, method, null, params); | |
}, | |
getAuthRequest: function (url, method, params, type, addToHeader) { | |
if (!params) { | |
params = {}; | |
} | |
var header = this.generateHeader(url, method, params, addToHeader); | |
return this.makeRequest(url, method, header, params, type); | |
}, | |
makeRequest: function (url, method, sig, data, type) { | |
var headers = null; | |
if (sig) { | |
headers = { Authorization: sig } | |
} | |
if ((method || "get").toLowerCase() === "get") { | |
var parts = []; | |
parts.push(url); | |
var start = true; | |
for (var k in data) { | |
parts.push(start ? "?" : "&"); | |
start = false; | |
parts.push(encodeURIComponent(k)); | |
parts.push("="); | |
parts.push(encodeURIComponent(data[k])); | |
} | |
url = parts.join(''); | |
} | |
return WinJS.xhr({ type: (method || "get").toUpperCase(), responseType: type || "json", url: url, headers: headers, data: data }).then(function (r) { | |
if (!type || type == "json") { | |
return JSON.parse(r.response); | |
} | |
return r.response; | |
}, function (r) { | |
return JSON.parse((r && r.response && r.response != "") ? r.response : "{}"); | |
}); | |
}, | |
setAccessDetails: function (key, secret) { | |
this._accessKey = key; | |
this._accessSecret = secret; | |
} | |
}) | |
}); | |
})(); |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment