Book a Demo!
CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutPoliciesSign UpSign In
Download
81141 views
1
'use strict'
2
3
var qs = require('qs')
4
, caseless = require('caseless')
5
, uuid = require('node-uuid')
6
, oauth = require('oauth-sign')
7
, crypto = require('crypto')
8
9
10
function OAuth (request) {
11
this.request = request
12
this.params = null
13
}
14
15
OAuth.prototype.buildParams = function (_oauth, uri, method, query, form, qsLib) {
16
var oa = {}
17
for (var i in _oauth) {
18
oa['oauth_' + i] = _oauth[i]
19
}
20
if (!oa.oauth_version) {
21
oa.oauth_version = '1.0'
22
}
23
if (!oa.oauth_timestamp) {
24
oa.oauth_timestamp = Math.floor( Date.now() / 1000 ).toString()
25
}
26
if (!oa.oauth_nonce) {
27
oa.oauth_nonce = uuid().replace(/-/g, '')
28
}
29
if (!oa.oauth_signature_method) {
30
oa.oauth_signature_method = 'HMAC-SHA1'
31
}
32
33
var consumer_secret_or_private_key = oa.oauth_consumer_secret || oa.oauth_private_key
34
delete oa.oauth_consumer_secret
35
delete oa.oauth_private_key
36
37
var token_secret = oa.oauth_token_secret
38
delete oa.oauth_token_secret
39
40
var realm = oa.oauth_realm
41
delete oa.oauth_realm
42
delete oa.oauth_transport_method
43
44
var baseurl = uri.protocol + '//' + uri.host + uri.pathname
45
var params = qsLib.parse([].concat(query, form, qsLib.stringify(oa)).join('&'))
46
47
oa.oauth_signature = oauth.sign(
48
oa.oauth_signature_method,
49
method,
50
baseurl,
51
params,
52
consumer_secret_or_private_key,
53
token_secret)
54
55
if (realm) {
56
oa.realm = realm
57
}
58
59
return oa
60
}
61
62
OAuth.prototype.buildBodyHash = function(_oauth, body) {
63
if (['HMAC-SHA1', 'RSA-SHA1'].indexOf(_oauth.signature_method || 'HMAC-SHA1') < 0) {
64
this.request.emit('error', new Error('oauth: ' + _oauth.signature_method +
65
' signature_method not supported with body_hash signing.'))
66
}
67
68
var shasum = crypto.createHash('sha1')
69
shasum.update(body || '')
70
var sha1 = shasum.digest('hex')
71
72
return new Buffer(sha1).toString('base64')
73
}
74
75
OAuth.prototype.concatParams = function (oa, sep, wrap) {
76
wrap = wrap || ''
77
78
var params = Object.keys(oa).filter(function (i) {
79
return i !== 'realm' && i !== 'oauth_signature'
80
}).sort()
81
82
if (oa.realm) {
83
params.splice(0, 1, 'realm')
84
}
85
params.push('oauth_signature')
86
87
return params.map(function (i) {
88
return i + '=' + wrap + oauth.rfc3986(oa[i]) + wrap
89
}).join(sep)
90
}
91
92
OAuth.prototype.onRequest = function (_oauth) {
93
var self = this
94
self.params = _oauth
95
96
var uri = self.request.uri || {}
97
, method = self.request.method || ''
98
, headers = caseless(self.request.headers)
99
, body = self.request.body || ''
100
, qsLib = self.request.qsLib || qs
101
102
var form
103
, query
104
, contentType = headers.get('content-type') || ''
105
, formContentType = 'application/x-www-form-urlencoded'
106
, transport = _oauth.transport_method || 'header'
107
108
if (contentType.slice(0, formContentType.length) === formContentType) {
109
contentType = formContentType
110
form = body
111
}
112
if (uri.query) {
113
query = uri.query
114
}
115
if (transport === 'body' && (method !== 'POST' || contentType !== formContentType)) {
116
self.request.emit('error', new Error('oauth: transport_method of body requires POST ' +
117
'and content-type ' + formContentType))
118
}
119
120
if (!form && typeof _oauth.body_hash === 'boolean') {
121
_oauth.body_hash = self.buildBodyHash(_oauth, self.request.body.toString())
122
}
123
124
var oa = self.buildParams(_oauth, uri, method, query, form, qsLib)
125
126
switch (transport) {
127
case 'header':
128
self.request.setHeader('Authorization', 'OAuth ' + self.concatParams(oa, ',', '"'))
129
break
130
131
case 'query':
132
self.request.path = (query ? '&' : '?') + self.concatParams(oa, '&')
133
break
134
135
case 'body':
136
self.request.body = (form ? form + '&' : '') + self.concatParams(oa, '&')
137
break
138
139
default:
140
self.request.emit('error', new Error('oauth: transport_method invalid'))
141
}
142
}
143
144
exports.OAuth = OAuth
145
146