Comparing version 1.0.0 to 1.1.0
## Changelog | ||
* `v1.1.0`: Experimental SAML Bearer Assertion Flow support | ||
* `v1.0.0`: Adds promises, improves streaming, better plugin support | ||
* `v0.10.0`: Moves onRefresh call to refreshToken and makes it's execution optional | ||
@@ -4,0 +6,0 @@ * `v0.9.4`: Avoids using request v2.48 because of a bug |
var gulp = require('gulp'); | ||
var seq = require('run-sequence'); | ||
var jshint = require('gulp-jshint'); | ||
var stylish = require('jshint-stylish'); | ||
var spawn = require('child_process').spawn; | ||
@@ -15,3 +17,3 @@ var files = { | ||
// run jshint tasks across all js files | ||
gulp.task('jshint', function() { | ||
gulp.task('lint', function() { | ||
return gulp.src(files.js) | ||
@@ -22,8 +24,23 @@ .pipe(jshint()) | ||
// run mocha tests | ||
gulp.task('test', function(cb) { | ||
var test = spawn('npm', [ 'test' ], { stdio: 'inherit' }); | ||
test.on('close', function(code) { | ||
if(code !== 0) { | ||
return cb(new Error('mocha test failures')); | ||
} | ||
cb(); | ||
}); | ||
}); | ||
// set up a file watcher and run jshint | ||
gulp.task('watch', function() { | ||
gulp.watch(files.js, ['default']); | ||
gulp.watch(files.js, ['lint']); | ||
}); | ||
// default task | ||
gulp.task('default', ['jshint']); | ||
gulp.task('default', function(cb) { | ||
seq('lint', 'test', cb); | ||
}); |
48
index.js
@@ -193,3 +193,5 @@ var request = require('request'); | ||
if(!opts) opts = {}; | ||
var self = this; | ||
var urlOpts = { | ||
@@ -200,8 +202,11 @@ 'response_type': opts.responseType || 'code', | ||
}; | ||
if(opts.display) { | ||
urlOpts.display = opts.display.toLowerCase(); | ||
} | ||
if(opts.immediate) { | ||
urlOpts.immediate = opts.immediate; | ||
} | ||
if(opts.scope) { | ||
@@ -214,8 +219,11 @@ if(_.isArray(opts.scope)) { | ||
} | ||
if(opts.state) { | ||
urlOpts.state = opts.state; | ||
} | ||
if(opts.nonce) { | ||
urlOpts.nonce = opts.nonce; | ||
} | ||
if(opts.prompt) { | ||
@@ -228,10 +236,22 @@ if(_.isArray(opts.prompt)) { | ||
} | ||
if(opts.loginHint) { | ||
urlOpts.login_hint = opts.loginHint; | ||
} | ||
if(self.environment == 'sandbox') { | ||
return this.testAuthEndpoint + '?' + qs.stringify(urlOpts); | ||
if(opts.urlOpts) { | ||
urlOpts = _.assign(urlOpts, opts.urlOpts); | ||
} | ||
var endpoint; | ||
if(opts.authEndpoint) { | ||
endpoint = opts.authEndpoint; | ||
} else if(self.environment == 'sandbox') { | ||
endpoint = this.testAuthEndpoint; | ||
} else { | ||
return this.authEndpoint + '?' + qs.stringify(urlOpts); | ||
endpoint = this.authEndpoint; | ||
} | ||
return endpoint + '?' + qs.stringify(urlOpts); | ||
}; | ||
@@ -262,2 +282,6 @@ | ||
bopts.redirect_uri = self.redirectUri; | ||
} else if(opts.assertion) { | ||
bopts.grant_type = 'assertion'; | ||
bopts.assertion_type = 'urn:oasis:names:tc:SAML:2.0:profiles:SSO:browser'; | ||
bopts.assertion = opts.assertion; | ||
} else if(opts.username || this.username) { | ||
@@ -283,2 +307,3 @@ bopts.grant_type = 'password'; | ||
_.assign(opts.oauth, res); | ||
if(opts.assertion) opts.oauth.assertion = opts.assertion; | ||
if(self.onRefresh && opts.executeOnRefresh === true) { | ||
@@ -312,8 +337,16 @@ self.onRefresh.call(self, opts.oauth, old, function(err3){ | ||
var refreshOpts = { | ||
'client_id': this.clientId, | ||
'grant_type': 'refresh_token', | ||
'redirect_uri': this.redirectUri, | ||
'refresh_token': opts.oauth.refresh_token | ||
client_id: this.clientId, | ||
redirect_uri: this.redirectUri | ||
}; | ||
// support for SAML-based token refreshes | ||
if(!opts.oauth.refresh_token && (opts.oauth.assertion || opts.assertion)) { | ||
refreshOpts.grant_type = 'assertion'; | ||
refreshOpts.assertion_type = 'urn:oasis:names:tc:SAML:2.0:profiles:SSO:browser'; | ||
refreshOpts.assertion = opts.assertion || opts.oauth.assertion; | ||
} else { | ||
refreshOpts.grant_type = 'refresh_token'; | ||
refreshOpts.refresh_token = opts.oauth.refresh_token; | ||
} | ||
// check for clientSecret and include if found | ||
@@ -333,2 +366,3 @@ if(this.clientSecret) { | ||
_.assign(opts.oauth, res); | ||
if(opts.assertion) opts.oauth.assertion = opts.assertion; | ||
if(self.onRefresh && opts.executeOnRefresh === true) { | ||
@@ -335,0 +369,0 @@ self.onRefresh.call(self, opts.oauth, old, function(err3){ |
@@ -5,3 +5,3 @@ { | ||
"description": "nforce is a REST API wrapper for force.com, database.com, and salesforce.com", | ||
"version": "1.0.0", | ||
"version": "1.1.0", | ||
"keywords": [ | ||
@@ -39,2 +39,3 @@ "salesforce", | ||
"mocha": "1.18.2", | ||
"run-sequence": "^1.0.2", | ||
"should": "3.3.1" | ||
@@ -41,0 +42,0 @@ }, |
@@ -185,7 +185,5 @@ nforce :: node.js salesforce REST API wrapper | ||
```js | ||
app.get('/auth/sfdc', | ||
function(req,res){ | ||
res.redirect(org.getAuthUri()); | ||
} | ||
); | ||
app.get('/auth/sfdc', function(req,res){ | ||
res.redirect(org.getAuthUri()); | ||
}); | ||
``` | ||
@@ -212,14 +210,13 @@ | ||
An example of using this function in a typical node route and populating the code from the request would be: | ||
```js | ||
app.get('/auth/sfdc/callback', | ||
function(req, res) { | ||
org.authenticate({code: req.query.code}, function(err, resp){ | ||
if(!err) { | ||
console.log('Access Token: ' + resp.access_token); | ||
} else { | ||
console.log('Error: ' + err.message); | ||
} | ||
}); | ||
} | ||
); | ||
app.get('/auth/sfdc/callback', function(req, res) { | ||
org.authenticate({code: req.query.code}, function(err, resp){ | ||
if(!err) { | ||
console.log('Access Token: ' + resp.access_token); | ||
} else { | ||
console.log('Error: ' + err.message); | ||
} | ||
}); | ||
}); | ||
``` | ||
@@ -442,2 +439,10 @@ | ||
Here is a list of some available plugins today: | ||
* [nforce-tooling](https://github.com/jeffdonthemic/nforce-tooling) Tooling API support | ||
* [nforce-chatter](https://github.com/jeffdonthemic/nforce-chatter) Chatter API support | ||
* [nforce-metadata](https://github.com/kevinohara80/nforce-metadata) Metadata API support | ||
* [nforce-express](https://github.com/kevinohara80/nforce-express) Express.js plugin for | ||
OAuth authentication helpers | ||
Documentation on authoring plugins is coming soon... | ||
@@ -657,2 +662,4 @@ | ||
supported by Salesforce OAuth 2.0. Default is `code`. | ||
* `authEndpoint`: (String:Optional) Override the auth endpoint to | ||
use for the token request | ||
* `display`: (String:Optional) Tailors the login page to the user's | ||
@@ -677,4 +684,5 @@ device type. Currently the only values supported are `page`, | ||
* `loginHint`: (String:Optional) Provide a valid username value with | ||
this | ||
parameter to pre-populate the login page with the username. | ||
this parameter to pre-populate the login page with the username. | ||
* `urlOpts`: (Object:Optional) Specify any other url arguments to | ||
include in the request. | ||
@@ -685,10 +693,7 @@ ### authenticate(opts, [callback]) | ||
from Salesforce or Force.com. This method either requires that you | ||
pass | ||
in the authorization code (authorization code flow) or username and | ||
password (username/password flow). | ||
pass in the authorization code (authorization code flow), username and | ||
password (username/password flow), or a SAML assertion (SAML Bearer | ||
Assertion Flow). | ||
* `code`: (String:Optional) An OAuth authorization code | ||
-- OR -- | ||
* `username`: (String:Optional) Your | ||
@@ -700,2 +705,4 @@ salesforce/force.com/database.com username | ||
This will be appended to your password if this property is set. | ||
* `assertion`: (String:Optional) A base64-encoded SAML assertion used | ||
in a SAML Bearer Assertion flow. | ||
* `executeOnRefresh`: (Boolean:Optional) If an onRefresh callback is | ||
@@ -711,2 +718,5 @@ defined | ||
multi-user mode | ||
* `assertion`: (String:Optional) A base64-encoded SAML assertion for use | ||
with the SAML Bearer Assertion Flow. The assertion can also be supplied as | ||
property of the `oauth` hash. | ||
* `executeOnRefresh`: (Boolean:Optional) If an onRefresh callback is | ||
@@ -713,0 +723,0 @@ defined |
License Policy Violation
LicenseThis package is not allowed per your license policy. Review the package's license to ensure compliance.
Found 1 instance in 1 package
Shell access
Supply chain riskThis module accesses the system shell. Accessing the system shell increases the risk of executing arbitrary code.
Found 1 instance in 1 package
License Policy Violation
LicenseThis package is not allowed per your license policy. Review the package's license to ensure compliance.
Found 1 instance in 1 package
279620
3187
1067
11
3