UNPKG

@ace-sdk/cli

Version:

ACE CLI - Command-line tool for intelligent pattern learning and playbook management

124 lines 5.1 kB
/** * Login Command - Device code authentication * @package @ace-sdk/cli * * v2.9.0: Enhanced to validate token with server before claiming "already logged in" */ import ora from 'ora'; import chalk from 'chalk'; import { login, getTokenStatus, isAuthenticatedAsync } from '@ace-sdk/core'; import { globalOptions } from '../cli.js'; export async function loginCommand(options) { const spinner = ora({ isSilent: globalOptions.quiet || globalOptions.json }); // Check token status locally first const tokenStatus = getTokenStatus(); if (tokenStatus.hasToken && !tokenStatus.needsReLogin) { // Token exists and appears valid locally - verify with server spinner.start('Checking authentication status...'); const authResult = await isAuthenticatedAsync(); spinner.stop(); if (authResult.authenticated && authResult.user) { if (globalOptions.json) { console.log(JSON.stringify({ warning: 'Already logged in', user: { email: authResult.user.email, user_id: authResult.user.user_id, organizations: authResult.user.organizations?.length ?? 0 } })); } else { console.log(chalk.yellow('Already logged in as:'), chalk.cyan(authResult.user.email)); console.log(chalk.gray('Use'), chalk.white('ce-ace logout'), chalk.gray('to switch accounts')); } return; } // Token exists but server rejected it - inform and proceed with login if (!globalOptions.json) { if (authResult.reason === 'session_expired') { console.log(chalk.yellow('Previous session expired. Starting new login...')); } else if (authResult.reason === 'server_error') { console.log(chalk.yellow('Could not verify session. Starting new login...')); } } } else if (tokenStatus.hasToken && tokenStatus.needsReLogin) { // Token is locally expired if (!globalOptions.json) { if (tokenStatus.isHardCapExpired) { console.log(chalk.yellow('Session hard cap expired (7-day limit). Please re-authenticate.')); } else if (tokenStatus.isRefreshExpired) { console.log(chalk.yellow('Session expired. Please re-authenticate.')); } } } try { await login({ clientType: 'cli', noBrowser: options.noBrowser, onUserCode: (code, url) => { if (globalOptions.json) { console.log(JSON.stringify({ event: 'device_code', user_code: code, verification_url: url })); } else { console.log(); console.log(chalk.cyan(' Open this URL to authenticate:')); console.log(chalk.white(` ${url}`)); console.log(); console.log(chalk.gray(' Or enter this code manually:'), chalk.yellow.bold(code)); console.log(); spinner.start('Waiting for authentication...'); } }, onProgress: (message) => { if (!globalOptions.json) { spinner.text = message; } }, onSuccess: (user) => { spinner.succeed('Authentication successful!'); if (globalOptions.json) { console.log(JSON.stringify({ success: true, user: { user_id: user.user_id, email: user.email, name: user.name, organizations: user.organizations } })); } else { console.log(); console.log(chalk.green('Logged in as:'), chalk.cyan(user.email)); if (user.organizations.length > 0) { console.log(chalk.gray('Organizations:'), user.organizations.map(o => o.name).join(', ')); } console.log(); console.log(chalk.gray('Run'), chalk.white('ce-ace whoami'), chalk.gray('to see your account info')); } } }); } catch (error) { spinner.fail('Authentication failed'); if (globalOptions.json) { console.error(JSON.stringify({ error: true, message: error instanceof Error ? error.message : String(error) })); } else { console.error(chalk.red(error instanceof Error ? error.message : String(error))); } process.exit(1); } } //# sourceMappingURL=login.js.map