import { supabase, clearStoredSession } from '../lib/supabase.js'; import * as p from '@clack/prompts'; import chalk from 'chalk'; import ora from 'ora'; export async function login() { p.intro(chalk.bold.cyan('VeloWork CLI Authentication')); // Check if session already exists const { data: { session } } = await supabase.auth.getSession(); if (session?.user) { const confirm = await p.confirm({ message: `You are already logged in as ${chalk.green(session.user.email)}. Do you want to log out and switch accounts?`, initialValue: false, }); if (p.isCancel(confirm) || !confirm) { p.outro(chalk.yellow('Login cancelled. Keeping current session.')); return; } const logoutSpinner = ora('Logging out of current session...').start(); await supabase.auth.signOut(); clearStoredSession(); logoutSpinner.succeed('Logged out of previous session.'); } // Prompt for credentials const email = await p.text({ message: 'Enter your email address:', placeholder: 'user@example.com', validate(value) { if (!value) return 'Email is required'; if (!/\S+@\S+\.\S+/.test(value)) return 'Please enter a valid email address'; return; }, }); if (p.isCancel(email)) { p.outro(chalk.yellow('Login cancelled.')); return; } const password = await p.password({ message: 'Enter your password:', validate(value) { if (!value) return 'Password is required'; return; }, }); if (p.isCancel(password)) { p.outro(chalk.yellow('Login cancelled.')); return; } const loginSpinner = ora('Connecting to Supabase and authenticating...').start(); try { const { data, error } = await supabase.auth.signInWithPassword({ email: email as string, password: password as string, }); if (error) { loginSpinner.fail(chalk.red('Authentication failed.')); p.note(error.message, chalk.red('Error Details')); p.outro(chalk.bold.red('Please try running "velowork login" again.')); return; } if (data.session) { loginSpinner.succeed(chalk.green('Authentication successful!')); p.outro( `Welcome back, ${chalk.bold.green(data.user?.email)}!\nYour access token has been securely stored.` ); } else { loginSpinner.fail(chalk.red('Did not receive a valid session.')); p.outro(chalk.bold.red('Please try again.')); } } catch (err: any) { loginSpinner.fail(chalk.red('An unexpected error occurred.')); p.note(err.message || String(err), 'Exception Details'); p.outro(chalk.bold.red('Process exited.')); } } export async function logout() { const spinner = ora('Logging out...').start(); try { const { error } = await supabase.auth.signOut(); clearStoredSession(); if (error) { // Even if Supabase request fails, we deleted the local session cache spinner.warn(chalk.yellow('Local session cleared, but API signout failed.')); } else { spinner.succeed(chalk.green('Successfully logged out!')); } console.log(chalk.gray('Your cached tokens have been deleted from your machine.')); } catch (err: any) { clearStoredSession(); spinner.fail(chalk.red('Error during logout, local session cleared anyway.')); } } export async function whoami() { const spinner = ora('Fetching session status...').start(); try { const { data: { user }, error } = await supabase.auth.getUser(); if (error || !user) { spinner.fail(chalk.yellow('You are not currently logged in.')); console.log(`Run ${chalk.cyan('velowork login')} to authenticate.`); return; } spinner.succeed(chalk.green('Session active!')); console.log('\n' + chalk.bold.cyan('--- Active Session Profile ---')); console.log(`${chalk.bold('Email:')} ${user.email}`); console.log(`${chalk.bold('User ID:')} ${user.id}`); console.log(`${chalk.bold('Created:')} ${user.created_at ? new Date(user.created_at).toLocaleString() : 'N/A'}`); console.log(chalk.bold.cyan('------------------------------\n')); } catch (err: any) { spinner.fail(chalk.red('Could not retrieve identity information.')); console.log(chalk.gray(err.message || String(err))); } }