diff --git a/src/commands/base-command.ts b/src/commands/base-command.ts index 25196e16ed3..d3b40a27b6e 100644 --- a/src/commands/base-command.ts +++ b/src/commands/base-command.ts @@ -23,6 +23,7 @@ import { USER_AGENT, chalk, logAndThrowError, + logJson, exit, getToken, log, @@ -516,7 +517,26 @@ export default class BaseCommand extends Command { const authLink = `${webUI}/authorize?response_type=ticket&ticket=${ticket.id}` log(`Opening ${authLink}`) - await openBrowser({ url: authLink }) + const browserOpened = await openBrowser({ url: authLink }) + + if (!browserOpened && !isInteractive() && ticket.id) { + const ticketId = ticket.id + logJson({ + ticket_id: ticketId, + url: authLink, + check_command: `netlify login --check ${ticketId}`, + agent_next_steps: + 'Give the URL to the user so they can authorize. Then poll the check_command for up to ten minutes to see if the user has logged in, or wait for them to tell you and then use check_command after.', + }) + log(`Ticket ID: ${ticketId}`) + log(`Authorize URL: ${authLink}`) + log() + log(`After authorizing, run: netlify login --check ${ticketId}`) + log() + log('After user opens the authorization URL and approves, the login will be complete.') + return exit() + } + log() log(`To request authorization from a human, run: ${chalk.cyanBright('netlify login --request ""')}`) log() diff --git a/src/commands/login/login.ts b/src/commands/login/login.ts index d6d7abf6ba0..ab3d4a6c34c 100644 --- a/src/commands/login/login.ts +++ b/src/commands/login/login.ts @@ -1,7 +1,6 @@ import { OptionValues } from 'commander' import { chalk, exit, getToken, log, logAndThrowError } from '../../utils/command-helpers.js' -import { isInteractive } from '../../utils/scripted-commands.js' import { TokenLocation } from '../../utils/types.js' import BaseCommand from '../base-command.js' @@ -51,11 +50,5 @@ export const login = async (options: OptionValues, command: BaseCommand) => { return exit() } - if (!isInteractive()) { - const { loginRequest } = await import('./login-request.js') - await loginRequest('CLI session', command.netlify.apiOpts) - return - } - await command.expensivelyAuthenticate() } diff --git a/src/utils/open-browser.ts b/src/utils/open-browser.ts index 22eaebc7e53..1033b4899c0 100644 --- a/src/utils/open-browser.ts +++ b/src/utils/open-browser.ts @@ -23,24 +23,26 @@ type OpenBrowsrProps = { url: string } -const openBrowser = async function ({ silentBrowserNoneError, url }: OpenBrowsrProps) { +const openBrowser = async function ({ silentBrowserNoneError, url }: OpenBrowsrProps): Promise { if (isDockerContainer()) { unableToOpenBrowserMessage({ url, message: 'Running inside a docker container' }) - return + return false } if (process.env.BROWSER === 'none') { if (!silentBrowserNoneError) { unableToOpenBrowserMessage({ url, message: "BROWSER environment variable is set to 'none'" }) } - return + return false } try { await open(url) + return true } catch (error) { if (error instanceof Error) { unableToOpenBrowserMessage({ url, message: error.message }) } + return false } }