UNPKG

incize

Version:

AI Commit Copilot for Power Developers

240 lines (239 loc) 8.37 kB
"use strict"; var __importDefault = (this && this.__importDefault) || function (mod) { return (mod && mod.__esModule) ? mod : { "default": mod }; }; Object.defineProperty(exports, "__esModule", { value: true }); exports.CLIAuthService = void 0; const ConfigManager_1 = require("../config/ConfigManager"); const CLIOutputRenderer_1 = require("../output/CLIOutputRenderer"); const chalk_1 = __importDefault(require("chalk")); const ora_1 = __importDefault(require("ora")); const readline_1 = __importDefault(require("readline")); class CLIAuthService { configManager; outputRenderer; API_BASE_URL = 'https://incize.dev/api'; constructor() { this.configManager = new ConfigManager_1.ConfigManager(); this.outputRenderer = new CLIOutputRenderer_1.CLIOutputRenderer(); } /** * Authenticate user with email/password or magic link */ async login(email) { const spinner = (0, ora_1.default)('Authenticating with Incize...').start(); try { // Get email if not provided if (!email) { email = await this.promptForEmail(); } // Validate email format if (!this.isValidEmail(email)) { spinner.fail('Invalid email format'); return false; } // Check if already authenticated const currentAuth = await this.getAuthStatus(); if (currentAuth.authenticated) { spinner.info('Already authenticated'); this.outputRenderer.renderAuthStatus(currentAuth); return true; } // Send authentication request const response = await this.sendAuthRequest(email); if (response.success && response.apiKey && response.user) { // Store authentication data await this.configManager.setAuthConfig({ apiKey: response.apiKey, userId: response.user.userId, subscriptionTier: response.user.subscriptionTier, preferences: response.user.preferences, lastLogin: new Date().toISOString() }); spinner.succeed('Authentication successful!'); this.outputRenderer.renderSuccess('Welcome to Incize! You are now authenticated.'); // Show user info this.outputRenderer.renderUserInfo(response.user); return true; } else { spinner.fail(response.error || 'Authentication failed'); return false; } } catch (error) { spinner.fail('Authentication failed'); console.error(chalk_1.default.red('Error:'), error instanceof Error ? error.message : 'Unknown error'); return false; } } /** * Logout user and clear local authentication */ async logout() { const spinner = (0, ora_1.default)('Logging out...').start(); try { const authConfig = await this.configManager.getAuthConfig(); if (!authConfig) { spinner.info('Not currently authenticated'); return true; } // Send logout request to server await this.sendLogoutRequest(authConfig.apiKey); // Clear local authentication await this.configManager.clearAuthConfig(); spinner.succeed('Logged out successfully'); this.outputRenderer.renderSuccess('You have been logged out of Incize.'); return true; } catch (error) { spinner.fail('Logout failed'); console.error(chalk_1.default.red('Error:'), error instanceof Error ? error.message : 'Unknown error'); return false; } } /** * Get current authentication status */ async getAuthStatus() { try { const authConfig = await this.configManager.getAuthConfig(); if (!authConfig || !authConfig.apiKey) { return { authenticated: false, user: null }; } // Validate token with server const user = await this.validateToken(authConfig.apiKey); if (user) { return { authenticated: true, user }; } else { // Clear invalid auth await this.configManager.clearAuthConfig(); return { authenticated: false, user: null }; } } catch (error) { return { authenticated: false, user: null }; } } /** * Get API key for authenticated requests */ async getApiKey() { const authConfig = await this.configManager.getAuthConfig(); return authConfig?.apiKey || null; } /** * Send authenticated request to API */ async sendAuthenticatedRequest(endpoint, options = {}) { const apiKey = await this.getApiKey(); if (!apiKey) { throw new Error('Not authenticated. Run `incize auth login` first.'); } const response = await fetch(`${this.API_BASE_URL}${endpoint}`, { ...options, headers: { 'Authorization': `Bearer ${apiKey}`, 'Content-Type': 'application/json', ...options.headers } }); if (!response.ok) { if (response.status === 401) { // Clear invalid auth await this.configManager.clearAuthConfig(); throw new Error('Authentication expired. Please login again.'); } throw new Error(`API request failed: ${response.statusText}`); } return response.json(); } /** * Send commit analysis to web dashboard */ async sendCommitAnalysis(analysis) { try { await this.sendAuthenticatedRequest('/commits', { method: 'POST', body: JSON.stringify(analysis) }); return true; } catch (error) { console.error(chalk_1.default.yellow('Warning: Could not sync to dashboard:'), error instanceof Error ? error.message : 'Unknown error'); return false; } } /** * Prompt user for email */ async promptForEmail() { const rl = readline_1.default.createInterface({ input: process.stdin, output: process.stdout }); return new Promise((resolve) => { rl.question(chalk_1.default.blue('Enter your email: '), (email) => { rl.close(); resolve(email.trim()); }); }); } /** * Validate email format */ isValidEmail(email) { const emailRegex = /^[^\s@]+@[^\s@]+\.[^\s@]+$/; return emailRegex.test(email); } /** * Send authentication request to server */ async sendAuthRequest(email) { const response = await fetch(`${this.API_BASE_URL}/auth/cli`, { method: 'POST', headers: { 'Content-Type': 'application/json' }, body: JSON.stringify({ email }) }); if (!response.ok) { throw new Error(`Authentication request failed: ${response.statusText}`); } return response.json(); } /** * Send logout request to server */ async sendLogoutRequest(apiKey) { await fetch(`${this.API_BASE_URL}/auth/logout`, { method: 'POST', headers: { 'Authorization': `Bearer ${apiKey}`, 'Content-Type': 'application/json' } }); } /** * Validate token with server */ async validateToken(apiKey) { try { const response = await fetch(`${this.API_BASE_URL}/auth/validate`, { method: 'GET', headers: { 'Authorization': `Bearer ${apiKey}` } }); if (response.ok) { return response.json(); } return null; } catch (error) { return null; } } } exports.CLIAuthService = CLIAuthService;