1const profile = require('npm-profile')
2const log = require('../utils/log-shim')
3const openUrlPrompt = require('../utils/open-url-prompt.js')
4const read = require('../utils/read-user-info.js')
5const otplease = require('../utils/otplease.js')
6
7const adduser = async (npm, { creds, ...opts }) => {
8  const authType = npm.config.get('auth-type')
9  let res
10  if (authType === 'web') {
11    try {
12      res = await profile.adduserWeb((url, emitter) => {
13        openUrlPrompt(
14          npm,
15          url,
16          'Create your account at',
17          'Press ENTER to open in the browser...',
18          emitter
19        )
20      }, opts)
21    } catch (err) {
22      if (err.code === 'ENYI') {
23        log.verbose('web add user not supported, trying couch')
24      } else {
25        throw err
26      }
27    }
28  }
29
30  // auth type !== web or ENYI error w/ web adduser
31  if (!res) {
32    const username = await read.username('Username:', creds.username)
33    const password = await read.password('Password:', creds.password)
34    const email = await read.email('Email: (this IS public) ', creds.email)
35    // npm registry quirk: If you "add" an existing user with their current
36    // password, it's effectively a login, and if that account has otp you'll
37    // be prompted for it.
38    res = await otplease(npm, opts, (reqOpts) =>
39      profile.adduserCouch(username, email, password, opts)
40    )
41  }
42
43  // We don't know the username if it was a web login, all we can reliably log is scope and registry
44  const message = `Logged in${opts.scope ? ` to scope ${opts.scope}` : ''} on ${opts.registry}.`
45
46  log.info('adduser', message)
47
48  return {
49    message,
50    newCreds: { token: res.token },
51  }
52}
53
54const login = async (npm, { creds, ...opts }) => {
55  const authType = npm.config.get('auth-type')
56  let res
57  if (authType === 'web') {
58    try {
59      res = await profile.loginWeb((url, emitter) => {
60        openUrlPrompt(
61          npm,
62          url,
63          'Login at',
64          'Press ENTER to open in the browser...',
65          emitter
66        )
67      }, opts)
68    } catch (err) {
69      if (err.code === 'ENYI') {
70        log.verbose('web login not supported, trying couch')
71      } else {
72        throw err
73      }
74    }
75  }
76
77  // auth type !== web or ENYI error w/ web login
78  if (!res) {
79    const username = await read.username('Username:', creds.username)
80    const password = await read.password('Password:', creds.password)
81    res = await otplease(npm, opts, (reqOpts) =>
82      profile.loginCouch(username, password, reqOpts)
83    )
84  }
85
86  // We don't know the username if it was a web login, all we can reliably log is scope and registry
87  const message = `Logged in${opts.scope ? ` to scope ${opts.scope}` : ''} on ${opts.registry}.`
88
89  log.info('login', message)
90
91  return {
92    message,
93    newCreds: { token: res.token },
94  }
95}
96
97module.exports = {
98  adduser,
99  login,
100}
101