├── README.md
├── LICENSE
├── index.html
├── dropbox.js
├── sha1.js
└── oauth.js
/README.md:
--------------------------------------------------------------------------------
1 | # dropbox-js
2 |
3 | JavaScript library for accessing the Dropbox API over OAuth.
--------------------------------------------------------------------------------
/LICENSE:
--------------------------------------------------------------------------------
1 | The MIT License (MIT)
2 |
3 | Copyright (c) 2015 Ben Cherry
4 |
5 | Permission is hereby granted, free of charge, to any person obtaining a copy
6 | of this software and associated documentation files (the "Software"), to deal
7 | in the Software without restriction, including without limitation the rights
8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9 | copies of the Software, and to permit persons to whom the Software is
10 | furnished to do so, subject to the following conditions:
11 |
12 | The above copyright notice and this permission notice shall be included in all
13 | copies or substantial portions of the Software.
14 |
15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21 | SOFTWARE.
22 |
--------------------------------------------------------------------------------
/index.html:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 | Dropbox JS API
6 |
7 |
8 |
36 |
37 |
38 |
39 |
40 |
41 |
59 |
60 |
--------------------------------------------------------------------------------
/dropbox.js:
--------------------------------------------------------------------------------
1 | var dropbox = {
2 | setup: function(consumerKey, consumerSecret) {
3 | this._consumerKey = consumerKey;
4 | this._consumerSecret = consumerSecret;
5 | this._requestCounter = $.now();
6 | },
7 |
8 | authenticate: function(email, password, callback) {
9 | var that = this;
10 |
11 | this._request("/token", {
12 | sendAuth: false,
13 |
14 | success: function(data) {
15 | console.log("authentication response", data);
16 | that._accessToken = data.token;
17 | that._accessTokenSecret = data.secret;
18 |
19 | if (callback) {
20 | callback();
21 | }
22 | },
23 | error: function() {
24 | console.error("authentication error", arguments);
25 | }
26 | }, {
27 | email: email,
28 | password: password
29 | });
30 | },
31 |
32 | getInfo: function() {
33 | this._request("/account/info", {
34 | success: function(data) {
35 | console.log("account info", data);
36 | },
37 |
38 | error: function() {
39 | console.log("account info error", arguments);
40 | }
41 | });
42 | },
43 |
44 | _request: function(path, params, data) {
45 | var requestId = "dropboxjsonp" + (this._requestCounter++);
46 | params = $.extend({}, {
47 | subdomain: "api", // some methods need api-content.dropbox.com
48 | apiVersion: "0",
49 | sendAuth: true,
50 |
51 | method: "GET",
52 | success: $.noop,
53 | error: $.noop
54 | }, params || {});
55 |
56 | if (params.sendAuth && !this._accessToken) {
57 | throw "Authenticated method called before authenticating";
58 | }
59 |
60 | var url = "https://" + params.subdomain + ".dropbox.com/" + params.apiVersion + path;
61 |
62 | var message = {
63 | action: url,
64 | method: params.method,
65 | parameters: {
66 | oauth_consumer_key: this._consumerKey,
67 | oauth_signature_method: "HMAC-SHA1",
68 | callback: requestId
69 | }
70 | };
71 |
72 | $.extend(message.parameters, data);
73 |
74 | if (params.sendAuth) {
75 | message.parameters.oauth_token = this._accessToken;
76 | }
77 |
78 | var oauthBits = {
79 | consumerSecret: this._consumerSecret
80 | };
81 |
82 | if (params.sendAuth) {
83 | oauthBits.tokenSecret = this._accessTokenSecret;
84 | }
85 |
86 | OAuth.setTimestampAndNonce(message);
87 | OAuth.SignatureMethod.sign(message, oauthBits);
88 |
89 | $.ajax({
90 | dataType: "jsonp",
91 | method: params.method,
92 | url: url,
93 | data: OAuth.getParameterMap(message.parameters),
94 | jsonpCallback: requestId,
95 |
96 | success: params.success,
97 | error: params.error
98 | });
99 | }
100 | };
101 |
--------------------------------------------------------------------------------
/sha1.js:
--------------------------------------------------------------------------------
1 | /*
2 | * A JavaScript implementation of the Secure Hash Algorithm, SHA-1, as defined
3 | * in FIPS PUB 180-1
4 | * Version 2.1a Copyright Paul Johnston 2000 - 2002.
5 | * Other contributors: Greg Holt, Andrew Kepert, Ydnar, Lostinet
6 | * Distributed under the BSD License
7 | * See http://pajhome.org.uk/crypt/md5 for details.
8 | */
9 |
10 | /*
11 | * Configurable variables. You may need to tweak these to be compatible with
12 | * the server-side, but the defaults work in most cases.
13 | */
14 | var hexcase = 0; /* hex output format. 0 - lowercase; 1 - uppercase */
15 | var b64pad = ""; /* base-64 pad character. "=" for strict RFC compliance */
16 | var chrsz = 8; /* bits per input character. 8 - ASCII; 16 - Unicode */
17 |
18 | /*
19 | * These are the functions you'll usually want to call
20 | * They take string arguments and return either hex or base-64 encoded strings
21 | */
22 | function hex_sha1(s){return binb2hex(core_sha1(str2binb(s),s.length * chrsz));}
23 | function b64_sha1(s){return binb2b64(core_sha1(str2binb(s),s.length * chrsz));}
24 | function str_sha1(s){return binb2str(core_sha1(str2binb(s),s.length * chrsz));}
25 | function hex_hmac_sha1(key, data){ return binb2hex(core_hmac_sha1(key, data));}
26 | function b64_hmac_sha1(key, data){ return binb2b64(core_hmac_sha1(key, data));}
27 | function str_hmac_sha1(key, data){ return binb2str(core_hmac_sha1(key, data));}
28 |
29 | /*
30 | * Perform a simple self-test to see if the VM is working
31 | */
32 | function sha1_vm_test()
33 | {
34 | return hex_sha1("abc") == "a9993e364706816aba3e25717850c26c9cd0d89d";
35 | }
36 |
37 | /*
38 | * Calculate the SHA-1 of an array of big-endian words, and a bit length
39 | */
40 | function core_sha1(x, len)
41 | {
42 | /* append padding */
43 | x[len >> 5] |= 0x80 << (24 - len % 32);
44 | x[((len + 64 >> 9) << 4) + 15] = len;
45 |
46 | var w = Array(80);
47 | var a = 1732584193;
48 | var b = -271733879;
49 | var c = -1732584194;
50 | var d = 271733878;
51 | var e = -1009589776;
52 |
53 | for(var i = 0; i < x.length; i += 16)
54 | {
55 | var olda = a;
56 | var oldb = b;
57 | var oldc = c;
58 | var oldd = d;
59 | var olde = e;
60 |
61 | for(var j = 0; j < 80; j++)
62 | {
63 | if(j < 16) w[j] = x[i + j];
64 | else w[j] = rol(w[j-3] ^ w[j-8] ^ w[j-14] ^ w[j-16], 1);
65 | var t = safe_add(safe_add(rol(a, 5), sha1_ft(j, b, c, d)),
66 | safe_add(safe_add(e, w[j]), sha1_kt(j)));
67 | e = d;
68 | d = c;
69 | c = rol(b, 30);
70 | b = a;
71 | a = t;
72 | }
73 |
74 | a = safe_add(a, olda);
75 | b = safe_add(b, oldb);
76 | c = safe_add(c, oldc);
77 | d = safe_add(d, oldd);
78 | e = safe_add(e, olde);
79 | }
80 | return Array(a, b, c, d, e);
81 |
82 | }
83 |
84 | /*
85 | * Perform the appropriate triplet combination function for the current
86 | * iteration
87 | */
88 | function sha1_ft(t, b, c, d)
89 | {
90 | if(t < 20) return (b & c) | ((~b) & d);
91 | if(t < 40) return b ^ c ^ d;
92 | if(t < 60) return (b & c) | (b & d) | (c & d);
93 | return b ^ c ^ d;
94 | }
95 |
96 | /*
97 | * Determine the appropriate additive constant for the current iteration
98 | */
99 | function sha1_kt(t)
100 | {
101 | return (t < 20) ? 1518500249 : (t < 40) ? 1859775393 :
102 | (t < 60) ? -1894007588 : -899497514;
103 | }
104 |
105 | /*
106 | * Calculate the HMAC-SHA1 of a key and some data
107 | */
108 | function core_hmac_sha1(key, data)
109 | {
110 | var bkey = str2binb(key);
111 | if(bkey.length > 16) bkey = core_sha1(bkey, key.length * chrsz);
112 |
113 | var ipad = Array(16), opad = Array(16);
114 | for(var i = 0; i < 16; i++)
115 | {
116 | ipad[i] = bkey[i] ^ 0x36363636;
117 | opad[i] = bkey[i] ^ 0x5C5C5C5C;
118 | }
119 |
120 | var hash = core_sha1(ipad.concat(str2binb(data)), 512 + data.length * chrsz);
121 | return core_sha1(opad.concat(hash), 512 + 160);
122 | }
123 |
124 | /*
125 | * Add integers, wrapping at 2^32. This uses 16-bit operations internally
126 | * to work around bugs in some JS interpreters.
127 | */
128 | function safe_add(x, y)
129 | {
130 | var lsw = (x & 0xFFFF) + (y & 0xFFFF);
131 | var msw = (x >> 16) + (y >> 16) + (lsw >> 16);
132 | return (msw << 16) | (lsw & 0xFFFF);
133 | }
134 |
135 | /*
136 | * Bitwise rotate a 32-bit number to the left.
137 | */
138 | function rol(num, cnt)
139 | {
140 | return (num << cnt) | (num >>> (32 - cnt));
141 | }
142 |
143 | /*
144 | * Convert an 8-bit or 16-bit string to an array of big-endian words
145 | * In 8-bit function, characters >255 have their hi-byte silently ignored.
146 | */
147 | function str2binb(str)
148 | {
149 | var bin = Array();
150 | var mask = (1 << chrsz) - 1;
151 | for(var i = 0; i < str.length * chrsz; i += chrsz)
152 | bin[i>>5] |= (str.charCodeAt(i / chrsz) & mask) << (32 - chrsz - i%32);
153 | return bin;
154 | }
155 |
156 | /*
157 | * Convert an array of big-endian words to a string
158 | */
159 | function binb2str(bin)
160 | {
161 | var str = "";
162 | var mask = (1 << chrsz) - 1;
163 | for(var i = 0; i < bin.length * 32; i += chrsz)
164 | str += String.fromCharCode((bin[i>>5] >>> (32 - chrsz - i%32)) & mask);
165 | return str;
166 | }
167 |
168 | /*
169 | * Convert an array of big-endian words to a hex string.
170 | */
171 | function binb2hex(binarray)
172 | {
173 | var hex_tab = hexcase ? "0123456789ABCDEF" : "0123456789abcdef";
174 | var str = "";
175 | for(var i = 0; i < binarray.length * 4; i++)
176 | {
177 | str += hex_tab.charAt((binarray[i>>2] >> ((3 - i%4)*8+4)) & 0xF) +
178 | hex_tab.charAt((binarray[i>>2] >> ((3 - i%4)*8 )) & 0xF);
179 | }
180 | return str;
181 | }
182 |
183 | /*
184 | * Convert an array of big-endian words to a base-64 string
185 | */
186 | function binb2b64(binarray)
187 | {
188 | var tab = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/";
189 | var str = "";
190 | for(var i = 0; i < binarray.length * 4; i += 3)
191 | {
192 | var triplet = (((binarray[i >> 2] >> 8 * (3 - i %4)) & 0xFF) << 16)
193 | | (((binarray[i+1 >> 2] >> 8 * (3 - (i+1)%4)) & 0xFF) << 8 )
194 | | ((binarray[i+2 >> 2] >> 8 * (3 - (i+2)%4)) & 0xFF);
195 | for(var j = 0; j < 4; j++)
196 | {
197 | if(i * 8 + j * 6 > binarray.length * 32) str += b64pad;
198 | else str += tab.charAt((triplet >> 6*(3-j)) & 0x3F);
199 | }
200 | }
201 | return str;
202 | }
203 |
--------------------------------------------------------------------------------
/oauth.js:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright 2008 Netflix, Inc.
3 | *
4 | * Licensed under the Apache License, Version 2.0 (the "License");
5 | * you may not use this file except in compliance with the License.
6 | * You may obtain a copy of the License at
7 | *
8 | * http://www.apache.org/licenses/LICENSE-2.0
9 | *
10 | * Unless required by applicable law or agreed to in writing, software
11 | * distributed under the License is distributed on an "AS IS" BASIS,
12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 | * See the License for the specific language governing permissions and
14 | * limitations under the License.
15 | */
16 |
17 | /* Here's some JavaScript software for implementing OAuth.
18 |
19 | This isn't as useful as you might hope. OAuth is based around
20 | allowing tools and websites to talk to each other. However,
21 | JavaScript running in web browsers is hampered by security
22 | restrictions that prevent code running on one website from
23 | accessing data stored or served on another.
24 |
25 | Before you start hacking, make sure you understand the limitations
26 | posed by cross-domain XMLHttpRequest.
27 |
28 | On the bright side, some platforms use JavaScript as their
29 | language, but enable the programmer to access other web sites.
30 | Examples include Google Gadgets, and Microsoft Vista Sidebar.
31 | For those platforms, this library should come in handy.
32 | */
33 |
34 | // The HMAC-SHA1 signature method calls b64_hmac_sha1, defined by
35 | // http://pajhome.org.uk/crypt/md5/sha1.js
36 |
37 | /* An OAuth message is represented as an object like this:
38 | {method: "GET", action: "http://server.com/path", parameters: ...}
39 |
40 | The parameters may be either a map {name: value, name2: value2}
41 | or an Array of name-value pairs [[name, value], [name2, value2]].
42 | The latter representation is more powerful: it supports parameters
43 | in a specific sequence, or several parameters with the same name;
44 | for example [["a", 1], ["b", 2], ["a", 3]].
45 |
46 | Parameter names and values are NOT percent-encoded in an object.
47 | They must be encoded before transmission and decoded after reception.
48 | For example, this message object:
49 | {method: "GET", action: "http://server/path", parameters: {p: "x y"}}
50 | ... can be transmitted as an HTTP request that begins:
51 | GET /path?p=x%20y HTTP/1.0
52 | (This isn't a valid OAuth request, since it lacks a signature etc.)
53 | Note that the object "x y" is transmitted as x%20y. To encode
54 | parameters, you can call OAuth.addToURL, OAuth.formEncode or
55 | OAuth.getAuthorization.
56 |
57 | This message object model harmonizes with the browser object model for
58 | input elements of an form, whose value property isn't percent encoded.
59 | The browser encodes each value before transmitting it. For example,
60 | see consumer.setInputs in example/consumer.js.
61 | */
62 |
63 | /* This script needs to know what time it is. By default, it uses the local
64 | clock (new Date), which is apt to be inaccurate in browsers. To do
65 | better, you can load this script from a URL whose query string contains
66 | an oauth_timestamp parameter, whose value is a current Unix timestamp.
67 | For example, when generating the enclosing document using PHP:
68 |
69 |