UNPKG

alnilam-cli

Version:

Git-native AI career coach that converts multi-year ambitions into weekly execution

221 lines (220 loc) 8.8 kB
"use strict"; var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) { if (k2 === undefined) k2 = k; var desc = Object.getOwnPropertyDescriptor(m, k); if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) { desc = { enumerable: true, get: function() { return m[k]; } }; } Object.defineProperty(o, k2, desc); }) : (function(o, m, k, k2) { if (k2 === undefined) k2 = k; o[k2] = m[k]; })); var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) { Object.defineProperty(o, "default", { enumerable: true, value: v }); }) : function(o, v) { o["default"] = v; }); var __importStar = (this && this.__importStar) || (function () { var ownKeys = function(o) { ownKeys = Object.getOwnPropertyNames || function (o) { var ar = []; for (var k in o) if (Object.prototype.hasOwnProperty.call(o, k)) ar[ar.length] = k; return ar; }; return ownKeys(o); }; return function (mod) { if (mod && mod.__esModule) return mod; var result = {}; if (mod != null) for (var k = ownKeys(mod), i = 0; i < k.length; i++) if (k[i] !== "default") __createBinding(result, mod, k[i]); __setModuleDefault(result, mod); return result; }; })(); Object.defineProperty(exports, "__esModule", { value: true }); exports.apiKeyCommand = void 0; const commander_1 = require("commander"); const auth_1 = require("../lib/auth"); const crypto = __importStar(require("crypto")); exports.apiKeyCommand = new commander_1.Command('api-key') .description('Manage API keys for external integrations'); // Generate API key exports.apiKeyCommand .command('create') .description('Create a new API key') .requiredOption('--name <name>', 'Human-readable name for the API key') .option('--expires <date>', 'Expiration date (YYYY-MM-DD) or days (number)', '0') .option('--scopes <scopes>', 'Comma-separated permissions (read,write)', 'read') .option('--json', 'Output as JSON') .action(async (options) => { try { const authToken = await (0, auth_1.getCurrentAuthToken)(); if (!authToken) { console.error('❌ Not authenticated. Run `alnl auth login` first.'); process.exit(1); } // Generate secure API key const apiKey = generateApiKey(); const keyHash = crypto.createHash('sha256').update(apiKey).digest('hex'); const keyPrefix = apiKey.substring(0, 12); // Show first 12 chars for identification // Parse expiration - support both dates (YYYY-MM-DD) and days (number) let expiresAt = null; if (options.expires !== '0') { const expiresInDays = parseInt(options.expires); if (!isNaN(expiresInDays) && expiresInDays > 0) { // Number of days expiresAt = new Date(Date.now() + expiresInDays * 24 * 60 * 60 * 1000).toISOString(); } else { // Try to parse as date const expiresDate = new Date(options.expires); if (!isNaN(expiresDate.getTime())) { expiresAt = expiresDate.toISOString(); } else { console.error('❌ Invalid expiration format. Use YYYY-MM-DD or number of days.'); process.exit(1); } } } // Parse scopes const scopes = options.scopes.split(',').map(s => s.trim()); const supabase = (0, auth_1.createAuthenticatedSupabaseClient)(); const { data, error } = await supabase .from('api_keys') .insert({ name: options.name, key_hash: keyHash, key_prefix: keyPrefix, scopes: scopes, expires_at: expiresAt }) .select() .single(); if (error) { console.error('❌ Failed to create API key:', error.message); process.exit(1); } if (options.json) { console.log(JSON.stringify({ id: data.id, name: data.name, api_key: apiKey, prefix: keyPrefix, scopes: data.scopes, expires_at: data.expires_at, created_at: data.created_at }, null, 2)); } else { console.log('✅ API key created successfully!'); console.log(''); console.log(`🔑 API Key: ${apiKey}`); console.log(`📝 Name: ${data.name}`); console.log(`🏷️ Prefix: ${keyPrefix}...`); console.log(`🛡️ Scopes: ${data.scopes.join(', ')}`); if (expiresAt) { console.log(`⏰ Expires: ${new Date(expiresAt).toLocaleDateString()}`); } else { console.log('⏰ Expires: Never'); } console.log(''); console.log('⚠️ Store this API key securely - it won\'t be shown again!'); console.log('💡 Use this key for ChatGPT integration and other external tools.'); } } catch (error) { console.error('❌ Error:', error.message); process.exit(1); } }); // List API keys exports.apiKeyCommand .command('list') .description('List all API keys') .option('--json', 'Output as JSON') .action(async (options) => { try { const authToken = await (0, auth_1.getCurrentAuthToken)(); if (!authToken) { console.error('❌ Not authenticated. Run `alnl auth login` first.'); process.exit(1); } const supabase = (0, auth_1.createAuthenticatedSupabaseClient)(); const { data, error } = await supabase .from('api_keys') .select('id, name, key_prefix, scopes, last_used_at, expires_at, created_at') .order('created_at', { ascending: false }); if (error) { console.error('❌ Failed to list API keys:', error.message); process.exit(1); } if (options.json) { console.log(JSON.stringify(data, null, 2)); } else { if (data.length === 0) { console.log('📝 No API keys found. Create one with `alnl api-key create --name "ChatGPT"`'); } else { console.log('🔑 Your API Keys:'); console.log(''); data.forEach((key, index) => { const expired = key.expires_at && new Date(key.expires_at) < new Date(); const status = expired ? '❌ Expired' : '✅ Active'; const lastUsed = key.last_used_at ? `Last used: ${new Date(key.last_used_at).toLocaleDateString()}` : 'Never used'; console.log(`${index + 1}. ${key.name} (${key.key_prefix}...)`); console.log(` Status: ${status}`); console.log(` Scopes: ${key.scopes.join(', ')}`); console.log(` ${lastUsed}`); if (key.expires_at) { console.log(` Expires: ${new Date(key.expires_at).toLocaleDateString()}`); } console.log(''); }); } } } catch (error) { console.error('❌ Error:', error.message); process.exit(1); } }); // Delete API key exports.apiKeyCommand .command('delete') .description('Delete an API key') .requiredOption('--id <id>', 'API key ID to delete') .action(async (options) => { try { const authToken = await (0, auth_1.getCurrentAuthToken)(); if (!authToken) { console.error('❌ Not authenticated. Run `alnl auth login` first.'); process.exit(1); } const supabase = (0, auth_1.createAuthenticatedSupabaseClient)(); const { error } = await supabase .from('api_keys') .delete() .eq('id', options.id); if (error) { console.error('❌ Failed to delete API key:', error.message); process.exit(1); } console.log('✅ API key deleted successfully!'); } catch (error) { console.error('❌ Error:', error.message); process.exit(1); } }); function generateApiKey() { // Generate a secure API key with format: alnl_<32_random_chars> const randomBytes = crypto.randomBytes(24); // 24 bytes = 32 base64url chars const randomString = randomBytes.toString('base64url'); return `alnl_${randomString}`; }