Welcome to mirror list, hosted at ThFree Co, Russian Federation.

github.com/npm/cli.git - Unnamed repository; edit this file 'description' to name the repository.
summaryrefslogtreecommitdiff
path: root/lib/auth
diff options
context:
space:
mode:
authorKat Marchán <kzm@sykosomatic.org>2017-01-06 05:06:26 +0300
committerC J Silverio <ceejceej@gmail.com>2017-02-10 02:37:51 +0300
commit95f51570337413497ed72d3e66ecf5ee2c165698 (patch)
treea1cdc0fbc2638072640ff008d0dd5618665f85ee /lib/auth
parent36541eccdfabbacceab87107a5ccef1d376c72a4 (diff)
adduser: add oauth and saml support
PR-URL: https://github.com/npm/npm/pull/13389 Credit: @zkat Reviewed-By: @iarna
Diffstat (limited to 'lib/auth')
-rw-r--r--lib/auth/oauth.js7
-rw-r--r--lib/auth/saml.js7
-rw-r--r--lib/auth/sso.js59
3 files changed, 73 insertions, 0 deletions
diff --git a/lib/auth/oauth.js b/lib/auth/oauth.js
new file mode 100644
index 000000000..1cb3ffec6
--- /dev/null
+++ b/lib/auth/oauth.js
@@ -0,0 +1,7 @@
+var ssoAuth = require('./sso')
+var npm = require('../npm')
+
+module.exports.login = function login () {
+ npm.config.set('sso-type', 'oauth')
+ ssoAuth.login.apply(this, arguments)
+}
diff --git a/lib/auth/saml.js b/lib/auth/saml.js
new file mode 100644
index 000000000..ae92ea5bb
--- /dev/null
+++ b/lib/auth/saml.js
@@ -0,0 +1,7 @@
+var ssoAuth = require('./sso')
+var npm = require('../npm')
+
+module.exports.login = function login () {
+ npm.config.set('sso-type', 'saml')
+ ssoAuth.login.apply(this, arguments)
+}
diff --git a/lib/auth/sso.js b/lib/auth/sso.js
new file mode 100644
index 000000000..faffe2fa5
--- /dev/null
+++ b/lib/auth/sso.js
@@ -0,0 +1,59 @@
+var log = require('npmlog')
+var npm = require('../npm.js')
+var output = require('../utils/output')
+var opener = require('opener')
+
+module.exports.login = function login (creds, registry, scope, cb) {
+ var ssoType = npm.config.get('sso-type')
+ if (!ssoType) { return cb(new Error('Missing option: sso-type')) }
+
+ var params = {
+ // We're reusing the legacy login endpoint, so we need some dummy
+ // stuff here to pass validation. They're never used.
+ auth: {
+ username: 'npm_' + ssoType + '_auth_dummy_user',
+ password: 'placeholder',
+ email: 'support@npmjs.com',
+ authType: ssoType
+ }
+ }
+ npm.registry.adduser(registry, params, function (er, doc) {
+ if (er) return cb(er)
+ if (!doc || !doc.token) return cb(new Error('no SSO token returned'))
+ if (!doc.sso) return cb(new Error('no SSO URL returned by services'))
+
+ output('If your browser doesn\'t open, visit ' +
+ doc.sso +
+ ' to complete authentication')
+ opener(doc.sso, { command: npm.config.get('browser') }, function () {
+ pollForSession(registry, doc.token, function (err, username) {
+ if (err) return cb(err)
+
+ log.info('adduser', 'Authorized user %s', username)
+ var scopeMessage = scope ? ' to scope ' + scope : ''
+ output('Logged in as %s%s on %s.', username, scopeMessage, registry)
+
+ cb(null, { token: doc.token })
+ })
+ })
+ })
+}
+
+function pollForSession (registry, token, cb) {
+ log.info('adduser', 'Polling for validated SSO session')
+ npm.registry.whoami(registry, {
+ auth: {
+ token: token
+ }
+ }, function (er, username) {
+ if (er && er.statusCode !== 401) {
+ cb(er)
+ } else if (!username) {
+ setTimeout(function () {
+ pollForSession(registry, token, cb)
+ }, npm.config.get('sso-poll-frequency'))
+ } else {
+ cb(null, username)
+ }
+ })
+}