This repository has been archived by the owner on Sep 10, 2018. It is now read-only.
-
Notifications
You must be signed in to change notification settings - Fork 4
/
api_bridge.js
103 lines (99 loc) · 3.35 KB
/
api_bridge.js
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
/**
* Functionality to communicate with the Asana API. This should get loaded
* in the "server" portion of the chrome extension because it will make
* HTTP requests and needs cross-domain priveleges.
*
* The bridge does not need to use an auth token to connect to
* the API, because since it is a browser extension it can access
* the user's cookies, and can use them to authenticate to the API.
* This capability is specific to browser extensions, and other
* types of applications would have to obtain an auth token to communicate
* with the API.
*/
Asana.ApiBridge = {
/**
* @type {String} Version of the Asana API to use.
*/
API_VERSION: "1.0",
/**
* @param opt_options {dict} Options to use; if unspecified will be loaded.
* @return {String} The base URL to use for API requests.
*/
baseApiUrl: function(opt_options) {
var options = opt_options || Asana.Options.loadOptions();
return 'https://' + options.asana_host_port + '/api/' + this.API_VERSION;
},
/**
* Make a request to the Asana API.
*
* @param http_method {String} HTTP request method to use (e.g. "POST")
* @param path {String} Path to call.
* @param params {dict} Parameters for API method; depends on method.
* @param callback {Function(response: dict)} Callback on completion.
* status {Integer} HTTP status code of response.
* data {dict} Object representing response of API call, depends on
* method. Only available if response was a 200.
* error {String?} Error message, if there was a problem.
*/
request: function(http_method, path, params, callback) {
var url = this.baseApiUrl() + path,
dfd = $.Deferred();
chrome.cookies.get({
url: url,
name: 'ticket'
}, function(cookie) {
if (!cookie) {
callback({
status: 401,
error: "Not Authorized"
});
return;
}
// Note that any URL fetched here must be matched by a permission in
// the manifest.json file!
var attrs = {
type: http_method,
url: url,
timeout: 30000, // 30 second timeout
headers: {
"X-Requested-With": "XMLHttpRequest"
},
accept: "application/json",
success: function(data, status, xhr) {
callback(data);
},
error: function(xhr, status, error) {
// jQuery's ajax() method has some rather funky error-handling.
// We try to accommodate that and normalize so that all types of
// errors look the same.
if (status === "error" && xhr.responseText) {
var response;
try {
response = $.parseJSON(xhr.responseText);
} catch (e) {
response = {
errors: [{message: "Could not parse response from server" }]
};
}
callback(response);
} else {
callback({ error: error || status });
}
},
xhrFields: {
withCredentials: true
}
};
if (http_method === "POST" || http_method === "PUT") {
attrs.data = JSON.stringify({data: params});
attrs.dataType = "json";
attrs.processData = false;
attrs.contentType = "application/json";
}
$.ajax(attrs)
.done(dfd.resolve)
.fail(dfd.reject);
});
return dfd.promise();
}
};