Book a Demo!
CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutPoliciesSign UpSign In
Download
81145 views
1
2
/*!
3
* knox - auth
4
* Copyright(c) 2010 LearnBoost <[email protected]>
5
* MIT Licensed
6
*/
7
8
/**
9
* Module dependencies.
10
*/
11
12
var crypto = require('crypto')
13
, parse = require('url').parse
14
;
15
16
/**
17
* Valid keys.
18
*/
19
20
var keys =
21
[ 'acl'
22
, 'location'
23
, 'logging'
24
, 'notification'
25
, 'partNumber'
26
, 'policy'
27
, 'requestPayment'
28
, 'torrent'
29
, 'uploadId'
30
, 'uploads'
31
, 'versionId'
32
, 'versioning'
33
, 'versions'
34
, 'website'
35
]
36
37
/**
38
* Return an "Authorization" header value with the given `options`
39
* in the form of "AWS <key>:<signature>"
40
*
41
* @param {Object} options
42
* @return {String}
43
* @api private
44
*/
45
46
function authorization (options) {
47
return 'AWS ' + options.key + ':' + sign(options)
48
}
49
50
module.exports = authorization
51
module.exports.authorization = authorization
52
53
/**
54
* Simple HMAC-SHA1 Wrapper
55
*
56
* @param {Object} options
57
* @return {String}
58
* @api private
59
*/
60
61
function hmacSha1 (options) {
62
return crypto.createHmac('sha1', options.secret).update(options.message).digest('base64')
63
}
64
65
module.exports.hmacSha1 = hmacSha1
66
67
/**
68
* Create a base64 sha1 HMAC for `options`.
69
*
70
* @param {Object} options
71
* @return {String}
72
* @api private
73
*/
74
75
function sign (options) {
76
options.message = stringToSign(options)
77
return hmacSha1(options)
78
}
79
module.exports.sign = sign
80
81
/**
82
* Create a base64 sha1 HMAC for `options`.
83
*
84
* Specifically to be used with S3 presigned URLs
85
*
86
* @param {Object} options
87
* @return {String}
88
* @api private
89
*/
90
91
function signQuery (options) {
92
options.message = queryStringToSign(options)
93
return hmacSha1(options)
94
}
95
module.exports.signQuery= signQuery
96
97
/**
98
* Return a string for sign() with the given `options`.
99
*
100
* Spec:
101
*
102
* <verb>\n
103
* <md5>\n
104
* <content-type>\n
105
* <date>\n
106
* [headers\n]
107
* <resource>
108
*
109
* @param {Object} options
110
* @return {String}
111
* @api private
112
*/
113
114
function stringToSign (options) {
115
var headers = options.amazonHeaders || ''
116
if (headers) headers += '\n'
117
var r =
118
[ options.verb
119
, options.md5
120
, options.contentType
121
, options.date ? options.date.toUTCString() : ''
122
, headers + options.resource
123
]
124
return r.join('\n')
125
}
126
module.exports.queryStringToSign = stringToSign
127
128
/**
129
* Return a string for sign() with the given `options`, but is meant exclusively
130
* for S3 presigned URLs
131
*
132
* Spec:
133
*
134
* <date>\n
135
* <resource>
136
*
137
* @param {Object} options
138
* @return {String}
139
* @api private
140
*/
141
142
function queryStringToSign (options){
143
return 'GET\n\n\n' + options.date + '\n' + options.resource
144
}
145
module.exports.queryStringToSign = queryStringToSign
146
147
/**
148
* Perform the following:
149
*
150
* - ignore non-amazon headers
151
* - lowercase fields
152
* - sort lexicographically
153
* - trim whitespace between ":"
154
* - join with newline
155
*
156
* @param {Object} headers
157
* @return {String}
158
* @api private
159
*/
160
161
function canonicalizeHeaders (headers) {
162
var buf = []
163
, fields = Object.keys(headers)
164
;
165
for (var i = 0, len = fields.length; i < len; ++i) {
166
var field = fields[i]
167
, val = headers[field]
168
, field = field.toLowerCase()
169
;
170
if (0 !== field.indexOf('x-amz')) continue
171
buf.push(field + ':' + val)
172
}
173
return buf.sort().join('\n')
174
}
175
module.exports.canonicalizeHeaders = canonicalizeHeaders
176
177
/**
178
* Perform the following:
179
*
180
* - ignore non sub-resources
181
* - sort lexicographically
182
*
183
* @param {String} resource
184
* @return {String}
185
* @api private
186
*/
187
188
function canonicalizeResource (resource) {
189
var url = parse(resource, true)
190
, path = url.pathname
191
, buf = []
192
;
193
194
Object.keys(url.query).forEach(function(key){
195
if (!~keys.indexOf(key)) return
196
var val = '' == url.query[key] ? '' : '=' + encodeURIComponent(url.query[key])
197
buf.push(key + val)
198
})
199
200
return path + (buf.length ? '?' + buf.sort().join('&') : '')
201
}
202
module.exports.canonicalizeResource = canonicalizeResource
203
204