1 module.exports = adduser
3 var log = require("npmlog")
4 , npm = require("./npm.js")
5 , read = require("read")
6 , userValidate = require("npm-user-validate")
10 crypto = require("crypto")
13 adduser.usage = 'npm adduser [--registry=url] [--scope=@orgname] [--always-auth]' +
16 function adduser (args, cb) {
18 if (!crypto) return cb(new Error(
19 "You must compile node with ssl support to use the adduser feature"))
21 var creds = npm.config.getCredentialsByURI(npm.config.get("registry"))
22 var c = { u : creds.username || ""
23 , p : creds.password || ""
24 , e : creds.email || ""
27 , fns = [readUsername, readPassword, readEmail, save]
33 if (fn) return fn(c, u, loop)
38 function readUsername (c, u, cb) {
39 var v = userValidate.username
40 read({prompt: "Username: ", default: c.u || ""}, function (er, un) {
42 return cb(er.message === "cancelled" ? er.message : er)
45 // make sure it's valid. we have to do this here, because
46 // couchdb will only ever say "bad password" with a 401 when
47 // you try to PUT a _users record that the validate_doc_update
48 // rejects for *any* reason.
51 return readUsername(c, u, cb)
56 log.warn(error.message)
57 return readUsername(c, u, cb)
60 c.changed = c.u !== un
66 function readPassword (c, u, cb) {
67 var v = userValidate.pw
70 if (c.p && !c.changed) {
71 prompt = "Password: (or leave unchanged) "
76 read({prompt: prompt, silent: true}, function (er, pw) {
78 return cb(er.message === "cancelled" ? er.message : er)
81 if (!c.changed && pw === "") {
82 // when the username was not changed,
83 // empty response means "use the old value"
88 return readPassword(c, u, cb)
93 log.warn(error.message)
94 return readPassword(c, u, cb)
97 c.changed = c.changed || c.p !== pw
103 function readEmail (c, u, cb) {
104 var v = userValidate.email
105 var r = { prompt: "Email: (this IS public) ", default: c.e || "" }
106 read(r, function (er, em) {
108 return cb(er.message === "cancelled" ? er.message : er)
112 return readEmail(c, u, cb)
117 log.warn(error.message)
118 return readEmail(c, u, cb)
126 function save (c, u, cb) {
129 // save existing configs, but yank off for this PUT
130 var uri = npm.config.get("registry")
131 var scope = npm.config.get("scope")
133 // there may be a saved scope and no --registry (for login)
135 if (scope.charAt(0) !== "@") scope = "@" + scope
137 var scopedRegistry = npm.config.get(scope + ":registry")
138 var cliRegistry = npm.config.get("registry", "cli")
139 if (scopedRegistry && !cliRegistry) uri = scopedRegistry
149 npm.registry.adduser(uri, params, function (er, doc) {
151 if (er) return cb(er)
153 // don't want this polluting the configuration
154 npm.config.del("_token", "user")
156 if (scope) npm.config.set(scope + ":registry", uri, "user")
158 if (doc && doc.token) {
159 npm.config.setCredentialsByURI(uri, {
164 npm.config.setCredentialsByURI(uri, {
168 alwaysAuth : npm.config.get("always-auth")
172 log.info('adduser', 'Authorized user %s', u.u)
173 var scopeMessage = scope ? ' to scope ' + scope : ''
174 console.log('Logged in as %s%s on %s.', u.u, scopeMessage, uri)
175 npm.config.save('user', cb)