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
104
105
106
107
108
109
110
111
112
113
114
|
(function(module, ns) {
var XHR = ns.require('xhr');
var QueryString = ns.require('querystring');
var Connection = ns.require('connection');
var OAuth = ns.require('oauth2');
/**
* Creates an XHR like object given a connection and a set of options
* (passed directly to the superclass)
*
* @param {Caldav.Connection} connection used for apiCredentials.
* @param {Object} options typical XHR options.
*/
function Oauth2(connection, options) {
if (
!connection ||
!connection.oauth ||
(
!connection.oauth.code &&
!connection.oauth.refresh_token
)
) {
throw new Error('connection .oauth must have code or refresh_token');
}
this.connection = connection;
this.oauth =
new OAuth(connection.apiCredentials);
// create a clone of options
var clone = Object.create(null);
if (typeof(options) !== 'undefined') {
for (var key in options) {
clone[key] = options[key];
}
}
XHR.call(this, clone);
}
Oauth2.prototype = {
__proto__: XHR.prototype,
_sendXHR: function(xhr) {
xhr.setRequestHeader(
'Authorization', 'Bearer ' + this.connection.oauth.access_token
);
xhr.send(this._serialize());
return xhr;
},
_updateConnection: function(credentials) {
var oauth = this.connection.oauth;
var update = { oauth: credentials };
if (oauth.refresh_token && !credentials.refresh_token)
credentials.refresh_token = oauth.refresh_token;
if (credentials.user) {
update.user = credentials.user;
delete credentials.user;
}
return this.connection.update(update);
},
send: function(callback) {
var xhr = this._buildXHR(callback);
var oauth = this.connection.oauth;
// everything is fine just send
if (this.oauth.accessTokenValid(oauth)) {
return this._sendXHR(xhr);
}
var handleTokenUpdates = (function handleTokenUpdates(err, credentials) {
if (err) {
return callback(err);
}
this._updateConnection(credentials);
return this._sendXHR(xhr);
}.bind(this));
if (oauth.code) {
this.oauth.authenticateCode(oauth.code, handleTokenUpdates);
// it should be impossible to have both code and refresh_token
// but we return as a guard
return xhr;
}
if (oauth.refresh_token) {
this.oauth.refreshToken(oauth.refresh_token, handleTokenUpdates);
return xhr;
}
}
};
module.exports = Oauth2;
}.apply(
this,
(this.Caldav) ?
[Caldav('http/oauth2'), Caldav] :
[module, require('../caldav')]
));
|