Team Ai
Datasetpublic

codekingpro/portable-devtools

sourceHugging Faceupdated 5mo agoView on Hugging Face
1likes15kdownloads
auth.js109 linesDownload Raw Back to utils
1const { webAuthOpener, adduserWeb, loginWeb, loginCouch, adduserCouch } = require('npm-profile')
2const { log } = require('proc-log')
3const { createOpener } = require('../utils/open-url.js')
4const read = require('../utils/read-user-info.js')
5
6const otplease = async (npm, opts, fn) => {
7  try {
8    return await fn(opts)
9  } catch (err) {
10    if (!process.stdin.isTTY || !process.stdout.isTTY) {
11      throw err
12    }
13
14    // web otp
15    if (err.code === 'EOTP' && err.body?.authUrl && err.body?.doneUrl) {
16      const { token: otp } = await webAuthOpener(
17        createOpener(npm, 'Authenticate your account at'),
18        err.body.authUrl,
19        err.body.doneUrl,
20        opts
21      )
22      return await fn({ ...opts, otp })
23    }
24
25    // classic otp
26    if (err.code === 'EOTP' || (err.code === 'E401' && /one-time pass/.test(err.body))) {
27      const otp = await read.otp('This operation requires a one-time password.\nEnter OTP:')
28      return await fn({ ...opts, otp })
29    }
30
31    throw err
32  }
33}
34
35const adduser = async (npm, { creds, ...opts }) => {
36  const authType = npm.config.get('auth-type')
37  let res
38  if (authType === 'web') {
39    try {
40      res = await adduserWeb(createOpener(npm, 'Create your account at'), opts)
41    } catch (err) {
42      if (err.code === 'ENYI') {
43        log.verbose('web add user not supported, trying couch')
44      } else {
45        throw err
46      }
47    }
48  }
49
50  // auth type !== web or ENYI error w/ web adduser
51  if (!res) {
52    const username = await read.username('Username:', creds.username)
53    const password = await read.password('Password:', creds.password)
54    const email = await read.email('Email (this will be public):', creds.email)
55    // npm registry quirk:
56    // If you "add" an existing user with their current password, it's effectively a login, and if that account has otp you'll be prompted for it.
57    res = await otplease(npm, opts, (reqOpts) => adduserCouch(username, email, password, reqOpts))
58  }
59
60  // We don't know the username if it was a web login, all we can reliably log is scope and registry
61  const message = `Logged in${opts.scope ? ` to scope ${opts.scope}` : ''} on ${opts.registry}.`
62
63  log.info('adduser', message)
64
65  return {
66    message,
67    newCreds: { token: res.token },
68  }
69}
70
71const login = async (npm, { creds, ...opts }) => {
72  const authType = npm.config.get('auth-type')
73  let res
74  if (authType === 'web') {
75    try {
76      res = await loginWeb(createOpener(npm, 'Login at'), opts)
77    } catch (err) {
78      if (err.code === 'ENYI') {
79        log.verbose('web login not supported, trying couch')
80      } else {
81        throw err
82      }
83    }
84  }
85
86  // auth type !== web or ENYI error w/ web login
87  if (!res) {
88    const username = await read.username('Username:', creds.username)
89    const password = await read.password('Password:', creds.password)
90    res = await otplease(npm, opts, (reqOpts) => loginCouch(username, password, reqOpts))
91  }
92
93  // We don't know the username if it was a web login, all we can reliably log is scope and registry
94  const message = `Logged in${opts.scope ? ` to scope ${opts.scope}` : ''} on ${opts.registry}.`
95
96  log.info('login', message)
97
98  return {
99    message,
100    newCreds: { token: res.token },
101  }
102}
103
104module.exports = {
105  adduser,
106  login,
107  otplease,
108}
109 
codekingpro/portable-devtools · Team Ai