-
Notifications
You must be signed in to change notification settings - Fork 3.3k
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
feat: Support pure web authentication for commands
* feat: Add support for web auth, utilizing code from npm-profile Co-authored-by: Jordan Harband <ljharb@gmail.com> Co-authored-by: Hayden Faulds <fauldsh@gmail.com> Co-authored-by: Sandeep Meduru <sandeepmeduru@github.com>
- Loading branch information
Showing
16 changed files
with
148 additions
and
26 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,17 +1,46 @@ | ||
async function otplease (opts, fn) { | ||
async function otplease (npm, opts, fn) { | ||
try { | ||
return await fn(opts) | ||
} catch (err) { | ||
const readUserInfo = require('./read-user-info.js') | ||
if (err.code !== 'EOTP' && (err.code !== 'E401' || !/one-time pass/.test(err.body))) { | ||
if (!process.stdin.isTTY || !process.stdout.isTTY) { | ||
throw err | ||
} else if (!process.stdin.isTTY || !process.stdout.isTTY) { | ||
throw err | ||
} else { | ||
} | ||
|
||
if (isWebOTP(err)) { | ||
const webAuth = require('./web-auth') | ||
const openUrlPrompt = require('./open-url-prompt') | ||
|
||
const openerPromise = (url, emitter) => | ||
openUrlPrompt( | ||
npm, | ||
url, | ||
'Authenticate your account at', | ||
'Press ENTER to open in the browser...', | ||
emitter | ||
) | ||
const otp = await webAuth(openerPromise, err.body.authUrl, err.body.doneUrl, opts) | ||
return await fn({ ...opts, otp }) | ||
} | ||
|
||
if (isClassicOTP(err)) { | ||
const readUserInfo = require('./read-user-info.js') | ||
const otp = await readUserInfo.otp('This operation requires a one-time password.\nEnter OTP:') | ||
return await fn({ ...opts, otp }) | ||
} | ||
|
||
throw err | ||
} | ||
} | ||
|
||
function isWebOTP (err) { | ||
if (!err.code === 'EOTP' || !err.body) { | ||
return false | ||
} | ||
return err.body.authUrl && err.body.doneUrl | ||
} | ||
|
||
function isClassicOTP (err) { | ||
return err.code === 'EOTP' || (err.code === 'E401' && /one-time pass/.test(err.body)) | ||
} | ||
|
||
module.exports = otplease |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,20 @@ | ||
const EventEmitter = require('events') | ||
const { webAuthCheckLogin } = require('npm-profile') | ||
|
||
async function webAuth (opener, initialUrl, doneUrl, opts) { | ||
const doneEmitter = new EventEmitter() | ||
|
||
const openPromise = opener(initialUrl, doneEmitter) | ||
const webAuthCheckPromise = webAuthCheckLogin(doneUrl, { ...opts, cache: false }) | ||
.then(authResult => { | ||
// cancel open prompt if it's present | ||
doneEmitter.emit('abort') | ||
|
||
return authResult.token | ||
}) | ||
|
||
await openPromise | ||
return await webAuthCheckPromise | ||
} | ||
|
||
module.exports = webAuth |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,32 @@ | ||
const t = require('tap') | ||
|
||
const webAuthCheckLogin = async () => { | ||
return { token: 'otp-token' } | ||
} | ||
|
||
const webauth = t.mock('../../../lib/utils/web-auth.js', { | ||
'npm-profile': { webAuthCheckLogin }, | ||
}) | ||
|
||
const initialUrl = 'https://example.com/auth' | ||
const doneUrl = 'https://example.com/done' | ||
const opts = {} | ||
|
||
t.test('returns token on success', async (t) => { | ||
const opener = async () => {} | ||
const result = await webauth(opener, initialUrl, doneUrl, opts) | ||
t.equal(result, 'otp-token') | ||
}) | ||
|
||
t.test('closes opener when auth check finishes', async (t) => { | ||
const opener = (_url, emitter) => { | ||
return new Promise((resolve, reject) => { | ||
// the only way to finish this promise is to emit aboter on the emitter | ||
emitter.addListener('abort', () => { | ||
resolve() | ||
}) | ||
}) | ||
} | ||
const result = await webauth(opener, initialUrl, doneUrl, opts) | ||
t.equal(result, 'otp-token') | ||
}) |