Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
- Loading branch information
Steve King
committed
Feb 16, 2013
1 parent
76fa5e4
commit 806c384
Showing
12 changed files
with
555 additions
and
0 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Original file line | Diff line number | Diff line change |
---|---|---|---|
@@ -0,0 +1,3 @@ | |||
.idea/* | |||
*.iml | |||
node_modules/* |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Original file line | Diff line number | Diff line change |
---|---|---|---|
@@ -0,0 +1,4 @@ | |||
.idea/* | |||
*.iml | |||
.git* | |||
node_modules/* |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Original file line | Diff line number | Diff line change |
---|---|---|---|
@@ -0,0 +1,23 @@ | |||
{ | |||
"name": "gauth", | |||
"version": "0.0.1", | |||
"description": "Middleware component to authenticate users through their Google account", | |||
"author": "Steve King <steve@mydev.co>", | |||
"contributors": [ { "name": "Steve King", "email": "steve@mydev.co" } ], | |||
"keywords": ["authentication", "oauth", "google", "express", "connect", "middleware"], | |||
"repository": "git://github.com/steveukx/gauth", | |||
"main":"./src/index.js", | |||
"engines": { "node": ">= 0.8.0" }, | |||
"dependencies":{ | |||
"promise-lite": "", | |||
"subscribable": "", | |||
"xhrequest": "" | |||
}, | |||
"devDependencies": { | |||
"express": "3.1.0", | |||
"unit-test": "" | |||
}, | |||
"scripts": { | |||
"test": "node test/test.js" | |||
} | |||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Original file line | Diff line number | Diff line change |
---|---|---|---|
@@ -0,0 +1,41 @@ | |||
/** | |||
* @exports AccessTokenGenerator | |||
*/ | |||
(function () { | |||
|
|||
"use strict"; | |||
|
|||
/** | |||
* The AccessTokenGenerator requires an end point URL that requests can be sent to and returns a promise interface | |||
* that will be resolved with the access token or rejected should any errors take place. | |||
* | |||
* @name AccessTokenGenerator | |||
* @constructor | |||
*/ | |||
function AccessTokenGenerator(endPointUrl) { | |||
var promise = new (require('promise-lite').Promise); | |||
var query = '?' + require('querystring').stringify({ | |||
"openid.ns": 'http://specs.openid.net/auth/2.0', | |||
"openid.mode": "associate", | |||
"openid.assoc_type": "HMAC-SHA1", | |||
"openid.session_type": "no-encryption" | |||
}); | |||
|
|||
require('xhrequest')(endPointUrl + query, { | |||
success: function (data) { | |||
promise.resolve(AccessTokenGenerator.getResultFromServerResponse(data.toString('utf8'))); | |||
}, | |||
error: function () { | |||
promise.reject(new Error("Unable to fetch an access token")); | |||
} | |||
}); | |||
return promise; | |||
} | |||
|
|||
AccessTokenGenerator.getResultFromServerResponse = function (data) { | |||
return data.match(/assoc_handle\:(.+)/)[1]; | |||
}; | |||
|
|||
module.exports = AccessTokenGenerator; | |||
|
|||
}()); |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Original file line | Diff line number | Diff line change |
---|---|---|---|
@@ -0,0 +1,128 @@ | |||
/** | |||
* @exports Authenticator | |||
*/ | |||
(function () { | |||
|
|||
"use strict"; | |||
|
|||
/** | |||
* | |||
* @name Authenticator | |||
* @constructor | |||
*/ | |||
function Authenticator(endPointUrl, assocHandle, baseUrl) { | |||
this._assocHandle = assocHandle; | |||
this._endPointUrl = endPointUrl; | |||
this._baseUrl = baseUrl; | |||
this._realm = (function(url) { return url.protocol + '//' + url.host + '/'; }(require('url').parse(baseUrl))); | |||
} | |||
|
|||
/** | |||
* @type {String} The base url is the absolute URL to the root of the authenticated content (eg: http://domain.com/usercontent/) | |||
*/ | |||
Authenticator.prototype._baseUrl = ""; | |||
|
|||
/** | |||
* @type {String} The realm is the trusted domain that the user must agree to authenticating with, derived from the host of the base url (eg: http://domain.com/) | |||
*/ | |||
Authenticator.prototype._realm = ""; | |||
|
|||
/** | |||
* Sets the base url to be used in this authenticator, and will as a result also set the realm to match the base url. | |||
* @param {String} baseUrl | |||
* @return {Authenticator} | |||
*/ | |||
Authenticator.prototype.setBaseUrl = function(baseUrl) { | |||
if(baseUrl != this._baseUrl) { | |||
this._baseUrl = baseUrl; | |||
this._realm = (function(url) { return url.protocol + '//' + url.host + '/'; }(require('url').parse(baseUrl))); | |||
} | |||
return this; | |||
}; | |||
|
|||
/** | |||
* Gets the URL that should be used to authenticate a user with a terminal URL of the supplied backTo path. | |||
* | |||
* @param {String} backTo | |||
* @return {string} | |||
*/ | |||
Authenticator.prototype.getLogInUrl = function(backTo) { | |||
var params = this._getLoginParameters(); | |||
params['openid.return_to'] += '?next=' + backTo; | |||
|
|||
return this._endPointUrl + '?' + require('querystring').stringify(params); | |||
}; | |||
|
|||
/** | |||
* Applies properties to the supplied object that will include email request parameters | |||
* @param {Object} params | |||
*/ | |||
Authenticator.prototype._mergeEmailRequest = function(params) { | |||
params['openid.ns.ax'] = 'http://openid.net/srv/ax/1.0'; | |||
params['openid.ax.mode'] = 'fetch_request'; | |||
params['openid.ax.required'] = 'email,firstname,lastname'; | |||
|
|||
params['openid.ax.type.email'] = 'http://schema.openid.net/contact/email'; | |||
params['openid.ax.type.firstname'] = 'http://axschema.org/namePerson/first'; | |||
params['openid.ax.type.lastname'] = 'http://axschema.org/namePerson/last'; | |||
}; | |||
|
|||
/** | |||
* Gets the URL parameters used for associating a user's google account with this application | |||
* @return {Object} | |||
*/ | |||
Authenticator.prototype._getLoginParameters = function() { | |||
var params = this._getParameters(); | |||
|
|||
params['openid.claimed_id'] = 'http://specs.openid.net/auth/2.0/identifier_select'; | |||
params['openid.identity'] = 'http://specs.openid.net/auth/2.0/identifier_select'; | |||
params['openid.return_to'] = this._baseUrl + '/responder'; | |||
params['openid.realm'] = this._realm; | |||
params['openid.assoc_handle'] = ''; | |||
params['openid.mode'] = 'checkid_setup'; | |||
this._mergeEmailRequest(params); | |||
|
|||
return params; | |||
}; | |||
|
|||
Authenticator.prototype._getIdentityResponseParameters = function() { | |||
var params = this._getParameters(); | |||
|
|||
params['openid.claimed_id'] = 'http://specs.openid.net/auth/2.0/identifier_select'; | |||
params['openid.identity'] = 'http://specs.openid.net/auth/2.0/identifier_select'; | |||
params['openid.return_to'] = this._baseUrl + '/responder'; | |||
params['openid.realm'] = this._realm; | |||
params['openid.assoc_handle'] = ''; | |||
params['openid.mode'] = 'checkid_setup'; | |||
this._mergeEmailRequest(params); | |||
|
|||
return params; | |||
}; | |||
|
|||
/** | |||
* Gets the URL parameters used for cancelling the association of the google account with this application | |||
* @return {Object} | |||
*/ | |||
Authenticator.prototype._getCancelParameters = function() { | |||
return { | |||
'openid.ns': 'http://specs.openid.net/auth/2.0', | |||
'openid.mode': 'cancel' | |||
}; | |||
}; | |||
|
|||
/** | |||
* Gets default parameters for all requests | |||
* @return {Object} | |||
*/ | |||
Authenticator.prototype._getParameters = function() { | |||
return { | |||
'openid.ns': 'http://specs.openid.net/auth/2.0', | |||
'openid.assoc_handle': this._assocHandle | |||
}; | |||
}; | |||
|
|||
|
|||
|
|||
module.exports = Authenticator; | |||
|
|||
}()); |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Original file line | Diff line number | Diff line change |
---|---|---|---|
@@ -0,0 +1,43 @@ | |||
/** | |||
* @exports EndPointResolver | |||
*/ | |||
(function () { | |||
|
|||
"use strict"; | |||
|
|||
/** | |||
* Sends a request to the supplied discovery URL and parses the response for the URL that subsequent requests should | |||
* be sent. The result of calling the EndPointResolver is a promise interface that will be resolved with the end point | |||
* url or rejected if any errors took place. | |||
* | |||
* @param {String} discoveryUrl | |||
* | |||
* @name EndPointResolver | |||
* @constructor | |||
*/ | |||
function EndPointResolver(discoveryUrl) { | |||
var promise = new (require('promise-lite').Promise); | |||
require('xhrequest')(discoveryUrl, { | |||
success: function(data) { | |||
promise.resolve(EndPointResolver.getResultFromServerResponse(data.toString('utf8'))); | |||
}, | |||
error: function() { | |||
promise.reject(new Error("Unable to connect to end point discovery URL")); | |||
} | |||
}); | |||
return promise; | |||
} | |||
|
|||
/** | |||
* Given the response data from the discovery resource, retrieves the URI for making all further requests bound to. | |||
* | |||
* @param {String} data | |||
* @return {String} | |||
*/ | |||
EndPointResolver.getResultFromServerResponse = function(data) { | |||
return data.match(/<URI>(.+)<\/URI>/i)[1]; | |||
}; | |||
|
|||
module.exports = EndPointResolver; | |||
|
|||
}()); |
Oops, something went wrong.