@@ -55,7 +55,7 @@ var passport = require('passport')
5555 * `authInfo` will contain the following properties:
5656 *
5757 * scheme always set to `OAuth`
58- * oauth.callbackURL URL to redirect the user to after authorization
58+ * oauth.callbackURL URL to redirect the user to after authorization
5959 *
6060 * When the consumer is making a request to the access token endpoint,
6161 * `authInfo` will contain the following properties (in addition to any optional
@@ -117,14 +117,13 @@ function ConsumerStrategy(options, consumer, token, validate) {
117117 if ( ! consumer ) throw new Error ( 'HTTP OAuth consumer authentication strategy requires a consumer function' ) ;
118118 if ( ! token ) throw new Error ( 'HTTP OAuth consumer authentication strategy requires a token function' ) ;
119119
120- // TODO: Add option to default host if its not in the request header.
121-
122120 passport . Strategy . call ( this ) ;
123121 this . name = 'oauth' ;
124122 this . _consumer = consumer ;
125123 this . _token = token ;
126124 this . _validate = validate ;
127125 this . _realm = options . realm || 'Clients' ;
126+ this . _host = options . host || null ;
128127}
129128
130129/**
@@ -142,13 +141,13 @@ util.inherits(ConsumerStrategy, passport.Strategy);
142141ConsumerStrategy . prototype . authenticate = function ( req ) {
143142 var params = undefined
144143 , header = null ;
145-
144+
146145 if ( req . headers && req . headers [ 'authorization' ] ) {
147146 var parts = req . headers [ 'authorization' ] . split ( ' ' ) ;
148147 if ( parts . length == 2 ) {
149148 var scheme = parts [ 0 ]
150149 , credentials = parts [ 1 ] ;
151-
150+
152151 if ( / O A u t h / i. test ( scheme ) ) {
153152 params = utils . parseHeader ( credentials ) ;
154153 header = params ;
@@ -157,28 +156,28 @@ ConsumerStrategy.prototype.authenticate = function(req) {
157156 return this . fail ( 400 ) ;
158157 }
159158 }
160-
159+
161160 if ( req . body && req . body [ 'oauth_signature' ] ) {
162161 if ( params ) { return this . fail ( 400 ) ; }
163162 params = req . body ;
164163 }
165-
164+
166165 if ( req . query && req . query [ 'oauth_signature' ] ) {
167166 if ( params ) { return this . fail ( 400 ) ; }
168167 token = req . query [ 'access_token' ] ;
169168 params = req . query ;
170169 }
171-
170+
172171 if ( ! params ) { return this . fail ( this . _challenge ( ) ) ; }
173-
172+
174173 if ( ! params [ 'oauth_consumer_key' ] ||
175174 ! params [ 'oauth_signature_method' ] ||
176175 ! params [ 'oauth_signature' ] ||
177176 ! params [ 'oauth_timestamp' ] ||
178177 ! params [ 'oauth_nonce' ] ) {
179178 return this . fail ( this . _challenge ( 'parameter_absent' ) , 400 ) ;
180179 }
181-
180+
182181 var consumerKey = params [ 'oauth_consumer_key' ]
183182 , requestToken = params [ 'oauth_token' ]
184183 , signatureMethod = params [ 'oauth_signature_method' ]
@@ -188,17 +187,17 @@ ConsumerStrategy.prototype.authenticate = function(req) {
188187 , callback = params [ 'oauth_callback' ]
189188 , verifier = params [ 'oauth_verifier' ]
190189 , version = params [ 'oauth_version' ]
191-
190+
192191 if ( version && version !== '1.0' ) {
193192 return this . fail ( this . _challenge ( 'version_rejected' ) , 400 ) ;
194193 }
195-
196-
194+
195+
197196 var self = this ;
198197 this . _consumer ( consumerKey , function ( err , consumer , consumerSecret ) {
199198 if ( err ) { return self . error ( err ) ; }
200199 if ( ! consumer ) { return self . fail ( self . _challenge ( 'consumer_key_rejected' ) ) ; }
201-
200+
202201 if ( ! requestToken ) {
203202 // If no `oauth_token` is present, the consumer is attempting to abtain
204203 // a request token. Validate the request using only the consumer key
@@ -215,22 +214,22 @@ ConsumerStrategy.prototype.authenticate = function(req) {
215214 var info = { } ;
216215 info . scheme = 'OAuth' ;
217216 info . oauth = { callbackURL : callback }
218-
217+
219218 // WARNING: If the consumer is not using OAuth 1.0a, the
220219 // `oauth_callback` parameter will not be present. Instead, it
221220 // will be supplied when the consumer redirects the user to the
222221 // service provider when obtaining authorization. A service
223222 // provider that unconditionally accepts a URL during this
224223 // phase may be inadvertently assisting in session fixation
225224 // attacks, as described here:
226- //
225+ //
227226 // http://oauth.net/advisories/2009-1/
228227 // http://hueniverse.com/2009/04/explaining-the-oauth-session-fixation-attack/
229228 //
230229 // Service providers are encouraged to implement monitoring to
231230 // detect potential attacks, and display advisory notices to
232231 // users.
233-
232+
234233 return self . success ( consumer , info ) ;
235234 } ) ;
236235 } else {
@@ -249,41 +248,41 @@ ConsumerStrategy.prototype.authenticate = function(req) {
249248 self . _token ( requestToken , function ( err , tokenSecret , info ) {
250249 if ( err ) { return self . error ( err ) ; }
251250 if ( ! tokenSecret ) { return self . fail ( self . _challenge ( 'token_rejected' ) ) ; }
252-
251+
253252 validate ( tokenSecret , function ( ) {
254253 info = info || { } ;
255254 info . scheme = 'OAuth' ;
256255 info . oauth = { token : requestToken , verifier : verifier }
257-
256+
258257 // WARNING: If the consumer is not using OAuth 1.0a, the
259258 // `oauth_verifier` parameter will not be present. This
260259 // makes it impossible to know if the user who authorized the
261260 // request token is the same user returning to the
262261 // application, as described here:
263262 //
264263 // http://hueniverse.com/2009/04/explaining-the-oauth-session-fixation-attack/
265-
264+
266265 return self . success ( consumer , info ) ;
267266 } ) ;
268267 } ) ;
269268 }
270-
269+
271270 function validate ( tokenSecret , ok ) {
272- var url = utils . originalURL ( req )
271+ var url = utils . originalURL ( self . _host , req )
273272 , query = req . query
274273 , body = req . body ;
275-
274+
276275 var sources = [ header , query ] ;
277- if ( req . headers [ 'content-type' ] &&
276+ if ( req . headers [ 'content-type' ] &&
278277 req . headers [ 'content-type' ] . slice ( 0 , 'application/x-www-form-urlencoded' . length ) ===
279278 'application/x-www-form-urlencoded' ) {
280279 sources . push ( body ) ;
281280 }
282-
281+
283282 var normalizedURL = utils . normalizeURI ( url )
284283 , normalizedParams = utils . normalizeParams . apply ( undefined , sources )
285284 , base = utils . constructBaseString ( req . method , normalizedURL , normalizedParams ) ;
286-
285+
287286 if ( signatureMethod == 'HMAC-SHA1' ) {
288287 var key = consumerSecret + '&' ;
289288 if ( tokenSecret ) { key += tokenSecret ; }
@@ -301,7 +300,7 @@ ConsumerStrategy.prototype.authenticate = function(req) {
301300 } else {
302301 return self . fail ( self . _challenge ( 'signature_method_rejected' ) , 400 ) ;
303302 }
304-
303+
305304 // If execution reaches this point, the request signature has been
306305 // verified and authentication is successful.
307306 if ( self . _validate ) {
@@ -335,12 +334,12 @@ ConsumerStrategy.prototype._challenge = function(problem, advice) {
335334 if ( advice && advice . length ) {
336335 challenge += ', oauth_problem_advice="' + utils . encode ( advice ) + '"' ;
337336 }
338-
337+
339338 return challenge ;
340339}
341340
342341
343342/**
344343 * Expose `TokenStrategy`.
345- */
344+ */
346345module . exports = ConsumerStrategy ;
0 commit comments