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
diff options
context:
space:
mode:
authorJulian Møller Ellehauge <jumoel@github.com>2022-06-22 23:58:41 +0300
committerGitHub <noreply@github.com>2022-06-22 23:58:41 +0300
commit06fd788f79e16da04d6e96aa56416cd2698f057a (patch)
tree7ca9e6a884b2b64cb65ac791fda52b8d2b963ea6 /lib
parentaab4079e810c06ff5fa847cbd53b5d7bab3dd24f (diff)
feat: prompt before opening web-login URL when performing `login`/`adduser` (#4960)
Prompt before opening web-login URL when performing login/adduser
Diffstat (limited to 'lib')
-rw-r--r--lib/auth/legacy.js12
-rw-r--r--lib/utils/open-url-prompt.js69
2 files changed, 79 insertions, 2 deletions
diff --git a/lib/auth/legacy.js b/lib/auth/legacy.js
index d1401ce14..9aed12f39 100644
--- a/lib/auth/legacy.js
+++ b/lib/auth/legacy.js
@@ -1,6 +1,6 @@
const profile = require('npm-profile')
const log = require('../utils/log-shim')
-const openUrl = require('../utils/open-url.js')
+const openUrlPrompt = require('../utils/open-url-prompt.js')
const read = require('../utils/read-user-info.js')
const loginPrompter = async (creds) => {
@@ -47,7 +47,15 @@ const login = async (npm, opts) => {
return newUser
}
- const openerPromise = (url) => openUrl(npm, url, 'to complete your login please visit')
+ const openerPromise = (url, emitter) =>
+ openUrlPrompt(
+ npm,
+ url,
+ 'Authenticate your account at',
+ 'Press ENTER to open in the browser...',
+ emitter
+ )
+
try {
res = await profile.login(openerPromise, loginPrompter, opts)
} catch (err) {
diff --git a/lib/utils/open-url-prompt.js b/lib/utils/open-url-prompt.js
new file mode 100644
index 000000000..3eb3ac288
--- /dev/null
+++ b/lib/utils/open-url-prompt.js
@@ -0,0 +1,69 @@
+const readline = require('readline')
+const opener = require('opener')
+
+function print (npm, title, url) {
+ const json = npm.config.get('json')
+
+ const message = json ? JSON.stringify({ title, url }) : `${title}:\n${url}`
+
+ npm.output(message)
+}
+
+// Prompt to open URL in browser if possible
+const promptOpen = async (npm, url, title, prompt, emitter) => {
+ const browser = npm.config.get('browser')
+ const isInteractive = process.stdin.isTTY === true && process.stdout.isTTY === true
+
+ try {
+ if (!/^https?:$/.test(new URL(url).protocol)) {
+ throw new Error()
+ }
+ } catch (_) {
+ throw new Error('Invalid URL: ' + url)
+ }
+
+ print(npm, title, url)
+
+ if (browser === false || !isInteractive) {
+ return
+ }
+
+ const rl = readline.createInterface({
+ input: process.stdin,
+ output: process.stdout,
+ })
+
+ const tryOpen = await new Promise(resolve => {
+ rl.question(prompt, () => {
+ resolve(true)
+ })
+
+ if (emitter && emitter.addListener) {
+ emitter.addListener('abort', () => {
+ rl.close()
+
+ // clear the prompt line
+ npm.output('')
+
+ resolve(false)
+ })
+ }
+ })
+
+ if (!tryOpen) {
+ return
+ }
+
+ const command = browser === true ? null : browser
+ await new Promise((resolve, reject) => {
+ opener(url, { command }, err => {
+ if (err) {
+ return reject(err)
+ }
+
+ return resolve()
+ })
+ })
+}
+
+module.exports = promptOpen