| 
									
										
										
										
											2017-03-20 17:55:27 -06:00
										 |  |  | 'use strict'; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | //var OAUTH3 = require('./oauth3.core.js').OAUTH3;
 | 
					
						
							|  |  |  | var OAUTH3 = require('./oauth3.issuer.js').OAUTH3; | 
					
						
							|  |  |  | // used for OAUTH3.urls.resourcePasswordOwner
 | 
					
						
							|  |  |  | // used for OAUTH3.authn.loginMeta
 | 
					
						
							|  |  |  | // used for OAUTH3.authn.otp
 | 
					
						
							|  |  |  | // used for OAUTH3.authn.resourcePasswordOwner
 | 
					
						
							|  |  |  | var PromiseA = require('bluebird'); | 
					
						
							|  |  |  | var requestAsync = PromiseA.promisify(require('request')); | 
					
						
							|  |  |  | var crypto = require('crypto'); | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-03-20 23:29:03 -06:00
										 |  |  | OAUTH3.PromiseA = PromiseA; | 
					
						
							| 
									
										
										
										
											2017-03-20 17:55:27 -06:00
										 |  |  | OAUTH3._discoverHelper = function(providerUri, opts) { | 
					
						
							| 
									
										
										
										
											2017-03-20 23:29:03 -06:00
										 |  |  |   return OAUTH3._node.discover(providerUri, opts); | 
					
						
							| 
									
										
										
										
											2017-03-20 17:55:27 -06:00
										 |  |  | }; | 
					
						
							|  |  |  | OAUTH3._requestHelper = function (preq, opts) { | 
					
						
							|  |  |  |   /* | 
					
						
							|  |  |  |   if (opts && opts.directives) { | 
					
						
							|  |  |  |     preq.url = OAUTH3.url.resolve(opts.directives.issuer, preq.url); | 
					
						
							|  |  |  |   } | 
					
						
							|  |  |  |   */ | 
					
						
							|  |  |  |   return OAUTH3._node.request(preq, opts); | 
					
						
							|  |  |  | }; | 
					
						
							| 
									
										
										
										
											2017-03-21 01:02:41 -06:00
										 |  |  | OAUTH3._base64.atob = function (base64) { | 
					
						
							|  |  |  |   return new Buffer(base64, 'base64').toString('utf8'); | 
					
						
							|  |  |  | }; | 
					
						
							|  |  |  | OAUTH3._base64.btoa = function (text) { | 
					
						
							|  |  |  |   return new Buffer(text, 'utf8').toString('base64'); | 
					
						
							|  |  |  | }; | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-03-20 17:55:27 -06:00
										 |  |  | OAUTH3._node = {}; | 
					
						
							|  |  |  | OAUTH3._node.discover = function(providerUri/*, opts*/) { | 
					
						
							|  |  |  |   return OAUTH3.request({ | 
					
						
							|  |  |  |     method: 'GET' | 
					
						
							|  |  |  |   , url: OAUTH3.url.normalize(providerUri) + '/.well-known/oauth3/directives.json' | 
					
						
							|  |  |  |   }).then(function (resp) { | 
					
						
							|  |  |  |     return resp.data; | 
					
						
							|  |  |  |   }); | 
					
						
							|  |  |  | }; | 
					
						
							|  |  |  | OAUTH3._node.request = function(preq/*, _sys*/) { | 
					
						
							|  |  |  |   var data = { | 
					
						
							|  |  |  |     method: preq.method | 
					
						
							|  |  |  |   , url: preq.url || preq.uri | 
					
						
							|  |  |  |   , headers: preq.headers | 
					
						
							|  |  |  |   , json: preq.data || preq.body || preq.json || undefined // TODO which to use?
 | 
					
						
							|  |  |  |   , formData: preq.formData || undefined | 
					
						
							|  |  |  |   }; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |   //console.log('DEBUG request');
 | 
					
						
							|  |  |  |   //console.log(preq.url || preq.uri);
 | 
					
						
							|  |  |  |   //console.log(data.json);
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |   return requestAsync(data).then(OAUTH3._node._parseJson); | 
					
						
							|  |  |  | }; | 
					
						
							|  |  |  | OAUTH3._node._parseJson = function (resp) { | 
					
						
							|  |  |  |   var err; | 
					
						
							|  |  |  |   var json = resp.body; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |   // TODO toCamelCase
 | 
					
						
							|  |  |  |   if (!(resp.statusCode >= 200 && resp.statusCode < 400)) { | 
					
						
							|  |  |  |     // console.log('[A3] DEBUG', resp.body);
 | 
					
						
							|  |  |  |     err = new Error("bad response code: " + resp.statusCode); | 
					
						
							|  |  |  |     err.result = resp.body; | 
					
						
							|  |  |  |     return PromiseA.reject(err); | 
					
						
							|  |  |  |   } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |   //console.log('resp.body', typeof resp.body);
 | 
					
						
							|  |  |  |   if ('string' === typeof json) { | 
					
						
							|  |  |  |     try { | 
					
						
							|  |  |  |       json = JSON.parse(json); | 
					
						
							|  |  |  |     } catch(e) { | 
					
						
							|  |  |  |       err = new Error('response not parsable:' + resp.body); | 
					
						
							|  |  |  |       err.result = resp.body; | 
					
						
							|  |  |  |       return PromiseA.reject(err); | 
					
						
							|  |  |  |     } | 
					
						
							|  |  |  |   } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |   // handle both Oauth2- and node-style errors
 | 
					
						
							|  |  |  |   if (json.error) { | 
					
						
							|  |  |  |     err = new Error(json.error && json.error.message || json.error_description || json.error); | 
					
						
							|  |  |  |     err.result = json; | 
					
						
							|  |  |  |     return PromiseA.reject(err); | 
					
						
							|  |  |  |   } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-03-21 01:02:41 -06:00
										 |  |  |   return { | 
					
						
							|  |  |  |     headers: resp.headers | 
					
						
							|  |  |  |   , status: resp.statusCode | 
					
						
							|  |  |  |   , data: json | 
					
						
							|  |  |  |   }; | 
					
						
							| 
									
										
										
										
											2017-03-20 17:55:27 -06:00
										 |  |  | }; | 
					
						
							| 
									
										
										
										
											2017-03-21 01:02:41 -06:00
										 |  |  | OAUTH3._logoutHelper = function(/*directives, opts*/) { | 
					
						
							| 
									
										
										
										
											2017-03-20 23:29:03 -06:00
										 |  |  |   // TODO allow prompting of which account
 | 
					
						
							|  |  |  |   return OAUTH3.PromiseA.reject(new Error("logout not yet implemented for node.js")); | 
					
						
							| 
									
										
										
										
											2017-03-20 17:55:27 -06:00
										 |  |  | }; | 
					
						
							|  |  |  | OAUTH3._node.randomState = function () { | 
					
						
							|  |  |  |   return crypto.randomBytes(16).toString('hex'); | 
					
						
							|  |  |  | }; | 
					
						
							|  |  |  | OAUTH3.randomState = OAUTH3._node.randomState; | 
					
						
							| 
									
										
										
										
											2017-03-20 23:29:03 -06:00
										 |  |  | 
 | 
					
						
							|  |  |  | module.exports = OAUTH3; |