You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
381 lines
11 KiB
381 lines
11 KiB
(function(f){if(typeof exports==="object"&&typeof module!=="undefined"){module.exports=f()}else if(typeof define==="function"&&define.amd){define([],f)}else{var g;if(typeof window!=="undefined"){g=window}else if(typeof global!=="undefined"){g=global}else if(typeof self!=="undefined"){g=self}else{g=this}(g.oauth1 || (g.oauth1 = {})).a = f()}})(function(){var define,module,exports;return (function(){function r(e,n,t){function o(i,f){if(!n[i]){if(!e[i]){var c="function"==typeof require&&require;if(!f&&c)return c(i,!0);if(u)return u(i,!0);var a=new Error("Cannot find module '"+i+"'");throw a.code="MODULE_NOT_FOUND",a}var p=n[i]={exports:{}};e[i][0].call(p.exports,function(r){var n=e[i][1][r];return o(n||r)},p,p.exports,r,e,n,t)}return n[i].exports}for(var u="function"==typeof require&&require,i=0;i<t.length;i++)o(t[i]);return o}return r})()({"oauth-1.0a":[function(require,module,exports){
|
|
if (typeof(module) !== 'undefined' && typeof(exports) !== 'undefined') {
|
|
module.exports = OAuth;
|
|
}
|
|
|
|
/**
|
|
* Constructor
|
|
* @param {Object} opts consumer key and secret
|
|
*/
|
|
function OAuth(opts) {
|
|
if(!(this instanceof OAuth)) {
|
|
return new OAuth(opts);
|
|
}
|
|
|
|
if(!opts) {
|
|
opts = {};
|
|
}
|
|
|
|
if(!opts.consumer) {
|
|
throw new Error('consumer option is required');
|
|
}
|
|
|
|
this.consumer = opts.consumer;
|
|
this.nonce_length = opts.nonce_length || 32;
|
|
this.version = opts.version || '1.0';
|
|
this.parameter_seperator = opts.parameter_seperator || ', ';
|
|
this.realm = opts.realm;
|
|
|
|
if(typeof opts.last_ampersand === 'undefined') {
|
|
this.last_ampersand = true;
|
|
} else {
|
|
this.last_ampersand = opts.last_ampersand;
|
|
}
|
|
|
|
// default signature_method is 'PLAINTEXT'
|
|
this.signature_method = opts.signature_method || 'PLAINTEXT';
|
|
|
|
if(this.signature_method == 'PLAINTEXT' && !opts.hash_function) {
|
|
opts.hash_function = function(base_string, key) {
|
|
return key;
|
|
}
|
|
}
|
|
|
|
if(!opts.hash_function) {
|
|
throw new Error('hash_function option is required');
|
|
}
|
|
|
|
this.hash_function = opts.hash_function;
|
|
this.body_hash_function = opts.body_hash_function || this.hash_function;
|
|
}
|
|
|
|
/**
|
|
* OAuth request authorize
|
|
* @param {Object} request data
|
|
* {
|
|
* method,
|
|
* url,
|
|
* data
|
|
* }
|
|
* @param {Object} key and secret token
|
|
* @return {Object} OAuth Authorized data
|
|
*/
|
|
OAuth.prototype.authorize = function(request, token) {
|
|
var oauth_data = {
|
|
oauth_consumer_key: this.consumer.key,
|
|
oauth_nonce: this.getNonce(),
|
|
oauth_signature_method: this.signature_method,
|
|
oauth_timestamp: this.getTimeStamp(),
|
|
oauth_version: this.version
|
|
};
|
|
|
|
if(!token) {
|
|
token = {};
|
|
}
|
|
|
|
if(token.key !== undefined) {
|
|
oauth_data.oauth_token = token.key;
|
|
}
|
|
|
|
if(!request.data) {
|
|
request.data = {};
|
|
}
|
|
|
|
if(request.includeBodyHash) {
|
|
oauth_data.oauth_body_hash = this.getBodyHash(request, token.secret)
|
|
}
|
|
|
|
oauth_data.oauth_signature = this.getSignature(request, token.secret, oauth_data);
|
|
|
|
return oauth_data;
|
|
};
|
|
|
|
/**
|
|
* Create a OAuth Signature
|
|
* @param {Object} request data
|
|
* @param {Object} token_secret key and secret token
|
|
* @param {Object} oauth_data OAuth data
|
|
* @return {String} Signature
|
|
*/
|
|
OAuth.prototype.getSignature = function(request, token_secret, oauth_data) {
|
|
return this.hash_function(this.getBaseString(request, oauth_data), this.getSigningKey(token_secret));
|
|
};
|
|
|
|
/**
|
|
* Create a OAuth Body Hash
|
|
* @param {Object} request data
|
|
*/
|
|
OAuth.prototype.getBodyHash = function(request, token_secret) {
|
|
var body = typeof request.data === 'string' ? request.data : JSON.stringify(request.data)
|
|
|
|
if (!this.body_hash_function) {
|
|
throw new Error('body_hash_function option is required');
|
|
}
|
|
|
|
return this.body_hash_function(body, this.getSigningKey(token_secret))
|
|
};
|
|
|
|
/**
|
|
* Base String = Method + Base Url + ParameterString
|
|
* @param {Object} request data
|
|
* @param {Object} OAuth data
|
|
* @return {String} Base String
|
|
*/
|
|
OAuth.prototype.getBaseString = function(request, oauth_data) {
|
|
return request.method.toUpperCase() + '&' + this.percentEncode(this.getBaseUrl(request.url)) + '&' + this.percentEncode(this.getParameterString(request, oauth_data));
|
|
};
|
|
|
|
/**
|
|
* Get data from url
|
|
* -> merge with oauth data
|
|
* -> percent encode key & value
|
|
* -> sort
|
|
*
|
|
* @param {Object} request data
|
|
* @param {Object} OAuth data
|
|
* @return {Object} Parameter string data
|
|
*/
|
|
OAuth.prototype.getParameterString = function(request, oauth_data) {
|
|
var base_string_data;
|
|
if (oauth_data.oauth_body_hash) {
|
|
base_string_data = this.sortObject(this.percentEncodeData(this.mergeObject(oauth_data, this.deParamUrl(request.url))));
|
|
} else {
|
|
base_string_data = this.sortObject(this.percentEncodeData(this.mergeObject(oauth_data, this.mergeObject(request.data, this.deParamUrl(request.url)))));
|
|
}
|
|
|
|
var data_str = '';
|
|
|
|
//base_string_data to string
|
|
for(var i = 0; i < base_string_data.length; i++) {
|
|
var key = base_string_data[i].key;
|
|
var value = base_string_data[i].value;
|
|
// check if the value is an array
|
|
// this means that this key has multiple values
|
|
if (value && Array.isArray(value)){
|
|
// sort the array first
|
|
value.sort();
|
|
|
|
var valString = "";
|
|
// serialize all values for this key: e.g. formkey=formvalue1&formkey=formvalue2
|
|
value.forEach((function(item, i){
|
|
valString += key + '=' + item;
|
|
if (i < value.length){
|
|
valString += "&";
|
|
}
|
|
}).bind(this));
|
|
data_str += valString;
|
|
} else {
|
|
data_str += key + '=' + value + '&';
|
|
}
|
|
}
|
|
|
|
//remove the last character
|
|
data_str = data_str.substr(0, data_str.length - 1);
|
|
return data_str;
|
|
};
|
|
|
|
/**
|
|
* Create a Signing Key
|
|
* @param {String} token_secret Secret Token
|
|
* @return {String} Signing Key
|
|
*/
|
|
OAuth.prototype.getSigningKey = function(token_secret) {
|
|
token_secret = token_secret || '';
|
|
|
|
if(!this.last_ampersand && !token_secret) {
|
|
return this.percentEncode(this.consumer.secret);
|
|
}
|
|
|
|
return this.percentEncode(this.consumer.secret) + '&' + this.percentEncode(token_secret);
|
|
};
|
|
|
|
/**
|
|
* Get base url
|
|
* @param {String} url
|
|
* @return {String}
|
|
*/
|
|
OAuth.prototype.getBaseUrl = function(url) {
|
|
return url.split('?')[0];
|
|
};
|
|
|
|
/**
|
|
* Get data from String
|
|
* @param {String} string
|
|
* @return {Object}
|
|
*/
|
|
OAuth.prototype.deParam = function(string) {
|
|
var arr = string.split('&');
|
|
var data = {};
|
|
|
|
for(var i = 0; i < arr.length; i++) {
|
|
var item = arr[i].split('=');
|
|
|
|
// '' value
|
|
item[1] = item[1] || '';
|
|
|
|
// check if the key already exists
|
|
// this can occur if the QS part of the url contains duplicate keys like this: ?formkey=formvalue1&formkey=formvalue2
|
|
if (data[item[0]]){
|
|
// the key exists already
|
|
if (!Array.isArray(data[item[0]])) {
|
|
// replace the value with an array containing the already present value
|
|
data[item[0]] = [data[item[0]]];
|
|
}
|
|
// and add the new found value to it
|
|
data[item[0]].push(decodeURIComponent(item[1]));
|
|
} else {
|
|
// it doesn't exist, just put the found value in the data object
|
|
data[item[0]] = decodeURIComponent(item[1]);
|
|
}
|
|
}
|
|
|
|
return data;
|
|
};
|
|
|
|
/**
|
|
* Get data from url
|
|
* @param {String} url
|
|
* @return {Object}
|
|
*/
|
|
OAuth.prototype.deParamUrl = function(url) {
|
|
var tmp = url.split('?');
|
|
|
|
if (tmp.length === 1)
|
|
return {};
|
|
|
|
return this.deParam(tmp[1]);
|
|
};
|
|
|
|
/**
|
|
* Percent Encode
|
|
* @param {String} str
|
|
* @return {String} percent encoded string
|
|
*/
|
|
OAuth.prototype.percentEncode = function(str) {
|
|
return encodeURIComponent(str)
|
|
.replace(/\!/g, "%21")
|
|
.replace(/\*/g, "%2A")
|
|
.replace(/\'/g, "%27")
|
|
.replace(/\(/g, "%28")
|
|
.replace(/\)/g, "%29");
|
|
};
|
|
|
|
/**
|
|
* Percent Encode Object
|
|
* @param {Object} data
|
|
* @return {Object} percent encoded data
|
|
*/
|
|
OAuth.prototype.percentEncodeData = function(data) {
|
|
var result = {};
|
|
|
|
for(var key in data) {
|
|
var value = data[key];
|
|
// check if the value is an array
|
|
if (value && Array.isArray(value)){
|
|
var newValue = [];
|
|
// percentEncode every value
|
|
value.forEach((function(val){
|
|
newValue.push(this.percentEncode(val));
|
|
}).bind(this));
|
|
value = newValue;
|
|
} else {
|
|
value = this.percentEncode(value);
|
|
}
|
|
result[this.percentEncode(key)] = value;
|
|
}
|
|
|
|
return result;
|
|
};
|
|
|
|
/**
|
|
* Get OAuth data as Header
|
|
* @param {Object} oauth_data
|
|
* @return {String} Header data key - value
|
|
*/
|
|
OAuth.prototype.toHeader = function(oauth_data) {
|
|
var sorted = this.sortObject(oauth_data);
|
|
|
|
var header_value = 'OAuth ';
|
|
|
|
if (this.realm) {
|
|
header_value += 'realm="' + this.realm + '"' + this.parameter_seperator;
|
|
}
|
|
|
|
for(var i = 0; i < sorted.length; i++) {
|
|
if (sorted[i].key.indexOf('oauth_') !== 0)
|
|
continue;
|
|
|
|
header_value += this.percentEncode(sorted[i].key) + '="' + this.percentEncode(sorted[i].value) + '"' + this.parameter_seperator;
|
|
}
|
|
|
|
return {
|
|
Authorization: header_value.substr(0, header_value.length - this.parameter_seperator.length) //cut the last chars
|
|
};
|
|
};
|
|
|
|
/**
|
|
* Create a random word characters string with input length
|
|
* @return {String} a random word characters string
|
|
*/
|
|
OAuth.prototype.getNonce = function() {
|
|
var word_characters = 'abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789';
|
|
var result = '';
|
|
|
|
for(var i = 0; i < this.nonce_length; i++) {
|
|
result += word_characters[parseInt(Math.random() * word_characters.length, 10)];
|
|
}
|
|
|
|
return result;
|
|
};
|
|
|
|
/**
|
|
* Get Current Unix TimeStamp
|
|
* @return {Int} current unix timestamp
|
|
*/
|
|
OAuth.prototype.getTimeStamp = function() {
|
|
return parseInt(new Date().getTime()/1000, 10);
|
|
};
|
|
|
|
////////////////////// HELPER FUNCTIONS //////////////////////
|
|
|
|
/**
|
|
* Merge object
|
|
* @param {Object} obj1
|
|
* @param {Object} obj2
|
|
* @return {Object}
|
|
*/
|
|
OAuth.prototype.mergeObject = function(obj1, obj2) {
|
|
obj1 = obj1 || {};
|
|
obj2 = obj2 || {};
|
|
|
|
var merged_obj = obj1;
|
|
for(var key in obj2) {
|
|
merged_obj[key] = obj2[key];
|
|
}
|
|
return merged_obj;
|
|
};
|
|
|
|
/**
|
|
* Sort object by key
|
|
* @param {Object} data
|
|
* @return {Array} sorted array
|
|
*/
|
|
OAuth.prototype.sortObject = function(data) {
|
|
var keys = Object.keys(data);
|
|
var result = [];
|
|
|
|
keys.sort();
|
|
|
|
for(var i = 0; i < keys.length; i++) {
|
|
var key = keys[i];
|
|
result.push({
|
|
key: key,
|
|
value: data[key],
|
|
});
|
|
}
|
|
|
|
return result;
|
|
};
|
|
|
|
},{}]},{},[])("oauth-1.0a")
|
|
});
|